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 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 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 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 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 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