mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-11-22 23:48:12 +00:00
simplify pbkdf2 (support only klen == hashlen) and split it
This commit is contained in:
parent
b8ec5567ba
commit
242a5de275
18
bip39.c
18
bip39.c
@ -168,8 +168,7 @@ void mnemonic_to_seed(const char *mnemonic, const char *passphrase, uint8_t seed
|
|||||||
int mnemoniclen = strlen(mnemonic);
|
int mnemoniclen = strlen(mnemonic);
|
||||||
// check cache
|
// check cache
|
||||||
if (mnemoniclen < 256 && passphraselen < 64) {
|
if (mnemoniclen < 256 && passphraselen < 64) {
|
||||||
int i;
|
for (int i = 0; i < BIP39_CACHE_SIZE; i++) {
|
||||||
for (i = 0; i < BIP39_CACHE_SIZE; i++) {
|
|
||||||
if (!bip39_cache[i].set) continue;
|
if (!bip39_cache[i].set) continue;
|
||||||
if (strcmp(bip39_cache[i].mnemonic, mnemonic) != 0) continue;
|
if (strcmp(bip39_cache[i].mnemonic, mnemonic) != 0) continue;
|
||||||
if (strcmp(bip39_cache[i].passphrase, passphrase) != 0) continue;
|
if (strcmp(bip39_cache[i].passphrase, passphrase) != 0) continue;
|
||||||
@ -179,10 +178,21 @@ void mnemonic_to_seed(const char *mnemonic, const char *passphrase, uint8_t seed
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
uint8_t salt[8 + 256 + 4];
|
uint8_t salt[8 + 256];
|
||||||
memcpy(salt, "mnemonic", 8);
|
memcpy(salt, "mnemonic", 8);
|
||||||
memcpy(salt + 8, passphrase, passphraselen);
|
memcpy(salt + 8, passphrase, passphraselen);
|
||||||
pbkdf2_hmac_sha512((const uint8_t *)mnemonic, strlen(mnemonic), salt, passphraselen + 8, BIP39_PBKDF2_ROUNDS, seed, 512 / 8, progress_callback);
|
PBKDF2_HMAC_SHA512_CTX pctx;
|
||||||
|
pbkdf2_hmac_sha512_Init(&pctx, (const uint8_t *)mnemonic, strlen(mnemonic), salt, passphraselen + 8);
|
||||||
|
if (progress_callback) {
|
||||||
|
progress_callback(0, BIP39_PBKDF2_ROUNDS);
|
||||||
|
}
|
||||||
|
for (int i = 0; i < 8; i++) {
|
||||||
|
pbkdf2_hmac_sha512_Update(&pctx, BIP39_PBKDF2_ROUNDS / 8);
|
||||||
|
if (progress_callback) {
|
||||||
|
progress_callback((i + 1) * BIP39_PBKDF2_ROUNDS / 8, BIP39_PBKDF2_ROUNDS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pbkdf2_hmac_sha512_Final(&pctx, seed);
|
||||||
#if USE_BIP39_CACHE
|
#if USE_BIP39_CACHE
|
||||||
// store to cache
|
// store to cache
|
||||||
if (mnemoniclen < 256 && passphraselen < 64) {
|
if (mnemoniclen < 256 && passphraselen < 64) {
|
||||||
|
116
pbkdf2.c
116
pbkdf2.c
@ -26,78 +26,78 @@
|
|||||||
#include "hmac.h"
|
#include "hmac.h"
|
||||||
#include "macros.h"
|
#include "macros.h"
|
||||||
|
|
||||||
void pbkdf2_hmac_sha256(const uint8_t *pass, int passlen, uint8_t *salt, int saltlen, uint32_t iterations, uint8_t *key, int keylen, void (*progress_callback)(uint32_t current, uint32_t total))
|
void pbkdf2_hmac_sha256_Init(PBKDF2_HMAC_SHA256_CTX *pctx, const uint8_t *pass, int passlen, uint8_t *salt, int saltlen)
|
||||||
{
|
{
|
||||||
const uint32_t HMACLEN = 256/8;
|
|
||||||
uint8_t f[HMACLEN], g[HMACLEN];
|
|
||||||
uint32_t blocks = keylen / HMACLEN;
|
|
||||||
if (keylen & (HMACLEN - 1)) {
|
|
||||||
blocks++;
|
|
||||||
}
|
|
||||||
for (uint32_t i = 1; i <= blocks; i++) {
|
|
||||||
HMAC_SHA256_CTX hctx;
|
HMAC_SHA256_CTX hctx;
|
||||||
hmac_sha256_Init(&hctx, pass, passlen);
|
hmac_sha256_Init(&hctx, pass, passlen);
|
||||||
hmac_sha256_Update(&hctx, salt, saltlen);
|
hmac_sha256_Update(&hctx, salt, saltlen);
|
||||||
uint32_t ii = ((i & 0xFF000000) >> 24) | ((i & 0x00FF0000) >> 8) | ((i & 0x0000FF00) << 8) | ((i & 0x000000FF) << 24);
|
hmac_sha256_Update(&hctx, (const uint8_t *)"\x00\x00\x00\x01", 4);
|
||||||
hmac_sha256_Update(&hctx, (const uint8_t *)&ii, sizeof(uint32_t));
|
hmac_sha256_Final(&hctx, pctx->g);
|
||||||
hmac_sha256_Final(&hctx, g);
|
memcpy(pctx->f, pctx->g, SHA256_DIGEST_LENGTH);
|
||||||
memcpy(f, g, HMACLEN);
|
pctx->pass = pass;
|
||||||
if (progress_callback) {
|
pctx->passlen = passlen;
|
||||||
progress_callback(0, iterations);
|
pctx->first = 1;
|
||||||
}
|
|
||||||
for (uint32_t j = 1; j < iterations; j++) {
|
|
||||||
hmac_sha256(pass, passlen, g, HMACLEN, g);
|
|
||||||
for (uint32_t k = 0; k < HMACLEN; k++) {
|
|
||||||
f[k] ^= g[k];
|
|
||||||
}
|
|
||||||
if (progress_callback && (j % 256 == 255)) {
|
|
||||||
progress_callback(j + 1, iterations);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (i == blocks && (keylen & (HMACLEN - 1))) {
|
|
||||||
memcpy(key + HMACLEN * (i - 1), f, keylen & (HMACLEN - 1));
|
|
||||||
} else {
|
|
||||||
memcpy(key + HMACLEN * (i - 1), f, HMACLEN);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
MEMSET_BZERO(f, sizeof(f));
|
|
||||||
MEMSET_BZERO(g, sizeof(g));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void pbkdf2_hmac_sha512(const uint8_t *pass, int passlen, uint8_t *salt, int saltlen, uint32_t iterations, uint8_t *key, int keylen, void (*progress_callback)(uint32_t current, uint32_t total))
|
void pbkdf2_hmac_sha256_Update(PBKDF2_HMAC_SHA256_CTX *pctx, uint32_t iterations)
|
||||||
{
|
{
|
||||||
const uint32_t HMACLEN = 512/8;
|
for (uint32_t i = pctx->first; i < iterations; i++) {
|
||||||
uint8_t f[HMACLEN], g[HMACLEN];
|
hmac_sha256(pctx->pass, pctx->passlen, pctx->g, SHA256_DIGEST_LENGTH, pctx->g);
|
||||||
uint32_t blocks = keylen / HMACLEN;
|
for (uint32_t j = 0; j < SHA256_DIGEST_LENGTH; j++) {
|
||||||
if (keylen & (HMACLEN - 1)) {
|
pctx->f[j] ^= pctx->g[j];
|
||||||
blocks++;
|
|
||||||
}
|
}
|
||||||
for (uint32_t i = 1; i <= blocks; i++) {
|
}
|
||||||
|
pctx->first = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void pbkdf2_hmac_sha256_Final(PBKDF2_HMAC_SHA256_CTX *pctx, uint8_t *key)
|
||||||
|
{
|
||||||
|
memcpy(key, pctx->f, SHA256_DIGEST_LENGTH);
|
||||||
|
MEMSET_BZERO(pctx, sizeof(PBKDF2_HMAC_SHA256_CTX));
|
||||||
|
}
|
||||||
|
|
||||||
|
void pbkdf2_hmac_sha256(const uint8_t *pass, int passlen, uint8_t *salt, int saltlen, uint32_t iterations, uint8_t *key)
|
||||||
|
{
|
||||||
|
PBKDF2_HMAC_SHA256_CTX pctx;
|
||||||
|
pbkdf2_hmac_sha256_Init(&pctx, pass, passlen, salt, saltlen);
|
||||||
|
pbkdf2_hmac_sha256_Update(&pctx, iterations);
|
||||||
|
pbkdf2_hmac_sha256_Final(&pctx, key);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pbkdf2_hmac_sha512_Init(PBKDF2_HMAC_SHA512_CTX *pctx, const uint8_t *pass, int passlen, uint8_t *salt, int saltlen)
|
||||||
|
{
|
||||||
HMAC_SHA512_CTX hctx;
|
HMAC_SHA512_CTX hctx;
|
||||||
hmac_sha512_Init(&hctx, pass, passlen);
|
hmac_sha512_Init(&hctx, pass, passlen);
|
||||||
hmac_sha512_Update(&hctx, salt, saltlen);
|
hmac_sha512_Update(&hctx, salt, saltlen);
|
||||||
uint32_t ii = ((i & 0xFF000000) >> 24) | ((i & 0x00FF0000) >> 8) | ((i & 0x0000FF00) << 8) | ((i & 0x000000FF) << 24);
|
hmac_sha512_Update(&hctx, (const uint8_t *)"\x00\x00\x00\x01", 4);
|
||||||
hmac_sha512_Update(&hctx, (const uint8_t *)&ii, sizeof(uint32_t));
|
hmac_sha512_Final(&hctx, pctx->g);
|
||||||
hmac_sha512_Final(&hctx, g);
|
memcpy(pctx->f, pctx->g, SHA512_DIGEST_LENGTH);
|
||||||
memcpy(f, g, HMACLEN);
|
pctx->pass = pass;
|
||||||
if (progress_callback) {
|
pctx->passlen = passlen;
|
||||||
progress_callback(0, iterations);
|
pctx->first = 1;
|
||||||
}
|
}
|
||||||
for (uint32_t j = 1; j < iterations; j++) {
|
|
||||||
hmac_sha512(pass, passlen, g, HMACLEN, g);
|
void pbkdf2_hmac_sha512_Update(PBKDF2_HMAC_SHA512_CTX *pctx, uint32_t iterations)
|
||||||
for (uint32_t k = 0; k < HMACLEN; k++) {
|
{
|
||||||
f[k] ^= g[k];
|
for (uint32_t i = pctx->first; i < iterations; i++) {
|
||||||
}
|
hmac_sha512(pctx->pass, pctx->passlen, pctx->g, SHA512_DIGEST_LENGTH, pctx->g);
|
||||||
if (progress_callback && (j % 256 == 255)) {
|
for (uint32_t j = 0; j < SHA512_DIGEST_LENGTH; j++) {
|
||||||
progress_callback(j + 1, iterations);
|
pctx->f[j] ^= pctx->g[j];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (i == blocks && (keylen & (HMACLEN - 1))) {
|
pctx->first = 0;
|
||||||
memcpy(key + HMACLEN * (i - 1), f, keylen & (HMACLEN - 1));
|
|
||||||
} else {
|
|
||||||
memcpy(key + HMACLEN * (i - 1), f, HMACLEN);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void pbkdf2_hmac_sha512_Final(PBKDF2_HMAC_SHA512_CTX *pctx, uint8_t *key)
|
||||||
|
{
|
||||||
|
memcpy(key, pctx->f, SHA512_DIGEST_LENGTH);
|
||||||
|
MEMSET_BZERO(pctx, sizeof(PBKDF2_HMAC_SHA512_CTX));
|
||||||
}
|
}
|
||||||
MEMSET_BZERO(f, sizeof(f));
|
|
||||||
MEMSET_BZERO(g, sizeof(g));
|
void pbkdf2_hmac_sha512(const uint8_t *pass, int passlen, uint8_t *salt, int saltlen, uint32_t iterations, uint8_t *key)
|
||||||
|
{
|
||||||
|
PBKDF2_HMAC_SHA512_CTX pctx;
|
||||||
|
pbkdf2_hmac_sha512_Init(&pctx, pass, passlen, salt, saltlen);
|
||||||
|
pbkdf2_hmac_sha512_Update(&pctx, iterations);
|
||||||
|
pbkdf2_hmac_sha512_Final(&pctx, key);
|
||||||
}
|
}
|
||||||
|
28
pbkdf2.h
28
pbkdf2.h
@ -25,8 +25,32 @@
|
|||||||
#define __PBKDF2_H__
|
#define __PBKDF2_H__
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include "sha2.h"
|
||||||
|
|
||||||
void pbkdf2_hmac_sha256(const uint8_t *pass, int passlen, uint8_t *salt, int saltlen, uint32_t iterations, uint8_t *key, int keylen, void (*progress_callback)(uint32_t current, uint32_t total));
|
typedef struct _PBKDF2_HMAC_SHA256_CTX {
|
||||||
void pbkdf2_hmac_sha512(const uint8_t *pass, int passlen, uint8_t *salt, int saltlen, uint32_t iterations, uint8_t *key, int keylen, void (*progress_callback)(uint32_t current, uint32_t total));
|
uint8_t f[SHA256_DIGEST_LENGTH];
|
||||||
|
uint8_t g[SHA256_DIGEST_LENGTH];
|
||||||
|
const uint8_t *pass;
|
||||||
|
int passlen;
|
||||||
|
char first;
|
||||||
|
} PBKDF2_HMAC_SHA256_CTX;
|
||||||
|
|
||||||
|
typedef struct _PBKDF2_HMAC_SHA512_CTX {
|
||||||
|
uint8_t f[SHA512_DIGEST_LENGTH];
|
||||||
|
uint8_t g[SHA512_DIGEST_LENGTH];
|
||||||
|
const uint8_t *pass;
|
||||||
|
int passlen;
|
||||||
|
char first;
|
||||||
|
} PBKDF2_HMAC_SHA512_CTX;
|
||||||
|
|
||||||
|
void pbkdf2_hmac_sha256_Init(PBKDF2_HMAC_SHA256_CTX *pctx, const uint8_t *pass, int passlen, uint8_t *salt, int saltlen);
|
||||||
|
void pbkdf2_hmac_sha256_Update(PBKDF2_HMAC_SHA256_CTX *pctx, uint32_t iterations);
|
||||||
|
void pbkdf2_hmac_sha256_Final(PBKDF2_HMAC_SHA256_CTX *pctx, uint8_t *key);
|
||||||
|
void pbkdf2_hmac_sha256(const uint8_t *pass, int passlen, uint8_t *salt, int saltlen, uint32_t iterations, uint8_t *key);
|
||||||
|
|
||||||
|
void pbkdf2_hmac_sha512_Init(PBKDF2_HMAC_SHA512_CTX *pctx, const uint8_t *pass, int passlen, uint8_t *salt, int saltlen);
|
||||||
|
void pbkdf2_hmac_sha512_Update(PBKDF2_HMAC_SHA512_CTX *pctx, uint32_t iterations);
|
||||||
|
void pbkdf2_hmac_sha512_Final(PBKDF2_HMAC_SHA512_CTX *pctx, uint8_t *key);
|
||||||
|
void pbkdf2_hmac_sha512(const uint8_t *pass, int passlen, uint8_t *salt, int saltlen, uint32_t iterations, uint8_t *key);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
18
tests.c
18
tests.c
@ -1169,20 +1169,20 @@ START_TEST(test_pbkdf2_hmac_sha256)
|
|||||||
uint8_t k[40], s[40];
|
uint8_t k[40], s[40];
|
||||||
|
|
||||||
strcpy((char *)s, "salt");
|
strcpy((char *)s, "salt");
|
||||||
pbkdf2_hmac_sha256((uint8_t *)"password", 8, s, 4, 1, k, 32, 0);
|
pbkdf2_hmac_sha256((uint8_t *)"password", 8, s, 4, 1, k);
|
||||||
ck_assert_mem_eq(k, fromhex("120fb6cffcf8b32c43e7225256c4f837a86548c92ccc35480805987cb70be17b"), 32);
|
ck_assert_mem_eq(k, fromhex("120fb6cffcf8b32c43e7225256c4f837a86548c92ccc35480805987cb70be17b"), 32);
|
||||||
|
|
||||||
strcpy((char *)s, "salt");
|
strcpy((char *)s, "salt");
|
||||||
pbkdf2_hmac_sha256((uint8_t *)"password", 8, s, 4, 2, k, 32, 0);
|
pbkdf2_hmac_sha256((uint8_t *)"password", 8, s, 4, 2, k);
|
||||||
ck_assert_mem_eq(k, fromhex("ae4d0c95af6b46d32d0adff928f06dd02a303f8ef3c251dfd6e2d85a95474c43"), 32);
|
ck_assert_mem_eq(k, fromhex("ae4d0c95af6b46d32d0adff928f06dd02a303f8ef3c251dfd6e2d85a95474c43"), 32);
|
||||||
|
|
||||||
strcpy((char *)s, "salt");
|
strcpy((char *)s, "salt");
|
||||||
pbkdf2_hmac_sha256((uint8_t *)"password", 8, s, 4, 4096, k, 32, 0);
|
pbkdf2_hmac_sha256((uint8_t *)"password", 8, s, 4, 4096, k);
|
||||||
ck_assert_mem_eq(k, fromhex("c5e478d59288c841aa530db6845c4c8d962893a001ce4e11a4963873aa98134a"), 32);
|
ck_assert_mem_eq(k, fromhex("c5e478d59288c841aa530db6845c4c8d962893a001ce4e11a4963873aa98134a"), 32);
|
||||||
|
|
||||||
strcpy((char *)s, "saltSALTsaltSALTsaltSALTsaltSALTsalt");
|
strcpy((char *)s, "saltSALTsaltSALTsaltSALTsaltSALTsalt");
|
||||||
pbkdf2_hmac_sha256((uint8_t *)"passwordPASSWORDpassword", 3*8, s, 9*4, 4096, k, 40, 0);
|
pbkdf2_hmac_sha256((uint8_t *)"passwordPASSWORDpassword", 3*8, s, 9*4, 4096, k);
|
||||||
ck_assert_mem_eq(k, fromhex("348c89dbcbd32b2f32d814b8116e84cf2b17347ebc1800181c4e2a1fb8dd53e1c635518c7dac47e9"), 40);
|
ck_assert_mem_eq(k, fromhex("348c89dbcbd32b2f32d814b8116e84cf2b17347ebc1800181c4e2a1fb8dd53e1"), 32);
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
@ -1192,19 +1192,19 @@ START_TEST(test_pbkdf2_hmac_sha512)
|
|||||||
uint8_t k[64], s[40];
|
uint8_t k[64], s[40];
|
||||||
|
|
||||||
strcpy((char *)s, "salt");
|
strcpy((char *)s, "salt");
|
||||||
pbkdf2_hmac_sha512((uint8_t *)"password", 8, s, 4, 1, k, 64, 0);
|
pbkdf2_hmac_sha512((uint8_t *)"password", 8, s, 4, 1, k);
|
||||||
ck_assert_mem_eq(k, fromhex("867f70cf1ade02cff3752599a3a53dc4af34c7a669815ae5d513554e1c8cf252c02d470a285a0501bad999bfe943c08f050235d7d68b1da55e63f73b60a57fce"), 64);
|
ck_assert_mem_eq(k, fromhex("867f70cf1ade02cff3752599a3a53dc4af34c7a669815ae5d513554e1c8cf252c02d470a285a0501bad999bfe943c08f050235d7d68b1da55e63f73b60a57fce"), 64);
|
||||||
|
|
||||||
strcpy((char *)s, "salt");
|
strcpy((char *)s, "salt");
|
||||||
pbkdf2_hmac_sha512((uint8_t *)"password", 8, s, 4, 2, k, 64, 0);
|
pbkdf2_hmac_sha512((uint8_t *)"password", 8, s, 4, 2, k);
|
||||||
ck_assert_mem_eq(k, fromhex("e1d9c16aa681708a45f5c7c4e215ceb66e011a2e9f0040713f18aefdb866d53cf76cab2868a39b9f7840edce4fef5a82be67335c77a6068e04112754f27ccf4e"), 64);
|
ck_assert_mem_eq(k, fromhex("e1d9c16aa681708a45f5c7c4e215ceb66e011a2e9f0040713f18aefdb866d53cf76cab2868a39b9f7840edce4fef5a82be67335c77a6068e04112754f27ccf4e"), 64);
|
||||||
|
|
||||||
strcpy((char *)s, "salt");
|
strcpy((char *)s, "salt");
|
||||||
pbkdf2_hmac_sha512((uint8_t *)"password", 8, s, 4, 4096, k, 64, 0);
|
pbkdf2_hmac_sha512((uint8_t *)"password", 8, s, 4, 4096, k);
|
||||||
ck_assert_mem_eq(k, fromhex("d197b1b33db0143e018b12f3d1d1479e6cdebdcc97c5c0f87f6902e072f457b5143f30602641b3d55cd335988cb36b84376060ecd532e039b742a239434af2d5"), 64);
|
ck_assert_mem_eq(k, fromhex("d197b1b33db0143e018b12f3d1d1479e6cdebdcc97c5c0f87f6902e072f457b5143f30602641b3d55cd335988cb36b84376060ecd532e039b742a239434af2d5"), 64);
|
||||||
|
|
||||||
strcpy((char *)s, "saltSALTsaltSALTsaltSALTsaltSALTsalt");
|
strcpy((char *)s, "saltSALTsaltSALTsaltSALTsaltSALTsalt");
|
||||||
pbkdf2_hmac_sha512((uint8_t *)"passwordPASSWORDpassword", 3*8, s, 9*4, 4096, k, 64, 0);
|
pbkdf2_hmac_sha512((uint8_t *)"passwordPASSWORDpassword", 3*8, s, 9*4, 4096, k);
|
||||||
ck_assert_mem_eq(k, fromhex("8c0511f4c6e597c6ac6315d8f0362e225f3c501495ba23b868c005174dc4ee71115b59f9e60cd9532fa33e0f75aefe30225c583a186cd82bd4daea9724a3d3b8"), 64);
|
ck_assert_mem_eq(k, fromhex("8c0511f4c6e597c6ac6315d8f0362e225f3c501495ba23b868c005174dc4ee71115b59f9e60cd9532fa33e0f75aefe30225c583a186cd82bd4daea9724a3d3b8"), 64);
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
Loading…
Reference in New Issue
Block a user