Update to 0.3.0 (New upstream + new RPC calls)
[novacoin.git] / src / pbkdf2.cpp
1 // Copyright (c) 2013 NovaCoin Developers
2
3 #include <string.h>
4 #include "pbkdf2.h"
5
6 static inline uint32_t
7 be32dec(const void *pp)
8 {
9     const uint8_t *p = (uint8_t const *)pp;
10
11     return ((uint32_t)(p[3]) + ((uint32_t)(p[2]) << 8) +
12         ((uint32_t)(p[1]) << 16) + ((uint32_t)(p[0]) << 24));
13 }
14
15 static inline void
16 be32enc(void *pp, uint32_t x)
17 {
18     uint8_t * p = (uint8_t *)pp;
19
20     p[3] = x & 0xff;
21     p[2] = (x >> 8) & 0xff;
22     p[1] = (x >> 16) & 0xff;
23     p[0] = (x >> 24) & 0xff;
24 }
25
26
27
28 /* Initialize an HMAC-SHA256 operation with the given key. */
29 void
30 HMAC_SHA256_Init(HMAC_SHA256_CTX * ctx, const void * _K, size_t Klen)
31 {
32     unsigned char pad[64];
33     unsigned char khash[32];
34     const unsigned char * K = (const unsigned char *)_K;
35     size_t i;
36
37     /* If Klen > 64, the key is really SHA256(K). */
38     if (Klen > 64) {
39         SHA256_Init(&ctx->ictx);
40         SHA256_Update(&ctx->ictx, K, Klen);
41         SHA256_Final(khash, &ctx->ictx);
42         K = khash;
43         Klen = 32;
44     }
45
46     /* Inner SHA256 operation is SHA256(K xor [block of 0x36] || data). */
47     SHA256_Init(&ctx->ictx);
48     memset(pad, 0x36, 64);
49     for (i = 0; i < Klen; i++)
50         pad[i] ^= K[i];
51     SHA256_Update(&ctx->ictx, pad, 64);
52
53     /* Outer SHA256 operation is SHA256(K xor [block of 0x5c] || hash). */
54     SHA256_Init(&ctx->octx);
55     memset(pad, 0x5c, 64);
56     for (i = 0; i < Klen; i++)
57         pad[i] ^= K[i];
58     SHA256_Update(&ctx->octx, pad, 64);
59
60     /* Clean the stack. */
61     memset(khash, 0, 32);
62 }
63
64 /* Add bytes to the HMAC-SHA256 operation. */
65 void
66 HMAC_SHA256_Update(HMAC_SHA256_CTX * ctx, const void *in, size_t len)
67 {
68
69     /* Feed data to the inner SHA256 operation. */
70     SHA256_Update(&ctx->ictx, in, len);
71 }
72
73 /* Finish an HMAC-SHA256 operation. */
74 void
75 HMAC_SHA256_Final(unsigned char digest[32], HMAC_SHA256_CTX * ctx)
76 {
77     unsigned char ihash[32];
78
79     /* Finish the inner SHA256 operation. */
80     SHA256_Final(ihash, &ctx->ictx);
81
82     /* Feed the inner hash to the outer SHA256 operation. */
83     SHA256_Update(&ctx->octx, ihash, 32);
84
85     /* Finish the outer SHA256 operation. */
86     SHA256_Final(digest, &ctx->octx);
87
88     /* Clean the stack. */
89     memset(ihash, 0, 32);
90 }
91
92 /**
93  * PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, c, buf, dkLen):
94  * Compute PBKDF2(passwd, salt, c, dkLen) using HMAC-SHA256 as the PRF, and
95  * write the output to buf.  The value dkLen must be at most 32 * (2^32 - 1).
96  */
97 void
98 PBKDF2_SHA256(const uint8_t * passwd, size_t passwdlen, const uint8_t * salt,
99     size_t saltlen, uint64_t c, uint8_t * buf, size_t dkLen)
100 {
101     HMAC_SHA256_CTX PShctx, hctx;
102     size_t i;
103     uint8_t ivec[4];
104     uint8_t U[32];
105     uint8_t T[32];
106     uint64_t j;
107     int k;
108     size_t clen;
109
110     /* Compute HMAC state after processing P and S. */
111     HMAC_SHA256_Init(&PShctx, passwd, passwdlen);
112     HMAC_SHA256_Update(&PShctx, salt, saltlen);
113
114     /* Iterate through the blocks. */
115     for (i = 0; i * 32 < dkLen; i++) {
116         /* Generate INT(i + 1). */
117         be32enc(ivec, (uint32_t)(i + 1));
118
119         /* Compute U_1 = PRF(P, S || INT(i)). */
120         memcpy(&hctx, &PShctx, sizeof(HMAC_SHA256_CTX));
121         HMAC_SHA256_Update(&hctx, ivec, 4);
122         HMAC_SHA256_Final(U, &hctx);
123
124         /* T_i = U_1 ... */
125         memcpy(T, U, 32);
126
127         for (j = 2; j <= c; j++) {
128             /* Compute U_j. */
129             HMAC_SHA256_Init(&hctx, passwd, passwdlen);
130             HMAC_SHA256_Update(&hctx, U, 32);
131             HMAC_SHA256_Final(U, &hctx);
132
133             /* ... xor U_j ... */
134             for (k = 0; k < 32; k++)
135                 T[k] ^= U[k];
136         }
137
138         /* Copy as many bytes as necessary into buf. */
139         clen = dkLen - i * 32;
140         if (clen > 32)
141             clen = 32;
142         memcpy(&buf[i * 32], T, clen);
143     }
144
145     /* Clean PShctx, since we never called _Final on it. */
146     memset(&PShctx, 0, sizeof(HMAC_SHA256_CTX));
147 }
148