1 /* This file is distributed under the following terms:
2
3 * Copyright 2005-2014 Colin Percival. All rights reserved.
4 * Copyright 2014 Sean Kelly. All rights reserved.
5
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 */
27
28 #include <assert.h>
29 #include <stdint.h>
30 #include <string.h>
31 #include <ByteOrder.h>
32
33 #include "pbkdf2.h"
34
35 /* Function which does the zeroing. */
36 static void
insecure_memzero_func(volatile void * buf,size_t len)37 insecure_memzero_func(volatile void * buf, size_t len)
38 {
39 volatile uint8_t * _buf = (volatile uint8_t *)buf;
40 size_t i;
41
42 for (i = 0; i < len; i++)
43 _buf[i] = 0;
44 }
45
46 /* Pointer to memory-zeroing function. */
47 void (* volatile insecure_memzero_ptr)(volatile void *, size_t) =
48 insecure_memzero_func;
49
50 /**
51 * HMAC_SHA256_Init(ctx, K, Klen):
52 * Initialize the HMAC-SHA256 context ${ctx} with ${Klen} bytes of key from
53 * ${K}.
54 */
55 void
HMAC_SHA256_Init(HMAC_SHA256_CTX * ctx,const void * _K,size_t Klen)56 HMAC_SHA256_Init(HMAC_SHA256_CTX * ctx, const void * _K, size_t Klen)
57 {
58 uint8_t pad[64];
59 uint8_t khash[32];
60 const uint8_t * K = (const uint8_t *)_K;
61 size_t i;
62
63 /* If Klen > 64, the key is really SHA256(K). */
64 if (Klen > 64) {
65 ctx->ictx.Init();
66 ctx->ictx.Update(K, Klen);
67 memcpy(khash, ctx->ictx.Digest(), 32);
68 K = khash;
69 Klen = 32;
70 }
71
72 /* Inner SHA256 operation is SHA256(K xor [block of 0x36] || data). */
73 ctx->ictx.Init();
74 memset(pad, 0x36, 64);
75 for (i = 0; i < Klen; i++)
76 pad[i] ^= K[i];
77 ctx->ictx.Update(pad, 64);
78
79 /* Outer SHA256 operation is SHA256(K xor [block of 0x5c] || hash). */
80 ctx->octx.Init();
81 memset(pad, 0x5c, 64);
82 for (i = 0; i < Klen; i++)
83 pad[i] ^= K[i];
84 ctx->octx.Update(pad, 64);
85
86 /* Clean the stack. */
87 insecure_memzero(khash, 32);
88 insecure_memzero(pad, 64);
89 }
90
91 /**
92 * HMAC_SHA256_Update(ctx, in, len):
93 * Input ${len} bytes from ${in} into the HMAC-SHA256 context ${ctx}.
94 */
95 void
HMAC_SHA256_Update(HMAC_SHA256_CTX * ctx,const void * in,size_t len)96 HMAC_SHA256_Update(HMAC_SHA256_CTX * ctx, const void * in, size_t len)
97 {
98
99 /* Feed data to the inner SHA256 operation. */
100 ctx->ictx.Update(in, len);
101 }
102
103 /**
104 * HMAC_SHA256_Final(digest, ctx):
105 * Output the HMAC-SHA256 of the data input to the context ${ctx} into the
106 * buffer ${digest}.
107 */
108 void
HMAC_SHA256_Final(uint8_t digest[32],HMAC_SHA256_CTX * ctx)109 HMAC_SHA256_Final(uint8_t digest[32], HMAC_SHA256_CTX * ctx)
110 {
111 uint8_t ihash[32];
112
113 /* Finish the inner SHA256 operation. */
114 memcpy(ihash, ctx->ictx.Digest(), 32);
115
116 /* Feed the inner hash to the outer SHA256 operation. */
117 ctx->octx.Update(ihash, 32);
118
119 /* Finish the outer SHA256 operation. */
120 memcpy(digest, ctx->octx.Digest(), 32);
121
122 /* Clean the stack. */
123 insecure_memzero(ihash, 32);
124 }
125
126 /**
127 * PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, c, buf, dkLen):
128 * Compute PBKDF2(passwd, salt, c, dkLen) using HMAC-SHA256 as the PRF, and
129 * write the output to buf. The value dkLen must be at most 32 * (2^32 - 1).
130 */
131 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)132 PBKDF2_SHA256(const uint8_t * passwd, size_t passwdlen, const uint8_t * salt,
133 size_t saltlen, uint64_t c, uint8_t * buf, size_t dkLen)
134 {
135 HMAC_SHA256_CTX PShctx, hctx;
136 size_t i;
137 uint32_t ivec;
138 uint8_t U[32];
139 uint8_t T[32];
140 uint64_t j;
141 int k;
142 size_t clen;
143
144 /* Sanity-check. */
145 assert(dkLen <= 32 * (size_t)(UINT32_MAX));
146
147 /* Compute HMAC state after processing P and S. */
148 HMAC_SHA256_Init(&PShctx, passwd, passwdlen);
149 HMAC_SHA256_Update(&PShctx, salt, saltlen);
150
151 /* Iterate through the blocks. */
152 for (i = 0; i * 32 < dkLen; i++) {
153 /* Generate INT(i + 1). */
154 ivec = B_HOST_TO_BENDIAN_INT32((uint32_t)(i + 1));
155
156 /* Compute U_1 = PRF(P, S || INT(i)). */
157 memcpy(&hctx, &PShctx, sizeof(HMAC_SHA256_CTX));
158 HMAC_SHA256_Update(&hctx, &ivec, 4);
159 HMAC_SHA256_Final(U, &hctx);
160
161 /* T_i = U_1 ... */
162 memcpy(T, U, 32);
163
164 for (j = 2; j <= c; j++) {
165 /* Compute U_j. */
166 HMAC_SHA256_Init(&hctx, passwd, passwdlen);
167 HMAC_SHA256_Update(&hctx, U, 32);
168 HMAC_SHA256_Final(U, &hctx);
169
170 /* ... xor U_j ... */
171 for (k = 0; k < 32; k++)
172 T[k] ^= U[k];
173 }
174
175 /* Copy as many bytes as necessary into buf. */
176 clen = dkLen - i * 32;
177 if (clen > 32)
178 clen = 32;
179 memcpy(&buf[i * 32], T, clen);
180 }
181
182 /* Clean PShctx, since we never called _Final on it. */
183 insecure_memzero(&PShctx, sizeof(HMAC_SHA256_CTX));
184 }
185