mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-11-21 23:18:13 +00:00
new pbkdf2 api with update
This commit is contained in:
parent
e1d9e96f15
commit
b7b57ae53e
109
extmod/modtrezorcrypto/modtrezorcrypto-pbkdf2.h
Normal file
109
extmod/modtrezorcrypto/modtrezorcrypto-pbkdf2.h
Normal file
@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Copyright (c) Pavol Rusnak, SatoshiLabs
|
||||
*
|
||||
* Licensed under Microsoft Reference Source License (Ms-RSL)
|
||||
* see LICENSE.md file for details
|
||||
*/
|
||||
|
||||
#include "py/objstr.h"
|
||||
|
||||
#include "trezor-crypto/pbkdf2.h"
|
||||
|
||||
// class Pbkdf2(object):
|
||||
typedef struct _mp_obj_Pbkdf2_t {
|
||||
mp_obj_base_t base;
|
||||
union {
|
||||
PBKDF2_HMAC_SHA256_CTX ctx256;
|
||||
PBKDF2_HMAC_SHA512_CTX ctx512;
|
||||
};
|
||||
int prf;
|
||||
} mp_obj_Pbkdf2_t;
|
||||
|
||||
STATIC mp_obj_t mod_TrezorCrypto_Pbkdf2_update(mp_obj_t self, mp_obj_t data);
|
||||
|
||||
// def Pbkdf2.__init__(self, prf: str, password: bytes, salt: bytes, iterations: int=None)
|
||||
STATIC mp_obj_t mod_TrezorCrypto_Pbkdf2_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
|
||||
mp_arg_check_num(n_args, n_kw, 3, 4, false);
|
||||
mp_obj_Pbkdf2_t *o = m_new_obj(mp_obj_Pbkdf2_t);
|
||||
o->base.type = type;
|
||||
|
||||
mp_buffer_info_t prf;
|
||||
mp_get_buffer_raise(args[0], &prf, MP_BUFFER_READ);
|
||||
mp_buffer_info_t password;
|
||||
mp_get_buffer_raise(args[1], &password, MP_BUFFER_READ);
|
||||
mp_buffer_info_t salt;
|
||||
mp_get_buffer_raise(args[2], &salt, MP_BUFFER_READ);
|
||||
|
||||
o->prf = 0;
|
||||
if (prf.len == 11 && memcmp(prf.buf, "hmac-sha256", prf.len) == 0) {
|
||||
pbkdf2_hmac_sha256_Init(&(o->ctx256), password.buf, password.len, salt.buf, salt.len);
|
||||
o->prf = 256;
|
||||
} else
|
||||
if (prf.len == 11 && memcmp(prf.buf, "hmac-sha512", prf.len) == 0) {
|
||||
pbkdf2_hmac_sha512_Init(&(o->ctx512), password.buf, password.len, salt.buf, salt.len);
|
||||
o->prf = 512;
|
||||
} else
|
||||
if (o->prf == 0) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "Invalid PRF"));
|
||||
}
|
||||
// constructor called with iterations as fourth parameter
|
||||
if (n_args > 3) {
|
||||
mod_TrezorCrypto_Pbkdf2_update(MP_OBJ_FROM_PTR(o), args[3]);
|
||||
}
|
||||
return MP_OBJ_FROM_PTR(o);
|
||||
}
|
||||
|
||||
// def Pbkdf2.update(self, iterations: int) -> None
|
||||
STATIC mp_obj_t mod_TrezorCrypto_Pbkdf2_update(mp_obj_t self, mp_obj_t iterations) {
|
||||
mp_obj_Pbkdf2_t *o = MP_OBJ_TO_PTR(self);
|
||||
uint32_t iter = mp_obj_get_int(iterations);
|
||||
if (o->prf == 256) {
|
||||
pbkdf2_hmac_sha256_Update(&(o->ctx256), iter);
|
||||
}
|
||||
if (o->prf == 512) {
|
||||
pbkdf2_hmac_sha512_Update(&(o->ctx512), iter);
|
||||
}
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_TrezorCrypto_Pbkdf2_update_obj, mod_TrezorCrypto_Pbkdf2_update);
|
||||
|
||||
// def Pbkdf2.key(self) -> bytes
|
||||
STATIC mp_obj_t mod_TrezorCrypto_Pbkdf2_key(mp_obj_t self) {
|
||||
mp_obj_Pbkdf2_t *o = MP_OBJ_TO_PTR(self);
|
||||
vstr_t vstr;
|
||||
if (o->prf == 256) {
|
||||
vstr_init_len(&vstr, SHA256_DIGEST_LENGTH);
|
||||
memcpy(vstr.buf, o->ctx256.f, SHA256_DIGEST_LENGTH);
|
||||
}
|
||||
if (o->prf == 512) {
|
||||
vstr_init_len(&vstr, SHA512_DIGEST_LENGTH);
|
||||
memcpy(vstr.buf, o->ctx512.f, SHA512_DIGEST_LENGTH);
|
||||
}
|
||||
return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_TrezorCrypto_Pbkdf2_key_obj, mod_TrezorCrypto_Pbkdf2_key);
|
||||
|
||||
// def Pbkdf2.__del__(self) -> None
|
||||
STATIC mp_obj_t mod_TrezorCrypto_Pbkdf2___del__(mp_obj_t self) {
|
||||
mp_obj_Pbkdf2_t *o = MP_OBJ_TO_PTR(self);
|
||||
memset(&(o->ctx256), 0, sizeof(PBKDF2_HMAC_SHA256_CTX));
|
||||
memset(&(o->ctx512), 0, sizeof(PBKDF2_HMAC_SHA512_CTX));
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_TrezorCrypto_Pbkdf2___del___obj, mod_TrezorCrypto_Pbkdf2___del__);
|
||||
|
||||
// Pbkdf2 stuff
|
||||
|
||||
STATIC const mp_rom_map_elem_t mod_TrezorCrypto_Pbkdf2_locals_dict_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR_update), MP_ROM_PTR(&mod_TrezorCrypto_Pbkdf2_update_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_key), MP_ROM_PTR(&mod_TrezorCrypto_Pbkdf2_key_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&mod_TrezorCrypto_Pbkdf2___del___obj) },
|
||||
};
|
||||
STATIC MP_DEFINE_CONST_DICT(mod_TrezorCrypto_Pbkdf2_locals_dict, mod_TrezorCrypto_Pbkdf2_locals_dict_table);
|
||||
|
||||
STATIC const mp_obj_type_t mod_TrezorCrypto_Pbkdf2_type = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_Pbkdf2,
|
||||
.make_new = mod_TrezorCrypto_Pbkdf2_make_new,
|
||||
.locals_dict = (void*)&mod_TrezorCrypto_Pbkdf2_locals_dict,
|
||||
};
|
@ -1,46 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Pavol Rusnak, SatoshiLabs
|
||||
*
|
||||
* Licensed under Microsoft Reference Source License (Ms-RSL)
|
||||
* see LICENSE.md file for details
|
||||
*/
|
||||
|
||||
#include "py/objstr.h"
|
||||
|
||||
#include "trezor-crypto/pbkdf2.h"
|
||||
|
||||
// def pbkdf2_hmac(hash_name: str, password: bytes, salt: bytes, iterations: int, dklen:int=None) -> bytes
|
||||
STATIC mp_obj_t mod_TrezorCrypto_pbkdf2_hmac(size_t n_args, const mp_obj_t *args) {
|
||||
mp_buffer_info_t hash_name;
|
||||
mp_get_buffer_raise(args[0], &hash_name, MP_BUFFER_READ);
|
||||
mp_buffer_info_t password;
|
||||
mp_get_buffer_raise(args[1], &password, MP_BUFFER_READ);
|
||||
mp_buffer_info_t salt;
|
||||
mp_get_buffer_raise(args[2], &salt, MP_BUFFER_READ);
|
||||
mp_int_t iterations = mp_obj_get_int(args[3]);
|
||||
mp_int_t dklen = (n_args > 4) ? mp_obj_get_int(args[4]) : 0;
|
||||
|
||||
int digestsize = 0;
|
||||
if (hash_name.len == 6 && memcmp(hash_name.buf, "sha256", hash_name.len) == 0) {
|
||||
digestsize = 32;
|
||||
} else
|
||||
if (hash_name.len == 6 && memcmp(hash_name.buf, "sha512", hash_name.len) == 0) {
|
||||
digestsize = 64;
|
||||
}
|
||||
if (digestsize == 0) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "Invalid hash_name"));
|
||||
}
|
||||
if (dklen == 0) {
|
||||
dklen = digestsize;
|
||||
}
|
||||
vstr_t vstr;
|
||||
vstr_init_len(&vstr, dklen);
|
||||
if (digestsize == 32) {
|
||||
pbkdf2_hmac_sha256(password.buf, password.len, salt.buf, salt.len, iterations, (uint8_t *)vstr.buf, dklen, NULL);
|
||||
}
|
||||
if (digestsize == 64) {
|
||||
pbkdf2_hmac_sha512(password.buf, password.len, salt.buf, salt.len, iterations, (uint8_t *)vstr.buf, dklen, NULL);
|
||||
}
|
||||
return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_TrezorCrypto_pbkdf2_hmac_obj, 4, 5, mod_TrezorCrypto_pbkdf2_hmac);
|
@ -16,7 +16,7 @@
|
||||
#if MICROPY_PY_TREZORCRYPTO
|
||||
|
||||
#include "modtrezorcrypto-ed25519.h"
|
||||
#include "modtrezorcrypto-pbkdf2_hmac.h"
|
||||
#include "modtrezorcrypto-pbkdf2.h"
|
||||
#include "modtrezorcrypto-ripemd160.h"
|
||||
#include "modtrezorcrypto-nist256p1.h"
|
||||
#include "modtrezorcrypto-secp256k1.h"
|
||||
@ -31,13 +31,13 @@ STATIC const mp_rom_map_elem_t mp_module_TrezorCrypto_globals_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_TrezorCrypto) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_Ed25519), MP_ROM_PTR(&mod_TrezorCrypto_Ed25519_type) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_Nist256p1), MP_ROM_PTR(&mod_TrezorCrypto_Nist256p1_type) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_Pbkdf2), MP_ROM_PTR(&mod_TrezorCrypto_Pbkdf2_type) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_Ripemd160), MP_ROM_PTR(&mod_TrezorCrypto_Ripemd160_type) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_Secp256k1), MP_ROM_PTR(&mod_TrezorCrypto_Secp256k1_type) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_Sha256), MP_ROM_PTR(&mod_TrezorCrypto_Sha256_type) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_Sha512), MP_ROM_PTR(&mod_TrezorCrypto_Sha512_type) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_Sha3_256), MP_ROM_PTR(&mod_TrezorCrypto_Sha3_256_type) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_Sha3_512), MP_ROM_PTR(&mod_TrezorCrypto_Sha3_512_type) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_pbkdf2_hmac), MP_ROM_PTR(&mod_TrezorCrypto_pbkdf2_hmac_obj) },
|
||||
};
|
||||
STATIC MP_DEFINE_CONST_DICT(mp_module_TrezorCrypto_globals, mp_module_TrezorCrypto_globals_table);
|
||||
|
||||
|
@ -4,40 +4,105 @@ sys.path.append('../lib')
|
||||
import unittest
|
||||
from ubinascii import unhexlify
|
||||
|
||||
from trezor.crypto import hashlib
|
||||
from trezor.crypto import hmac
|
||||
from trezor.crypto import pbkdf2
|
||||
|
||||
class TestCryptoPbkdf2(unittest.TestCase):
|
||||
|
||||
# vectors from https://stackoverflow.com/questions/5130513/pbkdf2-hmac-sha2-test-vectors
|
||||
def test_hmac_sha256(self):
|
||||
def test_pbkdf2_hmac_sha256(self):
|
||||
P = b'password'
|
||||
S = b'salt'
|
||||
dk = hashlib.pbkdf2_hmac('sha256', P, S, 1)
|
||||
dk = pbkdf2('hmac-sha256', P, S, 1).key()
|
||||
self.assertEqual(dk, unhexlify('120fb6cffcf8b32c43e7225256c4f837a86548c92ccc35480805987cb70be17b'))
|
||||
dk = hashlib.pbkdf2_hmac('sha256', P, S, 2)
|
||||
dk = pbkdf2('hmac-sha256', P, S, 2).key()
|
||||
self.assertEqual(dk, unhexlify('ae4d0c95af6b46d32d0adff928f06dd02a303f8ef3c251dfd6e2d85a95474c43'))
|
||||
dk = hashlib.pbkdf2_hmac('sha256', P, S, 4096)
|
||||
dk = pbkdf2('hmac-sha256', P, S, 4096).key()
|
||||
self.assertEqual(dk, unhexlify('c5e478d59288c841aa530db6845c4c8d962893a001ce4e11a4963873aa98134a'))
|
||||
P = b'passwordPASSWORDpassword'
|
||||
S = b'saltSALTsaltSALTsaltSALTsaltSALTsalt'
|
||||
dk = hashlib.pbkdf2_hmac('sha256', P, S, 4096, 40)
|
||||
self.assertEqual(dk, unhexlify('348c89dbcbd32b2f32d814b8116e84cf2b17347ebc1800181c4e2a1fb8dd53e1c635518c7dac47e9'))
|
||||
dk = pbkdf2('hmac-sha256', P, S, 4096).key()
|
||||
self.assertEqual(dk, unhexlify('348c89dbcbd32b2f32d814b8116e84cf2b17347ebc1800181c4e2a1fb8dd53e1'))
|
||||
|
||||
# vectors from https://stackoverflow.com/questions/15593184/pbkdf2-hmac-sha-512-test-vectors
|
||||
def test_hmac_sha512(self):
|
||||
def test_pbkdf2_hmac_sha256_update(self):
|
||||
P = b'password'
|
||||
S = b'salt'
|
||||
dk = hashlib.pbkdf2_hmac('sha512', P, S, 1)
|
||||
p = pbkdf2('hmac-sha256', P, S)
|
||||
p.update(1)
|
||||
dk = p.key()
|
||||
self.assertEqual(dk, unhexlify('120fb6cffcf8b32c43e7225256c4f837a86548c92ccc35480805987cb70be17b'))
|
||||
p = pbkdf2('hmac-sha256', P, S)
|
||||
p.update(1)
|
||||
p.update(1)
|
||||
dk = p.key()
|
||||
self.assertEqual(dk, unhexlify('ae4d0c95af6b46d32d0adff928f06dd02a303f8ef3c251dfd6e2d85a95474c43'))
|
||||
p = pbkdf2('hmac-sha256', P, S)
|
||||
for i in range(32):
|
||||
p.update(128)
|
||||
dk = p.key()
|
||||
self.assertEqual(dk, unhexlify('c5e478d59288c841aa530db6845c4c8d962893a001ce4e11a4963873aa98134a'))
|
||||
P = b'passwordPASSWORDpassword'
|
||||
S = b'saltSALTsaltSALTsaltSALTsaltSALTsalt'
|
||||
p = pbkdf2('hmac-sha256', P, S)
|
||||
for i in range(64):
|
||||
p.update(64)
|
||||
dk = p.key()
|
||||
self.assertEqual(dk, unhexlify('348c89dbcbd32b2f32d814b8116e84cf2b17347ebc1800181c4e2a1fb8dd53e1'))
|
||||
|
||||
# vectors from https://stackoverflow.com/questions/15593184/pbkdf2-hmac-sha-512-test-vectors
|
||||
def test_pbkdf2_hmac_sha512(self):
|
||||
P = b'password'
|
||||
S = b'salt'
|
||||
dk = pbkdf2('hmac-sha512', P, S, 1).key()
|
||||
self.assertEqual(dk, unhexlify('867f70cf1ade02cff3752599a3a53dc4af34c7a669815ae5d513554e1c8cf252c02d470a285a0501bad999bfe943c08f050235d7d68b1da55e63f73b60a57fce'))
|
||||
dk = hashlib.pbkdf2_hmac('sha512', P, S, 2)
|
||||
dk = pbkdf2('hmac-sha512', P, S, 2).key()
|
||||
self.assertEqual(dk, unhexlify('e1d9c16aa681708a45f5c7c4e215ceb66e011a2e9f0040713f18aefdb866d53cf76cab2868a39b9f7840edce4fef5a82be67335c77a6068e04112754f27ccf4e'))
|
||||
dk = hashlib.pbkdf2_hmac('sha512', P, S, 4096)
|
||||
dk = pbkdf2('hmac-sha512', P, S, 4096).key()
|
||||
self.assertEqual(dk, unhexlify('d197b1b33db0143e018b12f3d1d1479e6cdebdcc97c5c0f87f6902e072f457b5143f30602641b3d55cd335988cb36b84376060ecd532e039b742a239434af2d5'))
|
||||
P = b'passwordPASSWORDpassword'
|
||||
S = b'saltSALTsaltSALTsaltSALTsaltSALTsalt'
|
||||
dk = hashlib.pbkdf2_hmac('sha512', P, S, 4096)
|
||||
dk = pbkdf2('hmac-sha512', P, S, 4096).key()
|
||||
self.assertEqual(dk, unhexlify('8c0511f4c6e597c6ac6315d8f0362e225f3c501495ba23b868c005174dc4ee71115b59f9e60cd9532fa33e0f75aefe30225c583a186cd82bd4daea9724a3d3b8'))
|
||||
|
||||
def test_pbkdf2_hmac_sha512_update(self):
|
||||
P = b'password'
|
||||
S = b'salt'
|
||||
p = pbkdf2('hmac-sha512', P, S)
|
||||
p.update(1)
|
||||
dk = p.key()
|
||||
self.assertEqual(dk, unhexlify('867f70cf1ade02cff3752599a3a53dc4af34c7a669815ae5d513554e1c8cf252c02d470a285a0501bad999bfe943c08f050235d7d68b1da55e63f73b60a57fce'))
|
||||
p = pbkdf2('hmac-sha512', P, S)
|
||||
p.update(1)
|
||||
p.update(1)
|
||||
dk = p.key()
|
||||
self.assertEqual(dk, unhexlify('e1d9c16aa681708a45f5c7c4e215ceb66e011a2e9f0040713f18aefdb866d53cf76cab2868a39b9f7840edce4fef5a82be67335c77a6068e04112754f27ccf4e'))
|
||||
p = pbkdf2('hmac-sha512', P, S)
|
||||
for i in range(32):
|
||||
p.update(128)
|
||||
dk = p.key()
|
||||
self.assertEqual(dk, unhexlify('d197b1b33db0143e018b12f3d1d1479e6cdebdcc97c5c0f87f6902e072f457b5143f30602641b3d55cd335988cb36b84376060ecd532e039b742a239434af2d5'))
|
||||
P = b'passwordPASSWORDpassword'
|
||||
S = b'saltSALTsaltSALTsaltSALTsaltSALTsalt'
|
||||
p = pbkdf2('hmac-sha512', P, S)
|
||||
for i in range(64):
|
||||
p.update(64)
|
||||
dk = p.key()
|
||||
self.assertEqual(dk, unhexlify('8c0511f4c6e597c6ac6315d8f0362e225f3c501495ba23b868c005174dc4ee71115b59f9e60cd9532fa33e0f75aefe30225c583a186cd82bd4daea9724a3d3b8'))
|
||||
|
||||
def test_key_multi(self):
|
||||
P = b'password'
|
||||
S = b'salt'
|
||||
p = pbkdf2('hmac-sha256', P, S, 16)
|
||||
k0 = p.key()
|
||||
k1 = p.key()
|
||||
k2 = p.key()
|
||||
self.assertEqual(k0, k1)
|
||||
self.assertEqual(k0, k2)
|
||||
p = pbkdf2('hmac-sha512', P, S, 16)
|
||||
k0 = p.key()
|
||||
k1 = p.key()
|
||||
k2 = p.key()
|
||||
self.assertEqual(k0, k1)
|
||||
self.assertEqual(k0, k2)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
@ -0,0 +1 @@
|
||||
from TrezorCrypto import Pbkdf2 as pbkdf2
|
@ -3,4 +3,3 @@ from TrezorCrypto import Sha256 as sha256
|
||||
from TrezorCrypto import Sha512 as sha512
|
||||
from TrezorCrypto import Sha3_256 as sha3_256
|
||||
from TrezorCrypto import Sha3_512 as sha3_512
|
||||
from TrezorCrypto import pbkdf2_hmac
|
||||
|
2
vendor/trezor-crypto
vendored
2
vendor/trezor-crypto
vendored
@ -1 +1 @@
|
||||
Subproject commit b8ec5567ba701c77379f2111774456eb18b98790
|
||||
Subproject commit 242a5de275d36e2df6792c921a9cd7d8c8e8933b
|
Loading…
Reference in New Issue
Block a user