Replace spaces with tabs
[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         assert(lasym_key != NULL);
82
83         ret = EVP_PKEY_size(lasym_key->evp);
84         if (ret <= 0) {
85                 ret = YACA_ERROR_INTERNAL;
86                 ERROR_DUMP(ret);
87                 return ret;
88         }
89
90         max_len = ret;
91
92         ret = yaca_zalloc(max_len, (void**)&loutput);
93         if (ret != YACA_ERROR_NONE)
94                 return ret;
95
96         ret = fn(input_len,
97                          (const unsigned char*)input,
98                          (unsigned char*)loutput,
99                          EVP_PKEY_get0_RSA(lasym_key->evp),
100                          lpadding);
101
102         if (ret < 0) {
103                 ret = ERROR_HANDLE();
104                 goto exit;
105         }
106
107         if (ret == 0) {
108                 yaca_free(loutput);
109                 loutput = NULL;
110         }
111
112         *output_len = ret;
113         *output = loutput;
114         loutput = NULL;
115         ret = YACA_ERROR_NONE;
116
117 exit:
118         yaca_free(loutput);
119         return ret;
120 }
121
122
123 API int yaca_rsa_public_encrypt(yaca_padding_e padding,
124                                                                 const yaca_key_h pub_key,
125                                                                 const char *plaintext,
126                                                                 size_t plaintext_len,
127                                                                 char **ciphertext,
128                                                                 size_t *ciphertext_len)
129 {
130         if (pub_key == YACA_KEY_NULL || pub_key->type != YACA_KEY_TYPE_RSA_PUB)
131                 return YACA_ERROR_INVALID_PARAMETER;
132
133         switch (padding) {
134         case YACA_PADDING_NONE:
135         case YACA_PADDING_PKCS1:
136         case YACA_PADDING_PKCS1_OAEP:
137         case YACA_PADDING_PKCS1_SSLV23:
138                 break;
139         default:
140                 return YACA_ERROR_INVALID_PARAMETER;
141         }
142
143         return encrypt_decrypt(padding,
144                                                    pub_key,
145                                                    plaintext,
146                                                    plaintext_len,
147                                                    ciphertext,
148                                                    ciphertext_len,
149                                                    RSA_public_encrypt);
150 }
151
152 API int yaca_rsa_private_decrypt(yaca_padding_e padding,
153                                                                  const yaca_key_h prv_key,
154                                                                  const char *ciphertext,
155                                                                  size_t ciphertext_len,
156                                                                  char **plaintext,
157                                                                  size_t *plaintext_len)
158 {
159         if (prv_key == YACA_KEY_NULL || prv_key->type != YACA_KEY_TYPE_RSA_PRIV)
160                 return YACA_ERROR_INVALID_PARAMETER;
161
162         switch (padding) {
163         case YACA_PADDING_NONE:
164         case YACA_PADDING_PKCS1:
165         case YACA_PADDING_PKCS1_OAEP:
166         case YACA_PADDING_PKCS1_SSLV23:
167                 break;
168         default:
169                 return YACA_ERROR_INVALID_PARAMETER;
170         }
171
172         return encrypt_decrypt(padding,
173                                                    prv_key,
174                                                    ciphertext,
175                                                    ciphertext_len,
176                                                    plaintext,
177                                                    plaintext_len,
178                                                    RSA_private_decrypt);
179 }
180
181 API int yaca_rsa_private_encrypt(yaca_padding_e padding,
182                                                                  const yaca_key_h prv_key,
183                                                                  const char *plaintext,
184                                                                  size_t plaintext_len,
185                                                                  char **ciphertext,
186                                                                  size_t *ciphertext_len)
187 {
188         if (prv_key == YACA_KEY_NULL || prv_key->type != YACA_KEY_TYPE_RSA_PRIV)
189                 return YACA_ERROR_INVALID_PARAMETER;
190
191         switch (padding) {
192         case YACA_PADDING_NONE:
193         case YACA_PADDING_PKCS1:
194                 break;
195         default:
196                 return YACA_ERROR_INVALID_PARAMETER;
197         }
198
199         return encrypt_decrypt(padding,
200                                                    prv_key,
201                                                    plaintext,
202                                                    plaintext_len,
203                                                    ciphertext,
204                                                    ciphertext_len,
205                                                    RSA_private_encrypt);
206 }
207
208 API int yaca_rsa_public_decrypt(yaca_padding_e padding,
209                                                                 const yaca_key_h pub_key,
210                                                                 const char *ciphertext,
211                                                                 size_t ciphertext_len,
212                                                                 char **plaintext,
213                                                                 size_t *plaintext_len)
214 {
215         if (pub_key == YACA_KEY_NULL || pub_key->type != YACA_KEY_TYPE_RSA_PUB)
216                 return YACA_ERROR_INVALID_PARAMETER;
217
218         switch (padding) {
219         case YACA_PADDING_NONE:
220         case YACA_PADDING_PKCS1:
221                 break;
222         default:
223                 return YACA_ERROR_INVALID_PARAMETER;
224         }
225
226         return encrypt_decrypt(padding,
227                                                    pub_key,
228                                                    ciphertext,
229                                                    ciphertext_len,
230                                                    plaintext,
231                                                    plaintext_len,
232                                                    RSA_public_decrypt);
233 }