2 * Copyright (c) 2016 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
28 #include <openssl/evp.h>
30 #include <yaca_crypto.h>
31 #include <yaca_seal.h>
32 #include <yaca_error.h>
37 static int seal_generate_sym_key(yaca_encrypt_algorithm_e algo,
38 size_t sym_key_bit_len,
41 assert(sym_key != NULL);
43 if (algo == YACA_ENCRYPT_3DES_3TDEA ||
44 algo == YACA_ENCRYPT_UNSAFE_3DES_2TDEA ||
45 algo == YACA_ENCRYPT_UNSAFE_DES)
46 return yaca_key_generate(YACA_KEY_TYPE_DES, sym_key_bit_len, sym_key);
48 return yaca_key_generate(YACA_KEY_TYPE_SYMMETRIC, sym_key_bit_len, sym_key);
51 static int seal_generate_iv(const EVP_CIPHER *cipher, yaca_key_h *iv)
57 assert(cipher != NULL);
59 ret = EVP_CIPHER_iv_length(cipher);
61 ret = YACA_ERROR_INTERNAL;
69 return YACA_ERROR_NONE;
72 return yaca_key_generate(YACA_KEY_TYPE_IV, iv_len * 8, iv);
75 /* used for asymmetric encryption and decryption */
76 static int seal_encrypt_decrypt_key(const yaca_key_h asym_key,
77 const yaca_key_h in_key,
81 const struct yaca_key_evp_s *lasym_key;
82 const struct yaca_key_simple_s *lin_key;
83 struct yaca_key_simple_s *lout_key;
86 lin_key = key_get_simple(in_key);
88 return YACA_ERROR_INVALID_PARAMETER;
90 if (asym_key->type != YACA_KEY_TYPE_RSA_PRIV && asym_key->type != YACA_KEY_TYPE_RSA_PUB)
91 return YACA_ERROR_INVALID_PARAMETER;
93 lasym_key = key_get_evp(asym_key);
94 if (lasym_key == NULL)
95 return YACA_ERROR_INVALID_PARAMETER;
97 ret = EVP_PKEY_size(lasym_key->evp);
99 ret = YACA_ERROR_INTERNAL;
106 ret = yaca_zalloc(sizeof(struct yaca_key_simple_s) + output_len, (void**)&lout_key);
107 if (ret != YACA_ERROR_NONE)
110 lout_key->key.type = YACA_KEY_TYPE_SYMMETRIC;
111 lout_key->bit_len = output_len * 8;
113 if (asym_key->type == YACA_KEY_TYPE_RSA_PRIV)
114 ret = EVP_PKEY_decrypt_old((unsigned char*)lout_key->d,
115 (unsigned char*)lin_key->d,
116 lin_key->bit_len / 8,
119 ret = EVP_PKEY_encrypt_old((unsigned char*)lout_key->d,
120 (unsigned char*)lin_key->d,
121 lin_key->bit_len / 8,
125 ret = ERROR_HANDLE();
131 /* Update the key length just in case */
132 lout_key->bit_len = output_len * 8;
134 *out_key = (yaca_key_h)lout_key;
137 ret = YACA_ERROR_NONE;
140 yaca_key_destroy((yaca_key_h)lout_key);
145 API int yaca_seal_initialize(yaca_context_h *ctx,
146 const yaca_key_h pub_key,
147 yaca_encrypt_algorithm_e algo,
148 yaca_block_cipher_mode_e bcm,
149 size_t sym_key_bit_len,
154 const EVP_CIPHER *cipher;
155 yaca_key_h lsym_key = YACA_KEY_NULL;
156 yaca_key_h liv = YACA_KEY_NULL;
157 yaca_key_h lenc_sym_key = YACA_KEY_NULL;
159 if (pub_key == YACA_KEY_NULL || pub_key->type != YACA_KEY_TYPE_RSA_PUB ||
160 sym_key == NULL || bcm == YACA_BCM_WRAP || sym_key_bit_len % 8 != 0)
161 return YACA_ERROR_INVALID_PARAMETER;
163 ret = encrypt_get_algorithm(algo, bcm, sym_key_bit_len, &cipher);
164 if (ret != YACA_ERROR_NONE)
167 ret = seal_generate_sym_key(algo, sym_key_bit_len, &lsym_key);
168 if (ret != YACA_ERROR_NONE)
171 ret = seal_generate_iv(cipher, &liv);
172 if (ret != YACA_ERROR_NONE)
175 if (liv != YACA_KEY_NULL && iv == NULL) {
176 ret = YACA_ERROR_INVALID_PARAMETER;
180 /* using public key will make it encrypt the symmetric key */
181 ret = seal_encrypt_decrypt_key(pub_key, lsym_key, &lenc_sym_key);
182 if (ret != YACA_ERROR_NONE)
185 ret = encrypt_initialize(ctx, cipher, lsym_key, liv, OP_SEAL);
186 if (ret != YACA_ERROR_NONE)
189 *sym_key = lenc_sym_key;
190 lenc_sym_key = YACA_KEY_NULL;
193 ret = YACA_ERROR_NONE;
196 yaca_key_destroy(liv);
197 yaca_key_destroy(lsym_key);
198 yaca_key_destroy(lenc_sym_key);
203 API int yaca_seal_update(yaca_context_h ctx,
204 const char *plaintext,
205 size_t plaintext_len,
207 size_t *ciphertext_len)
209 return encrypt_update(ctx, (const unsigned char*)plaintext, plaintext_len,
210 (unsigned char*)ciphertext, ciphertext_len, OP_SEAL);
213 API int yaca_seal_finalize(yaca_context_h ctx,
215 size_t *ciphertext_len)
217 return encrypt_finalize(ctx, (unsigned char*)ciphertext, ciphertext_len, OP_SEAL);
220 API int yaca_open_initialize(yaca_context_h *ctx,
221 const yaca_key_h prv_key,
222 yaca_encrypt_algorithm_e algo,
223 yaca_block_cipher_mode_e bcm,
224 size_t sym_key_bit_len,
225 const yaca_key_h sym_key,
229 const EVP_CIPHER *cipher;
230 yaca_key_h lsym_key = YACA_KEY_NULL;
232 if (prv_key == YACA_KEY_NULL || prv_key->type != YACA_KEY_TYPE_RSA_PRIV ||
233 sym_key == YACA_KEY_NULL || bcm == YACA_BCM_WRAP || sym_key_bit_len % 8 != 0)
234 return YACA_ERROR_INVALID_PARAMETER;
236 ret = encrypt_get_algorithm(algo, bcm, sym_key_bit_len, &cipher);
237 if (ret != YACA_ERROR_NONE)
240 /* using private key will make it decrypt the symmetric key */
241 ret = seal_encrypt_decrypt_key(prv_key, sym_key, &lsym_key);
242 if (ret != YACA_ERROR_NONE)
245 ret = encrypt_initialize(ctx, cipher, lsym_key, iv, OP_OPEN);
246 if (ret != YACA_ERROR_NONE)
249 ret = YACA_ERROR_NONE;
252 yaca_key_destroy(lsym_key);
256 API int yaca_open_update(yaca_context_h ctx,
257 const char *ciphertext,
258 size_t ciphertext_len,
260 size_t *plaintext_len)
262 return encrypt_update(ctx, (const unsigned char*)ciphertext, ciphertext_len,
263 (unsigned char*)plaintext, plaintext_len, OP_OPEN);
266 API int yaca_open_finalize(yaca_context_h ctx,
268 size_t *plaintext_len)
270 return encrypt_finalize(ctx, (unsigned char*)plaintext, plaintext_len, OP_OPEN);