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