diff options
-rw-r--r-- | umac.c | 82 |
1 files changed, 41 insertions, 41 deletions
@@ -1,6 +1,6 @@ | |||
1 | /* $OpenBSD: umac.c,v 1.13 2017/10/27 01:01:17 djm Exp $ */ | 1 | /* $OpenBSD: umac.c,v 1.14 2017/11/28 06:04:51 djm Exp $ */ |
2 | /* ----------------------------------------------------------------------- | 2 | /* ----------------------------------------------------------------------- |
3 | * | 3 | * |
4 | * umac.c -- C Implementation UMAC Message Authentication | 4 | * umac.c -- C Implementation UMAC Message Authentication |
5 | * | 5 | * |
6 | * Version 0.93b of rfc4418.txt -- 2006 July 18 | 6 | * Version 0.93b of rfc4418.txt -- 2006 July 18 |
@@ -10,7 +10,7 @@ | |||
10 | * Please report bugs and suggestions to the UMAC webpage. | 10 | * Please report bugs and suggestions to the UMAC webpage. |
11 | * | 11 | * |
12 | * Copyright (c) 1999-2006 Ted Krovetz | 12 | * Copyright (c) 1999-2006 Ted Krovetz |
13 | * | 13 | * |
14 | * Permission to use, copy, modify, and distribute this software and | 14 | * Permission to use, copy, modify, and distribute this software and |
15 | * its documentation for any purpose and with or without fee, is hereby | 15 | * its documentation for any purpose and with or without fee, is hereby |
16 | * granted provided that the above copyright notice appears in all copies | 16 | * granted provided that the above copyright notice appears in all copies |
@@ -18,8 +18,8 @@ | |||
18 | * holder not be used in advertising or publicity pertaining to | 18 | * holder not be used in advertising or publicity pertaining to |
19 | * distribution of the software without specific, written prior permission. | 19 | * distribution of the software without specific, written prior permission. |
20 | * | 20 | * |
21 | * Comments should be directed to Ted Krovetz (tdk@acm.org) | 21 | * Comments should be directed to Ted Krovetz (tdk@acm.org) |
22 | * | 22 | * |
23 | * ---------------------------------------------------------------------- */ | 23 | * ---------------------------------------------------------------------- */ |
24 | 24 | ||
25 | /* ////////////////////// IMPORTANT NOTES ///////////////////////////////// | 25 | /* ////////////////////// IMPORTANT NOTES ///////////////////////////////// |
@@ -208,7 +208,7 @@ static void kdf(void *bufp, aes_int_key key, UINT8 ndx, int nbytes) | |||
208 | } | 208 | } |
209 | 209 | ||
210 | /* The final UHASH result is XOR'd with the output of a pseudorandom | 210 | /* The final UHASH result is XOR'd with the output of a pseudorandom |
211 | * function. Here, we use AES to generate random output and | 211 | * function. Here, we use AES to generate random output and |
212 | * xor the appropriate bytes depending on the last bits of nonce. | 212 | * xor the appropriate bytes depending on the last bits of nonce. |
213 | * This scheme is optimized for sequential, increasing big-endian nonces. | 213 | * This scheme is optimized for sequential, increasing big-endian nonces. |
214 | */ | 214 | */ |
@@ -284,28 +284,28 @@ static void pdf_gen_xor(pdf_ctx *pc, const UINT8 nonce[8], UINT8 buf[8]) | |||
284 | /* ---------------------------------------------------------------------- */ | 284 | /* ---------------------------------------------------------------------- */ |
285 | 285 | ||
286 | /* The NH-based hash functions used in UMAC are described in the UMAC paper | 286 | /* The NH-based hash functions used in UMAC are described in the UMAC paper |
287 | * and specification, both of which can be found at the UMAC website. | 287 | * and specification, both of which can be found at the UMAC website. |
288 | * The interface to this implementation has two | 288 | * The interface to this implementation has two |
289 | * versions, one expects the entire message being hashed to be passed | 289 | * versions, one expects the entire message being hashed to be passed |
290 | * in a single buffer and returns the hash result immediately. The second | 290 | * in a single buffer and returns the hash result immediately. The second |
291 | * allows the message to be passed in a sequence of buffers. In the | 291 | * allows the message to be passed in a sequence of buffers. In the |
292 | * muliple-buffer interface, the client calls the routine nh_update() as | 292 | * muliple-buffer interface, the client calls the routine nh_update() as |
293 | * many times as necessary. When there is no more data to be fed to the | 293 | * many times as necessary. When there is no more data to be fed to the |
294 | * hash, the client calls nh_final() which calculates the hash output. | 294 | * hash, the client calls nh_final() which calculates the hash output. |
295 | * Before beginning another hash calculation the nh_reset() routine | 295 | * Before beginning another hash calculation the nh_reset() routine |
296 | * must be called. The single-buffer routine, nh(), is equivalent to | 296 | * must be called. The single-buffer routine, nh(), is equivalent to |
297 | * the sequence of calls nh_update() and nh_final(); however it is | 297 | * the sequence of calls nh_update() and nh_final(); however it is |
298 | * optimized and should be prefered whenever the multiple-buffer interface | 298 | * optimized and should be prefered whenever the multiple-buffer interface |
299 | * is not necessary. When using either interface, it is the client's | 299 | * is not necessary. When using either interface, it is the client's |
300 | * responsability to pass no more than L1_KEY_LEN bytes per hash result. | 300 | * responsability to pass no more than L1_KEY_LEN bytes per hash result. |
301 | * | 301 | * |
302 | * The routine nh_init() initializes the nh_ctx data structure and | 302 | * The routine nh_init() initializes the nh_ctx data structure and |
303 | * must be called once, before any other PDF routine. | 303 | * must be called once, before any other PDF routine. |
304 | */ | 304 | */ |
305 | 305 | ||
306 | /* The "nh_aux" routines do the actual NH hashing work. They | 306 | /* The "nh_aux" routines do the actual NH hashing work. They |
307 | * expect buffers to be multiples of L1_PAD_BOUNDARY. These routines | 307 | * expect buffers to be multiples of L1_PAD_BOUNDARY. These routines |
308 | * produce output for all STREAMS NH iterations in one call, | 308 | * produce output for all STREAMS NH iterations in one call, |
309 | * allowing the parallel implementation of the streams. | 309 | * allowing the parallel implementation of the streams. |
310 | */ | 310 | */ |
311 | 311 | ||
@@ -328,10 +328,10 @@ typedef struct { | |||
328 | #if (UMAC_OUTPUT_LEN == 4) | 328 | #if (UMAC_OUTPUT_LEN == 4) |
329 | 329 | ||
330 | static void nh_aux(void *kp, const void *dp, void *hp, UINT32 dlen) | 330 | static void nh_aux(void *kp, const void *dp, void *hp, UINT32 dlen) |
331 | /* NH hashing primitive. Previous (partial) hash result is loaded and | 331 | /* NH hashing primitive. Previous (partial) hash result is loaded and |
332 | * then stored via hp pointer. The length of the data pointed at by "dp", | 332 | * then stored via hp pointer. The length of the data pointed at by "dp", |
333 | * "dlen", is guaranteed to be divisible by L1_PAD_BOUNDARY (32). Key | 333 | * "dlen", is guaranteed to be divisible by L1_PAD_BOUNDARY (32). Key |
334 | * is expected to be endian compensated in memory at key setup. | 334 | * is expected to be endian compensated in memory at key setup. |
335 | */ | 335 | */ |
336 | { | 336 | { |
337 | UINT64 h; | 337 | UINT64 h; |
@@ -677,7 +677,7 @@ static void nh_final(nh_ctx *hc, UINT8 *result) | |||
677 | if (hc->next_data_empty != 0) { | 677 | if (hc->next_data_empty != 0) { |
678 | nh_len = ((hc->next_data_empty + (L1_PAD_BOUNDARY - 1)) & | 678 | nh_len = ((hc->next_data_empty + (L1_PAD_BOUNDARY - 1)) & |
679 | ~(L1_PAD_BOUNDARY - 1)); | 679 | ~(L1_PAD_BOUNDARY - 1)); |
680 | zero_pad(hc->data + hc->next_data_empty, | 680 | zero_pad(hc->data + hc->next_data_empty, |
681 | nh_len - hc->next_data_empty); | 681 | nh_len - hc->next_data_empty); |
682 | nh_transform(hc, hc->data, nh_len); | 682 | nh_transform(hc, hc->data, nh_len); |
683 | hc->bytes_hashed += hc->next_data_empty; | 683 | hc->bytes_hashed += hc->next_data_empty; |
@@ -744,16 +744,16 @@ static void nh(nh_ctx *hc, const UINT8 *buf, UINT32 padded_len, | |||
744 | * buffers are presented sequentially. In the sequential interface, the | 744 | * buffers are presented sequentially. In the sequential interface, the |
745 | * UHASH client calls the routine uhash_update() as many times as necessary. | 745 | * UHASH client calls the routine uhash_update() as many times as necessary. |
746 | * When there is no more data to be fed to UHASH, the client calls | 746 | * When there is no more data to be fed to UHASH, the client calls |
747 | * uhash_final() which | 747 | * uhash_final() which |
748 | * calculates the UHASH output. Before beginning another UHASH calculation | 748 | * calculates the UHASH output. Before beginning another UHASH calculation |
749 | * the uhash_reset() routine must be called. The all-at-once UHASH routine, | 749 | * the uhash_reset() routine must be called. The all-at-once UHASH routine, |
750 | * uhash(), is equivalent to the sequence of calls uhash_update() and | 750 | * uhash(), is equivalent to the sequence of calls uhash_update() and |
751 | * uhash_final(); however it is optimized and should be | 751 | * uhash_final(); however it is optimized and should be |
752 | * used whenever the sequential interface is not necessary. | 752 | * used whenever the sequential interface is not necessary. |
753 | * | 753 | * |
754 | * The routine uhash_init() initializes the uhash_ctx data structure and | 754 | * The routine uhash_init() initializes the uhash_ctx data structure and |
755 | * must be called once, before any other UHASH routine. | 755 | * must be called once, before any other UHASH routine. |
756 | */ | 756 | */ |
757 | 757 | ||
758 | /* ---------------------------------------------------------------------- */ | 758 | /* ---------------------------------------------------------------------- */ |
759 | /* ----- Constants and uhash_ctx ---------------------------------------- */ | 759 | /* ----- Constants and uhash_ctx ---------------------------------------- */ |
@@ -835,7 +835,7 @@ static void poly_hash(uhash_ctx_t hc, UINT32 data_in[]) | |||
835 | 835 | ||
836 | for (i = 0; i < STREAMS; i++) { | 836 | for (i = 0; i < STREAMS; i++) { |
837 | if ((UINT32)(data[i] >> 32) == 0xfffffffful) { | 837 | if ((UINT32)(data[i] >> 32) == 0xfffffffful) { |
838 | hc->poly_accum[i] = poly64(hc->poly_accum[i], | 838 | hc->poly_accum[i] = poly64(hc->poly_accum[i], |
839 | hc->poly_key_8[i], p64 - 1); | 839 | hc->poly_key_8[i], p64 - 1); |
840 | hc->poly_accum[i] = poly64(hc->poly_accum[i], | 840 | hc->poly_accum[i] = poly64(hc->poly_accum[i], |
841 | hc->poly_key_8[i], (data[i] - 59)); | 841 | hc->poly_key_8[i], (data[i] - 59)); |
@@ -919,7 +919,7 @@ static void ip_long(uhash_ctx_t ahc, u_char *res) | |||
919 | if (ahc->poly_accum[i] >= p64) | 919 | if (ahc->poly_accum[i] >= p64) |
920 | ahc->poly_accum[i] -= p64; | 920 | ahc->poly_accum[i] -= p64; |
921 | t = ip_aux(0,ahc->ip_keys+(i*4), ahc->poly_accum[i]); | 921 | t = ip_aux(0,ahc->ip_keys+(i*4), ahc->poly_accum[i]); |
922 | STORE_UINT32_BIG((UINT32 *)res+i, | 922 | STORE_UINT32_BIG((UINT32 *)res+i, |
923 | ip_reduce_p36(t) ^ ahc->ip_trans[i]); | 923 | ip_reduce_p36(t) ^ ahc->ip_trans[i]); |
924 | } | 924 | } |
925 | } | 925 | } |
@@ -984,7 +984,7 @@ static void uhash_init(uhash_ctx_t ahc, aes_int_key prf_key) | |||
984 | for (i = 0; i < STREAMS; i++) | 984 | for (i = 0; i < STREAMS; i++) |
985 | memcpy(ahc->ip_keys+4*i, buf+(8*i+4)*sizeof(UINT64), | 985 | memcpy(ahc->ip_keys+4*i, buf+(8*i+4)*sizeof(UINT64), |
986 | 4*sizeof(UINT64)); | 986 | 4*sizeof(UINT64)); |
987 | endian_convert_if_le(ahc->ip_keys, sizeof(UINT64), | 987 | endian_convert_if_le(ahc->ip_keys, sizeof(UINT64), |
988 | sizeof(ahc->ip_keys)); | 988 | sizeof(ahc->ip_keys)); |
989 | for (i = 0; i < STREAMS*4; i++) | 989 | for (i = 0; i < STREAMS*4; i++) |
990 | ahc->ip_keys[i] %= p36; /* Bring into Z_p36 */ | 990 | ahc->ip_keys[i] %= p36; /* Bring into Z_p36 */ |
@@ -1134,7 +1134,7 @@ static int uhash(uhash_ctx_t ahc, u_char *msg, long len, u_char *res) | |||
1134 | */ | 1134 | */ |
1135 | if (len <= L1_KEY_LEN) { | 1135 | if (len <= L1_KEY_LEN) { |
1136 | if (len == 0) /* If zero length messages will not */ | 1136 | if (len == 0) /* If zero length messages will not */ |
1137 | nh_len = L1_PAD_BOUNDARY; /* be seen, comment out this case */ | 1137 | nh_len = L1_PAD_BOUNDARY; /* be seen, comment out this case */ |
1138 | else | 1138 | else |
1139 | nh_len = ((len + (L1_PAD_BOUNDARY - 1)) & ~(L1_PAD_BOUNDARY - 1)); | 1139 | nh_len = ((len + (L1_PAD_BOUNDARY - 1)) & ~(L1_PAD_BOUNDARY - 1)); |
1140 | extra_zeroes_needed = nh_len - len; | 1140 | extra_zeroes_needed = nh_len - len; |
@@ -1175,9 +1175,9 @@ static int uhash(uhash_ctx_t ahc, u_char *msg, long len, u_char *res) | |||
1175 | 1175 | ||
1176 | /* The UMAC interface has two interfaces, an all-at-once interface where | 1176 | /* The UMAC interface has two interfaces, an all-at-once interface where |
1177 | * the entire message to be authenticated is passed to UMAC in one buffer, | 1177 | * the entire message to be authenticated is passed to UMAC in one buffer, |
1178 | * and a sequential interface where the message is presented a little at a | 1178 | * and a sequential interface where the message is presented a little at a |
1179 | * time. The all-at-once is more optimaized than the sequential version and | 1179 | * time. The all-at-once is more optimaized than the sequential version and |
1180 | * should be preferred when the sequential interface is not required. | 1180 | * should be preferred when the sequential interface is not required. |
1181 | */ | 1181 | */ |
1182 | struct umac_ctx { | 1182 | struct umac_ctx { |
1183 | uhash_ctx hash; /* Hash function for message compression */ | 1183 | uhash_ctx hash; /* Hash function for message compression */ |
@@ -1213,7 +1213,7 @@ int umac_delete(struct umac_ctx *ctx) | |||
1213 | /* ---------------------------------------------------------------------- */ | 1213 | /* ---------------------------------------------------------------------- */ |
1214 | 1214 | ||
1215 | struct umac_ctx *umac_new(const u_char key[]) | 1215 | struct umac_ctx *umac_new(const u_char key[]) |
1216 | /* Dynamically allocate a umac_ctx struct, initialize variables, | 1216 | /* Dynamically allocate a umac_ctx struct, initialize variables, |
1217 | * generate subkeys from key. Align to 16-byte boundary. | 1217 | * generate subkeys from key. Align to 16-byte boundary. |
1218 | */ | 1218 | */ |
1219 | { | 1219 | { |
@@ -1263,7 +1263,7 @@ int umac_update(struct umac_ctx *ctx, const u_char *input, long len) | |||
1263 | /* ---------------------------------------------------------------------- */ | 1263 | /* ---------------------------------------------------------------------- */ |
1264 | 1264 | ||
1265 | #if 0 | 1265 | #if 0 |
1266 | int umac(struct umac_ctx *ctx, u_char *input, | 1266 | int umac(struct umac_ctx *ctx, u_char *input, |
1267 | long len, u_char tag[], | 1267 | long len, u_char tag[], |
1268 | u_char nonce[8]) | 1268 | u_char nonce[8]) |
1269 | /* All-in-one version simply calls umac_update() and umac_final(). */ | 1269 | /* All-in-one version simply calls umac_update() and umac_final(). */ |