1 /* Copyright (c) (2010,2011,2012,2014,2015,2016,2017,2018,2019,2020) Apple Inc. All rights reserved.
3 * corecrypto is licensed under Apple Inc.’s Internal Use License Agreement (which
4 * is contained in the License.txt file distributed with corecrypto) and only to
5 * people who accept that license. IMPORTANT: Any license rights granted to you by
6 * Apple Inc. (if any) are limited to internal use within your organization only on
7 * devices and computers you own or control, for the sole purpose of verifying the
8 * security characteristics and correct functioning of the Apple Software. You may
9 * not, directly or indirectly, redistribute the Apple Software or any portions thereof.
12 #ifndef _CORECRYPTO_CCRSA_H_
13 #define _CORECRYPTO_CCRSA_H_
15 #include <corecrypto/cc.h>
16 #include <corecrypto/ccdigest.h>
17 #include <corecrypto/ccrng.h>
18 #include <corecrypto/cczp.h>
19 #include <corecrypto/cc_fault_canary.h>
22 // Apple does not generate keys of greater than 4096 bits
23 // This limit is relaxed to accommodate potential third-party consumers
24 #define CCRSA_KEYGEN_MAX_NBITS 8192
26 struct ccrsa_full_ctx
{
27 __CCZP_ELEMENTS_DEFINITIONS(pb_
)
28 } CC_ALIGNED(CCN_UNIT_SIZE
);
30 struct ccrsa_pub_ctx
{
31 __CCZP_ELEMENTS_DEFINITIONS(pb_
)
32 } CC_ALIGNED(CCN_UNIT_SIZE
);
34 struct ccrsa_priv_ctx
{
35 __CCZP_ELEMENTS_DEFINITIONS(pv_
)
36 } CC_ALIGNED(CCN_UNIT_SIZE
);
38 typedef struct ccrsa_full_ctx
* ccrsa_full_ctx_t
;
39 typedef struct ccrsa_pub_ctx
* ccrsa_pub_ctx_t
;
40 typedef struct ccrsa_priv_ctx
* ccrsa_priv_ctx_t
;
43 public key cczp d=e^-1 mod lambda(m) priv key cczp priv key cczq dp, dq, qinv
46 +-------+------+-------+------++------++-------+------+---------++-------+------+---------++-------+-------+---------+
47 | zm_hd | m[n] |mr[n+1]| e[n] || d[n] || zp_hd |p[n/2]|pr[n/2+1]|| zq_hd |q[n/2]|qr[n/2+1]||dp[n/2]|dq[n/2]|qinv[n/2]|
48 +-------+------+-------+------++------++-------+------+---------++-------+------+---------++-------+-------+---------+
51 /* Return the size of an ccec_full_ctx where each ccn is _size_ bytes. Get _size_ through ccn_sizeof(nbits) */
53 /* Return the size of an ccec_full_ctx where each ccn is _size_ bytes. */
55 #define ccrsa_pub_ctx_size(_size_) (sizeof(struct cczp) + CCN_UNIT_SIZE + 3 * (_size_))
56 #define ccrsa_priv_ctx_size(_size_) ((sizeof(struct cczp) + CCN_UNIT_SIZE) * 2 + 7 * ccn_sizeof(ccn_bitsof_size(_size_)/2 + 1))
57 #define ccrsa_full_ctx_size(_size_) (ccrsa_pub_ctx_size(_size_) + _size_ + ccrsa_priv_ctx_size(_size_))
59 /* Declare a fully scheduled rsa key. Size is the size in bytes each ccn in
60 the key. For example to declare (on the stack or in a struct) a 1021 bit
61 rsa public key named foo use ccrsa_pub_ctx_decl(ccn_sizeof(1021), foo).
63 #define ccrsa_full_ctx_decl(_size_, _name_) cc_ctx_decl(struct ccrsa_full_ctx, ccrsa_full_ctx_size(_size_), _name_)
64 #define ccrsa_full_ctx_clear(_size_, _name_) cc_clear(ccrsa_full_ctx_size(_size_), _name_)
65 #define ccrsa_pub_ctx_decl(_size_, _name_) cc_ctx_decl(struct ccrsa_pub_ctx, ccrsa_pub_ctx_size(_size_), _name_)
66 #define ccrsa_pub_ctx_clear(_size_, _name_) cc_clear(ccrsa_pub_ctx_size(_size_), _name_)
68 // accessors to ccrsa full and public key fields. */
69 // The offsets are computed using pb_ccn. If any object other than ccrsa_full_ctx_t
70 // or ccrsa_pub_ctx_t is passed to the macros, compiler error is generated.
72 #define ccrsa_ctx_zm(_ctx_) ((cczp_t)(_ctx_))
73 #define ccrsa_ctx_n(_ctx_) (ccrsa_ctx_zm(_ctx_)->n)
74 #define ccrsa_ctx_m(_ctx_) ((_ctx_)->pb_ccn)
76 #define ccrsa_ctx_e(_ctx_) (ccrsa_ctx_m(_ctx_) + 2 * ccrsa_ctx_n(_ctx_) + 1)
77 #define ccrsa_ctx_d(_ctx_) (ccrsa_ctx_m(_ctx_) + 3 * ccrsa_ctx_n(_ctx_) + 1)
79 // accessors to ccrsa private key fields
80 // The offsets are computed using pv_ccn. If any object other than ccrsa_priv_ctx_t
81 // is passed to the macros, compiler error is generated.
82 #define ccrsa_ctx_private_zp(FK) ((cczp_t)ccrsa_get_private_ctx_ptr(FK))
83 #define ccrsa_ctx_private_zq(FK) ((cczp_t)((ccrsa_get_private_ctx_ptr(FK))->pv_ccn + 2 * ccrsa_ctx_private_zp(FK)->n + 1))
84 #define ccrsa_ctx_private_dp(FK) ((ccrsa_get_private_ctx_ptr(FK))->pv_ccn + 4 * ccrsa_ctx_private_zp(FK)->n + 2 + ccn_nof_size(sizeof(struct cczp)))
85 #define ccrsa_ctx_private_dq(FK) ((ccrsa_get_private_ctx_ptr(FK))->pv_ccn + 5 * ccrsa_ctx_private_zp(FK)->n + 2 + ccn_nof_size(sizeof(struct cczp)))
86 #define ccrsa_ctx_private_qinv(FK) ((ccrsa_get_private_ctx_ptr(FK))->pv_ccn + 6 * ccrsa_ctx_private_zp(FK)->n + 2 + ccn_nof_size(sizeof(struct cczp)))
88 /* rvalue accessors to ccec_key fields. */
90 ccrsa_priv_ctx_t
ccrsa_get_private_ctx_ptr(ccrsa_full_ctx_t fk
) {
91 ccrsa_priv_ctx_t priv
= (ccrsa_priv_ctx_t
)(ccrsa_ctx_d(fk
)+ccrsa_ctx_n(fk
));
96 @function ccrsa_ctx_public
97 @abstract gets the public key from full key
98 @param fk RSA full key
99 @result Returns RSA public ker
102 ccrsa_pub_ctx_t
ccrsa_ctx_public(ccrsa_full_ctx_t fk
) {
103 return (ccrsa_pub_ctx_t
) fk
;
107 @function ccrsa_pubkeylength
108 @abstract Compute the actual bit length of the RSA key (bit length of the modulus)
109 @param pubk An initialized RSA public key
110 @result bit length of the RSA key
113 size_t ccrsa_pubkeylength(ccrsa_pub_ctx_t pubk
);
115 /* PKCS1 pad_markers */
116 #define CCRSA_PKCS1_PAD_SIGN 1
117 #define CCRSA_PKCS1_PAD_ENCRYPT 2
120 @function ccrsa_init_pub
121 @abstract Initialize an RSA public key structure based on modulus and exponent. Values are copied into the structure.
122 @param pubk allocated public key structure (see requirements below)
123 @param modulus cc_unit array of the modulus
124 @param exponent cc_unit array of the exponent
125 @result CCERR_OK if no error
127 @discussion ccrsa_ctx_n(pubk) must have been initialized based on the modulus size, typically using ccn_nof_size(mod_nbytes).
128 The public key structure pubk is typically allocated with ccrsa_pub_ctx_decl(ccn_sizeof_size(mod_nbytes), pubk);
131 int ccrsa_init_pub(ccrsa_pub_ctx_t pubk
, const cc_unit
*modulus
,
132 const cc_unit
*exponent
);
134 /*! @function ccrsa_make_priv
135 @abstract Initializes an RSA public and private key given the public
136 exponent e and prime factors p and q.
138 @param full_ctx Initialized context with ccrsa_ctx_n(full_ctx) set to 2*ccn_nof_size(p_nbytes)
139 @param e_nbytes Number of bytes of public exponent e.
140 @param e_bytes Public exponent e in Big Endian.
141 @param p_nbytes Number of bytes of prime factor p.
142 @param p_bytes Prime factor p in Big Endian.
143 @param q_nbytes Number of bytes of prime factor q.
144 @param q_bytes Prime factor q in Big Endian.
146 @return 0 iff successful.
148 @discussion ccrsa_ctx_n(full_ctx) must already be set to 2*ccn_nof_size(p_mbytes), with the expectation that p_nbytes>q_nbytes.
149 e is the public exponent, and e_nbytes<= 2*p_nbytes.
150 The output is a fully formed RSA context with N=pq, d=e^{-1} mod lambda(N), and appropriate inverses of different associated values precomputed
151 to speed computation.
153 int ccrsa_make_priv(ccrsa_full_ctx_t full_ctx
,
154 size_t e_nbytes
, const uint8_t *e_bytes
,
155 size_t p_nbytes
, const uint8_t *p_bytes
,
156 size_t q_nbytes
, const uint8_t *q_bytes
);
158 /*! @function ccrsa_recover_priv
159 @abstract Initializes an RSA public and private key given the modulus m,
160 the public exponent e and the private exponent d.
162 @discussion Follows the algorithm described by
163 NIST SP 800-56B, Appendix C, "Prime Factory Recovery".
165 @param full_ctx Initialized context with ccrsa_ctx_n(full_ctx) set to ccn_nof_size(m_nbytes)
166 @param m_nbytes Number of bytes of modulus m.
167 @param m_bytes Modulus m in Big Endian.
168 @param e_nbytes Number of bytes of public exponent e.
169 @param e_bytes Public exponent e in Big Endian.
170 @param d_nbytes Number of bytes of private exponent d.
171 @param d_bytes Private exponent d in Big Endian.
172 @param rng RNG instance.
174 @return 0 iff successful.
176 int ccrsa_recover_priv(ccrsa_full_ctx_t full_ctx
,
177 size_t m_nbytes
, const uint8_t *m_bytes
,
178 size_t e_nbytes
, const uint8_t *e_bytes
,
179 size_t d_nbytes
, const uint8_t *d_bytes
,
180 struct ccrng_state
*rng
);
183 @function ccrsa_make_pub
184 @abstract Initialize public key based on modulus and public exponent as big endian byte arrays;
186 @param pubk allocated public key structure (see requirements below)
187 @param exp_nbytes Number of bytes in big endian exponent.
188 @param exp Pointer to big endian exponent e (may have leading 0's).
189 @param mod_nbytes Number of bytes in big endian modulus.
190 @param mod Pointer to big endian to rsa modulus N.
191 @result 0 iff successful.
193 @discussion ccrsa_ctx_n(pubk) must have been initialized based on the modulus size, typically using ccn_nof_size(mod_nbytes).
194 The public key structure pubk is typically allocated with ccrsa_pub_ctx_decl(ccn_sizeof_size(mod_nbytes), pubk);
197 CC_NONNULL((1, 3, 5))
198 int ccrsa_make_pub(ccrsa_pub_ctx_t pubk
,
199 size_t exp_nbytes
, const uint8_t *exp
,
200 size_t mod_nbytes
, const uint8_t *mod
);
203 @function ccrsa_pub_crypt
204 @abstract Perform an RSA public key operation: (in)^e mod m
205 @param key initialized public key defining e and m
206 @param out result of the operation, at least ccrsa_key_n(key) cc_units must have been allocated
207 @param in base of the exponentiation, of size ccrsa_key_n(key)
208 @result CCERR_OK if no error
210 @discussion Input to this function must not be secrets as the execution flow may expose their values
211 Clients can use ccn_read_uint() to convert bytes to cc_units to use for this API.
213 CC_NONNULL((1, 2, 3))
214 int ccrsa_pub_crypt(ccrsa_pub_ctx_t key
, cc_unit
*out
, const cc_unit
*in
);
217 @function ccrsa_generate_key
218 @abstract Generate a nbit RSA key pair.
220 @param nbits Bit size requested for the key
221 @param fk Allocated context where the generated key will be stored
222 @param e_nbytes Byte size of the input public exponent
223 @param e_bytes Input public exponent in big endian. Recommend value is {0x01, 0x00, 0x01}
224 @param rng Random Number generator used.
225 @result CCERR_OK if no error
228 fk should be allocated using ccrsa_full_ctx_decl(ccn_sizeof(nbits), fk).
229 The unsigned big endian byte array exponent e of length e_size is used as the exponent. It's an error to call this function with an exponent larger than nbits
232 int ccrsa_generate_key(size_t nbits
, ccrsa_full_ctx_t fk
,
233 size_t e_nbytes
, const void *e_bytes
, struct ccrng_state
*rng
) CC_WARN_RESULT
;
236 @function ccrsa_generate_fips186_key
237 @abstract Generate a nbit RSA key pair in conformance with FIPS186-4 standard.
239 @param nbits Bit size requested for the key
240 @param fk Allocated context where the generated key will be stored
241 @param e_nbytes Byte size of the input public exponent
242 @param e_bytes Input public exponent in big endian. Recommend value is {0x01, 0x00, 0x01}
243 @param rng Random Number generator used for p and q
244 @param rng_mr Random Number generator only used for the primality check
245 @result CCERR_OK if no error
248 fk should be allocated using ccrsa_full_ctx_decl(ccn_sizeof(nbits), fk).
249 rng and rng_mr shoud be set to the same value. The distinction is only relevant for testing
252 ccrsa_generate_fips186_key(size_t nbits
, ccrsa_full_ctx_t fk
,
253 size_t e_nbytes
, const void *e_bytes
,
254 struct ccrng_state
*rng
, struct ccrng_state
*rng_mr
) CC_WARN_RESULT
;
258 /* Construct RSA key from fix input in conformance with FIPS186-4 standard */
261 @function ccrsa_make_fips186_key
262 @abstract Initialize an RSA full key from explicit inputs necessary for validating conformance to FIPS186-4
264 @param nbits size in bits of the key to construct
265 @param e_n Size in cc_unit of the public exponent
266 @param e Public exponent represented in cc_units
267 @param xp1_nbytes Size in byte of the first seed for the construction of p
268 @param xp1 First seed for the construction of p
269 @param xp2_nbytes Size in byte of the second seed for the construction of p
270 @param xp2 Second seed for the construction of p
271 @param xp_nbytes Size in byte of the large seed for the construction of p
272 @param xp large seed for the construction of p
273 @param xq1_nbytes Size in byte of the first seed for the construction of q
274 @param xq1 First seed for the construction of q
275 @param xq2_nbytes Size in byte of the second seed for the construction of q
276 @param xq2 Second seed for the construction of q
277 @param xq_nbytes Size in byte of the large seed for the construction of q
278 @param xq large seed for the construction of q
279 @param fk Allocated context where the output constructed key is stored
280 @param np Pointer to the size in cc_unit of the buffer for the output prime factor p. Updated with actual size.
281 @param r_p Copy of the output prime factor p
282 @param nq Pointer to the size in cc_unit of the buffer for the output prime factor q. Updated with actual size.
283 @param r_q Copy of the output prime factor q
284 @param nm Pointer to the size in cc_unit of the buffer for the output modulus m=p*q. Updated with actual size.
285 @param r_m Copy of the output modulus m=p*q
286 @param nd Pointer to the size in cc_unit of the buffer for the output private exponent d. Updated with actual size.
287 @param r_d Copy of the output private exponent d
288 @result 0 iff successful.
291 fk should be allocated using ccrsa_full_ctx_decl(ccn_sizeof(nbits), fk).
294 CC_NONNULL((3, 5, 7, 9, 11, 13, 15, 16))
296 ccrsa_make_fips186_key(size_t nbits
,
297 const cc_size e_n
, const cc_unit
*e
,
298 const cc_size xp1_nbytes
, const cc_unit
*xp1
, const cc_size xp2_nbytes
, const cc_unit
*xp2
,
299 const cc_size xp_nbytes
, const cc_unit
*xp
,
300 const cc_size xq1_nbytes
, const cc_unit
*xq1
, const cc_size xq2_nbytes
, const cc_unit
*xq2
,
301 const cc_size xq_nbytes
, const cc_unit
*xq
,
303 cc_size
*np
, cc_unit
*r_p
,
304 cc_size
*nq
, cc_unit
*r_q
,
305 cc_size
*nm
, cc_unit
*r_m
,
306 cc_size
*nd
, cc_unit
*r_d
);
309 Signing and Verification algorithms
313 @function ccrsa_sign_pss
315 @brief ccrsa_sign_pss() generates RSASSA-PSS signature in PKCS1-V2 format given an input digest
317 @param key The RSA key
318 @param hashAlgorithm The hash algorithm used to generate mHash from the original message. It is also used inside the PSS encoding function.
319 @param MgfHashAlgorithm The hash algorithm for thr mask generation function
320 @param rng Random number geberator to generate salt in PSS encoding
321 @param salt_nbytes Intended length of the salt
322 @param digest_nbytes Length of message hash . Must be equal to hashAlgorithm->output_size
323 @param digest The input that needs to be signed. This is the hash of message M with length of hLen
324 @param sig_nbytes The length of generated signature in bytes, which equals the size of the RSA modulus.
325 @param sig The signature output
326 @return 0:ok, non-zero:error
329 note that in RSASSA-PSS, salt length is part of the signature as specified in ASN1
330 RSASSA-PSS-params ::= SEQUENCE {
331 hashAlgorithm [0] HashAlgorithm DEFAULT sha1,
332 maskGenAlgorithm [1] MaskGenAlgorithm DEFAULT mgf1SHA1,
333 saltLength [2] INTEGER DEFAULT 20,
334 trailerField [3] TrailerField DEFAULT trailerFieldBC
336 • If nlen = 1024 bits (i.e., 128 bytes), and the output length of the approved hash function output block is 512 bits (i.e., 64 bytes), then the length (in bytes) of the salt (sLen) shall satisfy 0 ≤ sLen ≤ hLen – 2,
337 • Otherwise, the length (in bytes) of the salt (sLen) shall satisfy 0 ≤ sLen ≤ hLen, where hLen is the length of the hash function output block (in bytes).
339 CC_NONNULL((1, 2, 3, 5, 7, 8, 9))
340 int ccrsa_sign_pss(ccrsa_full_ctx_t key
,
341 const struct ccdigest_info
* hashAlgorithm
, const struct ccdigest_info
* MgfHashAlgorithm
,
342 size_t salt_nbytes
, struct ccrng_state
*rng
,
343 size_t digest_nbytes
, const uint8_t *digest
,
344 size_t *sig_nbytes
, uint8_t *sig
);
347 @function ccrsa_sign_pss_msg
349 @brief ccrsa_sign_pss_msg() generates a RSASSA-PSS signature in PKCS1-V2 format given an input message
351 @param key The RSA key
352 @param hashAlgorithm The hash algorithm used to generate mHash from the input message. It is also used inside the PSS encoding function.
353 @param MgfHashAlgorithm The hash algorithm for thr mask generation function
354 @param rng Random number generator to generate salt in PSS encoding
355 @param salt_nbytes Intended length of the salt
356 @param msg_nbytes Length of message.
357 @param msg The input that needs to be signed. This will be hashed using `hashAlgorithm`
358 @param sig_nbytes The length of generated signature in bytes, which equals the size of the RSA modulus.
359 @param sig The signature output
360 @return 0:ok, non-zero:error
363 note that in RSASSA-PSS, salt length is part of the signature as specified in ASN1
364 RSASSA-PSS-params ::= SEQUENCE {
365 hashAlgorithm [0] HashAlgorithm DEFAULT sha1,
366 maskGenAlgorithm [1] MaskGenAlgorithm DEFAULT mgf1SHA1,
367 saltLength [2] INTEGER DEFAULT 20,
368 trailerField [3] TrailerField DEFAULT trailerFieldBC
370 • If nlen = 1024 bits (i.e., 128 bytes), and the output length of the approved hash function output block is 512 bits (i.e., 64 bytes), then the length (in bytes) of the salt (sLen) shall satisfy 0 ≤ sLen ≤ hLen – 2,
371 • Otherwise, the length (in bytes) of the salt (sLen) shall satisfy 0 ≤ sLen ≤ hLen, where hLen is the length of the hash function output block (in bytes).
373 CC_NONNULL((1, 2, 3, 5, 7, 8, 9))
374 int ccrsa_sign_pss_msg(ccrsa_full_ctx_t key
,
375 const struct ccdigest_info
* hashAlgorithm
, const struct ccdigest_info
* MgfHashAlgorithm
,
376 size_t salt_nbytes
, struct ccrng_state
*rng
,
377 size_t msg_nbytes
, const uint8_t *msg
,
378 size_t *sig_nbytes
, uint8_t *sig
);
381 @function ccrsa_verify_pss
383 @brief ccrsa_verify_pss() verifies RSASSA-PSS signature in PKCS1-V2 format
385 @param key The RSA public key
386 @param hashAlgorithm The hash algorithm used to generate mHash from the original message. It is also used inside the PSS encoding function.
387 @param MgfHashAlgorithm The hash algorithm for the mask generation function
388 @param digest_nbytes Length of message hash . Must be equal to hashAlgorithm->output_size
389 @param digest The signed message hash
390 @param sig_nbytes The length of generated signature in bytes, which equals the size of the RSA modulus.
391 @param sig The signature to verify
392 @param salt_nbytes Length of the salt as used during signature generation. Mismatch would result in the signature being considered invalid
393 @param valid Input boolean used to indicate a valid signature.
395 @result 0 && valid == True indicates a valid signature. If return != 0 or valid == False, the signature is invalid.
398 CC_NONNULL((2, 3, 5, 7, 9))
399 int ccrsa_verify_pss(ccrsa_pub_ctx_t key
,
400 const struct ccdigest_info
* hashAlgorithm
,
401 const struct ccdigest_info
* MgfHashAlgorithm
,
402 size_t digest_nbytes
, const uint8_t *digest
,
403 size_t sig_nbytes
, const uint8_t *sig
,
404 size_t salt_nbytes
, bool *valid
)
405 cc_deprecate_with_replacement("ccrsa_verify_pss_digest", 13.0, 10.15, 13.0, 6.0, 4.0);
408 @function ccrsa_verify_pss_digest
410 @brief ccrsa_verify_pss_digest() verifies RSASSA-PSS signature in PKCS1-V2 format, given the digest
412 @param key The RSA public key
413 @param di The hash algorithm used to generate the hash of the message.
414 @param mgfdi The hash algorithm for the mask generation function
415 @param digest_nbytes Length of digest. Must be equal to di->output_size
416 @param digest The signed message hash
417 @param sig_nbytes The length of generated signature in bytes, which equals the size of the RSA modulus.
418 @param sig The signature to verify
419 @param salt_nbytes Length of the salt as used during signature generation.
420 @param fault_canary_out OPTIONAL cc_fault_canary_t (see discussion)
422 @result CCERR_SIGNATURE_VALID on signature success.
423 CCERR_SIGNATURE_INVALID on signature failure.
424 other on some other signature verification issue.
426 @discussion If the fault_canary_out argument is not NULL, the value `CCRSA_PSS_FAULT_CANARY` will be placed into fault_canary_out
427 if the salted input hash is equal to the decoded hash (which strongly implies the signature is valid). Callers can then securely compare this output buffer against CCRSA_PSS_FAULT_CANARY, using CC_FAULT_CANARY_EQUAL, as an additional check of signature validity: if the two canary values are equal, the signature is valid otherwise it is not. If the signature is valid and the canary values are NOT equal this may indicate a potentially injected computational fault.
430 CC_NONNULL((1, 2, 3, 5, 7))
431 int ccrsa_verify_pss_digest(ccrsa_pub_ctx_t key
,
432 const struct ccdigest_info
* di
,
433 const struct ccdigest_info
* mgfdi
,
434 size_t digest_nbytes
, const uint8_t *digest
,
435 size_t sig_nbytes
, const uint8_t *sig
,
436 size_t salt_nbytes
, cc_fault_canary_t fault_canary_out
);
439 @function ccrsa_verify_pss_msg
441 @brief ccrsa_verify_pss_msg() verifies RSASSA-PSS signature in PKCS1-V2 format, given the message
443 @param key The RSA public key
444 @param di The hash algorithm used to generate the hash of the message.
445 @param mgfdi The hash algorithm for the mask generation function
446 @param msg_nbytes Length of message
447 @param msg The signed message
448 @param sig_nbytes The length of generated signature in bytes, which equals the size of the RSA modulus.
449 @param sig The signature to verify
450 @param salt_nbytes Length of the salt as used during signature generation.
451 @param fault_canary_out OPTIONAL cc_fault_canary_t (see discussion)
453 @result CCERR_SIGNATURE_VALID on signature success.
454 CCERR_SIGNATURE_INVALID on signature failure.
455 other on some other signature verification issue.
457 @discussion If the fault_canary_out argument is not NULL, the value `CCRSA_PSS_FAULT_CANARY` will be placed into fault_canary_out
458 if the salted input hash is equal to the decoded hash (which strongly implies the signature is valid). Callers can then securely compare this output buffer against CCRSA_PSS_FAULT_CANARY, using CC_FAULT_CANARY_EQUAL, as an additional check of signature validity: if the two canary values are equal, the signature is valid otherwise it is not. If the signature is valid and the canary values are NOT equal this may indicate a potentially injected computational fault.
461 CC_NONNULL((1, 2, 3, 5, 7))
462 int ccrsa_verify_pss_msg(ccrsa_pub_ctx_t key
,
463 const struct ccdigest_info
* di
,
464 const struct ccdigest_info
* mgfdi
,
465 size_t msg_nbytes
, const uint8_t *msg
,
466 size_t sig_nbytes
, const uint8_t *sig
,
467 size_t salt_nbytes
, cc_fault_canary_t fault_canary_out
);
471 @function ccrsa_sign_pkcs1v15
472 @abstract RSA signature with PKCS#1 v1.5 format per PKCS#1 v2.2
475 @param oid OID describing the type of digest passed in
476 @param digest_len Byte length of the digest
477 @param digest Byte array of digest_len bytes containing the digest
478 @param sig_len Pointer to the number of bytes allocated for sig.
479 Output the exact size of the signature.
480 @param sig Pointer to the allocated buffer of size *sig_len
481 for the output signature
483 @result CCERR_OK iff successful.
485 @discussion Null OID is a special case, required to support RFC 4346 where the padding
486 is based on SHA1+MD5. In general it is not recommended to use a NULL OID,
487 except when strictly required for interoperability
490 CC_NONNULL((1, 4, 5, 6))
491 int ccrsa_sign_pkcs1v15(ccrsa_full_ctx_t key
, const uint8_t *oid
,
492 size_t digest_len
, const uint8_t *digest
,
493 size_t *sig_len
, uint8_t *sig
);
496 @function ccrsa_sign_pkcs1v15_msg
497 @abstract RSA signature with PKCS#1 v1.5 format per PKCS#1 v2.2
500 @param di Digest context
501 @param msg_len Byte length of the message to sign
502 @param msg Byte array of msg_len bytes containing the message. Will be hashed with di.
503 @param sig_len Pointer to the number of bytes allocated for sig.
504 Output the exact size of the signature.
505 @param sig Pointer to the allocated buffer of size *sig_len
506 for the output signature
508 @result CCERR_OK iff successful.
510 @discussion Null OID is not supported by this API.
513 CC_NONNULL((1, 2, 4, 5, 6))
514 int ccrsa_sign_pkcs1v15_msg(ccrsa_full_ctx_t key
, const struct ccdigest_info
* di
,
515 size_t msg_len
, const uint8_t *msg
,
516 size_t *sig_len
, uint8_t *sig
);
520 @function ccrsa_verify_pkcs1v15
521 @abstract RSA signature with PKCS#1 v1.5 format per PKCS#1 v2.2
523 @param key Public key
524 @param oid OID describing the type of digest passed in
525 @param digest_len Byte length of the digest
526 @param digest Byte array of digest_len bytes containing the digest
527 @param sig_len Number of bytes of the signature sig.
528 @param sig Pointer to the signature buffer of sig_len
529 @param valid Output boolean, true if the signature is valid.
531 @result A return value of 0 and valid = True indicates a valid signature.
532 A non-zero return value or valid = False indicates an invalid signature.
534 @discussion Null OID is a special case, required to support RFC 4346
535 where the padding is based on SHA1+MD5. In general it is not
536 recommended to use a NULL OID, except when strictly required for
539 CC_NONNULL((1, 4, 6, 7))
540 int ccrsa_verify_pkcs1v15(ccrsa_pub_ctx_t key
, const uint8_t *oid
,
541 size_t digest_len
, const uint8_t *digest
,
542 size_t sig_len
, const uint8_t *sig
,
546 @function ccrsa_verify_pkcs1v15_digest
547 @abstract RSA signature with PKCS#1 v1.5 format per PKCS#1 v2.2, given a digest
549 @param key Public key
550 @param oid OID describing the type of digest passed in
551 @param digest_len Byte length of the digest
552 @param digest Byte array of digest_len bytes containing the digest
553 @param sig_len Number of bytes of the signature sig.
554 @param sig Pointer to the signature buffer of sig_len
555 @param fault_canary_out OPTIONAL cc_fault_canary_t
557 @result CCERR_VALID_SIGNATURE if a valid signature.
558 CCERR_INVALID_SIGNATURE if an invalid signature.
559 Other if the verification procedure failed.
561 @discussion If the fault_canary_out argument is not NULL, the value `CCRSA_PKCS1_FAULT_CANARY` will be placed into fault_canary_out
562 if the input hash is equal to the decoded hash (which strongly implies the signature is valid). Callers can then securely compare this output buffer against CCRSA_PKCS1_FAULT_CANARY, using CC_FAULT_CANARY_EQUAL, as an additional check of signature validity: if the two canary values are equal, the signature is valid otherwise it is not. If the signature is valid and the canary values are NOT equal this may indicate a potentially injected computational fault.
564 CC_NONNULL((1, 4, 6))
565 int ccrsa_verify_pkcs1v15_digest(ccrsa_pub_ctx_t key
, const uint8_t *oid
,
566 size_t digest_len
, const uint8_t *digest
,
567 size_t sig_len
, const uint8_t *sig
,
568 cc_fault_canary_t fault_canary_out
);
571 @function ccrsa_verify_pkcs1v15_msg
572 @abstract RSA signature with PKCS#1 v1.5 format per PKCS#1 v2.2
574 @param key Public key
575 @param di Hash function
576 @param msg_len Byte length of the digest
577 @param msg Byte array of digest_len bytes containing the digest
578 @param sig_len Number of bytes of the signature sig.
579 @param sig Pointer to the signature buffer of sig_len
580 @param fault_canary_out OPTIONAL cc_fault_canary_t
582 @result CCERR_VALID_SIGNATURE if a valid signature.
583 CCERR_INVALID_SIGNATURE if an invalid signature.
584 Other if the verification procedure failed.
586 @discussion Null OID is not supported by this API.
587 If the fault_canary_out argument is not NULL, the value `CCRSA_PKCS1_FAULT_CANARY` will
588 be placed into fault_canary_out if the input hash is equal to the decoded hash (which strongly
589 implies the signature is valid). Callers can then securely compare this output buffer against CCRSA_PKCS1_FAULT_CANARY, using CC_FAULT_CANARY_EQUAL, as an additional check of signature validity: if the two canary values are equal, the signature is valid otherwise it is not. If the signature is valid and the canary values are NOT equal this may indicate a potentially injected computational fault.
591 CC_NONNULL((1, 2, 4, 6))
592 int ccrsa_verify_pkcs1v15_msg(ccrsa_pub_ctx_t key
, const struct ccdigest_info
* di
,
593 size_t msg_len
, const uint8_t *msg
,
594 size_t sig_len
, const uint8_t *sig
,
595 cc_fault_canary_t fault_canary_out
);
598 @function ccder_encode_rsa_pub_size
599 @abstract Calculate size of public key export format data package.
601 @param key Public key
603 @result Returns size required for encoding.
607 size_t ccder_encode_rsa_pub_size(const ccrsa_pub_ctx_t key
);
610 @function ccrsa_export_priv_pkcs1
611 @abstract Export a public key.
613 @param key Public key
614 @param der Beginning of output DER buffer
615 @param der_end End of output DER buffer
618 CC_NONNULL((1, 2, 3))
619 uint8_t *ccder_encode_rsa_pub(const ccrsa_pub_ctx_t key
, uint8_t *der
, uint8_t *der_end
);
623 @function ccder_encode_rsa_priv_size
624 @abstract Calculate size of full key exported in PKCS#1 format.
628 @result Returns size required for encoding.
632 size_t ccder_encode_rsa_priv_size(const ccrsa_full_ctx_t key
);
635 @function ccder_encode_rsa_priv
636 @abstract Export a full key in PKCS#1 format.
639 @param der Beginning of output DER buffer
640 @param der_end End of output DER buffer
643 CC_NONNULL((1, 2, 3))
644 uint8_t *ccder_encode_rsa_priv(const ccrsa_full_ctx_t key
, const uint8_t *der
, uint8_t *der_end
);
647 @function ccder_decode_rsa_pub_n
648 @abstract Calculate "n" for a public key imported from a data package.
651 @param der Beginning of input DER buffer
652 @param der_end End of input DER buffer
654 @result the "n" of the RSA key that would result from the import. This can be used
655 to declare the key itself.
659 cc_size
ccder_decode_rsa_pub_n(const uint8_t *der
, const uint8_t *der_end
);
662 @function ccder_decode_rsa_pub
663 @abstract Import a public RSA key from a package in public key format.
666 @param key Public key (n must be set)
667 @param der Beginning of input DER buffer
668 @param der_end End of input DER buffer
670 @result Key is initialized using the data in the public key message.
673 CC_NONNULL((1, 2, 3))
674 const uint8_t *ccder_decode_rsa_pub(const ccrsa_pub_ctx_t key
, const uint8_t *der
, const uint8_t *der_end
);
677 @function ccder_decode_rsa_pub_x509_n
678 @abstract Calculate "n" for a public key imported from a data package in x509 format
680 @param der Beginning of input DER buffer
681 @param der_end End of input DER buffer
683 @result the "n" of the RSA key that would result from the import. This can be used
684 to declare the key itself.
688 cc_size
ccder_decode_rsa_pub_x509_n(const uint8_t *der
, const uint8_t *der_end
);
691 @function ccder_decode_rsa_pub_x509
692 @abstract Import a public RSA key from a package in x509 format.
694 @param key Public key (n must be set)
695 @param der Beginning of input DER buffer
696 @param der_end End of input DER buffer
698 @result Key is initialized using the data in the public key message.
701 CC_NONNULL((1, 2, 3))
702 const uint8_t *ccder_decode_rsa_pub_x509(const ccrsa_pub_ctx_t key
, const uint8_t *der
, const uint8_t *der_end
);
706 @function ccder_decode_rsa_priv_n
707 @abstract Calculate "n" for a private key imported from a data package.
709 @param der Beginning of input DER buffer
710 @param der_end End of input DER buffer
712 @result the "n" of the RSA key that would result from the import. This can be used
713 to declare the key itself.
717 cc_size
ccder_decode_rsa_priv_n(const uint8_t *der
, const uint8_t *der_end
);
720 @function ccder_decode_rsa_priv
721 @abstract Import a private RSA key from a package in PKCS#1 format.
723 @param key Full key (n must be set)
724 @param der Beginning of input DER buffer
725 @param der_end End of input DER buffer
727 @result Key is initialized using the data in the public key message.
730 CC_NONNULL((1, 2, 3))
731 const uint8_t *ccder_decode_rsa_priv(const ccrsa_full_ctx_t key
, const uint8_t *der
, const uint8_t *der_end
);
734 @function ccrsa_export_pub_size
735 @abstract Calculate size of public key exported data package.
737 @param key Public key
739 @result Returns size required for encoding.
742 CC_INLINE
CC_NONNULL((1))
743 size_t ccrsa_export_pub_size(const ccrsa_pub_ctx_t key
) {
744 return ccder_encode_rsa_pub_size(key
);
748 @function ccrsa_export_pub
749 @abstract Export a public key in public key format.
751 @param key Public key
752 @param out_len Allocated size
753 @param out Output buffer
757 int ccrsa_export_pub(const ccrsa_pub_ctx_t key
, size_t out_len
, uint8_t *out
);
759 @function ccrsa_import_pub_n
760 @abstract Calculate "n" for a public key imported from a data package.
762 @param inlen Length of public key package data
763 @param der pointer to public key package data
765 @result the "n" of the RSA key that would result from the import. This can be used
766 to declare the key itself.
769 CC_INLINE
CC_NONNULL((2))
770 cc_size
ccrsa_import_pub_n(size_t inlen
, const uint8_t *der
) {
771 cc_size size
= ccder_decode_rsa_pub_x509_n(der
, der
+ inlen
);
773 size
= ccder_decode_rsa_pub_n(der
, der
+ inlen
);
779 @function ccrsa_import_pub
780 @abstract Import a public RSA key from a package in public key format.
782 @param key Public key (n must be set)
783 @param inlen Length of public key package data
784 @param der pointer to public key package data
786 @result Key is initialized using the data in the public key message.
790 int ccrsa_import_pub(ccrsa_pub_ctx_t key
, size_t inlen
, const uint8_t *der
);
793 @function ccrsa_export_priv_size
794 @abstract Calculate size of full key exported in PKCS#1 format.
798 @result Returns size required for encoding.
801 CC_INLINE
CC_NONNULL((1))
802 size_t ccrsa_export_priv_size(const ccrsa_full_ctx_t key
) {
803 return ccder_encode_rsa_priv_size(key
);
807 @function ccrsa_export_priv
808 @abstract Export a full key in PKCS#1 format.
811 @param out_len Allocated size
812 @param out Output buffer
815 CC_INLINE
CC_NONNULL((1, 3))
816 int ccrsa_export_priv(const ccrsa_full_ctx_t key
, size_t out_len
, uint8_t *out
) {
817 return (ccder_encode_rsa_priv(key
, out
, out
+out_len
) != out
);
821 @function ccrsa_import_priv_n
822 @abstract Calculate size of full key exported in PKCS#1 format.
824 @param inlen Length of PKCS#1 package data
825 @param der pointer to PKCS#1 package data
827 @result the "n" of the RSA key that would result from the import. This can be used
828 to declare the key itself.
831 CC_INLINE
CC_NONNULL((2))
832 cc_size
ccrsa_import_priv_n(size_t inlen
, const uint8_t *der
) {
833 return ccder_decode_rsa_priv_n(der
, der
+ inlen
);
837 @function ccrsa_import_priv
838 @abstract Import a full RSA key from a package in PKCS#1 format.
840 @param key Full key (n must be set)
841 @param inlen Length of PKCS#1 package data
842 @param der pointer to PKCS#1 package data
844 @result Key is initialized using the data in the PKCS#1 message.
847 CC_INLINE
CC_NONNULL((1, 3))
848 int ccrsa_import_priv(ccrsa_full_ctx_t key
, size_t inlen
, const uint8_t *der
) {
849 return (ccder_decode_rsa_priv(key
, der
, der
+inlen
) == NULL
);
853 @function ccrsa_get_pubkey_components
854 @abstract Copy each component of the public key to the given buffers
856 @param pubkey Public key
857 @param modulus Buffer to the output buffer for the modulus
858 @param modulusLength Pointer to the byte size allocated for the modulus, updated with actual output size
859 @param exponent Buffer to the output buffer for the exponent
860 @param exponentLength Pointer to the byte size allocated for the exponent, updated with actual output size
862 @return 0 is success, not 0 in case of error
864 @discussion if either allocated buffer length is insufficient, the function returns an error
867 int ccrsa_get_pubkey_components(const ccrsa_pub_ctx_t pubkey
, uint8_t *modulus
, size_t *modulusLength
, uint8_t *exponent
, size_t *exponentLength
);
870 @function ccrsa_get_fullkey_components
871 @abstract Copy each component of the public key to the given buffers
874 @param modulus Buffer to the output buffer for the modulus
875 @param modulusLength Pointer to the byte size allocated for the modulus, updated with actual output size
876 @param exponent Buffer to the output buffer for the exponent
877 @param exponentLength Pointer to the byte size allocated for the exponent, updated with actual output size
878 @param p Buffer to the output buffer for the first prime factor of the modulus
879 @param pLength Pointer to the byte size allocated for the prime factor, updated with actual output size
880 @param q Buffer to the output buffer for the second prime factor of the modulus
881 @param qLength Pointer to the byte size allocated for the prime factor, updated with actual output size
883 @return 0 is success, not 0 in case of error
885 @discussion if either allocated buffer length is insufficient, the function returns an error
888 int ccrsa_get_fullkey_components(const ccrsa_full_ctx_t key
, uint8_t *modulus
, size_t *modulusLength
, uint8_t *exponent
, size_t *exponentLength
,
889 uint8_t *p
, size_t *pLength
, uint8_t *q
, size_t *qLength
);
893 @function ccrsa_dump_public_key
894 @abstract Print a rsa public key in the console (printf)
896 @param key Public key
898 void ccrsa_dump_public_key(ccrsa_pub_ctx_t key
);
901 @function ccrsa_dump_full_key
902 @abstract Print a rsa private key in the console (printf)
904 @param key Public key
906 void ccrsa_dump_full_key(ccrsa_full_ctx_t key
);
908 #endif /* _CORECRYPTO_CCRSA_H_ */