summaryrefslogtreecommitdiff
path: root/umac.c
diff options
context:
space:
mode:
Diffstat (limited to 'umac.c')
-rw-r--r--umac.c76
1 files changed, 39 insertions, 37 deletions
diff --git a/umac.c b/umac.c
index 0567c37f9..99416a510 100644
--- a/umac.c
+++ b/umac.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: umac.c,v 1.4 2011/10/19 10:39:48 djm Exp $ */ 1/* $OpenBSD: umac.c,v 1.7 2013/07/22 05:00:17 djm Exp $ */
2/* ----------------------------------------------------------------------- 2/* -----------------------------------------------------------------------
3 * 3 *
4 * umac.c -- C Implementation UMAC Message Authentication 4 * umac.c -- C Implementation UMAC Message Authentication
@@ -132,13 +132,13 @@ typedef unsigned int UWORD; /* Register */
132/* ---------------------------------------------------------------------- */ 132/* ---------------------------------------------------------------------- */
133 133
134#if HAVE_SWAP32 134#if HAVE_SWAP32
135#define LOAD_UINT32_REVERSED(p) (swap32(*(UINT32 *)(p))) 135#define LOAD_UINT32_REVERSED(p) (swap32(*(const UINT32 *)(p)))
136#define STORE_UINT32_REVERSED(p,v) (*(UINT32 *)(p) = swap32(v)) 136#define STORE_UINT32_REVERSED(p,v) (*(UINT32 *)(p) = swap32(v))
137#else /* HAVE_SWAP32 */ 137#else /* HAVE_SWAP32 */
138 138
139static UINT32 LOAD_UINT32_REVERSED(void *ptr) 139static UINT32 LOAD_UINT32_REVERSED(const void *ptr)
140{ 140{
141 UINT32 temp = *(UINT32 *)ptr; 141 UINT32 temp = *(const UINT32 *)ptr;
142 temp = (temp >> 24) | ((temp & 0x00FF0000) >> 8 ) 142 temp = (temp >> 24) | ((temp & 0x00FF0000) >> 8 )
143 | ((temp & 0x0000FF00) << 8 ) | (temp << 24); 143 | ((temp & 0x0000FF00) << 8 ) | (temp << 24);
144 return (UINT32)temp; 144 return (UINT32)temp;
@@ -159,7 +159,7 @@ static void STORE_UINT32_REVERSED(void *ptr, UINT32 x)
159 */ 159 */
160 160
161#if (__LITTLE_ENDIAN__) 161#if (__LITTLE_ENDIAN__)
162#define LOAD_UINT32_LITTLE(ptr) (*(UINT32 *)(ptr)) 162#define LOAD_UINT32_LITTLE(ptr) (*(const UINT32 *)(ptr))
163#define STORE_UINT32_BIG(ptr,x) STORE_UINT32_REVERSED(ptr,x) 163#define STORE_UINT32_BIG(ptr,x) STORE_UINT32_REVERSED(ptr,x)
164#else 164#else
165#define LOAD_UINT32_LITTLE(ptr) LOAD_UINT32_REVERSED(ptr) 165#define LOAD_UINT32_LITTLE(ptr) LOAD_UINT32_REVERSED(ptr)
@@ -184,7 +184,7 @@ typedef AES_KEY aes_int_key[1];
184#define aes_encryption(in,out,int_key) \ 184#define aes_encryption(in,out,int_key) \
185 AES_encrypt((u_char *)(in),(u_char *)(out),(AES_KEY *)int_key) 185 AES_encrypt((u_char *)(in),(u_char *)(out),(AES_KEY *)int_key)
186#define aes_key_setup(key,int_key) \ 186#define aes_key_setup(key,int_key) \
187 AES_set_encrypt_key((u_char *)(key),UMAC_KEY_LEN*8,int_key) 187 AES_set_encrypt_key((const u_char *)(key),UMAC_KEY_LEN*8,int_key)
188 188
189/* The user-supplied UMAC key is stretched using AES in a counter 189/* The user-supplied UMAC key is stretched using AES in a counter
190 * mode to supply all random bits needed by UMAC. The kdf function takes 190 * mode to supply all random bits needed by UMAC. The kdf function takes
@@ -240,7 +240,7 @@ static void pdf_init(pdf_ctx *pc, aes_int_key prf_key)
240 aes_encryption(pc->nonce, pc->cache, pc->prf_key); 240 aes_encryption(pc->nonce, pc->cache, pc->prf_key);
241} 241}
242 242
243static void pdf_gen_xor(pdf_ctx *pc, UINT8 nonce[8], UINT8 buf[8]) 243static void pdf_gen_xor(pdf_ctx *pc, const UINT8 nonce[8], UINT8 buf[8])
244{ 244{
245 /* 'ndx' indicates that we'll be using the 0th or 1st eight bytes 245 /* 'ndx' indicates that we'll be using the 0th or 1st eight bytes
246 * of the AES output. If last time around we returned the ndx-1st 246 * of the AES output. If last time around we returned the ndx-1st
@@ -254,19 +254,21 @@ static void pdf_gen_xor(pdf_ctx *pc, UINT8 nonce[8], UINT8 buf[8])
254#elif (UMAC_OUTPUT_LEN > 8) 254#elif (UMAC_OUTPUT_LEN > 8)
255#define LOW_BIT_MASK 0 255#define LOW_BIT_MASK 0
256#endif 256#endif
257 257 union {
258 UINT8 tmp_nonce_lo[4]; 258 UINT8 tmp_nonce_lo[4];
259 UINT32 align;
260 } t;
259#if LOW_BIT_MASK != 0 261#if LOW_BIT_MASK != 0
260 int ndx = nonce[7] & LOW_BIT_MASK; 262 int ndx = nonce[7] & LOW_BIT_MASK;
261#endif 263#endif
262 *(UINT32 *)tmp_nonce_lo = ((UINT32 *)nonce)[1]; 264 *(UINT32 *)t.tmp_nonce_lo = ((const UINT32 *)nonce)[1];
263 tmp_nonce_lo[3] &= ~LOW_BIT_MASK; /* zero last bit */ 265 t.tmp_nonce_lo[3] &= ~LOW_BIT_MASK; /* zero last bit */
264 266
265 if ( (((UINT32 *)tmp_nonce_lo)[0] != ((UINT32 *)pc->nonce)[1]) || 267 if ( (((UINT32 *)t.tmp_nonce_lo)[0] != ((UINT32 *)pc->nonce)[1]) ||
266 (((UINT32 *)nonce)[0] != ((UINT32 *)pc->nonce)[0]) ) 268 (((const UINT32 *)nonce)[0] != ((UINT32 *)pc->nonce)[0]) )
267 { 269 {
268 ((UINT32 *)pc->nonce)[0] = ((UINT32 *)nonce)[0]; 270 ((UINT32 *)pc->nonce)[0] = ((const UINT32 *)nonce)[0];
269 ((UINT32 *)pc->nonce)[1] = ((UINT32 *)tmp_nonce_lo)[0]; 271 ((UINT32 *)pc->nonce)[1] = ((UINT32 *)t.tmp_nonce_lo)[0];
270 aes_encryption(pc->nonce, pc->cache, pc->prf_key); 272 aes_encryption(pc->nonce, pc->cache, pc->prf_key);
271 } 273 }
272 274
@@ -333,7 +335,7 @@ typedef struct {
333 335
334#if (UMAC_OUTPUT_LEN == 4) 336#if (UMAC_OUTPUT_LEN == 4)
335 337
336static void nh_aux(void *kp, void *dp, void *hp, UINT32 dlen) 338static void nh_aux(void *kp, const void *dp, void *hp, UINT32 dlen)
337/* NH hashing primitive. Previous (partial) hash result is loaded and 339/* NH hashing primitive. Previous (partial) hash result is loaded and
338* then stored via hp pointer. The length of the data pointed at by "dp", 340* then stored via hp pointer. The length of the data pointed at by "dp",
339* "dlen", is guaranteed to be divisible by L1_PAD_BOUNDARY (32). Key 341* "dlen", is guaranteed to be divisible by L1_PAD_BOUNDARY (32). Key
@@ -343,7 +345,7 @@ static void nh_aux(void *kp, void *dp, void *hp, UINT32 dlen)
343 UINT64 h; 345 UINT64 h;
344 UWORD c = dlen / 32; 346 UWORD c = dlen / 32;
345 UINT32 *k = (UINT32 *)kp; 347 UINT32 *k = (UINT32 *)kp;
346 UINT32 *d = (UINT32 *)dp; 348 const UINT32 *d = (const UINT32 *)dp;
347 UINT32 d0,d1,d2,d3,d4,d5,d6,d7; 349 UINT32 d0,d1,d2,d3,d4,d5,d6,d7;
348 UINT32 k0,k1,k2,k3,k4,k5,k6,k7; 350 UINT32 k0,k1,k2,k3,k4,k5,k6,k7;
349 351
@@ -368,7 +370,7 @@ static void nh_aux(void *kp, void *dp, void *hp, UINT32 dlen)
368 370
369#elif (UMAC_OUTPUT_LEN == 8) 371#elif (UMAC_OUTPUT_LEN == 8)
370 372
371static void nh_aux(void *kp, void *dp, void *hp, UINT32 dlen) 373static void nh_aux(void *kp, const void *dp, void *hp, UINT32 dlen)
372/* Same as previous nh_aux, but two streams are handled in one pass, 374/* Same as previous nh_aux, but two streams are handled in one pass,
373 * reading and writing 16 bytes of hash-state per call. 375 * reading and writing 16 bytes of hash-state per call.
374 */ 376 */
@@ -376,7 +378,7 @@ static void nh_aux(void *kp, void *dp, void *hp, UINT32 dlen)
376 UINT64 h1,h2; 378 UINT64 h1,h2;
377 UWORD c = dlen / 32; 379 UWORD c = dlen / 32;
378 UINT32 *k = (UINT32 *)kp; 380 UINT32 *k = (UINT32 *)kp;
379 UINT32 *d = (UINT32 *)dp; 381 const UINT32 *d = (const UINT32 *)dp;
380 UINT32 d0,d1,d2,d3,d4,d5,d6,d7; 382 UINT32 d0,d1,d2,d3,d4,d5,d6,d7;
381 UINT32 k0,k1,k2,k3,k4,k5,k6,k7, 383 UINT32 k0,k1,k2,k3,k4,k5,k6,k7,
382 k8,k9,k10,k11; 384 k8,k9,k10,k11;
@@ -415,7 +417,7 @@ static void nh_aux(void *kp, void *dp, void *hp, UINT32 dlen)
415 417
416#elif (UMAC_OUTPUT_LEN == 12) 418#elif (UMAC_OUTPUT_LEN == 12)
417 419
418static void nh_aux(void *kp, void *dp, void *hp, UINT32 dlen) 420static void nh_aux(void *kp, const void *dp, void *hp, UINT32 dlen)
419/* Same as previous nh_aux, but two streams are handled in one pass, 421/* Same as previous nh_aux, but two streams are handled in one pass,
420 * reading and writing 24 bytes of hash-state per call. 422 * reading and writing 24 bytes of hash-state per call.
421*/ 423*/
@@ -423,7 +425,7 @@ static void nh_aux(void *kp, void *dp, void *hp, UINT32 dlen)
423 UINT64 h1,h2,h3; 425 UINT64 h1,h2,h3;
424 UWORD c = dlen / 32; 426 UWORD c = dlen / 32;
425 UINT32 *k = (UINT32 *)kp; 427 UINT32 *k = (UINT32 *)kp;
426 UINT32 *d = (UINT32 *)dp; 428 const UINT32 *d = (const UINT32 *)dp;
427 UINT32 d0,d1,d2,d3,d4,d5,d6,d7; 429 UINT32 d0,d1,d2,d3,d4,d5,d6,d7;
428 UINT32 k0,k1,k2,k3,k4,k5,k6,k7, 430 UINT32 k0,k1,k2,k3,k4,k5,k6,k7,
429 k8,k9,k10,k11,k12,k13,k14,k15; 431 k8,k9,k10,k11,k12,k13,k14,k15;
@@ -470,7 +472,7 @@ static void nh_aux(void *kp, void *dp, void *hp, UINT32 dlen)
470 472
471#elif (UMAC_OUTPUT_LEN == 16) 473#elif (UMAC_OUTPUT_LEN == 16)
472 474
473static void nh_aux(void *kp, void *dp, void *hp, UINT32 dlen) 475static void nh_aux(void *kp, const void *dp, void *hp, UINT32 dlen)
474/* Same as previous nh_aux, but two streams are handled in one pass, 476/* Same as previous nh_aux, but two streams are handled in one pass,
475 * reading and writing 24 bytes of hash-state per call. 477 * reading and writing 24 bytes of hash-state per call.
476*/ 478*/
@@ -478,7 +480,7 @@ static void nh_aux(void *kp, void *dp, void *hp, UINT32 dlen)
478 UINT64 h1,h2,h3,h4; 480 UINT64 h1,h2,h3,h4;
479 UWORD c = dlen / 32; 481 UWORD c = dlen / 32;
480 UINT32 *k = (UINT32 *)kp; 482 UINT32 *k = (UINT32 *)kp;
481 UINT32 *d = (UINT32 *)dp; 483 const UINT32 *d = (const UINT32 *)dp;
482 UINT32 d0,d1,d2,d3,d4,d5,d6,d7; 484 UINT32 d0,d1,d2,d3,d4,d5,d6,d7;
483 UINT32 k0,k1,k2,k3,k4,k5,k6,k7, 485 UINT32 k0,k1,k2,k3,k4,k5,k6,k7,
484 k8,k9,k10,k11,k12,k13,k14,k15, 486 k8,k9,k10,k11,k12,k13,k14,k15,
@@ -539,7 +541,7 @@ static void nh_aux(void *kp, void *dp, void *hp, UINT32 dlen)
539 541
540/* ---------------------------------------------------------------------- */ 542/* ---------------------------------------------------------------------- */
541 543
542static void nh_transform(nh_ctx *hc, UINT8 *buf, UINT32 nbytes) 544static void nh_transform(nh_ctx *hc, const UINT8 *buf, UINT32 nbytes)
543/* This function is a wrapper for the primitive NH hash functions. It takes 545/* This function is a wrapper for the primitive NH hash functions. It takes
544 * as argument "hc" the current hash context and a buffer which must be a 546 * as argument "hc" the current hash context and a buffer which must be a
545 * multiple of L1_PAD_BOUNDARY. The key passed to nh_aux is offset 547 * multiple of L1_PAD_BOUNDARY. The key passed to nh_aux is offset
@@ -614,7 +616,7 @@ static void nh_init(nh_ctx *hc, aes_int_key prf_key)
614 616
615/* ---------------------------------------------------------------------- */ 617/* ---------------------------------------------------------------------- */
616 618
617static void nh_update(nh_ctx *hc, UINT8 *buf, UINT32 nbytes) 619static void nh_update(nh_ctx *hc, const UINT8 *buf, UINT32 nbytes)
618/* Incorporate nbytes of data into a nh_ctx, buffer whatever is not an */ 620/* Incorporate nbytes of data into a nh_ctx, buffer whatever is not an */
619/* even multiple of HASH_BUF_BYTES. */ 621/* even multiple of HASH_BUF_BYTES. */
620{ 622{
@@ -709,7 +711,7 @@ static void nh_final(nh_ctx *hc, UINT8 *result)
709 711
710/* ---------------------------------------------------------------------- */ 712/* ---------------------------------------------------------------------- */
711 713
712static void nh(nh_ctx *hc, UINT8 *buf, UINT32 padded_len, 714static void nh(nh_ctx *hc, const UINT8 *buf, UINT32 padded_len,
713 UINT32 unpadded_len, UINT8 *result) 715 UINT32 unpadded_len, UINT8 *result)
714/* All-in-one nh_update() and nh_final() equivalent. 716/* All-in-one nh_update() and nh_final() equivalent.
715 * Assumes that padded_len is divisible by L1_PAD_BOUNDARY and result is 717 * Assumes that padded_len is divisible by L1_PAD_BOUNDARY and result is
@@ -1047,7 +1049,7 @@ static int uhash_free(uhash_ctx_t ctx)
1047#endif 1049#endif
1048/* ---------------------------------------------------------------------- */ 1050/* ---------------------------------------------------------------------- */
1049 1051
1050static int uhash_update(uhash_ctx_t ctx, u_char *input, long len) 1052static int uhash_update(uhash_ctx_t ctx, const u_char *input, long len)
1051/* Given len bytes of data, we parse it into L1_KEY_LEN chunks and 1053/* Given len bytes of data, we parse it into L1_KEY_LEN chunks and
1052 * hash each one with NH, calling the polyhash on each NH output. 1054 * hash each one with NH, calling the polyhash on each NH output.
1053 */ 1055 */
@@ -1057,7 +1059,7 @@ static int uhash_update(uhash_ctx_t ctx, u_char *input, long len)
1057 UINT8 *nh_result = (UINT8 *)&result_buf; 1059 UINT8 *nh_result = (UINT8 *)&result_buf;
1058 1060
1059 if (ctx->msg_len + len <= L1_KEY_LEN) { 1061 if (ctx->msg_len + len <= L1_KEY_LEN) {
1060 nh_update(&ctx->hash, (UINT8 *)input, len); 1062 nh_update(&ctx->hash, (const UINT8 *)input, len);
1061 ctx->msg_len += len; 1063 ctx->msg_len += len;
1062 } else { 1064 } else {
1063 1065
@@ -1072,7 +1074,7 @@ static int uhash_update(uhash_ctx_t ctx, u_char *input, long len)
1072 /* bytes to complete the current nh_block. */ 1074 /* bytes to complete the current nh_block. */
1073 if (bytes_hashed) { 1075 if (bytes_hashed) {
1074 bytes_remaining = (L1_KEY_LEN - bytes_hashed); 1076 bytes_remaining = (L1_KEY_LEN - bytes_hashed);
1075 nh_update(&ctx->hash, (UINT8 *)input, bytes_remaining); 1077 nh_update(&ctx->hash, (const UINT8 *)input, bytes_remaining);
1076 nh_final(&ctx->hash, nh_result); 1078 nh_final(&ctx->hash, nh_result);
1077 ctx->msg_len += bytes_remaining; 1079 ctx->msg_len += bytes_remaining;
1078 poly_hash(ctx,(UINT32 *)nh_result); 1080 poly_hash(ctx,(UINT32 *)nh_result);
@@ -1082,7 +1084,7 @@ static int uhash_update(uhash_ctx_t ctx, u_char *input, long len)
1082 1084
1083 /* Hash directly from input stream if enough bytes */ 1085 /* Hash directly from input stream if enough bytes */
1084 while (len >= L1_KEY_LEN) { 1086 while (len >= L1_KEY_LEN) {
1085 nh(&ctx->hash, (UINT8 *)input, L1_KEY_LEN, 1087 nh(&ctx->hash, (const UINT8 *)input, L1_KEY_LEN,
1086 L1_KEY_LEN, nh_result); 1088 L1_KEY_LEN, nh_result);
1087 ctx->msg_len += L1_KEY_LEN; 1089 ctx->msg_len += L1_KEY_LEN;
1088 len -= L1_KEY_LEN; 1090 len -= L1_KEY_LEN;
@@ -1093,7 +1095,7 @@ static int uhash_update(uhash_ctx_t ctx, u_char *input, long len)
1093 1095
1094 /* pass remaining < L1_KEY_LEN bytes of input data to NH */ 1096 /* pass remaining < L1_KEY_LEN bytes of input data to NH */
1095 if (len) { 1097 if (len) {
1096 nh_update(&ctx->hash, (UINT8 *)input, len); 1098 nh_update(&ctx->hash, (const UINT8 *)input, len);
1097 ctx->msg_len += len; 1099 ctx->msg_len += len;
1098 } 1100 }
1099 } 1101 }
@@ -1209,14 +1211,14 @@ int umac_delete(struct umac_ctx *ctx)
1209 if (ctx) { 1211 if (ctx) {
1210 if (ALLOC_BOUNDARY) 1212 if (ALLOC_BOUNDARY)
1211 ctx = (struct umac_ctx *)ctx->free_ptr; 1213 ctx = (struct umac_ctx *)ctx->free_ptr;
1212 xfree(ctx); 1214 free(ctx);
1213 } 1215 }
1214 return (1); 1216 return (1);
1215} 1217}
1216 1218
1217/* ---------------------------------------------------------------------- */ 1219/* ---------------------------------------------------------------------- */
1218 1220
1219struct umac_ctx *umac_new(u_char key[]) 1221struct umac_ctx *umac_new(const u_char key[])
1220/* Dynamically allocate a umac_ctx struct, initialize variables, 1222/* Dynamically allocate a umac_ctx struct, initialize variables,
1221 * generate subkeys from key. Align to 16-byte boundary. 1223 * generate subkeys from key. Align to 16-byte boundary.
1222 */ 1224 */
@@ -1233,7 +1235,7 @@ struct umac_ctx *umac_new(u_char key[])
1233 ctx = (struct umac_ctx *)((u_char *)ctx + bytes_to_add); 1235 ctx = (struct umac_ctx *)((u_char *)ctx + bytes_to_add);
1234 } 1236 }
1235 ctx->free_ptr = octx; 1237 ctx->free_ptr = octx;
1236 aes_key_setup(key,prf_key); 1238 aes_key_setup(key, prf_key);
1237 pdf_init(&ctx->pdf, prf_key); 1239 pdf_init(&ctx->pdf, prf_key);
1238 uhash_init(&ctx->hash, prf_key); 1240 uhash_init(&ctx->hash, prf_key);
1239 } 1241 }
@@ -1243,18 +1245,18 @@ struct umac_ctx *umac_new(u_char key[])
1243 1245
1244/* ---------------------------------------------------------------------- */ 1246/* ---------------------------------------------------------------------- */
1245 1247
1246int umac_final(struct umac_ctx *ctx, u_char tag[], u_char nonce[8]) 1248int umac_final(struct umac_ctx *ctx, u_char tag[], const u_char nonce[8])
1247/* Incorporate any pending data, pad, and generate tag */ 1249/* Incorporate any pending data, pad, and generate tag */
1248{ 1250{
1249 uhash_final(&ctx->hash, (u_char *)tag); 1251 uhash_final(&ctx->hash, (u_char *)tag);
1250 pdf_gen_xor(&ctx->pdf, (UINT8 *)nonce, (UINT8 *)tag); 1252 pdf_gen_xor(&ctx->pdf, (const UINT8 *)nonce, (UINT8 *)tag);
1251 1253
1252 return (1); 1254 return (1);
1253} 1255}
1254 1256
1255/* ---------------------------------------------------------------------- */ 1257/* ---------------------------------------------------------------------- */
1256 1258
1257int umac_update(struct umac_ctx *ctx, u_char *input, long len) 1259int umac_update(struct umac_ctx *ctx, const u_char *input, long len)
1258/* Given len bytes of data, we parse it into L1_KEY_LEN chunks and */ 1260/* Given len bytes of data, we parse it into L1_KEY_LEN chunks and */
1259/* hash each one, calling the PDF on the hashed output whenever the hash- */ 1261/* hash each one, calling the PDF on the hashed output whenever the hash- */
1260/* output buffer is full. */ 1262/* output buffer is full. */