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 case YACA_PADDING_PKCS1_SSLV23:
51 return RSA_PKCS1_PADDING;
52 case YACA_PADDING_PKCS1_PSS:
53 return RSA_PKCS1_PSS_PADDING;
54 case YACA_PADDING_PKCS1_OAEP:
55 return RSA_PKCS1_OAEP_PADDING;
62 typedef int (*encrypt_decrypt_fn)(int, const unsigned char*, unsigned char*, RSA*, int);
64 static int encrypt_decrypt(yaca_padding_e padding,
70 encrypt_decrypt_fn fn)
75 struct yaca_key_evp_s *lasym_key;
78 if ((input == NULL && input_len > 0) || (input != NULL && input_len == 0) ||
79 output == NULL || output_len == NULL)
80 return YACA_ERROR_INVALID_PARAMETER;
82 lpadding = rsa_padding2openssl(padding);
84 lasym_key = key_get_evp(key);
85 assert(lasym_key != NULL);
87 ret = EVP_PKEY_get_size(lasym_key->evp);
89 ret = YACA_ERROR_INTERNAL;
96 if (input_len > max_len)
97 return YACA_ERROR_INVALID_PARAMETER;
99 ret = yaca_zalloc(max_len, (void**)&loutput);
100 if (ret != YACA_ERROR_NONE)
104 (const unsigned char*)input,
105 (unsigned char*)loutput,
106 (RSA *)EVP_PKEY_get0_RSA(lasym_key->evp),
110 ret = ERROR_HANDLE();
122 ret = YACA_ERROR_NONE;
130 API int yaca_rsa_public_encrypt(yaca_padding_e padding,
131 const yaca_key_h pub_key,
132 const char *plaintext,
133 size_t plaintext_len,
135 size_t *ciphertext_len)
137 if (pub_key == YACA_KEY_NULL || pub_key->type != YACA_KEY_TYPE_RSA_PUB)
138 return YACA_ERROR_INVALID_PARAMETER;
141 case YACA_PADDING_NONE:
142 case YACA_PADDING_PKCS1:
143 case YACA_PADDING_PKCS1_OAEP:
144 case YACA_PADDING_PKCS1_SSLV23:
147 return YACA_ERROR_INVALID_PARAMETER;
150 return encrypt_decrypt(padding,
159 API int yaca_rsa_private_decrypt(yaca_padding_e padding,
160 const yaca_key_h prv_key,
161 const char *ciphertext,
162 size_t ciphertext_len,
164 size_t *plaintext_len)
166 if (prv_key == YACA_KEY_NULL || prv_key->type != YACA_KEY_TYPE_RSA_PRIV)
167 return YACA_ERROR_INVALID_PARAMETER;
170 case YACA_PADDING_NONE:
171 case YACA_PADDING_PKCS1:
172 case YACA_PADDING_PKCS1_OAEP:
173 case YACA_PADDING_PKCS1_SSLV23:
176 return YACA_ERROR_INVALID_PARAMETER;
179 return encrypt_decrypt(padding,
185 RSA_private_decrypt);
188 API int yaca_rsa_private_encrypt(yaca_padding_e padding,
189 const yaca_key_h prv_key,
190 const char *plaintext,
191 size_t plaintext_len,
193 size_t *ciphertext_len)
195 if (prv_key == YACA_KEY_NULL || prv_key->type != YACA_KEY_TYPE_RSA_PRIV)
196 return YACA_ERROR_INVALID_PARAMETER;
199 case YACA_PADDING_NONE:
200 case YACA_PADDING_PKCS1:
201 case YACA_PADDING_PKCS1_SSLV23:
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:
229 case YACA_PADDING_PKCS1_SSLV23:
232 return YACA_ERROR_INVALID_PARAMETER;
235 return encrypt_decrypt(padding,