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
30 #include <openssl/evp.h>
31 #include <openssl/rsa.h>
32 #include <openssl/bio.h>
33 #include <openssl/pem.h>
34 #include <openssl/des.h>
35 #include <openssl/dh.h>
37 #include <yaca_crypto.h>
38 #include <yaca_error.h>
43 struct openssl_password_data {
44 bool password_requested;
48 int openssl_password_cb(char *buf, int size, UNUSED int rwflag, void *u)
50 struct openssl_password_data *cb_data = u;
52 if (cb_data->password == NULL)
55 size_t pass_len = strlen(cb_data->password);
57 if (pass_len > INT_MAX || (int)pass_len > size)
60 memcpy(buf, cb_data->password, pass_len);
61 cb_data->password_requested = true;
66 int openssl_password_cb_error(UNUSED char *buf, UNUSED int size, UNUSED int rwflag, UNUSED void *u)
71 int base64_decode_length(const char *data, size_t data_len, size_t *len)
74 assert(data_len != 0);
78 size_t tmp_len = data_len;
80 if (data_len % 4 != 0)
81 return YACA_ERROR_INVALID_PARAMETER;
83 if (data[tmp_len - 1] == '=') {
85 if (data[tmp_len - 2] == '=')
89 *len = data_len / 4 * 3 - padded;
90 return YACA_ERROR_NONE;
93 #define TMP_BUF_LEN 512
95 int base64_decode(const char *data, size_t data_len, BIO **output)
98 assert(data_len != 0);
99 assert(output != NULL);
105 char tmpbuf[TMP_BUF_LEN];
110 /* This is because of BIO_new_mem_buf() having its length param typed int */
111 if (data_len > INT_MAX)
112 return YACA_ERROR_INVALID_PARAMETER;
114 /* First phase of correctness checking, calculate expected output length */
115 ret = base64_decode_length(data, data_len, &b64_len);
116 if (ret != YACA_ERROR_NONE)
119 b64 = BIO_new(BIO_f_base64());
121 ret = YACA_ERROR_INTERNAL;
126 src = BIO_new_mem_buf(data, data_len);
128 ret = YACA_ERROR_INTERNAL;
135 dst = BIO_new(BIO_s_mem());
137 ret = YACA_ERROR_INTERNAL;
142 BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
146 ret = BIO_read(b64, tmpbuf, TMP_BUF_LEN);
148 ret = YACA_ERROR_INTERNAL;
153 if (ret == YACA_ERROR_NONE)
156 if (BIO_write(dst, tmpbuf, ret) != ret) {
157 ret = YACA_ERROR_INTERNAL;
165 /* Check wether the length of the decoded data is what we expected */
166 out_len = BIO_get_mem_data(dst, &out);
168 ret = YACA_ERROR_INTERNAL;
172 if ((size_t)out_len != b64_len) {
173 ret = YACA_ERROR_INVALID_PARAMETER;
179 ret = YACA_ERROR_NONE;
188 int import_simple(yaca_key_h *key,
189 yaca_key_type_e key_type,
194 assert(data != NULL);
195 assert(data_len != 0);
199 const char *key_data;
201 struct yaca_key_simple_s *nk = NULL;
203 ret = base64_decode(data, data_len, &decoded);
204 if (ret == YACA_ERROR_NONE) {
205 /* Conversion successfull, get the BASE64 */
206 long len = BIO_get_mem_data(decoded, &key_data);
207 if (len <= 0 || key_data == NULL) {
208 ret = YACA_ERROR_INTERNAL;
213 } else if (ret == YACA_ERROR_INVALID_PARAMETER) {
214 /* This was not BASE64 or it was corrupted, treat as RAW */
215 key_data_len = data_len;
218 /* Some other, possibly unrecoverable error, give up */
222 /* key_bit_len has to fit in size_t */
223 if (key_data_len > SIZE_MAX / 8) {
224 ret = YACA_ERROR_INVALID_PARAMETER;
228 /* DES key length verification */
229 if (key_type == YACA_KEY_TYPE_DES) {
230 size_t key_bit_len = key_data_len * 8;
231 if (key_bit_len != YACA_KEY_LENGTH_UNSAFE_64BIT &&
232 key_bit_len != YACA_KEY_LENGTH_UNSAFE_128BIT &&
233 key_bit_len != YACA_KEY_LENGTH_192BIT) {
234 ret = YACA_ERROR_INVALID_PARAMETER;
239 ret = yaca_zalloc(sizeof(struct yaca_key_simple_s) + key_data_len, (void**)&nk);
240 if (ret != YACA_ERROR_NONE)
243 memcpy(nk->d, key_data, key_data_len);
244 nk->bit_len = key_data_len * 8;
245 nk->key.type = key_type;
247 *key = (yaca_key_h)nk;
249 ret = YACA_ERROR_NONE;
252 BIO_free_all(decoded);
257 int import_evp(yaca_key_h *key,
258 yaca_key_type_e key_type,
259 const char *password,
264 assert(password == NULL || password[0] != '\0');
265 assert(data != NULL);
266 assert(data_len != 0);
270 EVP_PKEY *pkey = NULL;
271 pem_password_cb *cb = openssl_password_cb;
272 struct openssl_password_data cb_data = {false, password};
274 bool password_supported;
275 yaca_key_type_e type;
276 struct yaca_key_evp_s *nk = NULL;
278 /* Neither PEM nor DER will ever be shorter then 4 bytes (12 seems
279 * to be minimum for DER, much more for PEM). This is just to make
280 * sure we have at least 4 bytes for strncmp() below.
283 return YACA_ERROR_INVALID_PARAMETER;
285 /* This is because of BIO_new_mem_buf() having its length param typed int */
286 if (data_len > INT_MAX)
287 return YACA_ERROR_INVALID_PARAMETER;
289 src = BIO_new_mem_buf(data, data_len);
291 ERROR_DUMP(YACA_ERROR_INTERNAL);
292 return YACA_ERROR_INTERNAL;
296 if (strncmp("----", data, 4) == 0) {
299 pkey = PEM_read_bio_PrivateKey(src, NULL, cb, (void*)&cb_data);
300 if (ERROR_HANDLE() == YACA_ERROR_INVALID_PASSWORD)
301 return YACA_ERROR_INVALID_PASSWORD;
303 password_supported = true;
308 pkey = PEM_read_bio_PUBKEY(src, NULL, openssl_password_cb_error, NULL);
311 password_supported = false;
316 X509 *x509 = PEM_read_bio_X509(src, NULL, openssl_password_cb_error, NULL);
318 pkey = X509_get_pubkey(x509);
323 password_supported = false;
330 pkey = d2i_PKCS8PrivateKey_bio(src, NULL, cb, (void*)&cb_data);
331 if (ERROR_HANDLE() == YACA_ERROR_INVALID_PASSWORD)
332 return YACA_ERROR_INVALID_PASSWORD;
334 password_supported = true;
339 pkey = d2i_PrivateKey_bio(src, NULL);
342 password_supported = false;
347 pkey = d2i_PUBKEY_bio(src, NULL);
350 password_supported = false;
355 X509 *x509 = d2i_X509_bio(src, NULL);
357 pkey = X509_get_pubkey(x509);
362 password_supported = false;
369 return YACA_ERROR_INVALID_PARAMETER;
371 /* password was given, but it was not required to perform import */
372 if (password != NULL && !cb_data.password_requested) {
373 if (password_supported)
374 ret = YACA_ERROR_INVALID_PASSWORD;
376 ret = YACA_ERROR_INVALID_PARAMETER;
380 switch (EVP_PKEY_type(pkey->type)) {
382 type = private ? YACA_KEY_TYPE_RSA_PRIV : YACA_KEY_TYPE_RSA_PUB;
386 type = private ? YACA_KEY_TYPE_DSA_PRIV : YACA_KEY_TYPE_DSA_PUB;
390 type = private ? YACA_KEY_TYPE_EC_PRIV : YACA_KEY_TYPE_EC_PUB;
394 ret = YACA_ERROR_INVALID_PARAMETER;
398 if (type != key_type) {
399 ret = YACA_ERROR_INVALID_PARAMETER;
403 ret = yaca_zalloc(sizeof(struct yaca_key_evp_s), (void**)&nk);
404 if (ret != YACA_ERROR_NONE)
408 *key = (yaca_key_h)nk;
412 ret = YACA_ERROR_NONE;
420 int export_simple_raw(struct yaca_key_simple_s *simple_key,
425 assert(simple_key != NULL);
426 assert(data != NULL);
427 assert(data_len != NULL);
429 size_t key_len = simple_key->bit_len / 8;
433 ret = yaca_malloc(key_len, (void**)data);
434 if (ret != YACA_ERROR_NONE)
437 memcpy(*data, simple_key->d, key_len);
440 return YACA_ERROR_NONE;
443 int export_simple_base64(struct yaca_key_simple_s *simple_key,
447 assert(simple_key != NULL);
448 assert(data != NULL);
449 assert(data_len != NULL);
452 size_t key_len = simple_key->bit_len / 8;
458 b64 = BIO_new(BIO_f_base64());
460 ret = YACA_ERROR_INTERNAL;
465 mem = BIO_new(BIO_s_mem());
467 ret = YACA_ERROR_INTERNAL;
473 BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
475 ret = BIO_write(b64, simple_key->d, key_len);
476 if (ret <= 0 || (unsigned)ret != key_len) {
477 ret = YACA_ERROR_INTERNAL;
482 ret = BIO_flush(b64);
484 ret = YACA_ERROR_INTERNAL;
489 bio_data_len = BIO_get_mem_data(mem, &bio_data);
490 if (bio_data_len <= 0) {
491 ret = YACA_ERROR_INTERNAL;
496 ret = yaca_malloc(bio_data_len, (void**)data);
497 if (ret != YACA_ERROR_NONE)
500 memcpy(*data, bio_data, bio_data_len);
501 *data_len = bio_data_len;
502 ret = YACA_ERROR_NONE;
510 int export_evp_default_bio(struct yaca_key_evp_s *evp_key,
511 yaca_key_file_format_e key_file_fmt,
512 const char *password,
515 assert(evp_key != NULL);
516 assert(password == NULL || password[0] != '\0');
520 const EVP_CIPHER *enc = NULL;
522 if (password != NULL)
523 enc = EVP_aes_256_cbc();
525 switch (key_file_fmt) {
527 case YACA_KEY_FILE_FORMAT_PEM:
528 switch (evp_key->key.type) {
530 case YACA_KEY_TYPE_RSA_PRIV:
531 ret = PEM_write_bio_RSAPrivateKey(mem, EVP_PKEY_get0(evp_key->evp),
532 enc, NULL, 0, NULL, (void*)password);
534 case YACA_KEY_TYPE_DSA_PRIV:
535 ret = PEM_write_bio_DSAPrivateKey(mem, EVP_PKEY_get0(evp_key->evp),
536 enc, NULL, 0, NULL, (void*)password);
539 case YACA_KEY_TYPE_RSA_PUB:
540 case YACA_KEY_TYPE_DSA_PUB:
541 if (password != NULL)
542 return YACA_ERROR_INVALID_PARAMETER;
543 ret = PEM_write_bio_PUBKEY(mem, evp_key->evp);
546 case YACA_KEY_TYPE_DH_PRIV:
547 case YACA_KEY_TYPE_DH_PUB:
548 case YACA_KEY_TYPE_EC_PRIV:
549 case YACA_KEY_TYPE_EC_PUB:
550 //TODO NOT_IMPLEMENTED
552 return YACA_ERROR_INVALID_PARAMETER;
557 case YACA_KEY_FILE_FORMAT_DER:
558 switch (evp_key->key.type) {
560 case YACA_KEY_TYPE_RSA_PRIV:
561 if (password != NULL)
562 return YACA_ERROR_INVALID_PARAMETER;
563 ret = i2d_RSAPrivateKey_bio(mem, EVP_PKEY_get0(evp_key->evp));
566 case YACA_KEY_TYPE_DSA_PRIV:
567 if (password != NULL)
568 return YACA_ERROR_INVALID_PARAMETER;
569 ret = i2d_DSAPrivateKey_bio(mem, EVP_PKEY_get0(evp_key->evp));
572 case YACA_KEY_TYPE_RSA_PUB:
573 case YACA_KEY_TYPE_DSA_PUB:
574 if (password != NULL)
575 return YACA_ERROR_INVALID_PARAMETER;
576 ret = i2d_PUBKEY_bio(mem, evp_key->evp);
579 case YACA_KEY_TYPE_DH_PRIV:
580 case YACA_KEY_TYPE_DH_PUB:
581 case YACA_KEY_TYPE_EC_PRIV:
582 case YACA_KEY_TYPE_EC_PUB:
583 //TODO NOT_IMPLEMENTED
585 return YACA_ERROR_INVALID_PARAMETER;
591 return YACA_ERROR_INVALID_PARAMETER;
595 ret = YACA_ERROR_INTERNAL;
600 return YACA_ERROR_NONE;
603 int export_evp_pkcs8_bio(struct yaca_key_evp_s *evp_key,
604 yaca_key_file_format_e key_file_fmt,
605 const char *password,
608 assert(evp_key != NULL);
609 assert(password == NULL || password[0] != '\0');
613 int nid = NID_pbeWithMD5AndDES_CBC;
615 /* PKCS8 export requires a password */
616 if (password == NULL)
617 return YACA_ERROR_INVALID_PARAMETER;
619 switch (key_file_fmt) {
621 case YACA_KEY_FILE_FORMAT_PEM:
622 switch (evp_key->key.type) {
624 case YACA_KEY_TYPE_RSA_PRIV:
625 case YACA_KEY_TYPE_DSA_PRIV:
626 ret = PEM_write_bio_PKCS8PrivateKey_nid(mem, evp_key->evp, nid,
627 NULL, 0, NULL, (void*)password);
629 case YACA_KEY_TYPE_DH_PRIV:
630 case YACA_KEY_TYPE_EC_PRIV:
631 //TODO NOT_IMPLEMENTED
633 /* Public keys are not supported by PKCS8 */
634 return YACA_ERROR_INVALID_PARAMETER;
639 case YACA_KEY_FILE_FORMAT_DER:
640 switch (evp_key->key.type) {
642 case YACA_KEY_TYPE_RSA_PRIV:
643 case YACA_KEY_TYPE_DSA_PRIV:
644 ret = i2d_PKCS8PrivateKey_nid_bio(mem, evp_key->evp, nid,
645 NULL, 0, NULL, (void*)password);
648 case YACA_KEY_TYPE_DH_PRIV:
649 case YACA_KEY_TYPE_EC_PRIV:
650 //TODO NOT_IMPLEMENTED
652 /* Public keys are not supported by PKCS8 */
653 return YACA_ERROR_INVALID_PARAMETER;
659 return YACA_ERROR_INVALID_PARAMETER;
663 ret = YACA_ERROR_INTERNAL;
668 return YACA_ERROR_NONE;
671 int export_evp(struct yaca_key_evp_s *evp_key,
672 yaca_key_format_e key_fmt,
673 yaca_key_file_format_e key_file_fmt,
674 const char *password,
678 assert(evp_key != NULL);
679 assert(password == NULL || password[0] != '\0');
680 assert(data != NULL);
681 assert(data_len != NULL);
683 int ret = YACA_ERROR_NONE;
688 mem = BIO_new(BIO_s_mem());
690 ret = YACA_ERROR_INTERNAL;
696 case YACA_KEY_FORMAT_DEFAULT:
697 ret = export_evp_default_bio(evp_key, key_file_fmt, password, mem);
699 case YACA_KEY_FORMAT_PKCS8:
700 ret = export_evp_pkcs8_bio(evp_key, key_file_fmt, password, mem);
703 ret = YACA_ERROR_INVALID_PARAMETER;
707 if (ret != YACA_ERROR_NONE)
710 ret = BIO_flush(mem);
712 ret = YACA_ERROR_INTERNAL;
717 bio_data_len = BIO_get_mem_data(mem, &bio_data);
718 if (bio_data_len <= 0) {
719 ret = YACA_ERROR_INTERNAL;
724 ret = yaca_malloc(bio_data_len, (void**)data);
725 if (ret != YACA_ERROR_NONE)
728 memcpy(*data, bio_data, bio_data_len);
729 *data_len = bio_data_len;
730 ret = YACA_ERROR_NONE;
738 int generate_simple(struct yaca_key_simple_s **out, size_t key_bit_len)
743 struct yaca_key_simple_s *nk;
744 size_t key_byte_len = key_bit_len / 8;
746 ret = yaca_zalloc(sizeof(struct yaca_key_simple_s) + key_byte_len, (void**)&nk);
747 if (ret != YACA_ERROR_NONE)
750 nk->bit_len = key_bit_len;
752 ret = yaca_randomize_bytes(nk->d, key_byte_len);
753 if (ret != YACA_ERROR_NONE)
757 return YACA_ERROR_NONE;
760 int generate_simple_des(struct yaca_key_simple_s **out, size_t key_bit_len)
764 if (key_bit_len != YACA_KEY_LENGTH_UNSAFE_64BIT &&
765 key_bit_len != YACA_KEY_LENGTH_UNSAFE_128BIT &&
766 key_bit_len != YACA_KEY_LENGTH_192BIT)
767 return YACA_ERROR_INVALID_PARAMETER;
770 struct yaca_key_simple_s *nk;
771 size_t key_byte_len = key_bit_len / 8;
773 ret = yaca_zalloc(sizeof(struct yaca_key_simple_s) + key_byte_len, (void**)&nk);
774 if (ret != YACA_ERROR_NONE)
777 DES_cblock *des_key = (DES_cblock*)nk->d;
778 if (key_byte_len >= 8) {
779 ret = DES_random_key(des_key);
781 ret = YACA_ERROR_INTERNAL;
786 if (key_byte_len >= 16) {
787 ret = DES_random_key(des_key + 1);
789 ret = YACA_ERROR_INTERNAL;
794 if (key_byte_len >= 24) {
795 ret = DES_random_key(des_key + 2);
797 ret = YACA_ERROR_INTERNAL;
803 nk->bit_len = key_bit_len;
806 ret = YACA_ERROR_NONE;
814 int generate_evp(struct yaca_key_evp_s **out, yaca_key_type_e key_type, size_t key_bit_len)
817 assert(key_bit_len > 0);
822 EVP_PKEY_CTX *pctx = NULL;
823 EVP_PKEY_CTX *kctx = NULL;
824 EVP_PKEY *pkey = NULL;
825 EVP_PKEY *params = NULL;
826 struct yaca_key_evp_s *nk;
829 case YACA_KEY_TYPE_RSA_PRIV:
830 assert(key_bit_len % 8 == 0);
835 case YACA_KEY_TYPE_DSA_PRIV:
836 assert(key_bit_len % 8 == 0);
838 /* Openssl generates 512-bit key for key lengths smaller than 512. It also
839 * rounds key size to multiplication of 64. */
840 if (key_bit_len < 512 || key_bit_len % 64 != 0)
841 return YACA_ERROR_INVALID_PARAMETER;
845 case YACA_KEY_TYPE_DH_PRIV:
846 assert(key_bit_len % 8 == 0);
852 return YACA_ERROR_INVALID_PARAMETER;
855 ret = yaca_zalloc(sizeof(struct yaca_key_evp_s), (void**)&nk);
856 if (ret != YACA_ERROR_NONE)
860 pctx = EVP_PKEY_CTX_new_id(id, NULL);
862 ret = YACA_ERROR_INTERNAL;
867 ret = EVP_PKEY_paramgen_init(pctx);
869 ret = YACA_ERROR_INTERNAL;
876 ret = EVP_PKEY_CTX_set_dsa_paramgen_bits(pctx, key_bit_len);
879 ret = EVP_PKEY_CTX_set_dh_paramgen_prime_len(pctx, key_bit_len);
882 /* We shouldn't be here */
884 ret = YACA_ERROR_INTERNAL;
888 ret = YACA_ERROR_INTERNAL;
893 ret = EVP_PKEY_paramgen(pctx, ¶ms);
894 if (ret != 1 || params == NULL) {
895 ret = YACA_ERROR_INTERNAL;
900 kctx = EVP_PKEY_CTX_new(params, NULL);
902 kctx = EVP_PKEY_CTX_new_id(id, NULL);
905 ret = YACA_ERROR_INTERNAL;
910 ret = EVP_PKEY_keygen_init(kctx);
912 ret = YACA_ERROR_INTERNAL;
917 if (id == EVP_PKEY_RSA) {
918 ret = EVP_PKEY_CTX_set_rsa_keygen_bits(kctx, key_bit_len);
920 ret = ERROR_HANDLE();
925 ret = EVP_PKEY_keygen(kctx, &pkey);
926 if (ret != 1 || pkey == NULL) {
927 ret = YACA_ERROR_INTERNAL;
937 ret = YACA_ERROR_NONE;
940 EVP_PKEY_CTX_free(kctx);
941 EVP_PKEY_free(params);
942 EVP_PKEY_CTX_free(pctx);
948 struct yaca_key_simple_s *key_get_simple(const yaca_key_h key)
950 struct yaca_key_simple_s *k;
952 if (key == YACA_KEY_NULL)
956 case YACA_KEY_TYPE_SYMMETRIC:
957 case YACA_KEY_TYPE_DES:
958 case YACA_KEY_TYPE_IV:
959 k = (struct yaca_key_simple_s *)key;
962 assert(k->bit_len != 0);
963 assert(k->bit_len % 8 == 0);
964 assert(k->d != NULL);
972 struct yaca_key_evp_s *key_get_evp(const yaca_key_h key)
974 struct yaca_key_evp_s *k;
976 if (key == YACA_KEY_NULL)
980 case YACA_KEY_TYPE_RSA_PUB:
981 case YACA_KEY_TYPE_RSA_PRIV:
982 case YACA_KEY_TYPE_DSA_PUB:
983 case YACA_KEY_TYPE_DSA_PRIV:
984 case YACA_KEY_TYPE_DH_PUB:
985 case YACA_KEY_TYPE_DH_PRIV:
986 k = (struct yaca_key_evp_s *)key;
989 assert(k->evp != NULL);
997 static yaca_key_h key_copy_simple(const struct yaca_key_simple_s *key)
1000 assert(key != NULL);
1002 struct yaca_key_simple_s *copy;
1003 size_t size = sizeof(struct yaca_key_simple_s) + key->bit_len / 8;
1005 ret = yaca_zalloc(size, (void**)©);
1006 if (ret != YACA_ERROR_NONE)
1007 return YACA_KEY_NULL;
1009 memcpy(copy, key, size);
1010 return (yaca_key_h)copy;
1013 static yaca_key_h key_copy_evp(const struct yaca_key_evp_s *key)
1016 assert(key != NULL);
1018 struct yaca_key_evp_s *copy = NULL;
1019 ret = yaca_zalloc(sizeof(struct yaca_key_evp_s), (void**)©);
1020 if (ret != YACA_ERROR_NONE)
1021 return YACA_KEY_NULL;
1023 /* raise the refcount */
1024 CRYPTO_add(&key->evp->references, 1, CRYPTO_LOCK_EVP_PKEY);
1026 copy->key.type = key->key.type;
1027 copy->evp = key->evp;
1028 return (yaca_key_h)copy;
1031 yaca_key_h key_copy(const yaca_key_h key)
1033 struct yaca_key_simple_s *simple = key_get_simple(key);
1034 struct yaca_key_evp_s *evp = key_get_evp(key);
1037 return key_copy_simple(simple);
1038 else if (evp != NULL)
1039 return key_copy_evp(evp);
1041 return YACA_KEY_NULL;
1044 API int yaca_key_get_type(const yaca_key_h key, yaca_key_type_e *key_type)
1046 const struct yaca_key_s *lkey = (const struct yaca_key_s *)key;
1048 if (lkey == NULL || key_type == NULL)
1049 return YACA_ERROR_INVALID_PARAMETER;
1051 *key_type = lkey->type;
1052 return YACA_ERROR_NONE;
1055 API int yaca_key_get_bit_length(const yaca_key_h key, size_t *key_bit_len)
1057 const struct yaca_key_simple_s *simple_key = key_get_simple(key);
1058 const struct yaca_key_evp_s *evp_key = key_get_evp(key);
1060 if (key_bit_len == NULL)
1061 return YACA_ERROR_INVALID_PARAMETER;
1063 if (simple_key != NULL) {
1064 *key_bit_len = simple_key->bit_len;
1065 return YACA_ERROR_NONE;
1068 if (evp_key != NULL) {
1071 // TODO: handle ECC keys when they're implemented
1072 ret = EVP_PKEY_bits(evp_key->evp);
1074 ret = YACA_ERROR_INTERNAL;
1080 return YACA_ERROR_NONE;
1083 return YACA_ERROR_INVALID_PARAMETER;
1086 API int yaca_key_import(yaca_key_type_e key_type,
1087 const char *password,
1092 if (key == NULL || data == NULL || data_len == 0)
1093 return YACA_ERROR_INVALID_PARAMETER;
1095 /* allow an empty password, OpenSSL returns an error with "" */
1096 if (password != NULL && password[0] == '\0')
1100 case YACA_KEY_TYPE_SYMMETRIC:
1101 case YACA_KEY_TYPE_DES:
1102 case YACA_KEY_TYPE_IV:
1103 if (password != NULL)
1104 return YACA_ERROR_INVALID_PARAMETER;
1105 return import_simple(key, key_type, data, data_len);
1106 case YACA_KEY_TYPE_RSA_PUB:
1107 case YACA_KEY_TYPE_RSA_PRIV:
1108 case YACA_KEY_TYPE_DSA_PUB:
1109 case YACA_KEY_TYPE_DSA_PRIV:
1110 return import_evp(key, key_type, password, data, data_len);
1111 case YACA_KEY_TYPE_DH_PUB:
1112 case YACA_KEY_TYPE_DH_PRIV:
1113 case YACA_KEY_TYPE_EC_PUB:
1114 case YACA_KEY_TYPE_EC_PRIV:
1115 //TODO NOT_IMPLEMENTED
1117 return YACA_ERROR_INVALID_PARAMETER;
1121 API int yaca_key_export(const yaca_key_h key,
1122 yaca_key_format_e key_fmt,
1123 yaca_key_file_format_e key_file_fmt,
1124 const char *password,
1128 struct yaca_key_simple_s *simple_key = key_get_simple(key);
1129 struct yaca_key_evp_s *evp_key = key_get_evp(key);
1131 if (data == NULL || data_len == NULL)
1132 return YACA_ERROR_INVALID_PARAMETER;
1134 /* allow an empty password, OpenSSL returns an error with "" */
1135 if (password != NULL && password[0] == '\0')
1138 if (password != NULL && simple_key != NULL)
1139 return YACA_ERROR_INVALID_PARAMETER;
1141 if (key_fmt == YACA_KEY_FORMAT_DEFAULT &&
1142 key_file_fmt == YACA_KEY_FILE_FORMAT_RAW &&
1144 return export_simple_raw(simple_key, data, data_len);
1146 if (key_fmt == YACA_KEY_FORMAT_DEFAULT &&
1147 key_file_fmt == YACA_KEY_FILE_FORMAT_BASE64 &&
1149 return export_simple_base64(simple_key, data, data_len);
1151 if (evp_key != NULL)
1152 return export_evp(evp_key, key_fmt, key_file_fmt,
1153 password, data, data_len);
1155 return YACA_ERROR_INVALID_PARAMETER;
1158 API int yaca_key_generate(yaca_key_type_e key_type,
1163 struct yaca_key_simple_s *nk_simple = NULL;
1164 struct yaca_key_evp_s *nk_evp = NULL;
1166 if (key == NULL || key_bit_len == 0 || key_bit_len % 8 != 0)
1167 return YACA_ERROR_INVALID_PARAMETER;
1170 case YACA_KEY_TYPE_SYMMETRIC:
1171 case YACA_KEY_TYPE_IV:
1172 ret = generate_simple(&nk_simple, key_bit_len);
1174 case YACA_KEY_TYPE_DES:
1175 ret = generate_simple_des(&nk_simple, key_bit_len);
1177 case YACA_KEY_TYPE_RSA_PRIV:
1178 case YACA_KEY_TYPE_DSA_PRIV:
1179 case YACA_KEY_TYPE_DH_PRIV:
1180 ret = generate_evp(&nk_evp, key_type, key_bit_len);
1182 case YACA_KEY_TYPE_EC_PRIV:
1183 //TODO NOT_IMPLEMENTED
1185 return YACA_ERROR_INVALID_PARAMETER;
1188 if (ret != YACA_ERROR_NONE)
1191 if (nk_simple != NULL) {
1192 nk_simple->key.type = key_type;
1193 *key = (yaca_key_h)nk_simple;
1194 } else if (nk_evp != NULL) {
1195 nk_evp->key.type = key_type;
1196 *key = (yaca_key_h)nk_evp;
1199 return YACA_ERROR_NONE;
1203 API int yaca_key_extract_public(const yaca_key_h prv_key, yaca_key_h *pub_key)
1206 struct yaca_key_evp_s *evp_key = key_get_evp(prv_key);
1207 struct yaca_key_evp_s *nk;
1209 EVP_PKEY *pkey = NULL;
1211 if (prv_key == YACA_KEY_NULL || evp_key == NULL || pub_key == NULL)
1212 return YACA_ERROR_INVALID_PARAMETER;
1214 ret = yaca_zalloc(sizeof(struct yaca_key_evp_s), (void**)&nk);
1215 if (ret != YACA_ERROR_NONE)
1218 mem = BIO_new(BIO_s_mem());
1220 ret = YACA_ERROR_INTERNAL;
1225 ret = i2d_PUBKEY_bio(mem, evp_key->evp);
1227 ret = YACA_ERROR_INTERNAL;
1232 pkey = d2i_PUBKEY_bio(mem, NULL);
1234 ret = YACA_ERROR_INTERNAL;
1242 switch (prv_key->type) {
1243 case YACA_KEY_TYPE_RSA_PRIV:
1244 nk->key.type = YACA_KEY_TYPE_RSA_PUB;
1246 case YACA_KEY_TYPE_DSA_PRIV:
1247 nk->key.type = YACA_KEY_TYPE_DSA_PUB;
1249 case YACA_KEY_TYPE_DH_PRIV:
1250 nk->key.type = YACA_KEY_TYPE_DH_PUB;
1252 case YACA_KEY_TYPE_EC_PRIV:
1253 nk->key.type = YACA_KEY_TYPE_EC_PUB;
1256 ret = YACA_ERROR_INVALID_PARAMETER;
1262 *pub_key = (yaca_key_h)nk;
1264 ret = YACA_ERROR_NONE;
1267 EVP_PKEY_free(pkey);
1274 API void yaca_key_destroy(yaca_key_h key)
1276 struct yaca_key_simple_s *simple_key = key_get_simple(key);
1277 struct yaca_key_evp_s *evp_key = key_get_evp(key);
1279 if (simple_key != NULL)
1280 yaca_free(simple_key);
1282 if (evp_key != NULL) {
1283 EVP_PKEY_free(evp_key->evp);
1288 API int yaca_key_derive_dh(const yaca_key_h prv_key,
1289 const yaca_key_h pub_key,
1290 yaca_key_h *sym_key)
1293 struct yaca_key_evp_s *lprv_key = key_get_evp(prv_key);
1294 struct yaca_key_evp_s *lpub_key = key_get_evp(pub_key);
1295 struct yaca_key_simple_s *nk = NULL;
1299 if (lprv_key == NULL || lpub_key == NULL || sym_key == NULL ||
1300 (!(lprv_key->key.type == YACA_KEY_TYPE_DH_PRIV &&
1301 lpub_key->key.type == YACA_KEY_TYPE_DH_PUB)
1303 !(lprv_key->key.type == YACA_KEY_TYPE_EC_PRIV &&
1304 lpub_key->key.type == YACA_KEY_TYPE_EC_PUB)))
1305 return YACA_ERROR_INVALID_PARAMETER;
1307 ctx = EVP_PKEY_CTX_new(lprv_key->evp, NULL);
1309 ret = YACA_ERROR_INTERNAL;
1314 ret = EVP_PKEY_derive_init(ctx);
1316 ret = YACA_ERROR_INTERNAL;
1321 ret = EVP_PKEY_derive_set_peer(ctx, lpub_key->evp);
1323 ret = YACA_ERROR_INTERNAL;
1328 ret = EVP_PKEY_derive(ctx, NULL, &nk_len);
1330 ret = YACA_ERROR_INTERNAL;
1335 if (nk_len == 0 || nk_len > SIZE_MAX / 8) {
1336 ret = YACA_ERROR_INVALID_PARAMETER;
1340 ret = yaca_zalloc(sizeof(struct yaca_key_simple_s) + nk_len, (void**)&nk);
1341 if (ret != YACA_ERROR_NONE)
1344 ret = EVP_PKEY_derive(ctx, (unsigned char*)nk->d, &nk_len);
1346 ret = YACA_ERROR_INTERNAL;
1351 nk->bit_len = nk_len * 8;
1352 nk->key.type = YACA_KEY_TYPE_SYMMETRIC;
1353 *sym_key = (yaca_key_h)nk;
1355 ret = YACA_ERROR_NONE;
1358 EVP_PKEY_CTX_free(ctx);
1363 API int yaca_key_derive_pbkdf2(const char *password,
1367 yaca_digest_algorithm_e algo,
1372 struct yaca_key_simple_s *nk;
1373 size_t key_byte_len = key_bit_len / 8;
1376 if (password == NULL ||
1377 (salt == NULL && salt_len > 0) || (salt != NULL && salt_len == 0) ||
1378 iterations == 0 || key_bit_len == 0 || key == NULL)
1379 return YACA_ERROR_INVALID_PARAMETER;
1381 if (key_bit_len % 8) /* Key length must be multiple of 8-bit_len */
1382 return YACA_ERROR_INVALID_PARAMETER;
1384 if (iterations > INT_MAX) /* OpenSSL limitation */
1385 return YACA_ERROR_INVALID_PARAMETER;
1387 ret = digest_get_algorithm(algo, &md);
1388 if (ret != YACA_ERROR_NONE)
1391 ret = yaca_zalloc(sizeof(struct yaca_key_simple_s) + key_byte_len, (void**)&nk);
1392 if (ret != YACA_ERROR_NONE)
1395 nk->bit_len = key_bit_len;
1396 nk->key.type = YACA_KEY_TYPE_SYMMETRIC; // TODO: how to handle other keys?
1398 ret = PKCS5_PBKDF2_HMAC(password, -1, (const unsigned char*)salt,
1399 salt_len, iterations, md, key_byte_len,
1400 (unsigned char*)nk->d);
1402 ret = YACA_ERROR_INTERNAL;
1407 *key = (yaca_key_h)nk;
1409 ret = YACA_ERROR_NONE;