Update multigest and libmultigest to version 20150211 + bring over lint fixes from the version in othersrc + document the concat, comb4p, xor and hash combiner functionsdiff -r1.1.1.1 -r1.2 pkgsrc/security/multigest/Makefile
(agc)
@@ -1,16 +1,16 @@ | @@ -1,16 +1,16 @@ | |||
1 | # $NetBSD: Makefile,v 1.1.1.1 2014/03/05 05:09:44 agc Exp $ | 1 | # $NetBSD: Makefile,v 1.2 2015/02/12 01:57:57 agc Exp $ | |
2 | 2 | |||
3 | DISTNAME= multigest-20140303 | 3 | DISTNAME= multigest-20150211 | |
4 | CATEGORIES= security | 4 | CATEGORIES= security | |
5 | MASTER_SITES= # not used | 5 | MASTER_SITES= # not used | |
6 | DISTFILES= # not used | 6 | DISTFILES= # not used | |
7 | 7 | |||
8 | MAINTAINER= agc@NetBSD.org | 8 | MAINTAINER= agc@NetBSD.org | |
9 | HOMEPAGE= http://www.NetBSD.org/ | 9 | HOMEPAGE= http://www.NetBSD.org/ | |
10 | COMMENT= Library and utility to calculate multiple message digests | 10 | COMMENT= Library and utility to calculate multiple message digests | |
11 | LICENSE= modified-bsd | 11 | LICENSE= modified-bsd | |
12 | 12 | |||
13 | AUTO_MKDIRS= yes | 13 | AUTO_MKDIRS= yes | |
14 | GNU_CONFIGURE= yes | 14 | GNU_CONFIGURE= yes | |
15 | 15 | |||
16 | do-extract: | 16 | do-extract: |
@@ -301,27 +301,27 @@ blake2b_init(BLAKE2_CTX *S, const uint8_ | @@ -301,27 +301,27 @@ blake2b_init(BLAKE2_CTX *S, const uint8_ | |||
301 | memset(P.personal, 0, sizeof(P.personal)); | 301 | memset(P.personal, 0, sizeof(P.personal)); | |
302 | return blake2b_init_param(S, &P); | 302 | return blake2b_init_param(S, &P); | |
303 | } | 303 | } | |
304 | 304 | |||
305 | 305 | |||
306 | static int | 306 | static int | |
307 | blake2b_compress(BLAKE2_CTX *S, const uint8_t block[BLAKE2B_BLOCKBYTES]) | 307 | blake2b_compress(BLAKE2_CTX *S, const uint8_t block[BLAKE2B_BLOCKBYTES]) | |
308 | { | 308 | { | |
309 | uint64_t m[16]; | 309 | uint64_t m[16]; | |
310 | uint64_t v[16]; | 310 | uint64_t v[16]; | |
311 | int i; | 311 | int i; | |
312 | 312 | |||
313 | for (i = 0; i < 16; ++i) { | 313 | for (i = 0; i < 16; ++i) { | |
314 | m[i] = load64(block + i * sizeof(m[i])); | 314 | m[i] = load64(block + (sizeof(m[i]) * (uint64_t)i)); | |
315 | } | 315 | } | |
316 | for (i = 0; i < 8; ++i) { | 316 | for (i = 0; i < 8; ++i) { | |
317 | v[i] = S->h[i]; | 317 | v[i] = S->h[i]; | |
318 | } | 318 | } | |
319 | v[8] = blake2b_IV[0]; | 319 | v[8] = blake2b_IV[0]; | |
320 | v[9] = blake2b_IV[1]; | 320 | v[9] = blake2b_IV[1]; | |
321 | v[10] = blake2b_IV[2]; | 321 | v[10] = blake2b_IV[2]; | |
322 | v[11] = blake2b_IV[3]; | 322 | v[11] = blake2b_IV[3]; | |
323 | v[12] = S->t[0] ^ blake2b_IV[4]; | 323 | v[12] = S->t[0] ^ blake2b_IV[4]; | |
324 | v[13] = S->t[1] ^ blake2b_IV[5]; | 324 | v[13] = S->t[1] ^ blake2b_IV[5]; | |
325 | v[14] = S->f[0] ^ blake2b_IV[6]; | 325 | v[14] = S->f[0] ^ blake2b_IV[6]; | |
326 | v[15] = S->f[1] ^ blake2b_IV[7]; | 326 | v[15] = S->f[1] ^ blake2b_IV[7]; | |
327 | #define G(r,i,a,b,c,d) do { \ | 327 | #define G(r,i,a,b,c,d) do { \ | |
@@ -402,18 +402,18 @@ blake2b_final(BLAKE2_CTX *S, uint8_t *ou | @@ -402,18 +402,18 @@ blake2b_final(BLAKE2_CTX *S, uint8_t *ou | |||
402 | 402 | |||
403 | if (S->buflen > BLAKE2B_BLOCKBYTES) { | 403 | if (S->buflen > BLAKE2B_BLOCKBYTES) { | |
404 | blake2b_increment_counter(S, BLAKE2B_BLOCKBYTES); | 404 | blake2b_increment_counter(S, BLAKE2B_BLOCKBYTES); | |
405 | blake2b_compress(S, S->buf); | 405 | blake2b_compress(S, S->buf); | |
406 | S->buflen -= BLAKE2B_BLOCKBYTES; | 406 | S->buflen -= BLAKE2B_BLOCKBYTES; | |
407 | memcpy(S->buf, S->buf + BLAKE2B_BLOCKBYTES, S->buflen); | 407 | memcpy(S->buf, S->buf + BLAKE2B_BLOCKBYTES, S->buflen); | |
408 | } | 408 | } | |
409 | blake2b_increment_counter(S, S->buflen); | 409 | blake2b_increment_counter(S, S->buflen); | |
410 | blake2b_set_lastblock(S); | 410 | blake2b_set_lastblock(S); | |
411 | memset(S->buf + S->buflen, 0, 2 * BLAKE2B_BLOCKBYTES - S->buflen); /* Padding */ | 411 | memset(S->buf + S->buflen, 0, 2 * BLAKE2B_BLOCKBYTES - S->buflen); /* Padding */ | |
412 | blake2b_compress(S, S->buf); | 412 | blake2b_compress(S, S->buf); | |
413 | for (i = 0; i < 8; ++i) { | 413 | for (i = 0; i < 8; ++i) { | |
414 | /* Output full hash to temp buffer */ | 414 | /* Output full hash to temp buffer */ | |
415 | store64(buffer + sizeof(S->h[i]) * i, S->h[i]); | 415 | store64(buffer + (sizeof(S->h[i]) * (uint64_t)i), S->h[i]); | |
416 | } | 416 | } | |
417 | memcpy(out, buffer, outlen); | 417 | memcpy(out, buffer, outlen); | |
418 | return 0; | 418 | return 0; | |
419 | } | 419 | } |
@@ -530,29 +530,29 @@ crc32c_sb8_64_bit(uint32_t crc, | @@ -530,29 +530,29 @@ crc32c_sb8_64_bit(uint32_t crc, | |||
530 | running_length = ((length - init_bytes) / 8) * 8; | 530 | running_length = ((length - init_bytes) / 8) * 8; | |
531 | end_bytes = length - init_bytes - running_length; | 531 | end_bytes = length - init_bytes - running_length; | |
532 | 532 | |||
533 | for (li = 0; li < init_bytes; li++) | 533 | for (li = 0; li < init_bytes; li++) | |
534 | crc = crc_tableil8_o32[(crc ^ *p_buf++) & 0x000000FF] ^ | 534 | crc = crc_tableil8_o32[(crc ^ *p_buf++) & 0x000000FF] ^ | |
535 | (crc >> 8); | 535 | (crc >> 8); | |
536 | for (li = 0; li < running_length / 8; li++) { | 536 | for (li = 0; li < running_length / 8; li++) { | |
537 | if (*(const char *)(const void *)&indian) { | 537 | if (*(const char *)(const void *)&indian) { | |
538 | /* little endian */ | 538 | /* little endian */ | |
539 | crc ^= *(const uint32_t *)(const void *) p_buf; | 539 | crc ^= *(const uint32_t *)(const void *) p_buf; | |
540 | p_buf += 4; | 540 | p_buf += 4; | |
541 | } else { | 541 | } else { | |
542 | crc ^= *p_buf++; | 542 | crc ^= *p_buf++; | |
543 | crc ^= (*p_buf++) << 8; | 543 | crc ^= (uint32_t)(*p_buf++) << 8; | |
544 | crc ^= (*p_buf++) << 16; | 544 | crc ^= (uint32_t)(*p_buf++) << 16; | |
545 | crc ^= (*p_buf++) << 24; | 545 | crc ^= (uint32_t)(*p_buf++) << 24; | |
546 | } | 546 | } | |
547 | term1 = crc_tableil8_o88[crc & 0x000000FF] ^ | 547 | term1 = crc_tableil8_o88[crc & 0x000000FF] ^ | |
548 | crc_tableil8_o80[(crc >> 8) & 0x000000FF]; | 548 | crc_tableil8_o80[(crc >> 8) & 0x000000FF]; | |
549 | term2 = crc >> 16; | 549 | term2 = crc >> 16; | |
550 | crc = term1 ^ | 550 | crc = term1 ^ | |
551 | crc_tableil8_o72[term2 & 0x000000FF] ^ | 551 | crc_tableil8_o72[term2 & 0x000000FF] ^ | |
552 | crc_tableil8_o64[(term2 >> 8) & 0x000000FF]; | 552 | crc_tableil8_o64[(term2 >> 8) & 0x000000FF]; | |
553 | if (*(const char *)(const void *)&indian) { | 553 | if (*(const char *)(const void *)&indian) { | |
554 | term1 = crc_tableil8_o56[(*(const uint32_t *)(const void *) p_buf) & 0x000000FF] ^ | 554 | term1 = crc_tableil8_o56[(*(const uint32_t *)(const void *) p_buf) & 0x000000FF] ^ | |
555 | crc_tableil8_o48[((*(const uint32_t *)(const void *) p_buf) >> 8) & 0x000000FF]; | 555 | crc_tableil8_o48[((*(const uint32_t *)(const void *) p_buf) >> 8) & 0x000000FF]; | |
556 | 556 | |||
557 | term2 = (*(const uint32_t *)(const void *) p_buf) >> 16; | 557 | term2 = (*(const uint32_t *)(const void *) p_buf) >> 16; | |
558 | crc = crc ^ | 558 | crc = crc ^ |
@@ -182,43 +182,43 @@ KeccakPermutationAfterXor(KECCAK_CTX *ct | @@ -182,43 +182,43 @@ KeccakPermutationAfterXor(KECCAK_CTX *ct | |||
182 | for (i = 0; i < dataLengthInBytes; i++) { | 182 | for (i = 0; i < dataLengthInBytes; i++) { | |
183 | state[i] ^= data[i]; | 183 | state[i] ^= data[i]; | |
184 | } | 184 | } | |
185 | keccak_permutation(ctx); | 185 | keccak_permutation(ctx); | |
186 | } | 186 | } | |
187 | 187 | |||
188 | static int | 188 | static int | |
189 | LFSR86540(uint8_t *LFSR) | 189 | LFSR86540(uint8_t *LFSR) | |
190 | { | 190 | { | |
191 | int result = ((*LFSR) & 0x01) != 0; | 191 | int result = ((*LFSR) & 0x01) != 0; | |
192 | 192 | |||
193 | if (((*LFSR) & 0x80) != 0) { | 193 | if (((*LFSR) & 0x80) != 0) { | |
194 | /* Primitive polynomial over GF(2): x^8+x^6+x^5+x^4+1 */ | 194 | /* Primitive polynomial over GF(2): x^8+x^6+x^5+x^4+1 */ | |
195 | (*LFSR) = ((*LFSR) << 1) ^ 0x71; | 195 | (*LFSR) = (uint8_t)((*LFSR) << 1) ^ 0x71; | |
196 | } else { | 196 | } else { | |
197 | (*LFSR) = (*LFSR) << 1; | 197 | (*LFSR) = (uint8_t)((*LFSR) << 1); | |
198 | } | 198 | } | |
199 | return result; | 199 | return result; | |
200 | } | 200 | } | |
201 | 201 | |||
202 | static void | 202 | static void | |
203 | keccak_initialise_RoundConstants(KECCAK_CTX *ctx) | 203 | keccak_initialise_RoundConstants(KECCAK_CTX *ctx) | |
204 | { | 204 | { | |
205 | uint8_t LFSRstate = 0x01; | 205 | uint8_t LFSRstate = 0x01; | |
206 | unsigned int i, j, bitPosition; | 206 | unsigned int i, j, bitPosition; | |
207 | 207 | |||
208 | for (i = 0; i < KECCAK_NUM_ROUNDS; i++) { | 208 | for (i = 0; i < KECCAK_NUM_ROUNDS; i++) { | |
209 | ctx->RoundConstants[i] = 0; | 209 | ctx->RoundConstants[i] = 0; | |
210 | for (j = 0; j < 7; j++) { | 210 | for (j = 0; j < 7; j++) { | |
211 | bitPosition = (1<<j)-1; /*2^j-1 */ | 211 | bitPosition = (unsigned)(1<<j)-1; /*2^j-1 */ | |
212 | if (LFSR86540(&LFSRstate)) { | 212 | if (LFSR86540(&LFSRstate)) { | |
213 | ctx->RoundConstants[i] ^= (uint64_t)1<<bitPosition; | 213 | ctx->RoundConstants[i] ^= (uint64_t)1<<bitPosition; | |
214 | } | 214 | } | |
215 | } | 215 | } | |
216 | } | 216 | } | |
217 | } | 217 | } | |
218 | 218 | |||
219 | static void | 219 | static void | |
220 | keccak_initialise_RhoOffsets(KECCAK_CTX *ctx) | 220 | keccak_initialise_RhoOffsets(KECCAK_CTX *ctx) | |
221 | { | 221 | { | |
222 | unsigned int x, y, t, newX, newY; | 222 | unsigned int x, y, t, newX, newY; | |
223 | 223 | |||
224 | ctx->RhoOffsets[INDEX(0, 0)] = 0; | 224 | ctx->RhoOffsets[INDEX(0, 0)] = 0; | |
@@ -288,49 +288,49 @@ absorb(KECCAK_CTX *ctx, const uint8_t *d | @@ -288,49 +288,49 @@ absorb(KECCAK_CTX *ctx, const uint8_t *d | |||
288 | partialBlock = (unsigned int)(databitlen - i); | 288 | partialBlock = (unsigned int)(databitlen - i); | |
289 | if (partialBlock+ctx->bitsInQueue > ctx->rate) { | 289 | if (partialBlock+ctx->bitsInQueue > ctx->rate) { | |
290 | partialBlock = ctx->rate-ctx->bitsInQueue; | 290 | partialBlock = ctx->rate-ctx->bitsInQueue; | |
291 | } | 291 | } | |
292 | partialByte = partialBlock % 8; | 292 | partialByte = partialBlock % 8; | |
293 | partialBlock -= partialByte; | 293 | partialBlock -= partialByte; | |
294 | memcpy(ctx->dataQueue+ctx->bitsInQueue/8, &data[(unsigned long)i/8], partialBlock/8); | 294 | memcpy(ctx->dataQueue+ctx->bitsInQueue/8, &data[(unsigned long)i/8], partialBlock/8); | |
295 | ctx->bitsInQueue += partialBlock; | 295 | ctx->bitsInQueue += partialBlock; | |
296 | i += partialBlock; | 296 | i += partialBlock; | |
297 | if (ctx->bitsInQueue == ctx->rate) { | 297 | if (ctx->bitsInQueue == ctx->rate) { | |
298 | absorb_queue(ctx); | 298 | absorb_queue(ctx); | |
299 | } | 299 | } | |
300 | if (partialByte > 0) { | 300 | if (partialByte > 0) { | |
301 | uint8_t mask = (1 << partialByte)-1; | 301 | uint8_t mask = (uint8_t)((1 << partialByte)-1); | |
302 | ctx->dataQueue[ctx->bitsInQueue/8] = data[(unsigned long)i/8] & mask; | 302 | ctx->dataQueue[ctx->bitsInQueue/8] = data[(unsigned long)i/8] & mask; | |
303 | ctx->bitsInQueue += partialByte; | 303 | ctx->bitsInQueue += partialByte; | |
304 | i += partialByte; | 304 | i += partialByte; | |
305 | } | 305 | } | |
306 | } | 306 | } | |
307 | } | 307 | } | |
308 | return 0; | 308 | return 0; | |
309 | } | 309 | } | |
310 | 310 | |||
311 | static void | 311 | static void | |
312 | PadAndSwitchToSqueezingPhase(KECCAK_CTX *ctx) | 312 | PadAndSwitchToSqueezingPhase(KECCAK_CTX *ctx) | |
313 | { | 313 | { | |
314 | /* Note: the bits are numbered from 0=LSB to 7=MSB */ | 314 | /* Note: the bits are numbered from 0=LSB to 7=MSB */ | |
315 | if (ctx->bitsInQueue + 1 == ctx->rate) { | 315 | if (ctx->bitsInQueue + 1 == ctx->rate) { | |
316 | ctx->dataQueue[ctx->bitsInQueue/8 ] |= 1 << (ctx->bitsInQueue % 8); | 316 | ctx->dataQueue[ctx->bitsInQueue/8 ] |= (uint8_t)(1 << (ctx->bitsInQueue % 8)); | |
317 | absorb_queue(ctx); | 317 | absorb_queue(ctx); | |
318 | memset(ctx->dataQueue, 0, ctx->rate/8); | 318 | memset(ctx->dataQueue, 0, ctx->rate/8); | |
319 | } else { | 319 | } else { | |
320 | memset(ctx->dataQueue + (ctx->bitsInQueue+7)/8, 0, ctx->rate/8 - (ctx->bitsInQueue+7)/8); | 320 | memset(ctx->dataQueue + (ctx->bitsInQueue+7)/8, 0, ctx->rate/8 - (ctx->bitsInQueue+7)/8); | |
321 | ctx->dataQueue[ctx->bitsInQueue/8 ] |= 1 << (ctx->bitsInQueue % 8); | 321 | ctx->dataQueue[ctx->bitsInQueue/8 ] |= (uint8_t)(1 << (ctx->bitsInQueue % 8)); | |
322 | } | 322 | } | |
323 | ctx->dataQueue[(ctx->rate-1)/8] |= 1 << ((ctx->rate-1) % 8); | 323 | ctx->dataQueue[(ctx->rate-1)/8] |= (uint8_t)(1 << ((ctx->rate-1) % 8)); | |
324 | absorb_queue(ctx); | 324 | absorb_queue(ctx); | |
325 | memcpy(ctx->dataQueue, ctx->state, ctx->rate/8); | 325 | memcpy(ctx->dataQueue, ctx->state, ctx->rate/8); | |
326 | ctx->bitsAvailableForSqueezing = ctx->rate; | 326 | ctx->bitsAvailableForSqueezing = ctx->rate; | |
327 | ctx->squeezing = 1; | 327 | ctx->squeezing = 1; | |
328 | } | 328 | } | |
329 | 329 | |||
330 | static int | 330 | static int | |
331 | squeeze(KECCAK_CTX *ctx, uint8_t *output, uint64_t outputLength) | 331 | squeeze(KECCAK_CTX *ctx, uint8_t *output, uint64_t outputLength) | |
332 | { | 332 | { | |
333 | uint64_t i; | 333 | uint64_t i; | |
334 | unsigned int partialBlock; | 334 | unsigned int partialBlock; | |
335 | 335 | |||
336 | if (!ctx->squeezing) { | 336 | if (!ctx->squeezing) { | |
@@ -371,41 +371,41 @@ KECCAK_Init(KECCAK_CTX *ctx, int hashbit | @@ -371,41 +371,41 @@ KECCAK_Init(KECCAK_CTX *ctx, int hashbit | |||
371 | break; | 371 | break; | |
372 | case 256: | 372 | case 256: | |
373 | init_sponge((KECCAK_CTX*)ctx, 1088, 512); | 373 | init_sponge((KECCAK_CTX*)ctx, 1088, 512); | |
374 | break; | 374 | break; | |
375 | case 384: | 375 | case 384: | |
376 | init_sponge((KECCAK_CTX*)ctx, 832, 768); | 376 | init_sponge((KECCAK_CTX*)ctx, 832, 768); | |
377 | break; | 377 | break; | |
378 | case 512: | 378 | case 512: | |
379 | init_sponge((KECCAK_CTX*)ctx, 576, 1024); | 379 | init_sponge((KECCAK_CTX*)ctx, 576, 1024); | |
380 | break; | 380 | break; | |
381 | default: | 381 | default: | |
382 | return BAD_HASHLEN; | 382 | return BAD_HASHLEN; | |
383 | } | 383 | } | |
384 | ctx->fixedOutputLength = hashbitlen; | 384 | ctx->fixedOutputLength = (uint32_t)hashbitlen; | |
385 | return SUCCESS; | 385 | return SUCCESS; | |
386 | } | 386 | } | |
387 | 387 | |||
388 | HashReturn | 388 | HashReturn | |
389 | KECCAK_Update(KECCAK_CTX *ctx, const uint8_t *data, uint64_t databitlen) | 389 | KECCAK_Update(KECCAK_CTX *ctx, const uint8_t *data, uint64_t databitlen) | |
390 | { | 390 | { | |
391 | HashReturn ret; | 391 | HashReturn ret; | |
392 | 392 | |||
393 | if ((databitlen % 8) == 0) { | 393 | if ((databitlen % 8) == 0) { | |
394 | return absorb((KECCAK_CTX*)ctx, data, databitlen); | 394 | return absorb((KECCAK_CTX*)ctx, data, databitlen); | |
395 | } | 395 | } | |
396 | ret = absorb((KECCAK_CTX*)ctx, data, databitlen - (databitlen % 8)); | 396 | ret = absorb((KECCAK_CTX*)ctx, data, databitlen - (databitlen % 8)); | |
397 | if (ret == SUCCESS) { | 397 | if (ret == SUCCESS) { | |
398 | uint8_t lastByte; | 398 | uint8_t lastByte; | |
399 | 399 | |||
400 | /* Align the last partial byte to the least significant bits */ | 400 | /* Align the last partial byte to the least significant bits */ | |
401 | lastByte = data[(unsigned long)databitlen/8] >> (8 - (databitlen % 8)); | 401 | lastByte = (uint8_t)(data[(unsigned long)databitlen/8] >> (8 - (databitlen % 8))); | |
402 | return absorb((KECCAK_CTX*)ctx, &lastByte, databitlen % 8); | 402 | return absorb((KECCAK_CTX*)ctx, &lastByte, databitlen % 8); | |
403 | } | 403 | } | |
404 | return ret; | 404 | return ret; | |
405 | } | 405 | } | |
406 | 406 | |||
407 | HashReturn | 407 | HashReturn | |
408 | KECCAK_Final(KECCAK_CTX *ctx, uint8_t *hashval) | 408 | KECCAK_Final(KECCAK_CTX *ctx, uint8_t *hashval) | |
409 | { | 409 | { | |
410 | return squeeze(ctx, hashval, ctx->fixedOutputLength); | 410 | return squeeze(ctx, hashval, ctx->fixedOutputLength); | |
411 | } | 411 | } |
@@ -1,71 +1,71 @@ | @@ -1,71 +1,71 @@ | |||
1 | .\" $NetBSD: libmultigest.3,v 1.1.1.1 2014/03/05 05:09:44 agc Exp $ | 1 | .\" $NetBSD: libmultigest.3,v 1.2 2015/02/12 01:57:57 agc Exp $ | |
2 | .\" | 2 | .\" | |
3 | .\" Copyright (c) 2013,2014 Alistair Crooks <agc@NetBSD.org> | 3 | .\" Copyright (c) 2013,2014,2015 Alistair Crooks <agc@NetBSD.org> | |
4 | .\" All rights reserved. | 4 | .\" All rights reserved. | |
5 | .\" | 5 | .\" | |
6 | .\" Redistribution and use in source and binary forms, with or without | 6 | .\" Redistribution and use in source and binary forms, with or without | |
7 | .\" modification, are permitted provided that the following conditions | 7 | .\" modification, are permitted provided that the following conditions | |
8 | .\" are met: | 8 | .\" are met: | |
9 | .\" 1. Redistributions of source code must retain the above copyright | 9 | .\" 1. Redistributions of source code must retain the above copyright | |
10 | .\" notice, this list of conditions and the following disclaimer. | 10 | .\" notice, this list of conditions and the following disclaimer. | |
11 | .\" 2. Redistributions in binary form must reproduce the above copyright | 11 | .\" 2. Redistributions in binary form must reproduce the above copyright | |
12 | .\" notice, this list of conditions and the following disclaimer in the | 12 | .\" notice, this list of conditions and the following disclaimer in the | |
13 | .\" documentation and/or other materials provided with the distribution. | 13 | .\" documentation and/or other materials provided with the distribution. | |
14 | .\" | 14 | .\" | |
15 | .\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | 15 | .\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | |
16 | .\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | 16 | .\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |
17 | .\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | 17 | .\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | |
18 | .\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | 18 | .\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | |
19 | .\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | 19 | .\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |
20 | .\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 20 | .\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
21 | .\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 21 | .\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
22 | .\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 22 | .\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
23 | .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 23 | .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | |
24 | .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 24 | .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
25 | .\" | 25 | .\" | |
26 | .Dd March 3, 2014 | 26 | .Dd February 11, 2015 | |
27 | .Dt LIBMULTIGEST 3 | 27 | .Dt LIBMULTIGEST 3 | |
28 | .Os | 28 | .Os | |
29 | .Sh NAME | 29 | .Sh NAME | |
30 | .Nm libmultigest | 30 | .Nm libmultigest | |
31 | .Nd Multiple digest library | 31 | .Nd Multiple digest library | |
32 | .Sh LIBRARY | 32 | .Sh LIBRARY | |
33 | .Lb libmultigest | 33 | .Lb libmultigest | |
34 | .Sh SYNOPSIS | 34 | .Sh SYNOPSIS | |
35 | .In multigest.h | 35 | .In multigest.h | |
36 | .Ft multigest_t * | 36 | .Ft multigest_t * | |
37 | .Fo multigest_new | 37 | .Fo multigest_new | |
38 | .Fa "void" | 38 | .Fa "void" | |
39 | .Fc | 39 | .Fc | |
40 | .Ft int | 40 | .Ft int | |
41 | .Fo multigest_init | 41 | .Fo multigest_init | |
42 | .Fa "multigest_t *mg" "const char *algorithms" | 42 | .Fa "multigest_t *mg" "const char *algorithms" | |
43 | .Fc | 43 | .Fc | |
44 | .Ft int | 44 | .Ft int | |
45 | .Fo multigest_add_subst | 45 | .Fo multigest_add_subst | |
46 | .Fa "multigest_t *mg" "const char *substregex" "const char *replacement" | 46 | .Fa "multigest_t *mg" "const char *substregex" "const char *replacement" | |
47 | .Fc | 47 | .Fc | |
48 | .Ft void | 48 | .Ft void | |
49 | .Fo multigest_update | 49 | .Fo multigest_update | |
50 | .Fa "multigest_t *mg" "const char *data" "size_t length" | 50 | .Fa "multigest_t *mg" "const void *data" "size_t length" | |
51 | .Fc | 51 | .Fc | |
52 | .Ft void | 52 | .Ft void | |
53 | .Fo multigest_final | 53 | .Fo multigest_final | |
54 | .Fa "unsigned char *rawdigest" "multigest_t *mg" | 54 | .Fa "unsigned char *rawdigest" "multigest_t *mg" | |
55 | .Fc | 55 | .Fc | |
56 | .Ft "uint8_t *" | 56 | .Ft "uint8_t *" | |
57 | .Fo multigest_data | 57 | .Fo multigest_data | |
58 | .Fa "const char *algorithms" "const char *data" "size_t length" | 58 | .Fa "const char *algorithms" "const void *data" "size_t length" | |
59 | .Fa "const unsigned char *rawoutput" "const char *substregex" | 59 | .Fa "const unsigned char *rawoutput" "const char *substregex" | |
60 | .Fa "const char *replacement" | 60 | .Fa "const char *replacement" | |
61 | .Fc | 61 | .Fc | |
62 | .Ft "uint8_t *" | 62 | .Ft "uint8_t *" | |
63 | .Fo multigest_file | 63 | .Fo multigest_file | |
64 | .Fa "const char *algorithms" "const char *filename" | 64 | .Fa "const char *algorithms" "const char *filename" | |
65 | .Fa "const unsigned char *rawoutput" "const char *substregex" | 65 | .Fa "const unsigned char *rawoutput" "const char *substregex" | |
66 | .Fa "const char *replacement" | 66 | .Fa "const char *replacement" | |
67 | .Fc | 67 | .Fc | |
68 | .Ft uint32_t | 68 | .Ft uint32_t | |
69 | .Fo multigest_get_rawsize | 69 | .Fo multigest_get_rawsize | |
70 | .Fa "multigest_t *mg" | 70 | .Fa "multigest_t *mg" | |
71 | .Fc | 71 | .Fc | |
@@ -113,26 +113,34 @@ RMD160 | @@ -113,26 +113,34 @@ RMD160 | |||
113 | SHA1 | 113 | SHA1 | |
114 | SHA256 | 114 | SHA256 | |
115 | SHA3-224 | 115 | SHA3-224 | |
116 | SHA3-256 | 116 | SHA3-256 | |
117 | SHA3-384 | 117 | SHA3-384 | |
118 | SHA3-512 | 118 | SHA3-512 | |
119 | SHA512 | 119 | SHA512 | |
120 | SIZE | 120 | SIZE | |
121 | TIGER2 | 121 | TIGER2 | |
122 | TIGER | 122 | TIGER | |
123 | WHIRLPOOL | 123 | WHIRLPOOL | |
124 | .Ed | 124 | .Ed | |
125 | .Pp | 125 | .Pp | |
126 | In addition, a number of hash combiner functions are defined: | |||
127 | .Bd -literal -offset indent | |||
128 | CONCAT | |||
129 | HASH | |||
130 | XOR | |||
131 | COMB4P | |||
132 | .Ed | |||
133 | .Pp | |||
126 | The | 134 | The | |
127 | .Dv crc32c | 135 | .Dv crc32c | |
128 | checksum is a simple, lightweight checksum, as found in SCTP and iSCSI. | 136 | checksum is a simple, lightweight checksum, as found in SCTP and iSCSI. | |
129 | It is useful since there are times when a secure digest is not needed, | 137 | It is useful since there are times when a secure digest is not needed, | |
130 | but rather an indication of correct transmission, where calculating a heavyweight | 138 | but rather an indication of correct transmission, where calculating a heavyweight | |
131 | digest may be overkill. | 139 | digest may be overkill. | |
132 | The | 140 | The | |
133 | .Dv TIGER2 | 141 | .Dv TIGER2 | |
134 | digest is different to the | 142 | digest is different to the | |
135 | .Dv TIGER | 143 | .Dv TIGER | |
136 | digest in its initialisation only. | 144 | digest in its initialisation only. | |
137 | Obviously, different values are calculated for the two digests. | 145 | Obviously, different values are calculated for the two digests. | |
138 | The | 146 | The | |
@@ -144,26 +152,69 @@ The winning SHA-3 contender, the sponge | @@ -144,26 +152,69 @@ The winning SHA-3 contender, the sponge | |||
144 | has been | 152 | has been | |
145 | included here, with 4 different digest lengths, of 224, 256, 384 and 512 bits. | 153 | included here, with 4 different digest lengths, of 224, 256, 384 and 512 bits. | |
146 | The | 154 | The | |
147 | .Dv size | 155 | .Dv size | |
148 | pseudo-algorithm simply prints the size of the input data in bytes. | 156 | pseudo-algorithm simply prints the size of the input data in bytes. | |
149 | .Pp | 157 | .Pp | |
150 | As the | 158 | As the | |
151 | .Nm | 159 | .Nm | |
152 | name suggests, multiple digests can be used to calculate compound digests. | 160 | name suggests, multiple digests can be used to calculate compound digests. | |
153 | The output from each digest is concatenated on the output. | 161 | The output from each digest is concatenated on the output. | |
154 | Digest names are provided to the initialisation function in a comma-separated | 162 | Digest names are provided to the initialisation function in a comma-separated | |
155 | list of names. | 163 | list of names. | |
156 | .Pp | 164 | .Pp | |
165 | The combiner functions define how the individual digests will be combined | |||
166 | in the finalisation stage. | |||
167 | They have different qualities, and different uses. | |||
168 | .Pp | |||
169 | The | |||
170 | .Dq CONCAT | |||
171 | algorithm, the default, simply concatenates the digests in the output. | |||
172 | It is useful when collision resistance is needed, but not pre-image resistance, | |||
173 | second pre-image resistance or PRF functionality. | |||
174 | .Pp | |||
175 | The | |||
176 | .Dq Comb4P | |||
177 | combiner should be used when collision resistance is needed, | |||
178 | or as a PRF, where target-collision resistance is needed, or | |||
179 | as a MAC. | |||
180 | However, this combiner is not as efficient as the other combiner algorithms, | |||
181 | requiring more CPU cycles. | |||
182 | .Pp | |||
183 | The | |||
184 | .Dq XOR | |||
185 | combiner xors the first two digests together. | |||
186 | This is useful as a PRF, but not where | |||
187 | collision resistance is needed. | |||
188 | .Pp | |||
189 | Finally, the | |||
190 | .Dq HASH | |||
191 | combiner takes the output of the second digest's | |||
192 | finalisation routine, and passes that as an update to the current state of | |||
193 | the first digest, and then finalises the multigest. | |||
194 | This is useful where pre-image resistance is needed, | |||
195 | but should not be used if collision resistance is needed. | |||
196 | .Pp | |||
197 | If less than two digest algorithms are provided in conjunction | |||
198 | with a combiner function, a zero multigest will result. | |||
199 | In addition, if the | |||
200 | .Dq XOR | |||
201 | combiner is given the same digest function as input, a zero | |||
202 | multigest will result. | |||
203 | The | |||
204 | .Dq Comb4P | |||
205 | combiner should be given two digests of the same size, | |||
206 | or a zero multigest will result. | |||
207 | .Pp | |||
157 | There are two interfaces to the | 208 | There are two interfaces to the | |
158 | .Nm | 209 | .Nm | |
159 | library, one using the lower-level functions | 210 | library, one using the lower-level functions | |
160 | .Fn multigest_init , | 211 | .Fn multigest_init , | |
161 | .Fn multigest_update | 212 | .Fn multigest_update | |
162 | and | 213 | and | |
163 | .Fn multigest_final | 214 | .Fn multigest_final | |
164 | to calculate the digests. | 215 | to calculate the digests. | |
165 | The other, higher-level interface, | 216 | The other, higher-level interface, | |
166 | uses the functions | 217 | uses the functions | |
167 | .Fn mutigest_data | 218 | .Fn mutigest_data | |
168 | and | 219 | and | |
169 | .Fn multigest_file | 220 | .Fn multigest_file | |
@@ -187,16 +238,16 @@ function can be used, passing the digest | @@ -187,16 +238,16 @@ function can be used, passing the digest | |||
187 | arguments to the function, or the | 238 | arguments to the function, or the | |
188 | .Fn multigest_get_rawsize | 239 | .Fn multigest_get_rawsize | |
189 | function can be used if the multigest structure has already | 240 | function can be used if the multigest structure has already | |
190 | been initialised. | 241 | been initialised. | |
191 | .Sh SEE ALSO | 242 | .Sh SEE ALSO | |
192 | .Xr md5 3 , | 243 | .Xr md5 3 , | |
193 | .Xr rmd160 3 , | 244 | .Xr rmd160 3 , | |
194 | .Xr sha1 3 , | 245 | .Xr sha1 3 , | |
195 | .Xr sha2 3 | 246 | .Xr sha2 3 | |
196 | .Sh HISTORY | 247 | .Sh HISTORY | |
197 | The | 248 | The | |
198 | .Nm | 249 | .Nm | |
199 | library first appeared in | 250 | library first appeared in | |
200 | .Nx 7.0 . | 251 | .Nx 8.0 . | |
201 | .Sh AUTHORS | 252 | .Sh AUTHORS | |
202 | .An Alistair Crooks Aq Mt agc@NetBSD.org . | 253 | .An Alistair Crooks Aq Mt agc@NetBSD.org . |
@@ -31,32 +31,32 @@ | @@ -31,32 +31,32 @@ | |||
31 | #include <stdlib.h> | 31 | #include <stdlib.h> | |
32 | #include <string.h> | 32 | #include <string.h> | |
33 | #include <unistd.h> | 33 | #include <unistd.h> | |
34 | 34 | |||
35 | #include "multigest.h" | 35 | #include "multigest.h" | |
36 | 36 | |||
37 | 37 | |||
38 | #define MB(x) ((x) * 1024 * 1024) | 38 | #define MB(x) ((x) * 1024 * 1024) | |
39 | 39 | |||
40 | /* read input into memory, and then multigest that */ | 40 | /* read input into memory, and then multigest that */ | |
41 | static int | 41 | static int | |
42 | do_input(const char *alg, uint8_t *raw, const char *pat, const char *repl) | 42 | do_input(const char *alg, uint8_t *raw, const char *pat, const char *repl) | |
43 | { | 43 | { | |
44 | ssize_t rc; | |||
44 | size_t cc; | 45 | size_t cc; | |
45 | size_t rc; | |||
46 | char *data; | 46 | char *data; | |
47 | 47 | |||
48 | if ((data = calloc(1, MB(4))) != NULL) { | 48 | if ((data = calloc(1, MB(4))) != NULL) { | |
49 | for (cc = 0 ; cc < MB(4) ; cc += rc) { | 49 | for (cc = 0 ; cc < MB(4) ; cc += (size_t)rc) { | |
50 | if ((rc = read(fileno(stdin), &data[cc], MB(4) - cc)) <= 0) { | 50 | if ((rc = read(fileno(stdin), &data[cc], MB(4) - cc)) <= 0) { | |
51 | break; | 51 | break; | |
52 | } | 52 | } | |
53 | } | 53 | } | |
54 | multigest_data(alg, data, cc, raw, pat, repl); | 54 | multigest_data(alg, data, cc, raw, pat, repl); | |
55 | free(data); | 55 | free(data); | |
56 | return 1; | 56 | return 1; | |
57 | } | 57 | } | |
58 | return 0; | 58 | return 0; | |
59 | } | 59 | } | |
60 | 60 | |||
61 | /* get the substitution pattern from the arg */ | 61 | /* get the substitution pattern from the arg */ | |
62 | static int | 62 | static int | |
@@ -100,46 +100,46 @@ read_check(const char *check) | @@ -100,46 +100,46 @@ read_check(const char *check) | |||
100 | char to[128]; | 100 | char to[128]; | |
101 | char *file; | 101 | char *file; | |
102 | char *subs; | 102 | char *subs; | |
103 | char *alg; | 103 | char *alg; | |
104 | char *in; | 104 | char *in; | |
105 | int ret; | 105 | int ret; | |
106 | 106 | |||
107 | regcomp(&r, "([^ ]+) \\(([^)]+)\\) \\((.*)\\) = ([0-9a-zA-Z]+)", REG_EXTENDED); | 107 | regcomp(&r, "([^ ]+) \\(([^)]+)\\) \\((.*)\\) = ([0-9a-zA-Z]+)", REG_EXTENDED); | |
108 | if ((fp = fopen(check, "r")) == NULL) { | 108 | if ((fp = fopen(check, "r")) == NULL) { | |
109 | fprintf(stderr, "can't check existing file '%s'\n", check); | 109 | fprintf(stderr, "can't check existing file '%s'\n", check); | |
110 | return 0; | 110 | return 0; | |
111 | } | 111 | } | |
112 | fstat(fileno(fp), &st); | 112 | fstat(fileno(fp), &st); | |
113 | if ((in = calloc(1, st.st_size + 1)) == NULL) { | 113 | if ((in = calloc(1, (size_t)(st.st_size + 1))) == NULL) { | |
114 | fclose(fp); | 114 | fclose(fp); | |
115 | return 0; | 115 | return 0; | |
116 | } | 116 | } | |
117 | read(fileno(fp), in, st.st_size); | 117 | read(fileno(fp), in, (size_t)(st.st_size)); | |
118 | in[st.st_size] = 0x0; | 118 | in[st.st_size] = 0x0; | |
119 | fclose(fp); | 119 | fclose(fp); | |
120 | if (regexec(&r, in, 10, match, 0) != 0) { | 120 | if (regexec(&r, in, 10, match, 0) != 0) { | |
121 | free(in); | 121 | free(in); | |
122 | return 0; | 122 | return 0; | |
123 | } | 123 | } | |
124 | alg = &in[match[1].rm_so]; | 124 | alg = &in[match[1].rm_so]; | |
125 | file = &in[match[2].rm_so]; | 125 | file = &in[match[2].rm_so]; | |
126 | subs = &in[match[3].rm_so]; | 126 | subs = &in[match[3].rm_so]; | |
127 | provided = &in[match[4].rm_so]; | 127 | provided = &in[match[4].rm_so]; | |
128 | in[match[1].rm_eo] = in[match[2].rm_eo] = in[match[3].rm_eo] = in[match[4].rm_eo] = 0x0; | 128 | in[match[1].rm_eo] = in[match[2].rm_eo] = in[match[3].rm_eo] = in[match[4].rm_eo] = 0x0; | |
129 | getsubst(subs, from, sizeof(from), to, sizeof(to)); | 129 | getsubst(subs, from, sizeof(from), to, sizeof(to)); | |
130 | multigest_file(alg, file, raw, from, to); | 130 | multigest_file(alg, file, raw, from, to); | |
131 | multigest_format_hex(raw, alg, calc, sizeof(calc)); | 131 | multigest_format_hex(raw, alg, calc, sizeof(calc)); | |
132 | if ((ret = memcmp(calc, provided, match[4].rm_eo - match[4].rm_so)) != 0) { | 132 | if ((ret = memcmp(calc, provided, (size_t)(match[4].rm_eo - match[4].rm_so))) != 0) { | |
133 | fprintf(stderr, "multigest: provided digest: '%s', calculated digest: '%s'\n", provided, calc); | 133 | fprintf(stderr, "multigest: provided digest: '%s', calculated digest: '%s'\n", provided, calc); | |
134 | } | 134 | } | |
135 | regfree(&r); | 135 | regfree(&r); | |
136 | free(in); | 136 | free(in); | |
137 | return ret == 0; | 137 | return ret == 0; | |
138 | } | 138 | } | |
139 | 139 | |||
140 | int | 140 | int | |
141 | main(int argc, char **argv) | 141 | main(int argc, char **argv) | |
142 | { | 142 | { | |
143 | const char *outname; | 143 | const char *outname; | |
144 | const char *format; | 144 | const char *format; | |
145 | const char *check; | 145 | const char *check; |
@@ -1,15 +1,15 @@ | @@ -1,15 +1,15 @@ | |||
1 | /*- | 1 | /*- | |
2 | * Copyright (c) 2013 Alistair Crooks <agc@NetBSD.org> | 2 | * Copyright (c) 2013,2015 Alistair Crooks <agc@NetBSD.org> | |
3 | * All rights reserved. | 3 | * All rights reserved. | |
4 | * | 4 | * | |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without | |
6 | * modification, are permitted provided that the following conditions | 6 | * modification, are permitted provided that the following conditions | |
7 | * are met: | 7 | * are met: | |
8 | * 1. Redistributions of source code must retain the above copyright | 8 | * 1. Redistributions of source code must retain the above copyright | |
9 | * notice, this list of conditions and the following disclaimer. | 9 | * notice, this list of conditions and the following disclaimer. | |
10 | * 2. Redistributions in binary form must reproduce the above copyright | 10 | * 2. Redistributions in binary form must reproduce the above copyright | |
11 | * notice, this list of conditions and the following disclaimer in the | 11 | * notice, this list of conditions and the following disclaimer in the | |
12 | * documentation and/or other materials provided with the distribution. | 12 | * documentation and/or other materials provided with the distribution. | |
13 | * | 13 | * | |
14 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | 14 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | |
15 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | 15 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |
@@ -76,305 +76,357 @@ | @@ -76,305 +76,357 @@ | |||
76 | * it easier to add digest functions. | 76 | * it easier to add digest functions. | |
77 | * | 77 | * | |
78 | * The table is searched once at initialisation time, and so there is | 78 | * The table is searched once at initialisation time, and so there is | |
79 | * only one table scan to find the correct digest algorithm. | 79 | * only one table scan to find the correct digest algorithm. | |
80 | * Algorithms are searched in a case-insensitive manner. | 80 | * Algorithms are searched in a case-insensitive manner. | |
81 | * The text for the algorithm name in the algs table is printed as the | 81 | * The text for the algorithm name in the algs table is printed as the | |
82 | * name of the algorithm in the output. Convention has this as upper | 82 | * name of the algorithm in the output. Convention has this as upper | |
83 | * case. | 83 | * case. | |
84 | */ | 84 | */ | |
85 | 85 | |||
86 | /*****/ | 86 | /*****/ | |
87 | 87 | |||
88 | static void | 88 | static void | |
89 | wrap_sha1_init(void *v) | 89 | wrap_md5_init(void *v) | |
90 | { | 90 | { | |
91 | SHA1Init(v); | 91 | MD5Init(v); | |
92 | } | 92 | } | |
93 | 93 | |||
94 | static void | 94 | static void | |
95 | wrap_md5_init(void *v) | 95 | wrap_md5_update(void *v, const void *data, unsigned len) | |
96 | { | 96 | { | |
97 | MD5Init(v); | 97 | MD5Update(v, (const uint8_t *)data, len); | |
98 | } | 98 | } | |
99 | 99 | |||
100 | static void | 100 | static void | |
101 | wrap_sha256_init(void *v) | 101 | wrap_md5_final(uint8_t *raw, void *v) | |
102 | { | 102 | { | |
103 | SHA256_Init(v); | 103 | MD5Final(raw, v); | |
104 | } | 104 | } | |
105 | 105 | |||
106 | /*****/ | |||
107 | ||||
106 | static void | 108 | static void | |
107 | wrap_sha512_init(void *v) | 109 | wrap_sha1_init(void *v) | |
108 | { | 110 | { | |
109 | SHA512_Init(v); | 111 | SHA1Init(v); | |
110 | } | 112 | } | |
111 | 113 | |||
112 | static void | 114 | static void | |
113 | wrap_rmd160_init(void *v) | 115 | wrap_sha1_update(void *v, const void *data, unsigned len) | |
114 | { | 116 | { | |
115 | RMD160Init(v); | 117 | SHA1Update(v, (const uint8_t *)data, len); | |
116 | } | 118 | } | |
117 | 119 | |||
118 | static void | 120 | static void | |
119 | wrap_crc32c_init(void *v) | 121 | wrap_sha1_final(uint8_t *raw, void *v) | |
120 | { | 122 | { | |
121 | crc32c_init(v); | 123 | SHA1Final(raw, v); | |
122 | } | 124 | } | |
123 | 125 | |||
126 | /*****/ | |||
127 | ||||
124 | static void | 128 | static void | |
125 | wrap_tiger_init(void *v) | 129 | wrap_sha256_init(void *v) | |
126 | { | 130 | { | |
127 | TIGER_Init(v); | 131 | SHA256_Init(v); | |
128 | } | 132 | } | |
129 | 133 | |||
130 | static void | 134 | static void | |
131 | wrap_tiger2_init(void *v) | 135 | wrap_sha256_update(void *v, const void *data, unsigned len) | |
132 | { | 136 | { | |
133 | TIGER2_Init(v); | 137 | SHA256_Update(v, (const uint8_t *)data, len); | |
134 | } | 138 | } | |
135 | 139 | |||
136 | static void | 140 | static void | |
137 | wrap_blake2_init(void *v) | 141 | wrap_sha256_final(uint8_t *raw, void *v) | |
138 | { | 142 | { | |
139 | blake2b_init(v, 64); | 143 | SHA256_Final(raw, v); | |
140 | } | 144 | } | |
141 | 145 | |||
146 | /*****/ | |||
147 | ||||
142 | static void | 148 | static void | |
143 | wrap_whirlpool_init(void *v) | 149 | wrap_sha512_init(void *v) | |
144 | { | 150 | { | |
145 | whirlpool_init(v); | 151 | SHA512_Init(v); | |
146 | } | 152 | } | |
147 | 153 | |||
148 | static void | 154 | static void | |
149 | wrap_keccak224_init(void *v) | 155 | wrap_sha512_update(void *v, const void *data, unsigned len) | |
150 | { | 156 | { | |
151 | KECCAK_Init(v, 224); | 157 | SHA512_Update(v, (const uint8_t *)data, len); | |
152 | } | 158 | } | |
153 | 159 | |||
154 | static void | 160 | static void | |
155 | wrap_keccak256_init(void *v) | 161 | wrap_sha512_final(uint8_t *raw, void *v) | |
156 | { | 162 | { | |
157 | KECCAK_Init(v, 256); | 163 | SHA512_Final(raw, v); | |
158 | } | 164 | } | |
159 | 165 | |||
166 | /*****/ | |||
167 | ||||
160 | static void | 168 | static void | |
161 | wrap_keccak384_init(void *v) | 169 | wrap_rmd160_init(void *v) | |
162 | { | 170 | { | |
163 | KECCAK_Init(v, 384); | 171 | RMD160Init(v); | |
164 | } | 172 | } | |
165 | 173 | |||
166 | static void | 174 | static void | |
167 | wrap_keccak512_init(void *v) | 175 | wrap_rmd160_update(void *v, const void *data, unsigned len) | |
168 | { | 176 | { | |
169 | KECCAK_Init(v, 512); | 177 | RMD160Update(v, (const uint8_t *)data, len); | |
170 | } | 178 | } | |
171 | 179 | |||
172 | static void | 180 | static void | |
173 | wrap_size_init(void *v) | 181 | wrap_rmd160_final(uint8_t *raw, void *v) | |
174 | { | 182 | { | |
175 | memset(v, 0x0, sizeof(uint64_t)); | 183 | RMD160Final(raw, v); | |
176 | } | 184 | } | |
177 | 185 | |||
178 | /*****/ | 186 | /*****/ | |
179 | 187 | |||
180 | static void | 188 | static void | |
181 | wrap_md5_update(void *v, const char *data, unsigned len) | 189 | wrap_crc32c_init(void *v) | |
182 | { | 190 | { | |
183 | MD5Update(v, (const uint8_t *)data, len); | 191 | crc32c_init(v); | |
184 | } | 192 | } | |
185 | 193 | |||
186 | static void | 194 | static void | |
187 | wrap_sha1_update(void *v, const char *data, unsigned len) | 195 | wrap_crc32c_update(void *v, const void *data, unsigned len) | |
188 | { | 196 | { | |
189 | SHA1Update(v, (const uint8_t *)data, len); | 197 | crc32c_update(v, (const uint8_t *)data, len); | |
190 | } | 198 | } | |
191 | 199 | |||
192 | static void | 200 | static void | |
193 | wrap_sha256_update(void *v, const char *data, unsigned len) | 201 | wrap_crc32c_final(uint8_t *raw, void *v) | |
194 | { | 202 | { | |
195 | SHA256_Update(v, (const uint8_t *)data, len); | 203 | crc32c_final((ctx32_t *)(void *)raw, v); | |
196 | } | 204 | } | |
197 | 205 | |||
198 | static void | 206 | /*****/ | |
199 | wrap_sha512_update(void *v, const char *data, unsigned len) | |||
200 | { | |||
201 | SHA512_Update(v, (const uint8_t *)data, len); | |||
202 | } | |||
203 | 207 | |||
204 | static void | 208 | static void | |
205 | wrap_rmd160_update(void *v, const char *data, unsigned len) | 209 | wrap_tiger_init(void *v) | |
206 | { | 210 | { | |
207 | RMD160Update(v, (const uint8_t *)data, len); | 211 | TIGER_Init(v); | |
208 | } | 212 | } | |
209 | 213 | |||
210 | static void | 214 | static void | |
211 | wrap_crc32c_update(void *v, const char *data, unsigned len) | 215 | wrap_tiger2_init(void *v) | |
212 | { | 216 | { | |
213 | crc32c_update(v, (const uint8_t *)data, len); | 217 | TIGER2_Init(v); | |
214 | } | 218 | } | |
215 | 219 | |||
216 | static void | 220 | static void | |
217 | wrap_tiger_update(void *v, const char *data, unsigned len) | 221 | wrap_tiger_update(void *v, const void *data, unsigned len) | |
218 | { | 222 | { | |
219 | TIGER_Update(v, (const uint8_t *)data, len); | 223 | TIGER_Update(v, (const uint8_t *)data, len); | |
220 | } | 224 | } | |
221 | 225 | |||
222 | static void | 226 | static void | |
223 | wrap_blake2_update(void *v, const char *data, unsigned len) | 227 | wrap_tiger_final(uint8_t *raw, void *v) | |
224 | { | 228 | { | |
225 | blake2b_update(v, (const uint8_t *)data, (uint64_t)len); | 229 | TIGER_Final(raw, v); | |
226 | } | 230 | } | |
227 | 231 | |||
232 | /*****/ | |||
233 | ||||
228 | static void | 234 | static void | |
229 | wrap_whirlpool_update(void *v, const char *data, unsigned len) | 235 | wrap_blake2_init(void *v) | |
230 | { | 236 | { | |
231 | whirlpool_update(v, (const uint8_t *)data, len); | 237 | blake2b_init(v, 64); | |
232 | } | 238 | } | |
233 | 239 | |||
234 | static void | 240 | static void | |
235 | wrap_keccak_update(void *v, const char *data, unsigned len) | 241 | wrap_blake2_update(void *v, const void *data, unsigned len) | |
236 | { | 242 | { | |
237 | /* number of bits for keccak */ | 243 | blake2b_update(v, (const uint8_t *)data, (uint64_t)len); | |
238 | KECCAK_Update(v, (const uint8_t *)data, (uint64_t)(len * 8)); | |||
239 | } | 244 | } | |
240 | 245 | |||
241 | static void | 246 | static void | |
242 | wrap_size_update(void *v, const char *data, unsigned len) | 247 | wrap_blake2_final(uint8_t *raw, void *v) | |
243 | { | 248 | { | |
244 | uint64_t n; | 249 | blake2b_final(v, raw, 64); | |
245 | ||||
246 | USE_ARG(data); | |||
247 | memcpy(&n, v, sizeof(n)); | |||
248 | n += len; | |||
249 | memcpy(v, &n, sizeof(n)); | |||
250 | } | 250 | } | |
251 | 251 | |||
252 | /*****/ | 252 | /*****/ | |
253 | 253 | |||
254 | static void | 254 | static void | |
255 | wrap_sha1_final(uint8_t *raw, void *v) | 255 | wrap_whirlpool_init(void *v) | |
256 | { | 256 | { | |
257 | SHA1Final(raw, v); | 257 | whirlpool_init(v); | |
258 | } | 258 | } | |
259 | 259 | |||
260 | static void | 260 | static void | |
261 | wrap_sha256_final(uint8_t *raw, void *v) | 261 | wrap_whirlpool_update(void *v, const void *data, unsigned len) | |
262 | { | 262 | { | |
263 | SHA256_Final(raw, v); | 263 | whirlpool_update(v, (const uint8_t *)data, len); | |
264 | } | 264 | } | |
265 | 265 | |||
266 | static void | 266 | static void | |
267 | wrap_sha512_final(uint8_t *raw, void *v) | 267 | wrap_whirlpool_final(uint8_t *raw, void *v) | |
268 | { | 268 | { | |
269 | SHA512_Final(raw, v); | 269 | whirlpool_finalize((char *)raw, v); | |
270 | } | 270 | } | |
271 | 271 | |||
272 | /*****/ | |||
273 | ||||
272 | static void | 274 | static void | |
273 | wrap_rmd160_final(uint8_t *raw, void *v) | 275 | wrap_keccak224_init(void *v) | |
274 | { | 276 | { | |
275 | RMD160Final(raw, v); | 277 | KECCAK_Init(v, 224); | |
276 | } | 278 | } | |
277 | 279 | |||
278 | static void | 280 | static void | |
279 | wrap_md5_final(uint8_t *raw, void *v) | 281 | wrap_keccak256_init(void *v) | |
280 | { | 282 | { | |
281 | MD5Final(raw, v); | 283 | KECCAK_Init(v, 256); | |
282 | } | 284 | } | |
283 | 285 | |||
284 | static void | 286 | static void | |
285 | wrap_crc32c_final(uint8_t *raw, void *v) | 287 | wrap_keccak384_init(void *v) | |
286 | { | 288 | { | |
287 | crc32c_final((ctx32_t *)(void *)raw, v); | 289 | KECCAK_Init(v, 384); | |
288 | } | 290 | } | |
289 | 291 | |||
290 | static void | 292 | static void | |
291 | wrap_tiger_final(uint8_t *raw, void *v) | 293 | wrap_keccak512_init(void *v) | |
292 | { | 294 | { | |
293 | TIGER_Final(raw, v); | 295 | KECCAK_Init(v, 512); | |
294 | } | 296 | } | |
295 | 297 | |||
296 | static void | 298 | static void | |
297 | wrap_blake2_final(uint8_t *raw, void *v) | 299 | wrap_keccak_update(void *v, const void *data, unsigned len) | |
298 | { | 300 | { | |
299 | blake2b_final(v, raw, 64); | 301 | /* number of bits for keccak */ | |
302 | KECCAK_Update(v, (const uint8_t *)data, (uint64_t)(len * 8)); | |||
300 | } | 303 | } | |
301 | 304 | |||
302 | static void | 305 | static void | |
303 | wrap_whirlpool_final(uint8_t *raw, void *v) | 306 | wrap_keccak_final(uint8_t *raw, void *v) | |
304 | { | 307 | { | |
305 | whirlpool_finalize((char *)raw, v); | 308 | KECCAK_Final(v, raw); | |
309 | } | |||
310 | ||||
311 | /*****/ | |||
312 | ||||
313 | static void | |||
314 | wrap_size_init(void *v) | |||
315 | { | |||
316 | memset(v, 0x0, sizeof(uint64_t)); | |||
306 | } | 317 | } | |
307 | 318 | |||
308 | static void | 319 | static void | |
309 | wrap_keccak_final(uint8_t *raw, void *v) | 320 | wrap_size_update(void *v, const void *data, unsigned len) | |
310 | { | 321 | { | |
311 | KECCAK_Final(v, raw); | 322 | uint64_t n; | |
323 | ||||
324 | USE_ARG(data); | |||
325 | memcpy(&n, v, sizeof(n)); | |||
326 | n += len; | |||
327 | memcpy(v, &n, sizeof(n)); | |||
312 | } | 328 | } | |
313 | 329 | |||
314 | static void | 330 | static void | |
315 | wrap_size_final(uint8_t *raw, void *v) | 331 | wrap_size_final(uint8_t *raw, void *v) | |
316 | { | 332 | { | |
317 | const int indian = 1; | 333 | const int indian = 1; | |
318 | uint64_t tmp; | 334 | uint64_t tmp; | |
319 | uint64_t w; | 335 | uint64_t w; | |
320 | 336 | |||
321 | memcpy(&w, v, sizeof(w)); | 337 | memcpy(&w, v, sizeof(w)); | |
322 | if (*(const char *)(const void *)&indian) { | 338 | if (*(const char *)(const void *)&indian) { | |
323 | /* little endian */ | 339 | /* little endian */ | |
324 | tmp = (w >> 32) | (w << 32); \ | 340 | tmp = (w >> 32) | (w << 32); \ | |
325 | tmp = ((tmp & (uint64_t)0xff00ff00ff00ff00ULL) >> 8) | | 341 | tmp = ((tmp & (uint64_t)0xff00ff00ff00ff00ULL) >> 8) | | |
326 | ((tmp & (uint64_t)0x00ff00ff00ff00ffULL) << 8); | 342 | ((tmp & (uint64_t)0x00ff00ff00ff00ffULL) << 8); | |
327 | w = ((tmp & (uint64_t)0xffff0000ffff0000ULL) >> 16) | | 343 | w = ((tmp & (uint64_t)0xffff0000ffff0000ULL) >> 16) | | |
328 | ((tmp & (uint64_t)0x0000ffff0000ffffULL) << 16); | 344 | ((tmp & (uint64_t)0x0000ffff0000ffffULL) << 16); | |
329 | } | 345 | } | |
330 | memcpy(raw, &w, sizeof(w)); | 346 | memcpy(raw, &w, sizeof(w)); | |
331 | } | 347 | } | |
332 | 348 | |||
333 | /*****/ | 349 | /*****/ | |
334 | 350 | |||
351 | static void | |||
352 | wrap_null_init(void *v) | |||
353 | { | |||
354 | USE_ARG(v); | |||
355 | } | |||
356 | ||||
357 | static void | |||
358 | wrap_null_update(void *v, const void *data, unsigned len) | |||
359 | { | |||
360 | USE_ARG(v); | |||
361 | USE_ARG(data); | |||
362 | USE_ARG(len); | |||
363 | } | |||
364 | ||||
365 | static void | |||
366 | wrap_null_final(uint8_t *raw, void *v) | |||
367 | { | |||
368 | USE_ARG(raw); | |||
369 | USE_ARG(v); | |||
370 | } | |||
371 | ||||
372 | /*****/ | |||
373 | ||||
374 | #define COMBINE_CONCAT 0x0 | |||
375 | #define COMBINE_COMB4P 0x1 | |||
376 | #define COMBINE_HASH 0x2 | |||
377 | #define COMBINE_XOR 0x3 | |||
378 | ||||
335 | /* digest algorithm struct */ | 379 | /* digest algorithm struct */ | |
336 | typedef struct Alg { | 380 | typedef struct Alg { | |
337 | const char *name; /* digest name */ | 381 | const char *name; /* digest name */ | |
338 | size_t namelen; /* length of name */ | 382 | size_t namelen; /* length of name */ | |
339 | size_t ctxsize; /* context size */ | 383 | size_t ctxsize; /* context size */ | |
340 | size_t rawsize; /* rawsize of output */ | 384 | size_t rawsize; /* rawsize of output */ | |
341 | mg_initfunc_t init; /* digest init function */ | 385 | mg_initfunc_t init; /* digest init function */ | |
342 | mg_updatefunc_t update; /* digest update function */ | 386 | mg_updatefunc_t update; /* digest update function */ | |
343 | mg_finalfunc_t final; /* digest final function */ | 387 | mg_finalfunc_t final; /* digest final function */ | |
388 | uint32_t combiner; /* combination type */ | |||
344 | } Alg; | 389 | } Alg; | |
345 | 390 | |||
346 | static const Alg algs[] = { | 391 | static const Alg algs[] = { | |
347 | { "MD5", 3, sizeof(MD5_CTX), 16, wrap_md5_init, wrap_md5_update, wrap_md5_final }, | 392 | { "MD5", 3, sizeof(MD5_CTX), 16, wrap_md5_init, wrap_md5_update, wrap_md5_final, 0 }, | |
348 | { "SHA1", 4, sizeof(SHA1_CTX), 20, wrap_sha1_init, wrap_sha1_update, wrap_sha1_final }, | 393 | { "SHA1", 4, sizeof(SHA1_CTX), 20, wrap_sha1_init, wrap_sha1_update, wrap_sha1_final, 0 }, | |
349 | { "SHA256", 6, sizeof(SHA256_CTX), 32, wrap_sha256_init, wrap_sha256_update, wrap_sha256_final }, | 394 | { "SHA256", 6, sizeof(SHA256_CTX), 32, wrap_sha256_init, wrap_sha256_update, wrap_sha256_final, 0 }, | |
350 | { "SHA512", 6, sizeof(SHA512_CTX), 64, wrap_sha512_init, wrap_sha512_update, wrap_sha512_final }, | 395 | { "SHA512", 6, sizeof(SHA512_CTX), 64, wrap_sha512_init, wrap_sha512_update, wrap_sha512_final, 0 }, | |
351 | { "BLAKE2", 6, sizeof(BLAKE2_CTX), 64, wrap_blake2_init, wrap_blake2_update, wrap_blake2_final }, | 396 | { "BLAKE2", 6, sizeof(BLAKE2_CTX), 64, wrap_blake2_init, wrap_blake2_update, wrap_blake2_final, 0 }, | |
352 | { "RMD160", 6, sizeof(RMD160_CTX), 20, wrap_rmd160_init, wrap_rmd160_update, wrap_rmd160_final }, | 397 | { "RMD160", 6, sizeof(RMD160_CTX), 20, wrap_rmd160_init, wrap_rmd160_update, wrap_rmd160_final, 0 }, | |
353 | { "RIPEMD160", 9, sizeof(RMD160_CTX), 20, wrap_rmd160_init, wrap_rmd160_update, wrap_rmd160_final }, | 398 | { "RIPEMD160", 9, sizeof(RMD160_CTX), 20, wrap_rmd160_init, wrap_rmd160_update, wrap_rmd160_final, 0 }, | |
354 | { "CRC32C", 6, sizeof(ctx32_t), 4, wrap_crc32c_init, wrap_crc32c_update, wrap_crc32c_final }, | 399 | { "CRC32C", 6, sizeof(ctx32_t), 4, wrap_crc32c_init, wrap_crc32c_update, wrap_crc32c_final, 0 }, | |
355 | { "TIGER2", 6, sizeof(TIGER_CTX), 24, wrap_tiger2_init, wrap_tiger_update, wrap_tiger_final }, | 400 | { "TIGER2", 6, sizeof(TIGER_CTX), 24, wrap_tiger2_init, wrap_tiger_update, wrap_tiger_final, 0 }, | |
356 | { "TIGER", 5, sizeof(TIGER_CTX), 24, wrap_tiger_init, wrap_tiger_update, wrap_tiger_final }, | 401 | { "TIGER", 5, sizeof(TIGER_CTX), 24, wrap_tiger_init, wrap_tiger_update, wrap_tiger_final, 0 }, | |
357 | { "WHIRLPOOL", 9, sizeof(whirlpool_context_t), 64, wrap_whirlpool_init, wrap_whirlpool_update, wrap_whirlpool_final }, | 402 | { "WHIRLPOOL", 9, sizeof(whirlpool_context_t), 64, wrap_whirlpool_init, wrap_whirlpool_update, wrap_whirlpool_final, 0 }, | |
358 | { "SHA3-224", 8, sizeof(KECCAK_CTX), 28, wrap_keccak224_init, wrap_keccak_update, wrap_keccak_final }, | 403 | { "SHA3-224", 8, sizeof(KECCAK_CTX), 28, wrap_keccak224_init, wrap_keccak_update, wrap_keccak_final, 0 }, | |
359 | { "SHA3-256", 8, sizeof(KECCAK_CTX), 32, wrap_keccak256_init, wrap_keccak_update, wrap_keccak_final }, | 404 | { "SHA3-256", 8, sizeof(KECCAK_CTX), 32, wrap_keccak256_init, wrap_keccak_update, wrap_keccak_final, 0 }, | |
360 | { "SHA3-384", 8, sizeof(KECCAK_CTX), 48, wrap_keccak384_init, wrap_keccak_update, wrap_keccak_final }, | 405 | { "SHA3-384", 8, sizeof(KECCAK_CTX), 48, wrap_keccak384_init, wrap_keccak_update, wrap_keccak_final, 0 }, | |
361 | { "SHA3-512", 8, sizeof(KECCAK_CTX), 64, wrap_keccak512_init, wrap_keccak_update, wrap_keccak_final }, | 406 | { "SHA3-512", 8, sizeof(KECCAK_CTX), 64, wrap_keccak512_init, wrap_keccak_update, wrap_keccak_final, 0 }, | |
362 | { "KECCAK-224", 10, sizeof(KECCAK_CTX), 28, wrap_keccak224_init, wrap_keccak_update, wrap_keccak_final }, | 407 | { "KECCAK-224", 10, sizeof(KECCAK_CTX), 28, wrap_keccak224_init, wrap_keccak_update, wrap_keccak_final, 0 }, | |
363 | { "KECCAK-256", 10, sizeof(KECCAK_CTX), 32, wrap_keccak256_init, wrap_keccak_update, wrap_keccak_final }, | 408 | { "KECCAK-256", 10, sizeof(KECCAK_CTX), 32, wrap_keccak256_init, wrap_keccak_update, wrap_keccak_final, 0 }, | |
364 | { "KECCAK-384", 10, sizeof(KECCAK_CTX), 48, wrap_keccak384_init, wrap_keccak_update, wrap_keccak_final }, | 409 | { "KECCAK-384", 10, sizeof(KECCAK_CTX), 48, wrap_keccak384_init, wrap_keccak_update, wrap_keccak_final, 0 }, | |
365 | { "KECCAK-512", 10, sizeof(KECCAK_CTX), 64, wrap_keccak512_init, wrap_keccak_update, wrap_keccak_final }, | 410 | { "KECCAK-512", 10, sizeof(KECCAK_CTX), 64, wrap_keccak512_init, wrap_keccak_update, wrap_keccak_final, 0 }, | |
366 | { "SIZE", 4, sizeof(uint64_t), 8, wrap_size_init, wrap_size_update, wrap_size_final }, | 411 | { "SIZE", 4, sizeof(uint64_t), 8, wrap_size_init, wrap_size_update, wrap_size_final, 0 }, | |
367 | { NULL, 0, 0, 0, NULL, NULL, NULL} | 412 | { "COMBCONCAT", 10, 0, 0, wrap_null_init, wrap_null_update, wrap_null_final, COMBINE_CONCAT }, | |
413 | { "CONCAT", 6, 0, 0, wrap_null_init, wrap_null_update, wrap_null_final, COMBINE_CONCAT }, | |||
414 | { "COMB4P", 6, 0, 0, wrap_null_init, wrap_null_update, wrap_null_final, COMBINE_COMB4P }, | |||
415 | { "COMBHASH", 8, 0, 0, wrap_null_init, wrap_null_update, wrap_null_final, COMBINE_HASH }, | |||
416 | { "HASH", 4, 0, 0, wrap_null_init, wrap_null_update, wrap_null_final, COMBINE_HASH }, | |||
417 | { "COMBXOR", 7, 0, 0, wrap_null_init, wrap_null_update, wrap_null_final, COMBINE_XOR }, | |||
418 | { "XOR", 3, 0, 0, wrap_null_init, wrap_null_update, wrap_null_final, COMBINE_XOR }, | |||
419 | { NULL, 0, 0, 0, NULL, NULL, NULL, 0} | |||
368 | }; | 420 | }; | |
369 | 421 | |||
370 | /* find an algorithm in the table above */ | 422 | /* find an algorithm in the table above */ | |
371 | static const Alg * | 423 | static const Alg * | |
372 | findalg(const char *algname) | 424 | findalg(const char *algname) | |
373 | { | 425 | { | |
374 | const Alg *alg; | 426 | const Alg *alg; | |
375 | 427 | |||
376 | for (alg = algs ; algname && alg->name ; alg++) { | 428 | for (alg = algs ; algname && alg->name ; alg++) { | |
377 | if (strncasecmp(algname, alg->name, alg->namelen) == 0) { | 429 | if (strncasecmp(algname, alg->name, alg->namelen) == 0) { | |
378 | return alg; | 430 | return alg; | |
379 | } | 431 | } | |
380 | } | 432 | } | |
@@ -383,99 +435,190 @@ findalg(const char *algname) | @@ -383,99 +435,190 @@ findalg(const char *algname) | |||
383 | 435 | |||
384 | /* normalise through regexp substitution */ | 436 | /* normalise through regexp substitution */ | |
385 | static int | 437 | static int | |
386 | normalise(multigest_t *multigest, const char *data, size_t len, int64_t *from) | 438 | normalise(multigest_t *multigest, const char *data, size_t len, int64_t *from) | |
387 | { | 439 | { | |
388 | #ifndef _KERNEL | 440 | #ifndef _KERNEL | |
389 | multigest_dig_t *d; | 441 | multigest_dig_t *d; | |
390 | regmatch_t match[2]; | 442 | regmatch_t match[2]; | |
391 | uint32_t i; | 443 | uint32_t i; | |
392 | 444 | |||
393 | *from = 0; | 445 | *from = 0; | |
394 | while (multigest->r && len > 0) { | 446 | while (multigest->r && len > 0) { | |
395 | match[0].rm_so = *from; | 447 | match[0].rm_so = *from; | |
396 | match[0].rm_eo = len; | 448 | match[0].rm_eo = (regoff_t)len; | |
397 | if (regexec(multigest->r, data, 2, match, REG_STARTEND) != 0) { | 449 | if (regexec(multigest->r, data, 2, match, REG_STARTEND) != 0) { | |
398 | break; | 450 | break; | |
399 | } | 451 | } | |
400 | for (d = multigest->digs, i = 0 ; i < multigest->digc ; i++, d++) { | 452 | for (d = multigest->digs, i = 0 ; i < multigest->digc ; i++, d++) { | |
401 | (*d->update)(&multigest->ctx[d->ctxoff], &data[*from], | 453 | if (d->rawsize) { | |
402 | (unsigned)(match[0].rm_so - *from)); | 454 | (*d->update)(&multigest->ctx[d->ctxoff], &data[*from], | |
403 | if (multigest->repllen) { | 455 | (unsigned)(match[0].rm_so - *from)); | |
404 | (*d->update)(&multigest->ctx[d->ctxoff], multigest->repl, | 456 | if (multigest->repllen) { | |
405 | multigest->repllen); | 457 | (*d->update)(&multigest->ctx[d->ctxoff], multigest->repl, | |
458 | multigest->repllen); | |||
459 | } | |||
406 | } | 460 | } | |
407 | } | 461 | } | |
408 | *from = match[0].rm_eo; | 462 | *from = match[0].rm_eo; | |
409 | } | 463 | } | |
410 | #else | 464 | #else | |
411 | *from = 0; | 465 | *from = 0; | |
412 | #endif | 466 | #endif | |
413 | return 1; | 467 | return 1; | |
414 | } | 468 | } | |
415 | 469 | |||
470 | /* xor the contents of two buffers together */ | |||
471 | static void | |||
472 | xorbuf(uint8_t *out, uint8_t *in1, uint8_t *in2, size_t size) | |||
473 | { | |||
474 | uint32_t j; | |||
475 | ||||
476 | for (j = 0 ; j < size ; j++) { | |||
477 | out[j] = in1[j] ^ in2[j]; | |||
478 | } | |||
479 | } | |||
480 | ||||
481 | /* a round of comb4p combination */ | |||
482 | static int | |||
483 | comb4p_round(multigest_t *m, uint8_t *out, uint8_t *in, multigest_dig_t *d1, multigest_dig_t *d2, uint32_t r) | |||
484 | { | |||
485 | const int indian = 1; | |||
486 | uint32_t b2; | |||
487 | uint32_t b4; | |||
488 | uint8_t h1[4096]; | |||
489 | uint8_t h2[4096]; | |||
490 | ||||
491 | if (*(const char *)(const void *)&indian) { | |||
492 | /* little endian - convert to bg endian) */ | |||
493 | b2 = (r & 0x00ff0000); | |||
494 | b4 = (r & 0x000000ff); | |||
495 | r = (r & 0xff00ff00) | (b2 >> 16) | (b4 << 16); | |||
496 | } | |||
497 | (*d1->update)(&m->ctx[d1->ctxoff], (const char *)&r, sizeof(r)); | |||
498 | (*d2->update)(&m->ctx[d2->ctxoff], (const char *)&r, sizeof(r)); | |||
499 | (*d1->update)(&m->ctx[d1->ctxoff], (const char *)in, (unsigned)d1->rawsize); | |||
500 | (*d2->update)(&m->ctx[d2->ctxoff], (const char *)in, (unsigned)d2->rawsize); | |||
501 | (*d1->final)(h1, &m->ctx[d1->ctxoff]); | |||
502 | xorbuf(out, out, h1, d1->rawsize); | |||
503 | (*d2->final)(h2, &m->ctx[d2->ctxoff]); | |||
504 | xorbuf(out, out, h2, d2->rawsize); | |||
505 | return 1; | |||
506 | } | |||
507 | ||||
508 | /* point d1 and d2 at the first 2 digests found */ | |||
509 | static int | |||
510 | find_digests(multigest_t *m, multigest_dig_t **d1, multigest_dig_t **d2) | |||
511 | { | |||
512 | multigest_dig_t *d; | |||
513 | uint32_t i; | |||
514 | ||||
515 | *d1 = *d2 = NULL; | |||
516 | for (d = m->digs, i = 0 ; i < m->digc ; i++, d++) { | |||
517 | if (d->rawsize) { | |||
518 | if (*d1) { | |||
519 | *d2 = d; | |||
520 | return 1; | |||
521 | } | |||
522 | *d1 = d; | |||
523 | } | |||
524 | } | |||
525 | return 0; | |||
526 | } | |||
527 | ||||
416 | /***************************************************************************/ | 528 | /***************************************************************************/ | |
417 | 529 | |||
418 | /* create a new struct and return it */ | 530 | /* create a new struct and return it */ | |
419 | multigest_t * | 531 | multigest_t * | |
420 | multigest_new(void) | 532 | multigest_new(void) | |
421 | { | 533 | { | |
422 | return calloc(1, sizeof(multigest_t)); | 534 | return calloc(1, sizeof(multigest_t)); | |
423 | } | 535 | } | |
424 | 536 | |||
425 | /* initialise a struct */ | 537 | /* initialise a struct */ | |
426 | int | 538 | int | |
427 | multigest_init(multigest_t *multigest, const char *algname) | 539 | multigest_init(multigest_t *multigest, const char *algname) | |
428 | { | 540 | { | |
429 | multigest_dig_t *d; | 541 | multigest_dig_t *d; | |
542 | multigest_dig_t *d1; | |||
543 | multigest_dig_t *d2; | |||
430 | const Alg *alg; | 544 | const Alg *alg; | |
431 | uint32_t ctxoff; | 545 | uint32_t ctxoff; | |
432 | uint32_t i; | 546 | uint32_t i; | |
433 | uint8_t *newv; | 547 | uint8_t *newv; | |
434 | 548 | |||
435 | if (multigest && algname) { | 549 | if (multigest && algname) { | |
436 | memset(multigest, 0x0, sizeof(*multigest)); | 550 | memset(multigest, 0x0, sizeof(*multigest)); | |
437 | multigest->type = strdup(algname); | 551 | multigest->type = strdup(algname); | |
438 | for (i = 0, d = multigest->digs, ctxoff = 0 ; *algname ; d++, i++) { | 552 | for (i = 0, d = multigest->digs, ctxoff = 0 ; *algname ; d++, i++) { | |
439 | if (i >= __arraycount(multigest->digs)) { | 553 | if (i >= __arraycount(multigest->digs)) { | |
440 | fprintf(stderr, "too many digest types %u\n", i); | 554 | fprintf(stderr, "too many digest types %u\n", i); | |
441 | break; | 555 | break; | |
442 | } | 556 | } | |
443 | if ((alg = findalg(algname)) == NULL) { | 557 | if ((alg = findalg(algname)) == NULL) { | |
444 | fprintf(stderr, "no such algorithm '%.10s'\n", algname); | 558 | fprintf(stderr, "no such algorithm '%.10s'\n", algname); | |
445 | break; | 559 | break; | |
446 | } | 560 | } | |
561 | if (alg->combiner) { | |||
562 | multigest->combiner = alg->combiner; | |||
563 | } | |||
447 | if (ctxoff + alg->ctxsize >= multigest->ctxsize) { | 564 | if (ctxoff + alg->ctxsize >= multigest->ctxsize) { | |
448 | if ((newv = realloc(multigest->ctx, multigest->ctxsize + 4096)) == NULL) { | 565 | if ((newv = realloc(multigest->ctx, multigest->ctxsize + 4096)) == NULL) { | |
449 | fprintf(stderr, "multigest_init: allocation issues\n"); | 566 | fprintf(stderr, "multigest_init: allocation issues\n"); | |
450 | return 0; | 567 | return 0; | |
451 | } | 568 | } | |
452 | multigest->ctx = newv; | 569 | multigest->ctx = newv; | |
453 | multigest->ctxsize += 4096; | 570 | multigest->ctxsize += 4096; | |
454 | } | 571 | } | |
455 | d->alg = strdup(alg->name); | 572 | d->alg = strdup(alg->name); | |
456 | (*alg->init)(&multigest->ctx[ctxoff]); | 573 | (*alg->init)(&multigest->ctx[ctxoff]); | |
457 | d->rawsize = alg->rawsize; | 574 | d->rawsize = alg->rawsize; | |
458 | multigest->rawsize += alg->rawsize; | 575 | multigest->rawsize += alg->rawsize; | |
459 | d->ctxoff = ctxoff; | 576 | d->ctxoff = ctxoff; | |
460 | d->update = alg->update; | 577 | d->update = alg->update; | |
461 | d->final = alg->final; | 578 | d->final = alg->final; | |
462 | ctxoff += (uint32_t)alg->ctxsize; | 579 | ctxoff += (uint32_t)alg->ctxsize; | |
463 | algname += alg->namelen; | 580 | algname += alg->namelen; | |
464 | if (*algname == ',') { | 581 | if (*algname == ',') { | |
465 | algname += 1; | 582 | algname += 1; | |
466 | } | 583 | } | |
467 | multigest->digc += 1; | 584 | multigest->digc += 1; | |
468 | } | 585 | } | |
586 | switch (multigest->combiner) { | |||
587 | case COMBINE_CONCAT: | |||
588 | multigest->outsize = multigest->rawsize; | |||
589 | break; | |||
590 | case COMBINE_COMB4P: | |||
591 | if (!find_digests(multigest, &d1, &d2)) { | |||
592 | fprintf(stderr, "multigest: comb4p < 2 digests\n"); | |||
593 | return 0; | |||
594 | } | |||
595 | multigest->outsize = d1->rawsize * 2; | |||
596 | break; | |||
597 | case COMBINE_XOR: | |||
598 | if (!find_digests(multigest, &d1, &d2)) { | |||
599 | fprintf(stderr, "multigest: xor < 2 digests\n"); | |||
600 | return 0; | |||
601 | } | |||
602 | multigest->outsize = d1->rawsize; | |||
603 | break; | |||
604 | case COMBINE_HASH: | |||
605 | if (!find_digests(multigest, &d1, &d2)) { | |||
606 | fprintf(stderr, "multigest: hash < 2 digests\n"); | |||
607 | return 0; | |||
608 | } | |||
609 | multigest->outsize = d1->rawsize; | |||
610 | break; | |||
611 | } | |||
469 | return 1; | 612 | return 1; | |
470 | } | 613 | } | |
471 | fprintf(stderr, "!multigest || !algname\n"); | 614 | fprintf(stderr, "!multigest || !algname\n"); | |
472 | return 0; | 615 | return 0; | |
473 | } | 616 | } | |
474 | 617 | |||
475 | /* add a substitution pattern */ | 618 | /* add a substitution pattern */ | |
476 | int | 619 | int | |
477 | multigest_add_subst(multigest_t *multigest, const char *from, const char *to) | 620 | multigest_add_subst(multigest_t *multigest, const char *from, const char *to) | |
478 | { | 621 | { | |
479 | if (multigest && from && from[0]) { | 622 | if (multigest && from && from[0]) { | |
480 | if ((multigest->r = calloc(1, sizeof(regex_t))) == NULL || | 623 | if ((multigest->r = calloc(1, sizeof(regex_t))) == NULL || | |
481 | regcomp(multigest->r, from, REG_EXTENDED) != 0) { | 624 | regcomp(multigest->r, from, REG_EXTENDED) != 0) { | |
@@ -483,91 +626,137 @@ multigest_add_subst(multigest_t *multige | @@ -483,91 +626,137 @@ multigest_add_subst(multigest_t *multige | |||
483 | } | 626 | } | |
484 | multigest->pat = strdup(from); | 627 | multigest->pat = strdup(from); | |
485 | if (to) { | 628 | if (to) { | |
486 | multigest->repl = strdup(to); | 629 | multigest->repl = strdup(to); | |
487 | multigest->repllen = (uint32_t)strlen(to); | 630 | multigest->repllen = (uint32_t)strlen(to); | |
488 | } | 631 | } | |
489 | return 1; | 632 | return 1; | |
490 | } | 633 | } | |
491 | return 0; | 634 | return 0; | |
492 | } | 635 | } | |
493 | 636 | |||
494 | /* update the digest with the input */ | 637 | /* update the digest with the input */ | |
495 | void | 638 | void | |
496 | multigest_update(multigest_t *multigest, const char *data, size_t len) | 639 | multigest_update(multigest_t *multigest, const void *vdata, size_t len) | |
497 | { | 640 | { | |
498 | multigest_dig_t *d; | 641 | multigest_dig_t *d; | |
642 | const char *data = (const char *)vdata; | |||
499 | uint32_t i; | 643 | uint32_t i; | |
500 | int64_t from; | 644 | int64_t from; | |
501 | 645 | |||
502 | if (multigest && data) { | 646 | if (multigest && data) { | |
503 | normalise(multigest, data, len, &from); | 647 | normalise(multigest, data, len, &from); | |
504 | for (d = multigest->digs, i = 0 ; i < multigest->digc ; i++, d++) { | 648 | for (d = multigest->digs, i = 0 ; i < multigest->digc ; i++, d++) { | |
505 | (*d->update)(&multigest->ctx[d->ctxoff], &data[from], (unsigned)(len - from)); | 649 | if (d->rawsize) { | |
650 | (*d->update)(&multigest->ctx[d->ctxoff], &data[from], (unsigned)(len - (unsigned)from)); | |||
651 | } | |||
506 | } | 652 | } | |
507 | } | 653 | } | |
508 | } | 654 | } | |
509 | 655 | |||
510 | /* finalise the digest */ | 656 | /* finalise the digest */ | |
511 | void | 657 | void | |
512 | multigest_final(multigest_t *multigest, uint8_t *raw) | 658 | multigest_final(multigest_t *m, uint8_t *raw) | |
513 | { | 659 | { | |
514 | multigest_dig_t *d; | 660 | multigest_dig_t *d1; | |
661 | multigest_dig_t *d2; | |||
515 | uint32_t rawoff; | 662 | uint32_t rawoff; | |
516 | uint32_t i; | 663 | uint32_t i; | |
664 | uint8_t h1[4096]; | |||
665 | uint8_t h2[4096]; | |||
517 | 666 | |||
518 | if (multigest && raw) { | 667 | if (m && raw) { | |
519 | rawoff = 0; | 668 | switch(m->combiner) { | |
520 | for (d = multigest->digs, i = 0 ; i < multigest->digc ; i++, d++) { | 669 | case COMBINE_COMB4P: | |
521 | (*d->final)(&raw[rawoff], &multigest->ctx[d->ctxoff]); | 670 | if (!find_digests(m, &d1, &d2)) { | |
522 | rawoff += (uint32_t)d->rawsize; | 671 | return; | |
672 | } | |||
673 | memset(h1, 0x0, sizeof(h1)); | |||
674 | memset(h2, 0x0, sizeof(h2)); | |||
675 | (*d1->final)(h1, &m->ctx[d1->ctxoff]); | |||
676 | (*d2->final)(h2, &m->ctx[d2->ctxoff]); | |||
677 | xorbuf(h1, h1, h2, d2->rawsize); | |||
678 | comb4p_round(m, h2, h1, d1, d2, 1); | |||
679 | comb4p_round(m, h1, h2, d1, d2, 2); | |||
680 | memcpy(raw, h1, d1->rawsize); | |||
681 | memcpy(&raw[d1->rawsize], h2, d2->rawsize); | |||
682 | break; | |||
683 | case COMBINE_CONCAT: | |||
684 | rawoff = 0; | |||
685 | for (d1 = m->digs, i = 0 ; i < m->digc ; i++, d1++) { | |||
686 | if (d1->rawsize) { | |||
687 | (*d1->final)(&raw[rawoff], &m->ctx[d1->ctxoff]); | |||
688 | rawoff += (uint32_t)d1->rawsize; | |||
689 | } | |||
690 | } | |||
691 | break; | |||
692 | case COMBINE_HASH: | |||
693 | if (!find_digests(m, &d1, &d2)) { | |||
694 | return; | |||
695 | } | |||
696 | (*d2->final)(h2, &m->ctx[d2->ctxoff]); | |||
697 | (*d1->update)(&m->ctx[d1->ctxoff], h2, (unsigned)d1->rawsize); | |||
698 | (*d1->final)(raw, &m->ctx[d1->ctxoff]); | |||
699 | break; | |||
700 | case COMBINE_XOR: | |||
701 | if (!find_digests(m, &d1, &d2)) { | |||
702 | return; | |||
703 | } | |||
704 | (*d2->final)(h2, &m->ctx[d2->ctxoff]); | |||
705 | (*d1->final)(h1, &m->ctx[d1->ctxoff]); | |||
706 | xorbuf(raw, h1, h2, m->outsize); | |||
707 | break; | |||
708 | default: | |||
709 | break; | |||
523 | } | 710 | } | |
524 | } | 711 | } | |
525 | } | 712 | } | |
526 | 713 | |||
527 | /* run sed on data and then digest it */ | 714 | /* run sed on data and then digest it */ | |
528 | uint8_t * | 715 | uint8_t * | |
529 | multigest_data(const char *alg, const char *data, size_t size, uint8_t *raw, const char *pat, const char *repl) | 716 | multigest_data(const char *alg, const void *data, size_t size, uint8_t *raw, const char *pat, const char *repl) | |
530 | { | 717 | { | |
531 | multigest_t s; | 718 | multigest_t m; | |
532 | 719 | |||
533 | if (data && alg && raw) { | 720 | if (data && alg && raw) { | |
534 | memset(&s, 0x0, sizeof(s)); | 721 | memset(&m, 0x0, sizeof(m)); | |
535 | multigest_init(&s, alg); | 722 | multigest_init(&m, alg); | |
536 | multigest_add_subst(&s, pat, repl); | 723 | multigest_add_subst(&m, pat, repl); | |
537 | multigest_update(&s, data, size); | 724 | multigest_update(&m, data, size); | |
538 | multigest_final(&s, raw); | 725 | multigest_final(&m, raw); | |
539 | multigest_free(&s); | 726 | multigest_free(&m); | |
540 | return raw; | 727 | return raw; | |
541 | } | 728 | } | |
542 | return NULL; | 729 | return NULL; | |
543 | } | 730 | } | |
544 | 731 | |||
545 | /* percent decode (pseudo-RFC1738) a string */ | 732 | /* percent decode (pseudo-RFC1738) a string */ | |
546 | void | 733 | void | |
547 | multigest_unpcstring(const char *in, size_t isize, char *out, size_t osize) | 734 | multigest_unpcstring(const char *in, size_t isize, char *out, size_t osize) | |
548 | { | 735 | { | |
549 | static const char *hexes = "0123456789abcdef"; | 736 | static const char *hexes = "0123456789abcdef"; | |
550 | const char *p[2]; | 737 | const char *p[2]; | |
551 | const char *i; | 738 | const char *i; | |
739 | uint8_t num; | |||
552 | char *o; | 740 | char *o; | |
553 | 741 | |||
554 | for (i = in, o = out ; (size_t)(o - out) < osize - 1 && (size_t)(i - in) < isize && *i ; o++) { | 742 | for (i = in, o = out ; (size_t)(o - out) < osize - 1 && (size_t)(i - in) < isize && *i ; o++) { | |
555 | if (*i == '%') { | 743 | if (*i == '%') { | |
556 | if ((p[0] = strchr(hexes, i[1])) == NULL || | 744 | if ((p[0] = strchr(hexes, i[1])) == NULL || | |
557 | (p[1] = strchr(hexes, i[2])) == NULL) { | 745 | (p[1] = strchr(hexes, i[2])) == NULL) { | |
558 | break; | 746 | break; | |
559 | } | 747 | } | |
560 | *o = ((char)(p[0] - hexes) * 16) + (p[1] - hexes); | 748 | num = (uint8_t)((p[0] - hexes) << 4) | (uint8_t)(p[1] - hexes); | |
749 | *o = (char)num; | |||
561 | i += 3; | 750 | i += 3; | |
562 | } else { | 751 | } else { | |
563 | *o = *i++; | 752 | *o = *i++; | |
564 | } | 753 | } | |
565 | } | 754 | } | |
566 | *o = 0x0; | 755 | *o = 0x0; | |
567 | } | 756 | } | |
568 | 757 | |||
569 | /* print as hex string */ | 758 | /* print as hex string */ | |
570 | int | 759 | int | |
571 | multigest_format_hex(uint8_t *raw, const char *algname, char *out, size_t size) | 760 | multigest_format_hex(uint8_t *raw, const char *algname, char *out, size_t size) | |
572 | { | 761 | { | |
573 | const Alg *alg; | 762 | const Alg *alg; | |
@@ -576,34 +765,34 @@ multigest_format_hex(uint8_t *raw, const | @@ -576,34 +765,34 @@ multigest_format_hex(uint8_t *raw, const | |||
576 | 765 | |||
577 | for (rawsize = 0 ; *algname ; rawsize += alg->rawsize) { | 766 | for (rawsize = 0 ; *algname ; rawsize += alg->rawsize) { | |
578 | if ((alg = findalg(algname)) == NULL) { | 767 | if ((alg = findalg(algname)) == NULL) { | |
579 | break; | 768 | break; | |
580 | } | 769 | } | |
581 | for (i = 0 ; i < alg->rawsize && (rawsize + i) * 2 < size; i++) { | 770 | for (i = 0 ; i < alg->rawsize && (rawsize + i) * 2 < size; i++) { | |
582 | snprintf(&out[(rawsize + i) * 2], 3, "%02hhx", raw[rawsize + i]); | 771 | snprintf(&out[(rawsize + i) * 2], 3, "%02hhx", raw[rawsize + i]); | |
583 | } | 772 | } | |
584 | algname += alg->namelen; | 773 | algname += alg->namelen; | |
585 | if (*algname == ',') { | 774 | if (*algname == ',') { | |
586 | algname += 1; | 775 | algname += 1; | |
587 | } | 776 | } | |
588 | } | 777 | } | |
589 | return (int)(rawsize + rawsize + 1); | 778 | return (int)(rawsize + rawsize); | |
590 | } | 779 | } | |
591 | 780 | |||
592 | /* return the size of output array we'll need */ | 781 | /* return the size of output array we'll need */ | |
593 | uint32_t | 782 | uint32_t | |
594 | multigest_get_rawsize(multigest_t *multigest) | 783 | multigest_get_rawsize(multigest_t *multigest) | |
595 | { | 784 | { | |
596 | return (multigest) ? (uint32_t)multigest->rawsize : 0; | 785 | return (multigest) ? (uint32_t)multigest->outsize : 0; | |
597 | } | 786 | } | |
598 | 787 | |||
599 | /* return the size of output array we'll need for the alg names */ | 788 | /* return the size of output array we'll need for the alg names */ | |
600 | uint32_t | 789 | uint32_t | |
601 | multigest_algs_rawsize(const char *alg) | 790 | multigest_algs_rawsize(const char *alg) | |
602 | { | 791 | { | |
603 | multigest_t m; | 792 | multigest_t m; | |
604 | uint32_t size; | 793 | uint32_t size; | |
605 | 794 | |||
606 | memset(&m, 0x0, sizeof(m)); | 795 | memset(&m, 0x0, sizeof(m)); | |
607 | if (!multigest_init(&m, alg)) { | 796 | if (!multigest_init(&m, alg)) { | |
608 | fprintf(stderr, "multigest_init: failed\n"); | 797 | fprintf(stderr, "multigest_init: failed\n"); | |
609 | return 0; | 798 | return 0; | |
@@ -627,26 +816,27 @@ pcstring(FILE *fp, const char *s) | @@ -627,26 +816,27 @@ pcstring(FILE *fp, const char *s) | |||
627 | fprintf(fp, "%c", *s); | 816 | fprintf(fp, "%c", *s); | |
628 | } else { | 817 | } else { | |
629 | fprintf(fp, "%%%02hhx", *s); | 818 | fprintf(fp, "%%%02hhx", *s); | |
630 | } | 819 | } | |
631 | } | 820 | } | |
632 | } | 821 | } | |
633 | 822 | |||
634 | /* print as hex string */ | 823 | /* print as hex string */ | |
635 | int | 824 | int | |
636 | multigest_print_hex(uint8_t *raw, const char *algname, const char *outname, | 825 | multigest_print_hex(uint8_t *raw, const char *algname, const char *outname, | |
637 | const char *f, const char *sub, const char *sep, const char *format) | 826 | const char *f, const char *sub, const char *sep, const char *format) | |
638 | { | 827 | { | |
639 | const Alg *alg; | 828 | const Alg *alg; | |
829 | size_t outsize; | |||
640 | size_t rawsize; | 830 | size_t rawsize; | |
641 | size_t i; | 831 | size_t i; | |
642 | FILE *fp; | 832 | FILE *fp; | |
643 | 833 | |||
644 | if (outname == NULL) { | 834 | if (outname == NULL) { | |
645 | fp = stdout; | 835 | fp = stdout; | |
646 | } else { | 836 | } else { | |
647 | if ((fp = fopen(outname, "w")) == NULL) { | 837 | if ((fp = fopen(outname, "w")) == NULL) { | |
648 | fprintf(stderr, "can't write to '%s'\n", outname); | 838 | fprintf(stderr, "can't write to '%s'\n", outname); | |
649 | return 0; | 839 | return 0; | |
650 | } | 840 | } | |
651 | } | 841 | } | |
652 | if (f != NULL) { | 842 | if (f != NULL) { | |
@@ -655,35 +845,38 @@ multigest_print_hex(uint8_t *raw, const | @@ -655,35 +845,38 @@ multigest_print_hex(uint8_t *raw, const | |||
655 | } | 845 | } | |
656 | if (format && strcasecmp(format, "openssl") == 0) { | 846 | if (format && strcasecmp(format, "openssl") == 0) { | |
657 | fprintf(fp, "(%s)= ", f); | 847 | fprintf(fp, "(%s)= ", f); | |
658 | } else if (format && strcasecmp(format, "digest") == 0) { | 848 | } else if (format && strcasecmp(format, "digest") == 0) { | |
659 | fprintf(fp, " (%s) = ", f); | 849 | fprintf(fp, " (%s) = ", f); | |
660 | } else { | 850 | } else { | |
661 | fprintf(fp, " (%s) (", f); | 851 | fprintf(fp, " (%s) (", f); | |
662 | if (sub) { | 852 | if (sub) { | |
663 | pcstring(fp, sub); | 853 | pcstring(fp, sub); | |
664 | } | 854 | } | |
665 | fprintf(fp, ") = "); | 855 | fprintf(fp, ") = "); | |
666 | } | 856 | } | |
667 | } | 857 | } | |
668 | for (rawsize = 0 ; *algname ; rawsize += alg->rawsize) { | 858 | outsize = multigest_algs_rawsize(algname); | |
859 | for (rawsize = 0 ; *algname && rawsize < outsize ; rawsize += alg->rawsize) { | |||
669 | if ((alg = findalg(algname)) == NULL) { | 860 | if ((alg = findalg(algname)) == NULL) { | |
670 | break; | 861 | break; | |
671 | } | 862 | } | |
672 | for (i = 0 ; i < alg->rawsize ; i++) { | 863 | if (!alg->combiner) { | |
673 | fprintf(fp, "%02hhx", raw[rawsize + i]); | 864 | for (i = 0 ; i < alg->rawsize ; i++) { | |
674 | } | 865 | fprintf(fp, "%02hhx", raw[rawsize + i]); | |
675 | if (sep) { | 866 | } | |
676 | fprintf(fp, "%s", sep); | 867 | if (sep) { | |
868 | fprintf(fp, "%s", sep); | |||
869 | } | |||
677 | } | 870 | } | |
678 | algname += alg->namelen; | 871 | algname += alg->namelen; | |
679 | if (*algname == ',') { | 872 | if (*algname == ',') { | |
680 | algname += 1; | 873 | algname += 1; | |
681 | } | 874 | } | |
682 | } | 875 | } | |
683 | fprintf(fp, "\n"); | 876 | fprintf(fp, "\n"); | |
684 | if (outname != NULL) { | 877 | if (outname != NULL) { | |
685 | fclose(fp); | 878 | fclose(fp); | |
686 | } | 879 | } | |
687 | return 1; | 880 | return 1; | |
688 | } | 881 | } | |
689 | 882 | |||
@@ -698,43 +891,43 @@ multigest_file(const char *alg, const ch | @@ -698,43 +891,43 @@ multigest_file(const char *alg, const ch | |||
698 | size_t cc; | 891 | size_t cc; | |
699 | char *mapped; | 892 | char *mapped; | |
700 | FILE *fp; | 893 | FILE *fp; | |
701 | 894 | |||
702 | if (f && alg && raw) { | 895 | if (f && alg && raw) { | |
703 | memset(&m, 0x0, sizeof(m)); | 896 | memset(&m, 0x0, sizeof(m)); | |
704 | multigest_init(&m, alg); | 897 | multigest_init(&m, alg); | |
705 | multigest_add_subst(&m, pat, repl); | 898 | multigest_add_subst(&m, pat, repl); | |
706 | if ((fp = fopen(f, "r")) == NULL) { | 899 | if ((fp = fopen(f, "r")) == NULL) { | |
707 | fprintf(stderr, "can't open '%s'\n", f); | 900 | fprintf(stderr, "can't open '%s'\n", f); | |
708 | return 0; | 901 | return 0; | |
709 | } | 902 | } | |
710 | fstat(fileno(fp), &st); | 903 | fstat(fileno(fp), &st); | |
711 | size = st.st_size; | 904 | size = (size_t)st.st_size; | |
712 | mapped = mmap(NULL, size, PROT_READ, MAP_SHARED, fileno(fp), 0); | 905 | mapped = mmap(NULL, size, PROT_READ, MAP_SHARED, fileno(fp), 0); | |
713 | if (mapped == MAP_FAILED) { | 906 | if (mapped == MAP_FAILED) { | |
714 | mapped = calloc(1, MB(1)); | 907 | mapped = calloc(1, MB(1)); | |
715 | for (cc = 0 ; cc < size ; cc += rc) { | 908 | for (cc = 0 ; cc < size ; cc += (size_t)rc) { | |
716 | if ((rc = read(fileno(fp), mapped, MB(1))) <= 0) { | 909 | if ((rc = read(fileno(fp), mapped, MB(1))) <= 0) { | |
717 | break; | 910 | break; | |
718 | } | 911 | } | |
719 | multigest_update(&m, mapped, (size_t)rc); | 912 | multigest_update(&m, mapped, (size_t)rc); | |
720 | } | 913 | } | |
721 | free(mapped); | 914 | free(mapped); | |
722 | } else { | 915 | } else { | |
723 | multigest_update(&m, mapped, (size_t)size); | 916 | multigest_update(&m, mapped, (size_t)size); | |
724 | munmap(mapped, size); | 917 | munmap(mapped, size); | |
725 | } | 918 | } | |
726 | fclose(fp); | 919 | fclose(fp); | |
727 | multigest_final(&m, raw); | 920 | multigest_final(&m, raw); | |
728 | multigest_free(&m); | 921 | multigest_free(&m); | |
729 | return raw; | 922 | return raw; | |
730 | } | 923 | } | |
731 | return NULL; | 924 | return NULL; | |
732 | } | 925 | } | |
733 | 926 | |||
734 | /* free resources used in a sedded digest */ | 927 | /* free resources used in a sedded digest */ | |
735 | void | 928 | void | |
736 | multigest_free(multigest_t *s) | 929 | multigest_free(multigest_t *s) | |
737 | { | 930 | { | |
738 | uint32_t i; | 931 | uint32_t i; | |
739 | 932 | |||
740 | if (s) { | 933 | if (s) { |
@@ -1,97 +1,99 @@ | @@ -1,97 +1,99 @@ | |||
1 | /*- | 1 | /*- | |
2 | * Copyright (c) 2014 Alistair Crooks <agc@NetBSD.org> | 2 | * Copyright (c) 2014,2015 Alistair Crooks <agc@NetBSD.org> | |
3 | * All rights reserved. | 3 | * All rights reserved. | |
4 | * | 4 | * | |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without | |
6 | * modification, are permitted provided that the following conditions | 6 | * modification, are permitted provided that the following conditions | |
7 | * are met: | 7 | * are met: | |
8 | * 1. Redistributions of source code must retain the above copyright | 8 | * 1. Redistributions of source code must retain the above copyright | |
9 | * notice, this list of conditions and the following disclaimer. | 9 | * notice, this list of conditions and the following disclaimer. | |
10 | * 2. Redistributions in binary form must reproduce the above copyright | 10 | * 2. Redistributions in binary form must reproduce the above copyright | |
11 | * notice, this list of conditions and the following disclaimer in the | 11 | * notice, this list of conditions and the following disclaimer in the | |
12 | * documentation and/or other materials provided with the distribution. | 12 | * documentation and/or other materials provided with the distribution. | |
13 | * | 13 | * | |
14 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | 14 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | |
15 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | 15 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |
16 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | 16 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | |
17 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | 17 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | |
18 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | 18 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |
19 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 19 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
20 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 20 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
21 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 21 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
22 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 22 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | |
23 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 23 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
24 | */ | 24 | */ | |
25 | #ifndef MULTIGEST_H_ | 25 | #ifndef MULTIGEST_H_ | |
26 | #define MULTIGEST_H_ 20140304 | 26 | #define MULTIGEST_H_ 20150211 | |
27 | 27 | |||
28 | #include <sys/types.h> | 28 | #include <sys/types.h> | |
29 | 29 | |||
30 | #include <inttypes.h> | 30 | #include <inttypes.h> | |
31 | 31 | |||
32 | typedef void (*mg_initfunc_t)(void *); | 32 | typedef void (*mg_initfunc_t)(void *); | |
33 | typedef void (*mg_updatefunc_t)(void *, const char *, unsigned); | 33 | typedef void (*mg_updatefunc_t)(void *, const void *, unsigned); | |
34 | typedef void (*mg_finalfunc_t)(uint8_t *, void *); | 34 | typedef void (*mg_finalfunc_t)(uint8_t *, void *); | |
35 | 35 | |||
36 | #define MG_MAX_DIG 32 | 36 | #define MG_MAX_DIG 32 | |
37 | 37 | |||
38 | /* a single digest struct */ | 38 | /* a single digest struct */ | |
39 | typedef struct multigest_dig_t { | 39 | typedef struct multigest_dig_t { | |
40 | char *alg; /* digest name */ | 40 | char *alg; /* digest name */ | |
41 | size_t ctxoff; /* offset in context */ | 41 | size_t ctxoff; /* offset in context */ | |
42 | size_t rawsize; /* length of raw output */ | 42 | size_t rawsize; /* length of raw output */ | |
43 | mg_updatefunc_t update; /* digest update function */ | 43 | mg_updatefunc_t update; /* digest update function */ | |
44 | mg_finalfunc_t final; /* final update function */ | 44 | mg_finalfunc_t final; /* final update function */ | |
45 | } multigest_dig_t; | 45 | } multigest_dig_t; | |
46 | 46 | |||
47 | /* a multiple digest struct */ | 47 | /* a multiple digest struct */ | |
48 | typedef struct multigest_t { | 48 | typedef struct multigest_t { | |
49 | void *r; /* regular expression for matching */ | 49 | void *r; /* regular expression for matching */ | |
50 | char *pat; /* pattern we match */ | 50 | char *pat; /* pattern we match */ | |
51 | char *repl; /* replacement text */ | 51 | char *repl; /* replacement text */ | |
52 | unsigned repllen; /* cached length of replacement */ | 52 | unsigned repllen; /* cached length of replacement */ | |
53 | char *type; /* digest type */ | 53 | char *type; /* digest type */ | |
54 | size_t rawsize; /* raw size of output digest */ | 54 | size_t rawsize; /* raw size of output digest */ | |
55 | size_t ctxsize; /* allocated size of contexts */ | 55 | size_t ctxsize; /* allocated size of contexts */ | |
56 | uint8_t *ctx; /* digest contexts */ | 56 | uint8_t *ctx; /* digest contexts */ | |
57 | uint32_t digc; /* # of digests */ | 57 | uint32_t digc; /* # of digests */ | |
58 | multigest_dig_t digs[MG_MAX_DIG]; /* digest algorithms being used */ | 58 | multigest_dig_t digs[MG_MAX_DIG]; /* digest algorithms being used */ | |
59 | uint32_t combiner; /* when finalising, combination algorithm */ | |||
60 | size_t outsize; /* output size of digest - combiners may change this */ | |||
59 | } multigest_t; | 61 | } multigest_t; | |
60 | 62 | |||
61 | #ifndef __BEGIN_DECLS | 63 | #ifndef __BEGIN_DECLS | |
62 | # if defined(__cplusplus) | 64 | # if defined(__cplusplus) | |
63 | # define __BEGIN_DECLS extern "C" { | 65 | # define __BEGIN_DECLS extern "C" { | |
64 | # define __END_DECLS } | 66 | # define __END_DECLS } | |
65 | # else | 67 | # else | |
66 | # define __BEGIN_DECLS | 68 | # define __BEGIN_DECLS | |
67 | # define __END_DECLS | 69 | # define __END_DECLS | |
68 | # endif | 70 | # endif | |
69 | #endif | 71 | #endif | |
70 | 72 | |||
71 | __BEGIN_DECLS | 73 | __BEGIN_DECLS | |
72 | 74 | |||
73 | /* new and free */ | 75 | /* new and free */ | |
74 | multigest_t *multigest_new(void); | 76 | multigest_t *multigest_new(void); | |
75 | void multigest_free(multigest_t */*s*/); | 77 | void multigest_free(multigest_t */*s*/); | |
76 | 78 | |||
77 | /* low-level interface */ | 79 | /* low-level interface */ | |
78 | int multigest_init(multigest_t */*multigest*/, const char */*alg*/); | 80 | int multigest_init(multigest_t */*multigest*/, const char */*alg*/); | |
79 | int multigest_add_subst(multigest_t */*multigest*/, const char */*from*/, const char */*to*/); | 81 | int multigest_add_subst(multigest_t */*multigest*/, const char */*from*/, const char */*to*/); | |
80 | void multigest_update(multigest_t */*multigest*/, const char */*data*/, size_t /*len*/); | 82 | void multigest_update(multigest_t */*multigest*/, const void */*data*/, size_t /*len*/); | |
81 | void multigest_final(multigest_t */*multigest*/, uint8_t */*raw*/); | 83 | void multigest_final(multigest_t */*multigest*/, uint8_t */*raw*/); | |
82 | uint32_t multigest_get_rawsize(multigest_t */*multigest*/); | 84 | uint32_t multigest_get_rawsize(multigest_t */*multigest*/); | |
83 | 85 | |||
84 | /* high-level interface */ | 86 | /* high-level interface */ | |
85 | uint8_t *multigest_data(const char */*alg*/, const char */*data*/, size_t /*size*/, uint8_t */*raw*/, const char */*pat*/, const char */*repl*/); | 87 | uint8_t *multigest_data(const char */*alg*/, const void */*data*/, size_t /*size*/, uint8_t */*raw*/, const char */*pat*/, const char */*repl*/); | |
86 | uint8_t *multigest_file(const char */*alg*/, const char */*f*/, uint8_t */*raw*/, const char */*pat*/, const char */*repl*/); | 88 | uint8_t *multigest_file(const char */*alg*/, const char */*f*/, uint8_t */*raw*/, const char */*pat*/, const char */*repl*/); | |
87 | uint32_t multigest_algs_rawsize(const char */*algs*/); | 89 | uint32_t multigest_algs_rawsize(const char */*algs*/); | |
88 | 90 | |||
89 | /* output */ | 91 | /* output */ | |
90 | void multigest_unpcstring(const char */*in*/, size_t /*isize*/, char */*out*/, size_t /*osize*/); | 92 | void multigest_unpcstring(const char */*in*/, size_t /*isize*/, char */*out*/, size_t /*osize*/); | |
91 | int multigest_format_hex(uint8_t */*raw*/, const char */*algname*/, char */*out*/, size_t /*size*/); | 93 | int multigest_format_hex(uint8_t */*raw*/, const char */*algname*/, char */*out*/, size_t /*size*/); | |
92 | int multigest_print_hex(uint8_t */*raw*/, const char */*algname*/, const char */*outname*/, const char */*f*/, const char */*sub*/, const char */*sep*/, const char */*format*/); | 94 | int multigest_print_hex(uint8_t */*raw*/, const char */*algname*/, const char */*outname*/, const char */*f*/, const char */*sub*/, const char */*sep*/, const char */*format*/); | |
93 | char *multigest_format_raw(const uint8_t */*in*/, size_t /*insize*/, char */*out*/, size_t /*outsize*/); | 95 | char *multigest_format_raw(const uint8_t */*in*/, size_t /*insize*/, char */*out*/, size_t /*outsize*/); | |
94 | 96 | |||
95 | __END_DECLS | 97 | __END_DECLS | |
96 | 98 | |||
97 | #endif | 99 | #endif |
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: rmd160.c,v 1.1.1.1 2014/03/05 05:09:44 agc Exp $ */ | 1 | /* $NetBSD: rmd160.c,v 1.2 2015/02/12 01:57:57 agc Exp $ */ | |
2 | 2 | |||
3 | /********************************************************************\ | 3 | /********************************************************************\ | |
4 | * | 4 | * | |
5 | * FILE: rmd160.c | 5 | * FILE: rmd160.c | |
6 | * | 6 | * | |
7 | * CONTENTS: A sample C-implementation of the RIPEMD-160 | 7 | * CONTENTS: A sample C-implementation of the RIPEMD-160 | |
8 | * hash-function. | 8 | * hash-function. | |
9 | * TARGET: any computer with an ANSI C compiler | 9 | * TARGET: any computer with an ANSI C compiler | |
10 | * | 10 | * | |
11 | * AUTHOR: Antoon Bosselaers, ESAT-COSIC | 11 | * AUTHOR: Antoon Bosselaers, ESAT-COSIC | |
12 | * (Arranged for libc by Todd C. Miller) | 12 | * (Arranged for libc by Todd C. Miller) | |
13 | * DATE: 1 March 1996 | 13 | * DATE: 1 March 1996 | |
14 | * VERSION: 1.0 | 14 | * VERSION: 1.0 | |
@@ -420,22 +420,22 @@ RMD160Final(uint8_t digest[20], RMD160_C | @@ -420,22 +420,22 @@ RMD160Final(uint8_t digest[20], RMD160_C | |||
420 | RMD160Transform(context->state, X); | 420 | RMD160Transform(context->state, X); | |
421 | memset(X, 0x0, sizeof(X)); | 421 | memset(X, 0x0, sizeof(X)); | |
422 | } | 422 | } | |
423 | 423 | |||
424 | /* append length in bits */ | 424 | /* append length in bits */ | |
425 | X[14] = context->length[0] << 3; | 425 | X[14] = context->length[0] << 3; | |
426 | X[15] = (context->length[0] >> 29) | | 426 | X[15] = (context->length[0] >> 29) | | |
427 | (context->length[1] << 3); | 427 | (context->length[1] << 3); | |
428 | RMD160Transform(context->state, X); | 428 | RMD160Transform(context->state, X); | |
429 | 429 | |||
430 | if (digest != NULL) { | 430 | if (digest != NULL) { | |
431 | for (i = 0; i < 20; i += 4) { | 431 | for (i = 0; i < 20; i += 4) { | |
432 | /* extracts the 8 least significant bits. */ | 432 | /* extracts the 8 least significant bits. */ | |
433 | digest[i] = context->state[i>>2]; | 433 | digest[i] = (uint8_t)context->state[i>>2]; | |
434 | digest[i + 1] = (context->state[i>>2] >> 8); | 434 | digest[i + 1] = (uint8_t)(context->state[i>>2] >> 8); | |
435 | digest[i + 2] = (context->state[i>>2] >> 16); | 435 | digest[i + 2] = (uint8_t)(context->state[i>>2] >> 16); | |
436 | digest[i + 3] = (context->state[i>>2] >> 24); | 436 | digest[i + 3] = (uint8_t)(context->state[i>>2] >> 24); | |
437 | } | 437 | } | |
438 | } | 438 | } | |
439 | } | 439 | } | |
440 | 440 | |||
441 | /************************ end of file rmd160.c **********************/ | 441 | /************************ end of file rmd160.c **********************/ |
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: sha1.c,v 1.1.1.1 2014/03/05 05:09:44 agc Exp $ */ | 1 | /* $NetBSD: sha1.c,v 1.2 2015/02/12 01:57:57 agc Exp $ */ | |
2 | /* $OpenBSD: sha1.c,v 1.9 1997/07/23 21:12:32 kstailey Exp $ */ | 2 | /* $OpenBSD: sha1.c,v 1.9 1997/07/23 21:12:32 kstailey Exp $ */ | |
3 | 3 | |||
4 | /* | 4 | /* | |
5 | * SHA-1 in C | 5 | * SHA-1 in C | |
6 | * By Steve Reid <steve@edmweb.com> | 6 | * By Steve Reid <steve@edmweb.com> | |
7 | * 100% Public Domain | 7 | * 100% Public Domain | |
8 | * | 8 | * | |
9 | * Test Vectors (from FIPS PUB 180-1) | 9 | * Test Vectors (from FIPS PUB 180-1) | |
10 | * "abc" | 10 | * "abc" | |
11 | * A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D | 11 | * A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D | |
12 | * "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" | 12 | * "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" | |
13 | * 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1 | 13 | * 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1 | |
14 | * A million repetitions of "a" | 14 | * A million repetitions of "a" | |
@@ -215,28 +215,28 @@ SHA1Init(SHA1_CTX *context) | @@ -215,28 +215,28 @@ SHA1Init(SHA1_CTX *context) | |||
215 | /* | 215 | /* | |
216 | * Run your data through this. | 216 | * Run your data through this. | |
217 | */ | 217 | */ | |
218 | void | 218 | void | |
219 | SHA1Update(SHA1_CTX *context, const uint8_t *data, size_t len) | 219 | SHA1Update(SHA1_CTX *context, const uint8_t *data, size_t len) | |
220 | { | 220 | { | |
221 | unsigned int i; | 221 | unsigned int i; | |
222 | uint32_t j; | 222 | uint32_t j; | |
223 | 223 | |||
224 | _DIAGASSERT(context != 0); | 224 | _DIAGASSERT(context != 0); | |
225 | _DIAGASSERT(data != 0); | 225 | _DIAGASSERT(data != 0); | |
226 | 226 | |||
227 | j = context->count[0]; | 227 | j = context->count[0]; | |
228 | if ((context->count[0] += len << 3) < j) | 228 | if ((context->count[0] += (uint32_t)(len << 3)) < j) | |
229 | context->count[1] += (len>>29)+1; | 229 | context->count[1] += (uint32_t)((len>>29)+1); | |
230 | j = (j >> 3) & 63; | 230 | j = (j >> 3) & 63; | |
231 | if ((j + len) > 63) { | 231 | if ((j + len) > 63) { | |
232 | i = 64 - j; | 232 | i = 64 - j; | |
233 | (void)memcpy(&context->buffer[j], data, i); | 233 | (void)memcpy(&context->buffer[j], data, i); | |
234 | SHA1Transform(context->state, context->buffer); | 234 | SHA1Transform(context->state, context->buffer); | |
235 | for ( ; i + 63 < len; i += 64) | 235 | for ( ; i + 63 < len; i += 64) | |
236 | SHA1Transform(context->state, &data[i]); | 236 | SHA1Transform(context->state, &data[i]); | |
237 | j = 0; | 237 | j = 0; | |
238 | } else { | 238 | } else { | |
239 | i = 0; | 239 | i = 0; | |
240 | } | 240 | } | |
241 | (void)memcpy(&context->buffer[j], &data[i], len - i); | 241 | (void)memcpy(&context->buffer[j], &data[i], len - i); | |
242 | } | 242 | } |
@@ -809,27 +809,27 @@ TIGER_Update(TIGER_CTX *ctx, const void | @@ -809,27 +809,27 @@ TIGER_Update(TIGER_CTX *ctx, const void | |||
809 | u.temp8[j] = 0; | 809 | u.temp8[j] = 0; | |
810 | } | 810 | } | |
811 | } | 811 | } | |
812 | if (j > 56) { | 812 | if (j > 56) { | |
813 | for (; j < 64; j++) { | 813 | for (; j < 64; j++) { | |
814 | u.temp8[j] = 0; | 814 | u.temp8[j] = 0; | |
815 | } | 815 | } | |
816 | tiger_compress(u.temp64, ctx->ctx); | 816 | tiger_compress(u.temp64, ctx->ctx); | |
817 | j = 0; | 817 | j = 0; | |
818 | } | 818 | } | |
819 | for (; j < 56; j++) { | 819 | for (; j < 56; j++) { | |
820 | u.temp8[j] = 0; | 820 | u.temp8[j] = 0; | |
821 | } | 821 | } | |
822 | ((uint64_t *)(void *)(&(u.temp8[56])))[0] = ((uint64_t)length) << 3; | 822 | u.temp64[7] = ((uint64_t)length) << 3; | |
823 | tiger_compress(u.temp64, ctx->ctx); | 823 | tiger_compress(u.temp64, ctx->ctx); | |
824 | } | 824 | } | |
825 | 825 | |||
826 | void | 826 | void | |
827 | TIGER_Final(uint8_t *digest, TIGER_CTX *ctx) | 827 | TIGER_Final(uint8_t *digest, TIGER_CTX *ctx) | |
828 | { | 828 | { | |
829 | uint64_t le[3]; | 829 | uint64_t le[3]; | |
830 | int indian = 1; | 830 | int indian = 1; | |
831 | int i; | 831 | int i; | |
832 | 832 | |||
833 | if (digest == NULL || ctx == NULL) { | 833 | if (digest == NULL || ctx == NULL) { | |
834 | return; | 834 | return; | |
835 | } | 835 | } |
@@ -1443,27 +1443,27 @@ whirlpool_update(whirlpool_context_t *st | @@ -1443,27 +1443,27 @@ whirlpool_update(whirlpool_context_t *st | |||
1443 | int sourcePos = 0; /* index of leftmost source u8 containing data (1 to 8 bits). */ | 1443 | int sourcePos = 0; /* index of leftmost source u8 containing data (1 to 8 bits). */ | |
1444 | unsigned sourceGap = (8 - ((int)sourceBits & 7)) & 7; /* space on source[sourcePos]. */ | 1444 | unsigned sourceGap = (8 - ((int)sourceBits & 7)) & 7; /* space on source[sourcePos]. */ | |
1445 | int bufferRem = structpointer->bufferBits & 7; /* occupied bits on buffer[bufferPos]. */ | 1445 | int bufferRem = structpointer->bufferBits & 7; /* occupied bits on buffer[bufferPos]. */ | |
1446 | int i; | 1446 | int i; | |
1447 | u32 b, carry; | 1447 | u32 b, carry; | |
1448 | u8 *buffer = structpointer->buffer; | 1448 | u8 *buffer = structpointer->buffer; | |
1449 | u8 *bitLength = structpointer->bitLength; | 1449 | u8 *bitLength = structpointer->bitLength; | |
1450 | int bufferBits = structpointer->bufferBits; | 1450 | int bufferBits = structpointer->bufferBits; | |
1451 | int bufferPos = structpointer->bufferPos; | 1451 | int bufferPos = structpointer->bufferPos; | |
1452 | 1452 | |||
1453 | /* | 1453 | /* | |
1454 | * tally the length of the added data: | 1454 | * tally the length of the added data: | |
1455 | */ | 1455 | */ | |
1456 | u64 value = sourceBits; | 1456 | u64 value = (u64)sourceBits; | |
1457 | for (i = 31, carry = 0; i >= 0 && (carry != 0 || value != LL(0)); i--) { | 1457 | for (i = 31, carry = 0; i >= 0 && (carry != 0 || value != LL(0)); i--) { | |
1458 | carry += bitLength[i] + ((u32)value & 0xff); | 1458 | carry += bitLength[i] + ((u32)value & 0xff); | |
1459 | bitLength[i] = (u8)carry; | 1459 | bitLength[i] = (u8)carry; | |
1460 | carry >>= 8; | 1460 | carry >>= 8; | |
1461 | value >>= 8; | 1461 | value >>= 8; | |
1462 | } | 1462 | } | |
1463 | /* | 1463 | /* | |
1464 | * process data in chunks of 8 bits (a more efficient approach would be to take whole-word chunks): | 1464 | * process data in chunks of 8 bits (a more efficient approach would be to take whole-word chunks): | |
1465 | */ | 1465 | */ | |
1466 | while (sourceBits > 8) { | 1466 | while (sourceBits > 8) { | |
1467 | /* N.B. at least source[sourcePos] and source[sourcePos+1] contain data. */ | 1467 | /* N.B. at least source[sourcePos] and source[sourcePos+1] contain data. */ | |
1468 | /* | 1468 | /* | |
1469 | * take a byte from the source: | 1469 | * take a byte from the source: | |
@@ -1475,43 +1475,43 @@ whirlpool_update(whirlpool_context_t *st | @@ -1475,43 +1475,43 @@ whirlpool_update(whirlpool_context_t *st | |||
1475 | */ | 1475 | */ | |
1476 | buffer[bufferPos++] |= (u8)(b >> bufferRem); | 1476 | buffer[bufferPos++] |= (u8)(b >> bufferRem); | |
1477 | bufferBits += 8 - bufferRem; /* bufferBits = 8*bufferPos; */ | 1477 | bufferBits += 8 - bufferRem; /* bufferBits = 8*bufferPos; */ | |
1478 | if (bufferBits == WHIRLPOOL_DIGEST_BITS) { | 1478 | if (bufferBits == WHIRLPOOL_DIGEST_BITS) { | |
1479 | /* | 1479 | /* | |
1480 | * process data block: | 1480 | * process data block: | |
1481 | */ | 1481 | */ | |
1482 | processBuffer(structpointer); | 1482 | processBuffer(structpointer); | |
1483 | /* | 1483 | /* | |
1484 | * reset buffer: | 1484 | * reset buffer: | |
1485 | */ | 1485 | */ | |
1486 | bufferBits = bufferPos = 0; | 1486 | bufferBits = bufferPos = 0; | |
1487 | } | 1487 | } | |
1488 | buffer[bufferPos] = b << (8 - bufferRem); | 1488 | buffer[bufferPos] = (u8)(b << (8 - bufferRem)); | |
1489 | bufferBits += bufferRem; | 1489 | bufferBits += bufferRem; | |
1490 | /* | 1490 | /* | |
1491 | * proceed to remaining data: | 1491 | * proceed to remaining data: | |
1492 | */ | 1492 | */ | |
1493 | sourceBits -= 8; | 1493 | sourceBits -= 8; | |
1494 | sourcePos++; | 1494 | sourcePos++; | |
1495 | } | 1495 | } | |
1496 | /* now 0 <= sourceBits <= 8; | 1496 | /* now 0 <= sourceBits <= 8; | |
1497 | * furthermore, all data (if any is left) is in source[sourcePos]. | 1497 | * furthermore, all data (if any is left) is in source[sourcePos]. | |
1498 | */ | 1498 | */ | |
1499 | if (sourceBits > 0) { | 1499 | if (sourceBits > 0) { | |
1500 | b = (source[sourcePos] << sourceGap) & 0xff; /* bits are left-justified on b. */ | 1500 | b = (source[sourcePos] << sourceGap) & 0xff; /* bits are left-justified on b. */ | |
1501 | /* | 1501 | /* | |
1502 | * process the remaining bits: | 1502 | * process the remaining bits: | |
1503 | */ | 1503 | */ | |
1504 | buffer[bufferPos] |= b >> bufferRem; | 1504 | buffer[bufferPos] |= (u8)(b >> bufferRem); | |
1505 | } else { | 1505 | } else { | |
1506 | b = 0; | 1506 | b = 0; | |
1507 | } | 1507 | } | |
1508 | if (bufferRem + sourceBits < 8) { | 1508 | if (bufferRem + sourceBits < 8) { | |
1509 | /* | 1509 | /* | |
1510 | * all remaining data fits on buffer[bufferPos], | 1510 | * all remaining data fits on buffer[bufferPos], | |
1511 | * and there still remains some space. | 1511 | * and there still remains some space. | |
1512 | */ | 1512 | */ | |
1513 | bufferBits += (int)sourceBits; | 1513 | bufferBits += (int)sourceBits; | |
1514 | } else { | 1514 | } else { | |
1515 | /* | 1515 | /* | |
1516 | * buffer[bufferPos] is full: | 1516 | * buffer[bufferPos] is full: | |
1517 | */ | 1517 | */ | |
@@ -1521,93 +1521,93 @@ whirlpool_update(whirlpool_context_t *st | @@ -1521,93 +1521,93 @@ whirlpool_update(whirlpool_context_t *st | |||
1521 | /* now 0 <= sourceBits < 8; | 1521 | /* now 0 <= sourceBits < 8; | |
1522 | * furthermore, all data (if any is left) is in source[sourcePos]. | 1522 | * furthermore, all data (if any is left) is in source[sourcePos]. | |
1523 | */ | 1523 | */ | |
1524 | if (bufferBits == WHIRLPOOL_DIGEST_BITS) { | 1524 | if (bufferBits == WHIRLPOOL_DIGEST_BITS) { | |
1525 | /* | 1525 | /* | |
1526 | * process data block: | 1526 | * process data block: | |
1527 | */ | 1527 | */ | |
1528 | processBuffer(structpointer); | 1528 | processBuffer(structpointer); | |
1529 | /* | 1529 | /* | |
1530 | * reset buffer: | 1530 | * reset buffer: | |
1531 | */ | 1531 | */ | |
1532 | bufferBits = bufferPos = 0; | 1532 | bufferBits = bufferPos = 0; | |
1533 | } | 1533 | } | |
1534 | buffer[bufferPos] = b << (8 - bufferRem); | 1534 | buffer[bufferPos] = (u8)(b << (8 - bufferRem)); | |
1535 | bufferBits += (int)sourceBits; | 1535 | bufferBits += (int)sourceBits; | |
1536 | } | 1536 | } | |
1537 | structpointer->bufferBits = bufferBits; | 1537 | structpointer->bufferBits = bufferBits; | |
1538 | structpointer->bufferPos = bufferPos; | 1538 | structpointer->bufferPos = bufferPos; | |
1539 | } | 1539 | } | |
1540 | 1540 | |||
1541 | /** | 1541 | /** | |
1542 | * Get the hash value from the hashing state. | 1542 | * Get the hash value from the hashing state. | |
1543 | * | 1543 | * | |
1544 | * This method uses the invariant: bufferBits < WHIRLPOOL_DIGEST_BITS | 1544 | * This method uses the invariant: bufferBits < WHIRLPOOL_DIGEST_BITS | |
1545 | */ | 1545 | */ | |
1546 | void | 1546 | void | |
1547 | whirlpool_finalize(char *result, whirlpool_context_t *structpointer) | 1547 | whirlpool_finalize(char *result, whirlpool_context_t *structpointer) | |
1548 | { | 1548 | { | |
1549 | int i; | 1549 | int i; | |
1550 | u8 *buffer = structpointer->buffer; | 1550 | u8 *buffer = structpointer->buffer; | |
1551 | u8 *bitLength = structpointer->bitLength; | 1551 | u8 *bitLength = structpointer->bitLength; | |
1552 | int bufferBits = structpointer->bufferBits; | 1552 | int bufferBits = structpointer->bufferBits; | |
1553 | int bufferPos = structpointer->bufferPos; | 1553 | int bufferPos = structpointer->bufferPos; | |
1554 | char *digest = result; | 1554 | char *digest = result; | |
1555 | 1555 | |||
1556 | /* | 1556 | /* | |
1557 | * append a '1'-bit: | 1557 | * append a '1'-bit: | |
1558 | */ | 1558 | */ | |
1559 | buffer[bufferPos] |= 0x80U >> (bufferBits & 7); | 1559 | buffer[bufferPos] |= (u8)(0x80U >> (bufferBits & 7)); | |
1560 | bufferPos++; /* all remaining bits on the current u8 are set to zero. */ | 1560 | bufferPos++; /* all remaining bits on the current u8 are set to zero. */ | |
1561 | /* | 1561 | /* | |
1562 | * pad with zero bits to complete (N*WHIRLPOOL_WBLOCK_BITS - WHIRLPOOL_LENGTH_BITS) bits: | 1562 | * pad with zero bits to complete (N*WHIRLPOOL_WBLOCK_BITS - WHIRLPOOL_LENGTH_BITS) bits: | |
1563 | */ | 1563 | */ | |
1564 | if (bufferPos > WHIRLPOOL_WBLOCK_BYTES - WHIRLPOOL_LENGTH_BYTES) { | 1564 | if (bufferPos > WHIRLPOOL_WBLOCK_BYTES - WHIRLPOOL_LENGTH_BYTES) { | |
1565 | if (bufferPos < WHIRLPOOL_WBLOCK_BYTES) { | 1565 | if (bufferPos < WHIRLPOOL_WBLOCK_BYTES) { | |
1566 | memset(&buffer[bufferPos], 0, WHIRLPOOL_WBLOCK_BYTES - bufferPos); | 1566 | memset(&buffer[bufferPos], 0, (size_t)(WHIRLPOOL_WBLOCK_BYTES - bufferPos)); | |
1567 | } | 1567 | } | |
1568 | /* | 1568 | /* | |
1569 | * process data block: | 1569 | * process data block: | |
1570 | */ | 1570 | */ | |
1571 | processBuffer(structpointer); | 1571 | processBuffer(structpointer); | |
1572 | /* | 1572 | /* | |
1573 | * reset buffer: | 1573 | * reset buffer: | |
1574 | */ | 1574 | */ | |
1575 | bufferPos = 0; | 1575 | bufferPos = 0; | |
1576 | } | 1576 | } | |
1577 | if (bufferPos < WHIRLPOOL_WBLOCK_BYTES - WHIRLPOOL_LENGTH_BYTES) { | 1577 | if (bufferPos < WHIRLPOOL_WBLOCK_BYTES - WHIRLPOOL_LENGTH_BYTES) { | |
1578 | memset(&buffer[bufferPos], 0, (WHIRLPOOL_WBLOCK_BYTES - WHIRLPOOL_LENGTH_BYTES) - bufferPos); | 1578 | memset(&buffer[bufferPos], 0, (size_t)((WHIRLPOOL_WBLOCK_BYTES - WHIRLPOOL_LENGTH_BYTES) - bufferPos)); | |
1579 | } | 1579 | } | |
1580 | bufferPos = WHIRLPOOL_WBLOCK_BYTES - WHIRLPOOL_LENGTH_BYTES; | 1580 | bufferPos = WHIRLPOOL_WBLOCK_BYTES - WHIRLPOOL_LENGTH_BYTES; | |
1581 | /* | 1581 | /* | |
1582 | * append bit length of hashed data: | 1582 | * append bit length of hashed data: | |
1583 | */ | 1583 | */ | |
1584 | memcpy(&buffer[WHIRLPOOL_WBLOCK_BYTES - WHIRLPOOL_LENGTH_BYTES], bitLength, WHIRLPOOL_LENGTH_BYTES); | 1584 | memcpy(&buffer[WHIRLPOOL_WBLOCK_BYTES - WHIRLPOOL_LENGTH_BYTES], bitLength, WHIRLPOOL_LENGTH_BYTES); | |
1585 | /* | 1585 | /* | |
1586 | * process data block: | 1586 | * process data block: | |
1587 | */ | 1587 | */ | |
1588 | processBuffer(structpointer); | 1588 | processBuffer(structpointer); | |
1589 | /* | 1589 | /* | |
1590 | * return the completed message digest: | 1590 | * return the completed message digest: | |
1591 | */ | 1591 | */ | |
1592 | for (i = 0; i < WHIRLPOOL_DIGEST_BYTES/8; i++) { | 1592 | for (i = 0; i < WHIRLPOOL_DIGEST_BYTES/8; i++) { | |
1593 | digest[0] = (u8)(structpointer->hash[i] >> 56); | 1593 | digest[0] = (char)(structpointer->hash[i] >> 56); | |
1594 | digest[1] = (u8)(structpointer->hash[i] >> 48); | 1594 | digest[1] = (char)(structpointer->hash[i] >> 48); | |
1595 | digest[2] = (u8)(structpointer->hash[i] >> 40); | 1595 | digest[2] = (char)(structpointer->hash[i] >> 40); | |
1596 | digest[3] = (u8)(structpointer->hash[i] >> 32); | 1596 | digest[3] = (char)(structpointer->hash[i] >> 32); | |
1597 | digest[4] = (u8)(structpointer->hash[i] >> 24); | 1597 | digest[4] = (char)(structpointer->hash[i] >> 24); | |
1598 | digest[5] = (u8)(structpointer->hash[i] >> 16); | 1598 | digest[5] = (char)(structpointer->hash[i] >> 16); | |
1599 | digest[6] = (u8)(structpointer->hash[i] >> 8); | 1599 | digest[6] = (char)(structpointer->hash[i] >> 8); | |
1600 | digest[7] = (u8)(structpointer->hash[i] ); | 1600 | digest[7] = (char)(structpointer->hash[i] ); | |
1601 | digest += 8; | 1601 | digest += 8; | |
1602 | } | 1602 | } | |
1603 | structpointer->bufferBits = bufferBits; | 1603 | structpointer->bufferBits = bufferBits; | |
1604 | structpointer->bufferPos = bufferPos; | 1604 | structpointer->bufferPos = bufferPos; | |
1605 | 1605 | |||
1606 | } | 1606 | } | |
1607 | 1607 | |||
1608 | static void | 1608 | static void | |
1609 | print_uint64(char *buf, uint64_t val) | 1609 | print_uint64(char *buf, uint64_t val) | |
1610 | { | 1610 | { | |
1611 | int i = 0; | 1611 | int i = 0; | |
1612 | static const char hexdigits[] = "0123456789abcdef"; | 1612 | static const char hexdigits[] = "0123456789abcdef"; | |
1613 | 1613 |