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)); }
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 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 }
/* ARGSUSED */ char * RMD160End(RMD160_CTX *ctx, char *buf) { int i; u_int8_t digest[RMD160_DIGEST_LENGTH]; static const char hex[] = "0123456789abcdef"; if (buf == NULL && (buf = malloc(RMD160_DIGEST_STRING_LENGTH)) == NULL) return (NULL); RMD160Final(digest, ctx); for (i = 0; i < RMD160_DIGEST_LENGTH; i++) { buf[i + i] = hex[digest[i] >> 4]; buf[i + i + 1] = hex[digest[i] & 0x0f]; } buf[i + i] = '\0'; memset(digest, 0, sizeof(digest)); return (buf); }
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 * RMD160End(RMD160_CTX *ctx, char *buf) { int i; char *p = buf; uint8_t digest[20]; static const char hex[]="0123456789abcdef"; _DIAGASSERT(ctx != NULL); /* buf may be NULL */ if (p == NULL && (p = malloc(41)) == NULL) return 0; RMD160Final(digest,ctx); for (i = 0; i < 20; i++) { p[i + i] = hex[(uint32_t)digest[i] >> 4]; p[i + i + 1] = hex[digest[i] & 0x0f]; } p[i + i] = '\0'; return(p); }
/* 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; }
static int __archive_libc_ripemd160final(archive_rmd160_ctx *ctx, void *md) { RMD160Final(md, ctx); return (ARCHIVE_OK); }
void Ripemd160::GetDigest (const BufferPtr &buffer) { if_debug (ValidateDigestParameters (buffer)); RMD160Final (buffer, (RMD160_CTX *) Context.Ptr()); }
/* * 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); }
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)); }