1 /* btoe: The opiebtoe() and opieetob() library functions:
2 Conversion to/from the six-English-word representation of a
5 %%% portions-copyright-cmetz-96
6 Portions of this software are Copyright 1996-1999 by Craig Metz, All Rights
7 Reserved. The Inner Net License Version 2 applies to these portions of
9 You should have received a copy of the license with this software. If
10 you didn't get a copy, you may request one from <license@inner.net>.
12 Portions of this software are Copyright 1995 by Randall Atkinson and Dan
13 McDonald, All Rights Reserved. All Rights under this copyright are assigned
14 to the U.S. Naval Research Laboratory (NRL). The NRL Copyright Notice and
15 License Agreement applies to this software.
19 Modified by cmetz for OPIE 2.4. Use struct opie_otpkey for binary arg.
20 Modified by cmetz for OPIE 2.2. Use FUNCTION declaration et al.
21 Remove unnecessary address futzing with Wp in opiebtoe.
22 Changed unsigned long to UINT4 for Alpha.
23 Modified at NRL for OPIE 2.2. Moved from put.c to libopie/opiebtoe.c.
24 Modified at NRL for OPIE 2.0.
25 Written at Bellcore for the S/Key Version 1 software distribution.
34 static UINT4 extract __P((char *s, int start, int length));
35 static VOIDRET insert __P((char *s, int x, int start, int length));
36 static int wsrch __P((char *w, int low, int high));
38 /* Dictionary for integer-word translations */
39 static char Wp[2048][4] =
2091 /* Encode 8 bytes in 'c' as a string of English words. */
2092 char *opiebtoe FUNCTION((engout, c), char *engout AND struct opie_otpkey *c)
2094 char cp[sizeof(struct opie_otpkey) + 1]; /* add in room for the parity 2 bits */
2098 memcpy(cp, c, sizeof(struct opie_otpkey));
2099 /* compute parity */
2100 for (p = 0, i = 0; i < 64; i += 2)
2101 p += extract(cp, i, 2);
2103 cp[8] = (char)(p << 6);
2104 strncat(engout, Wp[extract(cp, 0, 11)], 4);
2105 strcat(engout, " ");
2106 strncat(engout, Wp[extract(cp, 11, 11)], 4);
2107 strcat(engout, " ");
2108 strncat(engout, Wp[extract(cp, 22, 11)], 4);
2109 strcat(engout, " ");
2110 strncat(engout, Wp[extract(cp, 33, 11)], 4);
2111 strcat(engout, " ");
2112 strncat(engout, Wp[extract(cp, 44, 11)], 4);
2113 strcat(engout, " ");
2114 strncat(engout, Wp[extract(cp, 55, 11)], 4);
2118 /* convert English to binary
2119 * returns 1 OK - all good words and parity is OK
2120 * 0 word not in data base
2121 * -1 badly formed in put ie > 4 char word
2122 * -2 words OK but parity is wrong
2124 int opieetob FUNCTION((out, e), struct opie_otpkey *out AND char *e)
2126 char *word, *c, *input, b[9];
2127 int i, p, v, l, low, high, rval = -1;
2132 if ((i = strlen(e)) > 64)
2135 if (!(input = malloc(i+1)))
2138 strncpy(input, e, i);
2140 memset(b, 0, sizeof(b));
2141 memset(out, 0, sizeof(struct opie_otpkey));
2143 for (i = 0, p = 0, word = c = input; i < 6; i++, p += 11) {
2144 while (*c && !isalpha(*c)) c++;
2159 if ((!*c) && (i != 5))
2175 if ((v = wsrch(word, low, high)) < 0) {
2179 insert(b, v, p, 11);
2182 /* now check the parity of what we got */
2183 for (p = 0, i = 0; i < 64; i += 2)
2184 p += extract(b, i, 2);
2186 if ((p & 3) != extract(b, 64, 2)) {
2191 memcpy(out, b, sizeof(struct opie_otpkey));
2200 /* Internal subroutines for word encoding/decoding */
2202 /* Dictionary binary search */
2203 static int wsrch FUNCTION((w, low, high), char *w AND int low AND int high)
2208 i = (low + high) / 2;
2209 if ((j = strncmp(w, Wp[i], 4)) == 0)
2210 return i; /* Found it */
2211 if (high == low + 1) {
2212 /* Avoid effects of integer truncation in /2 */
2213 if (strncmp(w, Wp[high], 4) == 0)
2219 return -1; /* I don't *think* this can happen... */
2221 high = i; /* Search lower half */
2223 low = i; /* Search upper half */
2227 static VOIDRET insert FUNCTION((s, x, start, length), char *s AND int x AND int start AND int length)
2235 shift = ((8 - ((start + length) % 8)) % 8);
2236 y = (long) x << shift;
2237 cl = (y >> 16) & 0xff;
2238 cc = (y >> 8) & 0xff;
2240 if (shift + length > 16) {
2242 s[start / 8 + 1] |= cc;
2243 s[start / 8 + 2] |= cr;
2245 if (shift + length > 8) {
2247 s[start / 8 + 1] |= cr;
2253 static UINT4 extract FUNCTION((s, start, length), char *s AND int start AND int length)
2261 cc = s[start / 8 + 1];
2262 cr = s[start / 8 + 2];
2263 x = ((UINT4) (cl << 8 | cc) << 8 | cr);
2264 x = x >> (24 - (length + (start % 8)));
2265 x = (x & (0xffff >> (16 - length)));