1 /* -----------------------------------------------------------------------
2 *
3 * umac.c -- C Implementation UMAC Message Authentication
4 *
5 * Version 0.93b of rfc4418.txt -- 2006 July 18
6 *
7 * For a full description of UMAC message authentication see the UMAC
8 * world-wide-web page at http://www.cs.ucdavis.edu/~rogaway/umac
9 * Please report bugs and suggestions to the UMAC webpage.
10 *
11 * Copyright (c) 1999-2006 Ted Krovetz
12 *
13 * Permission to use, copy, modify, and distribute this software and
14 * its documentation for any purpose and with or without fee, is hereby
15 * granted provided that the above copyright notice appears in all copies
16 * and in supporting documentation, and that the name of the copyright
17 * holder not be used in advertising or publicity pertaining to
18 * distribution of the software without specific, written prior permission.
19 *
20 * Comments should be directed to Ted Krovetz (tdk@acm.org)
21 *
22 * ---------------------------------------------------------------------- */
23
24 /* ////////////////////// IMPORTANT NOTES /////////////////////////////////
25 *
26 * 1) This version does not work properly on messages larger than 16MB
27 *
28 * 2) If you set the switch to use SSE2, then all data must be 16-byte
29 * aligned
30 *
31 * 3) When calling the function umac(), it is assumed that msg is in
32 * a writable buffer of length divisible by 32 bytes. The message itself
33 * does not have to fill the entire buffer, but bytes beyond msg may be
34 * zeroed.
35 *
36 * 4) Three free AES implementations are supported by this implementation of
37 * UMAC. Paulo Barreto's version is in the public domain and can be found
38 * at http://www.esat.kuleuven.ac.be/~rijmen/rijndael/ (search for
39 * "Barreto"). The only two files needed are rijndael-alg-fst.c and
40 * rijndael-alg-fst.h. Brian Gladman's version is distributed with the GNU
41 * Public Licence at http://fp.gladman.plus.com/AES/index.htm. It
42 * includes a fast IA-32 assembly version. The OpenSSL crypo library is
43 * the third.
44 *
45 * 5) With FORCE_C_ONLY flags set to 0, incorrect results are sometimes
46 * produced under gcc with optimizations set -O3 or higher. Dunno why.
47 *
48 /////////////////////////////////////////////////////////////////////// */
49
50 /* ---------------------------------------------------------------------- */
51 /* --- User Switches ---------------------------------------------------- */
52 /* ---------------------------------------------------------------------- */
53
54 #ifndef UMAC_OUTPUT_LEN
55 # define UMAC_OUTPUT_LEN 8 /* Alowable: 4, 8, 12, 16 */
56 #endif
57
58 #if UMAC_OUTPUT_LEN != 4 && UMAC_OUTPUT_LEN != 8 && \
59 UMAC_OUTPUT_LEN != 12 && UMAC_OUTPUT_LEN != 16
60 # error UMAC_OUTPUT_LEN must be defined to 4, 8, 12 or 16
61 #endif
62
63 /* #define FORCE_C_ONLY 1 ANSI C and 64-bit integers req'd */
64 /* #define AES_IMPLEMENTAION 1 1 = OpenSSL, 2 = Barreto, 3 = Gladman */
65 /* #define SSE2 0 Is SSE2 is available? */
66 /* #define RUN_TESTS 0 Run basic correctness/speed tests */
67 /* #define UMAC_AE_SUPPORT 0 Enable auhthenticated encryption */
68
69 /* ---------------------------------------------------------------------- */
70 /* -- Global Includes --------------------------------------------------- */
71 /* ---------------------------------------------------------------------- */
72
73 #include "mod_sftp.h"
74 #include "umac.h"
75 #include <string.h>
76 #include <stdlib.h>
77 #include <stddef.h>
78
79 #if OPENSSL_VERSION_NUMBER > 0x000907000L
80
81 /* ---------------------------------------------------------------------- */
82 /* --- Primitive Data Types --- */
83 /* ---------------------------------------------------------------------- */
84
85 /* The following assumptions may need change on your system */
86 typedef uint8_t UINT8; /* 1 byte */
87 typedef uint16_t UINT16; /* 2 byte */
88 typedef uint32_t UINT32; /* 4 byte */
89 typedef uint64_t UINT64; /* 8 bytes */
90 typedef unsigned int UWORD; /* Register */
91
92 /* ---------------------------------------------------------------------- */
93 /* --- Constants -------------------------------------------------------- */
94 /* ---------------------------------------------------------------------- */
95
96 #define UMAC_KEY_LEN 16 /* UMAC takes 16 bytes of external key */
97
98 /* Message "words" are read from memory in an endian-specific manner. */
99 /* For this implementation to behave correctly, __LITTLE_ENDIAN__ must */
100 /* be set true if the host computer is little-endian. */
101
102 #if BYTE_ORDER == LITTLE_ENDIAN
103 #define __LITTLE_ENDIAN__ 1
104 #else
105 #define __LITTLE_ENDIAN__ 0
106 #endif
107
108 /* ---------------------------------------------------------------------- */
109 /* ---------------------------------------------------------------------- */
110 /* ----- Architecture Specific ------------------------------------------ */
111 /* ---------------------------------------------------------------------- */
112 /* ---------------------------------------------------------------------- */
113
114
115 /* ---------------------------------------------------------------------- */
116 /* ---------------------------------------------------------------------- */
117 /* ----- Primitive Routines --------------------------------------------- */
118 /* ---------------------------------------------------------------------- */
119 /* ---------------------------------------------------------------------- */
120
121
122 /* ---------------------------------------------------------------------- */
123 /* --- 32-bit by 32-bit to 64-bit Multiplication ------------------------ */
124 /* ---------------------------------------------------------------------- */
125
126 #define MUL64(a,b) ((UINT64)((UINT64)(UINT32)(a) * (UINT64)(UINT32)(b)))
127
128 /* ---------------------------------------------------------------------- */
129 /* --- Endian Conversion --- Forcing assembly on some platforms */
130 /* ---------------------------------------------------------------------- */
131
132 #if defined(HAVE_SWAP32)
133 #define LOAD_UINT32_REVERSED(p) (swap32(*(UINT32 *)(p)))
134 #define STORE_UINT32_REVERSED(p,v) (*(UINT32 *)(p) = swap32(v))
135 #else /* HAVE_SWAP32 */
136
LOAD_UINT32_REVERSED(void * ptr)137 static UINT32 LOAD_UINT32_REVERSED(void *ptr)
138 {
139 UINT32 temp = *(UINT32 *)ptr;
140 temp = (temp >> 24) | ((temp & 0x00FF0000) >> 8 )
141 | ((temp & 0x0000FF00) << 8 ) | (temp << 24);
142 return (UINT32)temp;
143 }
144
145 # if (__LITTLE_ENDIAN__)
STORE_UINT32_REVERSED(void * ptr,UINT32 x)146 static void STORE_UINT32_REVERSED(void *ptr, UINT32 x)
147 {
148 UINT32 i = (UINT32)x;
149 *(UINT32 *)ptr = (i >> 24) | ((i & 0x00FF0000) >> 8 )
150 | ((i & 0x0000FF00) << 8 ) | (i << 24);
151 }
152 # endif /* __LITTLE_ENDIAN */
153 #endif /* HAVE_SWAP32 */
154
155 /* The following definitions use the above reversal-primitives to do the right
156 * thing on endian specific load and stores.
157 */
158
159 #if (__LITTLE_ENDIAN__)
160 #define LOAD_UINT32_LITTLE(ptr) (*(UINT32 *)(ptr))
161 #define STORE_UINT32_BIG(ptr,x) STORE_UINT32_REVERSED(ptr,x)
162 #else
163 #define LOAD_UINT32_LITTLE(ptr) LOAD_UINT32_REVERSED(ptr)
164 #define STORE_UINT32_BIG(ptr,x) (*(UINT32 *)(ptr) = (UINT32)(x))
165 #endif
166
167 /* ---------------------------------------------------------------------- */
168 /* ---------------------------------------------------------------------- */
169 /* ----- Begin KDF & PDF Section ---------------------------------------- */
170 /* ---------------------------------------------------------------------- */
171 /* ---------------------------------------------------------------------- */
172
173 /* UMAC uses AES with 16 byte block and key lengths */
174 #define AES_BLOCK_LEN 16
175
176 /* OpenSSL's AES */
177 typedef AES_KEY aes_int_key[1];
178 #define aes_encryption(in,out,int_key) \
179 AES_encrypt((unsigned char *)(in),(unsigned char *)(out),(AES_KEY *)int_key)
180 #define aes_key_setup(key,int_key) \
181 AES_set_encrypt_key((unsigned char *)(key),UMAC_KEY_LEN*8,int_key)
182
183 /* The user-supplied UMAC key is stretched using AES in a counter
184 * mode to supply all random bits needed by UMAC. The kdf function takes
185 * an AES internal key representation 'key' and writes a stream of
186 * 'nbytes' bytes to the memory pointed at by 'bufp'. Each distinct
187 * 'ndx' causes a distinct byte stream.
188 */
kdf(void * bufp,aes_int_key key,UINT8 ndx,int nbytes)189 static void kdf(void *bufp, aes_int_key key, UINT8 ndx, int nbytes)
190 {
191 UINT8 in_buf[AES_BLOCK_LEN] = {0};
192 UINT8 out_buf[AES_BLOCK_LEN];
193 UINT8 *dst_buf = (UINT8 *)bufp;
194 int i;
195
196 /* Setup the initial value */
197 in_buf[AES_BLOCK_LEN-9] = ndx;
198 in_buf[AES_BLOCK_LEN-1] = i = 1;
199
200 while (nbytes >= AES_BLOCK_LEN) {
201 aes_encryption(in_buf, out_buf, key);
202 memcpy(dst_buf,out_buf,AES_BLOCK_LEN);
203 in_buf[AES_BLOCK_LEN-1] = ++i;
204 nbytes -= AES_BLOCK_LEN;
205 dst_buf += AES_BLOCK_LEN;
206 }
207 if (nbytes) {
208 aes_encryption(in_buf, out_buf, key);
209 memcpy(dst_buf,out_buf,nbytes);
210 }
211 }
212
213 /* The final UHASH result is XOR'd with the output of a pseudorandom
214 * function. Here, we use AES to generate random output and
215 * xor the appropriate bytes depending on the last bits of nonce.
216 * This scheme is optimized for sequential, increasing big-endian nonces.
217 */
218
219 typedef struct {
220 UINT8 cache[AES_BLOCK_LEN]; /* Previous AES output is saved */
221 UINT8 nonce[AES_BLOCK_LEN]; /* The AES input making above cache */
222 aes_int_key prf_key; /* Expanded AES key for PDF */
223 } pdf_ctx;
224
pdf_init(pdf_ctx * pc,aes_int_key prf_key)225 static void pdf_init(pdf_ctx *pc, aes_int_key prf_key)
226 {
227 UINT8 buf[UMAC_KEY_LEN];
228
229 kdf(buf, prf_key, 0, UMAC_KEY_LEN);
230 aes_key_setup(buf, pc->prf_key);
231
232 /* Initialize pdf and cache */
233 memset(pc->nonce, 0, sizeof(pc->nonce));
234 aes_encryption(pc->nonce, pc->cache, pc->prf_key);
235 }
236
pdf_gen_xor(pdf_ctx * pc,UINT8 nonce[8],UINT8 buf[8])237 static void pdf_gen_xor(pdf_ctx *pc, UINT8 nonce[8], UINT8 buf[8])
238 {
239 /* 'ndx' indicates that we'll be using the 0th or 1st eight bytes
240 * of the AES output. If last time around we returned the ndx-1st
241 * element, then we may have the result in the cache already.
242 */
243
244 #if (UMAC_OUTPUT_LEN == 4)
245 #define LOW_BIT_MASK 3
246 #elif (UMAC_OUTPUT_LEN == 8)
247 #define LOW_BIT_MASK 1
248 #elif (UMAC_OUTPUT_LEN > 8)
249 #define LOW_BIT_MASK 0
250 #endif
251
252 UINT8 tmp_nonce_lo[4];
253 #if LOW_BIT_MASK != 0
254 int ndx = nonce[7] & LOW_BIT_MASK;
255 #endif
256 memcpy(tmp_nonce_lo, &(nonce[4]), sizeof(UINT32));
257 tmp_nonce_lo[3] &= ~LOW_BIT_MASK; /* zero last bit */
258
259 /* ProFTPD Note: We've changed the original code where, which used explicit
260 * typecasting to treat the nonce[8] as a UINT32, to memcpy(3)/memcmp(3),
261 * to avoid strict aliasing gcc warnings when -O2 or higher is used.
262 */
263
264 if ( (memcmp(tmp_nonce_lo, &(pc->nonce[4]), sizeof(UINT32)) != 0) ||
265 (memcmp(nonce, pc->nonce, sizeof(UINT32)) != 0) )
266 {
267 memmove(pc->nonce, nonce, sizeof(UINT32));
268 memmove(&(pc->nonce[4]), tmp_nonce_lo, sizeof(UINT32));
269 aes_encryption(pc->nonce, pc->cache, pc->prf_key);
270 }
271
272 #if (UMAC_OUTPUT_LEN == 4)
273 *((UINT32 *)buf) ^= ((UINT32 *)pc->cache)[ndx];
274 #elif (UMAC_OUTPUT_LEN == 8)
275 *((UINT64 *)buf) ^= ((UINT64 *)pc->cache)[ndx];
276 #elif (UMAC_OUTPUT_LEN == 12)
277 ((UINT64 *)buf)[0] ^= ((UINT64 *)pc->cache)[0];
278 ((UINT32 *)buf)[2] ^= ((UINT32 *)pc->cache)[2];
279 #elif (UMAC_OUTPUT_LEN == 16)
280 ((UINT64 *)buf)[0] ^= ((UINT64 *)pc->cache)[0];
281 ((UINT64 *)buf)[1] ^= ((UINT64 *)pc->cache)[1];
282 #endif
283 }
284
285 /* ---------------------------------------------------------------------- */
286 /* ---------------------------------------------------------------------- */
287 /* ----- Begin NH Hash Section ------------------------------------------ */
288 /* ---------------------------------------------------------------------- */
289 /* ---------------------------------------------------------------------- */
290
291 /* The NH-based hash functions used in UMAC are described in the UMAC paper
292 * and specification, both of which can be found at the UMAC website.
293 * The interface to this implementation has two
294 * versions, one expects the entire message being hashed to be passed
295 * in a single buffer and returns the hash result immediately. The second
296 * allows the message to be passed in a sequence of buffers. In the
297 * muliple-buffer interface, the client calls the routine nh_update() as
298 * many times as necessary. When there is no more data to be fed to the
299 * hash, the client calls nh_final() which calculates the hash output.
300 * Before beginning another hash calculation the nh_reset() routine
301 * must be called. The single-buffer routine, nh(), is equivalent to
302 * the sequence of calls nh_update() and nh_final(); however it is
303 * optimized and should be preferred whenever the multiple-buffer interface
304 * is not necessary. When using either interface, it is the client's
305 * responsibility to pass no more than L1_KEY_LEN bytes per hash result.
306 *
307 * The routine nh_init() initializes the nh_ctx data structure and
308 * must be called once, before any other PDF routine.
309 */
310
311 /* The "nh_aux" routines do the actual NH hashing work. They
312 * expect buffers to be multiples of L1_PAD_BOUNDARY. These routines
313 * produce output for all STREAMS NH iterations in one call,
314 * allowing the parallel implementation of the streams.
315 */
316
317 #define STREAMS (UMAC_OUTPUT_LEN / 4) /* Number of times hash is applied */
318 #define L1_KEY_LEN 1024 /* Internal key bytes */
319 #define L1_KEY_SHIFT 16 /* Toeplitz key shift between streams */
320 #define L1_PAD_BOUNDARY 32 /* pad message to boundary multiple */
321 #define ALLOC_BOUNDARY 16 /* Keep buffers aligned to this */
322 #define HASH_BUF_BYTES 64 /* nh_aux_hb buffer multiple */
323
324 typedef struct {
325 UINT8 nh_key [L1_KEY_LEN + L1_KEY_SHIFT * (STREAMS - 1)]; /* NH Key */
326 UINT8 data [HASH_BUF_BYTES]; /* Incoming data buffer */
327 int next_data_empty; /* Bookkeeping variable for data buffer. */
328 int bytes_hashed; /* Bytes (out of L1_KEY_LEN) incorporated. */
329 UINT64 state[STREAMS]; /* on-line state */
330 } nh_ctx;
331
332
333 #if (UMAC_OUTPUT_LEN == 4)
334
nh_aux(void * kp,void * dp,void * hp,UINT32 dlen)335 static void nh_aux(void *kp, void *dp, void *hp, UINT32 dlen)
336 /* NH hashing primitive. Previous (partial) hash result is loaded and
337 * then stored via hp pointer. The length of the data pointed at by "dp",
338 * "dlen", is guaranteed to be divisible by L1_PAD_BOUNDARY (32). Key
339 * is expected to be endian compensated in memory at key setup.
340 */
341 {
342 UINT64 h;
343 UWORD c = dlen / 32;
344 UINT32 *k = (UINT32 *)kp;
345 UINT32 *d = (UINT32 *)dp;
346 UINT32 d0,d1,d2,d3,d4,d5,d6,d7;
347 UINT32 k0,k1,k2,k3,k4,k5,k6,k7;
348
349 h = *((UINT64 *)hp);
350 do {
351 d0 = LOAD_UINT32_LITTLE(d+0); d1 = LOAD_UINT32_LITTLE(d+1);
352 d2 = LOAD_UINT32_LITTLE(d+2); d3 = LOAD_UINT32_LITTLE(d+3);
353 d4 = LOAD_UINT32_LITTLE(d+4); d5 = LOAD_UINT32_LITTLE(d+5);
354 d6 = LOAD_UINT32_LITTLE(d+6); d7 = LOAD_UINT32_LITTLE(d+7);
355 k0 = *(k+0); k1 = *(k+1); k2 = *(k+2); k3 = *(k+3);
356 k4 = *(k+4); k5 = *(k+5); k6 = *(k+6); k7 = *(k+7);
357 h += MUL64((k0 + d0), (k4 + d4));
358 h += MUL64((k1 + d1), (k5 + d5));
359 h += MUL64((k2 + d2), (k6 + d6));
360 h += MUL64((k3 + d3), (k7 + d7));
361
362 d += 8;
363 k += 8;
364 } while (--c);
365 *((UINT64 *)hp) = h;
366 }
367
368 #elif (UMAC_OUTPUT_LEN == 8)
369
nh_aux(void * kp,void * dp,void * hp,UINT32 dlen)370 static void nh_aux(void *kp, void *dp, void *hp, UINT32 dlen)
371 /* Same as previous nh_aux, but two streams are handled in one pass,
372 * reading and writing 16 bytes of hash-state per call.
373 */
374 {
375 UINT64 h1,h2;
376 UWORD c = dlen / 32;
377 UINT32 *k = (UINT32 *)kp;
378 UINT32 *d = (UINT32 *)dp;
379 UINT32 d0,d1,d2,d3,d4,d5,d6,d7;
380 UINT32 k0,k1,k2,k3,k4,k5,k6,k7,
381 k8,k9,k10,k11;
382
383 h1 = *((UINT64 *)hp);
384 h2 = *((UINT64 *)hp + 1);
385 k0 = *(k+0); k1 = *(k+1); k2 = *(k+2); k3 = *(k+3);
386 do {
387 d0 = LOAD_UINT32_LITTLE(d+0); d1 = LOAD_UINT32_LITTLE(d+1);
388 d2 = LOAD_UINT32_LITTLE(d+2); d3 = LOAD_UINT32_LITTLE(d+3);
389 d4 = LOAD_UINT32_LITTLE(d+4); d5 = LOAD_UINT32_LITTLE(d+5);
390 d6 = LOAD_UINT32_LITTLE(d+6); d7 = LOAD_UINT32_LITTLE(d+7);
391 k4 = *(k+4); k5 = *(k+5); k6 = *(k+6); k7 = *(k+7);
392 k8 = *(k+8); k9 = *(k+9); k10 = *(k+10); k11 = *(k+11);
393
394 h1 += MUL64((k0 + d0), (k4 + d4));
395 h2 += MUL64((k4 + d0), (k8 + d4));
396
397 h1 += MUL64((k1 + d1), (k5 + d5));
398 h2 += MUL64((k5 + d1), (k9 + d5));
399
400 h1 += MUL64((k2 + d2), (k6 + d6));
401 h2 += MUL64((k6 + d2), (k10 + d6));
402
403 h1 += MUL64((k3 + d3), (k7 + d7));
404 h2 += MUL64((k7 + d3), (k11 + d7));
405
406 k0 = k8; k1 = k9; k2 = k10; k3 = k11;
407
408 d += 8;
409 k += 8;
410 } while (--c);
411 ((UINT64 *)hp)[0] = h1;
412 ((UINT64 *)hp)[1] = h2;
413 }
414
415 #elif (UMAC_OUTPUT_LEN == 12)
416
nh_aux(void * kp,void * dp,void * hp,UINT32 dlen)417 static void nh_aux(void *kp, void *dp, void *hp, UINT32 dlen)
418 /* Same as previous nh_aux, but two streams are handled in one pass,
419 * reading and writing 24 bytes of hash-state per call.
420 */
421 {
422 UINT64 h1,h2,h3;
423 UWORD c = dlen / 32;
424 UINT32 *k = (UINT32 *)kp;
425 UINT32 *d = (UINT32 *)dp;
426 UINT32 d0,d1,d2,d3,d4,d5,d6,d7;
427 UINT32 k0,k1,k2,k3,k4,k5,k6,k7,
428 k8,k9,k10,k11,k12,k13,k14,k15;
429
430 h1 = *((UINT64 *)hp);
431 h2 = *((UINT64 *)hp + 1);
432 h3 = *((UINT64 *)hp + 2);
433 k0 = *(k+0); k1 = *(k+1); k2 = *(k+2); k3 = *(k+3);
434 k4 = *(k+4); k5 = *(k+5); k6 = *(k+6); k7 = *(k+7);
435 do {
436 d0 = LOAD_UINT32_LITTLE(d+0); d1 = LOAD_UINT32_LITTLE(d+1);
437 d2 = LOAD_UINT32_LITTLE(d+2); d3 = LOAD_UINT32_LITTLE(d+3);
438 d4 = LOAD_UINT32_LITTLE(d+4); d5 = LOAD_UINT32_LITTLE(d+5);
439 d6 = LOAD_UINT32_LITTLE(d+6); d7 = LOAD_UINT32_LITTLE(d+7);
440 k8 = *(k+8); k9 = *(k+9); k10 = *(k+10); k11 = *(k+11);
441 k12 = *(k+12); k13 = *(k+13); k14 = *(k+14); k15 = *(k+15);
442
443 h1 += MUL64((k0 + d0), (k4 + d4));
444 h2 += MUL64((k4 + d0), (k8 + d4));
445 h3 += MUL64((k8 + d0), (k12 + d4));
446
447 h1 += MUL64((k1 + d1), (k5 + d5));
448 h2 += MUL64((k5 + d1), (k9 + d5));
449 h3 += MUL64((k9 + d1), (k13 + d5));
450
451 h1 += MUL64((k2 + d2), (k6 + d6));
452 h2 += MUL64((k6 + d2), (k10 + d6));
453 h3 += MUL64((k10 + d2), (k14 + d6));
454
455 h1 += MUL64((k3 + d3), (k7 + d7));
456 h2 += MUL64((k7 + d3), (k11 + d7));
457 h3 += MUL64((k11 + d3), (k15 + d7));
458
459 k0 = k8; k1 = k9; k2 = k10; k3 = k11;
460 k4 = k12; k5 = k13; k6 = k14; k7 = k15;
461
462 d += 8;
463 k += 8;
464 } while (--c);
465 ((UINT64 *)hp)[0] = h1;
466 ((UINT64 *)hp)[1] = h2;
467 ((UINT64 *)hp)[2] = h3;
468 }
469
470 #elif (UMAC_OUTPUT_LEN == 16)
471
nh_aux(void * kp,void * dp,void * hp,UINT32 dlen)472 static void nh_aux(void *kp, void *dp, void *hp, UINT32 dlen)
473 /* Same as previous nh_aux, but two streams are handled in one pass,
474 * reading and writing 24 bytes of hash-state per call.
475 */
476 {
477 UINT64 h1,h2,h3,h4;
478 UWORD c = dlen / 32;
479 UINT32 *k = (UINT32 *)kp;
480 UINT32 *d = (UINT32 *)dp;
481 UINT32 d0,d1,d2,d3,d4,d5,d6,d7;
482 UINT32 k0,k1,k2,k3,k4,k5,k6,k7,
483 k8,k9,k10,k11,k12,k13,k14,k15,
484 k16,k17,k18,k19;
485
486 h1 = *((UINT64 *)hp);
487 h2 = *((UINT64 *)hp + 1);
488 h3 = *((UINT64 *)hp + 2);
489 h4 = *((UINT64 *)hp + 3);
490 k0 = *(k+0); k1 = *(k+1); k2 = *(k+2); k3 = *(k+3);
491 k4 = *(k+4); k5 = *(k+5); k6 = *(k+6); k7 = *(k+7);
492 do {
493 d0 = LOAD_UINT32_LITTLE(d+0); d1 = LOAD_UINT32_LITTLE(d+1);
494 d2 = LOAD_UINT32_LITTLE(d+2); d3 = LOAD_UINT32_LITTLE(d+3);
495 d4 = LOAD_UINT32_LITTLE(d+4); d5 = LOAD_UINT32_LITTLE(d+5);
496 d6 = LOAD_UINT32_LITTLE(d+6); d7 = LOAD_UINT32_LITTLE(d+7);
497 k8 = *(k+8); k9 = *(k+9); k10 = *(k+10); k11 = *(k+11);
498 k12 = *(k+12); k13 = *(k+13); k14 = *(k+14); k15 = *(k+15);
499 k16 = *(k+16); k17 = *(k+17); k18 = *(k+18); k19 = *(k+19);
500
501 h1 += MUL64((k0 + d0), (k4 + d4));
502 h2 += MUL64((k4 + d0), (k8 + d4));
503 h3 += MUL64((k8 + d0), (k12 + d4));
504 h4 += MUL64((k12 + d0), (k16 + d4));
505
506 h1 += MUL64((k1 + d1), (k5 + d5));
507 h2 += MUL64((k5 + d1), (k9 + d5));
508 h3 += MUL64((k9 + d1), (k13 + d5));
509 h4 += MUL64((k13 + d1), (k17 + d5));
510
511 h1 += MUL64((k2 + d2), (k6 + d6));
512 h2 += MUL64((k6 + d2), (k10 + d6));
513 h3 += MUL64((k10 + d2), (k14 + d6));
514 h4 += MUL64((k14 + d2), (k18 + d6));
515
516 h1 += MUL64((k3 + d3), (k7 + d7));
517 h2 += MUL64((k7 + d3), (k11 + d7));
518 h3 += MUL64((k11 + d3), (k15 + d7));
519 h4 += MUL64((k15 + d3), (k19 + d7));
520
521 k0 = k8; k1 = k9; k2 = k10; k3 = k11;
522 k4 = k12; k5 = k13; k6 = k14; k7 = k15;
523 k8 = k16; k9 = k17; k10 = k18; k11 = k19;
524
525 d += 8;
526 k += 8;
527 } while (--c);
528 ((UINT64 *)hp)[0] = h1;
529 ((UINT64 *)hp)[1] = h2;
530 ((UINT64 *)hp)[2] = h3;
531 ((UINT64 *)hp)[3] = h4;
532 }
533
534 /* ---------------------------------------------------------------------- */
535 #endif /* UMAC_OUTPUT_LENGTH */
536 /* ---------------------------------------------------------------------- */
537
538
539 /* ---------------------------------------------------------------------- */
540
nh_transform(nh_ctx * hc,UINT8 * buf,UINT32 nbytes)541 static void nh_transform(nh_ctx *hc, UINT8 *buf, UINT32 nbytes)
542 /* This function is a wrapper for the primitive NH hash functions. It takes
543 * as argument "hc" the current hash context and a buffer which must be a
544 * multiple of L1_PAD_BOUNDARY. The key passed to nh_aux is offset
545 * appropriately according to how much message has been hashed already.
546 */
547 {
548 UINT8 *key;
549
550 key = hc->nh_key + hc->bytes_hashed;
551 nh_aux(key, buf, hc->state, nbytes);
552 }
553
554 /* ---------------------------------------------------------------------- */
555
556 #if (__LITTLE_ENDIAN__)
endian_convert(void * buf,UWORD bpw,UINT32 num_bytes)557 static void endian_convert(void *buf, UWORD bpw, UINT32 num_bytes)
558 /* We endian convert the keys on little-endian computers to */
559 /* compensate for the lack of big-endian memory reads during hashing. */
560 {
561 UWORD iters = num_bytes / bpw;
562 if (bpw == 4) {
563 UINT32 *p = (UINT32 *)buf;
564 do {
565 *p = LOAD_UINT32_REVERSED(p);
566 p++;
567 } while (--iters);
568 } else if (bpw == 8) {
569 UINT32 *p = (UINT32 *)buf;
570 UINT32 t;
571 do {
572 t = LOAD_UINT32_REVERSED(p+1);
573 p[1] = LOAD_UINT32_REVERSED(p);
574 p[0] = t;
575 p += 2;
576 } while (--iters);
577 }
578 }
579 #define endian_convert_if_le(x,y,z) endian_convert((x),(y),(z))
580 #else
581 #define endian_convert_if_le(x,y,z) do{}while(0) /* Do nothing */
582 #endif
583
584 /* ---------------------------------------------------------------------- */
585
nh_reset(nh_ctx * hc)586 static void nh_reset(nh_ctx *hc)
587 /* Reset nh_ctx to ready for hashing of new data */
588 {
589 hc->bytes_hashed = 0;
590 hc->next_data_empty = 0;
591 hc->state[0] = 0;
592 #if (UMAC_OUTPUT_LEN >= 8)
593 hc->state[1] = 0;
594 #endif
595 #if (UMAC_OUTPUT_LEN >= 12)
596 hc->state[2] = 0;
597 #endif
598 #if (UMAC_OUTPUT_LEN == 16)
599 hc->state[3] = 0;
600 #endif
601
602 }
603
604 /* ---------------------------------------------------------------------- */
605
nh_init(nh_ctx * hc,aes_int_key prf_key)606 static void nh_init(nh_ctx *hc, aes_int_key prf_key)
607 /* Generate nh_key, endian convert and reset to be ready for hashing. */
608 {
609 kdf(hc->nh_key, prf_key, 1, sizeof(hc->nh_key));
610 endian_convert_if_le(hc->nh_key, 4, sizeof(hc->nh_key));
611 nh_reset(hc);
612 }
613
614 /* ---------------------------------------------------------------------- */
615
nh_update(nh_ctx * hc,UINT8 * buf,UINT32 nbytes)616 static void nh_update(nh_ctx *hc, UINT8 *buf, UINT32 nbytes)
617 /* Incorporate nbytes of data into a nh_ctx, buffer whatever is not an */
618 /* even multiple of HASH_BUF_BYTES. */
619 {
620 UINT32 i,j;
621
622 j = hc->next_data_empty;
623 if ((j + nbytes) >= HASH_BUF_BYTES) {
624 if (j) {
625 i = HASH_BUF_BYTES - j;
626 memcpy(hc->data+j, buf, i);
627 nh_transform(hc,hc->data,HASH_BUF_BYTES);
628 nbytes -= i;
629 buf += i;
630 hc->bytes_hashed += HASH_BUF_BYTES;
631 }
632 if (nbytes >= HASH_BUF_BYTES) {
633 i = nbytes & ~(HASH_BUF_BYTES - 1);
634 nh_transform(hc, buf, i);
635 nbytes -= i;
636 buf += i;
637 hc->bytes_hashed += i;
638 }
639 j = 0;
640 }
641 memcpy(hc->data + j, buf, nbytes);
642 hc->next_data_empty = j + nbytes;
643 }
644
645 /* ---------------------------------------------------------------------- */
646
zero_pad(UINT8 * p,int nbytes)647 static void zero_pad(UINT8 *p, int nbytes)
648 {
649 /* Write "nbytes" of zeroes, beginning at "p" */
650 if (nbytes >= (int)sizeof(UWORD)) {
651 while ((ptrdiff_t)p % sizeof(UWORD)) {
652 *p = 0;
653 nbytes--;
654 p++;
655 }
656 while (nbytes >= (int)sizeof(UWORD)) {
657 *(UWORD *)p = 0;
658 nbytes -= sizeof(UWORD);
659 p += sizeof(UWORD);
660 }
661 }
662 while (nbytes) {
663 *p = 0;
664 nbytes--;
665 p++;
666 }
667 }
668
669 /* ---------------------------------------------------------------------- */
670
nh_final(nh_ctx * hc,UINT8 * result)671 static void nh_final(nh_ctx *hc, UINT8 *result)
672 /* After passing some number of data buffers to nh_update() for integration
673 * into an NH context, nh_final is called to produce a hash result. If any
674 * bytes are in the buffer hc->data, incorporate them into the
675 * NH context. Finally, add into the NH accumulation "state" the total number
676 * of bits hashed. The resulting numbers are written to the buffer "result".
677 * If nh_update was never called, L1_PAD_BOUNDARY zeroes are incorporated.
678 */
679 {
680 int nh_len, nbits;
681
682 if (hc->next_data_empty != 0) {
683 nh_len = ((hc->next_data_empty + (L1_PAD_BOUNDARY - 1)) &
684 ~(L1_PAD_BOUNDARY - 1));
685 zero_pad(hc->data + hc->next_data_empty,
686 nh_len - hc->next_data_empty);
687 nh_transform(hc, hc->data, nh_len);
688 hc->bytes_hashed += hc->next_data_empty;
689 } else if (hc->bytes_hashed == 0) {
690 nh_len = L1_PAD_BOUNDARY;
691 zero_pad(hc->data, L1_PAD_BOUNDARY);
692 nh_transform(hc, hc->data, nh_len);
693 }
694
695 nbits = (hc->bytes_hashed << 3);
696 ((UINT64 *)result)[0] = ((UINT64 *)hc->state)[0] + nbits;
697 #if (UMAC_OUTPUT_LEN >= 8)
698 ((UINT64 *)result)[1] = ((UINT64 *)hc->state)[1] + nbits;
699 #endif
700 #if (UMAC_OUTPUT_LEN >= 12)
701 ((UINT64 *)result)[2] = ((UINT64 *)hc->state)[2] + nbits;
702 #endif
703 #if (UMAC_OUTPUT_LEN == 16)
704 ((UINT64 *)result)[3] = ((UINT64 *)hc->state)[3] + nbits;
705 #endif
706 nh_reset(hc);
707 }
708
709 /* ---------------------------------------------------------------------- */
710
nh(nh_ctx * hc,UINT8 * buf,UINT32 padded_len,UINT32 unpadded_len,UINT8 * result)711 static void nh(nh_ctx *hc, UINT8 *buf, UINT32 padded_len,
712 UINT32 unpadded_len, UINT8 *result)
713 /* All-in-one nh_update() and nh_final() equivalent.
714 * Assumes that padded_len is divisible by L1_PAD_BOUNDARY and result is
715 * well aligned
716 */
717 {
718 UINT32 nbits;
719
720 /* Initialize the hash state */
721 nbits = (unpadded_len << 3);
722
723 ((UINT64 *)result)[0] = nbits;
724 #if (UMAC_OUTPUT_LEN >= 8)
725 ((UINT64 *)result)[1] = nbits;
726 #endif
727 #if (UMAC_OUTPUT_LEN >= 12)
728 ((UINT64 *)result)[2] = nbits;
729 #endif
730 #if (UMAC_OUTPUT_LEN == 16)
731 ((UINT64 *)result)[3] = nbits;
732 #endif
733
734 nh_aux(hc->nh_key, buf, result, padded_len);
735 }
736
737 /* ---------------------------------------------------------------------- */
738 /* ---------------------------------------------------------------------- */
739 /* ----- Begin UHASH Section -------------------------------------------- */
740 /* ---------------------------------------------------------------------- */
741 /* ---------------------------------------------------------------------- */
742
743 /* UHASH is a multi-layered algorithm. Data presented to UHASH is first
744 * hashed by NH. The NH output is then hashed by a polynomial-hash layer
745 * unless the initial data to be hashed is short. After the polynomial-
746 * layer, an inner-product hash is used to produce the final UHASH output.
747 *
748 * UHASH provides two interfaces, one all-at-once and another where data
749 * buffers are presented sequentially. In the sequential interface, the
750 * UHASH client calls the routine uhash_update() as many times as necessary.
751 * When there is no more data to be fed to UHASH, the client calls
752 * uhash_final() which
753 * calculates the UHASH output. Before beginning another UHASH calculation
754 * the uhash_reset() routine must be called. The all-at-once UHASH routine,
755 * uhash(), is equivalent to the sequence of calls uhash_update() and
756 * uhash_final(); however it is optimized and should be
757 * used whenever the sequential interface is not necessary.
758 *
759 * The routine uhash_init() initializes the uhash_ctx data structure and
760 * must be called once, before any other UHASH routine.
761 */
762
763 /* ---------------------------------------------------------------------- */
764 /* ----- Constants and uhash_ctx ---------------------------------------- */
765 /* ---------------------------------------------------------------------- */
766
767 /* ---------------------------------------------------------------------- */
768 /* ----- Poly hash and Inner-Product hash Constants --------------------- */
769 /* ---------------------------------------------------------------------- */
770
771 /* Primes and masks */
772 #define p36 ((UINT64)0x0000000FFFFFFFFBull) /* 2^36 - 5 */
773 #define p64 ((UINT64)0xFFFFFFFFFFFFFFC5ull) /* 2^64 - 59 */
774 #define m36 ((UINT64)0x0000000FFFFFFFFFull) /* The low 36 of 64 bits */
775
776
777 /* ---------------------------------------------------------------------- */
778
779 typedef struct uhash_ctx {
780 nh_ctx hash; /* Hash context for L1 NH hash */
781 UINT64 poly_key_8[STREAMS]; /* p64 poly keys */
782 UINT64 poly_accum[STREAMS]; /* poly hash result */
783 UINT64 ip_keys[STREAMS*4]; /* Inner-product keys */
784 UINT32 ip_trans[STREAMS]; /* Inner-product translation */
785 UINT32 msg_len; /* Total length of data passed */
786 /* to uhash */
787 } uhash_ctx;
788 typedef struct uhash_ctx *uhash_ctx_t;
789
790 /* ---------------------------------------------------------------------- */
791
792
793 /* The polynomial hashes use Horner's rule to evaluate a polynomial one
794 * word at a time. As described in the specification, poly32 and poly64
795 * require keys from special domains. The following implementations exploit
796 * the special domains to avoid overflow. The results are not guaranteed to
797 * be within Z_p32 and Z_p64, but the Inner-Product hash implementation
798 * patches any errant values.
799 */
800
poly64(UINT64 cur,UINT64 key,UINT64 data)801 static UINT64 poly64(UINT64 cur, UINT64 key, UINT64 data)
802 {
803 UINT32 key_hi = (UINT32)(key >> 32),
804 key_lo = (UINT32)key,
805 cur_hi = (UINT32)(cur >> 32),
806 cur_lo = (UINT32)cur,
807 x_lo,
808 x_hi;
809 UINT64 X,T,res;
810
811 X = MUL64(key_hi, cur_lo) + MUL64(cur_hi, key_lo);
812 x_lo = (UINT32)X;
813 x_hi = (UINT32)(X >> 32);
814
815 res = (MUL64(key_hi, cur_hi) + x_hi) * 59 + MUL64(key_lo, cur_lo);
816
817 T = ((UINT64)x_lo << 32);
818 res += T;
819 if (res < T)
820 res += 59;
821
822 res += data;
823 if (res < data)
824 res += 59;
825
826 return res;
827 }
828
829
830 /* Although UMAC is specified to use a ramped polynomial hash scheme, this
831 * implementation does not handle all ramp levels. Because we don't handle
832 * the ramp up to p128 modulus in this implementation, we are limited to
833 * 2^14 poly_hash() invocations per stream (for a total capacity of 2^24
834 * bytes input to UMAC per tag, ie. 16MB).
835 */
poly_hash(uhash_ctx_t hc,UINT32 data_in[])836 static void poly_hash(uhash_ctx_t hc, UINT32 data_in[])
837 {
838 int i;
839 UINT64 *data=(UINT64*)data_in;
840
841 for (i = 0; i < STREAMS; i++) {
842 if ((UINT32)(data[i] >> 32) == 0xfffffffful) {
843 hc->poly_accum[i] = poly64(hc->poly_accum[i],
844 hc->poly_key_8[i], p64 - 1);
845 hc->poly_accum[i] = poly64(hc->poly_accum[i],
846 hc->poly_key_8[i], (data[i] - 59));
847 } else {
848 hc->poly_accum[i] = poly64(hc->poly_accum[i],
849 hc->poly_key_8[i], data[i]);
850 }
851 }
852 }
853
854
855 /* ---------------------------------------------------------------------- */
856
857
858 /* The final step in UHASH is an inner-product hash. The poly hash
859 * produces a result not necessarily WORD_LEN bytes long. The inner-
860 * product hash breaks the polyhash output into 16-bit chunks and
861 * multiplies each with a 36 bit key.
862 */
863
ip_aux(UINT64 t,UINT64 * ipkp,UINT64 data)864 static UINT64 ip_aux(UINT64 t, UINT64 *ipkp, UINT64 data)
865 {
866 t = t + ipkp[0] * (UINT64)(UINT16)(data >> 48);
867 t = t + ipkp[1] * (UINT64)(UINT16)(data >> 32);
868 t = t + ipkp[2] * (UINT64)(UINT16)(data >> 16);
869 t = t + ipkp[3] * (UINT64)(UINT16)(data);
870
871 return t;
872 }
873
ip_reduce_p36(UINT64 t)874 static UINT32 ip_reduce_p36(UINT64 t)
875 {
876 /* Divisionless modular reduction */
877 UINT64 ret;
878
879 ret = (t & m36) + 5 * (t >> 36);
880 if (ret >= p36)
881 ret -= p36;
882
883 /* return least significant 32 bits */
884 return (UINT32)(ret);
885 }
886
887
888 /* If the data being hashed by UHASH is no longer than L1_KEY_LEN, then
889 * the polyhash stage is skipped and ip_short is applied directly to the
890 * NH output.
891 */
ip_short(uhash_ctx_t ahc,UINT8 * nh_res,unsigned char * res)892 static void ip_short(uhash_ctx_t ahc, UINT8 *nh_res, unsigned char *res)
893 {
894 UINT64 t;
895 UINT64 *nhp = (UINT64 *)nh_res;
896
897 t = ip_aux(0,ahc->ip_keys, nhp[0]);
898 STORE_UINT32_BIG((UINT32 *)res+0, ip_reduce_p36(t) ^ ahc->ip_trans[0]);
899 #if (UMAC_OUTPUT_LEN >= 8)
900 t = ip_aux(0,ahc->ip_keys+4, nhp[1]);
901 STORE_UINT32_BIG((UINT32 *)res+1, ip_reduce_p36(t) ^ ahc->ip_trans[1]);
902 #endif
903 #if (UMAC_OUTPUT_LEN >= 12)
904 t = ip_aux(0,ahc->ip_keys+8, nhp[2]);
905 STORE_UINT32_BIG((UINT32 *)res+2, ip_reduce_p36(t) ^ ahc->ip_trans[2]);
906 #endif
907 #if (UMAC_OUTPUT_LEN == 16)
908 t = ip_aux(0,ahc->ip_keys+12, nhp[3]);
909 STORE_UINT32_BIG((UINT32 *)res+3, ip_reduce_p36(t) ^ ahc->ip_trans[3]);
910 #endif
911 }
912
913 /* If the data being hashed by UHASH is longer than L1_KEY_LEN, then
914 * the polyhash stage is not skipped and ip_long is applied to the
915 * polyhash output.
916 */
ip_long(uhash_ctx_t ahc,unsigned char * res)917 static void ip_long(uhash_ctx_t ahc, unsigned char *res)
918 {
919 int i;
920 UINT64 t;
921
922 for (i = 0; i < STREAMS; i++) {
923 /* fix polyhash output not in Z_p64 */
924 if (ahc->poly_accum[i] >= p64)
925 ahc->poly_accum[i] -= p64;
926 t = ip_aux(0,ahc->ip_keys+(i*4), ahc->poly_accum[i]);
927 STORE_UINT32_BIG((UINT32 *)res+i,
928 ip_reduce_p36(t) ^ ahc->ip_trans[i]);
929 }
930 }
931
932
933 /* ---------------------------------------------------------------------- */
934
935 /* ---------------------------------------------------------------------- */
936
937 /* Reset uhash context for next hash session */
uhash_reset(uhash_ctx_t pc)938 static int uhash_reset(uhash_ctx_t pc)
939 {
940 nh_reset(&pc->hash);
941 pc->msg_len = 0;
942 pc->poly_accum[0] = 1;
943 #if (UMAC_OUTPUT_LEN >= 8)
944 pc->poly_accum[1] = 1;
945 #endif
946 #if (UMAC_OUTPUT_LEN >= 12)
947 pc->poly_accum[2] = 1;
948 #endif
949 #if (UMAC_OUTPUT_LEN == 16)
950 pc->poly_accum[3] = 1;
951 #endif
952 return 1;
953 }
954
955 /* ---------------------------------------------------------------------- */
956
957 /* Given a pointer to the internal key needed by kdf() and a uhash context,
958 * initialize the NH context and generate keys needed for poly and inner-
959 * product hashing. All keys are endian adjusted in memory so that native
960 * loads cause correct keys to be in registers during calculation.
961 */
uhash_init(uhash_ctx_t ahc,aes_int_key prf_key)962 static void uhash_init(uhash_ctx_t ahc, aes_int_key prf_key)
963 {
964 int i;
965 UINT8 buf[(8*STREAMS+4)*sizeof(UINT64)];
966
967 /* Zero the entire uhash context */
968 memset(ahc, 0, sizeof(uhash_ctx));
969
970 /* Initialize the L1 hash */
971 nh_init(&ahc->hash, prf_key);
972
973 /* Setup L2 hash variables */
974 kdf(buf, prf_key, 2, sizeof(buf)); /* Fill buffer with index 1 key */
975 for (i = 0; i < STREAMS; i++) {
976 /* Fill keys from the buffer, skipping bytes in the buffer not
977 * used by this implementation. Endian reverse the keys if on a
978 * little-endian computer.
979 */
980 memcpy(ahc->poly_key_8+i, buf+24*i, 8);
981 endian_convert_if_le(ahc->poly_key_8+i, 8, 8);
982 /* Mask the 64-bit keys to their special domain */
983 ahc->poly_key_8[i] &= ((UINT64)0x01ffffffu << 32) + 0x01ffffffu;
984 ahc->poly_accum[i] = 1; /* Our polyhash prepends a non-zero word */
985 }
986
987 /* Setup L3-1 hash variables */
988 kdf(buf, prf_key, 3, sizeof(buf)); /* Fill buffer with index 2 key */
989 for (i = 0; i < STREAMS; i++)
990 memcpy(ahc->ip_keys+4*i, buf+(8*i+4)*sizeof(UINT64),
991 4*sizeof(UINT64));
992 endian_convert_if_le(ahc->ip_keys, sizeof(UINT64),
993 sizeof(ahc->ip_keys));
994 for (i = 0; i < STREAMS*4; i++)
995 ahc->ip_keys[i] %= p36; /* Bring into Z_p36 */
996
997 /* Setup L3-2 hash variables */
998 /* Fill buffer with index 4 key */
999 kdf(ahc->ip_trans, prf_key, 4, STREAMS * sizeof(UINT32));
1000 endian_convert_if_le(ahc->ip_trans, sizeof(UINT32),
1001 STREAMS * sizeof(UINT32));
1002 }
1003
1004 /* ---------------------------------------------------------------------- */
1005
uhash_update(uhash_ctx_t ctx,unsigned char * input,long len)1006 static int uhash_update(uhash_ctx_t ctx, unsigned char *input, long len)
1007 /* Given len bytes of data, we parse it into L1_KEY_LEN chunks and
1008 * hash each one with NH, calling the polyhash on each NH output.
1009 */
1010 {
1011 UWORD bytes_hashed, bytes_remaining;
1012 UINT64 result_buf[STREAMS];
1013 UINT8 *nh_result = (UINT8 *)&result_buf;
1014
1015 if (ctx->msg_len + len <= L1_KEY_LEN) {
1016 nh_update(&ctx->hash, (UINT8 *)input, len);
1017 ctx->msg_len += len;
1018 } else {
1019
1020 bytes_hashed = ctx->msg_len % L1_KEY_LEN;
1021 if (ctx->msg_len == L1_KEY_LEN)
1022 bytes_hashed = L1_KEY_LEN;
1023
1024 if (bytes_hashed + len >= L1_KEY_LEN) {
1025
1026 /* If some bytes have been passed to the hash function */
1027 /* then we want to pass at most (L1_KEY_LEN - bytes_hashed) */
1028 /* bytes to complete the current nh_block. */
1029 if (bytes_hashed) {
1030 bytes_remaining = (L1_KEY_LEN - bytes_hashed);
1031 nh_update(&ctx->hash, (UINT8 *)input, bytes_remaining);
1032 nh_final(&ctx->hash, nh_result);
1033 ctx->msg_len += bytes_remaining;
1034 poly_hash(ctx,(UINT32 *)nh_result);
1035 len -= bytes_remaining;
1036 input += bytes_remaining;
1037 }
1038
1039 /* Hash directly from input stream if enough bytes */
1040 while (len >= L1_KEY_LEN) {
1041 nh(&ctx->hash, (UINT8 *)input, L1_KEY_LEN,
1042 L1_KEY_LEN, nh_result);
1043 ctx->msg_len += L1_KEY_LEN;
1044 len -= L1_KEY_LEN;
1045 input += L1_KEY_LEN;
1046 poly_hash(ctx,(UINT32 *)nh_result);
1047 }
1048 }
1049
1050 /* pass remaining < L1_KEY_LEN bytes of input data to NH */
1051 if (len) {
1052 nh_update(&ctx->hash, (UINT8 *)input, len);
1053 ctx->msg_len += len;
1054 }
1055 }
1056
1057 return (1);
1058 }
1059
1060 /* ---------------------------------------------------------------------- */
1061
uhash_final(uhash_ctx_t ctx,unsigned char * res)1062 static int uhash_final(uhash_ctx_t ctx, unsigned char *res)
1063 /* Incorporate any pending data, pad, and generate tag */
1064 {
1065 UINT64 result_buf[STREAMS];
1066 UINT8 *nh_result = (UINT8 *)&result_buf;
1067
1068 if (ctx->msg_len > L1_KEY_LEN) {
1069 if (ctx->msg_len % L1_KEY_LEN) {
1070 nh_final(&ctx->hash, nh_result);
1071 poly_hash(ctx,(UINT32 *)nh_result);
1072 }
1073 ip_long(ctx, res);
1074 } else {
1075 nh_final(&ctx->hash, nh_result);
1076 ip_short(ctx,nh_result, res);
1077 }
1078 uhash_reset(ctx);
1079 return (1);
1080 }
1081
1082 /* ---------------------------------------------------------------------- */
1083 /* ---------------------------------------------------------------------- */
1084 /* ----- Begin UMAC Section --------------------------------------------- */
1085 /* ---------------------------------------------------------------------- */
1086 /* ---------------------------------------------------------------------- */
1087
1088 /* The UMAC interface has two interfaces, an all-at-once interface where
1089 * the entire message to be authenticated is passed to UMAC in one buffer,
1090 * and a sequential interface where the message is presented a little at a
1091 * time. The all-at-once is more optimaized than the sequential version and
1092 * should be preferred when the sequential interface is not required.
1093 */
1094 struct umac_ctx {
1095 uhash_ctx hash; /* Hash function for message compression */
1096 pdf_ctx pdf; /* PDF for hashed output */
1097 void *free_ptr; /* Address to free this struct via */
1098 };
1099
1100 /* ---------------------------------------------------------------------- */
1101
umac_reset(struct umac_ctx * ctx)1102 int umac_reset(struct umac_ctx *ctx)
1103 /* Reset the hash function to begin a new authentication. */
1104 {
1105 uhash_reset(&ctx->hash);
1106 return (1);
1107 }
1108
1109 /* ---------------------------------------------------------------------- */
1110
umac_delete(struct umac_ctx * ctx)1111 int umac_delete(struct umac_ctx *ctx)
1112 /* Deallocate the ctx structure */
1113 {
1114 if (ctx) {
1115 if (ALLOC_BOUNDARY)
1116 ctx = (struct umac_ctx *)ctx->free_ptr;
1117 free(ctx);
1118 }
1119 return (1);
1120 }
1121
1122 /* ---------------------------------------------------------------------- */
1123
umac_alloc(void)1124 struct umac_ctx *umac_alloc(void) {
1125 struct umac_ctx *ctx, *octx;
1126 size_t bytes_to_add;
1127
1128 octx = ctx = malloc(sizeof(struct umac_ctx) + ALLOC_BOUNDARY);
1129 if (ctx) {
1130 if (ALLOC_BOUNDARY) {
1131 bytes_to_add = ALLOC_BOUNDARY -
1132 ((ptrdiff_t)ctx & (ALLOC_BOUNDARY - 1));
1133 ctx = (struct umac_ctx *)((unsigned char *)ctx + bytes_to_add);
1134 }
1135 ctx->free_ptr = octx;
1136 }
1137
1138 return (ctx);
1139 }
1140
umac_init(struct umac_ctx * ctx,unsigned char key[])1141 void umac_init(struct umac_ctx *ctx, unsigned char key[]) {
1142 aes_int_key prf_key;
1143
1144 aes_key_setup(key, prf_key);
1145 pdf_init(&ctx->pdf, prf_key);
1146 uhash_init(&ctx->hash, prf_key);
1147 }
1148
umac_new(unsigned char key[])1149 struct umac_ctx *umac_new(unsigned char key[])
1150 /* Dynamically allocate a umac_ctx struct, initialize variables,
1151 * generate subkeys from key. Align to 16-byte boundary.
1152 */
1153 {
1154 struct umac_ctx *ctx;
1155
1156 ctx = umac_alloc();
1157 if (ctx) {
1158 umac_init(ctx, key);
1159 }
1160
1161 return (ctx);
1162 }
1163
1164 /* ---------------------------------------------------------------------- */
1165
umac_final(struct umac_ctx * ctx,unsigned char tag[],unsigned char nonce[8])1166 int umac_final(struct umac_ctx *ctx, unsigned char tag[], unsigned char nonce[8])
1167 /* Incorporate any pending data, pad, and generate tag */
1168 {
1169 uhash_final(&ctx->hash, (unsigned char *)tag);
1170 pdf_gen_xor(&ctx->pdf, (UINT8 *)nonce, (UINT8 *)tag);
1171
1172 return (1);
1173 }
1174
1175 /* ---------------------------------------------------------------------- */
1176
umac_update(struct umac_ctx * ctx,unsigned char * input,long len)1177 int umac_update(struct umac_ctx *ctx, unsigned char *input, long len)
1178 /* Given len bytes of data, we parse it into L1_KEY_LEN chunks and */
1179 /* hash each one, calling the PDF on the hashed output whenever the hash- */
1180 /* output buffer is full. */
1181 {
1182 uhash_update(&ctx->hash, input, len);
1183 return (1);
1184 }
1185
1186 #else
1187
1188 struct umac_ctx {
1189 void *free_ptr; /* Address to free this struct via */
1190 };
1191
umac_reset(struct umac_ctx * ctx)1192 int umac_reset(struct umac_ctx *ctx)
1193 /* Reset the hash function to begin a new authentication. */
1194 {
1195 return (0);
1196 }
1197
1198 /* ---------------------------------------------------------------------- */
1199
umac_delete(struct umac_ctx * ctx)1200 int umac_delete(struct umac_ctx *ctx)
1201 /* Deallocate the ctx structure */
1202 {
1203 return (0);
1204 }
1205
1206 /* ---------------------------------------------------------------------- */
1207
umac_alloc(void)1208 struct umac_ctx *umac_alloc(void) {
1209 return (NULL);
1210 }
1211
umac_init(struct umac_ctx * ctx,unsigned char key[])1212 void umac_init(struct umac_ctx *ctx, unsigned char key[]) {
1213 }
1214
umac_new(unsigned char key[])1215 struct umac_ctx *umac_new(unsigned char key[])
1216 /* Dynamically allocate a umac_ctx struct, initialize variables,
1217 * generate subkeys from key. Align to 16-byte boundary.
1218 */
1219 {
1220 return (NULL);
1221 }
1222
1223 /* ---------------------------------------------------------------------- */
1224
umac_final(struct umac_ctx * ctx,unsigned char tag[],unsigned char nonce[8])1225 int umac_final(struct umac_ctx *ctx, unsigned char tag[], unsigned char nonce[8])
1226 {
1227 return (0);
1228 }
1229
1230 /* ---------------------------------------------------------------------- */
1231
umac_update(struct umac_ctx * ctx,unsigned char * input,long len)1232 int umac_update(struct umac_ctx *ctx, unsigned char *input, long len)
1233 /* Given len bytes of data, we parse it into L1_KEY_LEN chunks and */
1234 /* hash each one, calling the PDF on the hashed output whenever the hash- */
1235 /* output buffer is full. */
1236 {
1237 return (0);
1238 }
1239
1240 #endif /* OpenSSL-0.9.7 or later */
1241
1242 /* ---------------------------------------------------------------------- */
1243 /* ---------------------------------------------------------------------- */
1244 /* ----- End UMAC Section ----------------------------------------------- */
1245 /* ---------------------------------------------------------------------- */
1246 /* ---------------------------------------------------------------------- */
1247
1248