summaryrefslogtreecommitdiff
path: root/chip/g
diff options
context:
space:
mode:
authorMarius Schilder <mschilder@google.com>2017-06-19 18:40:12 -0700
committerMarius Schilder <mschilder@chromium.org>2017-07-06 21:53:35 +0000
commitbdd39d51a30a43516f1712b01c66cad26b37826f (patch)
tree92ec5a8cb0059bca477b2bb1fc8a06d3c9e8f037 /chip/g
parentde7e54c302a570e6bb99881836fc3bafe80acdbe (diff)
downloadchrome-ec-bdd39d51a30a43516f1712b01c66cad26b37826f.tar.gz
g: RSA randomization
Split bn_modexp() into three variants: bn_modexp() for large exponents (as before) bn_modexp_word() for single word public exponents bn_modexp_blinded() for large exponents w/ randomization We randomize bn_modexp_blinded() with: 1) pick 64 bit random R1 and compute R1 ** -1 and R1 ** pubexp, mod N. 2) multiply input by R1 ** pubexp 3) pick 64 bit random R2 and add (e*d*R2 - R2) to private exponent (i.e. a random multiple of phi(N)) 4) exponentiate 5) multiply output w/ R1 ** -1 to obtain expected result Since we enlarge the exponent, bn_modexp_blinded() is slower than bn_modexp(). We only use bn_modexp_blinded() when private exponents are in play and we have phi(N) available. Also refactored the combined p256 and rsa dcrypto binary blob into two parts. And added unique first word to each dcrypto blob to make code caching reliable. The TPM task stack maxes out at 8040/8192 in tcg_test due to increased stack usage of bn_modexp_blinded() but is still within safe bounds, with 88 byte redzone. BRANCH=cr50 BUG=b:35587382,b:35587381 TEST=buildall, tcg_test (200+) Change-Id: Ied1f908418f31f8025363179537aa4ebd2c80420 Reviewed-on: https://chromium-review.googlesource.com/540684 Reviewed-by: Marius Schilder <mschilder@chromium.org> Reviewed-by: Vadim Bendebury <vbendeb@chromium.org> Tested-by: Marius Schilder <mschilder@chromium.org>
Diffstat (limited to 'chip/g')
-rw-r--r--chip/g/build.mk3
-rw-r--r--chip/g/dcrypto/bn.c69
-rw-r--r--chip/g/dcrypto/bn_hw.c1371
-rw-r--r--chip/g/dcrypto/dcrypto_bn.c733
-rw-r--r--chip/g/dcrypto/dcrypto_p256.c941
-rw-r--r--chip/g/dcrypto/dcrypto_sha512.c840
-rw-r--r--chip/g/dcrypto/internal.h45
-rw-r--r--chip/g/dcrypto/rsa.c29
8 files changed, 2203 insertions, 1828 deletions
diff --git a/chip/g/build.mk b/chip/g/build.mk
index 692d4ec320..c13cccecad 100644
--- a/chip/g/build.mk
+++ b/chip/g/build.mk
@@ -36,7 +36,8 @@ chip-$(CONFIG_DCRYPTO)+= dcrypto/aes.o
chip-$(CONFIG_DCRYPTO)+= dcrypto/app_cipher.o
chip-$(CONFIG_DCRYPTO)+= dcrypto/app_key.o
chip-$(CONFIG_DCRYPTO)+= dcrypto/bn.o
-chip-$(CONFIG_DCRYPTO)+= dcrypto/bn_hw.o
+chip-$(CONFIG_DCRYPTO)+= dcrypto/dcrypto_bn.o
+chip-$(CONFIG_DCRYPTO)+= dcrypto/dcrypto_p256.o
chip-$(CONFIG_DCRYPTO)+= dcrypto/compare.o
chip-$(CONFIG_DCRYPTO)+= dcrypto/dcrypto_runtime.o
chip-$(CONFIG_DCRYPTO)+= dcrypto/gcm.o
diff --git a/chip/g/dcrypto/bn.c b/chip/g/dcrypto/bn.c
index b44280c2e0..0b100402f5 100644
--- a/chip/g/dcrypto/bn.c
+++ b/chip/g/dcrypto/bn.c
@@ -326,11 +326,12 @@ static uint32_t bn_compute_nprime(const uint32_t n0)
return ~ninv + 1; /* Two's complement. */
}
-/* Montgomery output = input ^ exp % N. */
/* TODO(ngm): this implementation not timing or side-channel safe by
* any measure. */
-void bn_mont_modexp(struct LITE_BIGNUM *output, const struct LITE_BIGNUM *input,
- const struct LITE_BIGNUM *exp, const struct LITE_BIGNUM *N)
+static void bn_modexp_internal(struct LITE_BIGNUM *output,
+ const struct LITE_BIGNUM *input,
+ const struct LITE_BIGNUM *exp,
+ const struct LITE_BIGNUM *N)
{
int i;
uint32_t nprime;
@@ -342,14 +343,6 @@ void bn_mont_modexp(struct LITE_BIGNUM *output, const struct LITE_BIGNUM *input,
struct LITE_BIGNUM acc;
struct LITE_BIGNUM aR;
-#ifndef CR50_NO_BN_ASM
- if ((bn_bits(N) & 255) == 0) {
- /* Use hardware support for standard key sizes. */
- bn_mont_modexp_asm(output, input, exp, N);
- return;
- }
-#endif
-
bn_init(&RR, RR_buf, bn_size(N));
bn_init(&acc, acc_buf, bn_size(N));
bn_init(&aR, aR_buf, bn_size(N));
@@ -394,6 +387,56 @@ void bn_mont_modexp(struct LITE_BIGNUM *output, const struct LITE_BIGNUM *input,
always_memset(aR_buf, 0, sizeof(aR_buf));
}
+/* output = input ^ exp % N */
+int bn_modexp(struct LITE_BIGNUM *output, const struct LITE_BIGNUM *input,
+ const struct LITE_BIGNUM *exp, const struct LITE_BIGNUM *N)
+{
+#ifndef CR50_NO_BN_ASM
+ if ((bn_bits(N) & 255) == 0) {
+ /* Use hardware support for standard key sizes. */
+ return dcrypto_modexp(output, input, exp, N);
+ }
+#endif
+ bn_modexp_internal(output, input, exp, N);
+ return 1;
+}
+
+/* output = input ^ exp % N */
+int bn_modexp_word(struct LITE_BIGNUM *output, const struct LITE_BIGNUM *input,
+ uint32_t exp, const struct LITE_BIGNUM *N)
+{
+#ifndef CR50_NO_BN_ASM
+ if ((bn_bits(N) & 255) == 0) {
+ /* Use hardware support for standard key sizes. */
+ return dcrypto_modexp_word(output, input, exp, N);
+ }
+#endif
+ {
+ struct LITE_BIGNUM pubexp;
+
+ DCRYPTO_bn_wrap(&pubexp, &exp, sizeof(exp));
+ bn_modexp_internal(output, input, &pubexp, N);
+ return 1;
+ }
+}
+
+/* output = input ^ exp % N */
+int bn_modexp_blinded(struct LITE_BIGNUM *output,
+ const struct LITE_BIGNUM *input,
+ const struct LITE_BIGNUM *exp,
+ const struct LITE_BIGNUM *N,
+ uint32_t pubexp)
+{
+#ifndef CR50_NO_BN_ASM
+ if ((bn_bits(N) & 255) == 0) {
+ /* Use hardware support for standard key sizes. */
+ return dcrypto_modexp_blinded(output, input, exp, N, pubexp);
+ }
+#endif
+ bn_modexp_internal(output, input, exp, N);
+ return 1;
+}
+
/* c[] += a * b[] */
static uint32_t bn_mul_add(struct LITE_BIGNUM *c, uint32_t a,
const struct LITE_BIGNUM *b, uint32_t offset)
@@ -1136,7 +1179,7 @@ static int bn_probable_prime(const struct LITE_BIGNUM *p)
}
/* y = a ^ r mod p */
- bn_mont_modexp(&y, &A, &r, p);
+ bn_modexp(&y, &A, &r, p);
if (bn_eq(&y, &ONE))
continue;
bn_add(&y, &ONE);
@@ -1147,7 +1190,7 @@ static int bn_probable_prime(const struct LITE_BIGNUM *p)
/* y = y ^ 2 mod p */
for (i = 0; i < s - 1; i++) {
bn_copy(&A, &y);
- bn_mont_modexp(&y, &A, &TWO, p);
+ bn_modexp(&y, &A, &TWO, p);
if (bn_eq(&y, &ONE))
return 0;
diff --git a/chip/g/dcrypto/bn_hw.c b/chip/g/dcrypto/bn_hw.c
deleted file mode 100644
index 5e5ca2dab8..0000000000
--- a/chip/g/dcrypto/bn_hw.c
+++ /dev/null
@@ -1,1371 +0,0 @@
-/* Copyright 2016 The Chromium OS Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-#include "dcrypto.h"
-#include "internal.h"
-#include "registers.h"
-#include "trng.h"
-
-/* Firmware blob for crypto accelerator */
-
-/* AUTO-GENERATED. DO NOT MODIFY. */
-const uint32_t IMEM_dcrypto[] = {
-/* @0x0: function vectors[15] { */
-#define CF_vectors_adr 0
-0x10080010, /* b p256init */
-0x1008000f, /* b __notused */
-0x1008004f, /* b p256isoncurve */
-0x10080237, /* b p256scalarmult */
-0x100801a8, /* b p256scalarbasemult */
-0x10080181, /* b p256sign */
-0x100801e2, /* b p256verify */
-0x1008000f, /* b __notused */
-0x1008000f, /* b __notused */
-0x1008000f, /* b __notused */
-0x10080323, /* b modexp */
-0x100802fe, /* b mul1 */
-0x100802cd, /* b mulx */
-0x1008034d, /* b modload */
-0x0c000000, /* ret */
-/* } */
-/* @0xf: function __notused[1] { */
-#define CF___notused_adr 15
-0x0c000000, /* ret */
-/* } */
-/* @0x10: function p256init[25] { */
-#define CF_p256init_adr 16
-0xfc000000, /* nop */
-0x4c7fff00, /* xor r31, r31, r31 */
-0x4c7bde00, /* xor r30, r30, r30 */
-0x80780001, /* movi r30.0l, #1 */
-0x847421c0, /* ldci r29, [#14] */
-0x847021e0, /* ldci r28, [#15] */
-0x98801d00, /* ldmod r29 */
-0x7c6c1f00, /* mov r27, r31 */
-0x83ed5ac6, /* movi r27.7h, #23238 */
-0x83ec35d8, /* movi r27.7l, #13784 */
-0x836daa3a, /* movi r27.6h, #43578 */
-0x836c93e7, /* movi r27.6l, #37863 */
-0x82edb3eb, /* movi r27.5h, #46059 */
-0x82ecbd55, /* movi r27.5l, #48469 */
-0x826d7698, /* movi r27.4h, #30360 */
-0x826c86bc, /* movi r27.4l, #34492 */
-0x81ed651d, /* movi r27.3h, #25885 */
-0x81ec06b0, /* movi r27.3l, #1712 */
-0x816dcc53, /* movi r27.2h, #52307 */
-0x816cb0f6, /* movi r27.2l, #45302 */
-0x80ed3bce, /* movi r27.1h, #15310 */
-0x80ec3c3e, /* movi r27.1l, #15422 */
-0x806d27d2, /* movi r27.0h, #10194 */
-0x806c604b, /* movi r27.0l, #24651 */
-0x0c000000, /* ret */
-/* } */
-/* @0x29: function MulMod[38] { */
-#define CF_MulMod_adr 41
-0x584f3800, /* mul128 r19, r24l, r25l */
-0x59d33800, /* mul128 r20, r24u, r25u */
-0x58d73800, /* mul128 r21, r24u, r25l */
-0x504eb310, /* add r19, r19, r21 << 128 */
-0x50d2b490, /* addc r20, r20, r21 >> 128 */
-0x59573800, /* mul128 r21, r24l, r25u */
-0x504eb310, /* add r19, r19, r21 << 128 */
-0x50d2b490, /* addc r20, r20, r21 >> 128 */
-0x645bfc02, /* selm r22, r28, r31 */
-0x685693ff, /* rshi r21, r19, r20 >> 255 */
-0x585f9500, /* mul128 r23, r21l, r28l */
-0x59e39500, /* mul128 r24, r21u, r28u */
-0x58e79500, /* mul128 r25, r21u, r28l */
-0x505f3710, /* add r23, r23, r25 << 128 */
-0x50e33890, /* addc r24, r24, r25 >> 128 */
-0x59679500, /* mul128 r25, r21l, r28u */
-0x505f3710, /* add r23, r23, r25 << 128 */
-0x50e33890, /* addc r24, r24, r25 >> 128 */
-0x6867f4ff, /* rshi r25, r20, r31 >> 255 */
-0x5062b800, /* add r24, r24, r21 */
-0x50e7f900, /* addc r25, r25, r31 */
-0x5062d800, /* add r24, r24, r22 */
-0x50e7f900, /* addc r25, r25, r31 */
-0x68573801, /* rshi r21, r24, r25 >> 1 */
-0x585abd00, /* mul128 r22, r29l, r21l */
-0x59debd00, /* mul128 r23, r29u, r21u */
-0x58e2bd00, /* mul128 r24, r29u, r21l */
-0x505b1610, /* add r22, r22, r24 << 128 */
-0x50df1790, /* addc r23, r23, r24 >> 128 */
-0x5962bd00, /* mul128 r24, r29l, r21u */
-0x505b1610, /* add r22, r22, r24 << 128 */
-0x50df1790, /* addc r23, r23, r24 >> 128 */
-0x545ad300, /* sub r22, r19, r22 */
-0x54d2f400, /* subb r20, r20, r23 */
-0x6457fd01, /* sell r21, r29, r31 */
-0x5456b600, /* sub r21, r22, r21 */
-0x9c4ff500, /* addm r19, r21, r31 */
-0x0c000000, /* ret */
-/* } */
-/* @0x4f: function p256isoncurve[24] { */
-#define CF_p256isoncurve_adr 79
-0x84004000, /* ldi r0, [#0] */
-0x95800000, /* lddmp r0 */
-0x82800018, /* movi r0.5l, #24 */
-0x83000018, /* movi r0.6l, #24 */
-0x80000000, /* movi r0.0l, #0 */
-0x97800000, /* ldrfp r0 */
-0x8c181600, /* ld *6, *6 */
-0x7c641800, /* mov r25, r24 */
-0x08000029, /* call &MulMod */
-0x7c001300, /* mov r0, r19 */
-0x8c141500, /* ld *5, *5 */
-0x7c641800, /* mov r25, r24 */
-0x08000029, /* call &MulMod */
-0x8c141500, /* ld *5, *5 */
-0x7c641300, /* mov r25, r19 */
-0x08000029, /* call &MulMod */
-0x8c141500, /* ld *5, *5 */
-0xa04f1300, /* subm r19, r19, r24 */
-0xa04f1300, /* subm r19, r19, r24 */
-0xa04f1300, /* subm r19, r19, r24 */
-0x9c637300, /* addm r24, r19, r27 */
-0x904c0500, /* st *5, *3 */
-0x90500000, /* st *0, *4 */
-0x0c000000, /* ret */
-/* } */
-/* @0x67: function ProjAdd[80] { */
-#define CF_ProjAdd_adr 103
-0x7c600b00, /* mov r24, r11 */
-0x7c640800, /* mov r25, r8 */
-0x08000029, /* call &MulMod */
-0x7c381300, /* mov r14, r19 */
-0x7c600c00, /* mov r24, r12 */
-0x7c640900, /* mov r25, r9 */
-0x08000029, /* call &MulMod */
-0x7c3c1300, /* mov r15, r19 */
-0x7c600d00, /* mov r24, r13 */
-0x7c640a00, /* mov r25, r10 */
-0x08000029, /* call &MulMod */
-0x7c401300, /* mov r16, r19 */
-0x9c458b00, /* addm r17, r11, r12 */
-0x9c492800, /* addm r18, r8, r9 */
-0x7c601100, /* mov r24, r17 */
-0x7c641200, /* mov r25, r18 */
-0x08000029, /* call &MulMod */
-0x9c49ee00, /* addm r18, r14, r15 */
-0xa0465300, /* subm r17, r19, r18 */
-0x9c49ac00, /* addm r18, r12, r13 */
-0x9c4d4900, /* addm r19, r9, r10 */
-0x7c601200, /* mov r24, r18 */
-0x7c641300, /* mov r25, r19 */
-0x08000029, /* call &MulMod */
-0x7c481300, /* mov r18, r19 */
-0x9c4e0f00, /* addm r19, r15, r16 */
-0xa04a7200, /* subm r18, r18, r19 */
-0x9c4dab00, /* addm r19, r11, r13 */
-0x9c314800, /* addm r12, r8, r10 */
-0x7c601300, /* mov r24, r19 */
-0x7c640c00, /* mov r25, r12 */
-0x08000029, /* call &MulMod */
-0x7c2c1300, /* mov r11, r19 */
-0x9c320e00, /* addm r12, r14, r16 */
-0xa0318b00, /* subm r12, r11, r12 */
-0x7c601b00, /* mov r24, r27 */
-0x7c641000, /* mov r25, r16 */
-0x08000029, /* call &MulMod */
-0xa02e6c00, /* subm r11, r12, r19 */
-0x9c356b00, /* addm r13, r11, r11 */
-0x9c2dab00, /* addm r11, r11, r13 */
-0xa0356f00, /* subm r13, r15, r11 */
-0x9c2d6f00, /* addm r11, r15, r11 */
-0x7c601b00, /* mov r24, r27 */
-0x7c640c00, /* mov r25, r12 */
-0x08000029, /* call &MulMod */
-0x9c3e1000, /* addm r15, r16, r16 */
-0x9c420f00, /* addm r16, r15, r16 */
-0xa0321300, /* subm r12, r19, r16 */
-0xa031cc00, /* subm r12, r12, r14 */
-0x9c3d8c00, /* addm r15, r12, r12 */
-0x9c318f00, /* addm r12, r15, r12 */
-0x9c3dce00, /* addm r15, r14, r14 */
-0x9c39cf00, /* addm r14, r15, r14 */
-0xa03a0e00, /* subm r14, r14, r16 */
-0x7c601200, /* mov r24, r18 */
-0x7c640c00, /* mov r25, r12 */
-0x08000029, /* call &MulMod */
-0x7c3c1300, /* mov r15, r19 */
-0x7c600e00, /* mov r24, r14 */
-0x7c640c00, /* mov r25, r12 */
-0x08000029, /* call &MulMod */
-0x7c401300, /* mov r16, r19 */
-0x7c600b00, /* mov r24, r11 */
-0x7c640d00, /* mov r25, r13 */
-0x08000029, /* call &MulMod */
-0x9c321300, /* addm r12, r19, r16 */
-0x7c601100, /* mov r24, r17 */
-0x7c640b00, /* mov r25, r11 */
-0x08000029, /* call &MulMod */
-0xa02df300, /* subm r11, r19, r15 */
-0x7c601200, /* mov r24, r18 */
-0x7c640d00, /* mov r25, r13 */
-0x08000029, /* call &MulMod */
-0x7c341300, /* mov r13, r19 */
-0x7c601100, /* mov r24, r17 */
-0x7c640e00, /* mov r25, r14 */
-0x08000029, /* call &MulMod */
-0x9c366d00, /* addm r13, r13, r19 */
-0x0c000000, /* ret */
-/* } */
-/* @0xb7: function ProjToAffine[116] { */
-#define CF_ProjToAffine_adr 183
-0x9c2bea00, /* addm r10, r10, r31 */
-0x7c600a00, /* mov r24, r10 */
-0x7c640a00, /* mov r25, r10 */
-0x08000029, /* call &MulMod */
-0x7c601300, /* mov r24, r19 */
-0x7c640a00, /* mov r25, r10 */
-0x08000029, /* call &MulMod */
-0x7c301300, /* mov r12, r19 */
-0x7c601300, /* mov r24, r19 */
-0x7c641300, /* mov r25, r19 */
-0x08000029, /* call &MulMod */
-0x7c601300, /* mov r24, r19 */
-0x7c641300, /* mov r25, r19 */
-0x08000029, /* call &MulMod */
-0x7c601300, /* mov r24, r19 */
-0x7c640c00, /* mov r25, r12 */
-0x08000029, /* call &MulMod */
-0x7c341300, /* mov r13, r19 */
-0x05004004, /* loop #4 ( */
-0x7c601300, /* mov r24, r19 */
-0x7c641300, /* mov r25, r19 */
-0x08000029, /* call &MulMod */
-0xfc000000, /* nop */
-/* ) */
-0x7c601300, /* mov r24, r19 */
-0x7c640d00, /* mov r25, r13 */
-0x08000029, /* call &MulMod */
-0x7c381300, /* mov r14, r19 */
-0x05008004, /* loop #8 ( */
-0x7c601300, /* mov r24, r19 */
-0x7c641300, /* mov r25, r19 */
-0x08000029, /* call &MulMod */
-0xfc000000, /* nop */
-/* ) */
-0x7c601300, /* mov r24, r19 */
-0x7c640e00, /* mov r25, r14 */
-0x08000029, /* call &MulMod */
-0x7c3c1300, /* mov r15, r19 */
-0x05010004, /* loop #16 ( */
-0x7c601300, /* mov r24, r19 */
-0x7c641300, /* mov r25, r19 */
-0x08000029, /* call &MulMod */
-0xfc000000, /* nop */
-/* ) */
-0x7c601300, /* mov r24, r19 */
-0x7c640f00, /* mov r25, r15 */
-0x08000029, /* call &MulMod */
-0x7c401300, /* mov r16, r19 */
-0x05020004, /* loop #32 ( */
-0x7c601300, /* mov r24, r19 */
-0x7c641300, /* mov r25, r19 */
-0x08000029, /* call &MulMod */
-0xfc000000, /* nop */
-/* ) */
-0x7c441300, /* mov r17, r19 */
-0x7c600a00, /* mov r24, r10 */
-0x7c641300, /* mov r25, r19 */
-0x08000029, /* call &MulMod */
-0x050c0004, /* loop #192 ( */
-0x7c601300, /* mov r24, r19 */
-0x7c641300, /* mov r25, r19 */
-0x08000029, /* call &MulMod */
-0xfc000000, /* nop */
-/* ) */
-0x7c481300, /* mov r18, r19 */
-0x7c601100, /* mov r24, r17 */
-0x7c641000, /* mov r25, r16 */
-0x08000029, /* call &MulMod */
-0x05010004, /* loop #16 ( */
-0x7c601300, /* mov r24, r19 */
-0x7c641300, /* mov r25, r19 */
-0x08000029, /* call &MulMod */
-0xfc000000, /* nop */
-/* ) */
-0x7c600f00, /* mov r24, r15 */
-0x7c641300, /* mov r25, r19 */
-0x08000029, /* call &MulMod */
-0x05008004, /* loop #8 ( */
-0x7c601300, /* mov r24, r19 */
-0x7c641300, /* mov r25, r19 */
-0x08000029, /* call &MulMod */
-0xfc000000, /* nop */
-/* ) */
-0x7c600e00, /* mov r24, r14 */
-0x7c641300, /* mov r25, r19 */
-0x08000029, /* call &MulMod */
-0x05004004, /* loop #4 ( */
-0x7c601300, /* mov r24, r19 */
-0x7c641300, /* mov r25, r19 */
-0x08000029, /* call &MulMod */
-0xfc000000, /* nop */
-/* ) */
-0x7c600d00, /* mov r24, r13 */
-0x7c641300, /* mov r25, r19 */
-0x08000029, /* call &MulMod */
-0x05002004, /* loop #2 ( */
-0x7c601300, /* mov r24, r19 */
-0x7c641300, /* mov r25, r19 */
-0x08000029, /* call &MulMod */
-0xfc000000, /* nop */
-/* ) */
-0x7c600c00, /* mov r24, r12 */
-0x7c641300, /* mov r25, r19 */
-0x08000029, /* call &MulMod */
-0x05002004, /* loop #2 ( */
-0x7c601300, /* mov r24, r19 */
-0x7c641300, /* mov r25, r19 */
-0x08000029, /* call &MulMod */
-0xfc000000, /* nop */
-/* ) */
-0x7c600a00, /* mov r24, r10 */
-0x7c641300, /* mov r25, r19 */
-0x08000029, /* call &MulMod */
-0x7c601300, /* mov r24, r19 */
-0x7c641200, /* mov r25, r18 */
-0x08000029, /* call &MulMod */
-0x7c381300, /* mov r14, r19 */
-0x7c600800, /* mov r24, r8 */
-0x7c640e00, /* mov r25, r14 */
-0x08000029, /* call &MulMod */
-0x7c2c1300, /* mov r11, r19 */
-0x7c600900, /* mov r24, r9 */
-0x7c640e00, /* mov r25, r14 */
-0x08000029, /* call &MulMod */
-0x7c301300, /* mov r12, r19 */
-0x0c000000, /* ret */
-/* } */
-/* @0x12b: function ModInv[17] { */
-#define CF_ModInv_adr 299
-0x98080000, /* stmod r2 */
-0x55080202, /* subi r2, r2, #2 */
-0x7c041e00, /* mov r1, r30 */
-0x0510000c, /* loop #256 ( */
-0x7c600100, /* mov r24, r1 */
-0x7c640100, /* mov r25, r1 */
-0x08000029, /* call &MulMod */
-0x7c0c1300, /* mov r3, r19 */
-0x50084200, /* add r2, r2, r2 */
-0x64046108, /* selc r1, r1, r3 */
-0x1008813a, /* bnc nomul */
-0x7c600300, /* mov r24, r3 */
-0x7c640000, /* mov r25, r0 */
-0x08000029, /* call &MulMod */
-0x7c041300, /* mov r1, r19 */
-/*nomul: */
-0xfc000000, /* nop */
-/* ) */
-0x0c000000, /* ret */
-/* } */
-/* @0x13c: function FetchBandRandomize[11] { */
-#define CF_FetchBandRandomize_adr 316
-0x99080000, /* strnd r2 */
-0x9c6be200, /* addm r26, r2, r31 */
-0x8c081500, /* ld *2, *5 */
-0x7c641a00, /* mov r25, r26 */
-0x08000029, /* call &MulMod */
-0x7c181300, /* mov r6, r19 */
-0x8c081600, /* ld *2, *6 */
-0x7c641a00, /* mov r25, r26 */
-0x08000029, /* call &MulMod */
-0x7c1c1300, /* mov r7, r19 */
-0x0c000000, /* ret */
-/* } */
-/* @0x147: function ProjDouble[5] { */
-#define CF_ProjDouble_adr 327
-0x7c2c0800, /* mov r11, r8 */
-0x7c300900, /* mov r12, r9 */
-0x7c340a00, /* mov r13, r10 */
-0x08000067, /* call &ProjAdd */
-0x0c000000, /* ret */
-/* } */
-/* @0x14c: function ScalarMult_internal[53] { */
-#define CF_ScalarMult_internal_adr 332
-0x84742200, /* ldci r29, [#16] */
-0x98801d00, /* ldmod r29 */
-0x8c041100, /* ld *1, *1 */
-0x9c07e100, /* addm r1, r1, r31 */
-0xa0002000, /* subm r0, r0, r1 */
-0x847421c0, /* ldci r29, [#14] */
-0x98801d00, /* ldmod r29 */
-0x0800013c, /* call &FetchBandRandomize */
-0x7c200600, /* mov r8, r6 */
-0x7c240700, /* mov r9, r7 */
-0x7c281a00, /* mov r10, r26 */
-0x08000147, /* call &ProjDouble */
-0x7c0c0b00, /* mov r3, r11 */
-0x7c100c00, /* mov r4, r12 */
-0x7c140d00, /* mov r5, r13 */
-0x7c201f00, /* mov r8, r31 */
-0x7c241e00, /* mov r9, r30 */
-0x7c281f00, /* mov r10, r31 */
-0x05100020, /* loop #256 ( */
-0x08000147, /* call &ProjDouble */
-0x0800013c, /* call &FetchBandRandomize */
-0x4c202000, /* xor r8, r0, r1 */
-0x64206602, /* selm r8, r6, r3 */
-0x64248702, /* selm r9, r7, r4 */
-0x6428ba02, /* selm r10, r26, r5 */
-0x7c080b00, /* mov r2, r11 */
-0x7c180c00, /* mov r6, r12 */
-0x7c1c0d00, /* mov r7, r13 */
-0x08000067, /* call &ProjAdd */
-0x44202000, /* or r8, r0, r1 */
-0x64204b02, /* selm r8, r11, r2 */
-0x6424cc02, /* selm r9, r12, r6 */
-0x6428ed02, /* selm r10, r13, r7 */
-0x680000ff, /* rshi r0, r0, r0 >> 255 */
-0x680421ff, /* rshi r1, r1, r1 >> 255 */
-0x992c0000, /* strnd r11 */
-0x99300000, /* strnd r12 */
-0x99340000, /* strnd r13 */
-0x99080000, /* strnd r2 */
-0x7c600300, /* mov r24, r3 */
-0x7c640200, /* mov r25, r2 */
-0x08000029, /* call &MulMod */
-0x7c0c1300, /* mov r3, r19 */
-0x7c600400, /* mov r24, r4 */
-0x7c640200, /* mov r25, r2 */
-0x08000029, /* call &MulMod */
-0x7c101300, /* mov r4, r19 */
-0x7c600500, /* mov r24, r5 */
-0x7c640200, /* mov r25, r2 */
-0x08000029, /* call &MulMod */
-0x7c141300, /* mov r5, r19 */
-/* ) */
-0x080000b7, /* call &ProjToAffine */
-0x0c000000, /* ret */
-/* } */
-/* @0x181: function p256sign[39] { */
-#define CF_p256sign_adr 385
-0xfc000000, /* nop */
-0x84004000, /* ldi r0, [#0] */
-0x95800000, /* lddmp r0 */
-0x80000000, /* movi r0.0l, #0 */
-0x80800001, /* movi r0.1l, #1 */
-0x81000018, /* movi r0.2l, #24 */
-0x97800000, /* ldrfp r0 */
-0x84002300, /* ldci r0, [#24] */
-0x90540000, /* st *0, *5 */
-0xfc000000, /* nop */
-0x84002320, /* ldci r0, [#25] */
-0x90580000, /* st *0, *6 */
-0xfc000000, /* nop */
-0x8c001000, /* ld *0, *0 */
-0x0800014c, /* call &ScalarMult_internal */
-0x84742200, /* ldci r29, [#16] */
-0x84702220, /* ldci r28, [#17] */
-0x98801d00, /* ldmod r29 */
-0x8c001000, /* ld *0, *0 */
-0x0800012b, /* call &ModInv */
-0x8c081700, /* ld *2, *7 */
-0x7c640100, /* mov r25, r1 */
-0x08000029, /* call &MulMod */
-0x9c63eb00, /* addm r24, r11, r31 */
-0x904c0200, /* st *2, *3 */
-0xfc000000, /* nop */
-0x7c641300, /* mov r25, r19 */
-0x08000029, /* call &MulMod */
-0x7c001300, /* mov r0, r19 */
-0x8c081200, /* ld *2, *2 */
-0x7c640100, /* mov r25, r1 */
-0x08000029, /* call &MulMod */
-0x9c001300, /* addm r0, r19, r0 */
-0x90500000, /* st *0, *4 */
-0xfc000000, /* nop */
-0x847421c0, /* ldci r29, [#14] */
-0x847021e0, /* ldci r28, [#15] */
-0x98801d00, /* ldmod r29 */
-0x0c000000, /* ret */
-/* } */
-/* @0x1a8: function p256scalarbasemult[21] { */
-#define CF_p256scalarbasemult_adr 424
-0xfc000000, /* nop */
-0x84004000, /* ldi r0, [#0] */
-0x95800000, /* lddmp r0 */
-0x80000000, /* movi r0.0l, #0 */
-0x80800001, /* movi r0.1l, #1 */
-0x81000018, /* movi r0.2l, #24 */
-0x8180000b, /* movi r0.3l, #11 */
-0x97800000, /* ldrfp r0 */
-0x8c001100, /* ld *0, *1 */
-0x99800000, /* ldrnd r0 */
-0x84002300, /* ldci r0, [#24] */
-0x90540000, /* st *0, *5 */
-0xfc000000, /* nop */
-0x84002320, /* ldci r0, [#25] */
-0x90580000, /* st *0, *6 */
-0xfc000000, /* nop */
-0x8c001700, /* ld *0, *7 */
-0x0800014c, /* call &ScalarMult_internal */
-0x90540b00, /* st *3++, *5 */
-0x90580b00, /* st *3++, *6 */
-0x0c000000, /* ret */
-/* } */
-/* @0x1bd: function ModInvVar[37] { */
-#define CF_ModInvVar_adr 445
-0x7c081f00, /* mov r2, r31 */
-0x7c0c1e00, /* mov r3, r30 */
-0x98100000, /* stmod r4 */
-0x981c0000, /* stmod r7 */
-0x7c140000, /* mov r5, r0 */
-/*impvt_Loop: */
-0x44108400, /* or r4, r4, r4 */
-0x100011cd, /* bl impvt_Uodd */
-0x6813e401, /* rshi r4, r4, r31 >> 1 */
-0x44084200, /* or r2, r2, r2 */
-0x100011c9, /* bl impvt_Rodd */
-0x680be201, /* rshi r2, r2, r31 >> 1 */
-0x100801c2, /* b impvt_Loop */
-/*impvt_Rodd: */
-0x50084700, /* add r2, r7, r2 */
-0x509bff00, /* addc r6, r31, r31 */
-0x6808c201, /* rshi r2, r2, r6 >> 1 */
-0x100801c2, /* b impvt_Loop */
-/*impvt_Uodd: */
-0x4414a500, /* or r5, r5, r5 */
-0x100011d8, /* bl impvt_UVodd */
-0x6817e501, /* rshi r5, r5, r31 >> 1 */
-0x440c6300, /* or r3, r3, r3 */
-0x100011d4, /* bl impvt_Sodd */
-0x680fe301, /* rshi r3, r3, r31 >> 1 */
-0x100801c2, /* b impvt_Loop */
-/*impvt_Sodd: */
-0x500c6700, /* add r3, r7, r3 */
-0x509bff00, /* addc r6, r31, r31 */
-0x680cc301, /* rshi r3, r3, r6 >> 1 */
-0x100801c2, /* b impvt_Loop */
-/*impvt_UVodd: */
-0x5c008500, /* cmp r5, r4 */
-0x100881dd, /* bnc impvt_V>=U */
-0xa0086200, /* subm r2, r2, r3 */
-0x5410a400, /* sub r4, r4, r5 */
-0x100801c2, /* b impvt_Loop */
-/*impvt_V>=U: */
-0xa00c4300, /* subm r3, r3, r2 */
-0x54148500, /* sub r5, r5, r4 */
-0x100841c2, /* bnz impvt_Loop */
-0x9c07e200, /* addm r1, r2, r31 */
-0x0c000000, /* ret */
-/* } */
-/* @0x1e2: function p256verify[85] { */
-#define CF_p256verify_adr 482
-0x84184000, /* ldi r6, [#0] */
-0x95800600, /* lddmp r6 */
-0x81980018, /* movi r6.3l, #24 */
-0x82180000, /* movi r6.4l, #0 */
-0x82980008, /* movi r6.5l, #8 */
-0x83180009, /* movi r6.6l, #9 */
-0x81180018, /* movi r6.2l, #24 */
-0x97800600, /* ldrfp r6 */
-0x8c0c1300, /* ld *3, *3 */
-0x8c101400, /* ld *4, *4 */
-0x7c600600, /* mov r24, r6 */
-0x48630000, /* not r24, r24 */
-0x84742200, /* ldci r29, [#16] */
-0x84702220, /* ldci r28, [#17] */
-0x98801d00, /* ldmod r29 */
-0x5c03e000, /* cmp r0, r31 */
-0x10004235, /* bz fail */
-0x5c03a000, /* cmp r0, r29 */
-0x10088235, /* bnc fail */
-0x5c03e600, /* cmp r6, r31 */
-0x10004235, /* bz fail */
-0x5c03a600, /* cmp r6, r29 */
-0x10088235, /* bnc fail */
-0x8c0c1300, /* ld *3, *3 */
-0x080001bd, /* call &ModInvVar */
-0x7c640100, /* mov r25, r1 */
-0x08000029, /* call &MulMod */
-0x7c001300, /* mov r0, r19 */
-0x8c081200, /* ld *2, *2 */
-0x7c640100, /* mov r25, r1 */
-0x08000029, /* call &MulMod */
-0x7c041300, /* mov r1, r19 */
-0x847421c0, /* ldci r29, [#14] */
-0x847021e0, /* ldci r28, [#15] */
-0x98801d00, /* ldmod r29 */
-0x8c141500, /* ld *5, *5 */
-0x8c181600, /* ld *6, *6 */
-0x7c281e00, /* mov r10, r30 */
-0x842c2300, /* ldci r11, [#24] */
-0x84302320, /* ldci r12, [#25] */
-0x7c341e00, /* mov r13, r30 */
-0x08000067, /* call &ProjAdd */
-0x7c0c0b00, /* mov r3, r11 */
-0x7c100c00, /* mov r4, r12 */
-0x7c140d00, /* mov r5, r13 */
-0x40082000, /* and r2, r0, r1 */
-0x7c2c1f00, /* mov r11, r31 */
-0x7c301e00, /* mov r12, r30 */
-0x7c341f00, /* mov r13, r31 */
-0x05100019, /* loop #256 ( */
-0x7c200b00, /* mov r8, r11 */
-0x7c240c00, /* mov r9, r12 */
-0x7c280d00, /* mov r10, r13 */
-0x08000067, /* call &ProjAdd */
-0x50084200, /* add r2, r2, r2 */
-0x1008821f, /* bnc noBoth */
-0x7c200300, /* mov r8, r3 */
-0x7c240400, /* mov r9, r4 */
-0x7c280500, /* mov r10, r5 */
-0x08000067, /* call &ProjAdd */
-0x1008022b, /* b noY */
-/*noBoth: */
-0x50180000, /* add r6, r0, r0 */
-0x10088225, /* bnc noG */
-0x8c141500, /* ld *5, *5 */
-0x8c181600, /* ld *6, *6 */
-0x7c281e00, /* mov r10, r30 */
-0x08000067, /* call &ProjAdd */
-/*noG: */
-0x50182100, /* add r6, r1, r1 */
-0x1008822b, /* bnc noY */
-0x84202300, /* ldci r8, [#24] */
-0x84242320, /* ldci r9, [#25] */
-0x7c281e00, /* mov r10, r30 */
-0x08000067, /* call &ProjAdd */
-/*noY: */
-0x50000000, /* add r0, r0, r0 */
-0x50042100, /* add r1, r1, r1 */
-/* ) */
-0x7c000d00, /* mov r0, r13 */
-0x080001bd, /* call &ModInvVar */
-0x7c600100, /* mov r24, r1 */
-0x7c640b00, /* mov r25, r11 */
-0x08000029, /* call &MulMod */
-0x84742200, /* ldci r29, [#16] */
-0x98801d00, /* ldmod r29 */
-0xa063f300, /* subm r24, r19, r31 */
-/*fail: */
-0x90440300, /* st *3, *1 */
-0x0c000000, /* ret */
-/* } */
-/* @0x237: function p256scalarmult[12] { */
-#define CF_p256scalarmult_adr 567
-0x84004000, /* ldi r0, [#0] */
-0x95800000, /* lddmp r0 */
-0x80000000, /* movi r0.0l, #0 */
-0x80800001, /* movi r0.1l, #1 */
-0x81000018, /* movi r0.2l, #24 */
-0x8180000b, /* movi r0.3l, #11 */
-0x97800000, /* ldrfp r0 */
-0x8c001000, /* ld *0, *0 */
-0x0800014c, /* call &ScalarMult_internal */
-0x90540b00, /* st *3++, *5 */
-0x90580b00, /* st *3++, *6 */
-0x0c000000, /* ret */
-/* } */
-/* @0x243: function d0inv[14] { */
-#define CF_d0inv_adr 579
-0x4c000000, /* xor r0, r0, r0 */
-0x80000001, /* movi r0.0l, #1 */
-0x7c740000, /* mov r29, r0 */
-0x05100008, /* loop #256 ( */
-0x5807bc00, /* mul128 r1, r28l, r29l */
-0x588bbc00, /* mul128 r2, r28u, r29l */
-0x50044110, /* add r1, r1, r2 << 128 */
-0x590bbc00, /* mul128 r2, r28l, r29u */
-0x50044110, /* add r1, r1, r2 << 128 */
-0x40040100, /* and r1, r1, r0 */
-0x44743d00, /* or r29, r29, r1 */
-0x50000000, /* add r0, r0, r0 */
-/* ) */
-0x5477bf00, /* sub r29, r31, r29 */
-0x0c000000, /* ret */
-/* } */
-/* @0x251: function selcxSub[10] { */
-#define CF_selcxSub_adr 593
-0x97800100, /* ldrfp r1 */
-0x95800000, /* lddmp r0 */
-0x540c6300, /* sub r3, r3, r3 */
-0x0600c005, /* loop *6 ( */
-0x8c081800, /* ld *2, *0++ */
-0x7c8c0000, /* ldr *3, *0 */
-0x54906200, /* subb r4, r2, r3 */
-0x66084408, /* selcx r2, r4, r2 */
-0x7ca00300, /* ldr *0++, *3 */
-/* ) */
-0x0c000000, /* ret */
-/* } */
-/* @0x25b: function computeRR[40] { */
-#define CF_computeRR_adr 603
-0x4c7fff00, /* xor r31, r31, r31 */
-0x84004000, /* ldi r0, [#0] */
-0x95800000, /* lddmp r0 */
-0x840c20c0, /* ldci r3, [#6] */
-0x40040398, /* and r1, r3, r0 >> 192 */
-0x480c6000, /* not r3, r3 */
-0x400c0300, /* and r3, r3, r0 */
-0x500c2301, /* add r3, r3, r1 << 8 */
-0x94800300, /* ldlc r3 */
-0x80040005, /* movi r1.0l, #5 */
-0x81040003, /* movi r1.2l, #3 */
-0x81840002, /* movi r1.3l, #2 */
-0x82040004, /* movi r1.4l, #4 */
-0x97800100, /* ldrfp r1 */
-0x4c0c6300, /* xor r3, r3, r3 */
-0x0600c001, /* loop *6 ( */
-0x7ca00200, /* ldr *0++, *2 */
-/* ) */
-0x560c1f00, /* subx r3, r31, r0 */
-0x08000251, /* call &selcxSub */
-0x06000010, /* loop *0 ( */
-0x97800100, /* ldrfp r1 */
-0x560c6300, /* subx r3, r3, r3 */
-0x0600c003, /* loop *6 ( */
-0x7c8c0000, /* ldr *3, *0 */
-0x52884200, /* addcx r2, r2, r2 */
-0x7ca00300, /* ldr *0++, *3 */
-/* ) */
-0x08000251, /* call &selcxSub */
-0x97800100, /* ldrfp r1 */
-0x95800000, /* lddmp r0 */
-0x560c6300, /* subx r3, r3, r3 */
-0x0600c003, /* loop *6 ( */
-0x8c081800, /* ld *2, *0++ */
-0x7c8c0800, /* ldr *3, *0++ */
-0x5e804300, /* cmpbx r3, r2 */
-/* ) */
-0x08000251, /* call &selcxSub */
-0xfc000000, /* nop */
-/* ) */
-0x97800100, /* ldrfp r1 */
-0x0600c001, /* loop *6 ( */
-0x90680800, /* st *0++, *2++ */
-/* ) */
-0x0c000000, /* ret */
-/* } */
-/* @0x283: function dmXd0[9] { */
-#define CF_dmXd0_adr 643
-0x586f3e00, /* mul128 r27, r30l, r25l */
-0x59eb3e00, /* mul128 r26, r30u, r25u */
-0x58df3e00, /* mul128 r23, r30u, r25l */
-0x506efb10, /* add r27, r27, r23 << 128 */
-0x50eafa90, /* addc r26, r26, r23 >> 128 */
-0x595f3e00, /* mul128 r23, r30l, r25u */
-0x506efb10, /* add r27, r27, r23 << 128 */
-0x50eafa90, /* addc r26, r26, r23 >> 128 */
-0x0c000000, /* ret */
-/* } */
-/* @0x28c: function dmXa[9] { */
-#define CF_dmXa_adr 652
-0x586c5e00, /* mul128 r27, r30l, r2l */
-0x59e85e00, /* mul128 r26, r30u, r2u */
-0x58dc5e00, /* mul128 r23, r30u, r2l */
-0x506efb10, /* add r27, r27, r23 << 128 */
-0x50eafa90, /* addc r26, r26, r23 >> 128 */
-0x595c5e00, /* mul128 r23, r30l, r2u */
-0x506efb10, /* add r27, r27, r23 << 128 */
-0x50eafa90, /* addc r26, r26, r23 >> 128 */
-0x0c000000, /* ret */
-/* } */
-/* @0x295: function mma[46] { */
-#define CF_mma_adr 661
-0x8204001e, /* movi r1.4l, #30 */
-0x82840018, /* movi r1.5l, #24 */
-0x97800100, /* ldrfp r1 */
-0x8c101b00, /* ld *4, *3++ */
-0x0800028c, /* call &dmXa */
-0x7c940800, /* ldr *5, *0++ */
-0x507b1b00, /* add r30, r27, r24 */
-0x50f7fa00, /* addc r29, r26, r31 */
-0x7c640300, /* mov r25, r3 */
-0x08000283, /* call &dmXd0 */
-0x7c641b00, /* mov r25, r27 */
-0x7c701a00, /* mov r28, r26 */
-0x7c601e00, /* mov r24, r30 */
-0x8c101800, /* ld *4, *0++ */
-0x08000283, /* call &dmXd0 */
-0x506f1b00, /* add r27, r27, r24 */
-0x50f3fa00, /* addc r28, r26, r31 */
-0x0600e00e, /* loop *7 ( */
-0x8c101b00, /* ld *4, *3++ */
-0x0800028c, /* call &dmXa */
-0x7c940800, /* ldr *5, *0++ */
-0x506f1b00, /* add r27, r27, r24 */
-0x50ebfa00, /* addc r26, r26, r31 */
-0x5063bb00, /* add r24, r27, r29 */
-0x50f7fa00, /* addc r29, r26, r31 */
-0x8c101800, /* ld *4, *0++ */
-0x08000283, /* call &dmXd0 */
-0x506f1b00, /* add r27, r27, r24 */
-0x50ebfa00, /* addc r26, r26, r31 */
-0x52639b00, /* addx r24, r27, r28 */
-0x7ca80500, /* ldr *2++, *5 */
-0x52f3fa00, /* addcx r28, r26, r31 */
-/* ) */
-0x52e39d00, /* addcx r24, r29, r28 */
-0x7ca80500, /* ldr *2++, *5 */
-0x95800000, /* lddmp r0 */
-0x97800100, /* ldrfp r1 */
-0x54739c00, /* sub r28, r28, r28 */
-0x0600c007, /* loop *6 ( */
-0x8c141800, /* ld *5, *0++ */
-0x7c900000, /* ldr *4, *0 */
-0x54f71e00, /* subb r29, r30, r24 */
-0x99600000, /* strnd r24 */
-0x7c800500, /* ldr *0, *5 */
-0x6663dd08, /* selcx r24, r29, r30 */
-0x7ca00500, /* ldr *0++, *5 */
-/* ) */
-0x0c000000, /* ret */
-/* } */
-/* @0x2c3: function setupPtrs[10] { */
-#define CF_setupPtrs_adr 707
-0x4c7fff00, /* xor r31, r31, r31 */
-0x95800000, /* lddmp r0 */
-0x94800000, /* ldlc r0 */
-0x4c042100, /* xor r1, r1, r1 */
-0x80040004, /* movi r1.0l, #4 */
-0x80840003, /* movi r1.1l, #3 */
-0x81040004, /* movi r1.2l, #4 */
-0x81840002, /* movi r1.3l, #2 */
-0x97800100, /* ldrfp r1 */
-0x0c000000, /* ret */
-/* } */
-/* @0x2cd: function mulx[19] { */
-#define CF_mulx_adr 717
-0x84004000, /* ldi r0, [#0] */
-0x080002c3, /* call &setupPtrs */
-0x8c041100, /* ld *1, *1 */
-0x4c084200, /* xor r2, r2, r2 */
-0x0600c001, /* loop *6 ( */
-0x7ca80300, /* ldr *2++, *3 */
-/* ) */
-0x97800100, /* ldrfp r1 */
-0x0600c004, /* loop *6 ( */
-0x8c0c1c00, /* ld *3, *4++ */
-0x95000000, /* stdmp r0 */
-0x08000295, /* call &mma */
-0x95800000, /* lddmp r0 */
-/* ) */
-0x97800100, /* ldrfp r1 */
-0x95800000, /* lddmp r0 */
-0x0600c001, /* loop *6 ( */
-0x90740800, /* st *0++, *5++ */
-/* ) */
-0x97800100, /* ldrfp r1 */
-0x95800000, /* lddmp r0 */
-0x0c000000, /* ret */
-/* } */
-/* @0x2e0: function mul1_exp[30] { */
-#define CF_mul1_exp_adr 736
-0x8c041100, /* ld *1, *1 */
-0x4c084200, /* xor r2, r2, r2 */
-0x0600c001, /* loop *6 ( */
-0x7ca80300, /* ldr *2++, *3 */
-/* ) */
-0x97800100, /* ldrfp r1 */
-0x80080001, /* movi r2.0l, #1 */
-0x0600c003, /* loop *6 ( */
-0x95800000, /* lddmp r0 */
-0x08000295, /* call &mma */
-0x4c084200, /* xor r2, r2, r2 */
-/* ) */
-0x97800100, /* ldrfp r1 */
-0x95800000, /* lddmp r0 */
-0x56084200, /* subx r2, r2, r2 */
-0x0600c003, /* loop *6 ( */
-0x8c041800, /* ld *1, *0++ */
-0x7c8c0800, /* ldr *3, *0++ */
-0x5e804300, /* cmpbx r3, r2 */
-/* ) */
-0x97800100, /* ldrfp r1 */
-0x95800000, /* lddmp r0 */
-0x540c6300, /* sub r3, r3, r3 */
-0x0600c006, /* loop *6 ( */
-0x8c041800, /* ld *1, *0++ */
-0x7c8c0800, /* ldr *3, *0++ */
-0x548c6200, /* subb r3, r2, r3 */
-0x66084308, /* selcx r2, r3, r2 */
-0x90740300, /* st *3, *5++ */
-0xfc000000, /* nop */
-/* ) */
-0x97800100, /* ldrfp r1 */
-0x95800000, /* lddmp r0 */
-0x0c000000, /* ret */
-/* } */
-/* @0x2fe: function mul1[4] { */
-#define CF_mul1_adr 766
-0x84004000, /* ldi r0, [#0] */
-0x080002c3, /* call &setupPtrs */
-0x080002e0, /* call &mul1_exp */
-0x0c000000, /* ret */
-/* } */
-/* @0x302: function sqrx_exp[19] { */
-#define CF_sqrx_exp_adr 770
-0x84004020, /* ldi r0, [#1] */
-0x95800000, /* lddmp r0 */
-0x8c041100, /* ld *1, *1 */
-0x4c084200, /* xor r2, r2, r2 */
-0x0600c001, /* loop *6 ( */
-0x7ca80300, /* ldr *2++, *3 */
-/* ) */
-0x97800100, /* ldrfp r1 */
-0x0600c004, /* loop *6 ( */
-0x8c0c1c00, /* ld *3, *4++ */
-0x95000000, /* stdmp r0 */
-0x08000295, /* call &mma */
-0x95800000, /* lddmp r0 */
-/* ) */
-0x97800100, /* ldrfp r1 */
-0x95800000, /* lddmp r0 */
-0x0600c001, /* loop *6 ( */
-0x90740800, /* st *0++, *5++ */
-/* ) */
-0x97800100, /* ldrfp r1 */
-0x95800000, /* lddmp r0 */
-0x0c000000, /* ret */
-/* } */
-/* @0x315: function mulx_exp[14] { */
-#define CF_mulx_exp_adr 789
-0x84004040, /* ldi r0, [#2] */
-0x95800000, /* lddmp r0 */
-0x8c041100, /* ld *1, *1 */
-0x4c084200, /* xor r2, r2, r2 */
-0x0600c001, /* loop *6 ( */
-0x7ca80300, /* ldr *2++, *3 */
-/* ) */
-0x97800100, /* ldrfp r1 */
-0x0600c004, /* loop *6 ( */
-0x8c0c1c00, /* ld *3, *4++ */
-0x95000000, /* stdmp r0 */
-0x08000295, /* call &mma */
-0x95800000, /* lddmp r0 */
-/* ) */
-0x97800100, /* ldrfp r1 */
-0x0c000000, /* ret */
-/* } */
-/* @0x323: function modexp[42] { */
-#define CF_modexp_adr 803
-0x080002cd, /* call &mulx */
-0x84004060, /* ldi r0, [#3] */
-0x95800000, /* lddmp r0 */
-0x54084200, /* sub r2, r2, r2 */
-0x0600c004, /* loop *6 ( */
-0xfc000000, /* nop */
-0x8c0c1800, /* ld *3, *0++ */
-0x54885f00, /* subb r2, r31, r2 */
-0x90740300, /* st *3, *5++ */
-/* ) */
-0xfc000000, /* nop */
-0x840820c0, /* ldci r2, [#6] */
-0x400c0298, /* and r3, r2, r0 >> 192 */
-0x48084000, /* not r2, r2 */
-0x40080200, /* and r2, r2, r0 */
-0x50086201, /* add r2, r2, r3 << 8 */
-0x94800200, /* ldlc r2 */
-0x06000015, /* loop *0 ( */
-0x08000302, /* call &sqrx_exp */
-0x08000315, /* call &mulx_exp */
-0x84004060, /* ldi r0, [#3] */
-0x95800000, /* lddmp r0 */
-0x99080000, /* strnd r2 */
-0x54084200, /* sub r2, r2, r2 */
-0x0600c004, /* loop *6 ( */
-0x99080000, /* strnd r2 */
-0x8c0c1400, /* ld *3, *4 */
-0x50884200, /* addc r2, r2, r2 */
-0x90700300, /* st *3, *4++ */
-/* ) */
-0x0600c008, /* loop *6 ( */
-0x99080000, /* strnd r2 */
-0x8c041500, /* ld *1, *5 */
-0x90540300, /* st *3, *5 */
-0x7c8c0800, /* ldr *3, *0++ */
-0x7c000200, /* mov r0, r2 */
-0x99080000, /* strnd r2 */
-0x64086008, /* selc r2, r0, r3 */
-0x90740300, /* st *3, *5++ */
-/* ) */
-0xfc000000, /* nop */
-/* ) */
-0x84004060, /* ldi r0, [#3] */
-0x95800000, /* lddmp r0 */
-0x080002e0, /* call &mul1_exp */
-0x0c000000, /* ret */
-/* } */
-/* @0x34d: function modload[12] { */
-#define CF_modload_adr 845
-0x4c7fff00, /* xor r31, r31, r31 */
-0x84004000, /* ldi r0, [#0] */
-0x95800000, /* lddmp r0 */
-0x94800000, /* ldlc r0 */
-0x8000001c, /* movi r0.0l, #28 */
-0x8080001d, /* movi r0.1l, #29 */
-0x97800000, /* ldrfp r0 */
-0x8c001000, /* ld *0, *0 */
-0x08000243, /* call &d0inv */
-0x90440100, /* st *1, *1 */
-0x0800025b, /* call &computeRR */
-0x0c000000, /* ret */
-/* } */
-};
-
-struct DMEM_montmul_ptrs {
- uint32_t pMod;
- uint32_t pDinv;
- uint32_t pRR;
- uint32_t pA;
- uint32_t pB;
- uint32_t pC;
- uint32_t n;
- uint32_t n1;
-};
-
-/*
- * This struct is "calling convention" for passing parameters into the
- * code block above for RSA operations. Parameters start at &DMEM[0].
- */
-struct DMEM_montmul {
- struct DMEM_montmul_ptrs in_ptrs;
- struct DMEM_montmul_ptrs sqr_ptrs;
- struct DMEM_montmul_ptrs mul_ptrs;
- struct DMEM_montmul_ptrs out_ptrs;
- uint32_t mod[RSA_WORDS_4K];
- uint32_t dInv[8];
- uint32_t RR[RSA_WORDS_4K];
- uint32_t in[RSA_WORDS_4K];
- uint32_t exp[RSA_WORDS_4K];
- uint32_t out[RSA_WORDS_4K];
-};
-
-#define DMEM_CELL_SIZE 32
-#define DMEM_INDEX(p, f) \
- (((const uint8_t *)&(p)->f - (const uint8_t *)(p)) / DMEM_CELL_SIZE)
-
-/* output = input ** exp % N. */
-/* TODO(ngm): add blinding; measure timing. */
-/* TODO(ngm): propagate return code. */
-void bn_mont_modexp_asm(struct LITE_BIGNUM *output,
- const struct LITE_BIGNUM *input,
- const struct LITE_BIGNUM *exp,
- const struct LITE_BIGNUM *N) {
- int i, result;
- struct DMEM_montmul *montmul;
-
- /* Initialize hardware; load code page. */
- dcrypto_init_and_lock();
- dcrypto_imem_load(0, IMEM_dcrypto, ARRAY_SIZE(IMEM_dcrypto));
-
- /* Point to DMEM. */
- montmul = (struct DMEM_montmul *)GREG32_ADDR(CRYPTO, DMEM_DUMMY);
-
- /* Setup DMEM pointers (as indices into DMEM which 256-bit cells). */
- montmul->in_ptrs.pMod = DMEM_INDEX(montmul, mod);
- montmul->in_ptrs.pDinv = DMEM_INDEX(montmul, dInv);
- montmul->in_ptrs.pRR = DMEM_INDEX(montmul, RR);
- montmul->in_ptrs.pA = DMEM_INDEX(montmul, in);
- montmul->in_ptrs.pB = DMEM_INDEX(montmul, exp);
- montmul->in_ptrs.pC = DMEM_INDEX(montmul, out);
- montmul->in_ptrs.n = bn_bits(N) / (DMEM_CELL_SIZE * 8);
- montmul->in_ptrs.n1 = montmul->in_ptrs.n - 1;
-
- montmul->sqr_ptrs = montmul->in_ptrs;
- montmul->mul_ptrs = montmul->in_ptrs;
- montmul->out_ptrs = montmul->in_ptrs;
-
- dcrypto_dmem_load(DMEM_INDEX(montmul, mod), N->d, bn_words(N));
- dcrypto_dmem_load(DMEM_INDEX(montmul, in), input->d, bn_words(input));
- dcrypto_dmem_load(DMEM_INDEX(montmul, exp), exp->d, bn_words(exp));
-
- /* 0 pad the exponent to full size. */
- for (i = bn_words(exp); i < bn_words(N); ++i)
- montmul->exp[i] = 0;
-
- /* Calculate RR and d0inv. */
- result = dcrypto_call(CF_modload_adr);
-
- if (bn_words(exp) > 1) {
- /* in = in * RR */
- montmul->in_ptrs.pA = DMEM_INDEX(montmul, in);
- montmul->in_ptrs.pB = DMEM_INDEX(montmul, RR);
- montmul->in_ptrs.pC = DMEM_INDEX(montmul, in);
-
- /* out = out * out */
- montmul->sqr_ptrs.pA = DMEM_INDEX(montmul, out);
- montmul->sqr_ptrs.pB = DMEM_INDEX(montmul, out);
- montmul->sqr_ptrs.pC = DMEM_INDEX(montmul, out);
-
- /* out = out * in */
- montmul->mul_ptrs.pA = DMEM_INDEX(montmul, in);
- montmul->mul_ptrs.pB = DMEM_INDEX(montmul, out);
- montmul->mul_ptrs.pC = DMEM_INDEX(montmul, out);
-
- /* out = out / R */
- montmul->out_ptrs.pA = DMEM_INDEX(montmul, out);
- montmul->out_ptrs.pB = DMEM_INDEX(montmul, exp);
- montmul->out_ptrs.pC = DMEM_INDEX(montmul, out);
-
- result |= dcrypto_call(CF_modexp_adr);
- } else {
- /* Small public exponent */
- uint32_t e = BN_DIGIT(exp, 0);
- uint32_t b = 0x80000000;
-
- while (b != 0 && !(b & e))
- b >>= 1;
-
- /* out = in * RR */
- montmul->in_ptrs.pA = DMEM_INDEX(montmul, in);
- montmul->in_ptrs.pB = DMEM_INDEX(montmul, RR);
- montmul->in_ptrs.pC = DMEM_INDEX(montmul, out);
- result |= dcrypto_call(CF_mulx_adr);
-
- /* in = in * RR */
- montmul->in_ptrs.pC = DMEM_INDEX(montmul, in);
- result |= dcrypto_call(CF_mulx_adr);
-
- b >>= 1;
-
- while (b != 0) {
- /* out = out * out */
- montmul->in_ptrs.pA = DMEM_INDEX(montmul, out);
- montmul->in_ptrs.pB = DMEM_INDEX(montmul, out);
- montmul->in_ptrs.pC = DMEM_INDEX(montmul, out);
- result |= dcrypto_call(CF_mulx_adr);
-
- if ((b & e) != 0) {
- /* out = out * in */
- montmul->in_ptrs.pA = DMEM_INDEX(montmul, in);
- montmul->in_ptrs.pB = DMEM_INDEX(montmul, out);
- montmul->in_ptrs.pC = DMEM_INDEX(montmul, out);
- result |= dcrypto_call(CF_mulx_adr);
- }
-
- b >>= 1;
- }
- /* out = out / R */
- montmul->in_ptrs.pA = DMEM_INDEX(montmul, out);
- montmul->in_ptrs.pB = DMEM_INDEX(montmul, out);
- montmul->in_ptrs.pC = DMEM_INDEX(montmul, out);
- result |= dcrypto_call(CF_mul1_adr);
- }
-
- memcpy(output->d, montmul->out, bn_size(output));
-
- (void) (result == 0); /* end of errorcode propagation */
-
- dcrypto_unlock();
-}
-
-/*
- * This struct is "calling convention" for passing parameters into the
- * code block above for ecc operations. Parameters start at &DMEM[0].
- */
-struct DMEM_ecc {
- uint32_t pK;
- uint32_t pRnd;
- uint32_t pMsg;
- uint32_t pR;
- uint32_t pS;
- uint32_t pX;
- uint32_t pY;
- uint32_t pD;
- p256_int k;
- p256_int rnd;
- p256_int msg;
- p256_int r;
- p256_int s;
- p256_int x;
- p256_int y;
- p256_int d;
-};
-
-static void dcrypto_ecc_init(void)
-{
- struct DMEM_ecc *pEcc =
- (struct DMEM_ecc *)GREG32_ADDR(CRYPTO, DMEM_DUMMY);
-
- dcrypto_imem_load(0, IMEM_dcrypto, ARRAY_SIZE(IMEM_dcrypto));
-
- pEcc->pK = DMEM_INDEX(pEcc, k);
- pEcc->pRnd = DMEM_INDEX(pEcc, rnd);
- pEcc->pMsg = DMEM_INDEX(pEcc, msg);
- pEcc->pR = DMEM_INDEX(pEcc, r);
- pEcc->pS = DMEM_INDEX(pEcc, s);
- pEcc->pX = DMEM_INDEX(pEcc, x);
- pEcc->pY = DMEM_INDEX(pEcc, y);
- pEcc->pD = DMEM_INDEX(pEcc, d);
-
- /* (over)write first words to ensure pairwise mismatch. */
- pEcc->k.a[0] = 1;
- pEcc->rnd.a[0] = 2;
- pEcc->msg.a[0] = 3;
- pEcc->r.a[0] = 4;
- pEcc->s.a[0] = 5;
- pEcc->x.a[0] = 6;
- pEcc->y.a[0] = 7;
- pEcc->d.a[0] = 8;
-}
-
-/*
- * Local copy function since for some reason we have p256_int as
- * packed structs.
- * This causes wrong writes (bytes vs. words) to the peripheral with
- * struct copies in case the src operand is unaligned.
- *
- * Our peripheral dst are always aligned correctly.
- * By making sure the src is aligned too, we get word copy behavior.
- */
-static inline void cp8w(p256_int *dst, const p256_int *src)
-{
- p256_int tmp;
-
- tmp = *src;
- *dst = tmp;
-}
-
-int dcrypto_p256_ecdsa_sign(const p256_int *key, const p256_int *message,
- p256_int *r, p256_int *s)
-{
- int i, result;
- struct DMEM_ecc *pEcc =
- (struct DMEM_ecc *)GREG32_ADDR(CRYPTO, DMEM_DUMMY);
-
- dcrypto_init_and_lock();
- dcrypto_ecc_init();
- result = dcrypto_call(CF_p256init_adr);
-
- /* Pick uniform 0 < k < R */
- do {
- for (i = 0; i < 8; ++i)
- pEcc->rnd.a[i] ^= rand();
- } while (p256_cmp(&SECP256r1_nMin2, &pEcc->rnd) < 0);
-
- p256_add_d(&pEcc->rnd, 1, &pEcc->k);
-
- for (i = 0; i < 8; ++i)
- pEcc->rnd.a[i] = rand();
-
- cp8w(&pEcc->msg, message);
- cp8w(&pEcc->d, key);
-
- result |= dcrypto_call(CF_p256sign_adr);
-
- cp8w(r, &pEcc->r);
- cp8w(s, &pEcc->s);
-
- /* Wipe d,k */
- cp8w(&pEcc->d, &pEcc->rnd);
- cp8w(&pEcc->k, &pEcc->rnd);
-
- dcrypto_unlock();
- return result == 0;
-}
-
-int dcrypto_p256_base_point_mul(const p256_int *k, p256_int *x, p256_int *y)
-{
- int i, result;
- struct DMEM_ecc *pEcc =
- (struct DMEM_ecc *)GREG32_ADDR(CRYPTO, DMEM_DUMMY);
-
- dcrypto_init_and_lock();
- dcrypto_ecc_init();
- result = dcrypto_call(CF_p256init_adr);
-
- for (i = 0; i < 8; ++i)
- pEcc->rnd.a[i] ^= rand();
-
- cp8w(&pEcc->d, k);
-
- result |= dcrypto_call(CF_p256scalarbasemult_adr);
-
- cp8w(x, &pEcc->x);
- cp8w(y, &pEcc->y);
-
- /* Wipe d */
- cp8w(&pEcc->d, &pEcc->rnd);
-
- dcrypto_unlock();
- return result == 0;
-}
-
-int dcrypto_p256_point_mul(const p256_int *k,
- const p256_int *in_x, const p256_int *in_y,
- p256_int *x, p256_int *y)
-{
- int i, result;
- struct DMEM_ecc *pEcc =
- (struct DMEM_ecc *)GREG32_ADDR(CRYPTO, DMEM_DUMMY);
-
- dcrypto_init_and_lock();
- dcrypto_ecc_init();
- result = dcrypto_call(CF_p256init_adr);
-
- for (i = 0; i < 8; ++i)
- pEcc->rnd.a[i] ^= rand();
-
- cp8w(&pEcc->k, k);
- cp8w(&pEcc->x, in_x);
- cp8w(&pEcc->y, in_y);
-
- result |= dcrypto_call(CF_p256scalarmult_adr);
-
- cp8w(x, &pEcc->x);
- cp8w(y, &pEcc->y);
-
- /* Wipe k,x,y */
- cp8w(&pEcc->k, &pEcc->rnd);
- cp8w(&pEcc->x, &pEcc->rnd);
- cp8w(&pEcc->y, &pEcc->rnd);
-
- dcrypto_unlock();
- return result == 0;
-}
-
-int dcrypto_p256_ecdsa_verify(const p256_int *key_x, const p256_int *key_y,
- const p256_int *message, const p256_int *r,
- const p256_int *s)
-{
- int i, result;
- struct DMEM_ecc *pEcc =
- (struct DMEM_ecc *)GREG32_ADDR(CRYPTO, DMEM_DUMMY);
-
- dcrypto_init_and_lock();
- dcrypto_ecc_init();
- result = dcrypto_call(CF_p256init_adr);
-
- cp8w(&pEcc->msg, message);
- cp8w(&pEcc->r, r);
- cp8w(&pEcc->s, s);
- cp8w(&pEcc->x, key_x);
- cp8w(&pEcc->y, key_y);
-
- result |= dcrypto_call(CF_p256verify_adr);
-
- for (i = 0; i < 8; ++i)
- result |= (pEcc->rnd.a[i] ^ r->a[i]);
-
- dcrypto_unlock();
- return result == 0;
-}
-
-int dcrypto_p256_is_valid_point(const p256_int *x, const p256_int *y)
-{
- int i, result;
- struct DMEM_ecc *pEcc =
- (struct DMEM_ecc *)GREG32_ADDR(CRYPTO, DMEM_DUMMY);
-
- dcrypto_init_and_lock();
- dcrypto_ecc_init();
- result = dcrypto_call(CF_p256init_adr);
-
- cp8w(&pEcc->x, x);
- cp8w(&pEcc->y, y);
-
- result |= dcrypto_call(CF_p256isoncurve_adr);
-
- for (i = 0; i < 8; ++i)
- result |= (pEcc->r.a[i] ^ pEcc->s.a[i]);
-
- dcrypto_unlock();
- return result == 0;
-}
diff --git a/chip/g/dcrypto/dcrypto_bn.c b/chip/g/dcrypto/dcrypto_bn.c
new file mode 100644
index 0000000000..5b6bbf8451
--- /dev/null
+++ b/chip/g/dcrypto/dcrypto_bn.c
@@ -0,0 +1,733 @@
+/* Copyright 2016 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#include "dcrypto.h"
+#include "internal.h"
+#include "registers.h"
+#include "trng.h"
+
+/* Firmware blob for crypto accelerator */
+
+/* AUTO-GENERATED. DO NOT MODIFY. */
+/* clang-format off */
+static const uint32_t IMEM_dcrypto[] = {
+/* @0x0: function tag[1] { */
+#define CF_tag_adr 0
+ 0xf8000001, /* sigini #1 */
+/* } */
+/* @0x1: function d0inv[14] { */
+#define CF_d0inv_adr 1
+ 0x4c000000, /* xor r0, r0, r0 */
+ 0x80000001, /* movi r0.0l, #1 */
+ 0x7c740000, /* mov r29, r0 */
+ 0x05100008, /* loop #256 ( */
+ 0x5807bc00, /* mul128 r1, r28l, r29l */
+ 0x588bbc00, /* mul128 r2, r28u, r29l */
+ 0x50044110, /* add r1, r1, r2 << 128 */
+ 0x590bbc00, /* mul128 r2, r28l, r29u */
+ 0x50044110, /* add r1, r1, r2 << 128 */
+ 0x40040100, /* and r1, r1, r0 */
+ 0x44743d00, /* or r29, r29, r1 */
+ 0x50000000, /* add r0, r0, r0 */
+ /* ) */
+ 0x5477bf00, /* sub r29, r31, r29 */
+ 0x0c000000, /* ret */
+/* } */
+/* @0xf: function selcxSub[10] { */
+#define CF_selcxSub_adr 15
+ 0x97800100, /* ldrfp r1 */
+ 0x95800000, /* lddmp r0 */
+ 0x540c6300, /* sub r3, r3, r3 */
+ 0x0600c005, /* loop *6 ( */
+ 0x8c081800, /* ld *2, *0++ */
+ 0x7c8c0000, /* ldr *3, *0 */
+ 0x54906200, /* subb r4, r2, r3 */
+ 0x66084408, /* selcx r2, r4, r2 */
+ 0x7ca00300, /* ldr *0++, *3 */
+ /* ) */
+ 0x0c000000, /* ret */
+/* } */
+/* @0x19: function computeRR[41] { */
+#define CF_computeRR_adr 25
+ 0x4c7fff00, /* xor r31, r31, r31 */
+ 0x84004000, /* ldi r0, [#0] */
+ 0x95800000, /* lddmp r0 */
+ 0x4c0c6300, /* xor r3, r3, r3 */
+ 0x800cffff, /* movi r3.0l, #65535 */
+ 0x40040398, /* and r1, r3, r0 >> 192 */
+ 0x480c6000, /* not r3, r3 */
+ 0x400c0300, /* and r3, r3, r0 */
+ 0x500c2301, /* add r3, r3, r1 << 8 */
+ 0x94800300, /* ldlc r3 */
+ 0x80040005, /* movi r1.0l, #5 */
+ 0x81040003, /* movi r1.2l, #3 */
+ 0x81840002, /* movi r1.3l, #2 */
+ 0x82040004, /* movi r1.4l, #4 */
+ 0x97800100, /* ldrfp r1 */
+ 0x4c0c6300, /* xor r3, r3, r3 */
+ 0x0600c001, /* loop *6 ( */
+ 0x7ca00200, /* ldr *0++, *2 */
+ /* ) */
+ 0x560c1f00, /* subx r3, r31, r0 */
+ 0x0800000f, /* call &selcxSub */
+ 0x06000010, /* loop *0 ( */
+ 0x97800100, /* ldrfp r1 */
+ 0x560c6300, /* subx r3, r3, r3 */
+ 0x0600c003, /* loop *6 ( */
+ 0x7c8c0000, /* ldr *3, *0 */
+ 0x52884200, /* addcx r2, r2, r2 */
+ 0x7ca00300, /* ldr *0++, *3 */
+ /* ) */
+ 0x0800000f, /* call &selcxSub */
+ 0x97800100, /* ldrfp r1 */
+ 0x95800000, /* lddmp r0 */
+ 0x560c6300, /* subx r3, r3, r3 */
+ 0x0600c003, /* loop *6 ( */
+ 0x8c081800, /* ld *2, *0++ */
+ 0x7c8c0800, /* ldr *3, *0++ */
+ 0x5e804300, /* cmpbx r3, r2 */
+ /* ) */
+ 0x0800000f, /* call &selcxSub */
+ 0xfc000000, /* nop */
+ /* ) */
+ 0x97800100, /* ldrfp r1 */
+ 0x0600c001, /* loop *6 ( */
+ 0x90680800, /* st *0++, *2++ */
+ /* ) */
+ 0x0c000000, /* ret */
+/* } */
+/* @0x42: function dmXd0[9] { */
+#define CF_dmXd0_adr 66
+ 0x586f3e00, /* mul128 r27, r30l, r25l */
+ 0x59eb3e00, /* mul128 r26, r30u, r25u */
+ 0x58df3e00, /* mul128 r23, r30u, r25l */
+ 0x506efb10, /* add r27, r27, r23 << 128 */
+ 0x50eafa90, /* addc r26, r26, r23 >> 128 */
+ 0x595f3e00, /* mul128 r23, r30l, r25u */
+ 0x506efb10, /* add r27, r27, r23 << 128 */
+ 0x50eafa90, /* addc r26, r26, r23 >> 128 */
+ 0x0c000000, /* ret */
+/* } */
+/* @0x4b: function dmXa[9] { */
+#define CF_dmXa_adr 75
+ 0x586c5e00, /* mul128 r27, r30l, r2l */
+ 0x59e85e00, /* mul128 r26, r30u, r2u */
+ 0x58dc5e00, /* mul128 r23, r30u, r2l */
+ 0x506efb10, /* add r27, r27, r23 << 128 */
+ 0x50eafa90, /* addc r26, r26, r23 >> 128 */
+ 0x595c5e00, /* mul128 r23, r30l, r2u */
+ 0x506efb10, /* add r27, r27, r23 << 128 */
+ 0x50eafa90, /* addc r26, r26, r23 >> 128 */
+ 0x0c000000, /* ret */
+/* } */
+/* @0x54: function mma[46] { */
+#define CF_mma_adr 84
+ 0x8204001e, /* movi r1.4l, #30 */
+ 0x82840018, /* movi r1.5l, #24 */
+ 0x97800100, /* ldrfp r1 */
+ 0x8c101b00, /* ld *4, *3++ */
+ 0x0800004b, /* call &dmXa */
+ 0x7c940800, /* ldr *5, *0++ */
+ 0x507b1b00, /* add r30, r27, r24 */
+ 0x50f7fa00, /* addc r29, r26, r31 */
+ 0x7c640300, /* mov r25, r3 */
+ 0x08000042, /* call &dmXd0 */
+ 0x7c641b00, /* mov r25, r27 */
+ 0x7c701a00, /* mov r28, r26 */
+ 0x7c601e00, /* mov r24, r30 */
+ 0x8c101800, /* ld *4, *0++ */
+ 0x08000042, /* call &dmXd0 */
+ 0x506f1b00, /* add r27, r27, r24 */
+ 0x50f3fa00, /* addc r28, r26, r31 */
+ 0x0600e00e, /* loop *7 ( */
+ 0x8c101b00, /* ld *4, *3++ */
+ 0x0800004b, /* call &dmXa */
+ 0x7c940800, /* ldr *5, *0++ */
+ 0x506f1b00, /* add r27, r27, r24 */
+ 0x50ebfa00, /* addc r26, r26, r31 */
+ 0x5063bb00, /* add r24, r27, r29 */
+ 0x50f7fa00, /* addc r29, r26, r31 */
+ 0x8c101800, /* ld *4, *0++ */
+ 0x08000042, /* call &dmXd0 */
+ 0x506f1b00, /* add r27, r27, r24 */
+ 0x50ebfa00, /* addc r26, r26, r31 */
+ 0x52639b00, /* addx r24, r27, r28 */
+ 0x7ca80500, /* ldr *2++, *5 */
+ 0x52f3fa00, /* addcx r28, r26, r31 */
+ /* ) */
+ 0x52e39d00, /* addcx r24, r29, r28 */
+ 0x7ca80500, /* ldr *2++, *5 */
+ 0x95800000, /* lddmp r0 */
+ 0x97800100, /* ldrfp r1 */
+ 0x54739c00, /* sub r28, r28, r28 */
+ 0x0600c007, /* loop *6 ( */
+ 0x8c141800, /* ld *5, *0++ */
+ 0x7c900000, /* ldr *4, *0 */
+ 0x54f71e00, /* subb r29, r30, r24 */
+ 0x99600000, /* strnd r24 */
+ 0x7c800500, /* ldr *0, *5 */
+ 0x6663dd08, /* selcx r24, r29, r30 */
+ 0x7ca00500, /* ldr *0++, *5 */
+ /* ) */
+ 0x0c000000, /* ret */
+/* } */
+/* @0x82: function setupPtrs[11] { */
+#define CF_setupPtrs_adr 130
+ 0x847c4000, /* ldi r31, [#0] */
+ 0x4c7fff00, /* xor r31, r31, r31 */
+ 0x95800000, /* lddmp r0 */
+ 0x94800000, /* ldlc r0 */
+ 0x7c041f00, /* mov r1, r31 */
+ 0x80040004, /* movi r1.0l, #4 */
+ 0x80840003, /* movi r1.1l, #3 */
+ 0x81040004, /* movi r1.2l, #4 */
+ 0x81840002, /* movi r1.3l, #2 */
+ 0x97800100, /* ldrfp r1 */
+ 0x0c000000, /* ret */
+/* } */
+/* @0x8d: function mulx[19] { */
+#define CF_mulx_adr 141
+ 0x84004000, /* ldi r0, [#0] */
+ 0x08000082, /* call &setupPtrs */
+ 0x8c041100, /* ld *1, *1 */
+ 0x7c081f00, /* mov r2, r31 */
+ 0x0600c001, /* loop *6 ( */
+ 0x7ca80300, /* ldr *2++, *3 */
+ /* ) */
+ 0x97800100, /* ldrfp r1 */
+ 0x0600c004, /* loop *6 ( */
+ 0x8c0c1c00, /* ld *3, *4++ */
+ 0x95000000, /* stdmp r0 */
+ 0x08000054, /* call &mma */
+ 0x95800000, /* lddmp r0 */
+ /* ) */
+ 0x97800100, /* ldrfp r1 */
+ 0x95800000, /* lddmp r0 */
+ 0x0600c001, /* loop *6 ( */
+ 0x90740800, /* st *0++, *5++ */
+ /* ) */
+ 0x97800100, /* ldrfp r1 */
+ 0x95800000, /* lddmp r0 */
+ 0x0c000000, /* ret */
+/* } */
+/* @0xa0: function mul1_exp[30] { */
+#define CF_mul1_exp_adr 160
+ 0x8c041100, /* ld *1, *1 */
+ 0x7c081f00, /* mov r2, r31 */
+ 0x0600c001, /* loop *6 ( */
+ 0x7ca80300, /* ldr *2++, *3 */
+ /* ) */
+ 0x97800100, /* ldrfp r1 */
+ 0x80080001, /* movi r2.0l, #1 */
+ 0x0600c003, /* loop *6 ( */
+ 0x95800000, /* lddmp r0 */
+ 0x08000054, /* call &mma */
+ 0x7c081f00, /* mov r2, r31 */
+ /* ) */
+ 0x97800100, /* ldrfp r1 */
+ 0x95800000, /* lddmp r0 */
+ 0x56084200, /* subx r2, r2, r2 */
+ 0x0600c003, /* loop *6 ( */
+ 0x8c041800, /* ld *1, *0++ */
+ 0x7c8c0800, /* ldr *3, *0++ */
+ 0x5e804300, /* cmpbx r3, r2 */
+ /* ) */
+ 0x97800100, /* ldrfp r1 */
+ 0x95800000, /* lddmp r0 */
+ 0x540c6300, /* sub r3, r3, r3 */
+ 0x0600c006, /* loop *6 ( */
+ 0x8c041800, /* ld *1, *0++ */
+ 0x7c8c0800, /* ldr *3, *0++ */
+ 0x548c6200, /* subb r3, r2, r3 */
+ 0x66084308, /* selcx r2, r3, r2 */
+ 0x90740300, /* st *3, *5++ */
+ 0xfc000000, /* nop */
+ /* ) */
+ 0x97800100, /* ldrfp r1 */
+ 0x95800000, /* lddmp r0 */
+ 0x0c000000, /* ret */
+/* } */
+/* @0xbe: function mul1[4] { */
+#define CF_mul1_adr 190
+ 0x84004000, /* ldi r0, [#0] */
+ 0x08000082, /* call &setupPtrs */
+ 0x080000a0, /* call &mul1_exp */
+ 0x0c000000, /* ret */
+/* } */
+/* @0xc2: function sqrx_exp[19] { */
+#define CF_sqrx_exp_adr 194
+ 0x84004020, /* ldi r0, [#1] */
+ 0x95800000, /* lddmp r0 */
+ 0x8c041100, /* ld *1, *1 */
+ 0x7c081f00, /* mov r2, r31 */
+ 0x0600c001, /* loop *6 ( */
+ 0x7ca80300, /* ldr *2++, *3 */
+ /* ) */
+ 0x97800100, /* ldrfp r1 */
+ 0x0600c004, /* loop *6 ( */
+ 0x8c0c1c00, /* ld *3, *4++ */
+ 0x95000000, /* stdmp r0 */
+ 0x08000054, /* call &mma */
+ 0x95800000, /* lddmp r0 */
+ /* ) */
+ 0x97800100, /* ldrfp r1 */
+ 0x95800000, /* lddmp r0 */
+ 0x0600c001, /* loop *6 ( */
+ 0x90740800, /* st *0++, *5++ */
+ /* ) */
+ 0x97800100, /* ldrfp r1 */
+ 0x95800000, /* lddmp r0 */
+ 0x0c000000, /* ret */
+/* } */
+/* @0xd5: function mulx_exp[14] { */
+#define CF_mulx_exp_adr 213
+ 0x84004040, /* ldi r0, [#2] */
+ 0x95800000, /* lddmp r0 */
+ 0x8c041100, /* ld *1, *1 */
+ 0x7c081f00, /* mov r2, r31 */
+ 0x0600c001, /* loop *6 ( */
+ 0x7ca80300, /* ldr *2++, *3 */
+ /* ) */
+ 0x97800100, /* ldrfp r1 */
+ 0x0600c004, /* loop *6 ( */
+ 0x8c0c1c00, /* ld *3, *4++ */
+ 0x95000000, /* stdmp r0 */
+ 0x08000054, /* call &mma */
+ 0x95800000, /* lddmp r0 */
+ /* ) */
+ 0x97800100, /* ldrfp r1 */
+ 0x0c000000, /* ret */
+/* } */
+/* @0xe3: function modexp[43] { */
+#define CF_modexp_adr 227
+ 0x0800008d, /* call &mulx */
+ 0x84004060, /* ldi r0, [#3] */
+ 0x95800000, /* lddmp r0 */
+ 0x54084200, /* sub r2, r2, r2 */
+ 0x0600c004, /* loop *6 ( */
+ 0xfc000000, /* nop */
+ 0x8c0c1800, /* ld *3, *0++ */
+ 0x54885f00, /* subb r2, r31, r2 */
+ 0x90740300, /* st *3, *5++ */
+ /* ) */
+ 0xfc000000, /* nop */
+ 0x7c081f00, /* mov r2, r31 */
+ 0x8008ffff, /* movi r2.0l, #65535 */
+ 0x400c0298, /* and r3, r2, r0 >> 192 */
+ 0x48084000, /* not r2, r2 */
+ 0x40080200, /* and r2, r2, r0 */
+ 0x50086201, /* add r2, r2, r3 << 8 */
+ 0x94800200, /* ldlc r2 */
+ 0x06000015, /* loop *0 ( */
+ 0x080000c2, /* call &sqrx_exp */
+ 0x080000d5, /* call &mulx_exp */
+ 0x84004060, /* ldi r0, [#3] */
+ 0x95800000, /* lddmp r0 */
+ 0x99080000, /* strnd r2 */
+ 0x54084200, /* sub r2, r2, r2 */
+ 0x0600c004, /* loop *6 ( */
+ 0x99080000, /* strnd r2 */
+ 0x8c0c1400, /* ld *3, *4 */
+ 0x50884200, /* addc r2, r2, r2 */
+ 0x90700300, /* st *3, *4++ */
+ /* ) */
+ 0x0600c008, /* loop *6 ( */
+ 0x99080000, /* strnd r2 */
+ 0x8c041500, /* ld *1, *5 */
+ 0x90540300, /* st *3, *5 */
+ 0x7c8c0800, /* ldr *3, *0++ */
+ 0x7c000200, /* mov r0, r2 */
+ 0x99080000, /* strnd r2 */
+ 0x64086008, /* selc r2, r0, r3 */
+ 0x90740300, /* st *3, *5++ */
+ /* ) */
+ 0xfc000000, /* nop */
+ /* ) */
+ 0x84004060, /* ldi r0, [#3] */
+ 0x95800000, /* lddmp r0 */
+ 0x080000a0, /* call &mul1_exp */
+ 0x0c000000, /* ret */
+/* } */
+/* @0x10e: function modexp_blinded[76] { */
+#define CF_modexp_blinded_adr 270
+ 0x0800008d, /* call &mulx */
+ 0x84004060, /* ldi r0, [#3] */
+ 0x95800000, /* lddmp r0 */
+ 0x54084200, /* sub r2, r2, r2 */
+ 0x0600c004, /* loop *6 ( */
+ 0xfc000000, /* nop */
+ 0x8c0c1800, /* ld *3, *0++ */
+ 0x54885f00, /* subb r2, r31, r2 */
+ 0x90740300, /* st *3, *5++ */
+ /* ) */
+ 0xfc000000, /* nop */
+ 0x8c0c1900, /* ld *3, *1++ */
+ 0x8c0c1100, /* ld *3, *1 */
+ 0x521c5f90, /* addx r7, r31, r2 >> 128 */
+ 0x590c4200, /* mul128 r3, r2l, r2u */
+ 0x7c181f00, /* mov r6, r31 */
+ 0x0600c011, /* loop *6 ( */
+ 0x99080000, /* strnd r2 */
+ 0x8c0c1400, /* ld *3, *4 */
+ 0x58106200, /* mul128 r4, r2l, r3l */
+ 0x59946200, /* mul128 r5, r2u, r3u */
+ 0x58806200, /* mul128 r0, r2u, r3l */
+ 0x50100410, /* add r4, r4, r0 << 128 */
+ 0x50940590, /* addc r5, r5, r0 >> 128 */
+ 0x59006200, /* mul128 r0, r2l, r3u */
+ 0x50100410, /* add r4, r4, r0 << 128 */
+ 0x50940590, /* addc r5, r5, r0 >> 128 */
+ 0x5010c400, /* add r4, r4, r6 */
+ 0x5097e500, /* addc r5, r5, r31 */
+ 0x50088200, /* add r2, r2, r4 */
+ 0x509be500, /* addc r6, r5, r31 */
+ 0x5688e200, /* subbx r2, r2, r7 */
+ 0x90700300, /* st *3, *4++ */
+ 0x541ce700, /* sub r7, r7, r7 */
+ /* ) */
+ 0x7c080600, /* mov r2, r6 */
+ 0x5688e200, /* subbx r2, r2, r7 */
+ 0x90500300, /* st *3, *4 */
+ 0xfc000000, /* nop */
+ 0x84004060, /* ldi r0, [#3] */
+ 0x7c081f00, /* mov r2, r31 */
+ 0x8008ffff, /* movi r2.0l, #65535 */
+ 0x400c0298, /* and r3, r2, r0 >> 192 */
+ 0x48084000, /* not r2, r2 */
+ 0x40080200, /* and r2, r2, r0 */
+ 0x510c0301, /* addi r3, r3, #1 */
+ 0x50086201, /* add r2, r2, r3 << 8 */
+ 0x94800200, /* ldlc r2 */
+ 0x06000019, /* loop *0 ( */
+ 0x080000c2, /* call &sqrx_exp */
+ 0x080000d5, /* call &mulx_exp */
+ 0x84004060, /* ldi r0, [#3] */
+ 0x95800000, /* lddmp r0 */
+ 0x99080000, /* strnd r2 */
+ 0x54084200, /* sub r2, r2, r2 */
+ 0x0600c004, /* loop *6 ( */
+ 0x99080000, /* strnd r2 */
+ 0x8c0c1400, /* ld *3, *4 */
+ 0x50884200, /* addc r2, r2, r2 */
+ 0x90700300, /* st *3, *4++ */
+ /* ) */
+ 0x99080000, /* strnd r2 */
+ 0x8c0c1400, /* ld *3, *4 */
+ 0x50884200, /* addc r2, r2, r2 */
+ 0x90700300, /* st *3, *4++ */
+ 0x0600c008, /* loop *6 ( */
+ 0x99080000, /* strnd r2 */
+ 0x8c041500, /* ld *1, *5 */
+ 0x90540300, /* st *3, *5 */
+ 0x7c8c0800, /* ldr *3, *0++ */
+ 0x7c000200, /* mov r0, r2 */
+ 0x99080000, /* strnd r2 */
+ 0x64086008, /* selc r2, r0, r3 */
+ 0x90740300, /* st *3, *5++ */
+ /* ) */
+ 0xfc000000, /* nop */
+ /* ) */
+ 0x84004060, /* ldi r0, [#3] */
+ 0x95800000, /* lddmp r0 */
+ 0x080000a0, /* call &mul1_exp */
+ 0x0c000000, /* ret */
+/* } */
+/* @0x15a: function modload[12] { */
+#define CF_modload_adr 346
+ 0x4c7fff00, /* xor r31, r31, r31 */
+ 0x84004000, /* ldi r0, [#0] */
+ 0x95800000, /* lddmp r0 */
+ 0x94800000, /* ldlc r0 */
+ 0x8000001c, /* movi r0.0l, #28 */
+ 0x8080001d, /* movi r0.1l, #29 */
+ 0x97800000, /* ldrfp r0 */
+ 0x8c001000, /* ld *0, *0 */
+ 0x08000001, /* call &d0inv */
+ 0x90440100, /* st *1, *1 */
+ 0x08000019, /* call &computeRR */
+ 0x0c000000, /* ret */
+ /* } */
+};
+/* clang-format on */
+
+struct DMEM_ctx_ptrs {
+ uint32_t pMod;
+ uint32_t pDinv;
+ uint32_t pRR;
+ uint32_t pA;
+ uint32_t pB;
+ uint32_t pC;
+ uint32_t n;
+ uint32_t n1;
+};
+
+/*
+ * This struct is "calling convention" for passing parameters into the
+ * code block above for RSA operations. Parameters start at &DMEM[0].
+ */
+struct DMEM_ctx {
+ struct DMEM_ctx_ptrs in_ptrs;
+ struct DMEM_ctx_ptrs sqr_ptrs;
+ struct DMEM_ctx_ptrs mul_ptrs;
+ struct DMEM_ctx_ptrs out_ptrs;
+ uint32_t mod[RSA_WORDS_4K];
+ uint32_t dInv[8];
+ uint32_t pubexp;
+ uint32_t _pad1[3];
+ uint32_t rnd[2];
+ uint32_t _pad2[2];
+ uint32_t RR[RSA_WORDS_4K];
+ uint32_t in[RSA_WORDS_4K];
+ uint32_t exp[RSA_WORDS_4K + 8]; /* extra word for randomization */
+ uint32_t out[RSA_WORDS_4K];
+ uint32_t bin[RSA_WORDS_4K];
+ uint32_t bout[RSA_WORDS_4K];
+};
+
+#define DMEM_CELL_SIZE 32
+#define DMEM_INDEX(p, f) \
+ (((const uint8_t *) &(p)->f - (const uint8_t *) (p)) / DMEM_CELL_SIZE)
+
+/* Get non-0 64 bit random */
+static void rand64(uint32_t dst[2])
+{
+ do {
+ dst[0] = rand();
+ dst[1] = rand();
+ } while ((dst[0] | dst[1]) == 0);
+}
+
+/* Grab dcrypto lock and set things up for modulus and input */
+static int setup_and_lock(const struct LITE_BIGNUM *N,
+ const struct LITE_BIGNUM *input)
+{
+ struct DMEM_ctx *ctx =
+ (struct DMEM_ctx *) GREG32_ADDR(CRYPTO, DMEM_DUMMY);
+
+ /* Initialize hardware; load code page. */
+ dcrypto_init_and_lock();
+ dcrypto_imem_load(0, IMEM_dcrypto, ARRAY_SIZE(IMEM_dcrypto));
+
+ /* Setup DMEM pointers (as indices into DMEM which are 256-bit cells).
+ */
+ ctx->in_ptrs.pMod = DMEM_INDEX(ctx, mod);
+ ctx->in_ptrs.pDinv = DMEM_INDEX(ctx, dInv);
+ ctx->in_ptrs.pRR = DMEM_INDEX(ctx, RR);
+ ctx->in_ptrs.pA = DMEM_INDEX(ctx, in);
+ ctx->in_ptrs.pB = DMEM_INDEX(ctx, exp);
+ ctx->in_ptrs.pC = DMEM_INDEX(ctx, out);
+ ctx->in_ptrs.n = bn_bits(N) / (DMEM_CELL_SIZE * 8);
+ ctx->in_ptrs.n1 = ctx->in_ptrs.n - 1;
+
+ ctx->sqr_ptrs = ctx->in_ptrs;
+ ctx->mul_ptrs = ctx->in_ptrs;
+ ctx->out_ptrs = ctx->in_ptrs;
+
+ dcrypto_dmem_load(DMEM_INDEX(ctx, mod), N->d, bn_words(N));
+ dcrypto_dmem_load(DMEM_INDEX(ctx, in), input->d, bn_words(input));
+
+ /* Calculate RR and d0inv. */
+ return dcrypto_call(CF_modload_adr);
+}
+
+#define MONTMUL(ctx, a, b, c) \
+ montmul(ctx, DMEM_INDEX(ctx, a), DMEM_INDEX(ctx, b), DMEM_INDEX(ctx, c))
+
+static int montmul(struct DMEM_ctx *ctx, uint32_t pA, uint32_t pB,
+ uint32_t pOut)
+{
+
+ ctx->in_ptrs.pA = pA;
+ ctx->in_ptrs.pB = pB;
+ ctx->in_ptrs.pC = pOut;
+
+ return dcrypto_call(CF_mulx_adr);
+}
+
+#define MONTOUT(ctx, a, b) montout(ctx, DMEM_INDEX(ctx, a), DMEM_INDEX(ctx, b))
+
+static int montout(struct DMEM_ctx *ctx, uint32_t pA, uint32_t pOut)
+{
+
+ ctx->in_ptrs.pA = pA;
+ ctx->in_ptrs.pB = 0;
+ ctx->in_ptrs.pC = pOut;
+
+ return dcrypto_call(CF_mul1_adr);
+}
+
+#define MODEXP(ctx, in, exp, out) \
+ modexp(ctx, CF_modexp_adr, DMEM_INDEX(ctx, RR), DMEM_INDEX(ctx, in), \
+ DMEM_INDEX(ctx, exp), DMEM_INDEX(ctx, out))
+
+#define MODEXP_BLINDED(ctx, in, exp, out) \
+ modexp(ctx, CF_modexp_blinded_adr, DMEM_INDEX(ctx, RR), \
+ DMEM_INDEX(ctx, in), DMEM_INDEX(ctx, exp), \
+ DMEM_INDEX(ctx, out))
+
+static int modexp(struct DMEM_ctx *ctx, uint32_t adr, uint32_t rr, uint32_t pIn,
+ uint32_t pExp, uint32_t pOut)
+{
+ /* in = in * RR */
+ ctx->in_ptrs.pA = pIn;
+ ctx->in_ptrs.pB = rr;
+ ctx->in_ptrs.pC = pIn;
+
+ /* out = out * out */
+ ctx->sqr_ptrs.pA = pOut;
+ ctx->sqr_ptrs.pB = pOut;
+ ctx->sqr_ptrs.pC = pOut;
+
+ /* out = out * in */
+ ctx->mul_ptrs.pA = pIn;
+ ctx->mul_ptrs.pB = pOut;
+ ctx->mul_ptrs.pC = pOut;
+
+ /* out = out / R */
+ ctx->out_ptrs.pA = pOut;
+ ctx->out_ptrs.pB = pExp;
+ ctx->out_ptrs.pC = pOut;
+
+ return dcrypto_call(adr);
+}
+
+/* output = input ** exp % N. */
+int dcrypto_modexp_blinded(struct LITE_BIGNUM *output,
+ const struct LITE_BIGNUM *input,
+ const struct LITE_BIGNUM *exp,
+ const struct LITE_BIGNUM *N, uint32_t pubexp)
+{
+ int i, result;
+ struct DMEM_ctx *ctx =
+ (struct DMEM_ctx *) GREG32_ADDR(CRYPTO, DMEM_DUMMY);
+
+ uint32_t r_buf[RSA_MAX_WORDS];
+ uint32_t rinv_buf[RSA_MAX_WORDS];
+
+ struct LITE_BIGNUM r;
+ struct LITE_BIGNUM rinv;
+
+ bn_init(&r, r_buf, bn_size(N));
+ bn_init(&rinv, rinv_buf, bn_size(N));
+
+ /*
+ * pick 64 bit r != 0
+ * We cannot tolerate risk of 0 since 0 breaks computation.
+ */
+ rand64(r_buf);
+
+ /*
+ * compute 1/r mod N
+ * Note this cannot fail since N is product of two large primes
+ * and r != 0, so we can ignore return value.
+ */
+ bn_modinv_vartime(&rinv, &r, N);
+
+ /*
+ * compute r^pubexp mod N
+ */
+ dcrypto_modexp_word(&r, &r, pubexp, N);
+
+ result = setup_and_lock(N, input);
+
+ /* Pick !0 64-bit random for exponent blinding */
+ rand64(ctx->rnd);
+ ctx->pubexp = pubexp;
+
+ ctx->_pad1[0] = ctx->_pad1[1] = ctx->_pad1[2] = 0;
+ ctx->_pad2[0] = ctx->_pad2[1] = 0;
+
+ dcrypto_dmem_load(DMEM_INDEX(ctx, bin), r.d, bn_words(&r));
+ dcrypto_dmem_load(DMEM_INDEX(ctx, bout), rinv.d, bn_words(&rinv));
+ dcrypto_dmem_load(DMEM_INDEX(ctx, exp), exp->d, bn_words(exp));
+
+ /* 0 pad the exponent to full size + 8 */
+ for (i = bn_words(exp); i < bn_words(N) + 8; ++i)
+ ctx->exp[i] = 0;
+
+ /* Blind input */
+ result |= MONTMUL(ctx, in, RR, in);
+ result |= MONTMUL(ctx, in, bin, in);
+
+ result |= MODEXP_BLINDED(ctx, in, exp, out);
+
+ /* remove blinding factor */
+ result |= MONTMUL(ctx, out, RR, out);
+ result |= MONTMUL(ctx, out, bout, out);
+ /* fully reduce out */
+ result |= MONTMUL(ctx, out, RR, out);
+ result |= MONTOUT(ctx, out, out);
+
+ memcpy(output->d, ctx->out, bn_size(output));
+
+ dcrypto_unlock();
+ return result == 0;
+}
+
+/* output = input ** exp % N. */
+int dcrypto_modexp(struct LITE_BIGNUM *output, const struct LITE_BIGNUM *input,
+ const struct LITE_BIGNUM *exp, const struct LITE_BIGNUM *N)
+{
+ int i, result;
+ struct DMEM_ctx *ctx =
+ (struct DMEM_ctx *) GREG32_ADDR(CRYPTO, DMEM_DUMMY);
+
+ result = setup_and_lock(N, input);
+
+ dcrypto_dmem_load(DMEM_INDEX(ctx, exp), exp->d, bn_words(exp));
+
+ /* 0 pad the exponent to full size */
+ for (i = bn_words(exp); i < bn_words(N); ++i)
+ ctx->exp[i] = 0;
+
+ result |= MODEXP(ctx, in, exp, out);
+
+ memcpy(output->d, ctx->out, bn_size(output));
+
+ dcrypto_unlock();
+ return result == 0;
+}
+
+/* output = input ** exp % N. */
+int dcrypto_modexp_word(struct LITE_BIGNUM *output,
+ const struct LITE_BIGNUM *input, uint32_t exp,
+ const struct LITE_BIGNUM *N)
+{
+ int result;
+ uint32_t e = exp;
+ uint32_t b = 0x80000000;
+ struct DMEM_ctx *ctx =
+ (struct DMEM_ctx *) GREG32_ADDR(CRYPTO, DMEM_DUMMY);
+
+ result = setup_and_lock(N, input);
+
+ /* Find top bit */
+ while (b != 0 && !(b & e))
+ b >>= 1;
+
+ /* out = in * RR */
+ result |= MONTMUL(ctx, in, RR, out);
+ /* in = in * RR */
+ result |= MONTMUL(ctx, in, RR, in);
+
+ while (b > 1) {
+ b >>= 1;
+
+ /* out = out * out */
+ result |= MONTMUL(ctx, out, out, out);
+
+ if ((b & e) != 0) {
+ /* out = out * in */
+ result |= MONTMUL(ctx, in, out, out);
+ }
+ }
+
+ /* out = out / R */
+ result |= MONTOUT(ctx, out, out);
+
+ memcpy(output->d, ctx->out, bn_size(output));
+
+ dcrypto_unlock();
+ return result == 0;
+}
diff --git a/chip/g/dcrypto/dcrypto_p256.c b/chip/g/dcrypto/dcrypto_p256.c
new file mode 100644
index 0000000000..db915cdde6
--- /dev/null
+++ b/chip/g/dcrypto/dcrypto_p256.c
@@ -0,0 +1,941 @@
+/* Copyright 2016 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#include "dcrypto.h"
+#include "internal.h"
+#include "registers.h"
+#include "trng.h"
+
+/* Firmware blob for crypto accelerator */
+
+/* AUTO-GENERATED. DO NOT MODIFY. */
+/* clang-format off */
+static const uint32_t IMEM_dcrypto[] = {
+/* @0x0: function tag[1] { */
+#define CF_tag_adr 0
+ 0xf8000002, /* sigini #2 */
+/* } */
+/* @0x1: function SetupP256PandMuLow[21] { */
+#define CF_SetupP256PandMuLow_adr 1
+ 0x55741f01, /* subi r29, r31, #1 */
+ 0x83750000, /* movi r29.6h, #0 */
+ 0x83740001, /* movi r29.6l, #1 */
+ 0x82f50000, /* movi r29.5h, #0 */
+ 0x82f40000, /* movi r29.5l, #0 */
+ 0x82750000, /* movi r29.4h, #0 */
+ 0x82740000, /* movi r29.4l, #0 */
+ 0x81f50000, /* movi r29.3h, #0 */
+ 0x81f40000, /* movi r29.3l, #0 */
+ 0x98801d00, /* ldmod r29 */
+ 0x55701f01, /* subi r28, r31, #1 */
+ 0x83f10000, /* movi r28.7h, #0 */
+ 0x83f00000, /* movi r28.7l, #0 */
+ 0x82f0fffe, /* movi r28.5l, #65534 */
+ 0x8270fffe, /* movi r28.4l, #65534 */
+ 0x81f0fffe, /* movi r28.3l, #65534 */
+ 0x80f10000, /* movi r28.1h, #0 */
+ 0x80f00000, /* movi r28.1l, #0 */
+ 0x80710000, /* movi r28.0h, #0 */
+ 0x80700003, /* movi r28.0l, #3 */
+ 0x0c000000, /* ret */
+/* } */
+/* @0x16: function p256init[22] { */
+#define CF_p256init_adr 22
+ 0x847c4000, /* ldi r31, [#0] */
+ 0x4c7fff00, /* xor r31, r31, r31 */
+ 0x51781f01, /* addi r30, r31, #1 */
+ 0x08000001, /* call &SetupP256PandMuLow */
+ 0x7c6c1f00, /* mov r27, r31 */
+ 0x83ed5ac6, /* movi r27.7h, #23238 */
+ 0x83ec35d8, /* movi r27.7l, #13784 */
+ 0x836daa3a, /* movi r27.6h, #43578 */
+ 0x836c93e7, /* movi r27.6l, #37863 */
+ 0x82edb3eb, /* movi r27.5h, #46059 */
+ 0x82ecbd55, /* movi r27.5l, #48469 */
+ 0x826d7698, /* movi r27.4h, #30360 */
+ 0x826c86bc, /* movi r27.4l, #34492 */
+ 0x81ed651d, /* movi r27.3h, #25885 */
+ 0x81ec06b0, /* movi r27.3l, #1712 */
+ 0x816dcc53, /* movi r27.2h, #52307 */
+ 0x816cb0f6, /* movi r27.2l, #45302 */
+ 0x80ed3bce, /* movi r27.1h, #15310 */
+ 0x80ec3c3e, /* movi r27.1l, #15422 */
+ 0x806d27d2, /* movi r27.0h, #10194 */
+ 0x806c604b, /* movi r27.0l, #24651 */
+ 0x0c000000, /* ret */
+/* } */
+/* @0x2c: function MulMod[38] { */
+#define CF_MulMod_adr 44
+ 0x584f3800, /* mul128 r19, r24l, r25l */
+ 0x59d33800, /* mul128 r20, r24u, r25u */
+ 0x58d73800, /* mul128 r21, r24u, r25l */
+ 0x504eb310, /* add r19, r19, r21 << 128 */
+ 0x50d2b490, /* addc r20, r20, r21 >> 128 */
+ 0x59573800, /* mul128 r21, r24l, r25u */
+ 0x504eb310, /* add r19, r19, r21 << 128 */
+ 0x50d2b490, /* addc r20, r20, r21 >> 128 */
+ 0x645bfc02, /* selm r22, r28, r31 */
+ 0x685693ff, /* rshi r21, r19, r20 >> 255 */
+ 0x585f9500, /* mul128 r23, r21l, r28l */
+ 0x59e39500, /* mul128 r24, r21u, r28u */
+ 0x58e79500, /* mul128 r25, r21u, r28l */
+ 0x505f3710, /* add r23, r23, r25 << 128 */
+ 0x50e33890, /* addc r24, r24, r25 >> 128 */
+ 0x59679500, /* mul128 r25, r21l, r28u */
+ 0x505f3710, /* add r23, r23, r25 << 128 */
+ 0x50e33890, /* addc r24, r24, r25 >> 128 */
+ 0x6867f4ff, /* rshi r25, r20, r31 >> 255 */
+ 0x5062b800, /* add r24, r24, r21 */
+ 0x50e7f900, /* addc r25, r25, r31 */
+ 0x5062d800, /* add r24, r24, r22 */
+ 0x50e7f900, /* addc r25, r25, r31 */
+ 0x68573801, /* rshi r21, r24, r25 >> 1 */
+ 0x585abd00, /* mul128 r22, r29l, r21l */
+ 0x59debd00, /* mul128 r23, r29u, r21u */
+ 0x58e2bd00, /* mul128 r24, r29u, r21l */
+ 0x505b1610, /* add r22, r22, r24 << 128 */
+ 0x50df1790, /* addc r23, r23, r24 >> 128 */
+ 0x5962bd00, /* mul128 r24, r29l, r21u */
+ 0x505b1610, /* add r22, r22, r24 << 128 */
+ 0x50df1790, /* addc r23, r23, r24 >> 128 */
+ 0x545ad300, /* sub r22, r19, r22 */
+ 0x54d2f400, /* subb r20, r20, r23 */
+ 0x6457fd01, /* sell r21, r29, r31 */
+ 0x5456b600, /* sub r21, r22, r21 */
+ 0x9c4ff500, /* addm r19, r21, r31 */
+ 0x0c000000, /* ret */
+/* } */
+/* @0x52: function p256isoncurve[24] { */
+#define CF_p256isoncurve_adr 82
+ 0x84004000, /* ldi r0, [#0] */
+ 0x95800000, /* lddmp r0 */
+ 0x82800018, /* movi r0.5l, #24 */
+ 0x83000018, /* movi r0.6l, #24 */
+ 0x80000000, /* movi r0.0l, #0 */
+ 0x97800000, /* ldrfp r0 */
+ 0x8c181600, /* ld *6, *6 */
+ 0x7c641800, /* mov r25, r24 */
+ 0x0800002c, /* call &MulMod */
+ 0x7c001300, /* mov r0, r19 */
+ 0x8c141500, /* ld *5, *5 */
+ 0x7c641800, /* mov r25, r24 */
+ 0x0800002c, /* call &MulMod */
+ 0x8c141500, /* ld *5, *5 */
+ 0x7c641300, /* mov r25, r19 */
+ 0x0800002c, /* call &MulMod */
+ 0x8c141500, /* ld *5, *5 */
+ 0xa04f1300, /* subm r19, r19, r24 */
+ 0xa04f1300, /* subm r19, r19, r24 */
+ 0xa04f1300, /* subm r19, r19, r24 */
+ 0x9c637300, /* addm r24, r19, r27 */
+ 0x904c0500, /* st *5, *3 */
+ 0x90500000, /* st *0, *4 */
+ 0x0c000000, /* ret */
+/* } */
+/* @0x6a: function ProjAdd[80] { */
+#define CF_ProjAdd_adr 106
+ 0x7c600b00, /* mov r24, r11 */
+ 0x7c640800, /* mov r25, r8 */
+ 0x0800002c, /* call &MulMod */
+ 0x7c381300, /* mov r14, r19 */
+ 0x7c600c00, /* mov r24, r12 */
+ 0x7c640900, /* mov r25, r9 */
+ 0x0800002c, /* call &MulMod */
+ 0x7c3c1300, /* mov r15, r19 */
+ 0x7c600d00, /* mov r24, r13 */
+ 0x7c640a00, /* mov r25, r10 */
+ 0x0800002c, /* call &MulMod */
+ 0x7c401300, /* mov r16, r19 */
+ 0x9c458b00, /* addm r17, r11, r12 */
+ 0x9c492800, /* addm r18, r8, r9 */
+ 0x7c601100, /* mov r24, r17 */
+ 0x7c641200, /* mov r25, r18 */
+ 0x0800002c, /* call &MulMod */
+ 0x9c49ee00, /* addm r18, r14, r15 */
+ 0xa0465300, /* subm r17, r19, r18 */
+ 0x9c49ac00, /* addm r18, r12, r13 */
+ 0x9c4d4900, /* addm r19, r9, r10 */
+ 0x7c601200, /* mov r24, r18 */
+ 0x7c641300, /* mov r25, r19 */
+ 0x0800002c, /* call &MulMod */
+ 0x7c481300, /* mov r18, r19 */
+ 0x9c4e0f00, /* addm r19, r15, r16 */
+ 0xa04a7200, /* subm r18, r18, r19 */
+ 0x9c4dab00, /* addm r19, r11, r13 */
+ 0x9c314800, /* addm r12, r8, r10 */
+ 0x7c601300, /* mov r24, r19 */
+ 0x7c640c00, /* mov r25, r12 */
+ 0x0800002c, /* call &MulMod */
+ 0x7c2c1300, /* mov r11, r19 */
+ 0x9c320e00, /* addm r12, r14, r16 */
+ 0xa0318b00, /* subm r12, r11, r12 */
+ 0x7c601b00, /* mov r24, r27 */
+ 0x7c641000, /* mov r25, r16 */
+ 0x0800002c, /* call &MulMod */
+ 0xa02e6c00, /* subm r11, r12, r19 */
+ 0x9c356b00, /* addm r13, r11, r11 */
+ 0x9c2dab00, /* addm r11, r11, r13 */
+ 0xa0356f00, /* subm r13, r15, r11 */
+ 0x9c2d6f00, /* addm r11, r15, r11 */
+ 0x7c601b00, /* mov r24, r27 */
+ 0x7c640c00, /* mov r25, r12 */
+ 0x0800002c, /* call &MulMod */
+ 0x9c3e1000, /* addm r15, r16, r16 */
+ 0x9c420f00, /* addm r16, r15, r16 */
+ 0xa0321300, /* subm r12, r19, r16 */
+ 0xa031cc00, /* subm r12, r12, r14 */
+ 0x9c3d8c00, /* addm r15, r12, r12 */
+ 0x9c318f00, /* addm r12, r15, r12 */
+ 0x9c3dce00, /* addm r15, r14, r14 */
+ 0x9c39cf00, /* addm r14, r15, r14 */
+ 0xa03a0e00, /* subm r14, r14, r16 */
+ 0x7c601200, /* mov r24, r18 */
+ 0x7c640c00, /* mov r25, r12 */
+ 0x0800002c, /* call &MulMod */
+ 0x7c3c1300, /* mov r15, r19 */
+ 0x7c600e00, /* mov r24, r14 */
+ 0x7c640c00, /* mov r25, r12 */
+ 0x0800002c, /* call &MulMod */
+ 0x7c401300, /* mov r16, r19 */
+ 0x7c600b00, /* mov r24, r11 */
+ 0x7c640d00, /* mov r25, r13 */
+ 0x0800002c, /* call &MulMod */
+ 0x9c321300, /* addm r12, r19, r16 */
+ 0x7c601100, /* mov r24, r17 */
+ 0x7c640b00, /* mov r25, r11 */
+ 0x0800002c, /* call &MulMod */
+ 0xa02df300, /* subm r11, r19, r15 */
+ 0x7c601200, /* mov r24, r18 */
+ 0x7c640d00, /* mov r25, r13 */
+ 0x0800002c, /* call &MulMod */
+ 0x7c341300, /* mov r13, r19 */
+ 0x7c601100, /* mov r24, r17 */
+ 0x7c640e00, /* mov r25, r14 */
+ 0x0800002c, /* call &MulMod */
+ 0x9c366d00, /* addm r13, r13, r19 */
+ 0x0c000000, /* ret */
+/* } */
+/* @0xba: function ProjToAffine[116] { */
+#define CF_ProjToAffine_adr 186
+ 0x9c2bea00, /* addm r10, r10, r31 */
+ 0x7c600a00, /* mov r24, r10 */
+ 0x7c640a00, /* mov r25, r10 */
+ 0x0800002c, /* call &MulMod */
+ 0x7c601300, /* mov r24, r19 */
+ 0x7c640a00, /* mov r25, r10 */
+ 0x0800002c, /* call &MulMod */
+ 0x7c301300, /* mov r12, r19 */
+ 0x7c601300, /* mov r24, r19 */
+ 0x7c641300, /* mov r25, r19 */
+ 0x0800002c, /* call &MulMod */
+ 0x7c601300, /* mov r24, r19 */
+ 0x7c641300, /* mov r25, r19 */
+ 0x0800002c, /* call &MulMod */
+ 0x7c601300, /* mov r24, r19 */
+ 0x7c640c00, /* mov r25, r12 */
+ 0x0800002c, /* call &MulMod */
+ 0x7c341300, /* mov r13, r19 */
+ 0x05004004, /* loop #4 ( */
+ 0x7c601300, /* mov r24, r19 */
+ 0x7c641300, /* mov r25, r19 */
+ 0x0800002c, /* call &MulMod */
+ 0xfc000000, /* nop */
+ /* ) */
+ 0x7c601300, /* mov r24, r19 */
+ 0x7c640d00, /* mov r25, r13 */
+ 0x0800002c, /* call &MulMod */
+ 0x7c381300, /* mov r14, r19 */
+ 0x05008004, /* loop #8 ( */
+ 0x7c601300, /* mov r24, r19 */
+ 0x7c641300, /* mov r25, r19 */
+ 0x0800002c, /* call &MulMod */
+ 0xfc000000, /* nop */
+ /* ) */
+ 0x7c601300, /* mov r24, r19 */
+ 0x7c640e00, /* mov r25, r14 */
+ 0x0800002c, /* call &MulMod */
+ 0x7c3c1300, /* mov r15, r19 */
+ 0x05010004, /* loop #16 ( */
+ 0x7c601300, /* mov r24, r19 */
+ 0x7c641300, /* mov r25, r19 */
+ 0x0800002c, /* call &MulMod */
+ 0xfc000000, /* nop */
+ /* ) */
+ 0x7c601300, /* mov r24, r19 */
+ 0x7c640f00, /* mov r25, r15 */
+ 0x0800002c, /* call &MulMod */
+ 0x7c401300, /* mov r16, r19 */
+ 0x05020004, /* loop #32 ( */
+ 0x7c601300, /* mov r24, r19 */
+ 0x7c641300, /* mov r25, r19 */
+ 0x0800002c, /* call &MulMod */
+ 0xfc000000, /* nop */
+ /* ) */
+ 0x7c441300, /* mov r17, r19 */
+ 0x7c600a00, /* mov r24, r10 */
+ 0x7c641300, /* mov r25, r19 */
+ 0x0800002c, /* call &MulMod */
+ 0x050c0004, /* loop #192 ( */
+ 0x7c601300, /* mov r24, r19 */
+ 0x7c641300, /* mov r25, r19 */
+ 0x0800002c, /* call &MulMod */
+ 0xfc000000, /* nop */
+ /* ) */
+ 0x7c481300, /* mov r18, r19 */
+ 0x7c601100, /* mov r24, r17 */
+ 0x7c641000, /* mov r25, r16 */
+ 0x0800002c, /* call &MulMod */
+ 0x05010004, /* loop #16 ( */
+ 0x7c601300, /* mov r24, r19 */
+ 0x7c641300, /* mov r25, r19 */
+ 0x0800002c, /* call &MulMod */
+ 0xfc000000, /* nop */
+ /* ) */
+ 0x7c600f00, /* mov r24, r15 */
+ 0x7c641300, /* mov r25, r19 */
+ 0x0800002c, /* call &MulMod */
+ 0x05008004, /* loop #8 ( */
+ 0x7c601300, /* mov r24, r19 */
+ 0x7c641300, /* mov r25, r19 */
+ 0x0800002c, /* call &MulMod */
+ 0xfc000000, /* nop */
+ /* ) */
+ 0x7c600e00, /* mov r24, r14 */
+ 0x7c641300, /* mov r25, r19 */
+ 0x0800002c, /* call &MulMod */
+ 0x05004004, /* loop #4 ( */
+ 0x7c601300, /* mov r24, r19 */
+ 0x7c641300, /* mov r25, r19 */
+ 0x0800002c, /* call &MulMod */
+ 0xfc000000, /* nop */
+ /* ) */
+ 0x7c600d00, /* mov r24, r13 */
+ 0x7c641300, /* mov r25, r19 */
+ 0x0800002c, /* call &MulMod */
+ 0x05002004, /* loop #2 ( */
+ 0x7c601300, /* mov r24, r19 */
+ 0x7c641300, /* mov r25, r19 */
+ 0x0800002c, /* call &MulMod */
+ 0xfc000000, /* nop */
+ /* ) */
+ 0x7c600c00, /* mov r24, r12 */
+ 0x7c641300, /* mov r25, r19 */
+ 0x0800002c, /* call &MulMod */
+ 0x05002004, /* loop #2 ( */
+ 0x7c601300, /* mov r24, r19 */
+ 0x7c641300, /* mov r25, r19 */
+ 0x0800002c, /* call &MulMod */
+ 0xfc000000, /* nop */
+ /* ) */
+ 0x7c600a00, /* mov r24, r10 */
+ 0x7c641300, /* mov r25, r19 */
+ 0x0800002c, /* call &MulMod */
+ 0x7c601300, /* mov r24, r19 */
+ 0x7c641200, /* mov r25, r18 */
+ 0x0800002c, /* call &MulMod */
+ 0x7c381300, /* mov r14, r19 */
+ 0x7c600800, /* mov r24, r8 */
+ 0x7c640e00, /* mov r25, r14 */
+ 0x0800002c, /* call &MulMod */
+ 0x7c2c1300, /* mov r11, r19 */
+ 0x7c600900, /* mov r24, r9 */
+ 0x7c640e00, /* mov r25, r14 */
+ 0x0800002c, /* call &MulMod */
+ 0x7c301300, /* mov r12, r19 */
+ 0x0c000000, /* ret */
+/* } */
+/* @0x12e: function ModInv[17] { */
+#define CF_ModInv_adr 302
+ 0x98080000, /* stmod r2 */
+ 0x55080202, /* subi r2, r2, #2 */
+ 0x7c041e00, /* mov r1, r30 */
+ 0x0510000c, /* loop #256 ( */
+ 0x7c600100, /* mov r24, r1 */
+ 0x7c640100, /* mov r25, r1 */
+ 0x0800002c, /* call &MulMod */
+ 0x7c0c1300, /* mov r3, r19 */
+ 0x50084200, /* add r2, r2, r2 */
+ 0x64046108, /* selc r1, r1, r3 */
+ 0x1008813d, /* bnc nomul */
+ 0x7c600300, /* mov r24, r3 */
+ 0x7c640000, /* mov r25, r0 */
+ 0x0800002c, /* call &MulMod */
+ 0x7c041300, /* mov r1, r19 */
+ /*nomul: */
+ 0xfc000000, /* nop */
+ /* ) */
+ 0x0c000000, /* ret */
+/* } */
+/* @0x13f: function FetchBandRandomize[11] { */
+#define CF_FetchBandRandomize_adr 319
+ 0x99080000, /* strnd r2 */
+ 0x9c6be200, /* addm r26, r2, r31 */
+ 0x8c081500, /* ld *2, *5 */
+ 0x7c641a00, /* mov r25, r26 */
+ 0x0800002c, /* call &MulMod */
+ 0x7c181300, /* mov r6, r19 */
+ 0x8c081600, /* ld *2, *6 */
+ 0x7c641a00, /* mov r25, r26 */
+ 0x0800002c, /* call &MulMod */
+ 0x7c1c1300, /* mov r7, r19 */
+ 0x0c000000, /* ret */
+/* } */
+/* @0x14a: function ProjDouble[5] { */
+#define CF_ProjDouble_adr 330
+ 0x7c2c0800, /* mov r11, r8 */
+ 0x7c300900, /* mov r12, r9 */
+ 0x7c340a00, /* mov r13, r10 */
+ 0x0800006a, /* call &ProjAdd */
+ 0x0c000000, /* ret */
+/* } */
+/* @0x14f: function SetupP256NandMuLow[25] { */
+#define CF_SetupP256NandMuLow_adr 335
+ 0x55741f01, /* subi r29, r31, #1 */
+ 0x83750000, /* movi r29.6h, #0 */
+ 0x83740000, /* movi r29.6l, #0 */
+ 0x81f5bce6, /* movi r29.3h, #48358 */
+ 0x81f4faad, /* movi r29.3l, #64173 */
+ 0x8175a717, /* movi r29.2h, #42775 */
+ 0x81749e84, /* movi r29.2l, #40580 */
+ 0x80f5f3b9, /* movi r29.1h, #62393 */
+ 0x80f4cac2, /* movi r29.1l, #51906 */
+ 0x8075fc63, /* movi r29.0h, #64611 */
+ 0x80742551, /* movi r29.0l, #9553 */
+ 0x55701f01, /* subi r28, r31, #1 */
+ 0x83f10000, /* movi r28.7h, #0 */
+ 0x83f00000, /* movi r28.7l, #0 */
+ 0x82f0fffe, /* movi r28.5l, #65534 */
+ 0x81f14319, /* movi r28.3h, #17177 */
+ 0x81f00552, /* movi r28.3l, #1362 */
+ 0x8171df1a, /* movi r28.2h, #57114 */
+ 0x81706c21, /* movi r28.2l, #27681 */
+ 0x80f1012f, /* movi r28.1h, #303 */
+ 0x80f0fd85, /* movi r28.1l, #64901 */
+ 0x8071eedf, /* movi r28.0h, #61151 */
+ 0x80709bfe, /* movi r28.0l, #39934 */
+ 0x98801d00, /* ldmod r29 */
+ 0x0c000000, /* ret */
+/* } */
+/* @0x168: function ScalarMult_internal[51] { */
+#define CF_ScalarMult_internal_adr 360
+ 0x0800014f, /* call &SetupP256NandMuLow */
+ 0x8c041100, /* ld *1, *1 */
+ 0x9c07e100, /* addm r1, r1, r31 */
+ 0xa0002000, /* subm r0, r0, r1 */
+ 0x08000001, /* call &SetupP256PandMuLow */
+ 0x0800013f, /* call &FetchBandRandomize */
+ 0x7c200600, /* mov r8, r6 */
+ 0x7c240700, /* mov r9, r7 */
+ 0x7c281a00, /* mov r10, r26 */
+ 0x0800014a, /* call &ProjDouble */
+ 0x7c0c0b00, /* mov r3, r11 */
+ 0x7c100c00, /* mov r4, r12 */
+ 0x7c140d00, /* mov r5, r13 */
+ 0x7c201f00, /* mov r8, r31 */
+ 0x7c241e00, /* mov r9, r30 */
+ 0x7c281f00, /* mov r10, r31 */
+ 0x05100020, /* loop #256 ( */
+ 0x0800014a, /* call &ProjDouble */
+ 0x0800013f, /* call &FetchBandRandomize */
+ 0x4c202000, /* xor r8, r0, r1 */
+ 0x64206602, /* selm r8, r6, r3 */
+ 0x64248702, /* selm r9, r7, r4 */
+ 0x6428ba02, /* selm r10, r26, r5 */
+ 0x7c080b00, /* mov r2, r11 */
+ 0x7c180c00, /* mov r6, r12 */
+ 0x7c1c0d00, /* mov r7, r13 */
+ 0x0800006a, /* call &ProjAdd */
+ 0x44202000, /* or r8, r0, r1 */
+ 0x64204b02, /* selm r8, r11, r2 */
+ 0x6424cc02, /* selm r9, r12, r6 */
+ 0x6428ed02, /* selm r10, r13, r7 */
+ 0x680000ff, /* rshi r0, r0, r0 >> 255 */
+ 0x680421ff, /* rshi r1, r1, r1 >> 255 */
+ 0x992c0000, /* strnd r11 */
+ 0x99300000, /* strnd r12 */
+ 0x99340000, /* strnd r13 */
+ 0x99080000, /* strnd r2 */
+ 0x7c600300, /* mov r24, r3 */
+ 0x7c640200, /* mov r25, r2 */
+ 0x0800002c, /* call &MulMod */
+ 0x7c0c1300, /* mov r3, r19 */
+ 0x7c600400, /* mov r24, r4 */
+ 0x7c640200, /* mov r25, r2 */
+ 0x0800002c, /* call &MulMod */
+ 0x7c101300, /* mov r4, r19 */
+ 0x7c600500, /* mov r24, r5 */
+ 0x7c640200, /* mov r25, r2 */
+ 0x0800002c, /* call &MulMod */
+ 0x7c141300, /* mov r5, r19 */
+ /* ) */
+ 0x080000ba, /* call &ProjToAffine */
+ 0x0c000000, /* ret */
+/* } */
+/* @0x19b: function get_P256B[35] { */
+#define CF_get_P256B_adr 411
+ 0x7c201f00, /* mov r8, r31 */
+ 0x83a16b17, /* movi r8.7h, #27415 */
+ 0x83a0d1f2, /* movi r8.7l, #53746 */
+ 0x8321e12c, /* movi r8.6h, #57644 */
+ 0x83204247, /* movi r8.6l, #16967 */
+ 0x82a1f8bc, /* movi r8.5h, #63676 */
+ 0x82a0e6e5, /* movi r8.5l, #59109 */
+ 0x822163a4, /* movi r8.4h, #25508 */
+ 0x822040f2, /* movi r8.4l, #16626 */
+ 0x81a17703, /* movi r8.3h, #30467 */
+ 0x81a07d81, /* movi r8.3l, #32129 */
+ 0x81212deb, /* movi r8.2h, #11755 */
+ 0x812033a0, /* movi r8.2l, #13216 */
+ 0x80a1f4a1, /* movi r8.1h, #62625 */
+ 0x80a03945, /* movi r8.1l, #14661 */
+ 0x8021d898, /* movi r8.0h, #55448 */
+ 0x8020c296, /* movi r8.0l, #49814 */
+ 0x7c241f00, /* mov r9, r31 */
+ 0x83a54fe3, /* movi r9.7h, #20451 */
+ 0x83a442e2, /* movi r9.7l, #17122 */
+ 0x8325fe1a, /* movi r9.6h, #65050 */
+ 0x83247f9b, /* movi r9.6l, #32667 */
+ 0x82a58ee7, /* movi r9.5h, #36583 */
+ 0x82a4eb4a, /* movi r9.5l, #60234 */
+ 0x82257c0f, /* movi r9.4h, #31759 */
+ 0x82249e16, /* movi r9.4l, #40470 */
+ 0x81a52bce, /* movi r9.3h, #11214 */
+ 0x81a43357, /* movi r9.3l, #13143 */
+ 0x81256b31, /* movi r9.2h, #27441 */
+ 0x81245ece, /* movi r9.2l, #24270 */
+ 0x80a5cbb6, /* movi r9.1h, #52150 */
+ 0x80a44068, /* movi r9.1l, #16488 */
+ 0x802537bf, /* movi r9.0h, #14271 */
+ 0x802451f5, /* movi r9.0l, #20981 */
+ 0x0c000000, /* ret */
+/* } */
+/* @0x1be: function p256sign[34] { */
+#define CF_p256sign_adr 446
+ 0xfc000000, /* nop */
+ 0x84004000, /* ldi r0, [#0] */
+ 0x95800000, /* lddmp r0 */
+ 0x80000000, /* movi r0.0l, #0 */
+ 0x80800001, /* movi r0.1l, #1 */
+ 0x81000018, /* movi r0.2l, #24 */
+ 0x82000008, /* movi r0.4l, #8 */
+ 0x82800009, /* movi r0.5l, #9 */
+ 0x97800000, /* ldrfp r0 */
+ 0x0800019b, /* call &get_P256B */
+ 0x90540400, /* st *4, *5 */
+ 0x90580500, /* st *5, *6 */
+ 0xfc000000, /* nop */
+ 0x8c001000, /* ld *0, *0 */
+ 0x08000168, /* call &ScalarMult_internal */
+ 0x0800014f, /* call &SetupP256NandMuLow */
+ 0x8c001000, /* ld *0, *0 */
+ 0x0800012e, /* call &ModInv */
+ 0x8c081700, /* ld *2, *7 */
+ 0x7c640100, /* mov r25, r1 */
+ 0x0800002c, /* call &MulMod */
+ 0x9c63eb00, /* addm r24, r11, r31 */
+ 0x904c0200, /* st *2, *3 */
+ 0xfc000000, /* nop */
+ 0x7c641300, /* mov r25, r19 */
+ 0x0800002c, /* call &MulMod */
+ 0x7c001300, /* mov r0, r19 */
+ 0x8c081200, /* ld *2, *2 */
+ 0x7c640100, /* mov r25, r1 */
+ 0x0800002c, /* call &MulMod */
+ 0x9c001300, /* addm r0, r19, r0 */
+ 0x90500000, /* st *0, *4 */
+ 0x08000001, /* call &SetupP256PandMuLow */
+ 0x0c000000, /* ret */
+/* } */
+/* @0x1e0: function p256scalarbasemult[21] { */
+#define CF_p256scalarbasemult_adr 480
+ 0xfc000000, /* nop */
+ 0x84004000, /* ldi r0, [#0] */
+ 0x95800000, /* lddmp r0 */
+ 0x80000000, /* movi r0.0l, #0 */
+ 0x80800001, /* movi r0.1l, #1 */
+ 0x81000018, /* movi r0.2l, #24 */
+ 0x8180000b, /* movi r0.3l, #11 */
+ 0x82000008, /* movi r0.4l, #8 */
+ 0x82800009, /* movi r0.5l, #9 */
+ 0x97800000, /* ldrfp r0 */
+ 0x8c001100, /* ld *0, *1 */
+ 0x99800000, /* ldrnd r0 */
+ 0x0800019b, /* call &get_P256B */
+ 0x90540400, /* st *4, *5 */
+ 0x90580500, /* st *5, *6 */
+ 0xfc000000, /* nop */
+ 0x8c001700, /* ld *0, *7 */
+ 0x08000168, /* call &ScalarMult_internal */
+ 0x90540b00, /* st *3++, *5 */
+ 0x90580b00, /* st *3++, *6 */
+ 0x0c000000, /* ret */
+/* } */
+/* @0x1f5: function ModInvVar[37] { */
+#define CF_ModInvVar_adr 501
+ 0x7c081f00, /* mov r2, r31 */
+ 0x7c0c1e00, /* mov r3, r30 */
+ 0x98100000, /* stmod r4 */
+ 0x981c0000, /* stmod r7 */
+ 0x7c140000, /* mov r5, r0 */
+ /*impvt_Loop: */
+ 0x44108400, /* or r4, r4, r4 */
+ 0x10001205, /* bl impvt_Uodd */
+ 0x6813e401, /* rshi r4, r4, r31 >> 1 */
+ 0x44084200, /* or r2, r2, r2 */
+ 0x10001201, /* bl impvt_Rodd */
+ 0x680be201, /* rshi r2, r2, r31 >> 1 */
+ 0x100801fa, /* b impvt_Loop */
+ /*impvt_Rodd: */
+ 0x50084700, /* add r2, r7, r2 */
+ 0x509bff00, /* addc r6, r31, r31 */
+ 0x6808c201, /* rshi r2, r2, r6 >> 1 */
+ 0x100801fa, /* b impvt_Loop */
+ /*impvt_Uodd: */
+ 0x4414a500, /* or r5, r5, r5 */
+ 0x10001210, /* bl impvt_UVodd */
+ 0x6817e501, /* rshi r5, r5, r31 >> 1 */
+ 0x440c6300, /* or r3, r3, r3 */
+ 0x1000120c, /* bl impvt_Sodd */
+ 0x680fe301, /* rshi r3, r3, r31 >> 1 */
+ 0x100801fa, /* b impvt_Loop */
+ /*impvt_Sodd: */
+ 0x500c6700, /* add r3, r7, r3 */
+ 0x509bff00, /* addc r6, r31, r31 */
+ 0x680cc301, /* rshi r3, r3, r6 >> 1 */
+ 0x100801fa, /* b impvt_Loop */
+ /*impvt_UVodd: */
+ 0x5c008500, /* cmp r5, r4 */
+ 0x10088215, /* bnc impvt_V>=U */
+ 0xa0086200, /* subm r2, r2, r3 */
+ 0x5410a400, /* sub r4, r4, r5 */
+ 0x100801fa, /* b impvt_Loop */
+ /*impvt_V>=U: */
+ 0xa00c4300, /* subm r3, r3, r2 */
+ 0x54148500, /* sub r5, r5, r4 */
+ 0x100841fa, /* bnz impvt_Loop */
+ 0x9c07e200, /* addm r1, r2, r31 */
+ 0x0c000000, /* ret */
+/* } */
+/* @0x21a: function p256verify[80] { */
+#define CF_p256verify_adr 538
+ 0x84184000, /* ldi r6, [#0] */
+ 0x95800600, /* lddmp r6 */
+ 0x81980018, /* movi r6.3l, #24 */
+ 0x82180000, /* movi r6.4l, #0 */
+ 0x82980008, /* movi r6.5l, #8 */
+ 0x83180009, /* movi r6.6l, #9 */
+ 0x8018000b, /* movi r6.0l, #11 */
+ 0x8398000c, /* movi r6.7l, #12 */
+ 0x81180018, /* movi r6.2l, #24 */
+ 0x97800600, /* ldrfp r6 */
+ 0x8c0c1300, /* ld *3, *3 */
+ 0x7c600600, /* mov r24, r6 */
+ 0x48630000, /* not r24, r24 */
+ 0x0800014f, /* call &SetupP256NandMuLow */
+ 0x5c03e600, /* cmp r6, r31 */
+ 0x10004268, /* bz fail */
+ 0x5c03a600, /* cmp r6, r29 */
+ 0x10088268, /* bnc fail */
+ 0x8c101400, /* ld *4, *4 */
+ 0x5c03e000, /* cmp r0, r31 */
+ 0x10004268, /* bz fail */
+ 0x5c03a000, /* cmp r0, r29 */
+ 0x10088268, /* bnc fail */
+ 0x080001f5, /* call &ModInvVar */
+ 0x8c0c1300, /* ld *3, *3 */
+ 0x7c640100, /* mov r25, r1 */
+ 0x0800002c, /* call &MulMod */
+ 0x7c001300, /* mov r0, r19 */
+ 0x8c081200, /* ld *2, *2 */
+ 0x7c640100, /* mov r25, r1 */
+ 0x0800002c, /* call &MulMod */
+ 0x7c041300, /* mov r1, r19 */
+ 0x08000001, /* call &SetupP256PandMuLow */
+ 0x8c001500, /* ld *0, *5 */
+ 0x8c1c1600, /* ld *7, *6 */
+ 0x7c341e00, /* mov r13, r30 */
+ 0x0800019b, /* call &get_P256B */
+ 0x7c281e00, /* mov r10, r30 */
+ 0x0800006a, /* call &ProjAdd */
+ 0x7c0c0b00, /* mov r3, r11 */
+ 0x7c100c00, /* mov r4, r12 */
+ 0x7c140d00, /* mov r5, r13 */
+ 0x40082000, /* and r2, r0, r1 */
+ 0x7c2c1f00, /* mov r11, r31 */
+ 0x7c301e00, /* mov r12, r30 */
+ 0x7c341f00, /* mov r13, r31 */
+ 0x05100018, /* loop #256 ( */
+ 0x7c200b00, /* mov r8, r11 */
+ 0x7c240c00, /* mov r9, r12 */
+ 0x7c280d00, /* mov r10, r13 */
+ 0x0800006a, /* call &ProjAdd */
+ 0x50084200, /* add r2, r2, r2 */
+ 0x10088254, /* bnc noBoth */
+ 0x7c200300, /* mov r8, r3 */
+ 0x7c240400, /* mov r9, r4 */
+ 0x7c280500, /* mov r10, r5 */
+ 0x0800006a, /* call &ProjAdd */
+ 0x1008025f, /* b noY */
+ /*noBoth: */
+ 0x50180000, /* add r6, r0, r0 */
+ 0x1008825a, /* bnc noG */
+ 0x8c141500, /* ld *5, *5 */
+ 0x8c181600, /* ld *6, *6 */
+ 0x7c281e00, /* mov r10, r30 */
+ 0x0800006a, /* call &ProjAdd */
+ /*noG: */
+ 0x50182100, /* add r6, r1, r1 */
+ 0x1008825f, /* bnc noY */
+ 0x0800019b, /* call &get_P256B */
+ 0x7c281e00, /* mov r10, r30 */
+ 0x0800006a, /* call &ProjAdd */
+ /*noY: */
+ 0x50000000, /* add r0, r0, r0 */
+ 0x50042100, /* add r1, r1, r1 */
+ /* ) */
+ 0x7c000d00, /* mov r0, r13 */
+ 0x080001f5, /* call &ModInvVar */
+ 0x7c600100, /* mov r24, r1 */
+ 0x7c640b00, /* mov r25, r11 */
+ 0x0800002c, /* call &MulMod */
+ 0x0800014f, /* call &SetupP256NandMuLow */
+ 0xa063f300, /* subm r24, r19, r31 */
+ /*fail: */
+ 0x90440300, /* st *3, *1 */
+ 0x0c000000, /* ret */
+/* } */
+/* @0x26a: function p256scalarmult[12] { */
+#define CF_p256scalarmult_adr 618
+ 0x84004000, /* ldi r0, [#0] */
+ 0x95800000, /* lddmp r0 */
+ 0x80000000, /* movi r0.0l, #0 */
+ 0x80800001, /* movi r0.1l, #1 */
+ 0x81000018, /* movi r0.2l, #24 */
+ 0x8180000b, /* movi r0.3l, #11 */
+ 0x97800000, /* ldrfp r0 */
+ 0x8c001000, /* ld *0, *0 */
+ 0x08000168, /* call &ScalarMult_internal */
+ 0x90540b00, /* st *3++, *5 */
+ 0x90580b00, /* st *3++, *6 */
+ 0x0c000000, /* ret */
+ /* } */
+};
+/* clang-format on */
+
+#define DMEM_CELL_SIZE 32
+#define DMEM_INDEX(p, f) \
+ (((const uint8_t *) &(p)->f - (const uint8_t *) (p)) / DMEM_CELL_SIZE)
+
+/*
+ * This struct is "calling convention" for passing parameters into the
+ * code block above for ecc operations. Parameters start at &DMEM[0].
+ */
+struct DMEM_ecc {
+ uint32_t pK;
+ uint32_t pRnd;
+ uint32_t pMsg;
+ uint32_t pR;
+ uint32_t pS;
+ uint32_t pX;
+ uint32_t pY;
+ uint32_t pD;
+ p256_int k;
+ p256_int rnd;
+ p256_int msg;
+ p256_int r;
+ p256_int s;
+ p256_int x;
+ p256_int y;
+ p256_int d;
+};
+
+static void dcrypto_ecc_init(void)
+{
+ struct DMEM_ecc *pEcc =
+ (struct DMEM_ecc *) GREG32_ADDR(CRYPTO, DMEM_DUMMY);
+
+ dcrypto_imem_load(0, IMEM_dcrypto, ARRAY_SIZE(IMEM_dcrypto));
+
+ pEcc->pK = DMEM_INDEX(pEcc, k);
+ pEcc->pRnd = DMEM_INDEX(pEcc, rnd);
+ pEcc->pMsg = DMEM_INDEX(pEcc, msg);
+ pEcc->pR = DMEM_INDEX(pEcc, r);
+ pEcc->pS = DMEM_INDEX(pEcc, s);
+ pEcc->pX = DMEM_INDEX(pEcc, x);
+ pEcc->pY = DMEM_INDEX(pEcc, y);
+ pEcc->pD = DMEM_INDEX(pEcc, d);
+
+ /* (over)write first words to ensure pairwise mismatch. */
+ pEcc->k.a[0] = 1;
+ pEcc->rnd.a[0] = 2;
+ pEcc->msg.a[0] = 3;
+ pEcc->r.a[0] = 4;
+ pEcc->s.a[0] = 5;
+ pEcc->x.a[0] = 6;
+ pEcc->y.a[0] = 7;
+ pEcc->d.a[0] = 8;
+}
+
+/*
+ * Local copy function since for some reason we have p256_int as
+ * packed structs.
+ * This causes wrong writes (bytes vs. words) to the peripheral with
+ * struct copies in case the src operand is unaligned.
+ *
+ * Our peripheral dst are always aligned correctly.
+ * By making sure the src is aligned too, we get word copy behavior.
+ */
+static inline void cp8w(p256_int *dst, const p256_int *src)
+{
+ p256_int tmp;
+
+ tmp = *src;
+ *dst = tmp;
+}
+
+int dcrypto_p256_ecdsa_sign(const p256_int *key, const p256_int *message,
+ p256_int *r, p256_int *s)
+{
+ int i, result;
+ struct DMEM_ecc *pEcc =
+ (struct DMEM_ecc *) GREG32_ADDR(CRYPTO, DMEM_DUMMY);
+
+ dcrypto_init_and_lock();
+ dcrypto_ecc_init();
+ result = dcrypto_call(CF_p256init_adr);
+
+ /* Pick uniform 0 < k < R */
+ do {
+ for (i = 0; i < 8; ++i)
+ pEcc->rnd.a[i] ^= rand();
+ } while (p256_cmp(&SECP256r1_nMin2, &pEcc->rnd) < 0);
+
+ p256_add_d(&pEcc->rnd, 1, &pEcc->k);
+
+ for (i = 0; i < 8; ++i)
+ pEcc->rnd.a[i] = rand();
+
+ cp8w(&pEcc->msg, message);
+ cp8w(&pEcc->d, key);
+
+ result |= dcrypto_call(CF_p256sign_adr);
+
+ cp8w(r, &pEcc->r);
+ cp8w(s, &pEcc->s);
+
+ /* Wipe d,k */
+ cp8w(&pEcc->d, &pEcc->rnd);
+ cp8w(&pEcc->k, &pEcc->rnd);
+
+ dcrypto_unlock();
+ return result == 0;
+}
+
+int dcrypto_p256_base_point_mul(const p256_int *k, p256_int *x, p256_int *y)
+{
+ int i, result;
+ struct DMEM_ecc *pEcc =
+ (struct DMEM_ecc *) GREG32_ADDR(CRYPTO, DMEM_DUMMY);
+
+ dcrypto_init_and_lock();
+ dcrypto_ecc_init();
+ result = dcrypto_call(CF_p256init_adr);
+
+ for (i = 0; i < 8; ++i)
+ pEcc->rnd.a[i] ^= rand();
+
+ cp8w(&pEcc->d, k);
+
+ result |= dcrypto_call(CF_p256scalarbasemult_adr);
+
+ cp8w(x, &pEcc->x);
+ cp8w(y, &pEcc->y);
+
+ /* Wipe d */
+ cp8w(&pEcc->d, &pEcc->rnd);
+
+ dcrypto_unlock();
+ return result == 0;
+}
+
+int dcrypto_p256_point_mul(const p256_int *k, const p256_int *in_x,
+ const p256_int *in_y, p256_int *x, p256_int *y)
+{
+ int i, result;
+ struct DMEM_ecc *pEcc =
+ (struct DMEM_ecc *) GREG32_ADDR(CRYPTO, DMEM_DUMMY);
+
+ dcrypto_init_and_lock();
+ dcrypto_ecc_init();
+ result = dcrypto_call(CF_p256init_adr);
+
+ for (i = 0; i < 8; ++i)
+ pEcc->rnd.a[i] ^= rand();
+
+ cp8w(&pEcc->k, k);
+ cp8w(&pEcc->x, in_x);
+ cp8w(&pEcc->y, in_y);
+
+ result |= dcrypto_call(CF_p256scalarmult_adr);
+
+ cp8w(x, &pEcc->x);
+ cp8w(y, &pEcc->y);
+
+ /* Wipe k,x,y */
+ cp8w(&pEcc->k, &pEcc->rnd);
+ cp8w(&pEcc->x, &pEcc->rnd);
+ cp8w(&pEcc->y, &pEcc->rnd);
+
+ dcrypto_unlock();
+ return result == 0;
+}
+
+int dcrypto_p256_ecdsa_verify(const p256_int *key_x, const p256_int *key_y,
+ const p256_int *message, const p256_int *r,
+ const p256_int *s)
+{
+ int i, result;
+ struct DMEM_ecc *pEcc =
+ (struct DMEM_ecc *) GREG32_ADDR(CRYPTO, DMEM_DUMMY);
+
+ dcrypto_init_and_lock();
+ dcrypto_ecc_init();
+ result = dcrypto_call(CF_p256init_adr);
+
+ cp8w(&pEcc->msg, message);
+ cp8w(&pEcc->r, r);
+ cp8w(&pEcc->s, s);
+ cp8w(&pEcc->x, key_x);
+ cp8w(&pEcc->y, key_y);
+
+ result |= dcrypto_call(CF_p256verify_adr);
+
+ for (i = 0; i < 8; ++i)
+ result |= (pEcc->rnd.a[i] ^ r->a[i]);
+
+ dcrypto_unlock();
+ return result == 0;
+}
+
+int dcrypto_p256_is_valid_point(const p256_int *x, const p256_int *y)
+{
+ int i, result;
+ struct DMEM_ecc *pEcc =
+ (struct DMEM_ecc *) GREG32_ADDR(CRYPTO, DMEM_DUMMY);
+
+ dcrypto_init_and_lock();
+ dcrypto_ecc_init();
+ result = dcrypto_call(CF_p256init_adr);
+
+ cp8w(&pEcc->x, x);
+ cp8w(&pEcc->y, y);
+
+ result |= dcrypto_call(CF_p256isoncurve_adr);
+
+ for (i = 0; i < 8; ++i)
+ result |= (pEcc->r.a[i] ^ pEcc->s.a[i]);
+
+ dcrypto_unlock();
+ return result == 0;
+}
diff --git a/chip/g/dcrypto/dcrypto_sha512.c b/chip/g/dcrypto/dcrypto_sha512.c
index 10776659d7..cdaff6853b 100644
--- a/chip/g/dcrypto/dcrypto_sha512.c
+++ b/chip/g/dcrypto/dcrypto_sha512.c
@@ -39,428 +39,434 @@ static uint32_t t_dcrypto;
#endif /* CRYPTO_TEST_SETUP */
/* auto-generated from go test haven -test.run=TestSha512 -test.v */
+/* clang-format off */
static const uint32_t IMEM_dcrypto[] = {
-/* @0x0: function expandw[84] { */
-#define CF_expandw_adr 0
- 0x4c3def00, /* xor r15, r15, r15 */
- 0x803c0013, /* movi r15.0l, #19 */
- 0x80bc0016, /* movi r15.1l, #22 */
- 0x97800f00, /* ldrfp r15 */
- 0x05004003, /* loop #4 ( */
- 0x8c001800, /* ld *0, *0++ */
- 0x906c0800, /* st *0++, *3++ */
- 0xfc000000, /* nop */
- /* ) */
- 0x0501004a, /* loop #16 ( */
- 0x684a6080, /* rshi r18, r0, r19 >> 128 */
- 0x68443340, /* rshi r17, r19, r1 >> 64 */
- 0x683e3201, /* rshi r15, r18, r17 >> 1 */
- 0x68423208, /* rshi r16, r18, r17 >> 8 */
- 0x4c3e0f00, /* xor r15, r15, r16 */
- 0x6843f207, /* rshi r16, r18, r31 >> 7 */
- 0x4c3e0f00, /* xor r15, r15, r16 */
- 0x505df398, /* add r23, r19, r15 >> 192 */
- 0x505eb788, /* add r23, r23, r21 >> 64 */
- 0x684ac0c0, /* rshi r18, r0, r22 >> 192 */
- 0x68443680, /* rshi r17, r22, r1 >> 128 */
- 0x683e3213, /* rshi r15, r18, r17 >> 19 */
- 0x6842323d, /* rshi r16, r18, r17 >> 61 */
- 0x4c3e0f00, /* xor r15, r15, r16 */
- 0x6843f206, /* rshi r16, r18, r31 >> 6 */
- 0x4c3e0f00, /* xor r15, r15, r16 */
- 0x505df798, /* add r23, r23, r15 >> 192 */
- 0x684a60c0, /* rshi r18, r0, r19 >> 192 */
- 0x68443380, /* rshi r17, r19, r1 >> 128 */
- 0x683e3201, /* rshi r15, r18, r17 >> 1 */
- 0x68423208, /* rshi r16, r18, r17 >> 8 */
- 0x4c3e0f00, /* xor r15, r15, r16 */
- 0x6843f207, /* rshi r16, r18, r31 >> 7 */
- 0x4c3e0f00, /* xor r15, r15, r16 */
- 0x50627f88, /* add r24, r31, r19 >> 64 */
- 0x5061f898, /* add r24, r24, r15 >> 192 */
- 0x5062b890, /* add r24, r24, r21 >> 128 */
- 0x684416c0, /* rshi r17, r22, r0 >> 192 */
- 0x683e3613, /* rshi r15, r22, r17 >> 19 */
- 0x6842363d, /* rshi r16, r22, r17 >> 61 */
- 0x4c3e0f00, /* xor r15, r15, r16 */
- 0x6843f606, /* rshi r16, r22, r31 >> 6 */
- 0x4c3e0f00, /* xor r15, r15, r16 */
- 0x5061f898, /* add r24, r24, r15 >> 192 */
- 0x684433c0, /* rshi r17, r19, r1 >> 192 */
- 0x683e3301, /* rshi r15, r19, r17 >> 1 */
- 0x68423308, /* rshi r16, r19, r17 >> 8 */
- 0x4c3e0f00, /* xor r15, r15, r16 */
- 0x6843f307, /* rshi r16, r19, r31 >> 7 */
- 0x4c3e0f00, /* xor r15, r15, r16 */
- 0x50667f90, /* add r25, r31, r19 >> 128 */
- 0x5065f998, /* add r25, r25, r15 >> 192 */
- 0x5066b998, /* add r25, r25, r21 >> 192 */
- 0x684ae040, /* rshi r18, r0, r23 >> 64 */
- 0x683ef213, /* rshi r15, r18, r23 >> 19 */
- 0x6842f23d, /* rshi r16, r18, r23 >> 61 */
- 0x4c3e0f00, /* xor r15, r15, r16 */
- 0x6843f206, /* rshi r16, r18, r31 >> 6 */
- 0x4c3e0f00, /* xor r15, r15, r16 */
- 0x5065f998, /* add r25, r25, r15 >> 192 */
- 0x684a8040, /* rshi r18, r0, r20 >> 64 */
- 0x683e9201, /* rshi r15, r18, r20 >> 1 */
- 0x68429208, /* rshi r16, r18, r20 >> 8 */
- 0x4c3e0f00, /* xor r15, r15, r16 */
- 0x6843f207, /* rshi r16, r18, r31 >> 7 */
- 0x4c3e0f00, /* xor r15, r15, r16 */
- 0x506a7f98, /* add r26, r31, r19 >> 192 */
- 0x5069fa98, /* add r26, r26, r15 >> 192 */
- 0x506ada00, /* add r26, r26, r22 */
- 0x684b0040, /* rshi r18, r0, r24 >> 64 */
- 0x683f1213, /* rshi r15, r18, r24 >> 19 */
- 0x6843123d, /* rshi r16, r18, r24 >> 61 */
- 0x4c3e0f00, /* xor r15, r15, r16 */
- 0x6843f206, /* rshi r16, r18, r31 >> 6 */
- 0x4c3e0f00, /* xor r15, r15, r16 */
- 0x5069fa98, /* add r26, r26, r15 >> 192 */
- 0x7c4c1400, /* mov r19, r20 */
- 0x7c501500, /* mov r20, r21 */
- 0x7c541600, /* mov r21, r22 */
- 0x685af640, /* rshi r22, r22, r23 >> 64 */
- 0x685b1640, /* rshi r22, r22, r24 >> 64 */
- 0x685b3640, /* rshi r22, r22, r25 >> 64 */
- 0x685b5640, /* rshi r22, r22, r26 >> 64 */
- 0x906c0100, /* st *1, *3++ */
- /* ) */
- 0x0c000000, /* ret */
+/* @0x0: function tag[1] { */
+#define CF_tag_adr 0
+ 0xf8000003, /* sigini #3 */
/* } */
-/* @0x54: function Sha512_a[125] { */
-#define CF_Sha512_a_adr 84
- 0x68580c40, /* rshi r22, r12, r0 >> 64 */
- 0x683c161c, /* rshi r15, r22, r0 >> 28 */
- 0x68541622, /* rshi r21, r22, r0 >> 34 */
- 0x4c3eaf00, /* xor r15, r15, r21 */
- 0x68541627, /* rshi r21, r22, r0 >> 39 */
- 0x4c3eaf00, /* xor r15, r15, r21 */
- 0x40402000, /* and r16, r0, r1 */
- 0x40544000, /* and r21, r0, r2 */
- 0x4c42b000, /* xor r16, r16, r21 */
- 0x40544100, /* and r21, r1, r2 */
- 0x4c42b000, /* xor r16, r16, r21 */
- 0x68458fc0, /* rshi r17, r15, r12 >> 192 */
- 0x50461100, /* add r17, r17, r16 */
- 0x68588d40, /* rshi r22, r13, r4 >> 64 */
- 0x6848960e, /* rshi r18, r22, r4 >> 14 */
- 0x68549612, /* rshi r21, r22, r4 >> 18 */
- 0x4c4ab200, /* xor r18, r18, r21 */
- 0x684c9629, /* rshi r19, r22, r4 >> 41 */
- 0x4c4a7200, /* xor r18, r18, r19 */
- 0x404ca400, /* and r19, r4, r5 */
- 0x48548000, /* not r21, r4 */
- 0x4054d500, /* and r21, r21, r6 */
- 0x4c4eb300, /* xor r19, r19, r21 */
- 0x6851b2c0, /* rshi r20, r18, r13 >> 192 */
- 0x5050f400, /* add r20, r20, r7 */
- 0x50515480, /* add r20, r20, r10 >> 0 */
- 0x68558b00, /* rshi r21, r11, r12 >> 0 */
- 0x50567500, /* add r21, r21, r19 */
- 0x5052b400, /* add r20, r20, r21 */
- 0x500e8300, /* add r3, r3, r20 */
- 0x501e3400, /* add r7, r20, r17 */
- 0x6858ec40, /* rshi r22, r12, r7 >> 64 */
- 0x683cf61c, /* rshi r15, r22, r7 >> 28 */
- 0x6854f622, /* rshi r21, r22, r7 >> 34 */
- 0x4c3eaf00, /* xor r15, r15, r21 */
- 0x6854f627, /* rshi r21, r22, r7 >> 39 */
- 0x4c3eaf00, /* xor r15, r15, r21 */
- 0x40400700, /* and r16, r7, r0 */
- 0x40542700, /* and r21, r7, r1 */
- 0x4c42b000, /* xor r16, r16, r21 */
- 0x40542000, /* and r21, r0, r1 */
- 0x4c42b000, /* xor r16, r16, r21 */
- 0x68458fc0, /* rshi r17, r15, r12 >> 192 */
- 0x50461100, /* add r17, r17, r16 */
- 0x68586d40, /* rshi r22, r13, r3 >> 64 */
- 0x6848760e, /* rshi r18, r22, r3 >> 14 */
- 0x68547612, /* rshi r21, r22, r3 >> 18 */
- 0x4c4ab200, /* xor r18, r18, r21 */
- 0x684c7629, /* rshi r19, r22, r3 >> 41 */
- 0x4c4a7200, /* xor r18, r18, r19 */
- 0x404c8300, /* and r19, r3, r4 */
- 0x48546000, /* not r21, r3 */
- 0x4054b500, /* and r21, r21, r5 */
- 0x4c4eb300, /* xor r19, r19, r21 */
- 0x6851b2c0, /* rshi r20, r18, r13 >> 192 */
- 0x5050d400, /* add r20, r20, r6 */
- 0x50515488, /* add r20, r20, r10 >> 64 */
- 0x68558b40, /* rshi r21, r11, r12 >> 64 */
- 0x50567500, /* add r21, r21, r19 */
- 0x5052b400, /* add r20, r20, r21 */
- 0x500a8200, /* add r2, r2, r20 */
- 0x501a3400, /* add r6, r20, r17 */
- 0x6858cc40, /* rshi r22, r12, r6 >> 64 */
- 0x683cd61c, /* rshi r15, r22, r6 >> 28 */
- 0x6854d622, /* rshi r21, r22, r6 >> 34 */
- 0x4c3eaf00, /* xor r15, r15, r21 */
- 0x6854d627, /* rshi r21, r22, r6 >> 39 */
- 0x4c3eaf00, /* xor r15, r15, r21 */
- 0x4040e600, /* and r16, r6, r7 */
- 0x40540600, /* and r21, r6, r0 */
- 0x4c42b000, /* xor r16, r16, r21 */
- 0x40540700, /* and r21, r7, r0 */
- 0x4c42b000, /* xor r16, r16, r21 */
- 0x68458fc0, /* rshi r17, r15, r12 >> 192 */
- 0x50461100, /* add r17, r17, r16 */
- 0x68584d40, /* rshi r22, r13, r2 >> 64 */
- 0x6848560e, /* rshi r18, r22, r2 >> 14 */
- 0x68545612, /* rshi r21, r22, r2 >> 18 */
- 0x4c4ab200, /* xor r18, r18, r21 */
- 0x684c5629, /* rshi r19, r22, r2 >> 41 */
- 0x4c4a7200, /* xor r18, r18, r19 */
- 0x404c6200, /* and r19, r2, r3 */
- 0x48544000, /* not r21, r2 */
- 0x40549500, /* and r21, r21, r4 */
- 0x4c4eb300, /* xor r19, r19, r21 */
- 0x6851b2c0, /* rshi r20, r18, r13 >> 192 */
- 0x5050b400, /* add r20, r20, r5 */
- 0x50515490, /* add r20, r20, r10 >> 128 */
- 0x68558b80, /* rshi r21, r11, r12 >> 128 */
- 0x50567500, /* add r21, r21, r19 */
- 0x5052b400, /* add r20, r20, r21 */
- 0x50068100, /* add r1, r1, r20 */
- 0x50163400, /* add r5, r20, r17 */
- 0x6858ac40, /* rshi r22, r12, r5 >> 64 */
- 0x683cb61c, /* rshi r15, r22, r5 >> 28 */
- 0x6854b622, /* rshi r21, r22, r5 >> 34 */
- 0x4c3eaf00, /* xor r15, r15, r21 */
- 0x6854b627, /* rshi r21, r22, r5 >> 39 */
- 0x4c3eaf00, /* xor r15, r15, r21 */
- 0x4040c500, /* and r16, r5, r6 */
- 0x4054e500, /* and r21, r5, r7 */
- 0x4c42b000, /* xor r16, r16, r21 */
- 0x4054e600, /* and r21, r6, r7 */
- 0x4c42b000, /* xor r16, r16, r21 */
- 0x68458fc0, /* rshi r17, r15, r12 >> 192 */
- 0x50461100, /* add r17, r17, r16 */
- 0x68582d40, /* rshi r22, r13, r1 >> 64 */
- 0x6848360e, /* rshi r18, r22, r1 >> 14 */
- 0x68543612, /* rshi r21, r22, r1 >> 18 */
- 0x4c4ab200, /* xor r18, r18, r21 */
- 0x684c3629, /* rshi r19, r22, r1 >> 41 */
- 0x4c4a7200, /* xor r18, r18, r19 */
- 0x404c4100, /* and r19, r1, r2 */
- 0x48542000, /* not r21, r1 */
- 0x40547500, /* and r21, r21, r3 */
- 0x4c4eb300, /* xor r19, r19, r21 */
- 0x6851b2c0, /* rshi r20, r18, r13 >> 192 */
- 0x50509400, /* add r20, r20, r4 */
- 0x50515498, /* add r20, r20, r10 >> 192 */
- 0x68558bc0, /* rshi r21, r11, r12 >> 192 */
- 0x50567500, /* add r21, r21, r19 */
- 0x5052b400, /* add r20, r20, r21 */
- 0x50028000, /* add r0, r0, r20 */
- 0x50123400, /* add r4, r20, r17 */
- 0x0c000000, /* ret */
+/* @0x1: function expandw[84] { */
+#define CF_expandw_adr 1
+ 0x4c3def00, /* xor r15, r15, r15 */
+ 0x803c0013, /* movi r15.0l, #19 */
+ 0x80bc0016, /* movi r15.1l, #22 */
+ 0x97800f00, /* ldrfp r15 */
+ 0x05004003, /* loop #4 ( */
+ 0x8c001800, /* ld *0, *0++ */
+ 0x906c0800, /* st *0++, *3++ */
+ 0xfc000000, /* nop */
+ /* ) */
+ 0x0501004a, /* loop #16 ( */
+ 0x684a6080, /* rshi r18, r0, r19 >> 128 */
+ 0x68443340, /* rshi r17, r19, r1 >> 64 */
+ 0x683e3201, /* rshi r15, r18, r17 >> 1 */
+ 0x68423208, /* rshi r16, r18, r17 >> 8 */
+ 0x4c3e0f00, /* xor r15, r15, r16 */
+ 0x6843f207, /* rshi r16, r18, r31 >> 7 */
+ 0x4c3e0f00, /* xor r15, r15, r16 */
+ 0x505df398, /* add r23, r19, r15 >> 192 */
+ 0x505eb788, /* add r23, r23, r21 >> 64 */
+ 0x684ac0c0, /* rshi r18, r0, r22 >> 192 */
+ 0x68443680, /* rshi r17, r22, r1 >> 128 */
+ 0x683e3213, /* rshi r15, r18, r17 >> 19 */
+ 0x6842323d, /* rshi r16, r18, r17 >> 61 */
+ 0x4c3e0f00, /* xor r15, r15, r16 */
+ 0x6843f206, /* rshi r16, r18, r31 >> 6 */
+ 0x4c3e0f00, /* xor r15, r15, r16 */
+ 0x505df798, /* add r23, r23, r15 >> 192 */
+ 0x684a60c0, /* rshi r18, r0, r19 >> 192 */
+ 0x68443380, /* rshi r17, r19, r1 >> 128 */
+ 0x683e3201, /* rshi r15, r18, r17 >> 1 */
+ 0x68423208, /* rshi r16, r18, r17 >> 8 */
+ 0x4c3e0f00, /* xor r15, r15, r16 */
+ 0x6843f207, /* rshi r16, r18, r31 >> 7 */
+ 0x4c3e0f00, /* xor r15, r15, r16 */
+ 0x50627f88, /* add r24, r31, r19 >> 64 */
+ 0x5061f898, /* add r24, r24, r15 >> 192 */
+ 0x5062b890, /* add r24, r24, r21 >> 128 */
+ 0x684416c0, /* rshi r17, r22, r0 >> 192 */
+ 0x683e3613, /* rshi r15, r22, r17 >> 19 */
+ 0x6842363d, /* rshi r16, r22, r17 >> 61 */
+ 0x4c3e0f00, /* xor r15, r15, r16 */
+ 0x6843f606, /* rshi r16, r22, r31 >> 6 */
+ 0x4c3e0f00, /* xor r15, r15, r16 */
+ 0x5061f898, /* add r24, r24, r15 >> 192 */
+ 0x684433c0, /* rshi r17, r19, r1 >> 192 */
+ 0x683e3301, /* rshi r15, r19, r17 >> 1 */
+ 0x68423308, /* rshi r16, r19, r17 >> 8 */
+ 0x4c3e0f00, /* xor r15, r15, r16 */
+ 0x6843f307, /* rshi r16, r19, r31 >> 7 */
+ 0x4c3e0f00, /* xor r15, r15, r16 */
+ 0x50667f90, /* add r25, r31, r19 >> 128 */
+ 0x5065f998, /* add r25, r25, r15 >> 192 */
+ 0x5066b998, /* add r25, r25, r21 >> 192 */
+ 0x684ae040, /* rshi r18, r0, r23 >> 64 */
+ 0x683ef213, /* rshi r15, r18, r23 >> 19 */
+ 0x6842f23d, /* rshi r16, r18, r23 >> 61 */
+ 0x4c3e0f00, /* xor r15, r15, r16 */
+ 0x6843f206, /* rshi r16, r18, r31 >> 6 */
+ 0x4c3e0f00, /* xor r15, r15, r16 */
+ 0x5065f998, /* add r25, r25, r15 >> 192 */
+ 0x684a8040, /* rshi r18, r0, r20 >> 64 */
+ 0x683e9201, /* rshi r15, r18, r20 >> 1 */
+ 0x68429208, /* rshi r16, r18, r20 >> 8 */
+ 0x4c3e0f00, /* xor r15, r15, r16 */
+ 0x6843f207, /* rshi r16, r18, r31 >> 7 */
+ 0x4c3e0f00, /* xor r15, r15, r16 */
+ 0x506a7f98, /* add r26, r31, r19 >> 192 */
+ 0x5069fa98, /* add r26, r26, r15 >> 192 */
+ 0x506ada00, /* add r26, r26, r22 */
+ 0x684b0040, /* rshi r18, r0, r24 >> 64 */
+ 0x683f1213, /* rshi r15, r18, r24 >> 19 */
+ 0x6843123d, /* rshi r16, r18, r24 >> 61 */
+ 0x4c3e0f00, /* xor r15, r15, r16 */
+ 0x6843f206, /* rshi r16, r18, r31 >> 6 */
+ 0x4c3e0f00, /* xor r15, r15, r16 */
+ 0x5069fa98, /* add r26, r26, r15 >> 192 */
+ 0x7c4c1400, /* mov r19, r20 */
+ 0x7c501500, /* mov r20, r21 */
+ 0x7c541600, /* mov r21, r22 */
+ 0x685af640, /* rshi r22, r22, r23 >> 64 */
+ 0x685b1640, /* rshi r22, r22, r24 >> 64 */
+ 0x685b3640, /* rshi r22, r22, r25 >> 64 */
+ 0x685b5640, /* rshi r22, r22, r26 >> 64 */
+ 0x906c0100, /* st *1, *3++ */
+ /* ) */
+ 0x0c000000, /* ret */
/* } */
-/* @0xd1: function Sha512_b[125] { */
-#define CF_Sha512_b_adr 209
- 0x68588d40, /* rshi r22, r13, r4 >> 64 */
- 0x683c961c, /* rshi r15, r22, r4 >> 28 */
- 0x68549622, /* rshi r21, r22, r4 >> 34 */
- 0x4c3eaf00, /* xor r15, r15, r21 */
- 0x68549627, /* rshi r21, r22, r4 >> 39 */
- 0x4c3eaf00, /* xor r15, r15, r21 */
- 0x4040a400, /* and r16, r4, r5 */
- 0x4054c400, /* and r21, r4, r6 */
- 0x4c42b000, /* xor r16, r16, r21 */
- 0x4054c500, /* and r21, r5, r6 */
- 0x4c42b000, /* xor r16, r16, r21 */
- 0x6845afc0, /* rshi r17, r15, r13 >> 192 */
- 0x50461100, /* add r17, r17, r16 */
- 0x68580c40, /* rshi r22, r12, r0 >> 64 */
- 0x6848160e, /* rshi r18, r22, r0 >> 14 */
- 0x68541612, /* rshi r21, r22, r0 >> 18 */
- 0x4c4ab200, /* xor r18, r18, r21 */
- 0x684c1629, /* rshi r19, r22, r0 >> 41 */
- 0x4c4a7200, /* xor r18, r18, r19 */
- 0x404c2000, /* and r19, r0, r1 */
- 0x48540000, /* not r21, r0 */
- 0x40545500, /* and r21, r21, r2 */
- 0x4c4eb300, /* xor r19, r19, r21 */
- 0x685192c0, /* rshi r20, r18, r12 >> 192 */
- 0x50507400, /* add r20, r20, r3 */
- 0x50515480, /* add r20, r20, r10 >> 0 */
- 0x6855ab00, /* rshi r21, r11, r13 >> 0 */
- 0x50567500, /* add r21, r21, r19 */
- 0x5052b400, /* add r20, r20, r21 */
- 0x501e8700, /* add r7, r7, r20 */
- 0x500e3400, /* add r3, r20, r17 */
- 0x68586d40, /* rshi r22, r13, r3 >> 64 */
- 0x683c761c, /* rshi r15, r22, r3 >> 28 */
- 0x68547622, /* rshi r21, r22, r3 >> 34 */
- 0x4c3eaf00, /* xor r15, r15, r21 */
- 0x68547627, /* rshi r21, r22, r3 >> 39 */
- 0x4c3eaf00, /* xor r15, r15, r21 */
- 0x40408300, /* and r16, r3, r4 */
- 0x4054a300, /* and r21, r3, r5 */
- 0x4c42b000, /* xor r16, r16, r21 */
- 0x4054a400, /* and r21, r4, r5 */
- 0x4c42b000, /* xor r16, r16, r21 */
- 0x6845afc0, /* rshi r17, r15, r13 >> 192 */
- 0x50461100, /* add r17, r17, r16 */
- 0x6858ec40, /* rshi r22, r12, r7 >> 64 */
- 0x6848f60e, /* rshi r18, r22, r7 >> 14 */
- 0x6854f612, /* rshi r21, r22, r7 >> 18 */
- 0x4c4ab200, /* xor r18, r18, r21 */
- 0x684cf629, /* rshi r19, r22, r7 >> 41 */
- 0x4c4a7200, /* xor r18, r18, r19 */
- 0x404c0700, /* and r19, r7, r0 */
- 0x4854e000, /* not r21, r7 */
- 0x40543500, /* and r21, r21, r1 */
- 0x4c4eb300, /* xor r19, r19, r21 */
- 0x685192c0, /* rshi r20, r18, r12 >> 192 */
- 0x50505400, /* add r20, r20, r2 */
- 0x50515488, /* add r20, r20, r10 >> 64 */
- 0x6855ab40, /* rshi r21, r11, r13 >> 64 */
- 0x50567500, /* add r21, r21, r19 */
- 0x5052b400, /* add r20, r20, r21 */
- 0x501a8600, /* add r6, r6, r20 */
- 0x500a3400, /* add r2, r20, r17 */
- 0x68584d40, /* rshi r22, r13, r2 >> 64 */
- 0x683c561c, /* rshi r15, r22, r2 >> 28 */
- 0x68545622, /* rshi r21, r22, r2 >> 34 */
- 0x4c3eaf00, /* xor r15, r15, r21 */
- 0x68545627, /* rshi r21, r22, r2 >> 39 */
- 0x4c3eaf00, /* xor r15, r15, r21 */
- 0x40406200, /* and r16, r2, r3 */
- 0x40548200, /* and r21, r2, r4 */
- 0x4c42b000, /* xor r16, r16, r21 */
- 0x40548300, /* and r21, r3, r4 */
- 0x4c42b000, /* xor r16, r16, r21 */
- 0x6845afc0, /* rshi r17, r15, r13 >> 192 */
- 0x50461100, /* add r17, r17, r16 */
- 0x6858cc40, /* rshi r22, r12, r6 >> 64 */
- 0x6848d60e, /* rshi r18, r22, r6 >> 14 */
- 0x6854d612, /* rshi r21, r22, r6 >> 18 */
- 0x4c4ab200, /* xor r18, r18, r21 */
- 0x684cd629, /* rshi r19, r22, r6 >> 41 */
- 0x4c4a7200, /* xor r18, r18, r19 */
- 0x404ce600, /* and r19, r6, r7 */
- 0x4854c000, /* not r21, r6 */
- 0x40541500, /* and r21, r21, r0 */
- 0x4c4eb300, /* xor r19, r19, r21 */
- 0x685192c0, /* rshi r20, r18, r12 >> 192 */
- 0x50503400, /* add r20, r20, r1 */
- 0x50515490, /* add r20, r20, r10 >> 128 */
- 0x6855ab80, /* rshi r21, r11, r13 >> 128 */
- 0x50567500, /* add r21, r21, r19 */
- 0x5052b400, /* add r20, r20, r21 */
- 0x50168500, /* add r5, r5, r20 */
- 0x50063400, /* add r1, r20, r17 */
- 0x68582d40, /* rshi r22, r13, r1 >> 64 */
- 0x683c361c, /* rshi r15, r22, r1 >> 28 */
- 0x68543622, /* rshi r21, r22, r1 >> 34 */
- 0x4c3eaf00, /* xor r15, r15, r21 */
- 0x68543627, /* rshi r21, r22, r1 >> 39 */
- 0x4c3eaf00, /* xor r15, r15, r21 */
- 0x40404100, /* and r16, r1, r2 */
- 0x40546100, /* and r21, r1, r3 */
- 0x4c42b000, /* xor r16, r16, r21 */
- 0x40546200, /* and r21, r2, r3 */
- 0x4c42b000, /* xor r16, r16, r21 */
- 0x6845afc0, /* rshi r17, r15, r13 >> 192 */
- 0x50461100, /* add r17, r17, r16 */
- 0x6858ac40, /* rshi r22, r12, r5 >> 64 */
- 0x6848b60e, /* rshi r18, r22, r5 >> 14 */
- 0x6854b612, /* rshi r21, r22, r5 >> 18 */
- 0x4c4ab200, /* xor r18, r18, r21 */
- 0x684cb629, /* rshi r19, r22, r5 >> 41 */
- 0x4c4a7200, /* xor r18, r18, r19 */
- 0x404cc500, /* and r19, r5, r6 */
- 0x4854a000, /* not r21, r5 */
- 0x4054f500, /* and r21, r21, r7 */
- 0x4c4eb300, /* xor r19, r19, r21 */
- 0x685192c0, /* rshi r20, r18, r12 >> 192 */
- 0x50501400, /* add r20, r20, r0 */
- 0x50515498, /* add r20, r20, r10 >> 192 */
- 0x6855abc0, /* rshi r21, r11, r13 >> 192 */
- 0x50567500, /* add r21, r21, r19 */
- 0x5052b400, /* add r20, r20, r21 */
- 0x50128400, /* add r4, r4, r20 */
- 0x50023400, /* add r0, r20, r17 */
- 0x0c000000, /* ret */
+/* @0x55: function Sha512_a[125] { */
+#define CF_Sha512_a_adr 85
+ 0x68580c40, /* rshi r22, r12, r0 >> 64 */
+ 0x683c161c, /* rshi r15, r22, r0 >> 28 */
+ 0x68541622, /* rshi r21, r22, r0 >> 34 */
+ 0x4c3eaf00, /* xor r15, r15, r21 */
+ 0x68541627, /* rshi r21, r22, r0 >> 39 */
+ 0x4c3eaf00, /* xor r15, r15, r21 */
+ 0x40402000, /* and r16, r0, r1 */
+ 0x40544000, /* and r21, r0, r2 */
+ 0x4c42b000, /* xor r16, r16, r21 */
+ 0x40544100, /* and r21, r1, r2 */
+ 0x4c42b000, /* xor r16, r16, r21 */
+ 0x68458fc0, /* rshi r17, r15, r12 >> 192 */
+ 0x50461100, /* add r17, r17, r16 */
+ 0x68588d40, /* rshi r22, r13, r4 >> 64 */
+ 0x6848960e, /* rshi r18, r22, r4 >> 14 */
+ 0x68549612, /* rshi r21, r22, r4 >> 18 */
+ 0x4c4ab200, /* xor r18, r18, r21 */
+ 0x684c9629, /* rshi r19, r22, r4 >> 41 */
+ 0x4c4a7200, /* xor r18, r18, r19 */
+ 0x404ca400, /* and r19, r4, r5 */
+ 0x48548000, /* not r21, r4 */
+ 0x4054d500, /* and r21, r21, r6 */
+ 0x4c4eb300, /* xor r19, r19, r21 */
+ 0x6851b2c0, /* rshi r20, r18, r13 >> 192 */
+ 0x5050f400, /* add r20, r20, r7 */
+ 0x50515480, /* add r20, r20, r10 >> 0 */
+ 0x68558b00, /* rshi r21, r11, r12 >> 0 */
+ 0x50567500, /* add r21, r21, r19 */
+ 0x5052b400, /* add r20, r20, r21 */
+ 0x500e8300, /* add r3, r3, r20 */
+ 0x501e3400, /* add r7, r20, r17 */
+ 0x6858ec40, /* rshi r22, r12, r7 >> 64 */
+ 0x683cf61c, /* rshi r15, r22, r7 >> 28 */
+ 0x6854f622, /* rshi r21, r22, r7 >> 34 */
+ 0x4c3eaf00, /* xor r15, r15, r21 */
+ 0x6854f627, /* rshi r21, r22, r7 >> 39 */
+ 0x4c3eaf00, /* xor r15, r15, r21 */
+ 0x40400700, /* and r16, r7, r0 */
+ 0x40542700, /* and r21, r7, r1 */
+ 0x4c42b000, /* xor r16, r16, r21 */
+ 0x40542000, /* and r21, r0, r1 */
+ 0x4c42b000, /* xor r16, r16, r21 */
+ 0x68458fc0, /* rshi r17, r15, r12 >> 192 */
+ 0x50461100, /* add r17, r17, r16 */
+ 0x68586d40, /* rshi r22, r13, r3 >> 64 */
+ 0x6848760e, /* rshi r18, r22, r3 >> 14 */
+ 0x68547612, /* rshi r21, r22, r3 >> 18 */
+ 0x4c4ab200, /* xor r18, r18, r21 */
+ 0x684c7629, /* rshi r19, r22, r3 >> 41 */
+ 0x4c4a7200, /* xor r18, r18, r19 */
+ 0x404c8300, /* and r19, r3, r4 */
+ 0x48546000, /* not r21, r3 */
+ 0x4054b500, /* and r21, r21, r5 */
+ 0x4c4eb300, /* xor r19, r19, r21 */
+ 0x6851b2c0, /* rshi r20, r18, r13 >> 192 */
+ 0x5050d400, /* add r20, r20, r6 */
+ 0x50515488, /* add r20, r20, r10 >> 64 */
+ 0x68558b40, /* rshi r21, r11, r12 >> 64 */
+ 0x50567500, /* add r21, r21, r19 */
+ 0x5052b400, /* add r20, r20, r21 */
+ 0x500a8200, /* add r2, r2, r20 */
+ 0x501a3400, /* add r6, r20, r17 */
+ 0x6858cc40, /* rshi r22, r12, r6 >> 64 */
+ 0x683cd61c, /* rshi r15, r22, r6 >> 28 */
+ 0x6854d622, /* rshi r21, r22, r6 >> 34 */
+ 0x4c3eaf00, /* xor r15, r15, r21 */
+ 0x6854d627, /* rshi r21, r22, r6 >> 39 */
+ 0x4c3eaf00, /* xor r15, r15, r21 */
+ 0x4040e600, /* and r16, r6, r7 */
+ 0x40540600, /* and r21, r6, r0 */
+ 0x4c42b000, /* xor r16, r16, r21 */
+ 0x40540700, /* and r21, r7, r0 */
+ 0x4c42b000, /* xor r16, r16, r21 */
+ 0x68458fc0, /* rshi r17, r15, r12 >> 192 */
+ 0x50461100, /* add r17, r17, r16 */
+ 0x68584d40, /* rshi r22, r13, r2 >> 64 */
+ 0x6848560e, /* rshi r18, r22, r2 >> 14 */
+ 0x68545612, /* rshi r21, r22, r2 >> 18 */
+ 0x4c4ab200, /* xor r18, r18, r21 */
+ 0x684c5629, /* rshi r19, r22, r2 >> 41 */
+ 0x4c4a7200, /* xor r18, r18, r19 */
+ 0x404c6200, /* and r19, r2, r3 */
+ 0x48544000, /* not r21, r2 */
+ 0x40549500, /* and r21, r21, r4 */
+ 0x4c4eb300, /* xor r19, r19, r21 */
+ 0x6851b2c0, /* rshi r20, r18, r13 >> 192 */
+ 0x5050b400, /* add r20, r20, r5 */
+ 0x50515490, /* add r20, r20, r10 >> 128 */
+ 0x68558b80, /* rshi r21, r11, r12 >> 128 */
+ 0x50567500, /* add r21, r21, r19 */
+ 0x5052b400, /* add r20, r20, r21 */
+ 0x50068100, /* add r1, r1, r20 */
+ 0x50163400, /* add r5, r20, r17 */
+ 0x6858ac40, /* rshi r22, r12, r5 >> 64 */
+ 0x683cb61c, /* rshi r15, r22, r5 >> 28 */
+ 0x6854b622, /* rshi r21, r22, r5 >> 34 */
+ 0x4c3eaf00, /* xor r15, r15, r21 */
+ 0x6854b627, /* rshi r21, r22, r5 >> 39 */
+ 0x4c3eaf00, /* xor r15, r15, r21 */
+ 0x4040c500, /* and r16, r5, r6 */
+ 0x4054e500, /* and r21, r5, r7 */
+ 0x4c42b000, /* xor r16, r16, r21 */
+ 0x4054e600, /* and r21, r6, r7 */
+ 0x4c42b000, /* xor r16, r16, r21 */
+ 0x68458fc0, /* rshi r17, r15, r12 >> 192 */
+ 0x50461100, /* add r17, r17, r16 */
+ 0x68582d40, /* rshi r22, r13, r1 >> 64 */
+ 0x6848360e, /* rshi r18, r22, r1 >> 14 */
+ 0x68543612, /* rshi r21, r22, r1 >> 18 */
+ 0x4c4ab200, /* xor r18, r18, r21 */
+ 0x684c3629, /* rshi r19, r22, r1 >> 41 */
+ 0x4c4a7200, /* xor r18, r18, r19 */
+ 0x404c4100, /* and r19, r1, r2 */
+ 0x48542000, /* not r21, r1 */
+ 0x40547500, /* and r21, r21, r3 */
+ 0x4c4eb300, /* xor r19, r19, r21 */
+ 0x6851b2c0, /* rshi r20, r18, r13 >> 192 */
+ 0x50509400, /* add r20, r20, r4 */
+ 0x50515498, /* add r20, r20, r10 >> 192 */
+ 0x68558bc0, /* rshi r21, r11, r12 >> 192 */
+ 0x50567500, /* add r21, r21, r19 */
+ 0x5052b400, /* add r20, r20, r21 */
+ 0x50028000, /* add r0, r0, r20 */
+ 0x50123400, /* add r4, r20, r17 */
+ 0x0c000000, /* ret */
/* } */
-/* @0x14e: function compress[70] { */
-#define CF_compress_adr 334
- 0xfc000000, /* nop */
- 0x4c7fff00, /* xor r31, r31, r31 */
- 0x4c000000, /* xor r0, r0, r0 */
- 0x4c042100, /* xor r1, r1, r1 */
- 0x55000001, /* subi r0, r0, #1 */
- 0x55040101, /* subi r1, r1, #1 */
- 0x84204100, /* ldi r8, [#8] */
- 0x94800800, /* ldlc r8 */
- 0x4c3def00, /* xor r15, r15, r15 */
- 0x803c000a, /* movi r15.0l, #10 */
- 0x95800f00, /* lddmp r15 */
- 0x06000039, /* loop *0 ( */
- 0x953c0000, /* stdmp r15 */
- 0x81bc002a, /* movi r15.3l, #42 */
- 0x95800f00, /* lddmp r15 */
- 0x08000000, /* call &expandw */
- 0x84004000, /* ldi r0, [#0] */
- 0x84044020, /* ldi r1, [#1] */
- 0x84084040, /* ldi r2, [#2] */
- 0x840c4060, /* ldi r3, [#3] */
- 0x84104080, /* ldi r4, [#4] */
- 0x841440a0, /* ldi r5, [#5] */
- 0x841840c0, /* ldi r6, [#6] */
- 0x841c40e0, /* ldi r7, [#7] */
- 0x4c3def00, /* xor r15, r15, r15 */
- 0x803c0060, /* movi r15.0l, #96 */
- 0x80bc000a, /* movi r15.1l, #10 */
- 0x813c000b, /* movi r15.2l, #11 */
- 0x96800f00, /* lddrp r15 */
- 0x97800f00, /* ldrfp r15 */
- 0x953c0000, /* stdmp r15 */
- 0x81bc002a, /* movi r15.3l, #42 */
- 0x95800f00, /* lddmp r15 */
- 0x4c318c00, /* xor r12, r12, r12 */
- 0x4c35ad00, /* xor r13, r13, r13 */
- 0x55300c01, /* subi r12, r12, #1 */
- 0x55340d01, /* subi r13, r13, #1 */
- 0x0500a007, /* loop #10 ( */
- 0x8c440800, /* ldc *1, *0++ */
- 0x8c081b00, /* ld *2, *3++ */
- 0x08000054, /* call &Sha512_a */
- 0x8c440800, /* ldc *1, *0++ */
- 0x8c081b00, /* ld *2, *3++ */
- 0x080000d1, /* call &Sha512_b */
- 0xfc000000, /* nop */
- /* ) */
- 0x843c4000, /* ldi r15, [#0] */
- 0x5001e000, /* add r0, r0, r15 */
- 0x843c4020, /* ldi r15, [#1] */
- 0x5005e100, /* add r1, r1, r15 */
- 0x843c4040, /* ldi r15, [#2] */
- 0x5009e200, /* add r2, r2, r15 */
- 0x843c4060, /* ldi r15, [#3] */
- 0x500de300, /* add r3, r3, r15 */
- 0x843c4080, /* ldi r15, [#4] */
- 0x5011e400, /* add r4, r4, r15 */
- 0x843c40a0, /* ldi r15, [#5] */
- 0x5015e500, /* add r5, r5, r15 */
- 0x843c40c0, /* ldi r15, [#6] */
- 0x5019e600, /* add r6, r6, r15 */
- 0x843c40e0, /* ldi r15, [#7] */
- 0x501de700, /* add r7, r7, r15 */
- 0x88004000, /* sti r0, [#0] */
- 0x88044020, /* sti r1, [#1] */
- 0x88084040, /* sti r2, [#2] */
- 0x880c4060, /* sti r3, [#3] */
- 0x88104080, /* sti r4, [#4] */
- 0x881440a0, /* sti r5, [#5] */
- 0x881840c0, /* sti r6, [#6] */
- 0x881c40e0, /* sti r7, [#7] */
- /* ) */
- 0x0c000000, /* ret */
- /* } */
+/* @0xd2: function Sha512_b[125] { */
+#define CF_Sha512_b_adr 210
+ 0x68588d40, /* rshi r22, r13, r4 >> 64 */
+ 0x683c961c, /* rshi r15, r22, r4 >> 28 */
+ 0x68549622, /* rshi r21, r22, r4 >> 34 */
+ 0x4c3eaf00, /* xor r15, r15, r21 */
+ 0x68549627, /* rshi r21, r22, r4 >> 39 */
+ 0x4c3eaf00, /* xor r15, r15, r21 */
+ 0x4040a400, /* and r16, r4, r5 */
+ 0x4054c400, /* and r21, r4, r6 */
+ 0x4c42b000, /* xor r16, r16, r21 */
+ 0x4054c500, /* and r21, r5, r6 */
+ 0x4c42b000, /* xor r16, r16, r21 */
+ 0x6845afc0, /* rshi r17, r15, r13 >> 192 */
+ 0x50461100, /* add r17, r17, r16 */
+ 0x68580c40, /* rshi r22, r12, r0 >> 64 */
+ 0x6848160e, /* rshi r18, r22, r0 >> 14 */
+ 0x68541612, /* rshi r21, r22, r0 >> 18 */
+ 0x4c4ab200, /* xor r18, r18, r21 */
+ 0x684c1629, /* rshi r19, r22, r0 >> 41 */
+ 0x4c4a7200, /* xor r18, r18, r19 */
+ 0x404c2000, /* and r19, r0, r1 */
+ 0x48540000, /* not r21, r0 */
+ 0x40545500, /* and r21, r21, r2 */
+ 0x4c4eb300, /* xor r19, r19, r21 */
+ 0x685192c0, /* rshi r20, r18, r12 >> 192 */
+ 0x50507400, /* add r20, r20, r3 */
+ 0x50515480, /* add r20, r20, r10 >> 0 */
+ 0x6855ab00, /* rshi r21, r11, r13 >> 0 */
+ 0x50567500, /* add r21, r21, r19 */
+ 0x5052b400, /* add r20, r20, r21 */
+ 0x501e8700, /* add r7, r7, r20 */
+ 0x500e3400, /* add r3, r20, r17 */
+ 0x68586d40, /* rshi r22, r13, r3 >> 64 */
+ 0x683c761c, /* rshi r15, r22, r3 >> 28 */
+ 0x68547622, /* rshi r21, r22, r3 >> 34 */
+ 0x4c3eaf00, /* xor r15, r15, r21 */
+ 0x68547627, /* rshi r21, r22, r3 >> 39 */
+ 0x4c3eaf00, /* xor r15, r15, r21 */
+ 0x40408300, /* and r16, r3, r4 */
+ 0x4054a300, /* and r21, r3, r5 */
+ 0x4c42b000, /* xor r16, r16, r21 */
+ 0x4054a400, /* and r21, r4, r5 */
+ 0x4c42b000, /* xor r16, r16, r21 */
+ 0x6845afc0, /* rshi r17, r15, r13 >> 192 */
+ 0x50461100, /* add r17, r17, r16 */
+ 0x6858ec40, /* rshi r22, r12, r7 >> 64 */
+ 0x6848f60e, /* rshi r18, r22, r7 >> 14 */
+ 0x6854f612, /* rshi r21, r22, r7 >> 18 */
+ 0x4c4ab200, /* xor r18, r18, r21 */
+ 0x684cf629, /* rshi r19, r22, r7 >> 41 */
+ 0x4c4a7200, /* xor r18, r18, r19 */
+ 0x404c0700, /* and r19, r7, r0 */
+ 0x4854e000, /* not r21, r7 */
+ 0x40543500, /* and r21, r21, r1 */
+ 0x4c4eb300, /* xor r19, r19, r21 */
+ 0x685192c0, /* rshi r20, r18, r12 >> 192 */
+ 0x50505400, /* add r20, r20, r2 */
+ 0x50515488, /* add r20, r20, r10 >> 64 */
+ 0x6855ab40, /* rshi r21, r11, r13 >> 64 */
+ 0x50567500, /* add r21, r21, r19 */
+ 0x5052b400, /* add r20, r20, r21 */
+ 0x501a8600, /* add r6, r6, r20 */
+ 0x500a3400, /* add r2, r20, r17 */
+ 0x68584d40, /* rshi r22, r13, r2 >> 64 */
+ 0x683c561c, /* rshi r15, r22, r2 >> 28 */
+ 0x68545622, /* rshi r21, r22, r2 >> 34 */
+ 0x4c3eaf00, /* xor r15, r15, r21 */
+ 0x68545627, /* rshi r21, r22, r2 >> 39 */
+ 0x4c3eaf00, /* xor r15, r15, r21 */
+ 0x40406200, /* and r16, r2, r3 */
+ 0x40548200, /* and r21, r2, r4 */
+ 0x4c42b000, /* xor r16, r16, r21 */
+ 0x40548300, /* and r21, r3, r4 */
+ 0x4c42b000, /* xor r16, r16, r21 */
+ 0x6845afc0, /* rshi r17, r15, r13 >> 192 */
+ 0x50461100, /* add r17, r17, r16 */
+ 0x6858cc40, /* rshi r22, r12, r6 >> 64 */
+ 0x6848d60e, /* rshi r18, r22, r6 >> 14 */
+ 0x6854d612, /* rshi r21, r22, r6 >> 18 */
+ 0x4c4ab200, /* xor r18, r18, r21 */
+ 0x684cd629, /* rshi r19, r22, r6 >> 41 */
+ 0x4c4a7200, /* xor r18, r18, r19 */
+ 0x404ce600, /* and r19, r6, r7 */
+ 0x4854c000, /* not r21, r6 */
+ 0x40541500, /* and r21, r21, r0 */
+ 0x4c4eb300, /* xor r19, r19, r21 */
+ 0x685192c0, /* rshi r20, r18, r12 >> 192 */
+ 0x50503400, /* add r20, r20, r1 */
+ 0x50515490, /* add r20, r20, r10 >> 128 */
+ 0x6855ab80, /* rshi r21, r11, r13 >> 128 */
+ 0x50567500, /* add r21, r21, r19 */
+ 0x5052b400, /* add r20, r20, r21 */
+ 0x50168500, /* add r5, r5, r20 */
+ 0x50063400, /* add r1, r20, r17 */
+ 0x68582d40, /* rshi r22, r13, r1 >> 64 */
+ 0x683c361c, /* rshi r15, r22, r1 >> 28 */
+ 0x68543622, /* rshi r21, r22, r1 >> 34 */
+ 0x4c3eaf00, /* xor r15, r15, r21 */
+ 0x68543627, /* rshi r21, r22, r1 >> 39 */
+ 0x4c3eaf00, /* xor r15, r15, r21 */
+ 0x40404100, /* and r16, r1, r2 */
+ 0x40546100, /* and r21, r1, r3 */
+ 0x4c42b000, /* xor r16, r16, r21 */
+ 0x40546200, /* and r21, r2, r3 */
+ 0x4c42b000, /* xor r16, r16, r21 */
+ 0x6845afc0, /* rshi r17, r15, r13 >> 192 */
+ 0x50461100, /* add r17, r17, r16 */
+ 0x6858ac40, /* rshi r22, r12, r5 >> 64 */
+ 0x6848b60e, /* rshi r18, r22, r5 >> 14 */
+ 0x6854b612, /* rshi r21, r22, r5 >> 18 */
+ 0x4c4ab200, /* xor r18, r18, r21 */
+ 0x684cb629, /* rshi r19, r22, r5 >> 41 */
+ 0x4c4a7200, /* xor r18, r18, r19 */
+ 0x404cc500, /* and r19, r5, r6 */
+ 0x4854a000, /* not r21, r5 */
+ 0x4054f500, /* and r21, r21, r7 */
+ 0x4c4eb300, /* xor r19, r19, r21 */
+ 0x685192c0, /* rshi r20, r18, r12 >> 192 */
+ 0x50501400, /* add r20, r20, r0 */
+ 0x50515498, /* add r20, r20, r10 >> 192 */
+ 0x6855abc0, /* rshi r21, r11, r13 >> 192 */
+ 0x50567500, /* add r21, r21, r19 */
+ 0x5052b400, /* add r20, r20, r21 */
+ 0x50128400, /* add r4, r4, r20 */
+ 0x50023400, /* add r0, r20, r17 */
+ 0x0c000000, /* ret */
+/* } */
+/* @0x14f: function compress[70] { */
+#define CF_compress_adr 335
+ 0xfc000000, /* nop */
+ 0x4c7fff00, /* xor r31, r31, r31 */
+ 0x4c000000, /* xor r0, r0, r0 */
+ 0x4c042100, /* xor r1, r1, r1 */
+ 0x55000001, /* subi r0, r0, #1 */
+ 0x55040101, /* subi r1, r1, #1 */
+ 0x84204100, /* ldi r8, [#8] */
+ 0x94800800, /* ldlc r8 */
+ 0x4c3def00, /* xor r15, r15, r15 */
+ 0x803c000a, /* movi r15.0l, #10 */
+ 0x95800f00, /* lddmp r15 */
+ 0x06000039, /* loop *0 ( */
+ 0x953c0000, /* stdmp r15 */
+ 0x81bc002a, /* movi r15.3l, #42 */
+ 0x95800f00, /* lddmp r15 */
+ 0x08000001, /* call &expandw */
+ 0x84004000, /* ldi r0, [#0] */
+ 0x84044020, /* ldi r1, [#1] */
+ 0x84084040, /* ldi r2, [#2] */
+ 0x840c4060, /* ldi r3, [#3] */
+ 0x84104080, /* ldi r4, [#4] */
+ 0x841440a0, /* ldi r5, [#5] */
+ 0x841840c0, /* ldi r6, [#6] */
+ 0x841c40e0, /* ldi r7, [#7] */
+ 0x4c3def00, /* xor r15, r15, r15 */
+ 0x803c0060, /* movi r15.0l, #96 */
+ 0x80bc000a, /* movi r15.1l, #10 */
+ 0x813c000b, /* movi r15.2l, #11 */
+ 0x96800f00, /* lddrp r15 */
+ 0x97800f00, /* ldrfp r15 */
+ 0x953c0000, /* stdmp r15 */
+ 0x81bc002a, /* movi r15.3l, #42 */
+ 0x95800f00, /* lddmp r15 */
+ 0x4c318c00, /* xor r12, r12, r12 */
+ 0x4c35ad00, /* xor r13, r13, r13 */
+ 0x55300c01, /* subi r12, r12, #1 */
+ 0x55340d01, /* subi r13, r13, #1 */
+ 0x0500a007, /* loop #10 ( */
+ 0x8c440800, /* ldc *1, *0++ */
+ 0x8c081b00, /* ld *2, *3++ */
+ 0x08000055, /* call &Sha512_a */
+ 0x8c440800, /* ldc *1, *0++ */
+ 0x8c081b00, /* ld *2, *3++ */
+ 0x080000d2, /* call &Sha512_b */
+ 0xfc000000, /* nop */
+ /* ) */
+ 0x843c4000, /* ldi r15, [#0] */
+ 0x5001e000, /* add r0, r0, r15 */
+ 0x843c4020, /* ldi r15, [#1] */
+ 0x5005e100, /* add r1, r1, r15 */
+ 0x843c4040, /* ldi r15, [#2] */
+ 0x5009e200, /* add r2, r2, r15 */
+ 0x843c4060, /* ldi r15, [#3] */
+ 0x500de300, /* add r3, r3, r15 */
+ 0x843c4080, /* ldi r15, [#4] */
+ 0x5011e400, /* add r4, r4, r15 */
+ 0x843c40a0, /* ldi r15, [#5] */
+ 0x5015e500, /* add r5, r5, r15 */
+ 0x843c40c0, /* ldi r15, [#6] */
+ 0x5019e600, /* add r6, r6, r15 */
+ 0x843c40e0, /* ldi r15, [#7] */
+ 0x501de700, /* add r7, r7, r15 */
+ 0x88004000, /* sti r0, [#0] */
+ 0x88044020, /* sti r1, [#1] */
+ 0x88084040, /* sti r2, [#2] */
+ 0x880c4060, /* sti r3, [#3] */
+ 0x88104080, /* sti r4, [#4] */
+ 0x881440a0, /* sti r5, [#5] */
+ 0x881840c0, /* sti r6, [#6] */
+ 0x881c40e0, /* sti r7, [#7] */
+ /* ) */
+ 0x0c000000, /* ret */
+ /* } */
};
+/* clang-format on */
struct DMEM_sha512 {
uint64_t H0[4];
diff --git a/chip/g/dcrypto/internal.h b/chip/g/dcrypto/internal.h
index 2864af9b86..575ab86c5d 100644
--- a/chip/g/dcrypto/internal.h
+++ b/chip/g/dcrypto/internal.h
@@ -78,20 +78,47 @@ void bn_init(struct LITE_BIGNUM *bn, void *buf, size_t len);
#define bn_bits(b) ((b)->dmax * LITE_BN_BITS2)
int bn_eq(const struct LITE_BIGNUM *a, const struct LITE_BIGNUM *b);
int bn_check_topbit(const struct LITE_BIGNUM *N);
-void bn_mont_modexp(struct LITE_BIGNUM *output, const struct LITE_BIGNUM *input,
- const struct LITE_BIGNUM *exp, const struct LITE_BIGNUM *N);
-void bn_mont_modexp_asm(struct LITE_BIGNUM *output,
+int bn_modexp(struct LITE_BIGNUM *output,
const struct LITE_BIGNUM *input,
const struct LITE_BIGNUM *exp,
const struct LITE_BIGNUM *N);
-uint32_t bn_add(struct LITE_BIGNUM *c, const struct LITE_BIGNUM *a);
-uint32_t bn_sub(struct LITE_BIGNUM *c, const struct LITE_BIGNUM *a);
-int bn_modinv_vartime(struct LITE_BIGNUM *r, const struct LITE_BIGNUM *e,
- const struct LITE_BIGNUM *MOD);
+int bn_modexp_word(struct LITE_BIGNUM *output,
+ const struct LITE_BIGNUM *input,
+ uint32_t pubexp,
+ const struct LITE_BIGNUM *N);
+int bn_modexp_blinded(struct LITE_BIGNUM *output,
+ const struct LITE_BIGNUM *input,
+ const struct LITE_BIGNUM *exp,
+ const struct LITE_BIGNUM *N,
+ uint32_t pubexp);
+uint32_t bn_add(struct LITE_BIGNUM *c,
+ const struct LITE_BIGNUM *a);
+uint32_t bn_sub(struct LITE_BIGNUM *c,
+ const struct LITE_BIGNUM *a);
+int bn_modinv_vartime(struct LITE_BIGNUM *r,
+ const struct LITE_BIGNUM *e,
+ const struct LITE_BIGNUM *MOD);
int bn_is_bit_set(const struct LITE_BIGNUM *a, int n);
/*
- * ECC.
+ * Accelerated bn.
+ */
+int dcrypto_modexp(struct LITE_BIGNUM *output,
+ const struct LITE_BIGNUM *input,
+ const struct LITE_BIGNUM *exp,
+ const struct LITE_BIGNUM *N);
+int dcrypto_modexp_word(struct LITE_BIGNUM *output,
+ const struct LITE_BIGNUM *input,
+ uint32_t pubexp,
+ const struct LITE_BIGNUM *N);
+int dcrypto_modexp_blinded(struct LITE_BIGNUM *output,
+ const struct LITE_BIGNUM *input,
+ const struct LITE_BIGNUM *exp,
+ const struct LITE_BIGNUM *N,
+ uint32_t pubexp);
+
+/*
+ * Accelerated p256.
*/
int dcrypto_p256_ecdsa_sign(const p256_int *key, const p256_int *message,
p256_int *r, p256_int *s)
@@ -110,7 +137,7 @@ int dcrypto_p256_is_valid_point(const p256_int *x, const p256_int *y)
__attribute__((warn_unused_result));
/*
- * Runtime.
+ * Accelerator runtime.
*
* Note dcrypto_init_and_lock grabs a mutex and dcrypto_unlock releases it.
* Do not use dcrypto_call, dcrypto_imem_load or dcrypto_dmem_load w/o holding
diff --git a/chip/g/dcrypto/rsa.c b/chip/g/dcrypto/rsa.c
index 4aa1ef281e..8a4115398d 100644
--- a/chip/g/dcrypto/rsa.c
+++ b/chip/g/dcrypto/rsa.c
@@ -501,16 +501,14 @@ int DCRYPTO_rsa_encrypt(struct RSA *rsa, uint8_t *out, uint32_t *out_len,
uint32_t e_buf[LITE_BN_BYTES / sizeof(uint32_t)];
struct LITE_BIGNUM padded;
- struct LITE_BIGNUM e;
struct LITE_BIGNUM encrypted;
+ int ret;
if (!check_modulus_params(&rsa->N, sizeof(padded_buf), out_len))
return 0;
bn_init(&padded, padded_buf, bn_size(&rsa->N));
bn_init(&encrypted, out, bn_size(&rsa->N));
- bn_init(&e, e_buf, sizeof(e_buf));
- BN_DIGIT(&e, 0) = rsa->e;
switch (padding) {
case PADDING_MODE_OAEP:
@@ -533,7 +531,7 @@ int DCRYPTO_rsa_encrypt(struct RSA *rsa, uint8_t *out, uint32_t *out_len,
/* If in_len < bn_size(&padded), padded will
* have leading zero bytes. */
memcpy(&p[bn_size(&padded) - in_len], in, in_len);
- /* TODO(ngm): in may be > N, bn_mont_mod_exp() should
+ /* TODO(ngm): in may be > N, bn_mod_exp() should
* handle this case. */
break;
default:
@@ -542,14 +540,14 @@ int DCRYPTO_rsa_encrypt(struct RSA *rsa, uint8_t *out, uint32_t *out_len,
/* Reverse from big-endian to little-endian notation. */
reverse((uint8_t *) padded.d, bn_size(&padded));
- bn_mont_modexp(&encrypted, &padded, &e, &rsa->N);
+ ret = bn_modexp_word(&encrypted, &padded, rsa->e, &rsa->N);
/* Back to big-endian notation. */
reverse((uint8_t *) encrypted.d, bn_size(&encrypted));
*out_len = bn_size(&encrypted);
always_memset(padded_buf, 0, sizeof(padded_buf));
always_memset(e_buf, 0, sizeof(e_buf));
- return 1;
+ return ret;
}
int DCRYPTO_rsa_decrypt(struct RSA *rsa, uint8_t *out, uint32_t *out_len,
@@ -562,7 +560,7 @@ int DCRYPTO_rsa_decrypt(struct RSA *rsa, uint8_t *out, uint32_t *out_len,
struct LITE_BIGNUM encrypted;
struct LITE_BIGNUM padded;
- int ret = 1;
+ int ret;
if (!check_modulus_params(&rsa->N, sizeof(padded_buf), NULL))
return 0;
@@ -576,7 +574,7 @@ int DCRYPTO_rsa_decrypt(struct RSA *rsa, uint8_t *out, uint32_t *out_len,
/* Reverse from big-endian to little-endian notation. */
reverse((uint8_t *) encrypted.d, encrypted.dmax * LITE_BN_BYTES);
- bn_mont_modexp(&padded, &encrypted, &rsa->d, &rsa->N);
+ ret = bn_modexp_blinded(&padded, &encrypted, &rsa->d, &rsa->N, rsa->e);
/* Back to big-endian notation. */
reverse((uint8_t *) padded.d, padded.dmax * LITE_BN_BYTES);
@@ -619,6 +617,7 @@ int DCRYPTO_rsa_sign(struct RSA *rsa, uint8_t *out, uint32_t *out_len,
struct LITE_BIGNUM padded;
struct LITE_BIGNUM signature;
+ int ret;
if (!check_modulus_params(&rsa->N, sizeof(padded_buf), out_len))
return 0;
@@ -643,13 +642,13 @@ int DCRYPTO_rsa_sign(struct RSA *rsa, uint8_t *out, uint32_t *out_len,
/* Reverse from big-endian to little-endian notation. */
reverse((uint8_t *) padded.d, bn_size(&padded));
- bn_mont_modexp(&signature, &padded, &rsa->d, &rsa->N);
+ ret = bn_modexp_blinded(&signature, &padded, &rsa->d, &rsa->N, rsa->e);
/* Back to big-endian notation. */
reverse((uint8_t *) signature.d, bn_size(&signature));
*out_len = bn_size(&rsa->N);
always_memset(padded_buf, 0, sizeof(padded_buf));
- return 1;
+ return ret;
}
int DCRYPTO_rsa_verify(const struct RSA *rsa, const uint8_t *digest,
@@ -659,12 +658,10 @@ int DCRYPTO_rsa_verify(const struct RSA *rsa, const uint8_t *digest,
{
uint32_t padded_buf[RSA_WORDS_4K];
uint32_t signature_buf[RSA_WORDS_4K];
- uint32_t e_buf[LITE_BN_BYTES / sizeof(uint32_t)];
struct LITE_BIGNUM padded;
struct LITE_BIGNUM signature;
- struct LITE_BIGNUM e;
- int ret = 1;
+ int ret;
if (!check_modulus_params(&rsa->N, sizeof(padded_buf), NULL))
return 0;
@@ -674,12 +671,10 @@ int DCRYPTO_rsa_verify(const struct RSA *rsa, const uint8_t *digest,
bn_init(&signature, signature_buf, bn_size(&rsa->N));
memcpy(signature_buf, sig, bn_size(&rsa->N));
bn_init(&padded, padded_buf, bn_size(&rsa->N));
- bn_init(&e, e_buf, sizeof(e_buf));
- BN_DIGIT(&e, 0) = rsa->e;
/* Reverse from big-endian to little-endian notation. */
reverse((uint8_t *) signature.d, bn_size(&signature));
- bn_mont_modexp(&padded, &signature, &e, &rsa->N);
+ ret = bn_modexp_word(&padded, &signature, rsa->e, &rsa->N);
/* Back to big-endian notation. */
reverse((uint8_t *) padded.d, bn_size(&padded));
@@ -694,7 +689,7 @@ int DCRYPTO_rsa_verify(const struct RSA *rsa, const uint8_t *digest,
if (!check_pkcs1_pss_pad(
digest, digest_len, (uint8_t *) padded.d,
bn_size(&padded), hashing))
- return 0;
+ ret = 0;
break;
default:
/* Unsupported padding mode. */