Software APIs
p256_common.h
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 #ifndef OPENTITAN_SW_DEVICE_LIB_CRYPTO_IMPL_ECC_P256_COMMON_H_
6 #define OPENTITAN_SW_DEVICE_LIB_CRYPTO_IMPL_ECC_P256_COMMON_H_
7 
8 #include <stddef.h>
9 #include <stdint.h>
10 
11 #include "sw/device/lib/crypto/drivers/otbn.h"
12 #include "sw/device/lib/crypto/impl/status.h"
13 
14 #ifdef __cplusplus
15 extern "C" {
16 #endif // __cplusplus
17 
18 enum {
19  /**
20  * Length of a P-256 curve point coordinate in bits (modulo p).
21  */
22  kP256CoordBits = 256,
23  /**
24  * Length of a P-256 curve point coordinate in bytes.
25  */
26  kP256CoordBytes = kP256CoordBits / 8,
27  /**
28  * Length of a P-256 curve point coordinate in words.
29  */
30  kP256CoordWords = kP256CoordBytes / sizeof(uint32_t),
31  /**
32  * Length of an element in the P-256 scalar field (modulo the curve order n).
33  */
34  kP256ScalarBits = 256,
35  /**
36  * Length of a secret scalar share in bytes.
37  */
38  kP256ScalarBytes = kP256ScalarBits / 8,
39  /**
40  * Length of secret scalar share in words.
41  */
42  kP256ScalarWords = kP256ScalarBytes / sizeof(uint32_t),
43  /**
44  * Length of a masked secret scalar share.
45  *
46  * This implementation uses extra redundant bits for side-channel protection.
47  */
48  kP256MaskedScalarShareBits = kP256ScalarBits + 64,
49  /**
50  * Length of a masked secret scalar share in bytes.
51  */
52  kP256MaskedScalarShareBytes = kP256MaskedScalarShareBits / 8,
53  /**
54  * Length of masked secret scalar share in words.
55  */
56  kP256MaskedScalarShareWords = kP256MaskedScalarShareBytes / sizeof(uint32_t),
57 };
58 
59 /**
60  * A type that holds a masked value from the P-256 scalar field.
61  *
62  * This struct is used to represent secret keys, which are integers modulo n.
63  * The key d is represented in two 320-bit shares, d0 and d1, such that d = (d0
64  * + d1) mod n. Mathematically, d0 and d1 could also be reduced modulo n, but
65  * the extra bits provide side-channel protection.
66  */
67 typedef struct p256_masked_scalar {
68  /**
69  * First share of the secret scalar.
70  */
71  uint32_t share0[kP256MaskedScalarShareWords];
72  /**
73  * Second share of the secret scalar.
74  */
75  uint32_t share1[kP256MaskedScalarShareWords];
77 
78 /**
79  * A type that holds a P-256 curve point.
80  */
81 typedef struct p256_point {
82  /**
83  * Affine x-coordinate.
84  */
85  uint32_t x[kP256CoordWords];
86  /**
87  * Affine y-coordinate.
88  */
89  uint32_t y[kP256CoordWords];
90 } p256_point_t;
91 
92 /**
93  * Write a masked P-256 scalar to OTBN's data memory.
94  *
95  * OTBN actually requires that 512 bits be written, even though only 320 are
96  * used; the others are ignored but must be set to avoid an error when OTBN
97  * attempts to read uninitialized memory.
98  *
99  * @param src Masked scalar to write.
100  * @param share0_addr DMEM address of the first share.
101  * @param share1_addr DMEM address of the second share.
102  * @return Result of the operation.
103  */
105 status_t p256_masked_scalar_write(const p256_masked_scalar_t *src,
106  const otbn_addr_t share0_addr,
107  const otbn_addr_t share1_addr);
108 
109 #ifdef __cplusplus
110 } // extern "C"
111 #endif // __cplusplus
112 
113 #endif // OPENTITAN_SW_DEVICE_LIB_CRYPTO_IMPL_ECC_P256_COMMON_H_