void RMD160Final(u_char digest[20], RMD160_CTX *ctx) { int i; u_char size[8]; u_int32_t padlen; PUT_64BIT_LE(size, ctx->count); /* * pad to 64 byte blocks, at least one byte from PADDING plus 8 bytes * for the size */ padlen = 64 - ((ctx->count/8) % 64); if (padlen < 1 + 8) padlen += 64; RMD160Update(ctx, PADDING, padlen - 8); /* padlen - 8 <= 64 */ RMD160Update(ctx, size, 8); if (digest != NULL) for (i = 0; i < 5; i++) PUT_32BIT_LE(digest + i*4, ctx->state[i]); memset(ctx, 0, sizeof (*ctx)); }
void hmac_ripemd160 (char *key, int keylen, char *input_digest, int len) { hmac_ripemd160_ctx hmac; unsigned char tk[RIPEMD160_DIGESTSIZE]; /* If the key is longer than the hash algorithm block size, let key = ripemd160(key), as per HMAC specifications. */ if (keylen > RIPEMD160_BLOCKSIZE) { RMD160_CTX tctx; RMD160Init(&tctx); RMD160Update(&tctx, (const unsigned char *) key, keylen); RMD160Final(tk, &tctx); key = (char *) tk; keylen = RIPEMD160_DIGESTSIZE; burn (&tctx, sizeof(tctx)); // Prevent leaks } hmac_ripemd160_internal (key, keylen, input_digest, len, &hmac); burn (&hmac, sizeof(hmac)); burn (tk, sizeof(tk)); }
static int __archive_libc_ripemd160update(archive_rmd160_ctx *ctx, const void *indata, size_t insize) { RMD160Update(ctx, indata, insize); return (ARCHIVE_OK); }
void RMD160(const uint8_t* input, size_t length, uint8_t digest[RMD160_DIGEST_LENGTH]) { RMD160CTX ctx; RMD160Init(&ctx); RMD160Update(&ctx, input, length); RMD160Final(&ctx, digest); }
void hmac_ripemd160_internal (char *key, int keylen, char *input_digest, int len, hmac_ripemd160_ctx* hmac) { RMD160_CTX* context = &(hmac->context); unsigned char* k_pad = (unsigned char*) hmac->k_pad; /* inner/outer padding - key XORd with ipad */ int i; /* RMD160(K XOR opad, RMD160(K XOR ipad, text)) where K is an n byte key ipad is the byte 0x36 repeated RIPEMD160_BLOCKSIZE times opad is the byte 0x5c repeated RIPEMD160_BLOCKSIZE times and text is the data being protected */ /* start out by storing key in pads */ memset(k_pad, 0x36, 65); /* XOR key with ipad and opad values */ for (i=0; i<keylen; i++) { k_pad[i] ^= key[i]; } /* perform inner RIPEMD-160 */ RMD160Init(context); /* init context for 1st pass */ RMD160Update(context, k_pad, RIPEMD160_BLOCKSIZE); /* start with inner pad */ RMD160Update(context, (const unsigned char *) input_digest, len); /* then text of datagram */ RMD160Final((unsigned char *) input_digest, context); /* finish up 1st pass */ /* perform outer RIPEMD-160 */ memset(k_pad, 0x5c, 65); for (i=0; i<keylen; i++) { k_pad[i] ^= key[i]; } RMD160Init(context); /* init context for 2nd pass */ RMD160Update(context, k_pad, RIPEMD160_BLOCKSIZE); /* start with outer pad */ /* results of 1st hash */ RMD160Update(context, (const unsigned char *) input_digest, RIPEMD160_DIGESTSIZE); RMD160Final((unsigned char *) input_digest, context); /* finish up 2nd pass */ }
void RMD160Pad(RMD160CTX* context) { uint8_t len[8]; uint32_t plen; PUT_64BIT_LE(len, context->count); plen = RMD160_BLOCK_LENGTH - ((context->count / 8) % RMD160_BLOCK_LENGTH); if (plen < 1 + 8) { plen += RMD160_BLOCK_LENGTH; } RMD160Update(context, PAD, plen - 8); RMD160Update(context, len, 8); }
char * RMD160Data(const u_char *data, size_t len, char *buf) { RMD160_CTX ctx; RMD160Init(&ctx); RMD160Update(&ctx, data, len); return (RMD160End(&ctx, buf)); }
void RMD160Pad(RMD160_CTX *ctx) { u_int8_t size[8]; size_t padlen; PUT_64BIT_LE(size, ctx->count); /* * pad to RMD160_BLOCK_LENGTH byte blocks, at least one byte from * PADDING plus 8 bytes for the size */ padlen = RMD160_BLOCK_LENGTH - ((ctx->count / 8) % RMD160_BLOCK_LENGTH); if (padlen < 1 + 8) padlen += RMD160_BLOCK_LENGTH; RMD160Update(ctx, PADDING, padlen - 8); /* padlen - 8 <= 64 */ RMD160Update(ctx, size, 8); }
char * RMD160Data(const uint8_t *data, size_t len, char *buf) { RMD160_CTX ctx; _DIAGASSERT(data != NULL); /* XXX: buf may be NULL ? */ RMD160Init(&ctx); RMD160Update(&ctx, data, len); return(RMD160End(&ctx, buf)); }
void derive_key_ripemd160 (char *pwd, int pwd_len, char *salt, int salt_len, uint32 iterations, char *dk, int dklen) { int b, l, r; hmac_ripemd160_ctx hmac; #ifndef TC_WINDOWS_BOOT unsigned char tk[RIPEMD160_DIGESTSIZE]; /* If the password is longer than the hash algorithm block size, let password = ripemd160(password), as per HMAC specifications. */ if (pwd_len > RIPEMD160_BLOCKSIZE) { RMD160_CTX tctx; RMD160Init(&tctx); RMD160Update(&tctx, (const unsigned char *) pwd, pwd_len); RMD160Final(tk, &tctx); pwd = (char *) tk; pwd_len = RIPEMD160_DIGESTSIZE; burn (&tctx, sizeof(tctx)); // Prevent leaks } #endif if (dklen % RIPEMD160_DIGESTSIZE) { l = 1 + dklen / RIPEMD160_DIGESTSIZE; } else { l = dklen / RIPEMD160_DIGESTSIZE; } r = dklen - (l - 1) * RIPEMD160_DIGESTSIZE; /* first l - 1 blocks */ for (b = 1; b < l; b++) { derive_u_ripemd160 (pwd, pwd_len, salt, salt_len, iterations, b, &hmac); memcpy (dk, hmac.u, RIPEMD160_DIGESTSIZE); dk += RIPEMD160_DIGESTSIZE; } /* last block */ derive_u_ripemd160 (pwd, pwd_len, salt, salt_len, iterations, b, &hmac); memcpy (dk, hmac.u, r); /* Prevent possible leaks. */ burn (&hmac, sizeof(hmac)); #ifndef TC_WINDOWS_BOOT burn (tk, sizeof(tk)); #endif }
static int keycrunch_rmd160(char *result, char *seed, char *passwd) { char *buf; RMD160_CTX rmd; u_int32_t results[5]; unsigned int buflen; /* * If seed and passwd are defined we are in keycrunch() mode, * else we are in f() mode. */ if (seed && passwd) { buflen = strlen(seed) + strlen(passwd); if ((buf = malloc(buflen + 1)) == NULL) return(-1); (void)strlcpy(buf, seed, buflen + 1); lowcase(buf); (void)strlcat(buf, passwd, buflen + 1); sevenbit(buf); } else { buf = result; buflen = SKEY_BINKEY_SIZE; } /* Crunch the key through RMD-160 */ RMD160Init(&rmd); RMD160Update(&rmd, (unsigned char *)buf, buflen); RMD160Final((unsigned char *)results, &rmd); /* Fold 160 to 64 bits */ results[0] ^= results[2]; results[1] ^= results[3]; results[0] ^= results[4]; (void)memcpy((void *)result, (void *)results, SKEY_BINKEY_SIZE); if (buf != result) (void)free(buf); return(0); }
char * RMD160File(char *filename, char *buf) { uint8_t buffer[BUFSIZ]; RMD160_CTX ctx; int fd, num, oerrno; _DIAGASSERT(filename != NULL); /* XXX: buf may be NULL ? */ RMD160Init(&ctx); if ((fd = open(filename, O_RDONLY)) < 0) return(0); while ((num = read(fd, buffer, sizeof(buffer))) > 0) RMD160Update(&ctx, buffer, (size_t)num); oerrno = errno; close(fd); errno = oerrno; return(num < 0 ? 0 : RMD160End(&ctx, buf)); }
char * RMD160FileChunk(const char *filename, char *buf, off_t off, off_t len) { struct stat sb; u_char buffer[BUFSIZ]; RMD160_CTX ctx; int fd, save_errno; ssize_t nr; RMD160Init(&ctx); if ((fd = open(filename, O_RDONLY)) < 0) return (NULL); if (len == 0) { if (fstat(fd, &sb) == -1) { close(fd); return (NULL); } len = sb.st_size; } if (off > 0 && lseek(fd, off, SEEK_SET) < 0) { close(fd); return (NULL); } while ((nr = read(fd, buffer, MIN(sizeof(buffer), len))) > 0) { RMD160Update(&ctx, buffer, (size_t)nr); if (len > 0 && (len -= nr) == 0) break; } save_errno = errno; close(fd); errno = save_errno; return (nr < 0 ? NULL : RMD160End(&ctx, buf)); }
static int RMD160Update_int(void *ctx, const u_int8_t *buf, u_int16_t len) { RMD160Update(ctx, buf, len); return 0; }
void Ripemd160::ProcessData (const ConstBufferPtr &data) { if_debug (ValidateDataParameters (data)); RMD160Update ((RMD160_CTX *) Context.Ptr(), data.Get(), (int) data.Size()); }
/* * mac: * method: hash method to use (see enum, gethash(..) output) * data1: buffer 1 (commonly a key[i]) * data1len: data1 lenght * data2: buffer 2 (commonly a message) * data2len: data2 lenght * dest: destination buffer * * Fills dest with a key and returns dest lenght * dest should have enough space. * On error returns -1 */ int mac(int method, const unsigned char *data1, unsigned int data1len, const unsigned char *data2, unsigned int data2len, unsigned char *dest) { HASH_CTX ctx; int i, destlen, tmplen; unsigned char *tmp; /* Calculate tmp buffer lenght */ tmplen = 0; if (data1len && data2len) { if (data1len > data2len) { tmplen = data1len / data2len * data2len; tmplen += (tmplen < data1len) ? data2len : 0; } else if (data1len < data2len) { tmplen = data2len / data1len * data1len; tmplen += (tmplen < data2len) ? data1len : 0; } else tmplen = data1len; } else { tmplen = (data1len) ? data1len : data2len; if (!tmplen) tmplen = 1; } /* Allocate needed memory and clear tmp buffer */ if ( (tmp = (unsigned char *) calloc(1, tmplen)) == NULL) return (-1); /* tmp = data1 xor data2 */ if (data1len && data2len) for (i = 0; i < tmplen; i++) tmp[i] = data1[i % data1len] ^ data2[i % data2len]; else if (data1len) memcpy(tmp, data1, tmplen); else memcpy(tmp, data2, tmplen); /* dest = hash(tmp) */ switch(method) { case MD5: MD5Init(&ctx.md5); MD5Update(&ctx.md5, tmp, tmplen); MD5Final(dest, &ctx.md5); destlen = 16; break; case RMD160: RMD160Init(&ctx.rmd160); RMD160Update(&ctx.rmd160, tmp, tmplen); RMD160Final(dest, &ctx.rmd160); destlen = 20; break; case SHA1: default: SHA1Init(&ctx.sha1); SHA1Update(&ctx.sha1, tmp, tmplen); SHA1Final(dest, &ctx.sha1); destlen = 20; break; } free(tmp); return (destlen); }
/* The random pool mixing function */ BOOL Randmix () { if (bRandmixEnabled) { unsigned char hashOutputBuffer [MAX_DIGESTSIZE]; WHIRLPOOL_CTX wctx; RMD160_CTX rctx; sha512_ctx sctx; sha256_ctx s256ctx; int poolIndex, digestIndex, digestSize; switch (HashFunction) { case RIPEMD160: digestSize = RIPEMD160_DIGESTSIZE; break; case SHA512: digestSize = SHA512_DIGESTSIZE; break; case SHA256: digestSize = SHA256_DIGESTSIZE; break; case WHIRLPOOL: digestSize = WHIRLPOOL_DIGESTSIZE; break; default: TC_THROW_FATAL_EXCEPTION; } if (RNG_POOL_SIZE % digestSize) TC_THROW_FATAL_EXCEPTION; for (poolIndex = 0; poolIndex < RNG_POOL_SIZE; poolIndex += digestSize) { /* Compute the message digest of the entire pool using the selected hash function. */ switch (HashFunction) { case RIPEMD160: RMD160Init(&rctx); RMD160Update(&rctx, pRandPool, RNG_POOL_SIZE); RMD160Final(hashOutputBuffer, &rctx); break; case SHA512: sha512_begin (&sctx); sha512_hash (pRandPool, RNG_POOL_SIZE, &sctx); sha512_end (hashOutputBuffer, &sctx); break; case SHA256: sha256_begin (&s256ctx); sha256_hash (pRandPool, RNG_POOL_SIZE, &s256ctx); sha256_end (hashOutputBuffer, &s256ctx); break; case WHIRLPOOL: WHIRLPOOL_init (&wctx); WHIRLPOOL_add (pRandPool, RNG_POOL_SIZE * 8, &wctx); WHIRLPOOL_finalize (&wctx, hashOutputBuffer); break; default: // Unknown/wrong ID TC_THROW_FATAL_EXCEPTION; } /* XOR the resultant message digest to the pool at the poolIndex position. */ for (digestIndex = 0; digestIndex < digestSize; digestIndex++) { pRandPool [poolIndex + digestIndex] ^= hashOutputBuffer [digestIndex]; } } /* Prevent leaks */ burn (hashOutputBuffer, MAX_DIGESTSIZE); switch (HashFunction) { case RIPEMD160: burn (&rctx, sizeof(rctx)); break; case SHA512: burn (&sctx, sizeof(sctx)); break; case SHA256: burn (&s256ctx, sizeof(s256ctx)); break; case WHIRLPOOL: burn (&wctx, sizeof(wctx)); break; default: // Unknown/wrong ID TC_THROW_FATAL_EXCEPTION; } } return TRUE; }
void hmac_ripemd160 (char *key, int keylen, char *input, int len, char *digest) { RMD160_CTX context; unsigned char k_ipad[65]; /* inner padding - key XORd with ipad */ unsigned char k_opad[65]; /* outer padding - key XORd with opad */ unsigned char tk[RIPEMD160_DIGESTSIZE]; int i; /* If the key is longer than the hash algorithm block size, let key = ripemd160(key), as per HMAC specifications. */ if (keylen > RIPEMD160_BLOCKSIZE) { RMD160_CTX tctx; RMD160Init(&tctx); RMD160Update(&tctx, (const unsigned char *) key, keylen); RMD160Final(tk, &tctx); key = (char *) tk; keylen = RIPEMD160_DIGESTSIZE; burn (&tctx, sizeof(tctx)); // Prevent leaks } /* RMD160(K XOR opad, RMD160(K XOR ipad, text)) where K is an n byte key ipad is the byte 0x36 repeated RIPEMD160_BLOCKSIZE times opad is the byte 0x5c repeated RIPEMD160_BLOCKSIZE times and text is the data being protected */ /* start out by storing key in pads */ memset(k_ipad, 0x36, sizeof(k_ipad)); memset(k_opad, 0x5c, sizeof(k_opad)); /* XOR key with ipad and opad values */ for (i=0; i<keylen; i++) { k_ipad[i] ^= key[i]; k_opad[i] ^= key[i]; } /* perform inner RIPEMD-160 */ RMD160Init(&context); /* init context for 1st pass */ RMD160Update(&context, k_ipad, RIPEMD160_BLOCKSIZE); /* start with inner pad */ RMD160Update(&context, (const unsigned char *) input, len); /* then text of datagram */ RMD160Final((unsigned char *) digest, &context); /* finish up 1st pass */ /* perform outer RIPEMD-160 */ RMD160Init(&context); /* init context for 2nd pass */ RMD160Update(&context, k_opad, RIPEMD160_BLOCKSIZE); /* start with outer pad */ /* results of 1st hash */ RMD160Update(&context, (const unsigned char *) digest, RIPEMD160_DIGESTSIZE); RMD160Final((unsigned char *) digest, &context); /* finish up 2nd pass */ /* Prevent possible leaks. */ burn (k_ipad, sizeof(k_ipad)); burn (k_opad, sizeof(k_opad)); burn (tk, sizeof(tk)); burn (&context, sizeof(context)); }