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>
40 #include <yaca_types.h>
44 struct openssl_password_data {
45 bool password_requested;
49 int openssl_password_cb(char *buf, int size, UNUSED int rwflag, void *u)
51 struct openssl_password_data *cb_data = u;
53 if (cb_data->password == NULL)
56 size_t pass_len = strlen(cb_data->password);
58 if (pass_len > INT_MAX || (int)pass_len > size)
61 memcpy(buf, cb_data->password, pass_len);
62 cb_data->password_requested = true;
67 int openssl_password_cb_error(UNUSED char *buf, UNUSED int size, UNUSED int rwflag, UNUSED void *u)
76 {YACA_KEY_LENGTH_EC_PRIME192V1, NID_X9_62_prime192v1},
77 {YACA_KEY_LENGTH_EC_PRIME256V1, NID_X9_62_prime256v1},
78 {YACA_KEY_LENGTH_EC_SECP256K1, NID_secp256k1},
79 {YACA_KEY_LENGTH_EC_SECP384R1, NID_secp384r1},
80 {YACA_KEY_LENGTH_EC_SECP521R1, NID_secp521r1}
83 static const size_t EC_NID_PAIRS_SIZE = sizeof(EC_NID_PAIRS) / sizeof(EC_NID_PAIRS[0]);
89 yaca_key_type_e params;
90 } KEY_TYPES_PARAMS[] = {
91 {EVP_PKEY_RSA, YACA_KEY_TYPE_RSA_PRIV, YACA_KEY_TYPE_RSA_PUB, -1},
92 {EVP_PKEY_DSA, YACA_KEY_TYPE_DSA_PRIV, YACA_KEY_TYPE_DSA_PUB, YACA_KEY_TYPE_DSA_PARAMS},
93 {EVP_PKEY_DH, YACA_KEY_TYPE_DH_PRIV, YACA_KEY_TYPE_DH_PUB, YACA_KEY_TYPE_DH_PARAMS},
94 {EVP_PKEY_EC, YACA_KEY_TYPE_EC_PRIV, YACA_KEY_TYPE_EC_PUB, YACA_KEY_TYPE_EC_PARAMS},
95 /* The following line is only used to import DHX (RFC5114) keys/params.
96 * In all other cases DH is used. It has to be below the DH one so conversions from YACA
97 * internal types are prioritized to EVP_PKEY_DH which is what we want. */
98 {EVP_PKEY_DHX, YACA_KEY_TYPE_DH_PRIV, YACA_KEY_TYPE_DH_PUB, YACA_KEY_TYPE_DH_PARAMS}
101 static const size_t KEY_TYPES_PARAMS_SIZE = sizeof(KEY_TYPES_PARAMS) / sizeof(KEY_TYPES_PARAMS[0]);
103 #define CONVERT_TYPES_TEMPLATE(data, src_type, src, dst_type, dst) \
104 static int convert_##src##_to_##dst (src_type src, dst_type *dst) \
106 assert(dst != NULL); \
108 for (i = 0; i < data##_SIZE; ++i) \
109 if (data[i].src == src) { \
110 if (data[i].dst != (dst_type)-1) { \
111 *dst = data[i].dst; \
112 return YACA_ERROR_NONE; \
115 return YACA_ERROR_INVALID_PARAMETER; \
118 CONVERT_TYPES_TEMPLATE(EC_NID_PAIRS, int, nid, size_t, ec)
119 CONVERT_TYPES_TEMPLATE(EC_NID_PAIRS, size_t, ec, int, nid)
121 CONVERT_TYPES_TEMPLATE(KEY_TYPES_PARAMS, yaca_key_type_e, params, int, evp_id)
122 CONVERT_TYPES_TEMPLATE(KEY_TYPES_PARAMS, yaca_key_type_e, priv, int, evp_id)
123 CONVERT_TYPES_TEMPLATE(KEY_TYPES_PARAMS, yaca_key_type_e, params, yaca_key_type_e, priv)
124 CONVERT_TYPES_TEMPLATE(KEY_TYPES_PARAMS, int, evp_id, yaca_key_type_e, priv)
125 CONVERT_TYPES_TEMPLATE(KEY_TYPES_PARAMS, int, evp_id, yaca_key_type_e, pub)
126 CONVERT_TYPES_TEMPLATE(KEY_TYPES_PARAMS, int, evp_id, yaca_key_type_e, params)
128 int base64_decode_length(const char *data, size_t data_len, size_t *len)
130 assert(data != NULL);
131 assert(data_len != 0);
135 size_t tmp_len = data_len;
137 if (data_len % 4 != 0)
138 return YACA_ERROR_INVALID_PARAMETER;
140 if (data[tmp_len - 1] == '=') {
142 if (data[tmp_len - 2] == '=')
146 *len = data_len / 4 * 3 - padded;
147 return YACA_ERROR_NONE;
150 #define TMP_BUF_LEN 512
152 int base64_decode(const char *data, size_t data_len, BIO **output)
154 assert(data != NULL);
155 assert(data_len != 0);
156 assert(output != NULL);
162 char tmpbuf[TMP_BUF_LEN];
167 /* This is because of BIO_new_mem_buf() having its length param typed int */
168 if (data_len > INT_MAX)
169 return YACA_ERROR_INVALID_PARAMETER;
171 /* First phase of correctness checking, calculate expected output length */
172 ret = base64_decode_length(data, data_len, &b64_len);
173 if (ret != YACA_ERROR_NONE)
176 b64 = BIO_new(BIO_f_base64());
178 ret = YACA_ERROR_INTERNAL;
183 src = BIO_new_mem_buf(data, data_len);
185 ret = YACA_ERROR_INTERNAL;
192 dst = BIO_new(BIO_s_mem());
194 ret = YACA_ERROR_INTERNAL;
199 BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
203 ret = BIO_read(b64, tmpbuf, TMP_BUF_LEN);
205 ret = YACA_ERROR_INTERNAL;
210 if (ret == YACA_ERROR_NONE)
213 if (BIO_write(dst, tmpbuf, ret) != ret) {
214 ret = YACA_ERROR_INTERNAL;
222 /* Check wether the length of the decoded data is what we expected */
223 out_len = BIO_get_mem_data(dst, &out);
225 ret = YACA_ERROR_INTERNAL;
229 if ((size_t)out_len != b64_len) {
230 ret = YACA_ERROR_INVALID_PARAMETER;
236 ret = YACA_ERROR_NONE;
245 int import_simple(yaca_key_h *key,
246 yaca_key_type_e key_type,
251 assert(data != NULL);
252 assert(data_len != 0);
256 const char *key_data;
258 struct yaca_key_simple_s *nk = NULL;
260 ret = base64_decode(data, data_len, &decoded);
261 if (ret == YACA_ERROR_NONE) {
262 /* Conversion successfull, get the BASE64 */
263 long len = BIO_get_mem_data(decoded, &key_data);
264 if (len <= 0 || key_data == NULL) {
265 ret = YACA_ERROR_INTERNAL;
270 } else if (ret == YACA_ERROR_INVALID_PARAMETER) {
271 /* This was not BASE64 or it was corrupted, treat as RAW */
272 key_data_len = data_len;
275 /* Some other, possibly unrecoverable error, give up */
279 /* key_bit_len has to fit in size_t */
280 if (key_data_len > SIZE_MAX / 8) {
281 ret = YACA_ERROR_INVALID_PARAMETER;
285 /* DES key length verification */
286 if (key_type == YACA_KEY_TYPE_DES) {
287 size_t key_bit_len = key_data_len * 8;
288 if (key_bit_len != YACA_KEY_LENGTH_UNSAFE_64BIT &&
289 key_bit_len != YACA_KEY_LENGTH_UNSAFE_128BIT &&
290 key_bit_len != YACA_KEY_LENGTH_192BIT) {
291 ret = YACA_ERROR_INVALID_PARAMETER;
296 ret = yaca_zalloc(sizeof(struct yaca_key_simple_s) + key_data_len, (void**)&nk);
297 if (ret != YACA_ERROR_NONE)
300 memcpy(nk->d, key_data, key_data_len);
301 nk->bit_len = key_data_len * 8;
302 nk->key.type = key_type;
304 *key = (yaca_key_h)nk;
306 ret = YACA_ERROR_NONE;
309 BIO_free_all(decoded);
314 static EVP_PKEY *d2i_DSAparams_bio_helper(BIO *src)
319 EVP_PKEY *pkey = NULL;
321 dsa = d2i_DSAparams_bio(src, NULL);
325 pkey = EVP_PKEY_new();
329 if (EVP_PKEY_assign_DSA(pkey, dsa) != 1)
340 static EVP_PKEY *d2i_DHparams_bio_helper(BIO *src)
345 EVP_PKEY *pkey = NULL;
347 dh = d2i_DHparams_bio(src, NULL);
351 pkey = EVP_PKEY_new();
355 if (EVP_PKEY_assign_DH(pkey, dh) != 1)
366 static EVP_PKEY *d2i_ECPKParameters_bio_helper(BIO *src)
370 EC_GROUP *ecg = NULL;
372 EVP_PKEY *pkey = NULL;
374 ecg = d2i_ECPKParameters_bio(src, NULL);
382 if (EC_KEY_set_group(eck, ecg) != 1)
388 pkey = EVP_PKEY_new();
392 if (EVP_PKEY_assign_EC_KEY(pkey, eck) != 1)
404 int import_evp(yaca_key_h *key,
405 yaca_key_type_e key_type,
406 const char *password,
411 assert(password == NULL || password[0] != '\0');
412 assert(data != NULL);
413 assert(data_len != 0);
417 EVP_PKEY *pkey = NULL;
418 pem_password_cb *cb = openssl_password_cb;
419 struct openssl_password_data cb_data = {false, password};
422 IMPORTED_KEY_CATEGORY_PRIVATE,
423 IMPORTED_KEY_CATEGORY_PUBLIC,
424 IMPORTED_KEY_CATEGORY_PARAMETERS
425 } imported_key_category;
426 yaca_key_type_e imported_key_type;
427 bool password_supported;
428 struct yaca_key_evp_s *nk = NULL;
430 /* Neither PEM nor DER will ever be shorter then 4 bytes (12 seems
431 * to be minimum for DER, much more for PEM). This is just to make
432 * sure we have at least 4 bytes for strncmp() below.
435 return YACA_ERROR_INVALID_PARAMETER;
437 /* This is because of BIO_new_mem_buf() having its length param typed int */
438 if (data_len > INT_MAX)
439 return YACA_ERROR_INVALID_PARAMETER;
441 src = BIO_new_mem_buf(data, data_len);
443 ERROR_DUMP(YACA_ERROR_INTERNAL);
444 return YACA_ERROR_INTERNAL;
448 if (strncmp("----", data, 4) == 0) {
451 pkey = PEM_read_bio_PrivateKey(src, NULL, cb, (void*)&cb_data);
452 if (ERROR_HANDLE() == YACA_ERROR_INVALID_PASSWORD)
453 return YACA_ERROR_INVALID_PASSWORD;
454 imported_key_category = IMPORTED_KEY_CATEGORY_PRIVATE;
455 password_supported = true;
460 pkey = PEM_read_bio_PUBKEY(src, NULL, openssl_password_cb_error, NULL);
462 imported_key_category = IMPORTED_KEY_CATEGORY_PUBLIC;
463 password_supported = false;
468 pkey = PEM_read_bio_Parameters(src, NULL);
470 imported_key_category = IMPORTED_KEY_CATEGORY_PARAMETERS;
471 password_supported = false;
476 X509 *x509 = PEM_read_bio_X509(src, NULL, openssl_password_cb_error, NULL);
478 pkey = X509_get_pubkey(x509);
482 imported_key_category = IMPORTED_KEY_CATEGORY_PUBLIC;
483 password_supported = false;
490 pkey = d2i_PKCS8PrivateKey_bio(src, NULL, cb, (void*)&cb_data);
491 if (ERROR_HANDLE() == YACA_ERROR_INVALID_PASSWORD)
492 return YACA_ERROR_INVALID_PASSWORD;
493 imported_key_category = IMPORTED_KEY_CATEGORY_PRIVATE;
494 password_supported = true;
499 pkey = d2i_PrivateKey_bio(src, NULL);
501 imported_key_category = IMPORTED_KEY_CATEGORY_PRIVATE;
502 password_supported = false;
507 pkey = d2i_PUBKEY_bio(src, NULL);
509 imported_key_category = IMPORTED_KEY_CATEGORY_PUBLIC;
510 password_supported = false;
515 pkey = d2i_DSAparams_bio_helper(src);
517 imported_key_category = IMPORTED_KEY_CATEGORY_PARAMETERS;
518 password_supported = false;
523 pkey = d2i_DHparams_bio_helper(src);
525 imported_key_category = IMPORTED_KEY_CATEGORY_PARAMETERS;
526 password_supported = false;
531 pkey = d2i_ECPKParameters_bio_helper(src);
533 imported_key_category = IMPORTED_KEY_CATEGORY_PARAMETERS;
534 password_supported = false;
539 X509 *x509 = d2i_X509_bio(src, NULL);
541 pkey = X509_get_pubkey(x509);
545 imported_key_category = IMPORTED_KEY_CATEGORY_PUBLIC;
546 password_supported = false;
553 return YACA_ERROR_INVALID_PARAMETER;
555 /* password was given, but it was not required to perform import */
556 if (password != NULL && !cb_data.password_requested) {
557 if (password_supported)
558 ret = YACA_ERROR_INVALID_PASSWORD;
560 ret = YACA_ERROR_INVALID_PARAMETER;
564 imported_evp_id = EVP_PKEY_type(pkey->type);
566 switch (imported_key_category) {
567 case IMPORTED_KEY_CATEGORY_PRIVATE:
568 ret = convert_evp_id_to_priv(imported_evp_id, &imported_key_type);
570 case IMPORTED_KEY_CATEGORY_PUBLIC:
571 ret = convert_evp_id_to_pub(imported_evp_id, &imported_key_type);
573 case IMPORTED_KEY_CATEGORY_PARAMETERS:
574 ret = convert_evp_id_to_params(imported_evp_id, &imported_key_type);
578 return YACA_ERROR_INTERNAL;
580 if (ret != YACA_ERROR_NONE)
583 if (imported_key_type != key_type) {
584 ret = YACA_ERROR_INVALID_PARAMETER;
588 ret = yaca_zalloc(sizeof(struct yaca_key_evp_s), (void**)&nk);
589 if (ret != YACA_ERROR_NONE)
593 *key = (yaca_key_h)nk;
594 (*key)->type = key_type;
597 ret = YACA_ERROR_NONE;
605 int export_simple_raw(struct yaca_key_simple_s *simple_key,
610 assert(simple_key != NULL);
611 assert(data != NULL);
612 assert(data_len != NULL);
614 size_t key_len = simple_key->bit_len / 8;
618 ret = yaca_malloc(key_len, (void**)data);
619 if (ret != YACA_ERROR_NONE)
622 memcpy(*data, simple_key->d, key_len);
625 return YACA_ERROR_NONE;
628 int export_simple_base64(struct yaca_key_simple_s *simple_key,
632 assert(simple_key != NULL);
633 assert(data != NULL);
634 assert(data_len != NULL);
637 size_t key_len = simple_key->bit_len / 8;
643 b64 = BIO_new(BIO_f_base64());
645 ret = YACA_ERROR_INTERNAL;
650 mem = BIO_new(BIO_s_mem());
652 ret = YACA_ERROR_INTERNAL;
658 BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
660 ret = BIO_write(b64, simple_key->d, key_len);
661 if (ret <= 0 || (unsigned)ret != key_len) {
662 ret = YACA_ERROR_INTERNAL;
667 ret = BIO_flush(b64);
669 ret = YACA_ERROR_INTERNAL;
674 bio_data_len = BIO_get_mem_data(mem, &bio_data);
675 if (bio_data_len <= 0) {
676 ret = YACA_ERROR_INTERNAL;
681 ret = yaca_malloc(bio_data_len, (void**)data);
682 if (ret != YACA_ERROR_NONE)
685 memcpy(*data, bio_data, bio_data_len);
686 *data_len = bio_data_len;
687 ret = YACA_ERROR_NONE;
695 int export_evp_default_bio(struct yaca_key_evp_s *evp_key,
696 yaca_key_file_format_e key_file_fmt,
697 const char *password,
700 assert(evp_key != NULL);
701 assert(password == NULL || password[0] != '\0');
705 const EVP_CIPHER *enc = NULL;
707 if (password != NULL)
708 enc = EVP_aes_256_cbc();
710 switch (key_file_fmt) {
712 case YACA_KEY_FILE_FORMAT_PEM:
713 switch (evp_key->key.type) {
715 case YACA_KEY_TYPE_RSA_PRIV:
716 case YACA_KEY_TYPE_DSA_PRIV:
717 case YACA_KEY_TYPE_DH_PRIV:
718 case YACA_KEY_TYPE_EC_PRIV:
719 ret = PEM_write_bio_PrivateKey(mem, evp_key->evp, enc,
720 NULL, 0, NULL, (void*)password);
723 case YACA_KEY_TYPE_RSA_PUB:
724 case YACA_KEY_TYPE_DSA_PUB:
725 case YACA_KEY_TYPE_DH_PUB:
726 case YACA_KEY_TYPE_EC_PUB:
727 if (password != NULL)
728 return YACA_ERROR_INVALID_PARAMETER;
729 ret = PEM_write_bio_PUBKEY(mem, evp_key->evp);
732 case YACA_KEY_TYPE_DSA_PARAMS:
733 case YACA_KEY_TYPE_DH_PARAMS:
734 case YACA_KEY_TYPE_EC_PARAMS:
735 if (password != NULL)
736 return YACA_ERROR_INVALID_PARAMETER;
737 ret = PEM_write_bio_Parameters(mem, evp_key->evp);
741 return YACA_ERROR_INVALID_PARAMETER;
746 case YACA_KEY_FILE_FORMAT_DER:
747 /* None of the formats in DEFAULT DER support a password */
748 if (password != NULL)
749 return YACA_ERROR_INVALID_PARAMETER;
751 switch (evp_key->key.type) {
753 case YACA_KEY_TYPE_RSA_PRIV:
754 case YACA_KEY_TYPE_DSA_PRIV:
755 case YACA_KEY_TYPE_DH_PRIV:
756 case YACA_KEY_TYPE_EC_PRIV:
757 ret = i2d_PrivateKey_bio(mem, evp_key->evp);
760 case YACA_KEY_TYPE_RSA_PUB:
761 case YACA_KEY_TYPE_DSA_PUB:
762 case YACA_KEY_TYPE_DH_PUB:
763 case YACA_KEY_TYPE_EC_PUB:
764 ret = i2d_PUBKEY_bio(mem, evp_key->evp);
767 case YACA_KEY_TYPE_DSA_PARAMS:
768 ret = i2d_DSAparams_bio(mem, EVP_PKEY_get0(evp_key->evp));
770 case YACA_KEY_TYPE_DH_PARAMS:
771 ret = i2d_DHparams_bio(mem, EVP_PKEY_get0(evp_key->evp));
773 case YACA_KEY_TYPE_EC_PARAMS: {
774 const EC_KEY *eck = EVP_PKEY_get0(evp_key->evp);
775 const EC_GROUP *ecg = EC_KEY_get0_group(eck);
776 ret = i2d_ECPKParameters_bio(mem, ecg);
781 return YACA_ERROR_INVALID_PARAMETER;
787 return YACA_ERROR_INVALID_PARAMETER;
791 ret = YACA_ERROR_INTERNAL;
796 return YACA_ERROR_NONE;
799 int export_evp_pkcs8_bio(struct yaca_key_evp_s *evp_key,
800 yaca_key_file_format_e key_file_fmt,
801 const char *password,
804 assert(evp_key != NULL);
805 assert(password == NULL || password[0] != '\0');
809 int nid = NID_pbeWithMD5AndDES_CBC;
811 /* PKCS8 export requires a password */
812 if (password == NULL)
813 return YACA_ERROR_INVALID_PARAMETER;
815 switch (key_file_fmt) {
817 case YACA_KEY_FILE_FORMAT_PEM:
818 switch (evp_key->key.type) {
820 case YACA_KEY_TYPE_RSA_PRIV:
821 case YACA_KEY_TYPE_DSA_PRIV:
822 case YACA_KEY_TYPE_DH_PRIV:
823 case YACA_KEY_TYPE_EC_PRIV:
824 ret = PEM_write_bio_PKCS8PrivateKey_nid(mem, evp_key->evp, nid,
825 NULL, 0, NULL, (void*)password);
829 return YACA_ERROR_INVALID_PARAMETER;
834 case YACA_KEY_FILE_FORMAT_DER:
835 switch (evp_key->key.type) {
837 case YACA_KEY_TYPE_RSA_PRIV:
838 case YACA_KEY_TYPE_DSA_PRIV:
839 case YACA_KEY_TYPE_DH_PRIV:
840 case YACA_KEY_TYPE_EC_PRIV:
841 ret = i2d_PKCS8PrivateKey_nid_bio(mem, evp_key->evp, nid,
842 NULL, 0, NULL, (void*)password);
846 return YACA_ERROR_INVALID_PARAMETER;
852 return YACA_ERROR_INVALID_PARAMETER;
856 ret = YACA_ERROR_INTERNAL;
861 return YACA_ERROR_NONE;
864 int export_evp(struct yaca_key_evp_s *evp_key,
865 yaca_key_format_e key_fmt,
866 yaca_key_file_format_e key_file_fmt,
867 const char *password,
871 assert(evp_key != NULL);
872 assert(password == NULL || password[0] != '\0');
873 assert(data != NULL);
874 assert(data_len != NULL);
876 int ret = YACA_ERROR_NONE;
881 mem = BIO_new(BIO_s_mem());
883 ret = YACA_ERROR_INTERNAL;
889 case YACA_KEY_FORMAT_DEFAULT:
890 ret = export_evp_default_bio(evp_key, key_file_fmt, password, mem);
892 case YACA_KEY_FORMAT_PKCS8:
893 ret = export_evp_pkcs8_bio(evp_key, key_file_fmt, password, mem);
896 ret = YACA_ERROR_INVALID_PARAMETER;
900 if (ret != YACA_ERROR_NONE)
903 ret = BIO_flush(mem);
905 ret = YACA_ERROR_INTERNAL;
910 bio_data_len = BIO_get_mem_data(mem, &bio_data);
911 if (bio_data_len <= 0) {
912 ret = YACA_ERROR_INTERNAL;
917 ret = yaca_malloc(bio_data_len, (void**)data);
918 if (ret != YACA_ERROR_NONE)
921 memcpy(*data, bio_data, bio_data_len);
922 *data_len = bio_data_len;
923 ret = YACA_ERROR_NONE;
931 int generate_simple(struct yaca_key_simple_s **out, size_t key_bit_len)
935 if (key_bit_len % 8 != 0)
936 return YACA_ERROR_INVALID_PARAMETER;
939 struct yaca_key_simple_s *nk;
940 size_t key_byte_len = key_bit_len / 8;
942 ret = yaca_zalloc(sizeof(struct yaca_key_simple_s) + key_byte_len, (void**)&nk);
943 if (ret != YACA_ERROR_NONE)
946 nk->bit_len = key_bit_len;
948 ret = yaca_randomize_bytes(nk->d, key_byte_len);
949 if (ret != YACA_ERROR_NONE)
953 return YACA_ERROR_NONE;
956 int generate_simple_des(struct yaca_key_simple_s **out, size_t key_bit_len)
960 if (key_bit_len != YACA_KEY_LENGTH_UNSAFE_64BIT &&
961 key_bit_len != YACA_KEY_LENGTH_UNSAFE_128BIT &&
962 key_bit_len != YACA_KEY_LENGTH_192BIT)
963 return YACA_ERROR_INVALID_PARAMETER;
966 struct yaca_key_simple_s *nk;
967 size_t key_byte_len = key_bit_len / 8;
969 ret = yaca_zalloc(sizeof(struct yaca_key_simple_s) + key_byte_len, (void**)&nk);
970 if (ret != YACA_ERROR_NONE)
973 DES_cblock *des_key = (DES_cblock*)nk->d;
974 if (key_byte_len >= 8) {
975 ret = DES_random_key(des_key);
977 ret = YACA_ERROR_INTERNAL;
982 if (key_byte_len >= 16) {
983 ret = DES_random_key(des_key + 1);
985 ret = YACA_ERROR_INTERNAL;
990 if (key_byte_len >= 24) {
991 ret = DES_random_key(des_key + 2);
993 ret = YACA_ERROR_INTERNAL;
999 nk->bit_len = key_bit_len;
1002 ret = YACA_ERROR_NONE;
1010 static int generate_evp_pkey_params(int evp_id, size_t key_bit_len, EVP_PKEY **params)
1012 assert(key_bit_len > 0);
1013 assert(params != NULL);
1016 EVP_PKEY_CTX *pctx = NULL;
1018 int dh_prime_len = 0;
1019 int dh_generator = 0;
1025 if ((key_bit_len & YACA_INTERNAL_KEYLEN_TYPE_MASK) != YACA_INTERNAL_KEYLEN_TYPE_BITS ||
1026 key_bit_len > INT_MAX || key_bit_len < 512 || key_bit_len % 64 != 0)
1027 return YACA_ERROR_INVALID_PARAMETER;
1029 bit_len = key_bit_len;
1033 if ((key_bit_len & YACA_INTERNAL_KEYLEN_TYPE_MASK) == YACA_INTERNAL_KEYLEN_TYPE_DH) {
1034 size_t gen_block = key_bit_len & YACA_INTERNAL_KEYLEN_DH_GEN_MASK;
1035 size_t prime_len_block = key_bit_len & YACA_INTERNAL_KEYLEN_DH_PRIME_MASK;
1037 /* This is impossible now as we take only 16 bits,
1038 * but for the sake of type safety */
1039 if (prime_len_block > INT_MAX)
1040 return YACA_ERROR_INVALID_PARAMETER;
1041 dh_prime_len = prime_len_block;
1043 if (gen_block == YACA_INTERNAL_KEYLEN_DH_GEN_2)
1045 else if (gen_block == YACA_INTERNAL_KEYLEN_DH_GEN_5)
1048 return YACA_ERROR_INVALID_PARAMETER;
1050 } else if ((key_bit_len & YACA_INTERNAL_KEYLEN_TYPE_MASK) == YACA_INTERNAL_KEYLEN_TYPE_DH_RFC) {
1051 if (key_bit_len == YACA_KEY_LENGTH_DH_RFC_1024_160)
1052 dh_rfc5114 = 1; /* OpenSSL magic numbers */
1053 else if (key_bit_len == YACA_KEY_LENGTH_DH_RFC_2048_224)
1055 else if (key_bit_len == YACA_KEY_LENGTH_DH_RFC_2048_256)
1058 return YACA_ERROR_INVALID_PARAMETER;
1061 return YACA_ERROR_INVALID_PARAMETER;
1066 ret = convert_ec_to_nid(key_bit_len, &ec_nid);
1067 if (ret != YACA_ERROR_NONE)
1072 /* We shouldn't be here */
1074 return YACA_ERROR_INTERNAL;
1077 pctx = EVP_PKEY_CTX_new_id(evp_id, NULL);
1079 ret = YACA_ERROR_INTERNAL;
1084 ret = EVP_PKEY_paramgen_init(pctx);
1086 ret = YACA_ERROR_INTERNAL;
1093 ret = EVP_PKEY_CTX_set_dsa_paramgen_bits(pctx, bit_len);
1096 if (dh_rfc5114 > 0) {
1097 /* The following code is based on the macro call below.
1098 * Unfortunately it doesn't work and the suspected reason is the
1099 * fact that the _set_dh_ variant actually passes EVP_PKEY_DHX:
1100 * ret = EVP_PKEY_CTX_set_dh_rfc5114(pctx, dh_rfc5114); */
1101 ret = EVP_PKEY_CTX_ctrl(pctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN,
1102 EVP_PKEY_CTRL_DH_RFC5114, dh_rfc5114, NULL);
1104 ret = EVP_PKEY_CTX_set_dh_paramgen_prime_len(pctx, dh_prime_len);
1106 ret = EVP_PKEY_CTX_set_dh_paramgen_generator(pctx, dh_generator);
1110 ret = EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, ec_nid);
1112 ret = EVP_PKEY_CTX_set_ec_param_enc(pctx, OPENSSL_EC_NAMED_CURVE);
1116 ret = YACA_ERROR_INTERNAL;
1121 ret = EVP_PKEY_paramgen(pctx, params);
1122 if (ret != 1 || params == NULL) {
1123 ret = YACA_ERROR_INTERNAL;
1128 ret = YACA_ERROR_NONE;
1131 EVP_PKEY_CTX_free(pctx);
1135 static int generate_evp_pkey_key(int evp_id, size_t key_bit_len, EVP_PKEY *params, EVP_PKEY **key)
1137 assert(key != NULL);
1138 assert(key_bit_len > 0 || params != NULL);
1141 EVP_PKEY_CTX *kctx = NULL;
1145 assert(params == NULL);
1146 kctx = EVP_PKEY_CTX_new_id(evp_id, NULL);
1151 if (params == NULL) {
1152 ret = generate_evp_pkey_params(evp_id, key_bit_len, ¶ms);
1153 if (ret != YACA_ERROR_NONE)
1156 CRYPTO_add(¶ms->references, 1, CRYPTO_LOCK_EVP_PKEY);
1159 kctx = EVP_PKEY_CTX_new(params, NULL);
1163 return YACA_ERROR_INTERNAL;
1166 ret = YACA_ERROR_INTERNAL;
1171 ret = EVP_PKEY_keygen_init(kctx);
1173 ret = YACA_ERROR_INTERNAL;
1178 if (evp_id == EVP_PKEY_RSA) {
1179 if ((key_bit_len & YACA_INTERNAL_KEYLEN_TYPE_MASK) != YACA_INTERNAL_KEYLEN_TYPE_BITS ||
1180 key_bit_len > INT_MAX || key_bit_len % 8 != 0) {
1181 ret = YACA_ERROR_INVALID_PARAMETER;
1185 ret = EVP_PKEY_CTX_set_rsa_keygen_bits(kctx, (int)key_bit_len);
1187 ret = ERROR_HANDLE();
1192 ret = EVP_PKEY_keygen(kctx, key);
1193 if (ret != 1 || key == NULL) {
1194 ret = YACA_ERROR_INTERNAL;
1199 ret = YACA_ERROR_NONE;
1202 EVP_PKEY_CTX_free(kctx);
1203 EVP_PKEY_free(params);
1207 static int generate_evp(yaca_key_type_e out_type, size_t key_bit_len,
1208 struct yaca_key_evp_s *params, struct yaca_key_evp_s **out)
1210 assert(out != NULL);
1211 assert(key_bit_len > 0 || params != NULL);
1215 EVP_PKEY *pkey_out = NULL;
1216 EVP_PKEY *pkey_params = NULL;
1218 if (params != NULL) {
1219 yaca_key_type_e key_type;
1220 yaca_key_type_e params_type = params->key.type;
1222 ret = convert_params_to_priv(params_type, &key_type);
1223 if (ret != YACA_ERROR_NONE)
1226 if (out_type != key_type)
1227 return YACA_ERROR_INVALID_PARAMETER;
1229 pkey_params = params->evp;
1233 case YACA_KEY_TYPE_DSA_PARAMS:
1234 case YACA_KEY_TYPE_DH_PARAMS:
1235 case YACA_KEY_TYPE_EC_PARAMS:
1236 assert(params == NULL);
1237 ret = convert_params_to_evp_id(out_type, &evp_id);
1238 if (ret != YACA_ERROR_NONE)
1241 ret = generate_evp_pkey_params(evp_id, key_bit_len, &pkey_out);
1243 case YACA_KEY_TYPE_RSA_PRIV:
1244 case YACA_KEY_TYPE_DSA_PRIV:
1245 case YACA_KEY_TYPE_DH_PRIV:
1246 case YACA_KEY_TYPE_EC_PRIV:
1247 ret = convert_priv_to_evp_id(out_type, &evp_id);
1248 if (ret != YACA_ERROR_NONE)
1251 ret = generate_evp_pkey_key(evp_id, key_bit_len, pkey_params, &pkey_out);
1254 return YACA_ERROR_INVALID_PARAMETER;
1256 if (ret != YACA_ERROR_NONE)
1259 ret = yaca_zalloc(sizeof(struct yaca_key_evp_s), (void**)out);
1260 if (ret != YACA_ERROR_NONE)
1263 (*out)->evp = pkey_out;
1266 ret = YACA_ERROR_NONE;
1269 EVP_PKEY_free(pkey_out);
1273 struct yaca_key_simple_s *key_get_simple(const yaca_key_h key)
1275 struct yaca_key_simple_s *k;
1277 if (key == YACA_KEY_NULL)
1280 switch (key->type) {
1281 case YACA_KEY_TYPE_SYMMETRIC:
1282 case YACA_KEY_TYPE_DES:
1283 case YACA_KEY_TYPE_IV:
1284 k = (struct yaca_key_simple_s *)key;
1287 assert(k->bit_len != 0);
1288 assert(k->bit_len % 8 == 0);
1289 assert(k->d != NULL);
1297 struct yaca_key_evp_s *key_get_evp(const yaca_key_h key)
1299 struct yaca_key_evp_s *k;
1301 if (key == YACA_KEY_NULL)
1304 switch (key->type) {
1305 case YACA_KEY_TYPE_RSA_PUB:
1306 case YACA_KEY_TYPE_RSA_PRIV:
1307 case YACA_KEY_TYPE_DSA_PUB:
1308 case YACA_KEY_TYPE_DSA_PRIV:
1309 case YACA_KEY_TYPE_DSA_PARAMS:
1310 case YACA_KEY_TYPE_DH_PUB:
1311 case YACA_KEY_TYPE_DH_PRIV:
1312 case YACA_KEY_TYPE_DH_PARAMS:
1313 case YACA_KEY_TYPE_EC_PUB:
1314 case YACA_KEY_TYPE_EC_PRIV:
1315 case YACA_KEY_TYPE_EC_PARAMS:
1316 k = (struct yaca_key_evp_s *)key;
1319 assert(k->evp != NULL);
1327 static yaca_key_h key_copy_simple(const struct yaca_key_simple_s *key)
1330 assert(key != NULL);
1332 struct yaca_key_simple_s *copy;
1333 size_t size = sizeof(struct yaca_key_simple_s) + key->bit_len / 8;
1335 ret = yaca_zalloc(size, (void**)©);
1336 if (ret != YACA_ERROR_NONE)
1337 return YACA_KEY_NULL;
1339 memcpy(copy, key, size);
1340 return (yaca_key_h)copy;
1343 static yaca_key_h key_copy_evp(const struct yaca_key_evp_s *key)
1346 assert(key != NULL);
1348 struct yaca_key_evp_s *copy = NULL;
1349 ret = yaca_zalloc(sizeof(struct yaca_key_evp_s), (void**)©);
1350 if (ret != YACA_ERROR_NONE)
1351 return YACA_KEY_NULL;
1353 /* raise the refcount */
1354 CRYPTO_add(&key->evp->references, 1, CRYPTO_LOCK_EVP_PKEY);
1356 copy->key.type = key->key.type;
1357 copy->evp = key->evp;
1358 return (yaca_key_h)copy;
1361 yaca_key_h key_copy(const yaca_key_h key)
1363 struct yaca_key_simple_s *simple = key_get_simple(key);
1364 struct yaca_key_evp_s *evp = key_get_evp(key);
1367 return key_copy_simple(simple);
1368 else if (evp != NULL)
1369 return key_copy_evp(evp);
1371 return YACA_KEY_NULL;
1374 API int yaca_key_get_type(const yaca_key_h key, yaca_key_type_e *key_type)
1376 const struct yaca_key_s *lkey = (const struct yaca_key_s *)key;
1378 if (lkey == NULL || key_type == NULL)
1379 return YACA_ERROR_INVALID_PARAMETER;
1381 *key_type = lkey->type;
1382 return YACA_ERROR_NONE;
1385 API int yaca_key_get_bit_length(const yaca_key_h key, size_t *key_bit_len)
1387 const struct yaca_key_simple_s *simple_key = key_get_simple(key);
1388 const struct yaca_key_evp_s *evp_key = key_get_evp(key);
1390 if (key_bit_len == NULL)
1391 return YACA_ERROR_INVALID_PARAMETER;
1393 if (simple_key != NULL) {
1394 *key_bit_len = simple_key->bit_len;
1395 return YACA_ERROR_NONE;
1398 if (evp_key != NULL) {
1401 switch (evp_key->key.type) {
1402 case YACA_KEY_TYPE_RSA_PRIV:
1403 case YACA_KEY_TYPE_RSA_PUB:
1404 case YACA_KEY_TYPE_DSA_PRIV:
1405 case YACA_KEY_TYPE_DSA_PUB:
1406 case YACA_KEY_TYPE_DH_PRIV:
1407 case YACA_KEY_TYPE_DH_PUB:
1408 ret = EVP_PKEY_bits(evp_key->evp);
1410 ret = YACA_ERROR_INTERNAL;
1416 return YACA_ERROR_NONE;
1417 case YACA_KEY_TYPE_EC_PRIV:
1418 case YACA_KEY_TYPE_EC_PUB: {
1419 assert(EVP_PKEY_type(evp_key->evp->type) == EVP_PKEY_EC);
1421 const EC_KEY *eck = EVP_PKEY_get0(evp_key->evp);
1422 const EC_GROUP *ecg = EC_KEY_get0_group(eck);
1423 int flags = EC_GROUP_get_asn1_flag(ecg);
1426 if (!(flags & OPENSSL_EC_NAMED_CURVE))
1427 /* This is case of a custom (not named) curve, that can happen when someone
1428 imports such a key into YACA. There is nothing that can be returned here */
1429 return YACA_ERROR_INVALID_PARAMETER;
1431 nid = EC_GROUP_get_curve_name(ecg);
1432 return convert_nid_to_ec(nid, key_bit_len);
1435 /* We shouldn't be here */
1437 return YACA_ERROR_INTERNAL;
1441 return YACA_ERROR_INVALID_PARAMETER;
1444 API int yaca_key_import(yaca_key_type_e key_type,
1445 const char *password,
1450 if (key == NULL || data == NULL || data_len == 0)
1451 return YACA_ERROR_INVALID_PARAMETER;
1453 /* allow an empty password, OpenSSL returns an error with "" */
1454 if (password != NULL && password[0] == '\0')
1458 case YACA_KEY_TYPE_SYMMETRIC:
1459 case YACA_KEY_TYPE_DES:
1460 case YACA_KEY_TYPE_IV:
1461 if (password != NULL)
1462 return YACA_ERROR_INVALID_PARAMETER;
1463 return import_simple(key, key_type, data, data_len);
1464 case YACA_KEY_TYPE_RSA_PUB:
1465 case YACA_KEY_TYPE_RSA_PRIV:
1466 case YACA_KEY_TYPE_DSA_PUB:
1467 case YACA_KEY_TYPE_DSA_PRIV:
1468 case YACA_KEY_TYPE_DSA_PARAMS:
1469 case YACA_KEY_TYPE_DH_PUB:
1470 case YACA_KEY_TYPE_DH_PRIV:
1471 case YACA_KEY_TYPE_DH_PARAMS:
1472 case YACA_KEY_TYPE_EC_PUB:
1473 case YACA_KEY_TYPE_EC_PRIV:
1474 case YACA_KEY_TYPE_EC_PARAMS:
1475 return import_evp(key, key_type, password, data, data_len);
1477 return YACA_ERROR_INVALID_PARAMETER;
1481 API int yaca_key_export(const yaca_key_h key,
1482 yaca_key_format_e key_fmt,
1483 yaca_key_file_format_e key_file_fmt,
1484 const char *password,
1488 struct yaca_key_simple_s *simple_key = key_get_simple(key);
1489 struct yaca_key_evp_s *evp_key = key_get_evp(key);
1491 if (data == NULL || data_len == NULL)
1492 return YACA_ERROR_INVALID_PARAMETER;
1494 /* allow an empty password, OpenSSL returns an error with "" */
1495 if (password != NULL && password[0] == '\0')
1498 if (password != NULL && simple_key != NULL)
1499 return YACA_ERROR_INVALID_PARAMETER;
1501 if (key_fmt == YACA_KEY_FORMAT_DEFAULT &&
1502 key_file_fmt == YACA_KEY_FILE_FORMAT_RAW &&
1504 return export_simple_raw(simple_key, data, data_len);
1506 if (key_fmt == YACA_KEY_FORMAT_DEFAULT &&
1507 key_file_fmt == YACA_KEY_FILE_FORMAT_BASE64 &&
1509 return export_simple_base64(simple_key, data, data_len);
1511 if (evp_key != NULL)
1512 return export_evp(evp_key, key_fmt, key_file_fmt,
1513 password, data, data_len);
1515 return YACA_ERROR_INVALID_PARAMETER;
1518 API int yaca_key_generate(yaca_key_type_e key_type,
1523 struct yaca_key_simple_s *nk_simple = NULL;
1524 struct yaca_key_evp_s *nk_evp = NULL;
1526 if (key == NULL || key_bit_len == 0)
1527 return YACA_ERROR_INVALID_PARAMETER;
1530 case YACA_KEY_TYPE_SYMMETRIC:
1531 case YACA_KEY_TYPE_IV:
1532 ret = generate_simple(&nk_simple, key_bit_len);
1534 case YACA_KEY_TYPE_DES:
1535 ret = generate_simple_des(&nk_simple, key_bit_len);
1537 case YACA_KEY_TYPE_RSA_PRIV:
1538 case YACA_KEY_TYPE_DSA_PRIV:
1539 case YACA_KEY_TYPE_DSA_PARAMS:
1540 case YACA_KEY_TYPE_DH_PRIV:
1541 case YACA_KEY_TYPE_DH_PARAMS:
1542 case YACA_KEY_TYPE_EC_PRIV:
1543 case YACA_KEY_TYPE_EC_PARAMS:
1544 ret = generate_evp(key_type, key_bit_len, NULL, &nk_evp);
1547 return YACA_ERROR_INVALID_PARAMETER;
1550 if (ret != YACA_ERROR_NONE)
1553 if (nk_simple != NULL) {
1554 nk_simple->key.type = key_type;
1555 *key = (yaca_key_h)nk_simple;
1556 } else if (nk_evp != NULL) {
1557 nk_evp->key.type = key_type;
1558 *key = (yaca_key_h)nk_evp;
1563 return YACA_ERROR_NONE;
1566 API int yaca_key_generate_from_parameters(const yaca_key_h params, yaca_key_h *prv_key)
1569 struct yaca_key_evp_s *evp_params = key_get_evp(params);
1570 yaca_key_type_e params_type;
1571 yaca_key_type_e key_type;
1572 struct yaca_key_evp_s *nk_evp = NULL;
1574 if (evp_params == NULL || prv_key == NULL)
1575 return YACA_ERROR_INVALID_PARAMETER;
1577 ret = yaca_key_get_type(params, ¶ms_type);
1578 if (ret != YACA_ERROR_NONE)
1581 ret = convert_params_to_priv(params_type, &key_type);
1582 if (ret != YACA_ERROR_NONE)
1585 ret = generate_evp(key_type, 0, evp_params, &nk_evp);
1586 if (ret != YACA_ERROR_NONE)
1589 assert(nk_evp != NULL);
1591 nk_evp->key.type = key_type;
1592 *prv_key = (yaca_key_h)nk_evp;
1594 return YACA_ERROR_NONE;
1597 API int yaca_key_extract_public(const yaca_key_h prv_key, yaca_key_h *pub_key)
1600 struct yaca_key_evp_s *evp_key = key_get_evp(prv_key);
1601 struct yaca_key_evp_s *nk;
1603 EVP_PKEY *pkey = NULL;
1605 if (prv_key == YACA_KEY_NULL || evp_key == NULL || pub_key == NULL)
1606 return YACA_ERROR_INVALID_PARAMETER;
1608 ret = yaca_zalloc(sizeof(struct yaca_key_evp_s), (void**)&nk);
1609 if (ret != YACA_ERROR_NONE)
1612 mem = BIO_new(BIO_s_mem());
1614 ret = YACA_ERROR_INTERNAL;
1619 ret = i2d_PUBKEY_bio(mem, evp_key->evp);
1621 ret = YACA_ERROR_INTERNAL;
1626 pkey = d2i_PUBKEY_bio(mem, NULL);
1628 ret = YACA_ERROR_INTERNAL;
1636 switch (prv_key->type) {
1637 case YACA_KEY_TYPE_RSA_PRIV:
1638 nk->key.type = YACA_KEY_TYPE_RSA_PUB;
1640 case YACA_KEY_TYPE_DSA_PRIV:
1641 nk->key.type = YACA_KEY_TYPE_DSA_PUB;
1643 case YACA_KEY_TYPE_DH_PRIV:
1644 nk->key.type = YACA_KEY_TYPE_DH_PUB;
1646 case YACA_KEY_TYPE_EC_PRIV:
1647 nk->key.type = YACA_KEY_TYPE_EC_PUB;
1650 ret = YACA_ERROR_INVALID_PARAMETER;
1656 *pub_key = (yaca_key_h)nk;
1658 ret = YACA_ERROR_NONE;
1661 EVP_PKEY_free(pkey);
1668 API void yaca_key_destroy(yaca_key_h key)
1670 struct yaca_key_simple_s *simple_key = key_get_simple(key);
1671 struct yaca_key_evp_s *evp_key = key_get_evp(key);
1673 if (simple_key != NULL)
1674 yaca_free(simple_key);
1676 if (evp_key != NULL) {
1677 EVP_PKEY_free(evp_key->evp);
1682 API int yaca_key_derive_dh(const yaca_key_h prv_key,
1683 const yaca_key_h pub_key,
1684 yaca_key_h *sym_key)
1687 struct yaca_key_evp_s *lprv_key = key_get_evp(prv_key);
1688 struct yaca_key_evp_s *lpub_key = key_get_evp(pub_key);
1689 struct yaca_key_simple_s *nk = NULL;
1693 if (lprv_key == NULL || lpub_key == NULL || sym_key == NULL ||
1694 (!(lprv_key->key.type == YACA_KEY_TYPE_DH_PRIV &&
1695 lpub_key->key.type == YACA_KEY_TYPE_DH_PUB)
1697 !(lprv_key->key.type == YACA_KEY_TYPE_EC_PRIV &&
1698 lpub_key->key.type == YACA_KEY_TYPE_EC_PUB)))
1699 return YACA_ERROR_INVALID_PARAMETER;
1701 ctx = EVP_PKEY_CTX_new(lprv_key->evp, NULL);
1703 ret = YACA_ERROR_INTERNAL;
1708 ret = EVP_PKEY_derive_init(ctx);
1710 ret = YACA_ERROR_INTERNAL;
1715 ret = EVP_PKEY_derive_set_peer(ctx, lpub_key->evp);
1717 ret = YACA_ERROR_INTERNAL;
1722 ret = EVP_PKEY_derive(ctx, NULL, &nk_len);
1724 ret = YACA_ERROR_INTERNAL;
1729 if (nk_len == 0 || nk_len > SIZE_MAX / 8) {
1730 ret = YACA_ERROR_INVALID_PARAMETER;
1734 ret = yaca_zalloc(sizeof(struct yaca_key_simple_s) + nk_len, (void**)&nk);
1735 if (ret != YACA_ERROR_NONE)
1738 ret = EVP_PKEY_derive(ctx, (unsigned char*)nk->d, &nk_len);
1740 ret = YACA_ERROR_INTERNAL;
1745 nk->bit_len = nk_len * 8;
1746 nk->key.type = YACA_KEY_TYPE_SYMMETRIC;
1747 *sym_key = (yaca_key_h)nk;
1749 ret = YACA_ERROR_NONE;
1752 EVP_PKEY_CTX_free(ctx);
1757 API int yaca_key_derive_pbkdf2(const char *password,
1761 yaca_digest_algorithm_e algo,
1766 struct yaca_key_simple_s *nk;
1767 size_t key_byte_len = key_bit_len / 8;
1770 if (password == NULL ||
1771 (salt == NULL && salt_len > 0) || (salt != NULL && salt_len == 0) ||
1772 iterations == 0 || key_bit_len == 0 || key == NULL)
1773 return YACA_ERROR_INVALID_PARAMETER;
1775 if (key_bit_len % 8) /* Key length must be multiple of 8-bit_len */
1776 return YACA_ERROR_INVALID_PARAMETER;
1778 if (iterations > INT_MAX) /* OpenSSL limitation */
1779 return YACA_ERROR_INVALID_PARAMETER;
1781 ret = digest_get_algorithm(algo, &md);
1782 if (ret != YACA_ERROR_NONE)
1785 ret = yaca_zalloc(sizeof(struct yaca_key_simple_s) + key_byte_len, (void**)&nk);
1786 if (ret != YACA_ERROR_NONE)
1789 nk->bit_len = key_bit_len;
1790 nk->key.type = YACA_KEY_TYPE_SYMMETRIC; // TODO: how to handle other keys?
1792 ret = PKCS5_PBKDF2_HMAC(password, -1, (const unsigned char*)salt,
1793 salt_len, iterations, md, key_byte_len,
1794 (unsigned char*)nk->d);
1796 ret = YACA_ERROR_INTERNAL;
1801 *key = (yaca_key_h)nk;
1803 ret = YACA_ERROR_NONE;