1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2025-06-21 15:39:01 +00:00

use pbkdf2_hmac from mbedtls

This commit is contained in:
Pavol Rusnak 2016-04-15 23:21:30 +02:00
parent a230d9d294
commit b29ece66ef
No known key found for this signature in database
GPG Key ID: 91F3B339B9A02A3D
5 changed files with 2589 additions and 93 deletions

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,52 @@
/*
* Copyright (c) Pavol Rusnak, SatoshiLabs
*
* Licensed under Microsoft Reference Source License (Ms-RSL)
* see LICENSE.md file for details
*/
#include "py/objstr.h"
#include "mbedtls/pkcs5.h"
#include "mbedtls/md_internal.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;
const mbedtls_md_info_t *info = 0;
if (hash_name.len == 6 && memcmp(hash_name.buf, "sha256", hash_name.len) == 0) {
info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);
} else
if (hash_name.len == 6 && memcmp(hash_name.buf, "sha512", hash_name.len) == 0) {
info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA512);
}
if (info == 0) {
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "Invalid hash_name"));
}
if (dklen == 0) {
dklen = info->size;
}
mbedtls_md_context_t ctx;
mbedtls_md_init(&ctx);
if (mbedtls_md_setup(&ctx, info, 1) == 0) {
vstr_t vstr;
vstr_init_len(&vstr, dklen);
mbedtls_pkcs5_pbkdf2_hmac(&ctx, password.buf, password.len, salt.buf, salt.len, iterations, dklen, (uint8_t *)vstr.buf);
mbedtls_md_free(&ctx);
return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr);
} else {
mbedtls_md_free(&ctx);
nlr_raise(mp_obj_new_exception_msg(&mp_type_RuntimeError, "mbedtls_md_setup failed"));
}
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_TrezorCrypto_pbkdf2_hmac_obj, 4, 5, mod_TrezorCrypto_pbkdf2_hmac);

View File

@ -16,6 +16,7 @@
#if MICROPY_PY_TREZORCRYPTO #if MICROPY_PY_TREZORCRYPTO
#include "modtrezorcrypto-base58.h" #include "modtrezorcrypto-base58.h"
#include "modtrezorcrypto-pbkdf2_hmac.h"
#include "modtrezorcrypto-ripemd160.h" #include "modtrezorcrypto-ripemd160.h"
#include "modtrezorcrypto-sha256.h" #include "modtrezorcrypto-sha256.h"
#include "modtrezorcrypto-sha512.h" #include "modtrezorcrypto-sha512.h"
@ -28,6 +29,7 @@ STATIC const mp_rom_map_elem_t mp_module_TrezorCrypto_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR_Ripemd160), MP_ROM_PTR(&mod_TrezorCrypto_Ripemd160_type) }, { MP_ROM_QSTR(MP_QSTR_Ripemd160), MP_ROM_PTR(&mod_TrezorCrypto_Ripemd160_type) },
{ MP_ROM_QSTR(MP_QSTR_Sha256), MP_ROM_PTR(&mod_TrezorCrypto_Sha256_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_Sha512), MP_ROM_PTR(&mod_TrezorCrypto_Sha512_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); STATIC MP_DEFINE_CONST_DICT(mp_module_TrezorCrypto_globals, mp_module_TrezorCrypto_globals_table);

View File

@ -1,95 +1,4 @@
from TrezorCrypto import Ripemd160 as ripemd160 from TrezorCrypto import Ripemd160 as ripemd160
from TrezorCrypto import Sha256 as sha256 from TrezorCrypto import Sha256 as sha256
from TrezorCrypto import Sha512 as sha512 from TrezorCrypto import Sha512 as sha512
from TrezorCrypto import pbkdf2_hmac
from . import hmac
def pbkdf2_hmac(name, password, salt, rounds, dklen=None):
if name == 'sha256':
digestmod = sha256
elif name == 'sha512':
digestmod = sha512
elif name == 'ripemd160':
digestmod = ripemd160
else:
raise ValueError('unknown digest', name)
if dklen is None:
dklen = digestmod.digest_size
p = Pbkdf2(password, salt, rounds, digestmod, hmac)
k = p.read(dklen)
p.close()
return k
#
# Copyright (C) 2007-2011 Dwayne C. Litzenberger <dlitz@dlitz.net>
# Copyright (C) 2016 Pavol Rusnak <stick@gk2.sk>
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
from ustruct import pack
class Pbkdf2(object):
def __init__(self, passphrase, salt, iterations, digestmodule, macmodule):
self.__macmodule = macmodule
self.__digestmodule = digestmodule
self.__passphrase = passphrase
self.__salt = salt
self.__iterations = iterations
self.__prf = self._pseudorandom
self.__blockNum = 0
self.__buf = b''
self.closed = False
def _pseudorandom(self, key, msg):
return self.__macmodule.new(key=key, msg=msg, digestmod=self.__digestmodule).digest()
def read(self, numbytes):
if self.closed:
raise ValueError('file-like object is closed')
size = len(self.__buf)
blocks = [self.__buf]
i = self.__blockNum
while size < numbytes:
i += 1
U = self.__prf(self.__passphrase, self.__salt + pack('!L', i))
block = U
for j in range(2, 1 + self.__iterations):
U = self.__prf(self.__passphrase, U)
block = bytes([x ^ y for (x, y) in zip(block, U)])
blocks.append(block)
size += len(block)
buf = b''.join(blocks)
retval = buf[:numbytes]
self.__buf = buf[numbytes:]
self.__blockNum = i
return retval
def close(self):
if not self.closed:
del self.__passphrase
del self.__salt
del self.__iterations
del self.__prf
del self.__blockNum
del self.__buf
self.closed = True

2
vendor/micropython vendored

@ -1 +1 @@
Subproject commit c83524cb4a55d862f348c63d28341485c6920398 Subproject commit 07d410191ad0bb5560a7a35a234291a8488f8e56