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 #include "tomcrypt_private.h"
11
12 /**
13 @file rsa_decrypt_key.c
14 RSA PKCS #1 Decryption, Tom St Denis and Andreas Lange
15 */
16
17 #ifdef LTC_MRSA
18
19 /**
20 PKCS #1 decrypt then v1.5 or OAEP depad
21 @param in The ciphertext
22 @param inlen The length of the ciphertext (octets)
23 @param out [out] The plaintext
24 @param outlen [in/out] The max size and resulting size of the plaintext (octets)
25 @param lparam The system "lparam" value
26 @param lparamlen The length of the lparam value (octets)
27 @param hash_idx The index of the hash desired
28 @param padding Type of padding (LTC_PKCS_1_OAEP or LTC_PKCS_1_V1_5)
29 @param stat [out] Result of the decryption, 1==valid, 0==invalid
30 @param key The corresponding private RSA key
31 @return CRYPT_OK if succcessul (even if invalid)
32 */
rsa_decrypt_key_ex(const unsigned char * in,unsigned long inlen,unsigned char * out,unsigned long * outlen,const unsigned char * lparam,unsigned long lparamlen,int hash_idx,int padding,int * stat,const rsa_key * key)33 int rsa_decrypt_key_ex(const unsigned char *in, unsigned long inlen,
34 unsigned char *out, unsigned long *outlen,
35 const unsigned char *lparam, unsigned long lparamlen,
36 int hash_idx, int padding,
37 int *stat, const rsa_key *key)
38 {
39 unsigned long modulus_bitlen, modulus_bytelen, x;
40 int err;
41 unsigned char *tmp;
42
43 LTC_ARGCHK(out != NULL);
44 LTC_ARGCHK(outlen != NULL);
45 LTC_ARGCHK(key != NULL);
46 LTC_ARGCHK(stat != NULL);
47
48 /* default to invalid */
49 *stat = 0;
50
51 /* valid padding? */
52
53 if ((padding != LTC_PKCS_1_V1_5) &&
54 (padding != LTC_PKCS_1_OAEP)) {
55 return CRYPT_PK_INVALID_PADDING;
56 }
57
58 if (padding == LTC_PKCS_1_OAEP) {
59 /* valid hash ? */
60 if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) {
61 return err;
62 }
63 }
64
65 /* get modulus len in bits */
66 modulus_bitlen = mp_count_bits( (key->N));
67
68 /* outlen must be at least the size of the modulus */
69 modulus_bytelen = mp_unsigned_bin_size( (key->N));
70 if (modulus_bytelen != inlen) {
71 return CRYPT_INVALID_PACKET;
72 }
73
74 /* allocate ram */
75 tmp = XMALLOC(inlen);
76 if (tmp == NULL) {
77 return CRYPT_MEM;
78 }
79
80 /* rsa decode the packet */
81 x = inlen;
82 if ((err = ltc_mp.rsa_me(in, inlen, tmp, &x, PK_PRIVATE, key)) != CRYPT_OK) {
83 XFREE(tmp);
84 return err;
85 }
86
87 if (padding == LTC_PKCS_1_OAEP) {
88 /* now OAEP decode the packet */
89 err = pkcs_1_oaep_decode(tmp, x, lparam, lparamlen, modulus_bitlen, hash_idx,
90 out, outlen, stat);
91 } else {
92 /* now PKCS #1 v1.5 depad the packet */
93 err = pkcs_1_v1_5_decode(tmp, x, LTC_PKCS_1_EME, modulus_bitlen, out, outlen, stat);
94 }
95
96 XFREE(tmp);
97 return err;
98 }
99
100 #endif /* LTC_MRSA */
101
102 /* ref: $Format:%D$ */
103 /* git commit: $Format:%H$ */
104 /* commit time: $Format:%ai$ */
105