Software APIs
otbn_testutils_rsa.c
1 // Copyright lowRISC contributors (OpenTitan project).
2 // Licensed under the Apache License, Version 2.0, see LICENSE for details.
3 // SPDX-License-Identifier: Apache-2.0
4 
5 #include "sw/device/lib/testing/otbn_testutils_rsa.h"
6 
7 #include "sw/device/lib/base/status.h"
10 
12 OTBN_DECLARE_SYMBOL_ADDR(rsa, mode);
13 OTBN_DECLARE_SYMBOL_ADDR(rsa, n_limbs);
14 OTBN_DECLARE_SYMBOL_ADDR(rsa, inout);
15 OTBN_DECLARE_SYMBOL_ADDR(rsa, modulus);
16 OTBN_DECLARE_SYMBOL_ADDR(rsa, exp);
17 
18 static const otbn_app_t kOtbnAppRsa = OTBN_APP_T_INIT(rsa);
19 static const otbn_addr_t kOtbnVarRsaMode = OTBN_ADDR_T_INIT(rsa, mode);
20 static const otbn_addr_t kOtbnVarRsaNLimbs = OTBN_ADDR_T_INIT(rsa, n_limbs);
21 static const otbn_addr_t kOtbnVarRsaInOut = OTBN_ADDR_T_INIT(rsa, inout);
22 static const otbn_addr_t kOtbnVarRsaModulus = OTBN_ADDR_T_INIT(rsa, modulus);
23 static const otbn_addr_t kOtbnVarRsaExp = OTBN_ADDR_T_INIT(rsa, exp);
24 
25 enum {
26  kOtbnWideWordBytes = 256 / 8,
27  kModeEncrypt = 1,
28  kModeDecrypt = 2,
29 };
30 
31 status_t otbn_testutils_rsa_load(dif_otbn_t *otbn) {
32  if (otbn == NULL) {
33  return INVALID_ARGUMENT();
34  }
35  return otbn_testutils_load_app(otbn, kOtbnAppRsa);
36 }
37 
38 status_t otbn_testutils_rsa_modexp_f4_start(dif_otbn_t *otbn,
39  const uint8_t *modulus,
40  const uint8_t *in,
41  size_t size_bytes) {
42  if (otbn == NULL || size_bytes % kOtbnWideWordBytes != 0) {
43  return INVALID_ARGUMENT();
44  }
45 
46  uint32_t n_limbs = size_bytes / kOtbnWideWordBytes;
47  if (n_limbs == 0 || n_limbs > 16) {
48  return INVALID_ARGUMENT();
49  }
50 
51  // Write input arguments.
52  uint32_t mode = kModeEncrypt;
53  TRY(otbn_testutils_write_data(otbn, sizeof(uint32_t), &mode,
54  kOtbnVarRsaMode));
55  TRY(otbn_testutils_write_data(otbn, sizeof(uint32_t), &n_limbs,
56  kOtbnVarRsaNLimbs));
57  TRY(otbn_testutils_write_data(otbn, size_bytes, modulus, kOtbnVarRsaModulus));
58  TRY(otbn_testutils_write_data(otbn, size_bytes, in, kOtbnVarRsaInOut));
59 
60  // Call OTBN to start the operation.
61  return otbn_testutils_execute(otbn);
62 }
63 
64 status_t otbn_testutils_rsa_modexp_consttime_start(
65  dif_otbn_t *otbn, const uint8_t *modulus, const uint8_t *private_exponent,
66  const uint8_t *in, size_t size_bytes) {
67  if (otbn == NULL || size_bytes % kOtbnWideWordBytes != 0) {
68  return INVALID_ARGUMENT();
69  }
70 
71  uint32_t n_limbs = size_bytes / kOtbnWideWordBytes;
72  if (n_limbs == 0 || n_limbs > 16) {
73  return INVALID_ARGUMENT();
74  }
75 
76  // Write input arguments.
77  uint32_t mode = kModeDecrypt;
78  TRY(otbn_testutils_write_data(otbn, sizeof(mode), &mode, kOtbnVarRsaMode));
79  TRY(otbn_testutils_write_data(otbn, sizeof(n_limbs), &n_limbs,
80  kOtbnVarRsaNLimbs));
81  TRY(otbn_testutils_write_data(otbn, size_bytes, modulus, kOtbnVarRsaModulus));
82  TRY(otbn_testutils_write_data(otbn, size_bytes, private_exponent,
83  kOtbnVarRsaExp));
84  TRY(otbn_testutils_write_data(otbn, size_bytes, in, kOtbnVarRsaInOut));
85 
86  // Call OTBN to start the operation.
87  return otbn_testutils_execute(otbn);
88 }
89 
90 static status_t modexp_finalize(dif_otbn_t *otbn, uint8_t *out,
91  size_t size_bytes) {
92  if (otbn == NULL || size_bytes % kOtbnWideWordBytes != 0) {
93  return INVALID_ARGUMENT();
94  }
95 
96  uint32_t n_limbs = size_bytes / kOtbnWideWordBytes;
97  if (n_limbs == 0 || n_limbs > 16) {
98  return INVALID_ARGUMENT();
99  }
100 
101  // Wait for OTBN to complete.
102  TRY(otbn_testutils_wait_for_done(otbn, kDifOtbnErrBitsNoError));
103 
104  // Read back results.
105  return otbn_testutils_read_data(otbn, size_bytes, kOtbnVarRsaInOut, out);
106 }
107 
108 status_t otbn_testutils_rsa_modexp_f4_finalize(dif_otbn_t *otbn, uint8_t *out,
109  size_t size_bytes) {
110  return modexp_finalize(otbn, out, size_bytes);
111 }
112 
113 status_t otbn_testutils_rsa_modexp_consttime_finalize(dif_otbn_t *otbn,
114  uint8_t *out,
115  size_t size_bytes) {
116  return modexp_finalize(otbn, out, size_bytes);
117 }