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