diff --git a/SConscript.firmware b/SConscript.firmware index 3a458cef..6caba9d2 100644 --- a/SConscript.firmware +++ b/SConscript.firmware @@ -28,6 +28,7 @@ CPPDEFINES_MOD += [ ] SOURCE_MOD += [ 'embed/extmod/modtrezorcrypto/modtrezorcrypto.c', + 'embed/extmod/modtrezorcrypto/crc.c', 'embed/extmod/modtrezorcrypto/rand.c', 'embed/extmod/modtrezorcrypto/ssss.c', 'vendor/trezor-crypto/address.c', diff --git a/SConscript.unix b/SConscript.unix index 522369ae..00726f96 100644 --- a/SConscript.unix +++ b/SConscript.unix @@ -29,6 +29,7 @@ CPPDEFINES_MOD += [ ] SOURCE_MOD += [ 'embed/extmod/modtrezorcrypto/modtrezorcrypto.c', + 'embed/extmod/modtrezorcrypto/crc.c', 'embed/extmod/modtrezorcrypto/rand.c', 'embed/extmod/modtrezorcrypto/ssss.c', 'vendor/trezor-crypto/address.c', diff --git a/embed/extmod/modtrezorcrypto/crc.c b/embed/extmod/modtrezorcrypto/crc.c new file mode 100644 index 00000000..e69785e4 --- /dev/null +++ b/embed/extmod/modtrezorcrypto/crc.c @@ -0,0 +1,59 @@ +/* + * CRC32 checksum + * + * Copyright (c) 1998-2003 by Joergen Ibsen / Jibz + * All Rights Reserved + * + * http://www.ibsensoftware.com/ + * + * This software is provided 'as-is', without any express + * or implied warranty. In no event will the authors be + * held liable for any damages arising from the use of + * this software. + * + * Permission is granted to anyone to use this software + * for any purpose, including commercial applications, + * and to alter it and redistribute it freely, subject to + * the following restrictions: + * + * 1. The origin of this software must not be + * misrepresented; you must not claim that you + * wrote the original software. If you use this + * software in a product, an acknowledgment in + * the product documentation would be appreciated + * but is not required. + * + * 2. Altered source versions must be plainly marked + * as such, and must not be misrepresented as + * being the original software. + * + * 3. This notice may not be removed or altered from + * any source distribution. + */ + +/* + * CRC32 algorithm taken from the zlib source, which is + * Copyright (C) 1995-1998 Jean-loup Gailly and Mark Adler + */ + +#include "crc.h" + +static const uint32_t crc32tab[16] = { + 0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac, 0x76dc4190, + 0x6b6b51f4, 0x4db26158, 0x5005713c, 0xedb88320, 0xf00f9344, + 0xd6d6a3e8, 0xcb61b38c, 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, + 0xbdbdf21c +}; + +/* crc is previous value for incremental computation, 0xffffffff initially */ +uint32_t crc32(const uint8_t *data, uint32_t length, uint32_t crc) +{ + for (uint32_t i = 0; i < length; ++i) { + crc ^= data[i]; + crc = crc32tab[crc & 0x0f] ^ (crc >> 4); + crc = crc32tab[crc & 0x0f] ^ (crc >> 4); + } + + // return value suitable for passing in next time, for final value invert it + return crc/* ^ 0xffffffff*/; +} diff --git a/embed/extmod/modtrezorcrypto/crc.h b/embed/extmod/modtrezorcrypto/crc.h new file mode 100644 index 00000000..113c898a --- /dev/null +++ b/embed/extmod/modtrezorcrypto/crc.h @@ -0,0 +1,15 @@ +/* + * Copyright (c) Pavol Rusnak, SatoshiLabs + * + * Licensed under TREZOR License + * see LICENSE file for details + */ + +#ifndef __CRC_H__ +#define __CRC_H__ + +#include + +uint32_t crc32(const uint8_t *data, uint32_t length, uint32_t crc); + +#endif diff --git a/embed/extmod/modtrezorcrypto/modtrezorcrypto-crc.h b/embed/extmod/modtrezorcrypto/modtrezorcrypto-crc.h new file mode 100644 index 00000000..1159b158 --- /dev/null +++ b/embed/extmod/modtrezorcrypto/modtrezorcrypto-crc.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) Pavol Rusnak, SatoshiLabs + * + * Licensed under TREZOR License + * see LICENSE file for details + */ + +#include "py/objstr.h" +#include "crc.h" + +mp_obj_t mod_trezorcrypto_crc_crc32(size_t n_args, const mp_obj_t *args) { + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(args[0], &bufinfo, MP_BUFFER_READ); + uint32_t crc = (n_args > 1) ? mp_obj_get_int_truncated(args[1]) : 0; + crc = crc32(bufinfo.buf, bufinfo.len, crc ^ 0xffffffff); + return mp_obj_new_int_from_uint(crc ^ 0xffffffff); +} +MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorcrypto_crc_crc32_obj, 1, 2, mod_trezorcrypto_crc_crc32); + +STATIC const mp_rom_map_elem_t mod_trezorcrypto_crc_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_crc) }, + { MP_ROM_QSTR(MP_QSTR_crc32), MP_ROM_PTR(&mod_trezorcrypto_crc_crc32_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(mod_trezorcrypto_crc_globals, mod_trezorcrypto_crc_globals_table); + +STATIC const mp_obj_module_t mod_trezorcrypto_crc_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&mod_trezorcrypto_crc_globals, +}; diff --git a/embed/extmod/modtrezorcrypto/modtrezorcrypto.c b/embed/extmod/modtrezorcrypto/modtrezorcrypto.c index c1fcb241..959e6210 100644 --- a/embed/extmod/modtrezorcrypto/modtrezorcrypto.c +++ b/embed/extmod/modtrezorcrypto/modtrezorcrypto.c @@ -19,13 +19,14 @@ #include "modtrezorcrypto-blake256.h" #include "modtrezorcrypto-blake2b.h" #include "modtrezorcrypto-blake2s.h" +#include "modtrezorcrypto-crc.h" #include "modtrezorcrypto-curve25519.h" #include "modtrezorcrypto-ed25519.h" +#include "modtrezorcrypto-nist256p1.h" #include "modtrezorcrypto-pbkdf2.h" #include "modtrezorcrypto-random.h" #include "modtrezorcrypto-rfc6979.h" #include "modtrezorcrypto-ripemd160.h" -#include "modtrezorcrypto-nist256p1.h" #include "modtrezorcrypto-secp256k1.h" #include "modtrezorcrypto-sha1.h" #include "modtrezorcrypto-sha256.h" @@ -37,24 +38,25 @@ 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_AES), MP_ROM_PTR(&mod_trezorcrypto_AES_type) }, + { MP_ROM_QSTR(MP_QSTR_bip32), MP_ROM_PTR(&mod_trezorcrypto_bip32_module) }, + { MP_ROM_QSTR(MP_QSTR_bip39), MP_ROM_PTR(&mod_trezorcrypto_bip39_module) }, { MP_ROM_QSTR(MP_QSTR_blake256), MP_ROM_PTR(&mod_trezorcrypto_Blake256_type) }, { MP_ROM_QSTR(MP_QSTR_blake2b), MP_ROM_PTR(&mod_trezorcrypto_Blake2b_type) }, { MP_ROM_QSTR(MP_QSTR_blake2s), MP_ROM_PTR(&mod_trezorcrypto_Blake2s_type) }, + { MP_ROM_QSTR(MP_QSTR_crc), MP_ROM_PTR(&mod_trezorcrypto_crc_module) }, + { MP_ROM_QSTR(MP_QSTR_curve25519), MP_ROM_PTR(&mod_trezorcrypto_curve25519_module) }, + { MP_ROM_QSTR(MP_QSTR_ed25519), MP_ROM_PTR(&mod_trezorcrypto_ed25519_module) }, + { MP_ROM_QSTR(MP_QSTR_nist256p1), MP_ROM_PTR(&mod_trezorcrypto_nist256p1_module) }, { MP_ROM_QSTR(MP_QSTR_pbkdf2), MP_ROM_PTR(&mod_trezorcrypto_Pbkdf2_type) }, + { MP_ROM_QSTR(MP_QSTR_random), MP_ROM_PTR(&mod_trezorcrypto_random_module) }, { MP_ROM_QSTR(MP_QSTR_rfc6979), MP_ROM_PTR(&mod_trezorcrypto_Rfc6979_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_module) }, { MP_ROM_QSTR(MP_QSTR_sha1), MP_ROM_PTR(&mod_trezorcrypto_Sha1_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_bip32), MP_ROM_PTR(&mod_trezorcrypto_bip32_module) }, - { MP_ROM_QSTR(MP_QSTR_bip39), MP_ROM_PTR(&mod_trezorcrypto_bip39_module) }, - { MP_ROM_QSTR(MP_QSTR_curve25519), MP_ROM_PTR(&mod_trezorcrypto_curve25519_module) }, - { MP_ROM_QSTR(MP_QSTR_ed25519), MP_ROM_PTR(&mod_trezorcrypto_ed25519_module) }, - { MP_ROM_QSTR(MP_QSTR_nist256p1), MP_ROM_PTR(&mod_trezorcrypto_nist256p1_module) }, - { MP_ROM_QSTR(MP_QSTR_random), MP_ROM_PTR(&mod_trezorcrypto_random_module) }, - { MP_ROM_QSTR(MP_QSTR_secp256k1), MP_ROM_PTR(&mod_trezorcrypto_secp256k1_module) }, { MP_ROM_QSTR(MP_QSTR_ssss), MP_ROM_PTR(&mod_trezorcrypto_ssss_module) }, }; STATIC MP_DEFINE_CONST_DICT(mp_module_trezorcrypto_globals, mp_module_trezorcrypto_globals_table); diff --git a/embed/firmware/mpconfigport.h b/embed/firmware/mpconfigport.h index e6f125f8..19ef5cd4 100644 --- a/embed/firmware/mpconfigport.h +++ b/embed/firmware/mpconfigport.h @@ -117,13 +117,13 @@ // extended modules #define MICROPY_PY_UCTYPES (1) -#define MICROPY_PY_UZLIB (1) +#define MICROPY_PY_UZLIB (0) #define MICROPY_PY_UJSON (0) #define MICROPY_PY_URE (0) #define MICROPY_PY_UHEAPQ (0) #define MICROPY_PY_UHASHLIB (0) #define MICROPY_PY_UBINASCII (1) -#define MICROPY_PY_UBINASCII_CRC32 (1) +#define MICROPY_PY_UBINASCII_CRC32 (0) #define MICROPY_PY_URANDOM (0) #define MICROPY_PY_URANDOM_EXTRA_FUNCS (0) #define MICROPY_PY_USELECT (0) diff --git a/embed/unix/mpconfigport.h b/embed/unix/mpconfigport.h index 995cca39..71720b63 100644 --- a/embed/unix/mpconfigport.h +++ b/embed/unix/mpconfigport.h @@ -114,7 +114,7 @@ #define MICROPY_PY_UTIME_MP_HAL (1) #define MICROPY_PY_UERRNO (0) #define MICROPY_PY_UCTYPES (1) -#define MICROPY_PY_UZLIB (1) +#define MICROPY_PY_UZLIB (0) #define MICROPY_PY_UJSON (0) #define MICROPY_PY_URE (0) #define MICROPY_PY_UHEAPQ (0) @@ -124,7 +124,7 @@ #define MICROPY_PY_UHASHLIB_SHA1 (0) #endif #define MICROPY_PY_UBINASCII (1) -#define MICROPY_PY_UBINASCII_CRC32 (1) +#define MICROPY_PY_UBINASCII_CRC32 (0) #define MICROPY_PY_URANDOM (0) #ifndef MICROPY_PY_USELECT_POSIX #define MICROPY_PY_USELECT_POSIX (0) diff --git a/src/trezor/crypto/__init__.py b/src/trezor/crypto/__init__.py index be6b0aa0..87a7e5e8 100644 --- a/src/trezor/crypto/__init__.py +++ b/src/trezor/crypto/__init__.py @@ -1,5 +1,6 @@ from trezorcrypto import bip32 from trezorcrypto import bip39 +from trezorcrypto import crc from trezorcrypto import pbkdf2 from trezorcrypto import random from trezorcrypto import rfc6979 diff --git a/tests/.gitignore b/tests/.gitignore new file mode 100644 index 00000000..ceddaa37 --- /dev/null +++ b/tests/.gitignore @@ -0,0 +1 @@ +.cache/ diff --git a/tests/test_trezor.crypto.crc.py b/tests/test_trezor.crypto.crc.py new file mode 100644 index 00000000..01abcd89 --- /dev/null +++ b/tests/test_trezor.crypto.crc.py @@ -0,0 +1,23 @@ +from common import * + +from trezor.crypto import crc +from ubinascii import unhexlify + + +class TestCryptoCrc(unittest.TestCase): + + vectors_crc32 = [ + ('123456789', 0xCBF43926), + (unhexlify('0000000000000000000000000000000000000000000000000000000000000000'), 0x190A55AD), + (unhexlify('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF'), 0xFF6CAB0B), + (unhexlify('000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F'), 0x91267E8A), + ('The quick brown fox jumps over the lazy dog', 0x414FA339), + ] + + def test_crc32(self): + for i, o in self.vectors_crc32: + self.assertEqual(crc.crc32(i), o) + + +if __name__ == '__main__': + unittest.main()