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>
36 #include <yaca_crypto.h>
37 #include <yaca_error.h>
42 /* This callback only exists to block the default OpenSSL one and
43 * allow us to check for a proper error code when the key is encrypted
45 int password_dummy_cb(char *buf, int size, int rwflag, void *u)
47 const char empty[] = "";
49 memcpy(buf, empty, sizeof(empty));
54 int base64_decode_length(const char *data, size_t data_len, size_t *len)
57 assert(data_len != 0);
61 size_t tmp_len = data_len;
63 if (data_len % 4 != 0)
64 return YACA_ERROR_INVALID_PARAMETER;
66 if (data[tmp_len - 1] == '=') {
68 if (data[tmp_len - 2] == '=')
72 *len = data_len / 4 * 3 - padded;
73 return YACA_ERROR_NONE;
76 #define TMP_BUF_LEN 512
78 int base64_decode(const char *data, size_t data_len, BIO **output)
81 assert(data_len != 0);
82 assert(output != NULL);
88 char tmpbuf[TMP_BUF_LEN];
93 /* This is because of BIO_new_mem_buf() having its length param typed int */
94 if (data_len > INT_MAX)
95 return YACA_ERROR_INVALID_PARAMETER;
97 /* First phase of correctness checking, calculate expected output length */
98 ret = base64_decode_length(data, data_len, &b64_len);
99 if (ret != YACA_ERROR_NONE)
102 b64 = BIO_new(BIO_f_base64());
104 ret = YACA_ERROR_INTERNAL;
109 src = BIO_new_mem_buf(data, data_len);
111 ret = YACA_ERROR_INTERNAL;
118 dst = BIO_new(BIO_s_mem());
120 ret = YACA_ERROR_INTERNAL;
125 BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
129 ret = BIO_read(b64, tmpbuf, TMP_BUF_LEN);
131 ret = YACA_ERROR_INTERNAL;
136 if (ret == YACA_ERROR_NONE)
139 if (BIO_write(dst, tmpbuf, ret) != ret) {
140 ret = YACA_ERROR_INTERNAL;
148 /* Check wether the length of the decoded data is what we expected */
149 out_len = BIO_get_mem_data(dst, &out);
151 ret = YACA_ERROR_INTERNAL;
155 if ((size_t)out_len != b64_len) {
156 ret = YACA_ERROR_INVALID_PARAMETER;
162 ret = YACA_ERROR_NONE;
171 int import_simple(yaca_key_h *key,
172 yaca_key_type_e key_type,
177 assert(data != NULL);
178 assert(data_len != 0);
182 const char *key_data;
184 struct yaca_key_simple_s *nk = NULL;
186 ret = base64_decode(data, data_len, &decoded);
187 if (ret == YACA_ERROR_NONE) {
188 /* Conversion successfull, get the BASE64 */
189 long len = BIO_get_mem_data(decoded, &key_data);
190 if (len <= 0 || key_data == NULL) {
191 ret = YACA_ERROR_INTERNAL;
196 } else if (ret == YACA_ERROR_INVALID_PARAMETER) {
197 /* This was not BASE64 or it was corrupted, treat as RAW */
198 key_data_len = data_len;
201 /* Some other, possibly unrecoverable error, give up */
205 /* key_bits has to fit in size_t */
206 if (key_data_len > SIZE_MAX / 8) {
207 ret = YACA_ERROR_INVALID_PARAMETER;
211 /* DES key length verification */
212 if (key_type == YACA_KEY_TYPE_DES) {
213 size_t key_bits = key_data_len * 8;
214 if (key_bits != YACA_KEY_LENGTH_UNSAFE_64BIT &&
215 key_bits != YACA_KEY_LENGTH_UNSAFE_128BIT &&
216 key_bits != YACA_KEY_LENGTH_192BIT) {
217 ret = YACA_ERROR_INVALID_PARAMETER;
222 ret = yaca_zalloc(sizeof(struct yaca_key_simple_s) + key_data_len, (void**)&nk);
223 if (ret != YACA_ERROR_NONE)
226 memcpy(nk->d, key_data, key_data_len);
227 nk->bits = key_data_len * 8;
228 nk->key.type = key_type;
230 *key = (yaca_key_h)nk;
232 ret = YACA_ERROR_NONE;
235 BIO_free_all(decoded);
240 bool check_import_wrong_pass()
242 unsigned long err = ERR_peek_error();
243 unsigned long err_bad_password_1 = ERR_PACK(ERR_LIB_PEM, PEM_F_PEM_DO_HEADER, PEM_R_BAD_DECRYPT);
244 unsigned long err_bad_password_2 = ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_DECRYPTFINAL_EX, EVP_R_BAD_DECRYPT);
246 if (err == err_bad_password_1 || err == err_bad_password_2)
252 int import_evp(yaca_key_h *key,
253 yaca_key_type_e key_type,
254 const char *password,
259 assert(password == NULL || password[0] != '\0');
260 assert(data != NULL);
261 assert(data_len != 0);
265 EVP_PKEY *pkey = NULL;
266 bool wrong_pass = false;
267 pem_password_cb *cb = NULL;
269 yaca_key_type_e type;
270 struct yaca_key_evp_s *nk = NULL;
272 /* Neither PEM nor DER will ever be shorter then 4 bytes (12 seems
273 * to be minimum for DER, much more for PEM). This is just to make
274 * sure we have at least 4 bytes for strncmp() below.
277 return YACA_ERROR_INVALID_PARAMETER;
279 /* This is because of BIO_new_mem_buf() having its length param typed int */
280 if (data_len > INT_MAX)
281 return YACA_ERROR_INVALID_PARAMETER;
283 src = BIO_new_mem_buf(data, data_len);
285 ERROR_DUMP(YACA_ERROR_INTERNAL);
286 return YACA_ERROR_INTERNAL;
289 /* Block the default OpenSSL password callback */
290 if (password == NULL)
291 cb = password_dummy_cb;
294 if (strncmp("----", data, 4) == 0) {
295 if (pkey == NULL && !wrong_pass) {
297 pkey = PEM_read_bio_PrivateKey(src, NULL, cb, (void*)password);
298 if (check_import_wrong_pass())
304 if (pkey == NULL && !wrong_pass) {
306 pkey = PEM_read_bio_PUBKEY(src, NULL, cb, (void*)password);
307 if (check_import_wrong_pass())
313 if (pkey == NULL && !wrong_pass) {
315 X509 *x509 = PEM_read_bio_X509(src, NULL, cb, (void*)password);
316 if (check_import_wrong_pass())
319 pkey = X509_get_pubkey(x509);
327 if (pkey == NULL && !wrong_pass) {
329 pkey = d2i_PKCS8PrivateKey_bio(src, NULL, cb, (void*)password);
330 if (check_import_wrong_pass())
336 if (pkey == NULL && !wrong_pass) {
338 pkey = d2i_PrivateKey_bio(src, NULL);
343 if (pkey == NULL && !wrong_pass) {
345 pkey = d2i_PUBKEY_bio(src, NULL);
354 return YACA_ERROR_INVALID_PASSWORD;
357 return YACA_ERROR_INVALID_PARAMETER;
359 switch (EVP_PKEY_type(pkey->type)) {
361 type = private ? YACA_KEY_TYPE_RSA_PRIV : YACA_KEY_TYPE_RSA_PUB;
365 type = private ? YACA_KEY_TYPE_DSA_PRIV : YACA_KEY_TYPE_DSA_PUB;
369 // type = private ? YACA_KEY_TYPE_EC_PRIV : YACA_KEY_TYPE_EC_PUB;
373 ret = YACA_ERROR_INVALID_PARAMETER;
377 if (type != key_type) {
378 ret = YACA_ERROR_INVALID_PARAMETER;
382 ret = yaca_zalloc(sizeof(struct yaca_key_evp_s), (void**)&nk);
383 if (ret != YACA_ERROR_NONE)
387 *key = (yaca_key_h)nk;
391 ret = YACA_ERROR_NONE;
399 int export_simple_raw(struct yaca_key_simple_s *simple_key,
404 assert(simple_key != NULL);
405 assert(data != NULL);
406 assert(data_len != NULL);
408 size_t key_len = simple_key->bits / 8;
412 ret = yaca_malloc(key_len, (void**)data);
413 if (ret != YACA_ERROR_NONE)
416 memcpy(*data, simple_key->d, key_len);
419 return YACA_ERROR_NONE;
422 int export_simple_base64(struct yaca_key_simple_s *simple_key,
426 assert(simple_key != NULL);
427 assert(data != NULL);
428 assert(data_len != NULL);
431 size_t key_len = simple_key->bits / 8;
437 b64 = BIO_new(BIO_f_base64());
439 ret = YACA_ERROR_INTERNAL;
444 mem = BIO_new(BIO_s_mem());
446 ret = YACA_ERROR_INTERNAL;
452 BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
454 ret = BIO_write(b64, simple_key->d, key_len);
455 if (ret <= 0 || (unsigned)ret != key_len) {
456 ret = YACA_ERROR_INTERNAL;
461 ret = BIO_flush(b64);
463 ret = YACA_ERROR_INTERNAL;
468 bio_data_len = BIO_get_mem_data(mem, &bio_data);
469 if (bio_data_len <= 0) {
470 ret = YACA_ERROR_INTERNAL;
475 ret = yaca_malloc(bio_data_len, (void**)data);
476 if (ret != YACA_ERROR_NONE)
479 memcpy(*data, bio_data, bio_data_len);
480 *data_len = bio_data_len;
481 ret = YACA_ERROR_NONE;
489 int export_evp_default_bio(struct yaca_key_evp_s *evp_key,
490 yaca_key_file_format_e key_file_fmt,
491 const char *password,
494 assert(evp_key != NULL);
495 assert(password == NULL || password[0] != '\0');
499 const EVP_CIPHER *enc = NULL;
501 if (password != NULL)
502 enc = EVP_aes_256_cbc();
504 switch (key_file_fmt) {
506 case YACA_KEY_FILE_FORMAT_PEM:
507 switch (evp_key->key.type) {
509 case YACA_KEY_TYPE_RSA_PRIV:
510 ret = PEM_write_bio_RSAPrivateKey(mem, EVP_PKEY_get0(evp_key->evp),
511 enc, NULL, 0, NULL, (void*)password);
513 case YACA_KEY_TYPE_DSA_PRIV:
514 ret = PEM_write_bio_DSAPrivateKey(mem, EVP_PKEY_get0(evp_key->evp),
515 enc, NULL, 0, NULL, (void*)password);
518 case YACA_KEY_TYPE_RSA_PUB:
519 case YACA_KEY_TYPE_DSA_PUB:
520 ret = PEM_write_bio_PUBKEY(mem, evp_key->evp);
523 // case YACA_KEY_TYPE_DH_PRIV:
524 // case YACA_KEY_TYPE_DH_PUB:
525 // case YACA_KEY_TYPE_EC_PRIV:
526 // case YACA_KEY_TYPE_EC_PUB:
527 // TODO NOT_IMPLEMENTED
529 return YACA_ERROR_INVALID_PARAMETER;
534 case YACA_KEY_FILE_FORMAT_DER:
535 switch (evp_key->key.type) {
537 case YACA_KEY_TYPE_RSA_PRIV:
538 ret = i2d_RSAPrivateKey_bio(mem, EVP_PKEY_get0(evp_key->evp));
541 case YACA_KEY_TYPE_DSA_PRIV:
542 ret = i2d_DSAPrivateKey_bio(mem, EVP_PKEY_get0(evp_key->evp));
545 case YACA_KEY_TYPE_RSA_PUB:
546 case YACA_KEY_TYPE_DSA_PUB:
547 ret = i2d_PUBKEY_bio(mem, evp_key->evp);
550 // case YACA_KEY_TYPE_DH_PRIV:
551 // case YACA_KEY_TYPE_DH_PUB:
552 // case YACA_KEY_TYPE_EC_PRIV:
553 // case YACA_KEY_TYPE_EC_PUB:
554 // TODO NOT_IMPLEMENTED
556 return YACA_ERROR_INVALID_PARAMETER;
562 return YACA_ERROR_INVALID_PARAMETER;
566 ret = YACA_ERROR_INTERNAL;
571 return YACA_ERROR_NONE;
574 int export_evp_pkcs8_bio(struct yaca_key_evp_s *evp_key,
575 yaca_key_file_format_e key_file_fmt,
576 const char *password,
579 assert(evp_key != NULL);
580 assert(password == NULL || password[0] != '\0');
586 if (password != NULL)
587 nid = NID_pbeWithMD5AndDES_CBC;
589 switch (key_file_fmt) {
591 case YACA_KEY_FILE_FORMAT_PEM:
592 switch (evp_key->key.type) {
594 case YACA_KEY_TYPE_RSA_PRIV:
595 case YACA_KEY_TYPE_DSA_PRIV:
596 ret = PEM_write_bio_PKCS8PrivateKey_nid(mem, evp_key->evp, nid,
597 NULL, 0, NULL, (void*)password);
599 // case YACA_KEY_TYPE_DH_PRIV:
600 // case YACA_KEY_TYPE_EC_PRIV:
601 // TODO NOT_IMPLEMENTED
603 /* Public keys are not supported by PKCS8 */
604 return YACA_ERROR_INVALID_PARAMETER;
609 case YACA_KEY_FILE_FORMAT_DER:
610 switch (evp_key->key.type) {
612 case YACA_KEY_TYPE_RSA_PRIV:
613 case YACA_KEY_TYPE_DSA_PRIV:
614 ret = i2d_PKCS8PrivateKey_nid_bio(mem, evp_key->evp, nid,
615 NULL, 0, NULL, (void*)password);
618 // case YACA_KEY_TYPE_DH_PRIV:
619 // case YACA_KEY_TYPE_EC_PRIV:
620 // TODO NOT_IMPLEMENTED
622 /* Public keys are not supported by PKCS8 */
623 return YACA_ERROR_INVALID_PARAMETER;
629 return YACA_ERROR_INVALID_PARAMETER;
633 ret = YACA_ERROR_INTERNAL;
638 return YACA_ERROR_NONE;
641 int export_evp(struct yaca_key_evp_s *evp_key,
642 yaca_key_format_e key_fmt,
643 yaca_key_file_format_e key_file_fmt,
644 const char *password,
648 assert(evp_key != NULL);
649 assert(password == NULL || password[0] != '\0');
650 assert(data != NULL);
651 assert(data_len != NULL);
653 int ret = YACA_ERROR_NONE;
658 mem = BIO_new(BIO_s_mem());
660 ret = YACA_ERROR_INTERNAL;
666 case YACA_KEY_FORMAT_DEFAULT:
667 ret = export_evp_default_bio(evp_key, key_file_fmt, password, mem);
669 case YACA_KEY_FORMAT_PKCS8:
670 ret = export_evp_pkcs8_bio(evp_key, key_file_fmt, password, mem);
673 ret = YACA_ERROR_INVALID_PARAMETER;
677 if (ret != YACA_ERROR_NONE)
680 ret = BIO_flush(mem);
682 ret = YACA_ERROR_INTERNAL;
687 bio_data_len = BIO_get_mem_data(mem, &bio_data);
688 if (bio_data_len <= 0) {
689 ret = YACA_ERROR_INTERNAL;
694 ret = yaca_malloc(bio_data_len, (void**)data);
695 if (ret != YACA_ERROR_NONE)
698 memcpy(*data, bio_data, bio_data_len);
699 *data_len = bio_data_len;
700 ret = YACA_ERROR_NONE;
708 int gen_simple(struct yaca_key_simple_s **out, size_t key_bits)
713 struct yaca_key_simple_s *nk;
714 size_t key_byte_len = key_bits / 8;
716 ret = yaca_zalloc(sizeof(struct yaca_key_simple_s) + key_byte_len, (void**)&nk);
717 if (ret != YACA_ERROR_NONE)
722 ret = yaca_randomize_bytes(nk->d, key_byte_len);
723 if (ret != YACA_ERROR_NONE)
727 return YACA_ERROR_NONE;
730 int gen_simple_des(struct yaca_key_simple_s **out, size_t key_bits)
734 if (key_bits != YACA_KEY_LENGTH_UNSAFE_64BIT &&
735 key_bits != YACA_KEY_LENGTH_UNSAFE_128BIT &&
736 key_bits != YACA_KEY_LENGTH_192BIT)
737 return YACA_ERROR_INVALID_PARAMETER;
740 struct yaca_key_simple_s *nk;
741 size_t key_byte_len = key_bits / 8;
743 ret = yaca_zalloc(sizeof(struct yaca_key_simple_s) + key_byte_len, (void**)&nk);
744 if (ret != YACA_ERROR_NONE)
747 DES_cblock *des_key = (DES_cblock*)nk->d;
748 if (key_byte_len >= 8) {
749 ret = DES_random_key(des_key);
751 ret = YACA_ERROR_INTERNAL;
756 if (key_byte_len >= 16) {
757 ret = DES_random_key(des_key + 1);
759 ret = YACA_ERROR_INTERNAL;
764 if (key_byte_len >= 24) {
765 ret = DES_random_key(des_key + 2);
767 ret = YACA_ERROR_INTERNAL;
776 ret = YACA_ERROR_NONE;
784 // TODO: consider merging gen_evp_*, they share awful lot of common code
785 int gen_evp_rsa(struct yaca_key_evp_s **out, size_t key_bits)
788 assert(key_bits > 0);
789 assert(key_bits % 8 == 0);
792 struct yaca_key_evp_s *nk;
794 EVP_PKEY *pkey = NULL;
796 ret = yaca_zalloc(sizeof(struct yaca_key_evp_s), (void**)&nk);
797 if (ret != YACA_ERROR_NONE)
800 ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL);
802 ret = YACA_ERROR_INTERNAL;
807 ret = EVP_PKEY_keygen_init(ctx);
809 ret = YACA_ERROR_INTERNAL;
814 ret = EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, key_bits);
816 ret = ERROR_HANDLE();
820 ret = EVP_PKEY_keygen(ctx, &pkey);
822 ret = YACA_ERROR_INTERNAL;
832 ret = YACA_ERROR_NONE;
835 EVP_PKEY_CTX_free(ctx);
841 int gen_evp_dsa(struct yaca_key_evp_s **out, size_t key_bits)
844 assert(key_bits > 0);
845 assert(key_bits % 8 == 0);
847 /* Openssl generates 512-bit key for key lengths smaller than 512. It also
848 * rounds key size to multiplication of 64. */
849 if (key_bits < 512 || key_bits % 64 != 0)
850 return YACA_ERROR_INVALID_PARAMETER;
853 struct yaca_key_evp_s *nk;
854 EVP_PKEY_CTX *pctx = NULL;
855 EVP_PKEY_CTX *kctx = NULL;
856 EVP_PKEY *pkey = NULL;
857 EVP_PKEY *params = NULL;
859 ret = yaca_zalloc(sizeof(struct yaca_key_evp_s), (void**)&nk);
860 if (ret != YACA_ERROR_NONE)
863 pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_DSA, NULL);
865 ret = YACA_ERROR_INTERNAL;
870 ret = EVP_PKEY_paramgen_init(pctx);
872 ret = YACA_ERROR_INTERNAL;
877 ret = EVP_PKEY_CTX_set_dsa_paramgen_bits(pctx, key_bits);
879 ret = ERROR_HANDLE();
883 ret = EVP_PKEY_paramgen(pctx, ¶ms);
885 ret = YACA_ERROR_INTERNAL;
890 kctx = EVP_PKEY_CTX_new(params, NULL);
892 ret = YACA_ERROR_INTERNAL;
897 ret = EVP_PKEY_keygen_init(kctx);
899 ret = YACA_ERROR_INTERNAL;
904 ret = EVP_PKEY_keygen(kctx, &pkey);
906 ret = YACA_ERROR_INTERNAL;
916 ret = YACA_ERROR_NONE;
919 EVP_PKEY_CTX_free(kctx);
920 EVP_PKEY_free(params);
921 EVP_PKEY_CTX_free(pctx);
927 struct yaca_key_simple_s *key_get_simple(const yaca_key_h key)
929 struct yaca_key_simple_s *k;
931 if (key == YACA_KEY_NULL)
935 case YACA_KEY_TYPE_SYMMETRIC:
936 case YACA_KEY_TYPE_DES:
937 case YACA_KEY_TYPE_IV:
938 k = (struct yaca_key_simple_s *)key;
941 assert(k->bits != 0);
942 assert(k->bits % 8 == 0);
943 assert(k->d != NULL);
951 struct yaca_key_evp_s *key_get_evp(const yaca_key_h key)
953 struct yaca_key_evp_s *k;
955 if (key == YACA_KEY_NULL)
959 case YACA_KEY_TYPE_RSA_PUB:
960 case YACA_KEY_TYPE_RSA_PRIV:
961 case YACA_KEY_TYPE_DSA_PUB:
962 case YACA_KEY_TYPE_DSA_PRIV:
963 k = (struct yaca_key_evp_s *)key;
966 assert(k->evp != NULL);
974 API int yaca_key_get_type(const yaca_key_h key, yaca_key_type_e *key_type)
976 const struct yaca_key_s *lkey = (const struct yaca_key_s *)key;
978 if (lkey == NULL || key_type == NULL)
979 return YACA_ERROR_INVALID_PARAMETER;
981 *key_type = lkey->type;
982 return YACA_ERROR_NONE;
985 API int yaca_key_get_bit_length(const yaca_key_h key, size_t *key_bit_len)
987 const struct yaca_key_simple_s *simple_key = key_get_simple(key);
988 const struct yaca_key_evp_s *evp_key = key_get_evp(key);
990 if (key_bit_len == NULL)
991 return YACA_ERROR_INVALID_PARAMETER;
993 if (simple_key != NULL) {
994 *key_bit_len = simple_key->bits;
995 return YACA_ERROR_NONE;
998 if (evp_key != NULL) {
1001 // TODO: handle ECC keys when they're implemented
1002 ret = EVP_PKEY_bits(evp_key->evp);
1004 ret = YACA_ERROR_INTERNAL;
1010 return YACA_ERROR_NONE;
1013 return YACA_ERROR_INVALID_PARAMETER;
1016 API int yaca_key_import(yaca_key_type_e key_type,
1017 const char *password,
1022 if (key == NULL || data == NULL || data_len == 0)
1023 return YACA_ERROR_INVALID_PARAMETER;
1025 /* allow an empty password, OpenSSL returns an error with "" */
1026 if (password != NULL && password[0] == '\0')
1030 case YACA_KEY_TYPE_SYMMETRIC:
1031 case YACA_KEY_TYPE_DES:
1032 case YACA_KEY_TYPE_IV:
1033 if (password != NULL)
1034 return YACA_ERROR_INVALID_PARAMETER;
1035 return import_simple(key, key_type, data, data_len);
1036 case YACA_KEY_TYPE_RSA_PUB:
1037 case YACA_KEY_TYPE_RSA_PRIV:
1038 case YACA_KEY_TYPE_DSA_PUB:
1039 case YACA_KEY_TYPE_DSA_PRIV:
1040 return import_evp(key, key_type, password, data, data_len);
1041 // case YACA_KEY_TYPE_DH_PUB:
1042 // case YACA_KEY_TYPE_DH_PRIV:
1043 // case YACA_KEY_TYPE_EC_PUB:
1044 // case YACA_KEY_TYPE_EC_PRIV:
1045 // TODO NOT_IMPLEMENTED
1047 return YACA_ERROR_INVALID_PARAMETER;
1051 API int yaca_key_export(const yaca_key_h key,
1052 yaca_key_format_e key_fmt,
1053 yaca_key_file_format_e key_file_fmt,
1054 const char *password,
1058 struct yaca_key_simple_s *simple_key = key_get_simple(key);
1059 struct yaca_key_evp_s *evp_key = key_get_evp(key);
1061 if (data == NULL || data_len == NULL)
1062 return YACA_ERROR_INVALID_PARAMETER;
1064 /* allow an empty password, OpenSSL returns an error with "" */
1065 if (password != NULL && password[0] == '\0')
1068 if (password != NULL && simple_key != NULL)
1069 return YACA_ERROR_INVALID_PARAMETER;
1071 if (key_fmt == YACA_KEY_FORMAT_DEFAULT &&
1072 key_file_fmt == YACA_KEY_FILE_FORMAT_RAW &&
1074 return export_simple_raw(simple_key, data, data_len);
1076 if (key_fmt == YACA_KEY_FORMAT_DEFAULT &&
1077 key_file_fmt == YACA_KEY_FILE_FORMAT_BASE64 &&
1079 return export_simple_base64(simple_key, data, data_len);
1081 if (evp_key != NULL)
1082 return export_evp(evp_key, key_fmt, key_file_fmt,
1083 password, data, data_len);
1085 return YACA_ERROR_INVALID_PARAMETER;
1088 API int yaca_key_generate(yaca_key_type_e key_type,
1093 struct yaca_key_simple_s *nk_simple = NULL;
1094 struct yaca_key_evp_s *nk_evp = NULL;
1096 if (key == NULL || key_bit_len == 0 || key_bit_len % 8 != 0)
1097 return YACA_ERROR_INVALID_PARAMETER;
1100 case YACA_KEY_TYPE_SYMMETRIC:
1101 case YACA_KEY_TYPE_IV:
1102 ret = gen_simple(&nk_simple, key_bit_len);
1104 case YACA_KEY_TYPE_DES:
1105 ret = gen_simple_des(&nk_simple, key_bit_len);
1107 case YACA_KEY_TYPE_RSA_PRIV:
1108 ret = gen_evp_rsa(&nk_evp, key_bit_len);
1110 case YACA_KEY_TYPE_DSA_PRIV:
1111 ret = gen_evp_dsa(&nk_evp, key_bit_len);
1113 // case YACA_KEY_TYPE_DH_PRIV:
1114 // case YACA_KEY_TYPE_EC_PRIV:
1115 // TODO NOT_IMPLEMENTED
1117 return YACA_ERROR_INVALID_PARAMETER;
1120 if (ret != YACA_ERROR_NONE)
1123 if (nk_simple != NULL) {
1124 nk_simple->key.type = key_type;
1125 *key = (yaca_key_h)nk_simple;
1126 } else if (nk_evp != NULL) {
1127 nk_evp->key.type = key_type;
1128 *key = (yaca_key_h)nk_evp;
1131 return YACA_ERROR_NONE;
1135 API int yaca_key_extract_public(const yaca_key_h prv_key, yaca_key_h *pub_key)
1138 struct yaca_key_evp_s *evp_key = key_get_evp(prv_key);
1139 struct yaca_key_evp_s *nk;
1141 EVP_PKEY *pkey = NULL;
1143 if (prv_key == YACA_KEY_NULL || evp_key == NULL || pub_key == NULL)
1144 return YACA_ERROR_INVALID_PARAMETER;
1146 ret = yaca_zalloc(sizeof(struct yaca_key_evp_s), (void**)&nk);
1147 if (ret != YACA_ERROR_NONE)
1150 mem = BIO_new(BIO_s_mem());
1152 ret = YACA_ERROR_INTERNAL;
1157 ret = i2d_PUBKEY_bio(mem, evp_key->evp);
1159 ret = YACA_ERROR_INTERNAL;
1164 pkey = d2i_PUBKEY_bio(mem, NULL);
1166 ret = YACA_ERROR_INTERNAL;
1174 switch (prv_key->type) {
1175 case YACA_KEY_TYPE_RSA_PRIV:
1176 nk->key.type = YACA_KEY_TYPE_RSA_PUB;
1178 case YACA_KEY_TYPE_DSA_PRIV:
1179 nk->key.type = YACA_KEY_TYPE_DSA_PUB;
1181 // case YACA_KEY_TYPE_EC_PRIV:
1182 // nk->key.type = YACA_KEY_TYPE_EC_PUB;
1185 ret = YACA_ERROR_INVALID_PARAMETER;
1191 *pub_key = (yaca_key_h)nk;
1193 ret = YACA_ERROR_NONE;
1196 EVP_PKEY_free(pkey);
1203 API int yaca_key_destroy(yaca_key_h key)
1205 struct yaca_key_simple_s *simple_key = key_get_simple(key);
1206 struct yaca_key_evp_s *evp_key = key_get_evp(key);
1208 if (simple_key != NULL)
1209 yaca_free(simple_key);
1211 if (evp_key != NULL) {
1212 EVP_PKEY_free(evp_key->evp);
1216 return YACA_ERROR_NONE;
1219 API int yaca_key_derive_pbkdf2(const char *password,
1223 yaca_digest_algorithm_e algo,
1228 struct yaca_key_simple_s *nk;
1229 size_t key_byte_len = key_bit_len / 8;
1232 if (password == NULL || salt == NULL || salt_len == 0 ||
1233 iterations == 0 || key_bit_len == 0 || key == NULL)
1234 return YACA_ERROR_INVALID_PARAMETER;
1236 if (key_bit_len % 8) /* Key length must be multiple of 8-bits */
1237 return YACA_ERROR_INVALID_PARAMETER;
1239 ret = digest_get_algorithm(algo, &md);
1240 if (ret != YACA_ERROR_NONE)
1243 ret = yaca_zalloc(sizeof(struct yaca_key_simple_s) + key_byte_len, (void**)&nk);
1244 if (ret != YACA_ERROR_NONE)
1247 nk->bits = key_bit_len;
1248 nk->key.type = YACA_KEY_TYPE_SYMMETRIC; // TODO: how to handle other keys?
1250 ret = PKCS5_PBKDF2_HMAC(password, -1, (const unsigned char*)salt,
1251 salt_len, iterations, md, key_byte_len,
1252 (unsigned char*)nk->d);
1254 ret = YACA_ERROR_INTERNAL;
1259 *key = (yaca_key_h)nk;
1261 ret = YACA_ERROR_NONE;