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