LTC sync RSA new style
Karel Miko
6 years ago
61 | 61 | _import_hex(Crypt::PK::RSA self, char *N, char *e, char *d=NULL, char *p=NULL, char *q=NULL, char *dP=NULL, char *dQ=NULL, char *qP=NULL) |
62 | 62 | PPCODE: |
63 | 63 | { |
64 | int rv; | |
65 | if (self->key.type != -1) { rsa_free(&self->key); self->key.type = -1; } | |
66 | rv = rsa_import_radix(16, N, e, d, p, q, dP, dQ, qP, &self->key); | |
67 | if (rv != CRYPT_OK) croak("FATAL: rsa_import_radix failed: %s", error_to_string(rv)); | |
64 | int i, rv; | |
65 | unsigned char Nbin[1024], ebin[128], dbin[1024], pbin[512], qbin[512], dPbin[512], dQbin[512], qPbin[512]; | |
66 | unsigned long Nlen=sizeof(Nbin), elen=sizeof(ebin), dlen=sizeof(dbin), plen=sizeof(pbin), | |
67 | qlen=sizeof(qbin), dPlen=sizeof(dPbin), dQlen=sizeof(dQbin), qPlen=sizeof(qPbin); | |
68 | ||
69 | rv = radix_to_bin(N, 16, Nbin, &Nlen); | |
70 | if (rv != CRYPT_OK) croak("FATAL: radix_to_bin(N) failed: %s", error_to_string(rv)); | |
71 | rv = radix_to_bin(e, 16, ebin, &elen); | |
72 | if (rv != CRYPT_OK) croak("FATAL: radix_to_bin(e) failed: %s", error_to_string(rv)); | |
73 | ||
74 | if (d && strlen(d) > 0) { | |
75 | /* private */ | |
76 | rv = radix_to_bin(d, 16, dbin, &dlen); | |
77 | if (rv != CRYPT_OK) croak("FATAL: radix_to_bin(d) failed: %s", error_to_string(rv)); | |
78 | rv = rsa_set_key(Nbin, Nlen, ebin, elen, dbin, dlen, &self->key); | |
79 | if (rv != CRYPT_OK) croak("FATAL: rsa_set_key failed: %s", error_to_string(rv)); | |
80 | } | |
81 | else { | |
82 | /* public */ | |
83 | rv = rsa_set_key(Nbin, Nlen, ebin, elen, NULL, 0, &self->key); | |
84 | if (rv != CRYPT_OK) croak("FATAL: rsa_set_key failed: %s", error_to_string(rv)); | |
85 | } | |
86 | ||
87 | if (p && strlen(p) > 0 && q && strlen(q) > 0) { | |
88 | /* private only */ | |
89 | rv = radix_to_bin(p, 16, pbin, &plen); | |
90 | if (rv != CRYPT_OK) croak("FATAL: radix_to_bin(p) failed: %s", error_to_string(rv)); | |
91 | rv = radix_to_bin(q, 16, qbin, &qlen); | |
92 | if (rv != CRYPT_OK) croak("FATAL: radix_to_bin(q) failed: %s", error_to_string(rv)); | |
93 | rv = rsa_set_factors(pbin, plen, qbin, qlen, &self->key); | |
94 | if (rv != CRYPT_OK) croak("FATAL: rsa_set_factors failed: %s", error_to_string(rv)); | |
95 | } | |
96 | ||
97 | if (dP && strlen(dP) > 0 && dQ && strlen(dQ) > 0 && qP && strlen(qP) > 0) { | |
98 | /* private only */ | |
99 | rv = radix_to_bin(dP, 16, dPbin, &dPlen); | |
100 | if (rv != CRYPT_OK) croak("FATAL: radix_to_bin(dP) failed: %s", error_to_string(rv)); | |
101 | rv = radix_to_bin(dQ, 16, dQbin, &dQlen); | |
102 | if (rv != CRYPT_OK) croak("FATAL: radix_to_bin(dQ) failed: %s", error_to_string(rv)); | |
103 | rv = radix_to_bin(qP, 16, qPbin, &qPlen); | |
104 | if (rv != CRYPT_OK) croak("FATAL: radix_to_bin(qP) failed: %s", error_to_string(rv)); | |
105 | rv = rsa_set_crt_params(dPbin, dPlen, dQbin, dQlen, qPbin, qPlen, &self->key); | |
106 | if (rv != CRYPT_OK) croak("FATAL: rsa_set_crt_params failed: %s", error_to_string(rv)); | |
107 | } | |
108 | ||
68 | 109 | XPUSHs(ST(0)); /* return self */ |
69 | 110 | } |
70 | 111 |
38 | 38 | ltc/mac/poly1305/poly1305.o ltc/mac/poly1305/poly1305_file.o ltc/mac/poly1305/poly1305_memory.o \ |
39 | 39 | ltc/mac/poly1305/poly1305_memory_multi.o ltc/mac/xcbc/xcbc_done.o ltc/mac/xcbc/xcbc_file.o \ |
40 | 40 | ltc/mac/xcbc/xcbc_init.o ltc/mac/xcbc/xcbc_memory.o ltc/mac/xcbc/xcbc_memory_multi.o \ |
41 | ltc/mac/xcbc/xcbc_process.o ltc/math/ltm_desc.o ltc/math/multi.o ltc/math/rand_bn.o \ | |
42 | ltc/math/rand_prime.o ltc/math/tfm_desc.o ltc/math/fp/ltc_ecc_fp_mulmod.o ltc/misc/adler32.o \ | |
43 | ltc/misc/burn_stack.o ltc/misc/compare_testvector.o ltc/misc/crc32.o ltc/misc/error_to_string.o \ | |
44 | ltc/misc/mem_neq.o ltc/misc/pk_get_oid.o ltc/misc/zeromem.o ltc/misc/base64/base64_decode.o \ | |
45 | ltc/misc/base64/base64_encode.o ltc/misc/crypt/crypt.o ltc/misc/crypt/crypt_argchk.o \ | |
46 | ltc/misc/crypt/crypt_cipher_descriptor.o ltc/misc/crypt/crypt_cipher_is_valid.o ltc/misc/crypt/crypt_find_cipher.o \ | |
47 | ltc/misc/crypt/crypt_find_cipher_any.o ltc/misc/crypt/crypt_find_cipher_id.o ltc/misc/crypt/crypt_find_hash.o \ | |
48 | ltc/misc/crypt/crypt_find_hash_any.o ltc/misc/crypt/crypt_find_hash_id.o ltc/misc/crypt/crypt_find_hash_oid.o \ | |
49 | ltc/misc/crypt/crypt_find_prng.o ltc/misc/crypt/crypt_fsa.o ltc/misc/crypt/crypt_hash_descriptor.o \ | |
50 | ltc/misc/crypt/crypt_hash_is_valid.o ltc/misc/crypt/crypt_inits.o ltc/misc/crypt/crypt_ltc_mp_descriptor.o \ | |
51 | ltc/misc/crypt/crypt_prng_descriptor.o ltc/misc/crypt/crypt_prng_is_valid.o ltc/misc/crypt/crypt_register_cipher.o \ | |
52 | ltc/misc/crypt/crypt_register_hash.o ltc/misc/crypt/crypt_register_prng.o ltc/misc/crypt/crypt_unregister_cipher.o \ | |
53 | ltc/misc/crypt/crypt_unregister_hash.o ltc/misc/crypt/crypt_unregister_prng.o ltc/misc/hkdf/hkdf.o \ | |
54 | ltc/misc/pkcs5/pkcs_5_1.o ltc/misc/pkcs5/pkcs_5_2.o ltc/modes/cbc/cbc_decrypt.o ltc/modes/cbc/cbc_done.o \ | |
55 | ltc/modes/cbc/cbc_encrypt.o ltc/modes/cbc/cbc_getiv.o ltc/modes/cbc/cbc_setiv.o ltc/modes/cbc/cbc_start.o \ | |
56 | ltc/modes/cfb/cfb_decrypt.o ltc/modes/cfb/cfb_done.o ltc/modes/cfb/cfb_encrypt.o \ | |
41 | ltc/mac/xcbc/xcbc_process.o ltc/math/ltm_desc.o ltc/math/multi.o ltc/math/radix_to_bin.o \ | |
42 | ltc/math/rand_bn.o ltc/math/rand_prime.o ltc/math/tfm_desc.o ltc/math/fp/ltc_ecc_fp_mulmod.o \ | |
43 | ltc/misc/adler32.o ltc/misc/burn_stack.o ltc/misc/compare_testvector.o ltc/misc/crc32.o \ | |
44 | ltc/misc/error_to_string.o ltc/misc/mem_neq.o ltc/misc/pk_get_oid.o ltc/misc/zeromem.o \ | |
45 | ltc/misc/base64/base64_decode.o ltc/misc/base64/base64_encode.o ltc/misc/crypt/crypt.o \ | |
46 | ltc/misc/crypt/crypt_argchk.o ltc/misc/crypt/crypt_cipher_descriptor.o ltc/misc/crypt/crypt_cipher_is_valid.o \ | |
47 | ltc/misc/crypt/crypt_find_cipher.o ltc/misc/crypt/crypt_find_cipher_any.o ltc/misc/crypt/crypt_find_cipher_id.o \ | |
48 | ltc/misc/crypt/crypt_find_hash.o ltc/misc/crypt/crypt_find_hash_any.o ltc/misc/crypt/crypt_find_hash_id.o \ | |
49 | ltc/misc/crypt/crypt_find_hash_oid.o ltc/misc/crypt/crypt_find_prng.o ltc/misc/crypt/crypt_fsa.o \ | |
50 | ltc/misc/crypt/crypt_hash_descriptor.o ltc/misc/crypt/crypt_hash_is_valid.o ltc/misc/crypt/crypt_inits.o \ | |
51 | ltc/misc/crypt/crypt_ltc_mp_descriptor.o ltc/misc/crypt/crypt_prng_descriptor.o ltc/misc/crypt/crypt_prng_is_valid.o \ | |
52 | ltc/misc/crypt/crypt_register_cipher.o ltc/misc/crypt/crypt_register_hash.o ltc/misc/crypt/crypt_register_prng.o \ | |
53 | ltc/misc/crypt/crypt_unregister_cipher.o ltc/misc/crypt/crypt_unregister_hash.o ltc/misc/crypt/crypt_unregister_prng.o \ | |
54 | ltc/misc/hkdf/hkdf.o ltc/misc/pkcs5/pkcs_5_1.o ltc/misc/pkcs5/pkcs_5_2.o ltc/modes/cbc/cbc_decrypt.o \ | |
55 | ltc/modes/cbc/cbc_done.o ltc/modes/cbc/cbc_encrypt.o ltc/modes/cbc/cbc_getiv.o ltc/modes/cbc/cbc_setiv.o \ | |
56 | ltc/modes/cbc/cbc_start.o ltc/modes/cfb/cfb_decrypt.o ltc/modes/cfb/cfb_done.o ltc/modes/cfb/cfb_encrypt.o \ | |
57 | 57 | ltc/modes/cfb/cfb_getiv.o ltc/modes/cfb/cfb_setiv.o ltc/modes/cfb/cfb_start.o ltc/modes/ctr/ctr_decrypt.o \ |
58 | 58 | ltc/modes/ctr/ctr_done.o ltc/modes/ctr/ctr_encrypt.o ltc/modes/ctr/ctr_getiv.o ltc/modes/ctr/ctr_setiv.o \ |
59 | 59 | ltc/modes/ctr/ctr_start.o ltc/modes/ecb/ecb_decrypt.o ltc/modes/ecb/ecb_done.o ltc/modes/ecb/ecb_encrypt.o \ |
104 | 104 | ltc/pk/pkcs1/pkcs_1_pss_encode.o ltc/pk/pkcs1/pkcs_1_v1_5_decode.o ltc/pk/pkcs1/pkcs_1_v1_5_encode.o \ |
105 | 105 | ltc/pk/rsa/rsa_decrypt_key.o ltc/pk/rsa/rsa_encrypt_key.o ltc/pk/rsa/rsa_export.o \ |
106 | 106 | ltc/pk/rsa/rsa_exptmod.o ltc/pk/rsa/rsa_free.o ltc/pk/rsa/rsa_get_size.o ltc/pk/rsa/rsa_import.o \ |
107 | ltc/pk/rsa/rsa_import_pkcs8.o ltc/pk/rsa/rsa_import_radix.o ltc/pk/rsa/rsa_import_x509.o \ | |
108 | ltc/pk/rsa/rsa_make_key.o ltc/pk/rsa/rsa_sign_hash.o ltc/pk/rsa/rsa_sign_saltlen_get.o \ | |
107 | ltc/pk/rsa/rsa_import_pkcs8.o ltc/pk/rsa/rsa_import_x509.o ltc/pk/rsa/rsa_make_key.o \ | |
108 | ltc/pk/rsa/rsa_set.o ltc/pk/rsa/rsa_sign_hash.o ltc/pk/rsa/rsa_sign_saltlen_get.o \ | |
109 | 109 | ltc/pk/rsa/rsa_verify_hash.o ltc/prngs/chacha20.o ltc/prngs/fortuna.o ltc/prngs/rc4.o \ |
110 | 110 | ltc/prngs/rng_get_bytes.o ltc/prngs/rng_make_prng.o ltc/prngs/sober128.o ltc/prngs/sprng.o \ |
111 | 111 | ltc/prngs/yarrow.o ltc/stream/chacha/chacha_crypt.o ltc/stream/chacha/chacha_done.o \ |
41 | 41 | ltc/mac/poly1305/poly1305.obj ltc/mac/poly1305/poly1305_file.obj ltc/mac/poly1305/poly1305_memory.obj \ |
42 | 42 | ltc/mac/poly1305/poly1305_memory_multi.obj ltc/mac/xcbc/xcbc_done.obj ltc/mac/xcbc/xcbc_file.obj \ |
43 | 43 | ltc/mac/xcbc/xcbc_init.obj ltc/mac/xcbc/xcbc_memory.obj ltc/mac/xcbc/xcbc_memory_multi.obj \ |
44 | ltc/mac/xcbc/xcbc_process.obj ltc/math/ltm_desc.obj ltc/math/multi.obj ltc/math/rand_bn.obj \ | |
45 | ltc/math/rand_prime.obj ltc/math/tfm_desc.obj ltc/math/fp/ltc_ecc_fp_mulmod.obj ltc/misc/adler32.obj \ | |
46 | ltc/misc/burn_stack.obj ltc/misc/compare_testvector.obj ltc/misc/crc32.obj ltc/misc/error_to_string.obj \ | |
47 | ltc/misc/mem_neq.obj ltc/misc/pk_get_oid.obj ltc/misc/zeromem.obj ltc/misc/base64/base64_decode.obj \ | |
48 | ltc/misc/base64/base64_encode.obj ltc/misc/crypt/crypt.obj ltc/misc/crypt/crypt_argchk.obj \ | |
49 | ltc/misc/crypt/crypt_cipher_descriptor.obj ltc/misc/crypt/crypt_cipher_is_valid.obj \ | |
44 | ltc/mac/xcbc/xcbc_process.obj ltc/math/ltm_desc.obj ltc/math/multi.obj ltc/math/radix_to_bin.obj \ | |
45 | ltc/math/rand_bn.obj ltc/math/rand_prime.obj ltc/math/tfm_desc.obj ltc/math/fp/ltc_ecc_fp_mulmod.obj \ | |
46 | ltc/misc/adler32.obj ltc/misc/burn_stack.obj ltc/misc/compare_testvector.obj ltc/misc/crc32.obj \ | |
47 | ltc/misc/error_to_string.obj ltc/misc/mem_neq.obj ltc/misc/pk_get_oid.obj ltc/misc/zeromem.obj \ | |
48 | ltc/misc/base64/base64_decode.obj ltc/misc/base64/base64_encode.obj ltc/misc/crypt/crypt.obj \ | |
49 | ltc/misc/crypt/crypt_argchk.obj ltc/misc/crypt/crypt_cipher_descriptor.obj ltc/misc/crypt/crypt_cipher_is_valid.obj \ | |
50 | 50 | ltc/misc/crypt/crypt_find_cipher.obj ltc/misc/crypt/crypt_find_cipher_any.obj ltc/misc/crypt/crypt_find_cipher_id.obj \ |
51 | 51 | ltc/misc/crypt/crypt_find_hash.obj ltc/misc/crypt/crypt_find_hash_any.obj ltc/misc/crypt/crypt_find_hash_id.obj \ |
52 | 52 | ltc/misc/crypt/crypt_find_hash_oid.obj ltc/misc/crypt/crypt_find_prng.obj ltc/misc/crypt/crypt_fsa.obj \ |
111 | 111 | ltc/pk/pkcs1/pkcs_1_pss_encode.obj ltc/pk/pkcs1/pkcs_1_v1_5_decode.obj ltc/pk/pkcs1/pkcs_1_v1_5_encode.obj \ |
112 | 112 | ltc/pk/rsa/rsa_decrypt_key.obj ltc/pk/rsa/rsa_encrypt_key.obj ltc/pk/rsa/rsa_export.obj \ |
113 | 113 | ltc/pk/rsa/rsa_exptmod.obj ltc/pk/rsa/rsa_free.obj ltc/pk/rsa/rsa_get_size.obj ltc/pk/rsa/rsa_import.obj \ |
114 | ltc/pk/rsa/rsa_import_pkcs8.obj ltc/pk/rsa/rsa_import_radix.obj ltc/pk/rsa/rsa_import_x509.obj \ | |
115 | ltc/pk/rsa/rsa_make_key.obj ltc/pk/rsa/rsa_sign_hash.obj ltc/pk/rsa/rsa_sign_saltlen_get.obj \ | |
114 | ltc/pk/rsa/rsa_import_pkcs8.obj ltc/pk/rsa/rsa_import_x509.obj ltc/pk/rsa/rsa_make_key.obj \ | |
115 | ltc/pk/rsa/rsa_set.obj ltc/pk/rsa/rsa_sign_hash.obj ltc/pk/rsa/rsa_sign_saltlen_get.obj \ | |
116 | 116 | ltc/pk/rsa/rsa_verify_hash.obj ltc/prngs/chacha20.obj ltc/prngs/fortuna.obj ltc/prngs/rc4.obj \ |
117 | 117 | ltc/prngs/rng_get_bytes.obj ltc/prngs/rng_make_prng.obj ltc/prngs/sober128.obj ltc/prngs/sprng.obj \ |
118 | 118 | ltc/prngs/yarrow.obj ltc/stream/chacha/chacha_crypt.obj ltc/stream/chacha/chacha_done.obj \ |
126 | 126 | int rsa_import_x509(const unsigned char *in, unsigned long inlen, rsa_key *key); |
127 | 127 | int rsa_import_pkcs8(const unsigned char *in, unsigned long inlen, |
128 | 128 | const void *passwd, unsigned long passwdlen, rsa_key *key); |
129 | int rsa_import_radix(int radix, char *N, char *e, char *d, char *p, char *q, char *dP, char *dQ, char *qP, rsa_key *key); | |
129 | ||
130 | int rsa_set_key(const unsigned char *N, unsigned long Nlen, | |
131 | const unsigned char *e, unsigned long elen, | |
132 | const unsigned char *d, unsigned long dlen, | |
133 | rsa_key *key); | |
134 | int rsa_set_factors(const unsigned char *p, unsigned long plen, | |
135 | const unsigned char *q, unsigned long qlen, | |
136 | rsa_key *key); | |
137 | int rsa_set_crt_params(const unsigned char *dP, unsigned long dPlen, | |
138 | const unsigned char *dQ, unsigned long dQlen, | |
139 | const unsigned char *qP, unsigned long qPlen, | |
140 | rsa_key *key); | |
130 | 141 | #endif |
131 | 142 | |
132 | 143 | /* ---- Katja ---- */ |
0 | /* LibTomCrypt, modular cryptographic library -- Tom St Denis | |
1 | * | |
2 | * LibTomCrypt is a library that provides various cryptographic | |
3 | * algorithms in a highly modular and flexible manner. | |
4 | * | |
5 | * The library is free for all purposes without any express | |
6 | * guarantee it works. | |
7 | */ | |
8 | #include "tomcrypt.h" | |
9 | ||
10 | /** | |
11 | @file radix_to_bin.c | |
12 | Convert data from a specific radix to binary. | |
13 | Steffen Jaeckel | |
14 | */ | |
15 | ||
16 | /** | |
17 | Convert data from a specific radix to binary | |
18 | ||
19 | The default MPI descriptors #ltm_desc, #tfm_desc and #gmp_desc | |
20 | have the following restrictions on parameters: | |
21 | ||
22 | \p in - NUL-terminated char buffer | |
23 | ||
24 | \p radix - 2..64 | |
25 | ||
26 | @param in The input | |
27 | @param radix The radix of the input | |
28 | @param out The output buffer | |
29 | @param len [in/out] The length of the output buffer | |
30 | ||
31 | @return CRYPT_OK on success. | |
32 | */ | |
33 | int radix_to_bin(const void *in, int radix, void *out, size_t* len) | |
34 | { | |
35 | size_t l; | |
36 | void* mpi; | |
37 | int err; | |
38 | ||
39 | LTC_ARGCHK(in != NULL); | |
40 | LTC_ARGCHK(len != NULL); | |
41 | ||
42 | if ((err = mp_init(&mpi)) != CRYPT_OK) return err; | |
43 | if ((err = mp_read_radix(mpi, in, radix)) != CRYPT_OK) goto LBL_ERR; | |
44 | ||
45 | if ((l = mp_unsigned_bin_size(mpi)) > *len) { | |
46 | *len = l; | |
47 | err = CRYPT_BUFFER_OVERFLOW; | |
48 | goto LBL_ERR; | |
49 | } | |
50 | *len = l; | |
51 | ||
52 | if ((err = mp_to_unsigned_bin(mpi, out)) != CRYPT_OK) goto LBL_ERR; | |
53 | ||
54 | LBL_ERR: | |
55 | mp_clear(mpi); | |
56 | return err; | |
57 | } | |
58 | ||
59 | /* ref: $Format:%D$ */ | |
60 | /* git commit: $Format:%H$ */ | |
61 | /* commit time: $Format:%ai$ */ |
4 | 4 | * |
5 | 5 | * The library is free for all purposes without any express |
6 | 6 | * guarantee it works. |
7 | * | |
8 | * Tom St Denis, tomstdenis@gmail.com, http://libtom.org | |
9 | * | |
10 | * Added RSA blinding --nmav | |
11 | 7 | */ |
12 | 8 | #include "tomcrypt.h" |
13 | 9 | |
14 | 10 | /** |
15 | 11 | @file rsa_exptmod.c |
16 | 12 | RSA PKCS exptmod, Tom St Denis |
13 | Added RSA blinding --nmav | |
17 | 14 | */ |
18 | 15 | |
19 | 16 | #ifdef LTC_MRSA |
99 | 96 | } |
100 | 97 | #endif /* LTC_RSA_BLINDING */ |
101 | 98 | |
102 | has_crt_parameters = (key->dP != NULL) && (mp_get_digit_count(key->dP) != 0) && | |
103 | (key->dQ != NULL) && (mp_get_digit_count(key->dQ) != 0) && | |
104 | (key->qP != NULL) && (mp_get_digit_count(key->qP) != 0); | |
99 | has_crt_parameters = (key->p != NULL) && (mp_get_digit_count(key->p) != 0) && | |
100 | (key->q != NULL) && (mp_get_digit_count(key->q) != 0) && | |
101 | (key->dP != NULL) && (mp_get_digit_count(key->dP) != 0) && | |
102 | (key->dQ != NULL) && (mp_get_digit_count(key->dQ) != 0) && | |
103 | (key->qP != NULL) && (mp_get_digit_count(key->qP) != 0); | |
105 | 104 | |
106 | 105 | if (!has_crt_parameters) { |
107 | 106 | /* |
21 | 21 | void rsa_free(rsa_key *key) |
22 | 22 | { |
23 | 23 | LTC_ARGCHKVD(key != NULL); |
24 | mp_clear_multi(key->q, key->p, key->qP, key->dP, key->dQ, key->N, key->d, key->e, NULL); | |
24 | mp_cleanup_multi(&key->q, &key->p, &key->qP, &key->dP, &key->dQ, &key->N, &key->d, &key->e, NULL); | |
25 | 25 | } |
26 | 26 | |
27 | 27 | #endif |
4 | 4 | * |
5 | 5 | * The library is free for all purposes without any express |
6 | 6 | * guarantee it works. |
7 | * | |
8 | * http://libtom.org | |
9 | 7 | */ |
10 | 8 | #include "tomcrypt.h" |
11 | 9 |
72 | 72 | /* alloc buffers */ |
73 | 73 | buf1len = inlen; /* approx. */ |
74 | 74 | buf1 = XMALLOC(buf1len); |
75 | if (buf1 == NULL) { err = CRYPT_MEM; goto LBL_NOCLEAR; } | |
75 | if (buf1 == NULL) { err = CRYPT_MEM; goto LBL_NOFREE; } | |
76 | 76 | buf2len = inlen; /* approx. */ |
77 | 77 | buf2 = XMALLOC(buf2len); |
78 | if (buf2 == NULL) { err = CRYPT_MEM; goto LBL_FREE; } | |
78 | if (buf2 == NULL) { err = CRYPT_MEM; goto LBL_FREE1; } | |
79 | 79 | |
80 | 80 | /* init key */ |
81 | 81 | err = mp_init_multi(&key->e, &key->d, &key->N, &key->dQ, &key->dP, &key->qP, &key->p, &key->q, &zero, &iter, NULL); |
82 | if (err != CRYPT_OK) { goto LBL_NOCLEAR; } | |
82 | if (err != CRYPT_OK) { goto LBL_FREE2; } | |
83 | 83 | |
84 | 84 | /* try to decode encrypted priv key */ |
85 | 85 | LTC_SET_ASN1(key_seq_e, 0, LTC_ASN1_OCTET_STRING, buf1, buf1len); |
133 | 133 | mp_clear_multi(zero, iter, NULL); |
134 | 134 | key->type = PK_PRIVATE; |
135 | 135 | err = CRYPT_OK; |
136 | goto LBL_FREE; | |
136 | goto LBL_FREE2; | |
137 | 137 | |
138 | 138 | LBL_ERR: |
139 | 139 | mp_clear_multi(key->d, key->e, key->N, key->dQ, key->dP, key->qP, key->p, key->q, zero, iter, NULL); |
140 | LBL_NOCLEAR: | |
140 | LBL_FREE2: | |
141 | 141 | XFREE(buf2); |
142 | LBL_FREE: | |
142 | LBL_FREE1: | |
143 | 143 | XFREE(buf1); |
144 | 144 | LBL_NOFREE: |
145 | 145 | return err; |
146 | 146 | } |
147 | 147 | |
148 | 148 | #endif /* LTC_MRSA */ |
149 | ||
150 | /* ref: $Format:%D$ */ | |
151 | /* git commit: $Format:%H$ */ | |
152 | /* commit time: $Format:%ai$ */ |
0 | /* LibTomCrypt, modular cryptographic library -- Tom St Denis | |
1 | * | |
2 | * LibTomCrypt is a library that provides various cryptographic | |
3 | * algorithms in a highly modular and flexible manner. | |
4 | * | |
5 | * The library is free for all purposes without any express | |
6 | * guarantee it works. | |
7 | */ | |
8 | #include "tomcrypt.h" | |
9 | ||
10 | /** | |
11 | Import RSA public or private key from raw numbers | |
12 | @param radix the radix the numbers are represented in (2-64, 16 = hexadecimal) | |
13 | @param N RSA's N in radix representation | |
14 | @param e RSA's e in radix representation | |
15 | @param d RSA's d in radix representation (only private key, NULL for public key) | |
16 | @param p RSA's p in radix representation (only private key, NULL for public key) | |
17 | @param q RSA's q in radix representation (only private key, NULL for public key) | |
18 | @param dP RSA's dP in radix representation (only private key, NULL for public key) | |
19 | @param dQ RSA's dQ in radix representation (only private key, NULL for public key) | |
20 | @param qP RSA's qP in radix representation (only private key, NULL for public key) | |
21 | @param key [out] the destination for the imported key | |
22 | @return CRYPT_OK if successful, upon error allocated memory is freed | |
23 | */ | |
24 | ||
25 | #ifdef LTC_MRSA | |
26 | ||
27 | int rsa_import_radix(int radix, char *N, char *e, char *d, char *p, char *q, char *dP, char *dQ, char *qP, rsa_key *key) | |
28 | { | |
29 | int err; | |
30 | ||
31 | LTC_ARGCHK(key != NULL); | |
32 | LTC_ARGCHK(N != NULL); | |
33 | LTC_ARGCHK(e != NULL); | |
34 | LTC_ARGCHK(ltc_mp.name != NULL); | |
35 | ||
36 | err = mp_init_multi(&key->e, &key->d, &key->N, &key->dQ, &key->dP, &key->qP, &key->p, &key->q, NULL); | |
37 | if (err != CRYPT_OK) return err; | |
38 | ||
39 | if ((err = mp_read_radix(key->N , N , radix)) != CRYPT_OK) { goto LBL_ERR; } | |
40 | if ((err = mp_read_radix(key->e , e , radix)) != CRYPT_OK) { goto LBL_ERR; } | |
41 | if (d && p && q && dP && dQ && qP && strlen(d)>0 && strlen(p)>0 && | |
42 | strlen(q)>0 && strlen(dP)>0 && strlen(dQ)>0 && strlen(qP)>0) { | |
43 | if ((err = mp_read_radix(key->d , d , radix)) != CRYPT_OK) { goto LBL_ERR; } | |
44 | if ((err = mp_read_radix(key->p , p , radix)) != CRYPT_OK) { goto LBL_ERR; } | |
45 | if ((err = mp_read_radix(key->q , q , radix)) != CRYPT_OK) { goto LBL_ERR; } | |
46 | if ((err = mp_read_radix(key->dP, dP, radix)) != CRYPT_OK) { goto LBL_ERR; } | |
47 | if ((err = mp_read_radix(key->dQ, dQ, radix)) != CRYPT_OK) { goto LBL_ERR; } | |
48 | if ((err = mp_read_radix(key->qP, qP, radix)) != CRYPT_OK) { goto LBL_ERR; } | |
49 | key->type = PK_PRIVATE; | |
50 | } | |
51 | else { | |
52 | key->type = PK_PUBLIC; | |
53 | } | |
54 | return CRYPT_OK; | |
55 | ||
56 | LBL_ERR: | |
57 | mp_clear_multi(key->d, key->e, key->N, key->dQ, key->dP, key->qP, key->p, key->q, NULL); | |
58 | return err; | |
59 | } | |
60 | ||
61 | #endif /* LTC_MRSA */ |
0 | /* LibTomCrypt, modular cryptographic library -- Tom St Denis | |
1 | * | |
2 | * LibTomCrypt is a library that provides various cryptographic | |
3 | * algorithms in a highly modular and flexible manner. | |
4 | * | |
5 | * The library is free for all purposes without any express | |
6 | * guarantee it works. | |
7 | */ | |
8 | #include "tomcrypt.h" | |
9 | ||
10 | ||
11 | #ifdef LTC_MRSA | |
12 | ||
13 | /** | |
14 | Import RSA key from raw numbers | |
15 | ||
16 | @param N RSA's N | |
17 | @param Nlen RSA's N's length | |
18 | @param e RSA's e | |
19 | @param elen RSA's e's length | |
20 | @param d RSA's d (only private key, NULL for public key) | |
21 | @param dlen RSA's d's length | |
22 | @param key [out] the destination for the imported key | |
23 | @return CRYPT_OK if successful | |
24 | */ | |
25 | int rsa_set_key(const unsigned char *N, unsigned long Nlen, | |
26 | const unsigned char *e, unsigned long elen, | |
27 | const unsigned char *d, unsigned long dlen, | |
28 | rsa_key *key) | |
29 | { | |
30 | int err; | |
31 | ||
32 | LTC_ARGCHK(key != NULL); | |
33 | LTC_ARGCHK(N != NULL); | |
34 | LTC_ARGCHK(e != NULL); | |
35 | LTC_ARGCHK(ltc_mp.name != NULL); | |
36 | ||
37 | err = mp_init_multi(&key->e, &key->d, &key->N, &key->dQ, &key->dP, &key->qP, &key->p, &key->q, NULL); | |
38 | if (err != CRYPT_OK) return err; | |
39 | ||
40 | if ((err = mp_read_unsigned_bin(key->N , (unsigned char *)N , Nlen)) != CRYPT_OK) { goto LBL_ERR; } | |
41 | if ((err = mp_read_unsigned_bin(key->e , (unsigned char *)e , elen)) != CRYPT_OK) { goto LBL_ERR; } | |
42 | if (d && dlen) { | |
43 | if ((err = mp_read_unsigned_bin(key->d , (unsigned char *)d , dlen)) != CRYPT_OK) { goto LBL_ERR; } | |
44 | key->type = PK_PRIVATE; | |
45 | } | |
46 | else { | |
47 | key->type = PK_PUBLIC; | |
48 | } | |
49 | return CRYPT_OK; | |
50 | ||
51 | LBL_ERR: | |
52 | rsa_free(key); | |
53 | return err; | |
54 | } | |
55 | ||
56 | /** | |
57 | Import factors of an RSA key from raw numbers | |
58 | ||
59 | Only for private keys. | |
60 | ||
61 | @param p RSA's p | |
62 | @param plen RSA's p's length | |
63 | @param q RSA's q | |
64 | @param qlen RSA's q's length | |
65 | @param key [out] the destination for the imported key | |
66 | @return CRYPT_OK if successful | |
67 | */ | |
68 | int rsa_set_factors(const unsigned char *p, unsigned long plen, | |
69 | const unsigned char *q, unsigned long qlen, | |
70 | rsa_key *key) | |
71 | { | |
72 | int err; | |
73 | ||
74 | LTC_ARGCHK(key != NULL); | |
75 | LTC_ARGCHK(p != NULL); | |
76 | LTC_ARGCHK(q != NULL); | |
77 | LTC_ARGCHK(ltc_mp.name != NULL); | |
78 | ||
79 | if (key->type != PK_PRIVATE) return CRYPT_PK_TYPE_MISMATCH; | |
80 | ||
81 | if ((err = mp_read_unsigned_bin(key->p , (unsigned char *)p , plen)) != CRYPT_OK) { goto LBL_ERR; } | |
82 | if ((err = mp_read_unsigned_bin(key->q , (unsigned char *)q , qlen)) != CRYPT_OK) { goto LBL_ERR; } | |
83 | return CRYPT_OK; | |
84 | ||
85 | LBL_ERR: | |
86 | rsa_free(key); | |
87 | return err; | |
88 | } | |
89 | ||
90 | /** | |
91 | Import CRT parameters of an RSA key from raw numbers | |
92 | ||
93 | Only for private keys. | |
94 | ||
95 | @param dP RSA's dP | |
96 | @param dPlen RSA's dP's length | |
97 | @param dQ RSA's dQ | |
98 | @param dQlen RSA's dQ's length | |
99 | @param qP RSA's qP | |
100 | @param qPlen RSA's qP's length | |
101 | @param key [out] the destination for the imported key | |
102 | @return CRYPT_OK if successful | |
103 | */ | |
104 | int rsa_set_crt_params(const unsigned char *dP, unsigned long dPlen, | |
105 | const unsigned char *dQ, unsigned long dQlen, | |
106 | const unsigned char *qP, unsigned long qPlen, | |
107 | rsa_key *key) | |
108 | { | |
109 | int err; | |
110 | ||
111 | LTC_ARGCHK(key != NULL); | |
112 | LTC_ARGCHK(dP != NULL); | |
113 | LTC_ARGCHK(dQ != NULL); | |
114 | LTC_ARGCHK(qP != NULL); | |
115 | LTC_ARGCHK(ltc_mp.name != NULL); | |
116 | ||
117 | if (key->type != PK_PRIVATE) return CRYPT_PK_TYPE_MISMATCH; | |
118 | ||
119 | if ((err = mp_read_unsigned_bin(key->dP, (unsigned char *)dP, dPlen)) != CRYPT_OK) { goto LBL_ERR; } | |
120 | if ((err = mp_read_unsigned_bin(key->dQ, (unsigned char *)dQ, dQlen)) != CRYPT_OK) { goto LBL_ERR; } | |
121 | if ((err = mp_read_unsigned_bin(key->qP, (unsigned char *)qP, qPlen)) != CRYPT_OK) { goto LBL_ERR; } | |
122 | return CRYPT_OK; | |
123 | ||
124 | LBL_ERR: | |
125 | rsa_free(key); | |
126 | return err; | |
127 | } | |
128 | ||
129 | #endif /* LTC_MRSA */ | |
130 | ||
131 | /* ref: $Format:%D$ */ | |
132 | /* git commit: $Format:%H$ */ | |
133 | /* commit time: $Format:%ai$ */ |
20 | 20 | @param inlen The length of the hash to sign (octets) |
21 | 21 | @param out [out] The signature |
22 | 22 | @param outlen [in/out] The max size and resulting size of the signature |
23 | @param padding Type of padding (LTC_PKCS_1_PSS or LTC_PKCS_1_V1_5) | |
23 | @param padding Type of padding (LTC_PKCS_1_PSS, LTC_PKCS_1_V1_5 or LTC_PKCS_1_V1_5_NA1) | |
24 | 24 | @param prng An active PRNG state |
25 | 25 | @param prng_idx The index of the PRNG desired |
26 | 26 | @param hash_idx The index of the hash desired |
44 | 44 | LTC_ARGCHK(key != NULL); |
45 | 45 | |
46 | 46 | /* valid padding? */ |
47 | if ((padding != LTC_PKCS_1_V1_5) && (padding != LTC_PKCS_1_PSS)) { | |
47 | if ((padding != LTC_PKCS_1_V1_5) && | |
48 | (padding != LTC_PKCS_1_PSS) && | |
49 | (padding != LTC_PKCS_1_V1_5_NA1)) { | |
48 | 50 | return CRYPT_PK_INVALID_PADDING; |
49 | 51 | } |
50 | 52 | |
51 | 53 | if (padding == LTC_PKCS_1_PSS) { |
52 | /* valid prng and hash ? */ | |
54 | /* valid prng ? */ | |
53 | 55 | if ((err = prng_is_valid(prng_idx)) != CRYPT_OK) { |
54 | 56 | return err; |
55 | 57 | } |
58 | } | |
59 | ||
60 | if (padding != LTC_PKCS_1_V1_5_NA1) { | |
61 | /* valid hash ? */ | |
56 | 62 | if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) { |
57 | 63 | return err; |
58 | 64 | } |
78 | 84 | } else { |
79 | 85 | /* PKCS #1 v1.5 pad the hash */ |
80 | 86 | unsigned char *tmpin; |
81 | ltc_asn1_list digestinfo[2], siginfo[2]; | |
82 | 87 | |
83 | /* not all hashes have OIDs... so sad */ | |
84 | if (hash_descriptor[hash_idx].OIDlen == 0) { | |
85 | return CRYPT_INVALID_ARG; | |
86 | } | |
88 | if (padding == LTC_PKCS_1_V1_5) { | |
89 | ltc_asn1_list digestinfo[2], siginfo[2]; | |
90 | /* not all hashes have OIDs... so sad */ | |
91 | if (hash_descriptor[hash_idx].OIDlen == 0) { | |
92 | return CRYPT_INVALID_ARG; | |
93 | } | |
87 | 94 | |
88 | 95 | /* construct the SEQUENCE |
89 | SEQUENCE { | |
90 | SEQUENCE {hashoid OID | |
91 | blah NULL | |
92 | } | |
96 | SEQUENCE { | |
97 | SEQUENCE {hashoid OID | |
98 | blah NULL | |
99 | } | |
93 | 100 | hash OCTET STRING |
101 | } | |
102 | */ | |
103 | LTC_SET_ASN1(digestinfo, 0, LTC_ASN1_OBJECT_IDENTIFIER, hash_descriptor[hash_idx].OID, hash_descriptor[hash_idx].OIDlen); | |
104 | LTC_SET_ASN1(digestinfo, 1, LTC_ASN1_NULL, NULL, 0); | |
105 | LTC_SET_ASN1(siginfo, 0, LTC_ASN1_SEQUENCE, digestinfo, 2); | |
106 | LTC_SET_ASN1(siginfo, 1, LTC_ASN1_OCTET_STRING, in, inlen); | |
107 | ||
108 | /* allocate memory for the encoding */ | |
109 | y = mp_unsigned_bin_size(key->N); | |
110 | tmpin = XMALLOC(y); | |
111 | if (tmpin == NULL) { | |
112 | return CRYPT_MEM; | |
94 | 113 | } |
95 | */ | |
96 | LTC_SET_ASN1(digestinfo, 0, LTC_ASN1_OBJECT_IDENTIFIER, hash_descriptor[hash_idx].OID, hash_descriptor[hash_idx].OIDlen); | |
97 | LTC_SET_ASN1(digestinfo, 1, LTC_ASN1_NULL, NULL, 0); | |
98 | LTC_SET_ASN1(siginfo, 0, LTC_ASN1_SEQUENCE, digestinfo, 2); | |
99 | LTC_SET_ASN1(siginfo, 1, LTC_ASN1_OCTET_STRING, in, inlen); | |
100 | 114 | |
101 | /* allocate memory for the encoding */ | |
102 | y = mp_unsigned_bin_size(key->N); | |
103 | tmpin = XMALLOC(y); | |
104 | if (tmpin == NULL) { | |
105 | return CRYPT_MEM; | |
106 | } | |
107 | ||
108 | if ((err = der_encode_sequence(siginfo, 2, tmpin, &y)) != CRYPT_OK) { | |
109 | XFREE(tmpin); | |
110 | return err; | |
115 | if ((err = der_encode_sequence(siginfo, 2, tmpin, &y)) != CRYPT_OK) { | |
116 | XFREE(tmpin); | |
117 | return err; | |
118 | } | |
119 | } else { | |
120 | /* set the pointer and data-length to the input values */ | |
121 | tmpin = (unsigned char *)in; | |
122 | y = inlen; | |
111 | 123 | } |
112 | 124 | |
113 | 125 | x = *outlen; |
114 | if ((err = pkcs_1_v1_5_encode(tmpin, y, LTC_PKCS_1_EMSA, | |
115 | modulus_bitlen, NULL, 0, | |
116 | out, &x)) != CRYPT_OK) { | |
126 | err = pkcs_1_v1_5_encode(tmpin, y, LTC_PKCS_1_EMSA, modulus_bitlen, NULL, 0, out, &x); | |
127 | ||
128 | if (padding == LTC_PKCS_1_V1_5) { | |
117 | 129 | XFREE(tmpin); |
130 | } | |
131 | ||
132 | if (err != CRYPT_OK) { | |
118 | 133 | return err; |
119 | 134 | } |
120 | XFREE(tmpin); | |
121 | 135 | } |
122 | 136 | |
123 | 137 | /* RSA encode it */ |
4 | 4 | * |
5 | 5 | * The library is free for all purposes without any express |
6 | 6 | * guarantee it works. |
7 | * | |
8 | * http://libtom.org | |
9 | 7 | */ |
10 | 8 | #include "tomcrypt.h" |
11 | 9 |
20 | 20 | @param siglen The length of the signature data (octets) |
21 | 21 | @param hash The hash of the message that was signed |
22 | 22 | @param hashlen The length of the hash of the message that was signed (octets) |
23 | @param padding Type of padding (LTC_PKCS_1_PSS or LTC_PKCS_1_V1_5) | |
23 | @param padding Type of padding (LTC_PKCS_1_PSS, LTC_PKCS_1_V1_5 or LTC_PKCS_1_V1_5_NA1) | |
24 | 24 | @param hash_idx The index of the desired hash |
25 | 25 | @param saltlen The length of the salt used during signature |
26 | 26 | @param stat [out] The result of the signature comparison, 1==valid, 0==invalid |
48 | 48 | /* valid padding? */ |
49 | 49 | |
50 | 50 | if ((padding != LTC_PKCS_1_V1_5) && |
51 | (padding != LTC_PKCS_1_PSS)) { | |
51 | (padding != LTC_PKCS_1_PSS) && | |
52 | (padding != LTC_PKCS_1_V1_5_NA1)) { | |
52 | 53 | return CRYPT_PK_INVALID_PADDING; |
53 | 54 | } |
54 | 55 | |
55 | if (padding == LTC_PKCS_1_PSS) { | |
56 | if (padding != LTC_PKCS_1_V1_5_NA1) { | |
56 | 57 | /* valid hash ? */ |
57 | 58 | if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) { |
58 | 59 | return err; |
100 | 101 | } else { |
101 | 102 | /* PKCS #1 v1.5 decode it */ |
102 | 103 | unsigned char *out; |
103 | unsigned long outlen, loid[16], reallen; | |
104 | unsigned long outlen; | |
104 | 105 | int decoded; |
105 | ltc_asn1_list digestinfo[2], siginfo[2]; | |
106 | ||
107 | /* not all hashes have OIDs... so sad */ | |
108 | if (hash_descriptor[hash_idx].OIDlen == 0) { | |
109 | err = CRYPT_INVALID_ARG; | |
110 | goto bail_2; | |
111 | } | |
112 | 106 | |
113 | 107 | /* allocate temp buffer for decoded hash */ |
114 | 108 | outlen = ((modulus_bitlen >> 3) + (modulus_bitlen & 7 ? 1 : 0)) - 3; |
123 | 117 | goto bail_2; |
124 | 118 | } |
125 | 119 | |
126 | /* now we must decode out[0...outlen-1] using ASN.1, test the OID and then test the hash */ | |
127 | /* construct the SEQUENCE | |
128 | SEQUENCE { | |
129 | SEQUENCE {hashoid OID | |
130 | blah NULL | |
131 | } | |
132 | hash OCTET STRING | |
120 | if (padding == LTC_PKCS_1_V1_5) { | |
121 | unsigned long loid[16], reallen; | |
122 | ltc_asn1_list digestinfo[2], siginfo[2]; | |
123 | ||
124 | /* not all hashes have OIDs... so sad */ | |
125 | if (hash_descriptor[hash_idx].OIDlen == 0) { | |
126 | err = CRYPT_INVALID_ARG; | |
127 | goto bail_2; | |
133 | 128 | } |
134 | */ | |
135 | LTC_SET_ASN1(digestinfo, 0, LTC_ASN1_OBJECT_IDENTIFIER, loid, sizeof(loid)/sizeof(loid[0])); | |
136 | LTC_SET_ASN1(digestinfo, 1, LTC_ASN1_NULL, NULL, 0); | |
137 | LTC_SET_ASN1(siginfo, 0, LTC_ASN1_SEQUENCE, digestinfo, 2); | |
138 | LTC_SET_ASN1(siginfo, 1, LTC_ASN1_OCTET_STRING, tmpbuf, siglen); | |
139 | 129 | |
140 | if ((err = der_decode_sequence(out, outlen, siginfo, 2)) != CRYPT_OK) { | |
141 | XFREE(out); | |
142 | goto bail_2; | |
143 | } | |
130 | /* now we must decode out[0...outlen-1] using ASN.1, test the OID and then test the hash */ | |
131 | /* construct the SEQUENCE | |
132 | SEQUENCE { | |
133 | SEQUENCE {hashoid OID | |
134 | blah NULL | |
135 | } | |
136 | hash OCTET STRING | |
137 | } | |
138 | */ | |
139 | LTC_SET_ASN1(digestinfo, 0, LTC_ASN1_OBJECT_IDENTIFIER, loid, sizeof(loid)/sizeof(loid[0])); | |
140 | LTC_SET_ASN1(digestinfo, 1, LTC_ASN1_NULL, NULL, 0); | |
141 | LTC_SET_ASN1(siginfo, 0, LTC_ASN1_SEQUENCE, digestinfo, 2); | |
142 | LTC_SET_ASN1(siginfo, 1, LTC_ASN1_OCTET_STRING, tmpbuf, siglen); | |
144 | 143 | |
145 | if ((err = der_length_sequence(siginfo, 2, &reallen)) != CRYPT_OK) { | |
146 | XFREE(out); | |
147 | goto bail_2; | |
148 | } | |
144 | if ((err = der_decode_sequence(out, outlen, siginfo, 2)) != CRYPT_OK) { | |
145 | XFREE(out); | |
146 | goto bail_2; | |
147 | } | |
149 | 148 | |
150 | /* test OID */ | |
151 | if ((reallen == outlen) && | |
152 | (digestinfo[0].size == hash_descriptor[hash_idx].OIDlen) && | |
153 | (XMEM_NEQ(digestinfo[0].data, hash_descriptor[hash_idx].OID, sizeof(unsigned long) * hash_descriptor[hash_idx].OIDlen) == 0) && | |
154 | (siginfo[1].size == hashlen) && | |
155 | (XMEM_NEQ(siginfo[1].data, hash, hashlen) == 0)) { | |
156 | *stat = 1; | |
149 | if ((err = der_length_sequence(siginfo, 2, &reallen)) != CRYPT_OK) { | |
150 | XFREE(out); | |
151 | goto bail_2; | |
152 | } | |
153 | ||
154 | /* test OID */ | |
155 | if ((reallen == outlen) && | |
156 | (digestinfo[0].size == hash_descriptor[hash_idx].OIDlen) && | |
157 | (XMEMCMP(digestinfo[0].data, hash_descriptor[hash_idx].OID, sizeof(unsigned long) * hash_descriptor[hash_idx].OIDlen) == 0) && | |
158 | (siginfo[1].size == hashlen) && | |
159 | (XMEMCMP(siginfo[1].data, hash, hashlen) == 0)) { | |
160 | *stat = 1; | |
161 | } | |
162 | } else { | |
163 | /* only check if the hash is equal */ | |
164 | if ((hashlen == outlen) && | |
165 | (XMEMCMP(out, hash, hashlen) == 0)) { | |
166 | *stat = 1; | |
167 | } | |
157 | 168 | } |
158 | 169 | |
159 | 170 | #ifdef LTC_CLEAN_STACK |