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__