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