xref: /optee_os/core/lib/libtomcrypt/src/pk/rsa/rsa_encrypt_key.c (revision 2a65ecaf7d6f855e24ce1a117fe1931f7378f82c)
1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis */
2 /* SPDX-License-Identifier: Unlicense */
3 #include "tomcrypt_private.h"
4 
5 /**
6   @file rsa_encrypt_key.c
7   RSA PKCS #1 encryption, Tom St Denis and Andreas Lange
8 */
9 
10 #ifdef LTC_MRSA
11 
12 /**
13     (PKCS #1 v2.0) OAEP pad then encrypt
14     @param in          The plaintext
15     @param inlen       The length of the plaintext (octets)
16     @param out         [out] The ciphertext
17     @param outlen      [in/out] The max size and resulting size of the ciphertext
18     @param lparam      The system "lparam" for the encryption
19     @param lparamlen   The length of lparam (octets)
20     @param prng        An active PRNG
21     @param prng_idx    The index of the desired prng
22     @param hash_idx    The index of the desired hash
23     @param padding     Type of padding (LTC_PKCS_1_OAEP or LTC_PKCS_1_V1_5)
24     @param key         The RSA key to encrypt to
25     @return CRYPT_OK if successful
26 */
rsa_encrypt_key_ex(const unsigned char * in,unsigned long inlen,unsigned char * out,unsigned long * outlen,const unsigned char * lparam,unsigned long lparamlen,prng_state * prng,int prng_idx,int mgf_hash,int lparam_hash,int padding,const rsa_key * key)27 int rsa_encrypt_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                              prng_state    *prng,     int            prng_idx,
31                              int            mgf_hash, int            lparam_hash,
32                              int            padding,
33                        const rsa_key       *key)
34 {
35   unsigned long modulus_bitlen, modulus_bytelen, x;
36   int           err;
37 
38   LTC_ARGCHK((inlen == 0) || (in != NULL));
39   LTC_ARGCHK(out    != NULL);
40   LTC_ARGCHK(outlen != NULL);
41   LTC_ARGCHK(key    != NULL);
42 
43   /* valid padding? */
44   if ((padding != LTC_PKCS_1_V1_5) &&
45       (padding != LTC_PKCS_1_OAEP)) {
46     return CRYPT_PK_INVALID_PADDING;
47   }
48 
49   /* valid prng? */
50   if ((err = prng_is_valid(prng_idx)) != CRYPT_OK) {
51      return err;
52   }
53 
54   if (padding == LTC_PKCS_1_OAEP) {
55     /* valid hash? */
56     if ((err = hash_is_valid(mgf_hash)) != CRYPT_OK) {
57        return err;
58     }
59   }
60 
61   /* get modulus len in bits */
62   modulus_bitlen = mp_count_bits( (key->N));
63 
64   /* outlen must be at least the size of the modulus */
65   modulus_bytelen = mp_unsigned_bin_size( (key->N));
66   if (modulus_bytelen > *outlen) {
67      *outlen = modulus_bytelen;
68      return CRYPT_BUFFER_OVERFLOW;
69   }
70 
71   if (padding == LTC_PKCS_1_OAEP) {
72     /* OAEP pad the key */
73     x = *outlen;
74     if ((err = pkcs_1_oaep_encode(in, inlen, lparam,
75                                   lparamlen, modulus_bitlen, prng, prng_idx, mgf_hash,
76                                   lparam_hash, out, &x)) != CRYPT_OK) {
77        return err;
78     }
79   } else {
80     /* PKCS #1 v1.5 pad the key */
81     x = *outlen;
82     if ((err = pkcs_1_v1_5_encode(in, inlen, LTC_PKCS_1_EME,
83                                   modulus_bitlen, prng, prng_idx,
84                                   out, &x)) != CRYPT_OK) {
85       return err;
86     }
87   }
88 
89   /* rsa exptmod the OAEP or PKCS #1 v1.5 pad */
90   return ltc_mp.rsa_me(out, x, out, outlen, PK_PUBLIC, key);
91 }
92 
93 #endif /* LTC_MRSA */
94