diff --git a/core/SConscript.firmware b/core/SConscript.firmware index 88f486d70b..39df3241ca 100644 --- a/core/SConscript.firmware +++ b/core/SConscript.firmware @@ -63,6 +63,7 @@ SOURCE_MOD += [ 'vendor/trezor-crypto/chacha20poly1305/chacha_merged.c', 'vendor/trezor-crypto/chacha20poly1305/poly1305-donna.c', 'vendor/trezor-crypto/chacha20poly1305/rfc7539.c', + 'vendor/trezor-crypto/chacha_drbg.c', 'vendor/trezor-crypto/curves.c', 'vendor/trezor-crypto/ecdsa.c', 'vendor/trezor-crypto/ed25519-donna/curve25519-donna-32bit.c', diff --git a/core/SConscript.unix b/core/SConscript.unix index 549244d770..377aba3613 100644 --- a/core/SConscript.unix +++ b/core/SConscript.unix @@ -63,6 +63,7 @@ SOURCE_MOD += [ 'vendor/trezor-crypto/chacha20poly1305/chacha_merged.c', 'vendor/trezor-crypto/chacha20poly1305/poly1305-donna.c', 'vendor/trezor-crypto/chacha20poly1305/rfc7539.c', + 'vendor/trezor-crypto/chacha_drbg.c', 'vendor/trezor-crypto/ed25519-donna/curve25519-donna-32bit.c', 'vendor/trezor-crypto/ed25519-donna/curve25519-donna-helpers.c', 'vendor/trezor-crypto/ed25519-donna/curve25519-donna-scalarmult-base.c', diff --git a/crypto/chacha_drbg.c b/crypto/chacha_drbg.c new file mode 100644 index 0000000000..4f90ad5fa7 --- /dev/null +++ b/crypto/chacha_drbg.c @@ -0,0 +1,62 @@ +/* + * This file is part of the Trezor project, https://trezor.io/ + * + * Copyright (c) SatoshiLabs + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "chacha_drbg.h" + +#include + +#define MAX(a, b) (a) > (b) ? (a) : (b) + +void chacha_drbg_init(CHACHA_DRBG_CTX *ctx, + const uint8_t entropy[CHACHA_DRBG_SEED_LENGTH]) { + uint8_t buffer[MAX(CHACHA_DRBG_KEY_LENGTH, CHACHA_DRBG_IV_LENGTH)] = {0}; + ECRYPT_keysetup(&ctx->chacha_ctx, buffer, CHACHA_DRBG_KEY_LENGTH * 8, + CHACHA_DRBG_IV_LENGTH * 8); + ECRYPT_ivsetup(&ctx->chacha_ctx, buffer); + + chacha_drbg_reseed(ctx, entropy); +} + +static void chacha_drbg_update(CHACHA_DRBG_CTX *ctx, + const uint8_t data[CHACHA_DRBG_SEED_LENGTH]) { + uint8_t buffer[CHACHA_DRBG_SEED_LENGTH] = {0}; + + if (data) + ECRYPT_encrypt_bytes(&ctx->chacha_ctx, data, buffer, + CHACHA_DRBG_SEED_LENGTH); + else + ECRYPT_keystream_bytes(&ctx->chacha_ctx, buffer, CHACHA_DRBG_SEED_LENGTH); + + ECRYPT_keysetup(&ctx->chacha_ctx, buffer, CHACHA_DRBG_KEY_LENGTH * 8, + CHACHA_DRBG_IV_LENGTH * 8); + ECRYPT_ivsetup(&ctx->chacha_ctx, buffer + CHACHA_DRBG_KEY_LENGTH); +} + +void chacha_drbg_generate(CHACHA_DRBG_CTX *ctx, uint8_t *output, + uint8_t output_length) { + ECRYPT_keystream_bytes(&ctx->chacha_ctx, output, output_length); + chacha_drbg_update(ctx, NULL); + ctx->reseed_counter++; +} + +void chacha_drbg_reseed(CHACHA_DRBG_CTX *ctx, + const uint8_t entropy[CHACHA_DRBG_SEED_LENGTH]) { + chacha_drbg_update(ctx, entropy); + ctx->reseed_counter = 1; +} diff --git a/crypto/chacha_drbg.h b/crypto/chacha_drbg.h new file mode 100644 index 0000000000..0f8979eaf6 --- /dev/null +++ b/crypto/chacha_drbg.h @@ -0,0 +1,43 @@ +/* + * This file is part of the Trezor project, https://trezor.io/ + * + * Copyright (c) SatoshiLabs + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __CHACHA_DRBG__ +#define __CHACHA_DRBG__ + +#include "chacha20poly1305/chacha20poly1305.h" + +// Very fast deterministic random bit generator inspired by CTR_DRBG in NIST SP +// 800-90A + +#define CHACHA_DRBG_KEY_LENGTH 16 +#define CHACHA_DRBG_IV_LENGTH 8 +#define CHACHA_DRBG_SEED_LENGTH (CHACHA_DRBG_KEY_LENGTH + CHACHA_DRBG_IV_LENGTH) + +typedef struct _CHACHA_DRBG_CTX { + ECRYPT_ctx chacha_ctx; + uint32_t reseed_counter; +} CHACHA_DRBG_CTX; + +void chacha_drbg_init(CHACHA_DRBG_CTX *ctx, + const uint8_t entropy[CHACHA_DRBG_SEED_LENGTH]); +void chacha_drbg_reseed(CHACHA_DRBG_CTX *ctx, + const uint8_t entropy[CHACHA_DRBG_SEED_LENGTH]); +void chacha_drbg_generate(CHACHA_DRBG_CTX *ctx, uint8_t *output, + uint8_t output_length); +#endif // __CHACHA_DRBG__