1 /*
2  * Interface of curve P-256 (ECDH and ECDSA)
3  *
4  * Copyright The Mbed TLS Contributors
5  * Author: Manuel Pégourié-Gonnard.
6  * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
7  */
8 #ifndef P256_M_H
9 #define P256_M_H
10 
11 #include <stdint.h>
12 #include <stddef.h>
13 
14 /* Status codes */
15 #define P256_SUCCESS            0
16 #define P256_RANDOM_FAILED      -1
17 #define P256_INVALID_PUBKEY     -2
18 #define P256_INVALID_PRIVKEY    -3
19 #define P256_INVALID_SIGNATURE  -4
20 
21 #ifdef __cplusplus
22 extern "C" {
23 #endif
24 
25 /*
26  * RNG function - must be provided externally and be cryptographically secure.
27  *
28  * in: output - must point to a writable buffer of at least output_size bytes.
29  *     output_size - the number of random bytes to write to output.
30  * out: output is filled with output_size random bytes.
31  *      return 0 on success, non-zero on errors.
32  */
33 extern int p256_generate_random(uint8_t * output, unsigned output_size);
34 
35 /*
36  * ECDH/ECDSA generate key pair
37  *
38  * [in] draws from p256_generate_random()
39  * [out] priv: on success, holds the private key, as a big-endian integer
40  * [out] pub: on success, holds the public key, as two big-endian integers
41  *
42  * return:  P256_SUCCESS on success
43  *          P256_RANDOM_FAILED on failure
44  */
45 int p256_gen_keypair(uint8_t priv[32], uint8_t pub[64]);
46 
47 /*
48  * ECDH compute shared secret
49  *
50  * [out] secret: on success, holds the shared secret, as a big-endian integer
51  * [in] priv: our private key as a big-endian integer
52  * [in] pub: the peer's public key, as two big-endian integers
53  *
54  * return:  P256_SUCCESS on success
55  *          P256_INVALID_PRIVKEY if priv is invalid
56  *          P256_INVALID_PUBKEY if pub is invalid
57  */
58 int p256_ecdh_shared_secret(uint8_t secret[32],
59                             const uint8_t priv[32], const uint8_t pub[64]);
60 
61 /*
62  * ECDSA sign
63  *
64  * [in] draws from p256_generate_random()
65  * [out] sig: on success, holds the signature, as two big-endian integers
66  * [in] priv: our private key as a big-endian integer
67  * [in] hash: the hash of the message to be signed
68  * [in] hlen: the size of hash in bytes
69  *
70  * return:  P256_SUCCESS on success
71  *          P256_RANDOM_FAILED on failure
72  *          P256_INVALID_PRIVKEY if priv is invalid
73  */
74 int p256_ecdsa_sign(uint8_t sig[64], const uint8_t priv[32],
75                     const uint8_t *hash, size_t hlen);
76 
77 /*
78  * ECDSA verify
79  *
80  * [in] sig: the signature to be verified, as two big-endian integers
81  * [in] pub: the associated public key, as two big-endian integers
82  * [in] hash: the hash of the message that was signed
83  * [in] hlen: the size of hash in bytes
84  *
85  * return:  P256_SUCCESS on success - the signature was verified as valid
86  *          P256_INVALID_PUBKEY if pub is invalid
87  *          P256_INVALID_SIGNATURE if the signature was found to be invalid
88  */
89 int p256_ecdsa_verify(const uint8_t sig[64], const uint8_t pub[64],
90                       const uint8_t *hash, size_t hlen);
91 
92 /*
93  * Public key validation
94  *
95  * Note: you never need to call this function, as all other functions always
96  * validate their input; however it's availabe if you want to validate the key
97  * without performing an operation.
98  *
99  * [in] pub: the public key, as two big-endian integers
100  *
101  * return:  P256_SUCCESS if the key is valid
102  *          P256_INVALID_PUBKEY if pub is invalid
103  */
104 int p256_validate_pubkey(const uint8_t pub[64]);
105 
106 /*
107  * Private key validation
108  *
109  * Note: you never need to call this function, as all other functions always
110  * validate their input; however it's availabe if you want to validate the key
111  * without performing an operation.
112  *
113  * [in] priv: the private key, as a big-endian integer
114  *
115  * return:  P256_SUCCESS if the key is valid
116  *          P256_INVALID_PRIVKEY if priv is invalid
117  */
118 int p256_validate_privkey(const uint8_t priv[32]);
119 
120 /*
121  * Compute public key from private key
122  *
123  * [out] pub: the associated public key, as two big-endian integers
124  * [in] priv: the private key, as a big-endian integer
125  *
126  * return:  P256_SUCCESS on success
127  *          P256_INVALID_PRIVKEY if priv is invalid
128  */
129 int p256_public_from_private(uint8_t pub[64], const uint8_t priv[32]);
130 
131 #ifdef __cplusplus
132 }
133 #endif
134 
135 #endif /* P256_M_H */
136