2 * Copyright (c) 2016-2021 Samsung Electronics Co., Ltd All Rights Reserved
4 * Contact: Krzysztof Jackiewicz <k.jackiewicz@samsung.com>
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License
21 * @brief Advanced API for low-level RSA operations
26 #include <openssl/evp.h>
27 #include <openssl/rsa.h>
30 #include <yaca_error.h>
31 #include <yaca_types.h>
32 #include <yaca_crypto.h>
37 #ifdef OPENSSL_MOCKUP_TESTS
38 #include "../tests/openssl_mock_redefine.h"
42 int rsa_padding2openssl(yaca_padding_e padding)
45 case YACA_PADDING_NONE:
46 return RSA_NO_PADDING;
47 case YACA_PADDING_X931:
48 return RSA_X931_PADDING;
49 case YACA_PADDING_PKCS1:
50 return RSA_PKCS1_PADDING;
51 case YACA_PADDING_PKCS1_PSS:
52 return RSA_PKCS1_PSS_PADDING;
53 case YACA_PADDING_PKCS1_OAEP:
54 return RSA_PKCS1_OAEP_PADDING;
55 case YACA_PADDING_PKCS1_SSLV23:
56 return RSA_SSLV23_PADDING;
63 typedef int (*encrypt_decrypt_fn)(int, const unsigned char*, unsigned char*, RSA*, int);
65 static int encrypt_decrypt(yaca_padding_e padding,
71 encrypt_decrypt_fn fn)
76 struct yaca_key_evp_s *lasym_key;
79 if ((input == NULL && input_len > 0) || (input != NULL && input_len == 0) ||
80 output == NULL || output_len == NULL)
81 return YACA_ERROR_INVALID_PARAMETER;
83 lpadding = rsa_padding2openssl(padding);
85 lasym_key = key_get_evp(key);
86 assert(lasym_key != NULL);
88 ret = EVP_PKEY_size(lasym_key->evp);
90 ret = YACA_ERROR_INTERNAL;
97 if (input_len > max_len)
98 return YACA_ERROR_INVALID_PARAMETER;
100 ret = yaca_zalloc(max_len, (void**)&loutput);
101 if (ret != YACA_ERROR_NONE)
105 (const unsigned char*)input,
106 (unsigned char*)loutput,
107 EVP_PKEY_get0_RSA(lasym_key->evp),
111 ret = ERROR_HANDLE();
123 ret = YACA_ERROR_NONE;
131 API int yaca_rsa_public_encrypt(yaca_padding_e padding,
132 const yaca_key_h pub_key,
133 const char *plaintext,
134 size_t plaintext_len,
136 size_t *ciphertext_len)
138 if (pub_key == YACA_KEY_NULL || pub_key->type != YACA_KEY_TYPE_RSA_PUB)
139 return YACA_ERROR_INVALID_PARAMETER;
142 case YACA_PADDING_NONE:
143 case YACA_PADDING_PKCS1:
144 case YACA_PADDING_PKCS1_OAEP:
145 case YACA_PADDING_PKCS1_SSLV23:
148 return YACA_ERROR_INVALID_PARAMETER;
151 return encrypt_decrypt(padding,
160 API int yaca_rsa_private_decrypt(yaca_padding_e padding,
161 const yaca_key_h prv_key,
162 const char *ciphertext,
163 size_t ciphertext_len,
165 size_t *plaintext_len)
167 if (prv_key == YACA_KEY_NULL || prv_key->type != YACA_KEY_TYPE_RSA_PRIV)
168 return YACA_ERROR_INVALID_PARAMETER;
171 case YACA_PADDING_NONE:
172 case YACA_PADDING_PKCS1:
173 case YACA_PADDING_PKCS1_OAEP:
174 case YACA_PADDING_PKCS1_SSLV23:
177 return YACA_ERROR_INVALID_PARAMETER;
180 return encrypt_decrypt(padding,
186 RSA_private_decrypt);
189 API int yaca_rsa_private_encrypt(yaca_padding_e padding,
190 const yaca_key_h prv_key,
191 const char *plaintext,
192 size_t plaintext_len,
194 size_t *ciphertext_len)
196 if (prv_key == YACA_KEY_NULL || prv_key->type != YACA_KEY_TYPE_RSA_PRIV)
197 return YACA_ERROR_INVALID_PARAMETER;
200 case YACA_PADDING_NONE:
201 case YACA_PADDING_PKCS1:
204 return YACA_ERROR_INVALID_PARAMETER;
207 return encrypt_decrypt(padding,
213 RSA_private_encrypt);
216 API int yaca_rsa_public_decrypt(yaca_padding_e padding,
217 const yaca_key_h pub_key,
218 const char *ciphertext,
219 size_t ciphertext_len,
221 size_t *plaintext_len)
223 if (pub_key == YACA_KEY_NULL || pub_key->type != YACA_KEY_TYPE_RSA_PUB)
224 return YACA_ERROR_INVALID_PARAMETER;
227 case YACA_PADDING_NONE:
228 case YACA_PADDING_PKCS1:
231 return YACA_ERROR_INVALID_PARAMETER;
234 return encrypt_decrypt(padding,