1 /******************************************************************************
2 *  Filename:       rom_crypto.h
3 *  Revised:        2020-09-17 15:26:49 +0200 (Thu, 17 Sep 2020)
4 *  Revision:       58682
5 *
6 *  Description:    This header file is the API to the crypto functions
7 *                  built into ROM on the CC13xx/CC26xx.
8 *
9 *  Copyright (c) 2015 - 2020, Texas Instruments Incorporated
10 *  All rights reserved.
11 *
12 *  Redistribution and use in source and binary forms, with or without
13 *  modification, are permitted provided that the following conditions are met:
14 *
15 *  1) Redistributions of source code must retain the above copyright notice,
16 *     this list of conditions and the following disclaimer.
17 *
18 *  2) Redistributions in binary form must reproduce the above copyright notice,
19 *     this list of conditions and the following disclaimer in the documentation
20 *     and/or other materials provided with the distribution.
21 *
22 *  3) Neither the name of the ORGANIZATION nor the names of its contributors may
23 *     be used to endorse or promote products derived from this software without
24 *     specific prior written permission.
25 *
26 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
27 *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
30 *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31 *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34 *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 *  POSSIBILITY OF SUCH DAMAGE.
37 *
38 *******************************************************************************/
39 
40 //*****************************************************************************
41 //
42 //! \addtogroup peripheral_group
43 //! @{
44 //! \addtogroup rom_crypto_api
45 //! @{
46 //
47 //*****************************************************************************
48 
49 #ifndef ROM_CRYPTO_H
50 #define ROM_CRYPTO_H
51 
52 #ifdef __cplusplus
53 extern "C"
54 {
55 #endif
56 
57 ////////////////////////////////////* ECC */////////////////////////////////////
58 
59 /* Curve Parameters in ROM */
60 
61 /* Curve parameters for the NISTP256 curve. These curve parameters are stored
62  * in ROM and can be accessed via the pointers below.
63  * Each curve parameter starts with the 32-bit word 0x08 followed by the actual
64  * parameter encoded in 32 bytes as a little-endian integer.
65  */
66 #define ECC_NISTP256_prime ((const uint32_t *) 0x100257d4)
67 #define ECC_NISTP256_order ((const uint32_t *) 0x100257f8)
68 #define ECC_NISTP256_a ((const uint32_t *) 0x1002581c)
69 #define ECC_NISTP256_b ((const uint32_t *) 0x10025840)
70 #define ECC_NISTP256_generatorX ((const uint32_t *) 0x10025864)
71 #define ECC_NISTP256_generatorY ((const uint32_t *) 0x10025888)
72 
73 /* Length in bytes of NISTP256 curve parameters excluding the prepended length
74  * word.
75  */
76 #define ECC_NISTP256_PARAM_LENGTH_BYTES 32
77 
78 /* Length in words of NISTP256 curve parameters excluding the prepended length
79  * word.
80  */
81 #define ECC_NISTP256_PARAM_LENGTH_WORDS (ECC_NISTP256_PARAM_LENGTH_BYTES / sizeof(uint32_t))
82 
83 /* Number of bytes for the length word prepended before all parameters passed
84  * into the ECC functions.
85  */
86 #define ECC_LENGTH_OFFSET_BYTES 4
87 
88 /* Window size, valid values are 2,3,4,5.
89  * Higher the value, faster the computation at the expense of memory usage.
90  *
91  * Recommended workzone size (in 4-byte words)
92  * Window size: 3, Workzone size: 275
93  *
94  */
95 #define ECC_WINDOW_SIZE 3
96 
97 /*
98  * ECC Supported Curves, define one:
99  * ECC_PRIME_NIST256_CURVE
100  */
101 #define ECC_PRIME_NIST256_CURVE
102 
103 /*
104  * ECC Return Status Flags.
105  */
106 // Scalar multiplication status
107 #define ECC_MODULUS_EVEN                   0xDC
108 #define ECC_MODULUS_LARGER_THAN_255_WORDS  0xD2
109 #define ECC_MODULUS_LENGTH_ZERO            0x08
110 #define ECC_MODULUS_MSW_IS_ZERO            0x30
111 #define ECC_SCALAR_TOO_LONG                0x35
112 #define ECC_SCALAR_LENGTH_ZERO             0x53
113 #define ECC_ORDER_TOO_LONG                 0xC6
114 #define ECC_ORDER_LENGTH_ZERO              0x6C
115 #define ECC_X_COORD_TOO_LONG               0x3C
116 #define ECC_X_COORD_LENGTH_ZERO            0xC3
117 #define ECC_Y_COORD_TOO_LONG               0x65
118 #define ECC_Y_COORD_LENGTH_ZERO            0x56
119 #define ECC_A_COEF_TOO_LONG                0x5C
120 #define ECC_A_COEF_LENGTH_ZERO             0xC5
121 #define ECC_BAD_WINDOW_SIZE                0x66
122 #define ECC_SCALAR_MUL_OK                  0x99
123 
124 // ECDSA and ECDH status
125 #define ECC_ORDER_LARGER_THAN_255_WORDS    0x28
126 #define ECC_ORDER_EVEN                     0x82
127 #define ECC_ORDER_MSW_IS_ZERO              0x23
128 #define ECC_ECC_KEY_TOO_LONG               0x25
129 #define ECC_ECC_KEY_LENGTH_ZERO            0x52
130 #define ECC_DIGEST_TOO_LONG                0x27
131 #define ECC_DIGEST_LENGTH_ZERO             0x72
132 #define ECC_ECDSA_SIGN_OK                  0x32
133 #define ECC_ECDSA_INVALID_SIGNATURE        0x5A
134 #define ECC_ECDSA_VALID_SIGNATURE          0xA5
135 #define ECC_SIG_P1_TOO_LONG                0x11
136 #define ECC_SIG_P1_LENGTH_ZERO             0x12
137 #define ECC_SIG_P2_TOO_LONG                0x22
138 #define ECC_SIG_P2_LENGTH_ZERO             0x21
139 
140 #define ECC_ECDSA_KEYGEN_OK                ECC_SCALAR_MUL_OK
141 #define ECC_ECDH_KEYGEN_OK                 ECC_SCALAR_MUL_OK
142 #define ECC_ECDH_COMMON_KEY_OK             ECC_SCALAR_MUL_OK
143 
144 //*****************************************************************************
145 /*!
146  * \brief Initialize elliptic curve parameters to default values and specify workzone.
147  *
148  * This function initializes the elliptic curve parameters to default values.
149  * The default elliptic curve used is NIST-P256.
150  *
151  * The workzone defaults to an expected window size of 3.
152  *
153  * This function can be called again to point the ECC workzone at
154  * a different memory buffer.
155  *
156  * \param pWorkzone Pointer to memory allocated for computations, input.
157  *                  See description at beginning of ECC section for
158  *                  memory requirements.
159  *
160  * \return None
161  */
162 //*****************************************************************************
163 extern void ECC_initialize(uint32_t *pWorkzone);
164 
165 //*****************************************************************************
166 /*!
167  *  \brief Initialize elliptic curve parameters to specified values and specify workzone.
168  *
169  *  This function may be used to explicitly specify the curve parameters used
170  *  by the ECC in ROM implementation.
171  *
172  *  All curve parameters must be prepended with a length word specifying the
173  *  length of the parameter in 32-bit words excluding the length word itself.
174  *  For NIST-P256, the length word is 8.
175  *
176  *  @param workzone   Pointer to memory allocated for computations, input.
177  *                    See description at beginning of ECC section for
178  *                    memory requirements.
179  *  @param windowSize Window size of \c workzone. Default value is 3.
180  *  @param prime      Curve prime
181  *  @param order      Curve order
182  *  @param a          Curve a value
183  *  @param b          Curve b value
184  *  @param generatorX X coordinate of generator point
185  *  @param generatorY Y coordinate of generator point
186  */
187 extern void ECC_init(uint32_t *workzone,
188                      uint8_t   windowSize,
189                      const uint32_t *prime,
190                      const uint32_t *order,
191                      const uint32_t *a,
192                      const uint32_t *b,
193                      const uint32_t *generatorX,
194                      const uint32_t *generatorY);
195 
196 //*****************************************************************************
197  /*!
198  * \brief Generate a key.
199  *
200  * This is used for both ECDH and ECDSA.
201  *
202  * \param randString  Pointer to random string, input.
203  * \param privateKey  Pointer to the private key, output.
204  * \param publicKey_x Pointer to public key X-coordinate, output.
205  * \param publicKey_y Pointer to public key Y-coordinate, output.
206  *
207  * \return Status
208  */
209 //*****************************************************************************
210 extern uint8_t ECC_generateKey(uint32_t *randString, uint32_t *privateKey,
211                                uint32_t *publicKey_x, uint32_t *publicKey_y);
212 
213 //*****************************************************************************
214 /*!
215  * \brief Sign data.
216  *
217  * \param secretKey  Pointer to the secret key, input.
218  * \param text       Pointer to the message, input.
219  * \param randString Pointer to random string, input.
220  * \param sign1      Pointer to signature part 1, output.
221  * \param sign2      Pointer to signature part 2, output.
222  *
223  * \return Status
224  */
225 //*****************************************************************************
226 extern uint8_t ECC_ECDSA_sign(uint32_t *secretKey, uint32_t *text, uint32_t *randString,
227                               uint32_t *sign1, uint32_t *sign2);
228 
229 //*****************************************************************************
230 /*!
231  * \brief Verify signature.
232  *
233  * \param publicKey_x Pointer to public key X-coordinate, input.
234  * \param publicKey_y Pointer to public key Y-coordinate, input.
235  * \param text        Pointer to message data, input.
236  * \param sign1       Pointer to signature part 1, input.
237  * \param sign2       Pointer to signature part 2, input.
238  *
239  * \return Status
240  */
241 //*****************************************************************************
242 extern uint8_t ECC_ECDSA_verify(uint32_t *publicKey_x, uint32_t *publicKey_y,
243                                 uint32_t *text, uint32_t *sign1, uint32_t *sign2);
244 
245 //*****************************************************************************
246 /*!
247  * \brief Compute the shared secret.
248  *
249  * \param privateKey     Pointer to private key, input.
250  * \param publicKey_x    Pointer to public key X-coordinate, input.
251  * \param publicKey_y    Pointer to public key Y-coordinate, input.
252  * \param sharedSecret_x Pointer to shared secret X-coordinate, output.
253  * \param sharedSecret_y Pointer to shared secret Y-coordinate, output.
254  *
255  * \return Status
256  */
257 //*****************************************************************************
258 extern uint8_t ECC_ECDH_computeSharedSecret(uint32_t *privateKey,
259                                             uint32_t *publicKey_x,
260                                             uint32_t *publicKey_y,
261                                             uint32_t *sharedSecret_x,
262                                             uint32_t *sharedSecret_y);
263 
264 
265 #ifdef __cplusplus
266 }
267 #endif
268 
269 #endif /* ROM_CRYPTO_H */
270 
271 //*****************************************************************************
272 //
273 //! Close the Doxygen group.
274 //! @}
275 //! @}
276 //
277 //*****************************************************************************
278