xref: /freebsd/crypto/libecc/include/libecc/sig/ec_key.h (revision f0865ec9906d5a18fa2a3b61381f22ce16e606ad)
1 /*
2  *  Copyright (C) 2017 - This file is part of libecc project
3  *
4  *  Authors:
5  *      Ryad BENADJILA <ryadbenadjila@gmail.com>
6  *      Arnaud EBALARD <arnaud.ebalard@ssi.gouv.fr>
7  *      Jean-Pierre FLORI <jean-pierre.flori@ssi.gouv.fr>
8  *
9  *  Contributors:
10  *      Nicolas VIVET <nicolas.vivet@ssi.gouv.fr>
11  *      Karim KHALFALLAH <karim.khalfallah@ssi.gouv.fr>
12  *
13  *  This software is licensed under a dual BSD and GPL v2 license.
14  *  See LICENSE file at the root folder of the project.
15  */
16 #ifndef __EC_KEY_H__
17 #define __EC_KEY_H__
18 
19 #include <libecc/lib_ecc_config.h>
20 #include <libecc/lib_ecc_types.h>
21 #include <libecc/fp/fp.h>
22 #include <libecc/curves/ec_params.h>
23 #include <libecc/nn/nn_rand.h>
24 #include <libecc/nn/nn_add.h>
25 #include <libecc/nn/nn_logical.h>
26 #include <libecc/curves/prj_pt.h>
27 #include <libecc/hash/hash_algs.h>
28 
29 /* Enum for exported keys */
30 typedef enum {
31 	EC_PUBKEY = 0,
32 	EC_PRIVKEY = 1,
33 } ec_key_type;
34 
35 /*
36  * Declarations for EC private keys
37  */
38 
39 #define PRIV_KEY_MAGIC ((word_t)(0x2feb91e938a4855dULL))
40 typedef struct {
41 	/* A key type can only be used for a given sig alg */
42 	ec_alg_type key_type;
43 
44 	/* Elliptic curve parameters */
45 	const ec_params *params;
46 
47 	/*
48 	 * Private key (usually an integer in ]0,q[, where q is
49 	 * the order of G, the generator of the group
50 	 * on the curve, or a derivative of this).
51 	 *
52 	 * For the specific case of EdDSA, this value will instead hold the
53 	 * digest derivation of the secret value sk that is twice the size of
54 	 * the digest size.
55 	 */
56 	nn x;
57 
58 	word_t magic;
59 } ec_priv_key;
60 
61 /* NOTE1: in the specific case of EdDSA, the hash size dictates the size of the
62  * private keys. Although EdDSA only uses specific hash algorithms, we are being
63  * conservative here by taking the maximum digest size (hence accepting losing some space
64  * wen storing the private key for more simplicity).
65  *
66  * NOTE2: we use MAX_DIGEST_SIZE as the basis for EdDSA private key size instead of
67  * (MAX_DIGEST_SIZE / 2) because we store the EdDSA private key in its *derived* formed,
68  * meaning that it is twice the size of a regular standardized private key.
69  *
70  */
71 #if defined(WITH_SIG_EDDSA25519) || defined(WITH_SIG_EDDSA448)
72 
73 #define EC_PRIV_KEY_MAX_SIZE	(LOCAL_MAX(MAX_DIGEST_SIZE, LOCAL_MAX(BYTECEIL(CURVES_MAX_Q_BIT_LEN), BYTECEIL(CURVES_MAX_P_BIT_LEN))))
74 
75 #define EC_PRIV_KEY_EXPORT_SIZE(priv_key)			\
76 	((u8)(LOCAL_MAX(MAX_DIGEST_SIZE, LOCAL_MAX(BYTECEIL((priv_key)->params->ec_gen_order_bitlen), BYTECEIL((priv_key)->params->ec_fp.p_bitlen)))))
77 
78 #else /* !(defined(WITH_SIG_EDDSA25519) || defined(WITH_SIG_EDDSA448)) */
79 
80 #define EC_PRIV_KEY_MAX_SIZE	(LOCAL_MAX(BYTECEIL(CURVES_MAX_Q_BIT_LEN), BYTECEIL(CURVES_MAX_P_BIT_LEN)))
81 
82 #define EC_PRIV_KEY_EXPORT_SIZE(priv_key)			\
83 	((u8)(LOCAL_MAX(BYTECEIL((priv_key)->params->ec_gen_order_bitlen), BYTECEIL((priv_key)->params->ec_fp.p_bitlen))))
84 
85 #endif /* defined(WITH_SIG_EDDSA25519) || defined(WITH_SIG_EDDSA448) */
86 
87 #define EC_STRUCTURED_PRIV_KEY_MAX_EXPORT_SIZE	(EC_PRIV_KEY_MAX_SIZE + 3)
88 #if (EC_STRUCTURED_PRIV_KEY_MAX_EXPORT_SIZE > 255)
89 #error "All structured priv keys size are expected to fit on an u8."
90 #endif
91 
92 #define EC_STRUCTURED_PRIV_KEY_EXPORT_SIZE(priv_key)			\
93 	((u8)(EC_PRIV_KEY_EXPORT_SIZE(priv_key) + (3 * sizeof(u8))))
94 
95 ATTRIBUTE_WARN_UNUSED_RET int priv_key_check_initialized(const ec_priv_key *A);
96 ATTRIBUTE_WARN_UNUSED_RET int priv_key_check_initialized_and_type(const ec_priv_key *A,
97 					ec_alg_type sig_type);
98 
99 ATTRIBUTE_WARN_UNUSED_RET int ec_priv_key_import_from_buf(ec_priv_key *priv_key,
100 				const ec_params *params,
101 				const u8 *priv_key_buf, u8 priv_key_buf_len,
102 				ec_alg_type ec_key_alg);
103 ATTRIBUTE_WARN_UNUSED_RET int ec_priv_key_export_to_buf(const ec_priv_key *priv_key, u8 *priv_key_buf,
104 			      u8 priv_key_buf_len);
105 
106 ATTRIBUTE_WARN_UNUSED_RET int ec_structured_priv_key_import_from_buf(ec_priv_key *priv_key,
107 					   const ec_params *params,
108 					   const u8 *priv_key_buf,
109 					   u8 priv_key_buf_len,
110 					   ec_alg_type ec_key_alg);
111 ATTRIBUTE_WARN_UNUSED_RET int ec_structured_priv_key_export_to_buf(const ec_priv_key *priv_key,
112 					 u8 *priv_key_buf,
113 					 u8 priv_key_buf_len);
114 
115 /*
116  * Declarations for EC public keys
117  */
118 
119 #define PUB_KEY_MAGIC ((word_t)(0x31327f37741ffb76ULL))
120 typedef struct {
121 	/* A key type can only be used for a given sig alg */
122 	ec_alg_type key_type;
123 
124 	/* Elliptic curve parameters */
125 	const ec_params *params;
126 
127 	/* Public key, i.e. y = xG mod p */
128 	prj_pt y;
129 
130 	word_t magic;
131 } ec_pub_key;
132 
133 #define EC_PUB_KEY_MAX_SIZE (3 * BYTECEIL(CURVES_MAX_P_BIT_LEN))
134 
135 #define EC_PUB_KEY_EXPORT_SIZE(pub_key)                                 \
136 	(3 * BYTECEIL((pub_key)->params->ec_curve.a.ctx->p_bitlen))
137 
138 #define EC_STRUCTURED_PUB_KEY_MAX_EXPORT_SIZE	(EC_PUB_KEY_MAX_SIZE + 3)
139 #if (EC_STRUCTURED_PUB_KEY_MAX_EXPORT_SIZE > 255)
140 #error "All structured pub keys size are expected to fit on an u8."
141 #endif
142 #define EC_STRUCTURED_PUB_KEY_EXPORT_SIZE(pub_key)			\
143 	((u8)(EC_PUB_KEY_EXPORT_SIZE(pub_key) + (u8)(3 * sizeof(u8))))
144 
145 ATTRIBUTE_WARN_UNUSED_RET int pub_key_check_initialized(const ec_pub_key *A);
146 ATTRIBUTE_WARN_UNUSED_RET int pub_key_check_initialized_and_type(const ec_pub_key *A,
147 				       ec_alg_type sig_type);
148 
149 ATTRIBUTE_WARN_UNUSED_RET int ec_pub_key_import_from_buf(ec_pub_key *pub_key, const ec_params *params,
150 			       const u8 *pub_key_buf, u8 pub_key_buf_len,
151 			       ec_alg_type ec_key_alg);
152 ATTRIBUTE_WARN_UNUSED_RET int ec_pub_key_export_to_buf(const ec_pub_key *pub_key, u8 *pub_key_buf,
153 			     u8 pub_key_buf_len);
154 
155 ATTRIBUTE_WARN_UNUSED_RET int ec_pub_key_import_from_aff_buf(ec_pub_key *pub_key, const ec_params *params,
156 			       const u8 *pub_key_buf, u8 pub_key_buf_len,
157 			       ec_alg_type ec_key_alg);
158 
159 ATTRIBUTE_WARN_UNUSED_RET int ec_pub_key_export_to_aff_buf(const ec_pub_key *pub_key, u8 *pub_key_buf,
160 			     u8 pub_key_buf_len);
161 
162 ATTRIBUTE_WARN_UNUSED_RET int ec_structured_pub_key_import_from_buf(ec_pub_key *pub_key,
163 					  const ec_params *params,
164 					  const u8 *pub_key_buf,
165 					  u8 pub_key_buf_len,
166 					  ec_alg_type ec_key_alg);
167 ATTRIBUTE_WARN_UNUSED_RET int ec_structured_pub_key_export_to_buf(const ec_pub_key *pub_key,
168 					u8 *pub_key_buf, u8 pub_key_buf_len);
169 
170 /*
171  * Declarations for EC key pairs
172  */
173 
174 typedef struct {
175 	ec_priv_key priv_key;
176 	ec_pub_key pub_key;
177 } ec_key_pair;
178 
179 ATTRIBUTE_WARN_UNUSED_RET int key_pair_check_initialized(const ec_key_pair *A);
180 
181 ATTRIBUTE_WARN_UNUSED_RET int key_pair_check_initialized_and_type(const ec_key_pair *A,
182 					 ec_alg_type sig_type);
183 
184 ATTRIBUTE_WARN_UNUSED_RET int ec_key_pair_import_from_priv_key_buf(ec_key_pair *kp,
185 					 const ec_params *params,
186 					 const u8 *priv_key, u8 priv_key_len,
187 					 ec_alg_type ec_key_alg);
188 ATTRIBUTE_WARN_UNUSED_RET int ec_key_pair_gen(ec_key_pair *kp, const ec_params *params,
189 		    ec_alg_type ec_key_alg);
190 
191 ATTRIBUTE_WARN_UNUSED_RET int ec_structured_key_pair_import_from_priv_key_buf(ec_key_pair *kp,
192 						    const ec_params *params,
193 						    const u8 *priv_key_buf,
194 						    u8 priv_key_buf_len,
195 						    ec_alg_type ec_key_alg);
196 /*
197  * NOTE: please use the following API with care as it does not check the consistency
198  * between the private and public keys! On one side, this "saves" a costly
199  * scalar multiplication when there is confidence in the source of the buffers,
200  * but on the other side the user of the API MUST check the source (integrity)
201  * of the private/public key pair. If unsure, it is advised to use the
202  * ec_structured_key_pair_import_from_priv_key_buf API that safely derives the
203  * public key from the private key.
204  *
205  */
206 ATTRIBUTE_WARN_UNUSED_RET int ec_structured_key_pair_import_from_buf(ec_key_pair *kp,
207 					   const ec_params *params,
208 					   const u8 *priv_key_buf,
209 					   u8 priv_key_buf_len,
210 					   const u8 *pub_key_buf,
211 					   u8 pub_key_buf_len,
212 					   ec_alg_type ec_key_alg);
213 
214 ATTRIBUTE_WARN_UNUSED_RET int generic_gen_priv_key(ec_priv_key *priv_key);
215 
216 
217 /* Type used for batch verification */
218 typedef struct {
219         nn number;
220         prj_pt point;
221 	u32 index;
222 } verify_batch_scratch_pad;
223 
224 #endif /* __EC_KEY_H__ */
225