Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
michael@0 | 1 | /*- |
michael@0 | 2 | * Copyright 2005,2007,2009 Colin Percival |
michael@0 | 3 | * All rights reserved. |
michael@0 | 4 | * |
michael@0 | 5 | * Redistribution and use in source and binary forms, with or without |
michael@0 | 6 | * modification, are permitted provided that the following conditions |
michael@0 | 7 | * are met: |
michael@0 | 8 | * 1. Redistributions of source code must retain the above copyright |
michael@0 | 9 | * notice, this list of conditions and the following disclaimer. |
michael@0 | 10 | * 2. Redistributions in binary form must reproduce the above copyright |
michael@0 | 11 | * notice, this list of conditions and the following disclaimer in the |
michael@0 | 12 | * documentation and/or other materials provided with the distribution. |
michael@0 | 13 | * |
michael@0 | 14 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND |
michael@0 | 15 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
michael@0 | 16 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
michael@0 | 17 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE |
michael@0 | 18 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
michael@0 | 19 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
michael@0 | 20 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
michael@0 | 21 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
michael@0 | 22 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
michael@0 | 23 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
michael@0 | 24 | * SUCH DAMAGE. |
michael@0 | 25 | */ |
michael@0 | 26 | #include <sys/types.h> |
michael@0 | 27 | |
michael@0 | 28 | #include <stdint.h> |
michael@0 | 29 | #include <string.h> |
michael@0 | 30 | |
michael@0 | 31 | #include <sys/endian.h> |
michael@0 | 32 | |
michael@0 | 33 | #include "pbkdf2_sha256.h" |
michael@0 | 34 | |
michael@0 | 35 | static inline uint32_t |
michael@0 | 36 | be32dec(const void *pp) |
michael@0 | 37 | { |
michael@0 | 38 | const uint8_t *p = (uint8_t const *)pp; |
michael@0 | 39 | |
michael@0 | 40 | return ((uint32_t)(p[3]) + |
michael@0 | 41 | ((uint32_t)(p[2]) << 8) + |
michael@0 | 42 | ((uint32_t)(p[1]) << 16) + |
michael@0 | 43 | ((uint32_t)(p[0]) << 24)); |
michael@0 | 44 | } |
michael@0 | 45 | |
michael@0 | 46 | static inline void |
michael@0 | 47 | be32enc(void *pp, uint32_t x) |
michael@0 | 48 | { |
michael@0 | 49 | uint8_t * p = (uint8_t *)pp; |
michael@0 | 50 | |
michael@0 | 51 | p[3] = x & 0xff; |
michael@0 | 52 | p[2] = (x >> 8) & 0xff; |
michael@0 | 53 | p[1] = (x >> 16) & 0xff; |
michael@0 | 54 | p[0] = (x >> 24) & 0xff; |
michael@0 | 55 | } |
michael@0 | 56 | |
michael@0 | 57 | /* |
michael@0 | 58 | * Encode a length len/4 vector of (uint32_t) into a length len vector of |
michael@0 | 59 | * (unsigned char) in big-endian form. Assumes len is a multiple of 4. |
michael@0 | 60 | */ |
michael@0 | 61 | static void |
michael@0 | 62 | be32enc_vect(unsigned char *dst, const uint32_t *src, size_t len) |
michael@0 | 63 | { |
michael@0 | 64 | size_t i; |
michael@0 | 65 | |
michael@0 | 66 | for (i = 0; i < len / 4; i++) |
michael@0 | 67 | be32enc(dst + i * 4, src[i]); |
michael@0 | 68 | } |
michael@0 | 69 | |
michael@0 | 70 | /* |
michael@0 | 71 | * Decode a big-endian length len vector of (unsigned char) into a length |
michael@0 | 72 | * len/4 vector of (uint32_t). Assumes len is a multiple of 4. |
michael@0 | 73 | */ |
michael@0 | 74 | static void |
michael@0 | 75 | be32dec_vect(uint32_t *dst, const unsigned char *src, size_t len) |
michael@0 | 76 | { |
michael@0 | 77 | size_t i; |
michael@0 | 78 | |
michael@0 | 79 | for (i = 0; i < len / 4; i++) |
michael@0 | 80 | dst[i] = be32dec(src + i * 4); |
michael@0 | 81 | } |
michael@0 | 82 | |
michael@0 | 83 | /* Elementary functions used by SHA256 */ |
michael@0 | 84 | #define Ch(x, y, z) ((x & (y ^ z)) ^ z) |
michael@0 | 85 | #define Maj(x, y, z) ((x & (y | z)) | (y & z)) |
michael@0 | 86 | #define SHR(x, n) (x >> n) |
michael@0 | 87 | #define ROTR(x, n) ((x >> n) | (x << (32 - n))) |
michael@0 | 88 | #define S0(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22)) |
michael@0 | 89 | #define S1(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25)) |
michael@0 | 90 | #define s0(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SHR(x, 3)) |
michael@0 | 91 | #define s1(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHR(x, 10)) |
michael@0 | 92 | |
michael@0 | 93 | /* SHA256 round function */ |
michael@0 | 94 | #define RND(a, b, c, d, e, f, g, h, k) \ |
michael@0 | 95 | t0 = h + S1(e) + Ch(e, f, g) + k; \ |
michael@0 | 96 | t1 = S0(a) + Maj(a, b, c); \ |
michael@0 | 97 | d += t0; \ |
michael@0 | 98 | h = t0 + t1; |
michael@0 | 99 | |
michael@0 | 100 | /* Adjusted round function for rotating state */ |
michael@0 | 101 | #define RNDr(S, W, i, k) \ |
michael@0 | 102 | RND(S[(64 - i) % 8], S[(65 - i) % 8], \ |
michael@0 | 103 | S[(66 - i) % 8], S[(67 - i) % 8], \ |
michael@0 | 104 | S[(68 - i) % 8], S[(69 - i) % 8], \ |
michael@0 | 105 | S[(70 - i) % 8], S[(71 - i) % 8], \ |
michael@0 | 106 | W[i] + k) |
michael@0 | 107 | |
michael@0 | 108 | /* |
michael@0 | 109 | * SHA256 block compression function. The 256-bit state is transformed via |
michael@0 | 110 | * the 512-bit input block to produce a new state. |
michael@0 | 111 | */ |
michael@0 | 112 | static void |
michael@0 | 113 | SHA256_Transform(uint32_t * state, const unsigned char block[64]) |
michael@0 | 114 | { |
michael@0 | 115 | uint32_t W[64]; |
michael@0 | 116 | uint32_t S[8]; |
michael@0 | 117 | uint32_t t0, t1; |
michael@0 | 118 | int i; |
michael@0 | 119 | |
michael@0 | 120 | /* 1. Prepare message schedule W. */ |
michael@0 | 121 | be32dec_vect(W, block, 64); |
michael@0 | 122 | for (i = 16; i < 64; i++) |
michael@0 | 123 | W[i] = s1(W[i - 2]) + W[i - 7] + s0(W[i - 15]) + W[i - 16]; |
michael@0 | 124 | |
michael@0 | 125 | /* 2. Initialize working variables. */ |
michael@0 | 126 | memcpy(S, state, 32); |
michael@0 | 127 | |
michael@0 | 128 | /* 3. Mix. */ |
michael@0 | 129 | RNDr(S, W, 0, 0x428a2f98); |
michael@0 | 130 | RNDr(S, W, 1, 0x71374491); |
michael@0 | 131 | RNDr(S, W, 2, 0xb5c0fbcf); |
michael@0 | 132 | RNDr(S, W, 3, 0xe9b5dba5); |
michael@0 | 133 | RNDr(S, W, 4, 0x3956c25b); |
michael@0 | 134 | RNDr(S, W, 5, 0x59f111f1); |
michael@0 | 135 | RNDr(S, W, 6, 0x923f82a4); |
michael@0 | 136 | RNDr(S, W, 7, 0xab1c5ed5); |
michael@0 | 137 | RNDr(S, W, 8, 0xd807aa98); |
michael@0 | 138 | RNDr(S, W, 9, 0x12835b01); |
michael@0 | 139 | RNDr(S, W, 10, 0x243185be); |
michael@0 | 140 | RNDr(S, W, 11, 0x550c7dc3); |
michael@0 | 141 | RNDr(S, W, 12, 0x72be5d74); |
michael@0 | 142 | RNDr(S, W, 13, 0x80deb1fe); |
michael@0 | 143 | RNDr(S, W, 14, 0x9bdc06a7); |
michael@0 | 144 | RNDr(S, W, 15, 0xc19bf174); |
michael@0 | 145 | RNDr(S, W, 16, 0xe49b69c1); |
michael@0 | 146 | RNDr(S, W, 17, 0xefbe4786); |
michael@0 | 147 | RNDr(S, W, 18, 0x0fc19dc6); |
michael@0 | 148 | RNDr(S, W, 19, 0x240ca1cc); |
michael@0 | 149 | RNDr(S, W, 20, 0x2de92c6f); |
michael@0 | 150 | RNDr(S, W, 21, 0x4a7484aa); |
michael@0 | 151 | RNDr(S, W, 22, 0x5cb0a9dc); |
michael@0 | 152 | RNDr(S, W, 23, 0x76f988da); |
michael@0 | 153 | RNDr(S, W, 24, 0x983e5152); |
michael@0 | 154 | RNDr(S, W, 25, 0xa831c66d); |
michael@0 | 155 | RNDr(S, W, 26, 0xb00327c8); |
michael@0 | 156 | RNDr(S, W, 27, 0xbf597fc7); |
michael@0 | 157 | RNDr(S, W, 28, 0xc6e00bf3); |
michael@0 | 158 | RNDr(S, W, 29, 0xd5a79147); |
michael@0 | 159 | RNDr(S, W, 30, 0x06ca6351); |
michael@0 | 160 | RNDr(S, W, 31, 0x14292967); |
michael@0 | 161 | RNDr(S, W, 32, 0x27b70a85); |
michael@0 | 162 | RNDr(S, W, 33, 0x2e1b2138); |
michael@0 | 163 | RNDr(S, W, 34, 0x4d2c6dfc); |
michael@0 | 164 | RNDr(S, W, 35, 0x53380d13); |
michael@0 | 165 | RNDr(S, W, 36, 0x650a7354); |
michael@0 | 166 | RNDr(S, W, 37, 0x766a0abb); |
michael@0 | 167 | RNDr(S, W, 38, 0x81c2c92e); |
michael@0 | 168 | RNDr(S, W, 39, 0x92722c85); |
michael@0 | 169 | RNDr(S, W, 40, 0xa2bfe8a1); |
michael@0 | 170 | RNDr(S, W, 41, 0xa81a664b); |
michael@0 | 171 | RNDr(S, W, 42, 0xc24b8b70); |
michael@0 | 172 | RNDr(S, W, 43, 0xc76c51a3); |
michael@0 | 173 | RNDr(S, W, 44, 0xd192e819); |
michael@0 | 174 | RNDr(S, W, 45, 0xd6990624); |
michael@0 | 175 | RNDr(S, W, 46, 0xf40e3585); |
michael@0 | 176 | RNDr(S, W, 47, 0x106aa070); |
michael@0 | 177 | RNDr(S, W, 48, 0x19a4c116); |
michael@0 | 178 | RNDr(S, W, 49, 0x1e376c08); |
michael@0 | 179 | RNDr(S, W, 50, 0x2748774c); |
michael@0 | 180 | RNDr(S, W, 51, 0x34b0bcb5); |
michael@0 | 181 | RNDr(S, W, 52, 0x391c0cb3); |
michael@0 | 182 | RNDr(S, W, 53, 0x4ed8aa4a); |
michael@0 | 183 | RNDr(S, W, 54, 0x5b9cca4f); |
michael@0 | 184 | RNDr(S, W, 55, 0x682e6ff3); |
michael@0 | 185 | RNDr(S, W, 56, 0x748f82ee); |
michael@0 | 186 | RNDr(S, W, 57, 0x78a5636f); |
michael@0 | 187 | RNDr(S, W, 58, 0x84c87814); |
michael@0 | 188 | RNDr(S, W, 59, 0x8cc70208); |
michael@0 | 189 | RNDr(S, W, 60, 0x90befffa); |
michael@0 | 190 | RNDr(S, W, 61, 0xa4506ceb); |
michael@0 | 191 | RNDr(S, W, 62, 0xbef9a3f7); |
michael@0 | 192 | RNDr(S, W, 63, 0xc67178f2); |
michael@0 | 193 | |
michael@0 | 194 | /* 4. Mix local working variables into global state. */ |
michael@0 | 195 | for (i = 0; i < 8; i++) |
michael@0 | 196 | state[i] += S[i]; |
michael@0 | 197 | |
michael@0 | 198 | /* Clean the stack. */ |
michael@0 | 199 | memset(W, 0, 256); |
michael@0 | 200 | memset(S, 0, 32); |
michael@0 | 201 | t0 = t1 = 0; |
michael@0 | 202 | } |
michael@0 | 203 | |
michael@0 | 204 | static unsigned char PAD[64] = { |
michael@0 | 205 | 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
michael@0 | 206 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
michael@0 | 207 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
michael@0 | 208 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 |
michael@0 | 209 | }; |
michael@0 | 210 | |
michael@0 | 211 | /* Add padding and terminating bit-count. */ |
michael@0 | 212 | static void |
michael@0 | 213 | SHA256_Pad(SHA256_CTX * ctx) |
michael@0 | 214 | { |
michael@0 | 215 | unsigned char len[8]; |
michael@0 | 216 | uint32_t r, plen; |
michael@0 | 217 | |
michael@0 | 218 | /* |
michael@0 | 219 | * Convert length to a vector of bytes -- we do this now rather |
michael@0 | 220 | * than later because the length will change after we pad. |
michael@0 | 221 | */ |
michael@0 | 222 | be32enc_vect(len, ctx->count, 8); |
michael@0 | 223 | |
michael@0 | 224 | /* Add 1--64 bytes so that the resulting length is 56 mod 64. */ |
michael@0 | 225 | r = (ctx->count[1] >> 3) & 0x3f; |
michael@0 | 226 | plen = (r < 56) ? (56 - r) : (120 - r); |
michael@0 | 227 | SHA256_Update(ctx, PAD, (size_t)plen); |
michael@0 | 228 | |
michael@0 | 229 | /* Add the terminating bit-count. */ |
michael@0 | 230 | SHA256_Update(ctx, len, 8); |
michael@0 | 231 | } |
michael@0 | 232 | |
michael@0 | 233 | /* SHA-256 initialization. Begins a SHA-256 operation. */ |
michael@0 | 234 | void |
michael@0 | 235 | SHA256_Init(SHA256_CTX * ctx) |
michael@0 | 236 | { |
michael@0 | 237 | |
michael@0 | 238 | /* Zero bits processed so far. */ |
michael@0 | 239 | ctx->count[0] = ctx->count[1] = 0; |
michael@0 | 240 | |
michael@0 | 241 | /* Magic initialization constants. */ |
michael@0 | 242 | ctx->state[0] = 0x6A09E667; |
michael@0 | 243 | ctx->state[1] = 0xBB67AE85; |
michael@0 | 244 | ctx->state[2] = 0x3C6EF372; |
michael@0 | 245 | ctx->state[3] = 0xA54FF53A; |
michael@0 | 246 | ctx->state[4] = 0x510E527F; |
michael@0 | 247 | ctx->state[5] = 0x9B05688C; |
michael@0 | 248 | ctx->state[6] = 0x1F83D9AB; |
michael@0 | 249 | ctx->state[7] = 0x5BE0CD19; |
michael@0 | 250 | } |
michael@0 | 251 | |
michael@0 | 252 | /* Add bytes into the hash. */ |
michael@0 | 253 | void |
michael@0 | 254 | SHA256_Update(SHA256_CTX * ctx, const void *in, size_t len) |
michael@0 | 255 | { |
michael@0 | 256 | uint32_t bitlen[2]; |
michael@0 | 257 | uint32_t r; |
michael@0 | 258 | const unsigned char *src = in; |
michael@0 | 259 | |
michael@0 | 260 | /* Number of bytes left in the buffer from previous updates. */ |
michael@0 | 261 | r = (ctx->count[1] >> 3) & 0x3f; |
michael@0 | 262 | |
michael@0 | 263 | /* Convert the length into a number of bits. */ |
michael@0 | 264 | bitlen[1] = ((uint32_t)len) << 3; |
michael@0 | 265 | bitlen[0] = (uint32_t)(len >> 29); |
michael@0 | 266 | |
michael@0 | 267 | /* Update number of bits. */ |
michael@0 | 268 | if ((ctx->count[1] += bitlen[1]) < bitlen[1]) |
michael@0 | 269 | ctx->count[0]++; |
michael@0 | 270 | ctx->count[0] += bitlen[0]; |
michael@0 | 271 | |
michael@0 | 272 | /* Handle the case where we don't need to perform any transforms. */ |
michael@0 | 273 | if (len < 64 - r) { |
michael@0 | 274 | memcpy(&ctx->buf[r], src, len); |
michael@0 | 275 | return; |
michael@0 | 276 | } |
michael@0 | 277 | |
michael@0 | 278 | /* Finish the current block. */ |
michael@0 | 279 | memcpy(&ctx->buf[r], src, 64 - r); |
michael@0 | 280 | SHA256_Transform(ctx->state, ctx->buf); |
michael@0 | 281 | src += 64 - r; |
michael@0 | 282 | len -= 64 - r; |
michael@0 | 283 | |
michael@0 | 284 | /* Perform complete blocks. */ |
michael@0 | 285 | while (len >= 64) { |
michael@0 | 286 | SHA256_Transform(ctx->state, src); |
michael@0 | 287 | src += 64; |
michael@0 | 288 | len -= 64; |
michael@0 | 289 | } |
michael@0 | 290 | |
michael@0 | 291 | /* Copy left over data into buffer. */ |
michael@0 | 292 | memcpy(ctx->buf, src, len); |
michael@0 | 293 | } |
michael@0 | 294 | |
michael@0 | 295 | /* |
michael@0 | 296 | * SHA-256 finalization. Pads the input data, exports the hash value, |
michael@0 | 297 | * and clears the context state. |
michael@0 | 298 | */ |
michael@0 | 299 | void |
michael@0 | 300 | SHA256_Final(unsigned char digest[32], SHA256_CTX * ctx) |
michael@0 | 301 | { |
michael@0 | 302 | |
michael@0 | 303 | /* Add padding. */ |
michael@0 | 304 | SHA256_Pad(ctx); |
michael@0 | 305 | |
michael@0 | 306 | /* Write the hash. */ |
michael@0 | 307 | be32enc_vect(digest, ctx->state, 32); |
michael@0 | 308 | |
michael@0 | 309 | /* Clear the context state. */ |
michael@0 | 310 | memset((void *)ctx, 0, sizeof(*ctx)); |
michael@0 | 311 | } |
michael@0 | 312 | |
michael@0 | 313 | /* Initialize an HMAC-SHA256 operation with the given key. */ |
michael@0 | 314 | void |
michael@0 | 315 | HMAC_SHA256_Init(HMAC_SHA256_CTX * ctx, const void * _K, size_t Klen) |
michael@0 | 316 | { |
michael@0 | 317 | unsigned char pad[64]; |
michael@0 | 318 | unsigned char khash[32]; |
michael@0 | 319 | const unsigned char * K = _K; |
michael@0 | 320 | size_t i; |
michael@0 | 321 | |
michael@0 | 322 | /* If Klen > 64, the key is really SHA256(K). */ |
michael@0 | 323 | if (Klen > 64) { |
michael@0 | 324 | SHA256_Init(&ctx->ictx); |
michael@0 | 325 | SHA256_Update(&ctx->ictx, K, Klen); |
michael@0 | 326 | SHA256_Final(khash, &ctx->ictx); |
michael@0 | 327 | K = khash; |
michael@0 | 328 | Klen = 32; |
michael@0 | 329 | } |
michael@0 | 330 | |
michael@0 | 331 | /* Inner SHA256 operation is SHA256(K xor [block of 0x36] || data). */ |
michael@0 | 332 | SHA256_Init(&ctx->ictx); |
michael@0 | 333 | memset(pad, 0x36, 64); |
michael@0 | 334 | for (i = 0; i < Klen; i++) |
michael@0 | 335 | pad[i] ^= K[i]; |
michael@0 | 336 | SHA256_Update(&ctx->ictx, pad, 64); |
michael@0 | 337 | |
michael@0 | 338 | /* Outer SHA256 operation is SHA256(K xor [block of 0x5c] || hash). */ |
michael@0 | 339 | SHA256_Init(&ctx->octx); |
michael@0 | 340 | memset(pad, 0x5c, 64); |
michael@0 | 341 | for (i = 0; i < Klen; i++) |
michael@0 | 342 | pad[i] ^= K[i]; |
michael@0 | 343 | SHA256_Update(&ctx->octx, pad, 64); |
michael@0 | 344 | |
michael@0 | 345 | /* Clean the stack. */ |
michael@0 | 346 | memset(khash, 0, 32); |
michael@0 | 347 | } |
michael@0 | 348 | |
michael@0 | 349 | /* Add bytes to the HMAC-SHA256 operation. */ |
michael@0 | 350 | void |
michael@0 | 351 | HMAC_SHA256_Update(HMAC_SHA256_CTX * ctx, const void *in, size_t len) |
michael@0 | 352 | { |
michael@0 | 353 | |
michael@0 | 354 | /* Feed data to the inner SHA256 operation. */ |
michael@0 | 355 | SHA256_Update(&ctx->ictx, in, len); |
michael@0 | 356 | } |
michael@0 | 357 | |
michael@0 | 358 | /* Finish an HMAC-SHA256 operation. */ |
michael@0 | 359 | void |
michael@0 | 360 | HMAC_SHA256_Final(unsigned char digest[32], HMAC_SHA256_CTX * ctx) |
michael@0 | 361 | { |
michael@0 | 362 | unsigned char ihash[32]; |
michael@0 | 363 | |
michael@0 | 364 | /* Finish the inner SHA256 operation. */ |
michael@0 | 365 | SHA256_Final(ihash, &ctx->ictx); |
michael@0 | 366 | |
michael@0 | 367 | /* Feed the inner hash to the outer SHA256 operation. */ |
michael@0 | 368 | SHA256_Update(&ctx->octx, ihash, 32); |
michael@0 | 369 | |
michael@0 | 370 | /* Finish the outer SHA256 operation. */ |
michael@0 | 371 | SHA256_Final(digest, &ctx->octx); |
michael@0 | 372 | |
michael@0 | 373 | /* Clean the stack. */ |
michael@0 | 374 | memset(ihash, 0, 32); |
michael@0 | 375 | } |
michael@0 | 376 | |
michael@0 | 377 | /** |
michael@0 | 378 | * PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, c, buf, dkLen): |
michael@0 | 379 | * Compute PBKDF2(passwd, salt, c, dkLen) using HMAC-SHA256 as the PRF, and |
michael@0 | 380 | * write the output to buf. The value dkLen must be at most 32 * (2^32 - 1). |
michael@0 | 381 | */ |
michael@0 | 382 | void |
michael@0 | 383 | PBKDF2_SHA256(const uint8_t * passwd, size_t passwdlen, const uint8_t * salt, |
michael@0 | 384 | size_t saltlen, uint64_t c, uint8_t * buf, size_t dkLen) |
michael@0 | 385 | { |
michael@0 | 386 | HMAC_SHA256_CTX PShctx, hctx; |
michael@0 | 387 | size_t i; |
michael@0 | 388 | uint8_t ivec[4]; |
michael@0 | 389 | uint8_t U[32]; |
michael@0 | 390 | uint8_t T[32]; |
michael@0 | 391 | uint64_t j; |
michael@0 | 392 | int k; |
michael@0 | 393 | size_t clen; |
michael@0 | 394 | |
michael@0 | 395 | /* Compute HMAC state after processing P and S. */ |
michael@0 | 396 | HMAC_SHA256_Init(&PShctx, passwd, passwdlen); |
michael@0 | 397 | HMAC_SHA256_Update(&PShctx, salt, saltlen); |
michael@0 | 398 | |
michael@0 | 399 | /* Iterate through the blocks. */ |
michael@0 | 400 | for (i = 0; i * 32 < dkLen; i++) { |
michael@0 | 401 | /* Generate INT(i + 1). */ |
michael@0 | 402 | be32enc(ivec, (uint32_t)(i + 1)); |
michael@0 | 403 | |
michael@0 | 404 | /* Compute U_1 = PRF(P, S || INT(i)). */ |
michael@0 | 405 | memcpy(&hctx, &PShctx, sizeof(HMAC_SHA256_CTX)); |
michael@0 | 406 | HMAC_SHA256_Update(&hctx, ivec, 4); |
michael@0 | 407 | HMAC_SHA256_Final(U, &hctx); |
michael@0 | 408 | |
michael@0 | 409 | /* T_i = U_1 ... */ |
michael@0 | 410 | memcpy(T, U, 32); |
michael@0 | 411 | |
michael@0 | 412 | for (j = 2; j <= c; j++) { |
michael@0 | 413 | /* Compute U_j. */ |
michael@0 | 414 | HMAC_SHA256_Init(&hctx, passwd, passwdlen); |
michael@0 | 415 | HMAC_SHA256_Update(&hctx, U, 32); |
michael@0 | 416 | HMAC_SHA256_Final(U, &hctx); |
michael@0 | 417 | |
michael@0 | 418 | /* ... xor U_j ... */ |
michael@0 | 419 | for (k = 0; k < 32; k++) |
michael@0 | 420 | T[k] ^= U[k]; |
michael@0 | 421 | } |
michael@0 | 422 | |
michael@0 | 423 | /* Copy as many bytes as necessary into buf. */ |
michael@0 | 424 | clen = dkLen - i * 32; |
michael@0 | 425 | if (clen > 32) |
michael@0 | 426 | clen = 32; |
michael@0 | 427 | memcpy(&buf[i * 32], T, clen); |
michael@0 | 428 | } |
michael@0 | 429 | |
michael@0 | 430 | /* Clean PShctx, since we never called _Final on it. */ |
michael@0 | 431 | memset(&PShctx, 0, sizeof(HMAC_SHA256_CTX)); |
michael@0 | 432 | } |