xref: /optee_os/core/lib/libtomcrypt/src/headers/tomcrypt_private.h (revision 2a65ecaf7d6f855e24ce1a117fe1931f7378f82c)
1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis */
2 /* SPDX-License-Identifier: Unlicense */
3 
4 #include "tomcrypt.h"
5 
6 /*
7  * Internal Macros
8  */
9 /* Static assertion */
10 #define LTC_STATIC_ASSERT(msg, cond) typedef char ltc_static_assert_##msg[(cond) ? 1 : -1];
11 
12 #define LTC_PAD_MASK       (0xF000U)
13 
14 #if defined(ENDIAN_64BITWORD)
15    #define CONSTPTR(n) CONST64(n)
16 #else
17    #define CONSTPTR(n) n ## uL
18 #endif
19 
20 LTC_STATIC_ASSERT(correct_CONSTPTR_size, sizeof(CONSTPTR(1)) == sizeof(void*))
21 
22 /* Poor-man's `uintptr_t` since we can't use stdint.h
23  * c.f. https://github.com/DCIT/perl-CryptX/issues/95#issuecomment-1745280962 */
24 typedef size_t ltc_uintptr;
25 
26 LTC_STATIC_ASSERT(correct_ltc_uintptr_size, sizeof(ltc_uintptr) == sizeof(void*))
27 
28 /* Aligns a `unsigned char` buffer `buf` to `n` bytes and returns that aligned address.
29  * Make sure that the buffer that is passed is huge enough.
30  */
31 #define LTC_ALIGN_BUF(buf, n) ((void*)((ltc_uintptr)&((unsigned char*)(buf))[n - 1] & (~(CONSTPTR(n) - CONSTPTR(1)))))
32 
33 /* `NULL` as defined by the standard is not guaranteed to be of a pointer
34  * type. In order to make sure that in vararg API's a pointer type is used,
35  * define our own version and use that one internally.
36  */
37 #ifndef LTC_NULL
38    #define LTC_NULL ((void *)0)
39 #endif
40 
41 /*
42  * Internal Enums
43  */
44 
45 enum ltc_oid_id {
46    LTC_OID_RSA,
47    LTC_OID_DSA,
48    LTC_OID_EC,
49    LTC_OID_EC_PRIMEF,
50    LTC_OID_X25519,
51    LTC_OID_ED25519,
52 };
53 
54 /*
55  * Internal Types
56  */
57 
58 typedef struct {
59   int size;
60   const char *name, *base, *prime;
61 } ltc_dh_set_type;
62 
63 
64 typedef int (*fn_kdf_t)(const unsigned char *password, unsigned long password_len,
65                               const unsigned char *salt,     unsigned long salt_len,
66                               int iteration_count,  int hash_idx,
67                               unsigned char *out,   unsigned long *outlen);
68 
69 typedef struct {
70    /* KDF */
71    fn_kdf_t kdf;
72    /* Hash or HMAC */
73    const char* h;
74    /* cipher */
75    const char* c;
76    unsigned long keylen;
77    /* not used for pbkdf2 */
78    unsigned long blocklen;
79 } pbes_properties;
80 
81 typedef struct
82 {
83    pbes_properties type;
84    const void *pwd;
85    unsigned long pwdlen;
86    ltc_asn1_list *enc_data;
87    ltc_asn1_list *salt;
88    ltc_asn1_list *iv;
89    unsigned long iterations;
90    /* only used for RC2 */
91    unsigned long key_bits;
92 } pbes_arg;
93 
94 /*
95  * Internal functions
96  */
97 
98 
99 /* tomcrypt_cipher.h */
100 
101 #if defined(LTC_AES_NI) && defined(LTC_AMD64_SSE4_1)
102 #define LTC_HAS_AES_NI
103 #endif
104 
105 void blowfish_enc(ulong32 *data, unsigned long blocks, const symmetric_key *skey);
106 int blowfish_expand(const unsigned char *key, int keylen,
107                     const unsigned char *data, int datalen,
108                     symmetric_key *skey);
109 int blowfish_setup_with_data(const unsigned char *key, int keylen,
110                              const unsigned char *data, int datalen,
111                              symmetric_key *skey);
112 
113 /* tomcrypt_hash.h */
114 
115 /* a macro for making hash "process" functions */
116 #define HASH_PROCESS_(func_name, compress_name, compress_n_name, state_var, block_size)     \
117 int func_name (hash_state * md, const unsigned char *in, unsigned long inlen)               \
118 {                                                                                           \
119     unsigned long n, blocks;                                                                \
120     int           err;                                                                      \
121     int           (*compress)(hash_state *, const unsigned char *) = compress_name;         \
122     int           (*compress_n)(hash_state *, const unsigned char *, int) = compress_n_name;\
123     LTC_ARGCHK(md != NULL);                                                                 \
124     LTC_ARGCHK(in != NULL);                                                                 \
125     if (md-> state_var .curlen > sizeof(md-> state_var .buf)) {                             \
126        return CRYPT_INVALID_ARG;                                                            \
127     }                                                                                       \
128     if (((md-> state_var .length + inlen * 8) < md-> state_var .length)                     \
129           || ((inlen * 8) < inlen)) {                                                       \
130       return CRYPT_HASH_OVERFLOW;                                                           \
131     }                                                                                       \
132     while (inlen > 0) {                                                                     \
133         if (md-> state_var .curlen == 0 && inlen >= block_size) {                           \
134            if (compress_n) {                                                                \
135               blocks = inlen / block_size;                                                  \
136               err = compress_n (md, in, blocks);                                            \
137            } else {                                                                         \
138               blocks = 1;                                                                   \
139               err = compress (md, in);                                                      \
140            }                                                                                \
141            if (err != CRYPT_OK)                                                             \
142               return err;                                                                   \
143            md-> state_var .length += blocks * block_size * 8;                               \
144            in             += blocks * block_size;                                           \
145            inlen          -= blocks * block_size;                                           \
146         } else {                                                                            \
147            n = MIN(inlen, (block_size - md-> state_var .curlen));                           \
148            XMEMCPY(md-> state_var .buf + md-> state_var.curlen, in, (size_t)n);             \
149            md-> state_var .curlen += n;                                                     \
150            in             += n;                                                             \
151            inlen          -= n;                                                             \
152            if (md-> state_var .curlen == block_size) {                                      \
153               if (compress_n) {                                                             \
154                  err = compress_n (md, md-> state_var .buf, 1);                             \
155               } else {                                                                      \
156                  err = compress (md, md-> state_var .buf);                                  \
157               }                                                                             \
158               if (err != CRYPT_OK) {                                                        \
159                  return err;                                                                \
160               }                                                                             \
161               md-> state_var .length += 8*block_size;                                       \
162               md-> state_var .curlen = 0;                                                   \
163            }                                                                                \
164        }                                                                                    \
165     }                                                                                       \
166     return CRYPT_OK;                                                                        \
167 }
168 
169 /* define a hash "process" function based on a 1-block compress function */
170 #define HASH_PROCESS(func_name, compress_name, state_var, block_size)                       \
171         HASH_PROCESS_(func_name, compress_name, NULL, state_var, block_size)
172 
173 /* define a hash "process" function based on a n-block compress function */
174 #define HASH_PROCESS_NBLOCKS(func_name, compress_n_name, state_var, block_size)             \
175        HASH_PROCESS_(func_name, NULL, compress_n_name, state_var, block_size)
176 
177 
178 /* tomcrypt_mac.h */
179 
180 int ocb3_int_ntz(unsigned long x);
181 void ocb3_int_xor_blocks(unsigned char *out, const unsigned char *block_a, const unsigned char *block_b, unsigned long block_len);
182 
183 
184 /* tomcrypt_math.h */
185 
186 #if !defined(DESC_DEF_ONLY)
187 
188 #define MP_DIGIT_BIT                 ltc_mp.bits_per_digit
189 
190 /* some handy macros */
191 #define mp_init(a)                   ltc_mp.init(a)
192 #define mp_init_multi                ltc_init_multi
193 #define mp_init_size(a, b)           ltc_mp.init_size(a, b)
194 #define mp_init_multi_size           ltc_init_multi_size
195 #define mp_clear(a)                  ltc_mp.deinit(a)
196 #define mp_clear_multi               ltc_deinit_multi
197 #define mp_cleanup_multi             ltc_cleanup_multi
198 #define mp_init_copy(a, b)           ltc_mp.init_copy(a, b)
199 
200 #define mp_neg(a, b)                 ltc_mp.neg(a, b)
201 #define mp_copy(a, b)                ltc_mp.copy(a, b)
202 
203 #define mp_set(a, b)                 ltc_mp.set_int(a, b)
204 #define mp_set_int(a, b)             ltc_mp.set_int(a, b)
205 #define mp_get_int(a)                ltc_mp.get_int(a)
206 #define mp_get_digit(a, n)           ltc_mp.get_digit(a, n)
207 #define mp_get_digit_count(a)        ltc_mp.get_digit_count(a)
208 #define mp_cmp(a, b)                 ltc_mp.compare(a, b)
209 #define mp_cmp_d(a, b)               ltc_mp.compare_d(a, b)
210 #define mp_count_bits(a)             ltc_mp.count_bits(a)
211 #define mp_cnt_lsb(a)                ltc_mp.count_lsb_bits(a)
212 #define mp_2expt(a, b)               ltc_mp.twoexpt(a, b)
213 
214 #define mp_read_radix(a, b, c)       ltc_mp.read_radix(a, b, c)
215 #define mp_toradix(a, b, c)          ltc_mp.write_radix(a, b, c)
216 #define mp_unsigned_bin_size(a)      ltc_mp.unsigned_size(a)
217 #define mp_to_unsigned_bin(a, b)     ltc_mp.unsigned_write(a, b)
218 #define mp_read_unsigned_bin(a, b, c) ltc_mp.unsigned_read(a, b, c)
219 
220 #define mp_add(a, b, c)              ltc_mp.add(a, b, c)
221 #define mp_add_d(a, b, c)            ltc_mp.addi(a, b, c)
222 #define mp_sub(a, b, c)              ltc_mp.sub(a, b, c)
223 #define mp_sub_d(a, b, c)            ltc_mp.subi(a, b, c)
224 #define mp_mul(a, b, c)              ltc_mp.mul(a, b, c)
225 #define mp_mul_d(a, b, c)            ltc_mp.muli(a, b, c)
226 #define mp_sqr(a, b)                 ltc_mp.sqr(a, b)
227 #define mp_sqrtmod_prime(a, b, c)    ltc_mp.sqrtmod_prime(a, b, c)
228 #define mp_div(a, b, c, d)           ltc_mp.mpdiv(a, b, c, d)
229 #define mp_div_2(a, b)               ltc_mp.div_2(a, b)
230 #define mp_mod(a, b, c)              ltc_mp.mpdiv(a, b, NULL, c)
231 #define mp_mod_d(a, b, c)            ltc_mp.modi(a, b, c)
232 #define mp_gcd(a, b, c)              ltc_mp.gcd(a, b, c)
233 #define mp_lcm(a, b, c)              ltc_mp.lcm(a, b, c)
234 
235 #define mp_addmod(a, b, c, d)        ltc_mp.addmod(a, b, c, d)
236 #define mp_submod(a, b, c, d)        ltc_mp.submod(a, b, c, d)
237 #define mp_mulmod(a, b, c, d)        ltc_mp.mulmod(a, b, c, d)
238 #define mp_sqrmod(a, b, c)           ltc_mp.sqrmod(a, b, c)
239 #define mp_invmod(a, b, c)           ltc_mp.invmod(a, b, c)
240 
241 #define mp_montgomery_setup(a, b)    ltc_mp.montgomery_setup(a, b)
242 #define mp_montgomery_normalization(a, b) ltc_mp.montgomery_normalization(a, b)
243 #define mp_montgomery_reduce(a, b, c)   ltc_mp.montgomery_reduce(a, b, c)
244 #define mp_montgomery_free(a)        ltc_mp.montgomery_deinit(a)
245 
246 #define mp_exptmod(a,b,c,d)          ltc_mp.exptmod(a,b,c,d)
247 #define mp_prime_is_prime(a, b, c)   ltc_mp.isprime(a, b, c)
248 
249 #define mp_iszero(a)                 (mp_cmp_d(a, 0) == LTC_MP_EQ ? LTC_MP_YES : LTC_MP_NO)
250 #define mp_isodd(a)                  (mp_get_digit_count(a) > 0 ? (mp_get_digit(a, 0) & 1 ? LTC_MP_YES : LTC_MP_NO) : LTC_MP_NO)
251 #define mp_exch(a, b)                do { void *ABC__tmp = a; a = b; b = ABC__tmp; } while(0)
252 
253 #define mp_tohex(a, b)               mp_toradix(a, b, 16)
254 
255 #define mp_rand(a, b)                ltc_mp.rand(a, b)
256 
257 #endif
258 
259 
260 /* tomcrypt_misc.h */
261 
262 typedef enum {
263    /** Use `\r\n` as line separator */
264    BASE64_PEM_CRLF = 1,
265    /** Create output with 72 chars line length */
266    BASE64_PEM_SSH = 2,
267 } base64_pem_flags;
268 
269 int base64_encode_pem(const unsigned char *in,  unsigned long inlen,
270                                      char *out, unsigned long *outlen,
271                             unsigned int  flags);
272 
273 void copy_or_zeromem(const unsigned char* src, unsigned char* dest, unsigned long len, int coz);
274 
275 int pbes_decrypt(const pbes_arg  *arg, unsigned char *dec_data, unsigned long *dec_size);
276 
277 int pbes1_extract(const ltc_asn1_list *s, pbes_arg *res);
278 int pbes2_extract(const ltc_asn1_list *s, pbes_arg *res);
279 
280 
281 /* tomcrypt_pk.h */
282 
283 int rand_bn_bits(void *N, int bits, prng_state *prng, int wprng);
284 int rand_bn_upto(void *N, void *limit, prng_state *prng, int wprng);
285 
286 int pk_get_oid(enum ltc_oid_id id, const char **st);
287 int pk_oid_str_to_num(const char *OID, unsigned long *oid, unsigned long *oidlen);
288 int pk_oid_num_to_str(const unsigned long *oid, unsigned long oidlen, char *OID, unsigned long *outlen);
289 
290 /* ---- DH Routines ---- */
291 #ifdef LTC_MRSA
292 int rsa_init(rsa_key *key);
293 void rsa_shrink_key(rsa_key *key);
294 int rsa_make_key_bn_e(prng_state *prng, int wprng, int size, void *e,
295                       rsa_key *key); /* used by op-tee */
296 int rsa_import_pkcs1(const unsigned char *in, unsigned long inlen, rsa_key *key);
297 #endif /* LTC_MRSA */
298 
299 /* ---- DH Routines ---- */
300 #ifdef LTC_MDH
301 extern const ltc_dh_set_type ltc_dh_sets[];
302 
303 int dh_check_pubkey(const dh_key *key);
304 #endif /* LTC_MDH */
305 
306 /* ---- ECC Routines ---- */
307 #ifdef LTC_MECC
308 int ecc_set_curve_from_mpis(void *a, void *b, void *prime, void *order, void *gx, void *gy, unsigned long cofactor, ecc_key *key);
309 int ecc_copy_curve(const ecc_key *srckey, ecc_key *key);
310 int ecc_set_curve_by_size(int size, ecc_key *key);
311 int ecc_import_subject_public_key_info(const unsigned char *in, unsigned long inlen, ecc_key *key);
312 
313 #ifdef LTC_SSH
314 int ecc_ssh_ecdsa_encode_name(char *buffer, unsigned long *buflen, const ecc_key *key);
315 #endif
316 
317 /* low level functions */
318 ecc_point *ltc_ecc_new_point(void);
319 void       ltc_ecc_del_point(ecc_point *p);
320 int        ltc_ecc_set_point_xyz(ltc_mp_digit x, ltc_mp_digit y, ltc_mp_digit z, ecc_point *p);
321 int        ltc_ecc_copy_point(const ecc_point *src, ecc_point *dst);
322 int        ltc_ecc_is_point(const ltc_ecc_dp *dp, void *x, void *y);
323 int        ltc_ecc_is_point_at_infinity(const ecc_point *P, void *modulus, int *retval);
324 int        ltc_ecc_import_point(const unsigned char *in, unsigned long inlen, void *prime, void *a, void *b, void *x, void *y);
325 int        ltc_ecc_export_point(unsigned char *out, unsigned long *outlen, void *x, void *y, unsigned long size, int compressed);
326 int        ltc_ecc_verify_key(const ecc_key *key);
327 
328 /* point ops (mp == montgomery digit) */
329 #if !defined(LTC_MECC_ACCEL) || defined(LTM_DESC) || defined(GMP_DESC)
330 /* R = 2P */
331 int ltc_ecc_projective_dbl_point(const ecc_point *P, ecc_point *R, void *ma, void *modulus, void *mp);
332 
333 /* R = P + Q */
334 int ltc_ecc_projective_add_point(const ecc_point *P, const ecc_point *Q, ecc_point *R, void *ma, void *modulus, void *mp);
335 #endif
336 
337 #if defined(LTC_MECC_FP)
338 /* optimized point multiplication using fixed point cache (HAC algorithm 14.117) */
339 int ltc_ecc_fp_mulmod(void *k, ecc_point *G, ecc_point *R, void *a, void *modulus, int map);
340 
341 /* functions for saving/loading/freeing/adding to fixed point cache */
342 int ltc_ecc_fp_save_state(unsigned char **out, unsigned long *outlen);
343 int ltc_ecc_fp_restore_state(unsigned char *in, unsigned long inlen);
344 void ltc_ecc_fp_free(void);
345 int ltc_ecc_fp_add_point(ecc_point *g, void *modulus, int lock);
346 
347 /* lock/unlock all points currently in fixed point cache */
348 void ltc_ecc_fp_tablelock(int lock);
349 #endif
350 
351 /* R = kG */
352 int ltc_ecc_mulmod(void *k, const ecc_point *G, ecc_point *R, void *a, void *modulus, int map);
353 
354 #ifdef LTC_ECC_SHAMIR
355 /* kA*A + kB*B = C */
356 int ltc_ecc_mul2add(const ecc_point *A, void *kA,
357                     const ecc_point *B, void *kB,
358                           ecc_point *C,
359                                void *ma,
360                                void *modulus);
361 
362 #ifdef LTC_MECC_FP
363 /* Shamir's trick with optimized point multiplication using fixed point cache */
364 int ltc_ecc_fp_mul2add(const ecc_point *A, void *kA,
365                        const ecc_point *B, void *kB,
366                              ecc_point *C,
367                                   void *ma,
368                                   void *modulus);
369 #endif
370 
371 #endif
372 
373 
374 /* map P to affine from projective */
375 int ltc_ecc_map(ecc_point *P, void *modulus, void *mp);
376 #endif /* LTC_MECC */
377 
378 #ifdef LTC_MDSA
379 int dsa_int_validate_xy(const dsa_key *key, int *stat);
380 int dsa_int_validate_pqg(const dsa_key *key, int *stat);
381 int dsa_int_validate_primes(const dsa_key *key, int *stat);
382 #endif /* LTC_MDSA */
383 
384 
385 #ifdef LTC_CURVE25519
386 
387 int tweetnacl_crypto_sign(
388   unsigned char *sm,unsigned long long *smlen,
389   const unsigned char *m,unsigned long long mlen,
390   const unsigned char *sk,const unsigned char *pk,
391   const unsigned char *ctx,unsigned long long cs);
392 int tweetnacl_crypto_sign_open(
393   int *stat,
394   unsigned char *m,unsigned long long *mlen,
395   const unsigned char *sm,unsigned long long smlen,
396   const unsigned char *ctx, unsigned long long cs,
397   const unsigned char *pk);
398 int tweetnacl_crypto_sign_keypair(prng_state *prng, int wprng, unsigned char *pk,unsigned char *sk);
399 int tweetnacl_crypto_sk_to_pk(unsigned char *pk, const unsigned char *sk);
400 int tweetnacl_crypto_scalarmult(unsigned char *q, const unsigned char *n, const unsigned char *p);
401 int tweetnacl_crypto_scalarmult_base(unsigned char *q,const unsigned char *n);
402 int tweetnacl_crypto_ph(unsigned char *out, const unsigned char *msg, unsigned long long msglen);
403 
404 typedef int (*sk_to_pk)(unsigned char *pk ,const unsigned char *sk);
405 int ec25519_import_pkcs8(const unsigned char *in, unsigned long inlen,
406                        const void *pwd, unsigned long pwdlen,
407                        enum ltc_oid_id id, sk_to_pk fp,
408                        curve25519_key *key);
409 int ec25519_export(       unsigned char *out, unsigned long *outlen,
410                                     int  which,
411                    const curve25519_key *key);
412 int ec25519_crypto_ctx(      unsigned char *out, unsigned long *outlen,
413                              unsigned char flag,
414                        const unsigned char *ctx, unsigned long  ctxlen);
415 #endif /* LTC_CURVE25519 */
416 
417 #ifdef LTC_DER
418 
419 #define LTC_ASN1_IS_TYPE(e, t) (((e) != NULL) && ((e)->type == (t)))
420 
421 /* DER handling */
422 int der_decode_custom_type_ex(const unsigned char *in, unsigned long  inlen,
423                            ltc_asn1_list *root,
424                            ltc_asn1_list *list,     unsigned long  outlen, unsigned int flags);
425 
426 int der_encode_asn1_identifier(const ltc_asn1_list *id, unsigned char *out, unsigned long *outlen);
427 int der_decode_asn1_identifier(const unsigned char *in, unsigned long *inlen, ltc_asn1_list *id);
428 int der_length_asn1_identifier(const ltc_asn1_list *id, unsigned long *idlen);
429 
430 int der_encode_asn1_length(unsigned long len, unsigned char* out, unsigned long* outlen);
431 int der_decode_asn1_length(const unsigned char *in, unsigned long *inlen, unsigned long *outlen);
432 int der_length_asn1_length(unsigned long len, unsigned long *outlen);
433 
434 int der_length_sequence_ex(const ltc_asn1_list *list, unsigned long inlen,
435                            unsigned long *outlen, unsigned long *payloadlen);
436 
437 extern const ltc_asn1_type  der_asn1_tag_to_type_map[];
438 extern const unsigned long  der_asn1_tag_to_type_map_sz;
439 
440 extern const int der_asn1_type_to_identifier_map[];
441 extern const unsigned long der_asn1_type_to_identifier_map_sz;
442 
443 int der_decode_sequence_multi_ex(const unsigned char *in, unsigned long inlen, unsigned int flags, ...)
444                                  LTC_NULL_TERMINATED;
445 
446 int der_teletex_char_encode(int c);
447 int der_teletex_value_decode(int v);
448 
449 int der_utf8_valid_char(const wchar_t c);
450 
451 typedef int (*public_key_decode_cb)(const unsigned char *in, unsigned long inlen, void *ctx);
452 
453 int x509_decode_public_key_from_certificate(const unsigned char *in, unsigned long inlen,
454                                             enum ltc_oid_id algorithm, ltc_asn1_type param_type,
455                                             ltc_asn1_list* parameters, unsigned long *parameters_len,
456                                             public_key_decode_cb callback, void *ctx);
457 
458 /* SUBJECT PUBLIC KEY INFO */
459 int x509_encode_subject_public_key_info(unsigned char *out, unsigned long *outlen,
460         unsigned int algorithm, const void* public_key, unsigned long public_key_len,
461         ltc_asn1_type parameters_type, ltc_asn1_list* parameters, unsigned long parameters_len);
462 
463 int x509_decode_subject_public_key_info(const unsigned char *in, unsigned long inlen,
464         unsigned int algorithm, void* public_key, unsigned long* public_key_len,
465         ltc_asn1_type parameters_type, ltc_asn1_list* parameters, unsigned long *parameters_len);
466 
467 int pk_oid_cmp_with_ulong(const char *o1, const unsigned long *o2, unsigned long o2size);
468 int pk_oid_cmp_with_asn1(const char *o1, const ltc_asn1_list *o2);
469 
470 #endif /* LTC_DER */
471 
472 /* tomcrypt_pkcs.h */
473 
474 #ifdef LTC_PKCS_8
475 
476 int pkcs8_decode_flexi(const unsigned char  *in,  unsigned long inlen,
477                                     const void  *pwd, unsigned long pwdlen,
478                                  ltc_asn1_list **decoded_list);
479 
480 #endif  /* LTC_PKCS_8 */
481 
482 
483 #ifdef LTC_PKCS_12
484 
485 int pkcs12_utf8_to_utf16(const unsigned char *in,  unsigned long  inlen,
486                                unsigned char *out, unsigned long *outlen);
487 
488 int pkcs12_kdf(               int   hash_id,
489                const unsigned char *pw,         unsigned long pwlen,
490                const unsigned char *salt,       unsigned long saltlen,
491                      unsigned int   iterations, unsigned char purpose,
492                      unsigned char *out,        unsigned long outlen);
493 
494 #endif  /* LTC_PKCS_12 */
495 
496 /* tomcrypt_prng.h */
497 
498 #define LTC_PRNG_EXPORT(which) \
499 int which ## _export(unsigned char *out, unsigned long *outlen, prng_state *prng)      \
500 {                                                                                      \
501    unsigned long len = which ## _desc.export_size;                                     \
502                                                                                        \
503    LTC_ARGCHK(prng   != NULL);                                                         \
504    LTC_ARGCHK(out    != NULL);                                                         \
505    LTC_ARGCHK(outlen != NULL);                                                         \
506                                                                                        \
507    if (*outlen < len) {                                                                \
508       *outlen = len;                                                                   \
509       return CRYPT_BUFFER_OVERFLOW;                                                    \
510    }                                                                                   \
511                                                                                        \
512    if (which ## _read(out, len, prng) != len) {                                        \
513       return CRYPT_ERROR_READPRNG;                                                     \
514    }                                                                                   \
515                                                                                        \
516    *outlen = len;                                                                      \
517    return CRYPT_OK;                                                                    \
518 }
519 
520 /* extract a byte portably */
521 #ifdef _MSC_VER
522    #define LTC_BYTE(x, n) ((unsigned char)((x) >> (8 * (n))))
523 #else
524    #define LTC_BYTE(x, n) (((x) >> (8 * (n))) & 255)
525 #endif
526