Fix svace defects
[platform/core/security/yaca.git] / src / rsa.c
1 /*
2  *  Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *  Contact: Krzysztof Jackiewicz <k.jackiewicz@samsung.com>
5  *
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
9  *
10  *      http://www.apache.org/licenses/LICENSE-2.0
11  *
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
17  */
18
19 /**
20  * @file   rsa.c
21  * @brief  Advanced API for low-level RSA operations
22  */
23
24 #include <assert.h>
25
26 #include <openssl/evp.h>
27 #include <openssl/rsa.h>
28
29 #include <yaca_rsa.h>
30 #include <yaca_error.h>
31 #include <yaca_types.h>
32 #include <yaca_crypto.h>
33 #include <yaca_key.h>
34
35 #include "internal.h"
36
37 int rsa_padding2openssl(yaca_padding_e padding)
38 {
39         switch (padding) {
40         case YACA_PADDING_NONE:
41                 return RSA_NO_PADDING;
42         case YACA_PADDING_X931:
43                 return RSA_X931_PADDING;
44         case YACA_PADDING_PKCS1:
45                 return RSA_PKCS1_PADDING;
46         case YACA_PADDING_PKCS1_PSS:
47                 return RSA_PKCS1_PSS_PADDING;
48         case YACA_PADDING_PKCS1_OAEP:
49                 return RSA_PKCS1_OAEP_PADDING;
50         case YACA_PADDING_PKCS1_SSLV23:
51                 return RSA_SSLV23_PADDING;
52         default:
53                 return -1;
54         }
55 }
56
57 typedef int (*encrypt_decrypt_fn)(int, const unsigned char*, unsigned char*, RSA*, int);
58
59 static int encrypt_decrypt(yaca_padding_e padding,
60                            const yaca_key_h key,
61                            const char *input,
62                            size_t input_len,
63                            char **output,
64                            size_t *output_len,
65                            encrypt_decrypt_fn fn)
66 {
67         int ret;
68         size_t max_len;
69         char *loutput = NULL;
70         struct yaca_key_evp_s *lasym_key;
71         int lpadding;
72
73         if ((input == NULL && input_len > 0) || (input != NULL && input_len == 0) ||
74             output == NULL || output_len == NULL)
75                 return YACA_ERROR_INVALID_PARAMETER;
76
77         lpadding = rsa_padding2openssl(padding);
78         assert(lpadding != -1);
79
80         lasym_key = key_get_evp(key);
81         if (lasym_key == NULL)
82                 return YACA_ERROR_INVALID_PARAMETER;
83
84         ret = EVP_PKEY_size(lasym_key->evp);
85         if (ret <= 0) {
86                 ret = YACA_ERROR_INTERNAL;
87                 ERROR_DUMP(ret);
88                 return ret;
89         }
90
91         max_len = ret;
92
93         ret = yaca_zalloc(max_len, (void**)&loutput);
94         if (ret != YACA_ERROR_NONE)
95                 return ret;
96
97         ret = fn(input_len,
98                  (const unsigned char*)input,
99                  (unsigned char*)loutput,
100                  lasym_key->evp->pkey.rsa,
101                  lpadding);
102
103         if (ret < 0) {
104                 ret = ERROR_HANDLE();
105                 goto exit;
106         }
107
108         if (ret == 0) {
109                 yaca_free(loutput);
110                 loutput = NULL;
111         }
112
113         *output_len = ret;
114         *output = loutput;
115         loutput = NULL;
116         ret = YACA_ERROR_NONE;
117
118 exit:
119         yaca_free(loutput);
120         return ret;
121 }
122
123
124 API int yaca_rsa_public_encrypt(yaca_padding_e padding,
125                                 const yaca_key_h pub_key,
126                                 const char *plaintext,
127                                 size_t plaintext_len,
128                                 char **ciphertext,
129                                 size_t *ciphertext_len)
130 {
131         if (pub_key == YACA_KEY_NULL || pub_key->type != YACA_KEY_TYPE_RSA_PUB)
132                 return YACA_ERROR_INVALID_PARAMETER;
133
134         switch (padding) {
135         case YACA_PADDING_NONE:
136         case YACA_PADDING_PKCS1:
137         case YACA_PADDING_PKCS1_OAEP:
138         case YACA_PADDING_PKCS1_SSLV23:
139                 break;
140         default:
141                 return YACA_ERROR_INVALID_PARAMETER;
142         }
143
144         return encrypt_decrypt(padding,
145                                pub_key,
146                                plaintext,
147                                plaintext_len,
148                                ciphertext,
149                                ciphertext_len,
150                                RSA_public_encrypt);
151 }
152
153 API int yaca_rsa_private_decrypt(yaca_padding_e padding,
154                                  const yaca_key_h prv_key,
155                                  const char *ciphertext,
156                                  size_t ciphertext_len,
157                                  char **plaintext,
158                                  size_t *plaintext_len)
159 {
160         if (prv_key == YACA_KEY_NULL || prv_key->type != YACA_KEY_TYPE_RSA_PRIV)
161                 return YACA_ERROR_INVALID_PARAMETER;
162
163         switch (padding) {
164         case YACA_PADDING_NONE:
165         case YACA_PADDING_PKCS1:
166         case YACA_PADDING_PKCS1_OAEP:
167         case YACA_PADDING_PKCS1_SSLV23:
168                 break;
169         default:
170                 return YACA_ERROR_INVALID_PARAMETER;
171         }
172
173         return encrypt_decrypt(padding,
174                                prv_key,
175                                ciphertext,
176                                ciphertext_len,
177                                plaintext,
178                                plaintext_len,
179                                RSA_private_decrypt);
180 }
181
182 API int yaca_rsa_private_encrypt(yaca_padding_e padding,
183                                  const yaca_key_h prv_key,
184                                  const char *plaintext,
185                                  size_t plaintext_len,
186                                  char **ciphertext,
187                                  size_t *ciphertext_len)
188 {
189         if (prv_key == YACA_KEY_NULL || prv_key->type != YACA_KEY_TYPE_RSA_PRIV)
190                 return YACA_ERROR_INVALID_PARAMETER;
191
192         switch (padding) {
193         case YACA_PADDING_NONE:
194         case YACA_PADDING_PKCS1:
195                 break;
196         default:
197                 return YACA_ERROR_INVALID_PARAMETER;
198         }
199
200         return encrypt_decrypt(padding,
201                                prv_key,
202                                plaintext,
203                                plaintext_len,
204                                ciphertext,
205                                ciphertext_len,
206                                RSA_private_encrypt);
207 }
208
209 API int yaca_rsa_public_decrypt(yaca_padding_e padding,
210                                 const yaca_key_h pub_key,
211                                 const char *ciphertext,
212                                 size_t ciphertext_len,
213                                 char **plaintext,
214                                 size_t *plaintext_len)
215 {
216         if (pub_key == YACA_KEY_NULL || pub_key->type != YACA_KEY_TYPE_RSA_PUB)
217                 return YACA_ERROR_INVALID_PARAMETER;
218
219         switch (padding) {
220         case YACA_PADDING_NONE:
221         case YACA_PADDING_PKCS1:
222                 break;
223         default:
224                 return YACA_ERROR_INVALID_PARAMETER;
225         }
226
227         return encrypt_decrypt(padding,
228                                pub_key,
229                                ciphertext,
230                                ciphertext_len,
231                                plaintext,
232                                plaintext_len,
233                                RSA_public_decrypt);
234 }