GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: lib/libskey/put.c Lines: 0 99 0.0 %
Date: 2017-11-07 Branches: 0 60 0.0 %

Line Branch Exec Source
1
/* OpenBSD S/Key (put.c)
2
 *
3
 * Authors:
4
 *          Neil M. Haller <nmh@thumper.bellcore.com>
5
 *          Philip R. Karn <karn@chicago.qualcomm.com>
6
 *          John S. Walden <jsw@thumper.bellcore.com>
7
 *          Scott Chasin <chasin@crimelab.com>
8
 *
9
 * Dictionary lookup and extraction.
10
 *
11
 * $OpenBSD: put.c,v 1.14 2013/11/29 19:00:51 deraadt Exp $
12
 */
13
14
#include <stdio.h>
15
#include <stdlib.h>
16
#include <string.h>
17
#include <assert.h>
18
#include <ctype.h>
19
20
#include "skey.h"
21
22
static unsigned int extract(char *, int, int);
23
static void standard(char *);
24
static void insert(char *, int, int, int);
25
static int wsrch(char *, int, int);
26
27
/* Standard dictionary for integer-word translations */
28
static const char * const Wp[2048] = {
29
	"A",      "ABE",    "ACE",    "ACT",    "AD",     "ADA",    "ADD",
30
	"AGO",    "AID",    "AIM",    "AIR",    "ALL",    "ALP",    "AM",
31
	"AMY",    "AN",     "ANA",    "AND",    "ANN",    "ANT",    "ANY",
32
	"APE",    "APS",    "APT",    "ARC",    "ARE",    "ARK",    "ARM",
33
	"ART",    "AS",     "ASH",    "ASK",    "AT",     "ATE",    "AUG",
34
	"AUK",    "AVE",    "AWE",    "AWK",    "AWL",    "AWN",    "AX",
35
	"AYE",    "BAD",    "BAG",    "BAH",    "BAM",    "BAN",    "BAR",
36
	"BAT",    "BAY",    "BE",     "BED",    "BEE",    "BEG",    "BEN",
37
	"BET",    "BEY",    "BIB",    "BID",    "BIG",    "BIN",    "BIT",
38
	"BOB",    "BOG",    "BON",    "BOO",    "BOP",    "BOW",    "BOY",
39
	"BUB",    "BUD",    "BUG",    "BUM",    "BUN",    "BUS",    "BUT",
40
	"BUY",    "BY",     "BYE",    "CAB",    "CAL",    "CAM",    "CAN",
41
	"CAP",    "CAR",    "CAT",    "CAW",    "COD",    "COG",    "COL",
42
	"CON",    "COO",    "COP",    "COT",    "COW",    "COY",    "CRY",
43
	"CUB",    "CUE",    "CUP",    "CUR",    "CUT",    "DAB",    "DAD",
44
	"DAM",    "DAN",    "DAR",    "DAY",    "DEE",    "DEL",    "DEN",
45
	"DES",    "DEW",    "DID",    "DIE",    "DIG",    "DIN",    "DIP",
46
	"DO",     "DOE",    "DOG",    "DON",    "DOT",    "DOW",    "DRY",
47
	"DUB",    "DUD",    "DUE",    "DUG",    "DUN",    "EAR",    "EAT",
48
	"ED",     "EEL",    "EGG",    "EGO",    "ELI",    "ELK",    "ELM",
49
	"ELY",    "EM",     "END",    "EST",    "ETC",    "EVA",    "EVE",
50
	"EWE",    "EYE",    "FAD",    "FAN",    "FAR",    "FAT",    "FAY",
51
	"FED",    "FEE",    "FEW",    "FIB",    "FIG",    "FIN",    "FIR",
52
	"FIT",    "FLO",    "FLY",    "FOE",    "FOG",    "FOR",    "FRY",
53
	"FUM",    "FUN",    "FUR",    "GAB",    "GAD",    "GAG",    "GAL",
54
	"GAM",    "GAP",    "GAS",    "GAY",    "GEE",    "GEL",    "GEM",
55
	"GET",    "GIG",    "GIL",    "GIN",    "GO",     "GOT",    "GUM",
56
	"GUN",    "GUS",    "GUT",    "GUY",    "GYM",    "GYP",    "HA",
57
	"HAD",    "HAL",    "HAM",    "HAN",    "HAP",    "HAS",    "HAT",
58
	"HAW",    "HAY",    "HE",     "HEM",    "HEN",    "HER",    "HEW",
59
	"HEY",    "HI",     "HID",    "HIM",    "HIP",    "HIS",    "HIT",
60
	"HO",     "HOB",    "HOC",    "HOE",    "HOG",    "HOP",    "HOT",
61
	"HOW",    "HUB",    "HUE",    "HUG",    "HUH",    "HUM",    "HUT",
62
	"I",      "ICY",    "IDA",    "IF",     "IKE",    "ILL",    "INK",
63
	"INN",    "IO",     "ION",    "IQ",     "IRA",    "IRE",    "IRK",
64
	"IS",     "IT",     "ITS",    "IVY",    "JAB",    "JAG",    "JAM",
65
	"JAN",    "JAR",    "JAW",    "JAY",    "JET",    "JIG",    "JIM",
66
	"JO",     "JOB",    "JOE",    "JOG",    "JOT",    "JOY",    "JUG",
67
	"JUT",    "KAY",    "KEG",    "KEN",    "KEY",    "KID",    "KIM",
68
	"KIN",    "KIT",    "LA",     "LAB",    "LAC",    "LAD",    "LAG",
69
	"LAM",    "LAP",    "LAW",    "LAY",    "LEA",    "LED",    "LEE",
70
	"LEG",    "LEN",    "LEO",    "LET",    "LEW",    "LID",    "LIE",
71
	"LIN",    "LIP",    "LIT",    "LO",     "LOB",    "LOG",    "LOP",
72
	"LOS",    "LOT",    "LOU",    "LOW",    "LOY",    "LUG",    "LYE",
73
	"MA",     "MAC",    "MAD",    "MAE",    "MAN",    "MAO",    "MAP",
74
	"MAT",    "MAW",    "MAY",    "ME",     "MEG",    "MEL",    "MEN",
75
	"MET",    "MEW",    "MID",    "MIN",    "MIT",    "MOB",    "MOD",
76
	"MOE",    "MOO",    "MOP",    "MOS",    "MOT",    "MOW",    "MUD",
77
	"MUG",    "MUM",    "MY",     "NAB",    "NAG",    "NAN",    "NAP",
78
	"NAT",    "NAY",    "NE",     "NED",    "NEE",    "NET",    "NEW",
79
	"NIB",    "NIL",    "NIP",    "NIT",    "NO",     "NOB",    "NOD",
80
	"NON",    "NOR",    "NOT",    "NOV",    "NOW",    "NU",     "NUN",
81
	"NUT",    "O",      "OAF",    "OAK",    "OAR",    "OAT",    "ODD",
82
	"ODE",    "OF",     "OFF",    "OFT",    "OH",     "OIL",    "OK",
83
	"OLD",    "ON",     "ONE",    "OR",     "ORB",    "ORE",    "ORR",
84
	"OS",     "OTT",    "OUR",    "OUT",    "OVA",    "OW",     "OWE",
85
	"OWL",    "OWN",    "OX",     "PA",     "PAD",    "PAL",    "PAM",
86
	"PAN",    "PAP",    "PAR",    "PAT",    "PAW",    "PAY",    "PEA",
87
	"PEG",    "PEN",    "PEP",    "PER",    "PET",    "PEW",    "PHI",
88
	"PI",     "PIE",    "PIN",    "PIT",    "PLY",    "PO",     "POD",
89
	"POE",    "POP",    "POT",    "POW",    "PRO",    "PRY",    "PUB",
90
	"PUG",    "PUN",    "PUP",    "PUT",    "QUO",    "RAG",    "RAM",
91
	"RAN",    "RAP",    "RAT",    "RAW",    "RAY",    "REB",    "RED",
92
	"REP",    "RET",    "RIB",    "RID",    "RIG",    "RIM",    "RIO",
93
	"RIP",    "ROB",    "ROD",    "ROE",    "RON",    "ROT",    "ROW",
94
	"ROY",    "RUB",    "RUE",    "RUG",    "RUM",    "RUN",    "RYE",
95
	"SAC",    "SAD",    "SAG",    "SAL",    "SAM",    "SAN",    "SAP",
96
	"SAT",    "SAW",    "SAY",    "SEA",    "SEC",    "SEE",    "SEN",
97
	"SET",    "SEW",    "SHE",    "SHY",    "SIN",    "SIP",    "SIR",
98
	"SIS",    "SIT",    "SKI",    "SKY",    "SLY",    "SO",     "SOB",
99
	"SOD",    "SON",    "SOP",    "SOW",    "SOY",    "SPA",    "SPY",
100
	"SUB",    "SUD",    "SUE",    "SUM",    "SUN",    "SUP",    "TAB",
101
	"TAD",    "TAG",    "TAN",    "TAP",    "TAR",    "TEA",    "TED",
102
	"TEE",    "TEN",    "THE",    "THY",    "TIC",    "TIE",    "TIM",
103
	"TIN",    "TIP",    "TO",     "TOE",    "TOG",    "TOM",    "TON",
104
	"TOO",    "TOP",    "TOW",    "TOY",    "TRY",    "TUB",    "TUG",
105
	"TUM",    "TUN",    "TWO",    "UN",     "UP",     "US",     "USE",
106
	"VAN",    "VAT",    "VET",    "VIE",    "WAD",    "WAG",    "WAR",
107
	"WAS",    "WAY",    "WE",     "WEB",    "WED",    "WEE",    "WET",
108
	"WHO",    "WHY",    "WIN",    "WIT",    "WOK",    "WON",    "WOO",
109
	"WOW",    "WRY",    "WU",     "YAM",    "YAP",    "YAW",    "YE",
110
	"YEA",    "YES",    "YET",    "YOU",    "ABED",   "ABEL",   "ABET",
111
	"ABLE",   "ABUT",   "ACHE",   "ACID",   "ACME",   "ACRE",   "ACTA",
112
	"ACTS",   "ADAM",   "ADDS",   "ADEN",   "AFAR",   "AFRO",   "AGEE",
113
	"AHEM",   "AHOY",   "AIDA",   "AIDE",   "AIDS",   "AIRY",   "AJAR",
114
	"AKIN",   "ALAN",   "ALEC",   "ALGA",   "ALIA",   "ALLY",   "ALMA",
115
	"ALOE",   "ALSO",   "ALTO",   "ALUM",   "ALVA",   "AMEN",   "AMES",
116
	"AMID",   "AMMO",   "AMOK",   "AMOS",   "AMRA",   "ANDY",   "ANEW",
117
	"ANNA",   "ANNE",   "ANTE",   "ANTI",   "AQUA",   "ARAB",   "ARCH",
118
	"AREA",   "ARGO",   "ARID",   "ARMY",   "ARTS",   "ARTY",   "ASIA",
119
	"ASKS",   "ATOM",   "AUNT",   "AURA",   "AUTO",   "AVER",   "AVID",
120
	"AVIS",   "AVON",   "AVOW",   "AWAY",   "AWRY",   "BABE",   "BABY",
121
	"BACH",   "BACK",   "BADE",   "BAIL",   "BAIT",   "BAKE",   "BALD",
122
	"BALE",   "BALI",   "BALK",   "BALL",   "BALM",   "BAND",   "BANE",
123
	"BANG",   "BANK",   "BARB",   "BARD",   "BARE",   "BARK",   "BARN",
124
	"BARR",   "BASE",   "BASH",   "BASK",   "BASS",   "BATE",   "BATH",
125
	"BAWD",   "BAWL",   "BEAD",   "BEAK",   "BEAM",   "BEAN",   "BEAR",
126
	"BEAT",   "BEAU",   "BECK",   "BEEF",   "BEEN",   "BEER",   "BEET",
127
	"BELA",   "BELL",   "BELT",   "BEND",   "BENT",   "BERG",   "BERN",
128
	"BERT",   "BESS",   "BEST",   "BETA",   "BETH",   "BHOY",   "BIAS",
129
	"BIDE",   "BIEN",   "BILE",   "BILK",   "BILL",   "BIND",   "BING",
130
	"BIRD",   "BITE",   "BITS",   "BLAB",   "BLAT",   "BLED",   "BLEW",
131
	"BLOB",   "BLOC",   "BLOT",   "BLOW",   "BLUE",   "BLUM",   "BLUR",
132
	"BOAR",   "BOAT",   "BOCA",   "BOCK",   "BODE",   "BODY",   "BOGY",
133
	"BOHR",   "BOIL",   "BOLD",   "BOLO",   "BOLT",   "BOMB",   "BONA",
134
	"BOND",   "BONE",   "BONG",   "BONN",   "BONY",   "BOOK",   "BOOM",
135
	"BOON",   "BOOT",   "BORE",   "BORG",   "BORN",   "BOSE",   "BOSS",
136
	"BOTH",   "BOUT",   "BOWL",   "BOYD",   "BRAD",   "BRAE",   "BRAG",
137
	"BRAN",   "BRAY",   "BRED",   "BREW",   "BRIG",   "BRIM",   "BROW",
138
	"BUCK",   "BUDD",   "BUFF",   "BULB",   "BULK",   "BULL",   "BUNK",
139
	"BUNT",   "BUOY",   "BURG",   "BURL",   "BURN",   "BURR",   "BURT",
140
	"BURY",   "BUSH",   "BUSS",   "BUST",   "BUSY",   "BYTE",   "CADY",
141
	"CAFE",   "CAGE",   "CAIN",   "CAKE",   "CALF",   "CALL",   "CALM",
142
	"CAME",   "CANE",   "CANT",   "CARD",   "CARE",   "CARL",   "CARR",
143
	"CART",   "CASE",   "CASH",   "CASK",   "CAST",   "CAVE",   "CEIL",
144
	"CELL",   "CENT",   "CERN",   "CHAD",   "CHAR",   "CHAT",   "CHAW",
145
	"CHEF",   "CHEN",   "CHEW",   "CHIC",   "CHIN",   "CHOU",   "CHOW",
146
	"CHUB",   "CHUG",   "CHUM",   "CITE",   "CITY",   "CLAD",   "CLAM",
147
	"CLAN",   "CLAW",   "CLAY",   "CLOD",   "CLOG",   "CLOT",   "CLUB",
148
	"CLUE",   "COAL",   "COAT",   "COCA",   "COCK",   "COCO",   "CODA",
149
	"CODE",   "CODY",   "COED",   "COIL",   "COIN",   "COKE",   "COLA",
150
	"COLD",   "COLT",   "COMA",   "COMB",   "COME",   "COOK",   "COOL",
151
	"COON",   "COOT",   "CORD",   "CORE",   "CORK",   "CORN",   "COST",
152
	"COVE",   "COWL",   "CRAB",   "CRAG",   "CRAM",   "CRAY",   "CREW",
153
	"CRIB",   "CROW",   "CRUD",   "CUBA",   "CUBE",   "CUFF",   "CULL",
154
	"CULT",   "CUNY",   "CURB",   "CURD",   "CURE",   "CURL",   "CURT",
155
	"CUTS",   "DADE",   "DALE",   "DAME",   "DANA",   "DANE",   "DANG",
156
	"DANK",   "DARE",   "DARK",   "DARN",   "DART",   "DASH",   "DATA",
157
	"DATE",   "DAVE",   "DAVY",   "DAWN",   "DAYS",   "DEAD",   "DEAF",
158
	"DEAL",   "DEAN",   "DEAR",   "DEBT",   "DECK",   "DEED",   "DEEM",
159
	"DEER",   "DEFT",   "DEFY",   "DELL",   "DENT",   "DENY",   "DESK",
160
	"DIAL",   "DICE",   "DIED",   "DIET",   "DIME",   "DINE",   "DING",
161
	"DINT",   "DIRE",   "DIRT",   "DISC",   "DISH",   "DISK",   "DIVE",
162
	"DOCK",   "DOES",   "DOLE",   "DOLL",   "DOLT",   "DOME",   "DONE",
163
	"DOOM",   "DOOR",   "DORA",   "DOSE",   "DOTE",   "DOUG",   "DOUR",
164
	"DOVE",   "DOWN",   "DRAB",   "DRAG",   "DRAM",   "DRAW",   "DREW",
165
	"DRUB",   "DRUG",   "DRUM",   "DUAL",   "DUCK",   "DUCT",   "DUEL",
166
	"DUET",   "DUKE",   "DULL",   "DUMB",   "DUNE",   "DUNK",   "DUSK",
167
	"DUST",   "DUTY",   "EACH",   "EARL",   "EARN",   "EASE",   "EAST",
168
	"EASY",   "EBEN",   "ECHO",   "EDDY",   "EDEN",   "EDGE",   "EDGY",
169
	"EDIT",   "EDNA",   "EGAN",   "ELAN",   "ELBA",   "ELLA",   "ELSE",
170
	"EMIL",   "EMIT",   "EMMA",   "ENDS",   "ERIC",   "EROS",   "EVEN",
171
	"EVER",   "EVIL",   "EYED",   "FACE",   "FACT",   "FADE",   "FAIL",
172
	"FAIN",   "FAIR",   "FAKE",   "FALL",   "FAME",   "FANG",   "FARM",
173
	"FAST",   "FATE",   "FAWN",   "FEAR",   "FEAT",   "FEED",   "FEEL",
174
	"FEET",   "FELL",   "FELT",   "FEND",   "FERN",   "FEST",   "FEUD",
175
	"FIEF",   "FIGS",   "FILE",   "FILL",   "FILM",   "FIND",   "FINE",
176
	"FINK",   "FIRE",   "FIRM",   "FISH",   "FISK",   "FIST",   "FITS",
177
	"FIVE",   "FLAG",   "FLAK",   "FLAM",   "FLAT",   "FLAW",   "FLEA",
178
	"FLED",   "FLEW",   "FLIT",   "FLOC",   "FLOG",   "FLOW",   "FLUB",
179
	"FLUE",   "FOAL",   "FOAM",   "FOGY",   "FOIL",   "FOLD",   "FOLK",
180
	"FOND",   "FONT",   "FOOD",   "FOOL",   "FOOT",   "FORD",   "FORE",
181
	"FORK",   "FORM",   "FORT",   "FOSS",   "FOUL",   "FOUR",   "FOWL",
182
	"FRAU",   "FRAY",   "FRED",   "FREE",   "FRET",   "FREY",   "FROG",
183
	"FROM",   "FUEL",   "FULL",   "FUME",   "FUND",   "FUNK",   "FURY",
184
	"FUSE",   "FUSS",   "GAFF",   "GAGE",   "GAIL",   "GAIN",   "GAIT",
185
	"GALA",   "GALE",   "GALL",   "GALT",   "GAME",   "GANG",   "GARB",
186
	"GARY",   "GASH",   "GATE",   "GAUL",   "GAUR",   "GAVE",   "GAWK",
187
	"GEAR",   "GELD",   "GENE",   "GENT",   "GERM",   "GETS",   "GIBE",
188
	"GIFT",   "GILD",   "GILL",   "GILT",   "GINA",   "GIRD",   "GIRL",
189
	"GIST",   "GIVE",   "GLAD",   "GLEE",   "GLEN",   "GLIB",   "GLOB",
190
	"GLOM",   "GLOW",   "GLUE",   "GLUM",   "GLUT",   "GOAD",   "GOAL",
191
	"GOAT",   "GOER",   "GOES",   "GOLD",   "GOLF",   "GONE",   "GONG",
192
	"GOOD",   "GOOF",   "GORE",   "GORY",   "GOSH",   "GOUT",   "GOWN",
193
	"GRAB",   "GRAD",   "GRAY",   "GREG",   "GREW",   "GREY",   "GRID",
194
	"GRIM",   "GRIN",   "GRIT",   "GROW",   "GRUB",   "GULF",   "GULL",
195
	"GUNK",   "GURU",   "GUSH",   "GUST",   "GWEN",   "GWYN",   "HAAG",
196
	"HAAS",   "HACK",   "HAIL",   "HAIR",   "HALE",   "HALF",   "HALL",
197
	"HALO",   "HALT",   "HAND",   "HANG",   "HANK",   "HANS",   "HARD",
198
	"HARK",   "HARM",   "HART",   "HASH",   "HAST",   "HATE",   "HATH",
199
	"HAUL",   "HAVE",   "HAWK",   "HAYS",   "HEAD",   "HEAL",   "HEAR",
200
	"HEAT",   "HEBE",   "HECK",   "HEED",   "HEEL",   "HEFT",   "HELD",
201
	"HELL",   "HELM",   "HERB",   "HERD",   "HERE",   "HERO",   "HERS",
202
	"HESS",   "HEWN",   "HICK",   "HIDE",   "HIGH",   "HIKE",   "HILL",
203
	"HILT",   "HIND",   "HINT",   "HIRE",   "HISS",   "HIVE",   "HOBO",
204
	"HOCK",   "HOFF",   "HOLD",   "HOLE",   "HOLM",   "HOLT",   "HOME",
205
	"HONE",   "HONK",   "HOOD",   "HOOF",   "HOOK",   "HOOT",   "HORN",
206
	"HOSE",   "HOST",   "HOUR",   "HOVE",   "HOWE",   "HOWL",   "HOYT",
207
	"HUCK",   "HUED",   "HUFF",   "HUGE",   "HUGH",   "HUGO",   "HULK",
208
	"HULL",   "HUNK",   "HUNT",   "HURD",   "HURL",   "HURT",   "HUSH",
209
	"HYDE",   "HYMN",   "IBIS",   "ICON",   "IDEA",   "IDLE",   "IFFY",
210
	"INCA",   "INCH",   "INTO",   "IONS",   "IOTA",   "IOWA",   "IRIS",
211
	"IRMA",   "IRON",   "ISLE",   "ITCH",   "ITEM",   "IVAN",   "JACK",
212
	"JADE",   "JAIL",   "JAKE",   "JANE",   "JAVA",   "JEAN",   "JEFF",
213
	"JERK",   "JESS",   "JEST",   "JIBE",   "JILL",   "JILT",   "JIVE",
214
	"JOAN",   "JOBS",   "JOCK",   "JOEL",   "JOEY",   "JOHN",   "JOIN",
215
	"JOKE",   "JOLT",   "JOVE",   "JUDD",   "JUDE",   "JUDO",   "JUDY",
216
	"JUJU",   "JUKE",   "JULY",   "JUNE",   "JUNK",   "JUNO",   "JURY",
217
	"JUST",   "JUTE",   "KAHN",   "KALE",   "KANE",   "KANT",   "KARL",
218
	"KATE",   "KEEL",   "KEEN",   "KENO",   "KENT",   "KERN",   "KERR",
219
	"KEYS",   "KICK",   "KILL",   "KIND",   "KING",   "KIRK",   "KISS",
220
	"KITE",   "KLAN",   "KNEE",   "KNEW",   "KNIT",   "KNOB",   "KNOT",
221
	"KNOW",   "KOCH",   "KONG",   "KUDO",   "KURD",   "KURT",   "KYLE",
222
	"LACE",   "LACK",   "LACY",   "LADY",   "LAID",   "LAIN",   "LAIR",
223
	"LAKE",   "LAMB",   "LAME",   "LAND",   "LANE",   "LANG",   "LARD",
224
	"LARK",   "LASS",   "LAST",   "LATE",   "LAUD",   "LAVA",   "LAWN",
225
	"LAWS",   "LAYS",   "LEAD",   "LEAF",   "LEAK",   "LEAN",   "LEAR",
226
	"LEEK",   "LEER",   "LEFT",   "LEND",   "LENS",   "LENT",   "LEON",
227
	"LESK",   "LESS",   "LEST",   "LETS",   "LIAR",   "LICE",   "LICK",
228
	"LIED",   "LIEN",   "LIES",   "LIEU",   "LIFE",   "LIFT",   "LIKE",
229
	"LILA",   "LILT",   "LILY",   "LIMA",   "LIMB",   "LIME",   "LIND",
230
	"LINE",   "LINK",   "LINT",   "LION",   "LISA",   "LIST",   "LIVE",
231
	"LOAD",   "LOAF",   "LOAM",   "LOAN",   "LOCK",   "LOFT",   "LOGE",
232
	"LOIS",   "LOLA",   "LONE",   "LONG",   "LOOK",   "LOON",   "LOOT",
233
	"LORD",   "LORE",   "LOSE",   "LOSS",   "LOST",   "LOUD",   "LOVE",
234
	"LOWE",   "LUCK",   "LUCY",   "LUGE",   "LUKE",   "LULU",   "LUND",
235
	"LUNG",   "LURA",   "LURE",   "LURK",   "LUSH",   "LUST",   "LYLE",
236
	"LYNN",   "LYON",   "LYRA",   "MACE",   "MADE",   "MAGI",   "MAID",
237
	"MAIL",   "MAIN",   "MAKE",   "MALE",   "MALI",   "MALL",   "MALT",
238
	"MANA",   "MANN",   "MANY",   "MARC",   "MARE",   "MARK",   "MARS",
239
	"MART",   "MARY",   "MASH",   "MASK",   "MASS",   "MAST",   "MATE",
240
	"MATH",   "MAUL",   "MAYO",   "MEAD",   "MEAL",   "MEAN",   "MEAT",
241
	"MEEK",   "MEET",   "MELD",   "MELT",   "MEMO",   "MEND",   "MENU",
242
	"MERT",   "MESH",   "MESS",   "MICE",   "MIKE",   "MILD",   "MILE",
243
	"MILK",   "MILL",   "MILT",   "MIMI",   "MIND",   "MINE",   "MINI",
244
	"MINK",   "MINT",   "MIRE",   "MISS",   "MIST",   "MITE",   "MITT",
245
	"MOAN",   "MOAT",   "MOCK",   "MODE",   "MOLD",   "MOLE",   "MOLL",
246
	"MOLT",   "MONA",   "MONK",   "MONT",   "MOOD",   "MOON",   "MOOR",
247
	"MOOT",   "MORE",   "MORN",   "MORT",   "MOSS",   "MOST",   "MOTH",
248
	"MOVE",   "MUCH",   "MUCK",   "MUDD",   "MUFF",   "MULE",   "MULL",
249
	"MURK",   "MUSH",   "MUST",   "MUTE",   "MUTT",   "MYRA",   "MYTH",
250
	"NAGY",   "NAIL",   "NAIR",   "NAME",   "NARY",   "NASH",   "NAVE",
251
	"NAVY",   "NEAL",   "NEAR",   "NEAT",   "NECK",   "NEED",   "NEIL",
252
	"NELL",   "NEON",   "NERO",   "NESS",   "NEST",   "NEWS",   "NEWT",
253
	"NIBS",   "NICE",   "NICK",   "NILE",   "NINA",   "NINE",   "NOAH",
254
	"NODE",   "NOEL",   "NOLL",   "NONE",   "NOOK",   "NOON",   "NORM",
255
	"NOSE",   "NOTE",   "NOUN",   "NOVA",   "NUDE",   "NULL",   "NUMB",
256
	"OATH",   "OBEY",   "OBOE",   "ODIN",   "OHIO",   "OILY",   "OINT",
257
	"OKAY",   "OLAF",   "OLDY",   "OLGA",   "OLIN",   "OMAN",   "OMEN",
258
	"OMIT",   "ONCE",   "ONES",   "ONLY",   "ONTO",   "ONUS",   "ORAL",
259
	"ORGY",   "OSLO",   "OTIS",   "OTTO",   "OUCH",   "OUST",   "OUTS",
260
	"OVAL",   "OVEN",   "OVER",   "OWLY",   "OWNS",   "QUAD",   "QUIT",
261
	"QUOD",   "RACE",   "RACK",   "RACY",   "RAFT",   "RAGE",   "RAID",
262
	"RAIL",   "RAIN",   "RAKE",   "RANK",   "RANT",   "RARE",   "RASH",
263
	"RATE",   "RAVE",   "RAYS",   "READ",   "REAL",   "REAM",   "REAR",
264
	"RECK",   "REED",   "REEF",   "REEK",   "REEL",   "REID",   "REIN",
265
	"RENA",   "REND",   "RENT",   "REST",   "RICE",   "RICH",   "RICK",
266
	"RIDE",   "RIFT",   "RILL",   "RIME",   "RING",   "RINK",   "RISE",
267
	"RISK",   "RITE",   "ROAD",   "ROAM",   "ROAR",   "ROBE",   "ROCK",
268
	"RODE",   "ROIL",   "ROLL",   "ROME",   "ROOD",   "ROOF",   "ROOK",
269
	"ROOM",   "ROOT",   "ROSA",   "ROSE",   "ROSS",   "ROSY",   "ROTH",
270
	"ROUT",   "ROVE",   "ROWE",   "ROWS",   "RUBE",   "RUBY",   "RUDE",
271
	"RUDY",   "RUIN",   "RULE",   "RUNG",   "RUNS",   "RUNT",   "RUSE",
272
	"RUSH",   "RUSK",   "RUSS",   "RUST",   "RUTH",   "SACK",   "SAFE",
273
	"SAGE",   "SAID",   "SAIL",   "SALE",   "SALK",   "SALT",   "SAME",
274
	"SAND",   "SANE",   "SANG",   "SANK",   "SARA",   "SAUL",   "SAVE",
275
	"SAYS",   "SCAN",   "SCAR",   "SCAT",   "SCOT",   "SEAL",   "SEAM",
276
	"SEAR",   "SEAT",   "SEED",   "SEEK",   "SEEM",   "SEEN",   "SEES",
277
	"SELF",   "SELL",   "SEND",   "SENT",   "SETS",   "SEWN",   "SHAG",
278
	"SHAM",   "SHAW",   "SHAY",   "SHED",   "SHIM",   "SHIN",   "SHOD",
279
	"SHOE",   "SHOT",   "SHOW",   "SHUN",   "SHUT",   "SICK",   "SIDE",
280
	"SIFT",   "SIGH",   "SIGN",   "SILK",   "SILL",   "SILO",   "SILT",
281
	"SINE",   "SING",   "SINK",   "SIRE",   "SITE",   "SITS",   "SITU",
282
	"SKAT",   "SKEW",   "SKID",   "SKIM",   "SKIN",   "SKIT",   "SLAB",
283
	"SLAM",   "SLAT",   "SLAY",   "SLED",   "SLEW",   "SLID",   "SLIM",
284
	"SLIT",   "SLOB",   "SLOG",   "SLOT",   "SLOW",   "SLUG",   "SLUM",
285
	"SLUR",   "SMOG",   "SMUG",   "SNAG",   "SNOB",   "SNOW",   "SNUB",
286
	"SNUG",   "SOAK",   "SOAR",   "SOCK",   "SODA",   "SOFA",   "SOFT",
287
	"SOIL",   "SOLD",   "SOME",   "SONG",   "SOON",   "SOOT",   "SORE",
288
	"SORT",   "SOUL",   "SOUR",   "SOWN",   "STAB",   "STAG",   "STAN",
289
	"STAR",   "STAY",   "STEM",   "STEW",   "STIR",   "STOW",   "STUB",
290
	"STUN",   "SUCH",   "SUDS",   "SUIT",   "SULK",   "SUMS",   "SUNG",
291
	"SUNK",   "SURE",   "SURF",   "SWAB",   "SWAG",   "SWAM",   "SWAN",
292
	"SWAT",   "SWAY",   "SWIM",   "SWUM",   "TACK",   "TACT",   "TAIL",
293
	"TAKE",   "TALE",   "TALK",   "TALL",   "TANK",   "TASK",   "TATE",
294
	"TAUT",   "TEAL",   "TEAM",   "TEAR",   "TECH",   "TEEM",   "TEEN",
295
	"TEET",   "TELL",   "TEND",   "TENT",   "TERM",   "TERN",   "TESS",
296
	"TEST",   "THAN",   "THAT",   "THEE",   "THEM",   "THEN",   "THEY",
297
	"THIN",   "THIS",   "THUD",   "THUG",   "TICK",   "TIDE",   "TIDY",
298
	"TIED",   "TIER",   "TILE",   "TILL",   "TILT",   "TIME",   "TINA",
299
	"TINE",   "TINT",   "TINY",   "TIRE",   "TOAD",   "TOGO",   "TOIL",
300
	"TOLD",   "TOLL",   "TONE",   "TONG",   "TONY",   "TOOK",   "TOOL",
301
	"TOOT",   "TORE",   "TORN",   "TOTE",   "TOUR",   "TOUT",   "TOWN",
302
	"TRAG",   "TRAM",   "TRAY",   "TREE",   "TREK",   "TRIG",   "TRIM",
303
	"TRIO",   "TROD",   "TROT",   "TROY",   "TRUE",   "TUBA",   "TUBE",
304
	"TUCK",   "TUFT",   "TUNA",   "TUNE",   "TUNG",   "TURF",   "TURN",
305
	"TUSK",   "TWIG",   "TWIN",   "TWIT",   "ULAN",   "UNIT",   "URGE",
306
	"USED",   "USER",   "USES",   "UTAH",   "VAIL",   "VAIN",   "VALE",
307
	"VARY",   "VASE",   "VAST",   "VEAL",   "VEDA",   "VEIL",   "VEIN",
308
	"VEND",   "VENT",   "VERB",   "VERY",   "VETO",   "VICE",   "VIEW",
309
	"VINE",   "VISE",   "VOID",   "VOLT",   "VOTE",   "WACK",   "WADE",
310
	"WAGE",   "WAIL",   "WAIT",   "WAKE",   "WALE",   "WALK",   "WALL",
311
	"WALT",   "WAND",   "WANE",   "WANG",   "WANT",   "WARD",   "WARM",
312
	"WARN",   "WART",   "WASH",   "WAST",   "WATS",   "WATT",   "WAVE",
313
	"WAVY",   "WAYS",   "WEAK",   "WEAL",   "WEAN",   "WEAR",   "WEED",
314
	"WEEK",   "WEIR",   "WELD",   "WELL",   "WELT",   "WENT",   "WERE",
315
	"WERT",   "WEST",   "WHAM",   "WHAT",   "WHEE",   "WHEN",   "WHET",
316
	"WHOA",   "WHOM",   "WICK",   "WIFE",   "WILD",   "WILL",   "WIND",
317
	"WINE",   "WING",   "WINK",   "WINO",   "WIRE",   "WISE",   "WISH",
318
	"WITH",   "WOLF",   "WONT",   "WOOD",   "WOOL",   "WORD",   "WORE",
319
	"WORK",   "WORM",   "WORN",   "WOVE",   "WRIT",   "WYNN",   "YALE",
320
	"YANG",   "YANK",   "YARD",   "YARN",   "YAWL",   "YAWN",   "YEAH",
321
	"YEAR",   "YELL",   "YOGA",   "YOKE"
322
};
323
324
/*
325
 * Encode 8 bytes in 'c' as a string of 6 four-letter English words separated
326
 * by spaces.  The 'out' pointer must have at least 30 bytes for storage.
327
 */
328
char *
329
btoe(char *engout, char *c)
330
{
331
	char cp[10];	/* add in room for the parity 2 bits + extract() slop */
332
	int p, i, indices[6];
333
334
	/* workaround for extract() reads beyond end of data */
335
	(void)memset(cp, 0, sizeof(cp));
336
	(void)memcpy(cp, c, 8);
337
338
	/* compute parity */
339
	for (p = 0, i = 0; i < 64; i += 2)
340
		p += extract(cp, i, 2);
341
342
	cp[8] = (char)p << 6;
343
344
	indices[0] = extract(cp, 0, 11);
345
	indices[1] = extract(cp, 11, 11);
346
	indices[2] = extract(cp, 22, 11);
347
	indices[3] = extract(cp, 33, 11);
348
	indices[4] = extract(cp, 44, 11);
349
	indices[5] = extract(cp, 55, 11);
350
351
	snprintf(engout, 30, "%.4s %.4s %.4s %.4s %.4s %.4s", Wp[indices[0]],
352
	    Wp[indices[1]], Wp[indices[2]], Wp[indices[3]],
353
	    Wp[indices[4]], Wp[indices[5]]);
354
355
	return(engout);
356
}
357
358
/*
359
 * Converts the 6 space-separated english words in 'e' to binary form.
360
 * The 'out' variable must be at least SKEY_BINKEY_SIZE bytes in size.
361
 * returns 1 OK - all good words and parity is OK
362
 *         0 word not in data base
363
 *        -1 badly formed in put ie > 4 char word
364
 *        -2 words OK but parity is wrong
365
 */
366
int
367
etob(char *out, char *e)
368
{
369
	char *word;
370
	int i, p, v, l, low, high;
371
	char b[SKEY_BINKEY_SIZE+1];
372
	char input[36];
373
	char *last;
374
375
	if (e == NULL)
376
		return(-1);
377
378
	(void)strlcpy(input, e, sizeof(input));
379
	(void)memset(b, 0, sizeof(b));
380
	(void)memset(out, 0, SKEY_BINKEY_SIZE);
381
	for (i = 0, p = 0; i < 6; i++, p += 11) {
382
		if ((word = strtok_r(i == 0 ? input : NULL, " ", &last)) == NULL)
383
			return(-1);
384
385
		l = strlen(word);
386
		if (l > 4 || l < 1) {
387
			return(-1);
388
		} else if (l < 4) {
389
			low = 0;
390
			high = 570;
391
		} else {
392
			low = 571;
393
			high = 2047;
394
		}
395
		standard(word);
396
397
		if ((v = wsrch(word, low, high)) < 0)
398
			return(0);
399
400
		insert(b, v, p, 11);
401
	}
402
403
	/* now check the parity of what we got */
404
	for (p = 0, i = 0; i < 64; i += 2)
405
		p += extract(b, i, 2);
406
407
	if ((p & 3) != extract(b, 64, 2))
408
		return(-2);
409
410
	(void)memcpy(out, b, SKEY_BINKEY_SIZE);
411
412
	return(1);
413
}
414
415
/*
416
 * Format 8 bytes as a series of four 16-bit hex digits.
417
 * The 'out' pointer must have at least 20 bytes for storage.
418
 */
419
char *
420
put8(char *out, char *s)
421
{
422
	(void)snprintf(out, 20, "%02X%02X %02X%02X %02X%02X %02X%02X",
423
			s[0] & 0xff, s[1] & 0xff, s[2] & 0xff,
424
			s[3] & 0xff, s[4] & 0xff, s[5] & 0xff,
425
			s[6] & 0xff, s[7] & 0xff);
426
	return(out);
427
}
428
429
/* Internal subroutines for word encoding/decoding */
430
431
/* Dictionary binary search */
432
static int
433
wsrch(char *w, int low, int high)
434
{
435
	int i, j;
436
437
	for (;;) {
438
		i = (low + high) / 2;
439
440
		if ((j = strncmp(w, Wp[i], 4)) == 0)
441
			return(i);			/* Found it */
442
443
		if (high == low + 1) {
444
			/* Avoid effects of integer truncation in /2 */
445
			if (strncmp(w, Wp[high], 4) == 0)
446
				return(high);
447
			else
448
				return(-1);
449
		}
450
451
		if (low >= high)
452
			return(-1);	/* I don't *think* this can happen... */
453
		if (j < 0)
454
			high = i;	/* Search lower half */
455
		else
456
			low = i;	/* Search upper half */
457
	}
458
}
459
460
static void
461
insert(char *s, int x, int start, int length)
462
{
463
	unsigned char cl;
464
	unsigned char cc;
465
	unsigned char cr;
466
	unsigned int y;
467
	int shift;
468
469
	assert(length <= 11);
470
	assert(start >= 0);
471
	assert(length >= 0);
472
	assert(start + length <= 66);
473
474
	shift = ((8 - ((start + length) % 8)) % 8);
475
	y = x << shift;
476
	cl = (y >> 16) & 0xff;
477
	cc = (y >> 8) & 0xff;
478
	cr = y & 0xff;
479
	if (shift + length > 16) {
480
		s[start / 8] |= cl;
481
		s[start / 8 + 1] |= cc;
482
		s[start / 8 + 2] |= cr;
483
	} else if (shift + length > 8) {
484
		s[start / 8] |= cc;
485
		s[start / 8 + 1] |= cr;
486
	} else {
487
		s[start / 8] |= cr;
488
 	}
489
}
490
491
static void
492
standard(char *word)
493
{
494
	while (*word) {
495
		if (!isascii((unsigned char)*word))
496
			break;
497
		if (islower((unsigned char)*word))
498
			*word = toupper((unsigned char)*word);
499
		if (*word == '1')
500
			*word = 'L';
501
		if (*word == '0')
502
			*word = 'O';
503
		if (*word == '5')
504
			*word = 'S';
505
		word++;
506
	}
507
}
508
509
/* Extract 'length' bits from the char array 's' starting with bit 'start' */
510
static unsigned int
511
extract(char *s, int start, int length)
512
{
513
	unsigned char cl;
514
	unsigned char cc;
515
	unsigned char cr;
516
	unsigned int x;
517
518
	assert(length <= 11);
519
	assert(start >= 0);
520
	assert(length >= 0);
521
	assert(start + length <= 66);
522
523
	cl = s[start / 8];
524
	cc = s[start / 8 + 1];
525
	cr = s[start / 8 + 2];
526
	x = ((int)(cl << 8 | cc) << 8 | cr);
527
	x = x >> (24 - (length + (start % 8)));
528
	x = (x & (0xffff >> (16 - length)));
529
530
	return(x);
531
}