int get_random(uint8_t *buffer, size_t len){ int i; uint8_t shabuf[SHA256_DIGEST_LEN]; HMAC_SHA256_CTX ctx; size_t left; for (i=0, left=len; left > 0 ; ++i){ HMAC_SHA256_Init(&ctx, entropy_pool, 32); HMAC_SHA256_Update(&ctx, "generate", 8); HMAC_SHA256_Final(shabuf, &ctx); HMAC_SHA256_Init(&ctx, entropy_pool, 32); HMAC_SHA256_Update(&ctx, "reseed", 6); HMAC_SHA256_Final(entropy_pool, &ctx); memcpy(buffer + i*SHA256_DIGEST_LEN, shabuf, left > SHA256_DIGEST_LEN ? SHA256_DIGEST_LEN: left); if (left > SHA256_DIGEST_LEN) left -= SHA256_DIGEST_LEN; else left = 0; } ZERO(shabuf); ZERO(ctx); return len; }
/** * proto_crypt_enc(ibuf, len, obuf, k): * Encrypt ${len} bytes from ${ibuf} into PCRYPT_ESZ bytes using the keys in * ${k}, and write the result into ${obuf}. */ void proto_crypt_enc(uint8_t * ibuf, size_t len, uint8_t obuf[PCRYPT_ESZ], struct proto_keys * k) { HMAC_SHA256_CTX ctx; uint8_t pnum_exp[8]; /* Sanity-check the length. */ assert(len <= PCRYPT_MAXDSZ); /* Copy the decrypted data into the encrypted buffer. */ memcpy(obuf, ibuf, len); /* Pad up to PCRYPT_MAXDSZ with zeroes. */ memset(&obuf[len], 0, PCRYPT_MAXDSZ - len); /* Add the length. */ be32enc(&obuf[PCRYPT_MAXDSZ], len); /* Encrypt the buffer in-place. */ crypto_aesctr_buf(k->k_aes, k->pnum, obuf, obuf, PCRYPT_MAXDSZ + 4); /* Append an HMAC. */ be64enc(pnum_exp, k->pnum); HMAC_SHA256_Init(&ctx, k->k_hmac, 32); HMAC_SHA256_Update(&ctx, obuf, PCRYPT_MAXDSZ + 4); HMAC_SHA256_Update(&ctx, pnum_exp, 8); HMAC_SHA256_Final(&obuf[PCRYPT_MAXDSZ + 4], &ctx); /* Increment packet number. */ k->pnum += 1; }
/** * PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, c, buf, dkLen): * Compute PBKDF2(passwd, salt, c, dkLen) using HMAC-SHA256 as the PRF, and * write the output to buf. The value dkLen must be at most 32 * (2^32 - 1). */ 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)); }
/** * crypto_hash_data_key_2(key, keylen, data0, len0, data1, len1, buf): * Hash the concatenation of two buffers with the provided HMAC-SHA256 key. */ void crypto_hash_data_key_2(const uint8_t * key, size_t keylen, const uint8_t * data0, size_t len0, const uint8_t * data1, size_t len1, uint8_t buf[32]) { HMAC_SHA256_CTX hctx; /* Do the hashing. */ HMAC_SHA256_Init(&hctx, key, keylen); HMAC_SHA256_Update(&hctx, data0, len0); HMAC_SHA256_Update(&hctx, data1, len1); HMAC_SHA256_Final(buf, &hctx); /* Clean the stack. */ memset(&hctx, 0, sizeof(HMAC_SHA256_CTX)); }
/** * scryptdec_buf(inbuf, inbuflen, outbuf, outlen, passwd, passwdlen, * maxmem, maxmemfrac, maxtime): * Decrypt inbuflen bytes from inbuf, writing the result into outbuf and the * decrypted data length to outlen. The allocated length of outbuf must * be at least inbuflen. */ int scryptdec_buf(const uint8_t * inbuf, size_t inbuflen, uint8_t * outbuf, size_t * outlen, const uint8_t * passwd, size_t passwdlen, size_t maxmem, double maxmemfrac, double maxtime) { uint8_t hbuf[32]; uint8_t dk[64]; uint8_t * key_enc = dk; uint8_t * key_hmac = &dk[32]; int rc; HMAC_SHA256_CTX hctx; struct crypto_aes_key * key_enc_exp; struct crypto_aesctr * AES; /* * All versions of the scrypt format will start with "scrypt" and * have at least 7 bytes of header. */ if ((inbuflen < 7) || (memcmp(inbuf, "scrypt", 6) != 0)) return (7); /* Check the format. */ if (inbuf[6] != 0) return (8); /* We must have at least 128 bytes. */ if (inbuflen < 128) return (7); /* Parse the header and generate derived keys. */ if ((rc = scryptdec_setup(inbuf, dk, passwd, passwdlen, maxmem, maxmemfrac, maxtime)) != 0) return (rc); /* Decrypt data. */ if ((key_enc_exp = crypto_aes_key_expand(key_enc, 32)) == NULL) return (5); if ((AES = crypto_aesctr_init(key_enc_exp, 0)) == NULL) return (6); crypto_aesctr_stream(AES, &inbuf[96], outbuf, inbuflen - 128); crypto_aesctr_free(AES); crypto_aes_key_free(key_enc_exp); *outlen = inbuflen - 128; /* Verify signature. */ HMAC_SHA256_Init(&hctx, key_hmac, 32); HMAC_SHA256_Update(&hctx, inbuf, inbuflen - 32); HMAC_SHA256_Final(hbuf, &hctx); if (memcmp(hbuf, &inbuf[inbuflen - 32], 32)) return (7); /* Zero sensitive data. */ insecure_memzero(dk, 64); /* Success! */ return (0); }
static int scryptenc_setup(uint8_t header[96], uint8_t dk[64], const uint8_t * passwd, size_t passwdlen, size_t maxmem, double maxmemfrac, double maxtime) { uint8_t salt[32]; uint8_t hbuf[32]; int logN; uint64_t N; uint32_t r; uint32_t p; SHA256_CTX ctx; uint8_t * key_hmac = &dk[32]; HMAC_SHA256_CTX hctx; int rc; /* Pick values for N, r, p. */ if ((rc = pickparams(maxmem, maxmemfrac, maxtime, &logN, &r, &p)) != 0) return (rc); N = (uint64_t)(1) << logN; /* Get some salt. */ if (crypto_entropy_read(salt, 32)) return (4); /* Generate the derived keys. */ if (crypto_scrypt(passwd, passwdlen, salt, 32, N, r, p, dk, 64)) return (3); /* Construct the file header. */ memcpy(header, "scrypt", 6); header[6] = 0; header[7] = logN; be32enc(&header[8], r); be32enc(&header[12], p); memcpy(&header[16], salt, 32); /* Add header checksum. */ SHA256_Init(&ctx); SHA256_Update(&ctx, header, 48); SHA256_Final(hbuf, &ctx); memcpy(&header[48], hbuf, 16); /* Add header signature (used for verifying password). */ HMAC_SHA256_Init(&hctx, key_hmac, 32); HMAC_SHA256_Update(&hctx, header, 64); HMAC_SHA256_Final(hbuf, &hctx); memcpy(&header[64], hbuf, 32); /* Success! */ return (0); }
static int scryptdec_setup(const uint8_t header[96], uint8_t dk[64], const uint8_t * passwd, size_t passwdlen, size_t maxmem, double maxmemfrac, double maxtime, int verbose) { uint8_t salt[32]; uint8_t hbuf[32]; int logN; uint32_t r; uint32_t p; uint64_t N; SHA256_CTX ctx; uint8_t * key_hmac = &dk[32]; HMAC_SHA256_CTX hctx; int rc; /* Parse N, r, p, salt. */ logN = header[7]; r = be32dec(&header[8]); p = be32dec(&header[12]); memcpy(salt, &header[16], 32); /* Verify header checksum. */ SHA256_Init(&ctx); SHA256_Update(&ctx, header, 48); SHA256_Final(hbuf, &ctx); if (memcmp(&header[48], hbuf, 16)) return (7); /* * Check whether the provided parameters are valid and whether the * key derivation function can be computed within the allowed memory * and CPU time. */ if ((rc = checkparams(maxmem, maxmemfrac, maxtime, logN, r, p, verbose)) != 0) return (rc); /* Compute the derived keys. */ N = (uint64_t)(1) << logN; if (crypto_scrypt(passwd, passwdlen, salt, 32, N, r, p, dk, 64)) return (3); /* Check header signature (i.e., verify password). */ HMAC_SHA256_Init(&hctx, key_hmac, 32); HMAC_SHA256_Update(&hctx, header, 64); HMAC_SHA256_Final(hbuf, &hctx); if (memcmp(hbuf, &header[64], 32)) return (11); /* Success! */ return (0); }
bool hkdf_expand(const uint8_t *key, size_t key_len, const uint8_t *info, size_t info_len, uint8_t *out, size_t out_len) { uint8_t previous[HASH_LEN]; uint8_t previous_len = 0; HMAC_SHA256_CTX ctx; // The RFC states that the counter has only one byte, so we can’t produce // more output than this (which is already too much for any real // application). if (out_len > HASH_LEN * 255) { errno = EOVERFLOW; return false; } for (uint8_t i = 1;; ++i) { HMAC_SHA256_Init(&ctx, key, key_len); HMAC_SHA256_Update(&ctx, previous, previous_len); HMAC_SHA256_Update(&ctx, info, info_len); HMAC_SHA256_Update(&ctx, &i, 1); HMAC_SHA256_Final(previous, &ctx); if (previous_len == 0) previous_len = HASH_LEN; if (out_len <= HASH_LEN) { // Copies the last bytes to |out| and we’re done. memcpy(out, previous, out_len); break; } else { // Copies the HMAC() output to |out| and prepares for the next // round. memcpy(out, previous, HASH_LEN); out += HASH_LEN; out_len -= HASH_LEN; } } return true; }
/** * crypto_hash_data_2(key, data0, len0, data1, len1, buf): * Hash the concatenation of two buffers, as in crypto_hash_data. */ int crypto_hash_data_2(int key, const uint8_t * data0, size_t len0, const uint8_t * data1, size_t len1, uint8_t buf[32]) { HMAC_SHA256_CTX hctx; SHA256_CTX ctx; struct crypto_hmac_key * hkey; if (key == CRYPTO_KEY_HMAC_SHA256) { /* Hash the data. */ SHA256_Init(&ctx); SHA256_Update(&ctx, data0, len0); SHA256_Update(&ctx, data1, len1); SHA256_Final(buf, &ctx); /* Clean the stack. */ memset(&ctx, 0, sizeof(SHA256_CTX)); } else { if ((hkey = crypto_keys_lookup_HMAC(key)) == NULL) goto err0; /* Do the HMAC. */ HMAC_SHA256_Init(&hctx, hkey->key, hkey->len); HMAC_SHA256_Update(&hctx, data0, len0); HMAC_SHA256_Update(&hctx, data1, len1); HMAC_SHA256_Final(buf, &hctx); /* Clean the stack. */ memset(&hctx, 0, sizeof(HMAC_SHA256_CTX)); } /* Success! */ return (0); err0: /* Failure! */ return (-1); }
/** * proto_crypt_dec(ibuf, obuf, k): * Decrypt PCRYPT_ESZ bytes from ${ibuf} using the keys in ${k}. If the data * is valid, write it into ${obuf} and return the length; otherwise, return * -1. */ ssize_t proto_crypt_dec(uint8_t ibuf[PCRYPT_ESZ], uint8_t * obuf, struct proto_keys * k) { HMAC_SHA256_CTX ctx; uint8_t hbuf[32]; uint8_t pnum_exp[8]; size_t len; /* Verify HMAC. */ be64enc(pnum_exp, k->pnum); HMAC_SHA256_Init(&ctx, k->k_hmac, 32); HMAC_SHA256_Update(&ctx, ibuf, PCRYPT_MAXDSZ + 4); HMAC_SHA256_Update(&ctx, pnum_exp, 8); HMAC_SHA256_Final(hbuf, &ctx); if (crypto_verify_bytes(hbuf, &ibuf[PCRYPT_MAXDSZ + 4], 32)) return (-1); /* Decrypt the buffer in-place. */ crypto_aesctr_buf(k->k_aes, k->pnum, ibuf, ibuf, PCRYPT_MAXDSZ + 4); /* Increment packet number. */ k->pnum += 1; /* Parse length. */ len = be32dec(&ibuf[PCRYPT_MAXDSZ]); /* Make sure nobody is being evil here... */ if ((len == 0) || (len > PCRYPT_MAXDSZ)) return (-1); /* Copy the bytes into the output buffer. */ memcpy(obuf, ibuf, len); /* Return the decrypted length. */ return (len); }
/** * scryptenc_buf(inbuf, inbuflen, outbuf, passwd, passwdlen, * maxmem, maxmemfrac, maxtime): * Encrypt inbuflen bytes from inbuf, writing the resulting inbuflen + 128 * bytes to outbuf. */ int scryptenc_buf(const uint8_t * inbuf, size_t inbuflen, uint8_t * outbuf, const uint8_t * passwd, size_t passwdlen, size_t maxmem, double maxmemfrac, double maxtime) { uint8_t dk[64]; uint8_t hbuf[32]; uint8_t header[96]; uint8_t * key_enc = dk; uint8_t * key_hmac = &dk[32]; int rc; HMAC_SHA256_CTX hctx; struct crypto_aes_key * key_enc_exp; struct crypto_aesctr * AES; /* Generate the header and derived key. */ if ((rc = scryptenc_setup(header, dk, passwd, passwdlen, maxmem, maxmemfrac, maxtime)) != 0) return (rc); /* Copy header into output buffer. */ memcpy(outbuf, header, 96); /* Encrypt data. */ if ((key_enc_exp = crypto_aes_key_expand(key_enc, 32)) == NULL) return (5); if ((AES = crypto_aesctr_init(key_enc_exp, 0)) == NULL) return (6); crypto_aesctr_stream(AES, inbuf, &outbuf[96], inbuflen); crypto_aesctr_free(AES); crypto_aes_key_free(key_enc_exp); /* Add signature. */ HMAC_SHA256_Init(&hctx, key_hmac, 32); HMAC_SHA256_Update(&hctx, outbuf, 96 + inbuflen); HMAC_SHA256_Final(hbuf, &hctx); memcpy(&outbuf[96 + inbuflen], hbuf, 32); /* Zero sensitive data. */ insecure_memzero(dk, 64); /* Success! */ return (0); }
bool hkdf(const uint8_t *salt, size_t salt_len, const uint8_t *key, size_t key_len, const uint8_t *info, size_t info_len, uint8_t *out, size_t out_len) { uint8_t prk[HASH_LEN]; HMAC_SHA256_CTX ctx; // Performs the extract phase. Notice that |salt| is used as the key and // |key| as the message. HMAC_SHA256_Init(&ctx, salt, salt_len); HMAC_SHA256_Update(&ctx, key, key_len); HMAC_SHA256_Final(prk, &ctx); // Performs the expand phase. if (!hkdf_expand(prk, HASH_LEN, info, info_len, out, out_len)) return false; explicit_bzero(prk, HASH_LEN); return true; }
// // Verifies password hash (also ensures hash integrity at same time) // int Verify(const uint8_t* kdf, const uint8_t* passwd, size_t passwdSize) { uint64_t N=0; uint32_t r=0, p=0; uint8_t dk[64], salt[32], hbuf[32]; uint8_t * key_hmac = &dk[32]; HMAC_SHA256_CTX hctx; SHA256_CTX ctx; /* Parse N, r, p, salt. */ N = (uint64_t)1 << kdf[7]; //Remember, kdf[7] is actually LogN r = be32dec(&kdf[8]); p = be32dec(&kdf[12]); memcpy(salt, &kdf[16], 32); /* Verify hash checksum. */ SHA256_Init(&ctx); SHA256_Update(&ctx, kdf, 48); SHA256_Final(hbuf, &ctx); if (memcmp(&kdf[48], hbuf, 16)) return (7); /* Compute Derived Key */ if (ScryptHashFunction(passwd, passwdSize, salt, 32, N, r, p, dk, 64)) return (3); /* Check hash signature (i.e., verify password). */ HMAC_SHA256_Init(&hctx, key_hmac, 32); HMAC_SHA256_Update(&hctx, kdf, 64); HMAC_SHA256_Final(hbuf, &hctx); if (memcmp(hbuf, &kdf[64], 32)) return (11); return (0); //Success }
// // Creates a password hash. This is the actual key derivation function // unsigned int KDF(const uint8_t* passwd, size_t passwdSize, uint8_t* kdf, uint32_t logN, uint32_t r, uint32_t p, const uint8_t* salt) { uint64_t N=1; uint8_t dk[64], hbuf[32]; uint8_t *key_hmac = &dk[32]; SHA256_CTX ctx; HMAC_SHA256_CTX hctx; /* Generate the derived keys. */ N <<= logN; if (ScryptHashFunction(passwd, passwdSize, salt, 32, N, r, p, dk, 64)) return (3); /* Construct the hash. */ memcpy(kdf, "scrypt", 6); //Sticking with Colin Percival's format of putting scrypt at the beginning kdf[6] = 0; kdf[7] = logN; be32enc(&kdf[8], r); be32enc(&kdf[12], p); memcpy(&kdf[16], salt, 32); /* Add hash checksum. */ SHA256_Init(&ctx); SHA256_Update(&ctx, kdf, 48); SHA256_Final(hbuf, &ctx); memcpy(&kdf[48], hbuf, 16); /* Add hash signature (used for verifying password). */ HMAC_SHA256_Init(&hctx, key_hmac, 32); HMAC_SHA256_Update(&hctx, kdf, 64); HMAC_SHA256_Final(hbuf, &hctx); memcpy(&kdf[64], hbuf, 32); return 0; //success }
/** * scryptdec_file(infile, outfile, passwd, passwdlen, * maxmem, maxmemfrac, maxtime): * Read a stream from infile and decrypt it, writing the resulting stream to * outfile. */ int scryptdec_file(FILE * infile, FILE * outfile, const uint8_t * passwd, size_t passwdlen, size_t maxmem, double maxmemfrac, double maxtime) { uint8_t buf[ENCBLOCK + 32]; uint8_t header[96]; uint8_t hbuf[32]; uint8_t dk[64]; uint8_t * key_enc = dk; uint8_t * key_hmac = &dk[32]; size_t buflen = 0; size_t readlen; HMAC_SHA256_CTX hctx; struct crypto_aes_key * key_enc_exp; struct crypto_aesctr * AES; int rc; /* * Read the first 7 bytes of the file; all future versions of scrypt * are guaranteed to have at least 7 bytes of header. */ if (fread(header, 7, 1, infile) < 1) { if (ferror(infile)) return (13); else return (7); } /* Do we have the right magic? */ if (memcmp(header, "scrypt", 6)) return (7); if (header[6] != 0) return (8); /* * Read another 89 bytes of the file; version 0 of the scrypt file * format has a 96-byte header. */ if (fread(&header[7], 89, 1, infile) < 1) { if (ferror(infile)) return (13); else return (7); } /* Parse the header and generate derived keys. */ if ((rc = scryptdec_setup(header, dk, passwd, passwdlen, maxmem, maxmemfrac, maxtime)) != 0) return (rc); /* Start hashing with the header. */ HMAC_SHA256_Init(&hctx, key_hmac, 32); HMAC_SHA256_Update(&hctx, header, 96); /* * We don't know how long the encrypted data block is (we can't know, * since data can be streamed into 'scrypt enc') so we need to read * data and decrypt all of it except the final 32 bytes, then check * if that final 32 bytes is the correct signature. */ if ((key_enc_exp = crypto_aes_key_expand(key_enc, 32)) == NULL) return (5); if ((AES = crypto_aesctr_init(key_enc_exp, 0)) == NULL) return (6); do { /* Read data until we have more than 32 bytes of it. */ if ((readlen = fread(&buf[buflen], 1, ENCBLOCK + 32 - buflen, infile)) == 0) break; buflen += readlen; if (buflen <= 32) continue; /* * Decrypt, hash, and output everything except the last 32 * bytes out of what we have in our buffer. */ HMAC_SHA256_Update(&hctx, buf, buflen - 32); crypto_aesctr_stream(AES, buf, buf, buflen - 32); if (fwrite(buf, 1, buflen - 32, outfile) < buflen - 32) { crypto_aesctr_free(AES); return (12); } /* Move the last 32 bytes to the start of the buffer. */ memmove(buf, &buf[buflen - 32], 32); buflen = 32; } while (1); crypto_aesctr_free(AES); crypto_aes_key_free(key_enc_exp); /* Did we exit the loop due to a read error? */ if (ferror(infile)) return (13); /* Did we read enough data that we *might* have a valid signature? */ if (buflen < 32) return (7); /* Verify signature. */ HMAC_SHA256_Final(hbuf, &hctx); if (memcmp(hbuf, buf, 32)) return (7); /* Zero sensitive data. */ insecure_memzero(dk, 64); return (0); }
/** * scryptenc_file(infile, outfile, passwd, passwdlen, * maxmem, maxmemfrac, maxtime): * Read a stream from infile and encrypt it, writing the resulting stream to * outfile. */ int scryptenc_file(FILE * infile, FILE * outfile, const uint8_t * passwd, size_t passwdlen, size_t maxmem, double maxmemfrac, double maxtime) { uint8_t buf[ENCBLOCK]; uint8_t dk[64]; uint8_t hbuf[32]; uint8_t header[96]; uint8_t * key_enc = dk; uint8_t * key_hmac = &dk[32]; size_t readlen; HMAC_SHA256_CTX hctx; struct crypto_aes_key * key_enc_exp; struct crypto_aesctr * AES; int rc; /* Generate the header and derived key. */ if ((rc = scryptenc_setup(header, dk, passwd, passwdlen, maxmem, maxmemfrac, maxtime)) != 0) return (rc); /* Hash and write the header. */ HMAC_SHA256_Init(&hctx, key_hmac, 32); HMAC_SHA256_Update(&hctx, header, 96); if (fwrite(header, 96, 1, outfile) != 1) return (12); /* * Read blocks of data, encrypt them, and write them out; hash the * data as it is produced. */ if ((key_enc_exp = crypto_aes_key_expand(key_enc, 32)) == NULL) return (5); if ((AES = crypto_aesctr_init(key_enc_exp, 0)) == NULL) return (6); do { if ((readlen = fread(buf, 1, ENCBLOCK, infile)) == 0) break; crypto_aesctr_stream(AES, buf, buf, readlen); HMAC_SHA256_Update(&hctx, buf, readlen); if (fwrite(buf, 1, readlen, outfile) < readlen) { crypto_aesctr_free(AES); return (12); } } while (1); crypto_aesctr_free(AES); crypto_aes_key_free(key_enc_exp); /* Did we exit the loop due to a read error? */ if (ferror(infile)) return (13); /* Compute the final HMAC and output it. */ HMAC_SHA256_Final(hbuf, &hctx); if (fwrite(hbuf, 32, 1, outfile) != 1) return (12); /* Zero sensitive data. */ insecure_memzero(dk, 64); /* Success! */ return (0); }