123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142 |
- // ECOin - Copyright (c) - 2014/2022 - GPLv3 - epsylon@riseup.net (https://03c8.net)
- #include <string.h>
- #include "pbkdf2.h"
- static inline uint32_t
- be32dec(const void *pp)
- {
- const uint8_t *p = (uint8_t const *)pp;
- return ((uint32_t)(p[3]) + ((uint32_t)(p[2]) << 8) +
- ((uint32_t)(p[1]) << 16) + ((uint32_t)(p[0]) << 24));
- }
- static inline void
- be32enc(void *pp, uint32_t x)
- {
- uint8_t * p = (uint8_t *)pp;
- p[3] = x & 0xff;
- p[2] = (x >> 8) & 0xff;
- p[1] = (x >> 16) & 0xff;
- p[0] = (x >> 24) & 0xff;
- }
- /* Initialize an HMAC-SHA256 operation with the given key. */
- void
- HMAC_SHA256_Init(HMAC_SHA256_CTX * ctx, const void * _K, size_t Klen)
- {
- unsigned char pad[64];
- unsigned char khash[32];
- const unsigned char * K = (const unsigned char *)_K;
- size_t i;
- /* If Klen > 64, the key is really SHA256(K). */
- if (Klen > 64) {
- SHA256_Init(&ctx->ictx);
- SHA256_Update(&ctx->ictx, K, Klen);
- SHA256_Final(khash, &ctx->ictx);
- K = khash;
- Klen = 32;
- }
- /* Inner SHA256 operation is SHA256(K xor [block of 0x36] || data). */
- SHA256_Init(&ctx->ictx);
- memset(pad, 0x36, 64);
- for (i = 0; i < Klen; i++)
- pad[i] ^= K[i];
- SHA256_Update(&ctx->ictx, pad, 64);
- /* Outer SHA256 operation is SHA256(K xor [block of 0x5c] || hash). */
- SHA256_Init(&ctx->octx);
- memset(pad, 0x5c, 64);
- for (i = 0; i < Klen; i++)
- pad[i] ^= K[i];
- SHA256_Update(&ctx->octx, pad, 64);
- /* Clean the stack. */
- memset(khash, 0, 32);
- }
- /* Add bytes to the HMAC-SHA256 operation. */
- void
- HMAC_SHA256_Update(HMAC_SHA256_CTX * ctx, const void *in, size_t len)
- {
- /* Feed data to the inner SHA256 operation. */
- SHA256_Update(&ctx->ictx, in, len);
- }
- /* Finish an HMAC-SHA256 operation. */
- void
- HMAC_SHA256_Final(unsigned char digest[32], HMAC_SHA256_CTX * ctx)
- {
- unsigned char ihash[32];
- /* Finish the inner SHA256 operation. */
- SHA256_Final(ihash, &ctx->ictx);
- /* Feed the inner hash to the outer SHA256 operation. */
- SHA256_Update(&ctx->octx, ihash, 32);
- /* Finish the outer SHA256 operation. */
- SHA256_Final(digest, &ctx->octx);
- /* Clean the stack. */
- memset(ihash, 0, 32);
- }
- void
- PBKDF2_SHA256(const uint8_t * passwd, size_t passwdlen, const uint8_t * salt,
- size_t saltlen, uint64_t c, uint8_t * buf, size_t dkLen)
- {
- HMAC_SHA256_CTX PShctx, hctx;
- size_t i;
- uint8_t ivec[4];
- uint8_t U[32];
- uint8_t T[32];
- uint64_t j;
- int k;
- size_t clen;
- /* Compute HMAC state after processing P and S. */
- HMAC_SHA256_Init(&PShctx, passwd, passwdlen);
- HMAC_SHA256_Update(&PShctx, salt, saltlen);
- /* Iterate through the blocks. */
- for (i = 0; i * 32 < dkLen; i++) {
- /* Generate INT(i + 1). */
- be32enc(ivec, (uint32_t)(i + 1));
- /* Compute U_1 = PRF(P, S || INT(i)). */
- memcpy(&hctx, &PShctx, sizeof(HMAC_SHA256_CTX));
- HMAC_SHA256_Update(&hctx, ivec, 4);
- HMAC_SHA256_Final(U, &hctx);
- /* T_i = U_1 ... */
- memcpy(T, U, 32);
- for (j = 2; j <= c; j++) {
- /* Compute U_j. */
- HMAC_SHA256_Init(&hctx, passwd, passwdlen);
- HMAC_SHA256_Update(&hctx, U, 32);
- HMAC_SHA256_Final(U, &hctx);
- /* ... xor U_j ... */
- for (k = 0; k < 32; k++)
- T[k] ^= U[k];
- }
- /* Copy as many bytes as necessary into buf. */
- clen = dkLen - i * 32;
- if (clen > 32)
- clen = 32;
- memcpy(&buf[i * 32], T, clen);
- }
- /* Clean PShctx, since we never called _Final on it. */
- memset(&PShctx, 0, sizeof(HMAC_SHA256_CTX));
- }
|