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}
97 static const size_t KEY_TYPES_PARAMS_SIZE = sizeof(KEY_TYPES_PARAMS) / sizeof(KEY_TYPES_PARAMS[0]);
99 #define CONVERT_TYPES_TEMPLATE(data, src_type, src, dst_type, dst) \
100 static int convert_##src##_to_##dst (src_type src, dst_type *dst) \
102 assert(dst != NULL); \
104 for (i = 0; i < data##_SIZE; ++i) \
105 if (data[i].src == src) { \
106 if (data[i].dst != (dst_type)-1) { \
107 *dst = data[i].dst; \
108 return YACA_ERROR_NONE; \
111 return YACA_ERROR_INVALID_PARAMETER; \
114 CONVERT_TYPES_TEMPLATE(EC_NID_PAIRS, int, nid, size_t, ec)
115 CONVERT_TYPES_TEMPLATE(EC_NID_PAIRS, size_t, ec, int, nid)
117 CONVERT_TYPES_TEMPLATE(KEY_TYPES_PARAMS, yaca_key_type_e, params, int, evp_id)
118 CONVERT_TYPES_TEMPLATE(KEY_TYPES_PARAMS, yaca_key_type_e, priv, int, evp_id)
119 CONVERT_TYPES_TEMPLATE(KEY_TYPES_PARAMS, yaca_key_type_e, params, yaca_key_type_e, priv)
121 int base64_decode_length(const char *data, size_t data_len, size_t *len)
123 assert(data != NULL);
124 assert(data_len != 0);
128 size_t tmp_len = data_len;
130 if (data_len % 4 != 0)
131 return YACA_ERROR_INVALID_PARAMETER;
133 if (data[tmp_len - 1] == '=') {
135 if (data[tmp_len - 2] == '=')
139 *len = data_len / 4 * 3 - padded;
140 return YACA_ERROR_NONE;
143 #define TMP_BUF_LEN 512
145 int base64_decode(const char *data, size_t data_len, BIO **output)
147 assert(data != NULL);
148 assert(data_len != 0);
149 assert(output != NULL);
155 char tmpbuf[TMP_BUF_LEN];
160 /* This is because of BIO_new_mem_buf() having its length param typed int */
161 if (data_len > INT_MAX)
162 return YACA_ERROR_INVALID_PARAMETER;
164 /* First phase of correctness checking, calculate expected output length */
165 ret = base64_decode_length(data, data_len, &b64_len);
166 if (ret != YACA_ERROR_NONE)
169 b64 = BIO_new(BIO_f_base64());
171 ret = YACA_ERROR_INTERNAL;
176 src = BIO_new_mem_buf(data, data_len);
178 ret = YACA_ERROR_INTERNAL;
185 dst = BIO_new(BIO_s_mem());
187 ret = YACA_ERROR_INTERNAL;
192 BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
196 ret = BIO_read(b64, tmpbuf, TMP_BUF_LEN);
198 ret = YACA_ERROR_INTERNAL;
203 if (ret == YACA_ERROR_NONE)
206 if (BIO_write(dst, tmpbuf, ret) != ret) {
207 ret = YACA_ERROR_INTERNAL;
215 /* Check wether the length of the decoded data is what we expected */
216 out_len = BIO_get_mem_data(dst, &out);
218 ret = YACA_ERROR_INTERNAL;
222 if ((size_t)out_len != b64_len) {
223 ret = YACA_ERROR_INVALID_PARAMETER;
229 ret = YACA_ERROR_NONE;
238 int import_simple(yaca_key_h *key,
239 yaca_key_type_e key_type,
244 assert(data != NULL);
245 assert(data_len != 0);
249 const char *key_data;
251 struct yaca_key_simple_s *nk = NULL;
253 ret = base64_decode(data, data_len, &decoded);
254 if (ret == YACA_ERROR_NONE) {
255 /* Conversion successfull, get the BASE64 */
256 long len = BIO_get_mem_data(decoded, &key_data);
257 if (len <= 0 || key_data == NULL) {
258 ret = YACA_ERROR_INTERNAL;
263 } else if (ret == YACA_ERROR_INVALID_PARAMETER) {
264 /* This was not BASE64 or it was corrupted, treat as RAW */
265 key_data_len = data_len;
268 /* Some other, possibly unrecoverable error, give up */
272 /* key_bit_len has to fit in size_t */
273 if (key_data_len > SIZE_MAX / 8) {
274 ret = YACA_ERROR_INVALID_PARAMETER;
278 /* DES key length verification */
279 if (key_type == YACA_KEY_TYPE_DES) {
280 size_t key_bit_len = key_data_len * 8;
281 if (key_bit_len != YACA_KEY_LENGTH_UNSAFE_64BIT &&
282 key_bit_len != YACA_KEY_LENGTH_UNSAFE_128BIT &&
283 key_bit_len != YACA_KEY_LENGTH_192BIT) {
284 ret = YACA_ERROR_INVALID_PARAMETER;
289 ret = yaca_zalloc(sizeof(struct yaca_key_simple_s) + key_data_len, (void**)&nk);
290 if (ret != YACA_ERROR_NONE)
293 memcpy(nk->d, key_data, key_data_len);
294 nk->bit_len = key_data_len * 8;
295 nk->key.type = key_type;
297 *key = (yaca_key_h)nk;
299 ret = YACA_ERROR_NONE;
302 BIO_free_all(decoded);
307 int import_evp(yaca_key_h *key,
308 yaca_key_type_e key_type,
309 const char *password,
314 assert(password == NULL || password[0] != '\0');
315 assert(data != NULL);
316 assert(data_len != 0);
320 EVP_PKEY *pkey = NULL;
321 pem_password_cb *cb = openssl_password_cb;
322 struct openssl_password_data cb_data = {false, password};
324 bool password_supported;
325 yaca_key_type_e type;
326 struct yaca_key_evp_s *nk = NULL;
328 /* Neither PEM nor DER will ever be shorter then 4 bytes (12 seems
329 * to be minimum for DER, much more for PEM). This is just to make
330 * sure we have at least 4 bytes for strncmp() below.
333 return YACA_ERROR_INVALID_PARAMETER;
335 /* This is because of BIO_new_mem_buf() having its length param typed int */
336 if (data_len > INT_MAX)
337 return YACA_ERROR_INVALID_PARAMETER;
339 src = BIO_new_mem_buf(data, data_len);
341 ERROR_DUMP(YACA_ERROR_INTERNAL);
342 return YACA_ERROR_INTERNAL;
346 if (strncmp("----", data, 4) == 0) {
349 pkey = PEM_read_bio_PrivateKey(src, NULL, cb, (void*)&cb_data);
350 if (ERROR_HANDLE() == YACA_ERROR_INVALID_PASSWORD)
351 return YACA_ERROR_INVALID_PASSWORD;
353 password_supported = true;
358 pkey = PEM_read_bio_PUBKEY(src, NULL, openssl_password_cb_error, NULL);
361 password_supported = false;
366 X509 *x509 = PEM_read_bio_X509(src, NULL, openssl_password_cb_error, NULL);
368 pkey = X509_get_pubkey(x509);
373 password_supported = false;
380 pkey = d2i_PKCS8PrivateKey_bio(src, NULL, cb, (void*)&cb_data);
381 if (ERROR_HANDLE() == YACA_ERROR_INVALID_PASSWORD)
382 return YACA_ERROR_INVALID_PASSWORD;
384 password_supported = true;
389 pkey = d2i_PrivateKey_bio(src, NULL);
392 password_supported = false;
397 pkey = d2i_PUBKEY_bio(src, NULL);
400 password_supported = false;
405 X509 *x509 = d2i_X509_bio(src, NULL);
407 pkey = X509_get_pubkey(x509);
412 password_supported = false;
419 return YACA_ERROR_INVALID_PARAMETER;
421 /* password was given, but it was not required to perform import */
422 if (password != NULL && !cb_data.password_requested) {
423 if (password_supported)
424 ret = YACA_ERROR_INVALID_PASSWORD;
426 ret = YACA_ERROR_INVALID_PARAMETER;
430 switch (EVP_PKEY_type(pkey->type)) {
432 type = private ? YACA_KEY_TYPE_RSA_PRIV : YACA_KEY_TYPE_RSA_PUB;
436 type = private ? YACA_KEY_TYPE_DSA_PRIV : YACA_KEY_TYPE_DSA_PUB;
440 type = private ? YACA_KEY_TYPE_EC_PRIV : YACA_KEY_TYPE_EC_PUB;
444 ret = YACA_ERROR_INVALID_PARAMETER;
448 if (type != key_type) {
449 ret = YACA_ERROR_INVALID_PARAMETER;
453 ret = yaca_zalloc(sizeof(struct yaca_key_evp_s), (void**)&nk);
454 if (ret != YACA_ERROR_NONE)
458 *key = (yaca_key_h)nk;
462 ret = YACA_ERROR_NONE;
470 int export_simple_raw(struct yaca_key_simple_s *simple_key,
475 assert(simple_key != NULL);
476 assert(data != NULL);
477 assert(data_len != NULL);
479 size_t key_len = simple_key->bit_len / 8;
483 ret = yaca_malloc(key_len, (void**)data);
484 if (ret != YACA_ERROR_NONE)
487 memcpy(*data, simple_key->d, key_len);
490 return YACA_ERROR_NONE;
493 int export_simple_base64(struct yaca_key_simple_s *simple_key,
497 assert(simple_key != NULL);
498 assert(data != NULL);
499 assert(data_len != NULL);
502 size_t key_len = simple_key->bit_len / 8;
508 b64 = BIO_new(BIO_f_base64());
510 ret = YACA_ERROR_INTERNAL;
515 mem = BIO_new(BIO_s_mem());
517 ret = YACA_ERROR_INTERNAL;
523 BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
525 ret = BIO_write(b64, simple_key->d, key_len);
526 if (ret <= 0 || (unsigned)ret != key_len) {
527 ret = YACA_ERROR_INTERNAL;
532 ret = BIO_flush(b64);
534 ret = YACA_ERROR_INTERNAL;
539 bio_data_len = BIO_get_mem_data(mem, &bio_data);
540 if (bio_data_len <= 0) {
541 ret = YACA_ERROR_INTERNAL;
546 ret = yaca_malloc(bio_data_len, (void**)data);
547 if (ret != YACA_ERROR_NONE)
550 memcpy(*data, bio_data, bio_data_len);
551 *data_len = bio_data_len;
552 ret = YACA_ERROR_NONE;
560 int export_evp_default_bio(struct yaca_key_evp_s *evp_key,
561 yaca_key_file_format_e key_file_fmt,
562 const char *password,
565 assert(evp_key != NULL);
566 assert(password == NULL || password[0] != '\0');
570 const EVP_CIPHER *enc = NULL;
572 if (password != NULL)
573 enc = EVP_aes_256_cbc();
575 switch (key_file_fmt) {
577 case YACA_KEY_FILE_FORMAT_PEM:
578 switch (evp_key->key.type) {
580 case YACA_KEY_TYPE_RSA_PRIV:
581 ret = PEM_write_bio_RSAPrivateKey(mem, EVP_PKEY_get0(evp_key->evp),
582 enc, NULL, 0, NULL, (void*)password);
584 case YACA_KEY_TYPE_DSA_PRIV:
585 ret = PEM_write_bio_DSAPrivateKey(mem, EVP_PKEY_get0(evp_key->evp),
586 enc, NULL, 0, NULL, (void*)password);
589 case YACA_KEY_TYPE_RSA_PUB:
590 case YACA_KEY_TYPE_DSA_PUB:
591 if (password != NULL)
592 return YACA_ERROR_INVALID_PARAMETER;
593 ret = PEM_write_bio_PUBKEY(mem, evp_key->evp);
596 case YACA_KEY_TYPE_DH_PRIV:
597 case YACA_KEY_TYPE_DH_PUB:
598 case YACA_KEY_TYPE_EC_PRIV:
599 case YACA_KEY_TYPE_EC_PUB:
600 //TODO NOT_IMPLEMENTED
602 return YACA_ERROR_INVALID_PARAMETER;
607 case YACA_KEY_FILE_FORMAT_DER:
608 switch (evp_key->key.type) {
610 case YACA_KEY_TYPE_RSA_PRIV:
611 if (password != NULL)
612 return YACA_ERROR_INVALID_PARAMETER;
613 ret = i2d_RSAPrivateKey_bio(mem, EVP_PKEY_get0(evp_key->evp));
616 case YACA_KEY_TYPE_DSA_PRIV:
617 if (password != NULL)
618 return YACA_ERROR_INVALID_PARAMETER;
619 ret = i2d_DSAPrivateKey_bio(mem, EVP_PKEY_get0(evp_key->evp));
622 case YACA_KEY_TYPE_RSA_PUB:
623 case YACA_KEY_TYPE_DSA_PUB:
624 if (password != NULL)
625 return YACA_ERROR_INVALID_PARAMETER;
626 ret = i2d_PUBKEY_bio(mem, evp_key->evp);
629 case YACA_KEY_TYPE_DH_PRIV:
630 case YACA_KEY_TYPE_DH_PUB:
631 case YACA_KEY_TYPE_EC_PRIV:
632 case YACA_KEY_TYPE_EC_PUB:
633 //TODO NOT_IMPLEMENTED
635 return YACA_ERROR_INVALID_PARAMETER;
641 return YACA_ERROR_INVALID_PARAMETER;
645 ret = YACA_ERROR_INTERNAL;
650 return YACA_ERROR_NONE;
653 int export_evp_pkcs8_bio(struct yaca_key_evp_s *evp_key,
654 yaca_key_file_format_e key_file_fmt,
655 const char *password,
658 assert(evp_key != NULL);
659 assert(password == NULL || password[0] != '\0');
663 int nid = NID_pbeWithMD5AndDES_CBC;
665 /* PKCS8 export requires a password */
666 if (password == NULL)
667 return YACA_ERROR_INVALID_PARAMETER;
669 switch (key_file_fmt) {
671 case YACA_KEY_FILE_FORMAT_PEM:
672 switch (evp_key->key.type) {
674 case YACA_KEY_TYPE_RSA_PRIV:
675 case YACA_KEY_TYPE_DSA_PRIV:
676 ret = PEM_write_bio_PKCS8PrivateKey_nid(mem, evp_key->evp, nid,
677 NULL, 0, NULL, (void*)password);
679 case YACA_KEY_TYPE_DH_PRIV:
680 case YACA_KEY_TYPE_EC_PRIV:
681 //TODO NOT_IMPLEMENTED
683 /* Public keys are not supported by PKCS8 */
684 return YACA_ERROR_INVALID_PARAMETER;
689 case YACA_KEY_FILE_FORMAT_DER:
690 switch (evp_key->key.type) {
692 case YACA_KEY_TYPE_RSA_PRIV:
693 case YACA_KEY_TYPE_DSA_PRIV:
694 ret = i2d_PKCS8PrivateKey_nid_bio(mem, evp_key->evp, nid,
695 NULL, 0, NULL, (void*)password);
698 case YACA_KEY_TYPE_DH_PRIV:
699 case YACA_KEY_TYPE_EC_PRIV:
700 //TODO NOT_IMPLEMENTED
702 /* Public keys are not supported by PKCS8 */
703 return YACA_ERROR_INVALID_PARAMETER;
709 return YACA_ERROR_INVALID_PARAMETER;
713 ret = YACA_ERROR_INTERNAL;
718 return YACA_ERROR_NONE;
721 int export_evp(struct yaca_key_evp_s *evp_key,
722 yaca_key_format_e key_fmt,
723 yaca_key_file_format_e key_file_fmt,
724 const char *password,
728 assert(evp_key != NULL);
729 assert(password == NULL || password[0] != '\0');
730 assert(data != NULL);
731 assert(data_len != NULL);
733 int ret = YACA_ERROR_NONE;
738 mem = BIO_new(BIO_s_mem());
740 ret = YACA_ERROR_INTERNAL;
746 case YACA_KEY_FORMAT_DEFAULT:
747 ret = export_evp_default_bio(evp_key, key_file_fmt, password, mem);
749 case YACA_KEY_FORMAT_PKCS8:
750 ret = export_evp_pkcs8_bio(evp_key, key_file_fmt, password, mem);
753 ret = YACA_ERROR_INVALID_PARAMETER;
757 if (ret != YACA_ERROR_NONE)
760 ret = BIO_flush(mem);
762 ret = YACA_ERROR_INTERNAL;
767 bio_data_len = BIO_get_mem_data(mem, &bio_data);
768 if (bio_data_len <= 0) {
769 ret = YACA_ERROR_INTERNAL;
774 ret = yaca_malloc(bio_data_len, (void**)data);
775 if (ret != YACA_ERROR_NONE)
778 memcpy(*data, bio_data, bio_data_len);
779 *data_len = bio_data_len;
780 ret = YACA_ERROR_NONE;
788 int generate_simple(struct yaca_key_simple_s **out, size_t key_bit_len)
792 if (key_bit_len % 8 != 0)
793 return YACA_ERROR_INVALID_PARAMETER;
796 struct yaca_key_simple_s *nk;
797 size_t key_byte_len = key_bit_len / 8;
799 ret = yaca_zalloc(sizeof(struct yaca_key_simple_s) + key_byte_len, (void**)&nk);
800 if (ret != YACA_ERROR_NONE)
803 nk->bit_len = key_bit_len;
805 ret = yaca_randomize_bytes(nk->d, key_byte_len);
806 if (ret != YACA_ERROR_NONE)
810 return YACA_ERROR_NONE;
813 int generate_simple_des(struct yaca_key_simple_s **out, size_t key_bit_len)
817 if (key_bit_len != YACA_KEY_LENGTH_UNSAFE_64BIT &&
818 key_bit_len != YACA_KEY_LENGTH_UNSAFE_128BIT &&
819 key_bit_len != YACA_KEY_LENGTH_192BIT)
820 return YACA_ERROR_INVALID_PARAMETER;
823 struct yaca_key_simple_s *nk;
824 size_t key_byte_len = key_bit_len / 8;
826 ret = yaca_zalloc(sizeof(struct yaca_key_simple_s) + key_byte_len, (void**)&nk);
827 if (ret != YACA_ERROR_NONE)
830 DES_cblock *des_key = (DES_cblock*)nk->d;
831 if (key_byte_len >= 8) {
832 ret = DES_random_key(des_key);
834 ret = YACA_ERROR_INTERNAL;
839 if (key_byte_len >= 16) {
840 ret = DES_random_key(des_key + 1);
842 ret = YACA_ERROR_INTERNAL;
847 if (key_byte_len >= 24) {
848 ret = DES_random_key(des_key + 2);
850 ret = YACA_ERROR_INTERNAL;
856 nk->bit_len = key_bit_len;
859 ret = YACA_ERROR_NONE;
867 static int generate_evp_pkey_params(int evp_id, size_t key_bit_len, EVP_PKEY **params)
869 assert(key_bit_len > 0);
870 assert(params != NULL);
873 EVP_PKEY_CTX *pctx = NULL;
875 int dh_prime_len = 0;
876 int dh_generator = 0;
882 if ((key_bit_len & YACA_INTERNAL_KEYLEN_TYPE_MASK) != YACA_INTERNAL_KEYLEN_TYPE_BITS ||
883 key_bit_len > INT_MAX || key_bit_len < 512 || key_bit_len % 64 != 0)
884 return YACA_ERROR_INVALID_PARAMETER;
886 bit_len = key_bit_len;
890 if ((key_bit_len & YACA_INTERNAL_KEYLEN_TYPE_MASK) == YACA_INTERNAL_KEYLEN_TYPE_DH) {
891 size_t gen_block = key_bit_len & YACA_INTERNAL_KEYLEN_DH_GEN_MASK;
892 size_t prime_len_block = key_bit_len & YACA_INTERNAL_KEYLEN_DH_PRIME_MASK;
894 /* This is impossible now as we take only 16 bits,
895 * but for the sake of type safety */
896 if (prime_len_block > INT_MAX)
897 return YACA_ERROR_INVALID_PARAMETER;
898 dh_prime_len = prime_len_block;
900 if (gen_block == YACA_INTERNAL_KEYLEN_DH_GEN_2)
902 else if (gen_block == YACA_INTERNAL_KEYLEN_DH_GEN_5)
905 return YACA_ERROR_INVALID_PARAMETER;
907 } else if ((key_bit_len & YACA_INTERNAL_KEYLEN_TYPE_MASK) == YACA_INTERNAL_KEYLEN_TYPE_DH_RFC) {
908 if (key_bit_len == YACA_KEY_LENGTH_DH_RFC_1024_160)
909 dh_rfc5114 = 1; /* OpenSSL magic numbers */
910 else if (key_bit_len == YACA_KEY_LENGTH_DH_RFC_2048_224)
912 else if (key_bit_len == YACA_KEY_LENGTH_DH_RFC_2048_256)
915 return YACA_ERROR_INVALID_PARAMETER;
918 return YACA_ERROR_INVALID_PARAMETER;
923 ret = convert_ec_to_nid(key_bit_len, &ec_nid);
924 if (ret != YACA_ERROR_NONE)
929 /* We shouldn't be here */
931 return YACA_ERROR_INTERNAL;
934 pctx = EVP_PKEY_CTX_new_id(evp_id, NULL);
936 ret = YACA_ERROR_INTERNAL;
941 ret = EVP_PKEY_paramgen_init(pctx);
943 ret = YACA_ERROR_INTERNAL;
950 ret = EVP_PKEY_CTX_set_dsa_paramgen_bits(pctx, bit_len);
953 if (dh_rfc5114 > 0) {
954 /* The following code is based on the macro call below.
955 * Unfortunately it doesn't work and the suspected reason is the
956 * fact that the _set_dh_ variant actually passes EVP_PKEY_DHX:
957 * ret = EVP_PKEY_CTX_set_dh_rfc5114(pctx, dh_rfc5114); */
958 ret = EVP_PKEY_CTX_ctrl(pctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN,
959 EVP_PKEY_CTRL_DH_RFC5114, dh_rfc5114, NULL);
961 ret = EVP_PKEY_CTX_set_dh_paramgen_prime_len(pctx, dh_prime_len);
963 ret = EVP_PKEY_CTX_set_dh_paramgen_generator(pctx, dh_generator);
967 ret = EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, ec_nid);
969 ret = EVP_PKEY_CTX_set_ec_param_enc(pctx, OPENSSL_EC_NAMED_CURVE);
973 ret = YACA_ERROR_INTERNAL;
978 ret = EVP_PKEY_paramgen(pctx, params);
979 if (ret != 1 || params == NULL) {
980 ret = YACA_ERROR_INTERNAL;
985 ret = YACA_ERROR_NONE;
988 EVP_PKEY_CTX_free(pctx);
992 static int generate_evp_pkey_key(int evp_id, size_t key_bit_len, EVP_PKEY *params, EVP_PKEY **key)
995 assert(key_bit_len > 0 || params != NULL);
998 EVP_PKEY_CTX *kctx = NULL;
1002 assert(params == NULL);
1003 kctx = EVP_PKEY_CTX_new_id(evp_id, NULL);
1008 if (params == NULL) {
1009 ret = generate_evp_pkey_params(evp_id, key_bit_len, ¶ms);
1010 if (ret != YACA_ERROR_NONE)
1013 CRYPTO_add(¶ms->references, 1, CRYPTO_LOCK_EVP_PKEY);
1016 kctx = EVP_PKEY_CTX_new(params, NULL);
1020 return YACA_ERROR_INTERNAL;
1023 ret = YACA_ERROR_INTERNAL;
1028 ret = EVP_PKEY_keygen_init(kctx);
1030 ret = YACA_ERROR_INTERNAL;
1035 if (evp_id == EVP_PKEY_RSA) {
1036 if ((key_bit_len & YACA_INTERNAL_KEYLEN_TYPE_MASK) != YACA_INTERNAL_KEYLEN_TYPE_BITS ||
1037 key_bit_len > INT_MAX || key_bit_len % 8 != 0) {
1038 ret = YACA_ERROR_INVALID_PARAMETER;
1042 ret = EVP_PKEY_CTX_set_rsa_keygen_bits(kctx, (int)key_bit_len);
1044 ret = ERROR_HANDLE();
1049 ret = EVP_PKEY_keygen(kctx, key);
1050 if (ret != 1 || key == NULL) {
1051 ret = YACA_ERROR_INTERNAL;
1056 ret = YACA_ERROR_NONE;
1059 EVP_PKEY_CTX_free(kctx);
1060 EVP_PKEY_free(params);
1064 static int generate_evp(yaca_key_type_e out_type, size_t key_bit_len,
1065 struct yaca_key_evp_s *params, struct yaca_key_evp_s **out)
1067 assert(out != NULL);
1068 assert(key_bit_len > 0 || params != NULL);
1072 EVP_PKEY *pkey_out = NULL;
1073 EVP_PKEY *pkey_params = NULL;
1075 if (params != NULL) {
1076 yaca_key_type_e key_type;
1077 yaca_key_type_e params_type = params->key.type;
1079 ret = convert_params_to_priv(params_type, &key_type);
1080 if (ret != YACA_ERROR_NONE)
1083 if (out_type != key_type)
1084 return YACA_ERROR_INVALID_PARAMETER;
1086 pkey_params = params->evp;
1090 case YACA_KEY_TYPE_DSA_PARAMS:
1091 case YACA_KEY_TYPE_DH_PARAMS:
1092 case YACA_KEY_TYPE_EC_PARAMS:
1093 assert(params == NULL);
1094 ret = convert_params_to_evp_id(out_type, &evp_id);
1095 if (ret != YACA_ERROR_NONE)
1098 ret = generate_evp_pkey_params(evp_id, key_bit_len, &pkey_out);
1100 case YACA_KEY_TYPE_RSA_PRIV:
1101 case YACA_KEY_TYPE_DSA_PRIV:
1102 case YACA_KEY_TYPE_DH_PRIV:
1103 case YACA_KEY_TYPE_EC_PRIV:
1104 ret = convert_priv_to_evp_id(out_type, &evp_id);
1105 if (ret != YACA_ERROR_NONE)
1108 ret = generate_evp_pkey_key(evp_id, key_bit_len, pkey_params, &pkey_out);
1111 return YACA_ERROR_INVALID_PARAMETER;
1113 if (ret != YACA_ERROR_NONE)
1116 ret = yaca_zalloc(sizeof(struct yaca_key_evp_s), (void**)out);
1117 if (ret != YACA_ERROR_NONE)
1120 (*out)->evp = pkey_out;
1123 ret = YACA_ERROR_NONE;
1126 EVP_PKEY_free(pkey_out);
1130 struct yaca_key_simple_s *key_get_simple(const yaca_key_h key)
1132 struct yaca_key_simple_s *k;
1134 if (key == YACA_KEY_NULL)
1137 switch (key->type) {
1138 case YACA_KEY_TYPE_SYMMETRIC:
1139 case YACA_KEY_TYPE_DES:
1140 case YACA_KEY_TYPE_IV:
1141 k = (struct yaca_key_simple_s *)key;
1144 assert(k->bit_len != 0);
1145 assert(k->bit_len % 8 == 0);
1146 assert(k->d != NULL);
1154 struct yaca_key_evp_s *key_get_evp(const yaca_key_h key)
1156 struct yaca_key_evp_s *k;
1158 if (key == YACA_KEY_NULL)
1161 switch (key->type) {
1162 case YACA_KEY_TYPE_RSA_PUB:
1163 case YACA_KEY_TYPE_RSA_PRIV:
1164 case YACA_KEY_TYPE_DSA_PUB:
1165 case YACA_KEY_TYPE_DSA_PRIV:
1166 case YACA_KEY_TYPE_DSA_PARAMS:
1167 case YACA_KEY_TYPE_DH_PUB:
1168 case YACA_KEY_TYPE_DH_PRIV:
1169 case YACA_KEY_TYPE_DH_PARAMS:
1170 case YACA_KEY_TYPE_EC_PUB:
1171 case YACA_KEY_TYPE_EC_PRIV:
1172 case YACA_KEY_TYPE_EC_PARAMS:
1173 k = (struct yaca_key_evp_s *)key;
1176 assert(k->evp != NULL);
1184 static yaca_key_h key_copy_simple(const struct yaca_key_simple_s *key)
1187 assert(key != NULL);
1189 struct yaca_key_simple_s *copy;
1190 size_t size = sizeof(struct yaca_key_simple_s) + key->bit_len / 8;
1192 ret = yaca_zalloc(size, (void**)©);
1193 if (ret != YACA_ERROR_NONE)
1194 return YACA_KEY_NULL;
1196 memcpy(copy, key, size);
1197 return (yaca_key_h)copy;
1200 static yaca_key_h key_copy_evp(const struct yaca_key_evp_s *key)
1203 assert(key != NULL);
1205 struct yaca_key_evp_s *copy = NULL;
1206 ret = yaca_zalloc(sizeof(struct yaca_key_evp_s), (void**)©);
1207 if (ret != YACA_ERROR_NONE)
1208 return YACA_KEY_NULL;
1210 /* raise the refcount */
1211 CRYPTO_add(&key->evp->references, 1, CRYPTO_LOCK_EVP_PKEY);
1213 copy->key.type = key->key.type;
1214 copy->evp = key->evp;
1215 return (yaca_key_h)copy;
1218 yaca_key_h key_copy(const yaca_key_h key)
1220 struct yaca_key_simple_s *simple = key_get_simple(key);
1221 struct yaca_key_evp_s *evp = key_get_evp(key);
1224 return key_copy_simple(simple);
1225 else if (evp != NULL)
1226 return key_copy_evp(evp);
1228 return YACA_KEY_NULL;
1231 API int yaca_key_get_type(const yaca_key_h key, yaca_key_type_e *key_type)
1233 const struct yaca_key_s *lkey = (const struct yaca_key_s *)key;
1235 if (lkey == NULL || key_type == NULL)
1236 return YACA_ERROR_INVALID_PARAMETER;
1238 *key_type = lkey->type;
1239 return YACA_ERROR_NONE;
1242 API int yaca_key_get_bit_length(const yaca_key_h key, size_t *key_bit_len)
1244 const struct yaca_key_simple_s *simple_key = key_get_simple(key);
1245 const struct yaca_key_evp_s *evp_key = key_get_evp(key);
1247 if (key_bit_len == NULL)
1248 return YACA_ERROR_INVALID_PARAMETER;
1250 if (simple_key != NULL) {
1251 *key_bit_len = simple_key->bit_len;
1252 return YACA_ERROR_NONE;
1255 if (evp_key != NULL) {
1258 switch (evp_key->key.type) {
1259 case YACA_KEY_TYPE_RSA_PRIV:
1260 case YACA_KEY_TYPE_RSA_PUB:
1261 case YACA_KEY_TYPE_DSA_PRIV:
1262 case YACA_KEY_TYPE_DSA_PUB:
1263 case YACA_KEY_TYPE_DH_PRIV:
1264 case YACA_KEY_TYPE_DH_PUB:
1265 ret = EVP_PKEY_bits(evp_key->evp);
1267 ret = YACA_ERROR_INTERNAL;
1273 return YACA_ERROR_NONE;
1274 case YACA_KEY_TYPE_EC_PRIV:
1275 case YACA_KEY_TYPE_EC_PUB: {
1276 assert(EVP_PKEY_type(evp_key->evp->type) == EVP_PKEY_EC);
1278 const EC_KEY *eck = EVP_PKEY_get0(evp_key->evp);
1279 const EC_GROUP *ecg = EC_KEY_get0_group(eck);
1280 int flags = EC_GROUP_get_asn1_flag(ecg);
1283 if (!(flags & OPENSSL_EC_NAMED_CURVE))
1284 /* This is case of a custom (not named) curve, that can happen when someone
1285 imports such a key into YACA. There is nothing that can be returned here */
1286 return YACA_ERROR_INVALID_PARAMETER;
1288 nid = EC_GROUP_get_curve_name(ecg);
1289 return convert_nid_to_ec(nid, key_bit_len);
1292 /* We shouldn't be here */
1294 return YACA_ERROR_INTERNAL;
1298 return YACA_ERROR_INVALID_PARAMETER;
1301 API int yaca_key_import(yaca_key_type_e key_type,
1302 const char *password,
1307 if (key == NULL || data == NULL || data_len == 0)
1308 return YACA_ERROR_INVALID_PARAMETER;
1310 /* allow an empty password, OpenSSL returns an error with "" */
1311 if (password != NULL && password[0] == '\0')
1315 case YACA_KEY_TYPE_SYMMETRIC:
1316 case YACA_KEY_TYPE_DES:
1317 case YACA_KEY_TYPE_IV:
1318 if (password != NULL)
1319 return YACA_ERROR_INVALID_PARAMETER;
1320 return import_simple(key, key_type, data, data_len);
1321 case YACA_KEY_TYPE_RSA_PUB:
1322 case YACA_KEY_TYPE_RSA_PRIV:
1323 case YACA_KEY_TYPE_DSA_PUB:
1324 case YACA_KEY_TYPE_DSA_PRIV:
1325 return import_evp(key, key_type, password, data, data_len);
1326 case YACA_KEY_TYPE_DH_PUB:
1327 case YACA_KEY_TYPE_DH_PRIV:
1328 case YACA_KEY_TYPE_EC_PUB:
1329 case YACA_KEY_TYPE_EC_PRIV:
1330 //TODO NOT_IMPLEMENTED
1332 return YACA_ERROR_INVALID_PARAMETER;
1336 API int yaca_key_export(const yaca_key_h key,
1337 yaca_key_format_e key_fmt,
1338 yaca_key_file_format_e key_file_fmt,
1339 const char *password,
1343 struct yaca_key_simple_s *simple_key = key_get_simple(key);
1344 struct yaca_key_evp_s *evp_key = key_get_evp(key);
1346 if (data == NULL || data_len == NULL)
1347 return YACA_ERROR_INVALID_PARAMETER;
1349 /* allow an empty password, OpenSSL returns an error with "" */
1350 if (password != NULL && password[0] == '\0')
1353 if (password != NULL && simple_key != NULL)
1354 return YACA_ERROR_INVALID_PARAMETER;
1356 if (key_fmt == YACA_KEY_FORMAT_DEFAULT &&
1357 key_file_fmt == YACA_KEY_FILE_FORMAT_RAW &&
1359 return export_simple_raw(simple_key, data, data_len);
1361 if (key_fmt == YACA_KEY_FORMAT_DEFAULT &&
1362 key_file_fmt == YACA_KEY_FILE_FORMAT_BASE64 &&
1364 return export_simple_base64(simple_key, data, data_len);
1366 if (evp_key != NULL)
1367 return export_evp(evp_key, key_fmt, key_file_fmt,
1368 password, data, data_len);
1370 return YACA_ERROR_INVALID_PARAMETER;
1373 API int yaca_key_generate(yaca_key_type_e key_type,
1378 struct yaca_key_simple_s *nk_simple = NULL;
1379 struct yaca_key_evp_s *nk_evp = NULL;
1381 if (key == NULL || key_bit_len == 0)
1382 return YACA_ERROR_INVALID_PARAMETER;
1385 case YACA_KEY_TYPE_SYMMETRIC:
1386 case YACA_KEY_TYPE_IV:
1387 ret = generate_simple(&nk_simple, key_bit_len);
1389 case YACA_KEY_TYPE_DES:
1390 ret = generate_simple_des(&nk_simple, key_bit_len);
1392 case YACA_KEY_TYPE_RSA_PRIV:
1393 case YACA_KEY_TYPE_DSA_PRIV:
1394 case YACA_KEY_TYPE_DSA_PARAMS:
1395 case YACA_KEY_TYPE_DH_PRIV:
1396 case YACA_KEY_TYPE_DH_PARAMS:
1397 case YACA_KEY_TYPE_EC_PRIV:
1398 case YACA_KEY_TYPE_EC_PARAMS:
1399 ret = generate_evp(key_type, key_bit_len, NULL, &nk_evp);
1402 return YACA_ERROR_INVALID_PARAMETER;
1405 if (ret != YACA_ERROR_NONE)
1408 if (nk_simple != NULL) {
1409 nk_simple->key.type = key_type;
1410 *key = (yaca_key_h)nk_simple;
1411 } else if (nk_evp != NULL) {
1412 nk_evp->key.type = key_type;
1413 *key = (yaca_key_h)nk_evp;
1418 return YACA_ERROR_NONE;
1421 API int yaca_key_generate_from_parameters(const yaca_key_h params, yaca_key_h *prv_key)
1424 struct yaca_key_evp_s *evp_params = key_get_evp(params);
1425 yaca_key_type_e params_type;
1426 yaca_key_type_e key_type;
1427 struct yaca_key_evp_s *nk_evp = NULL;
1429 if (evp_params == NULL || prv_key == NULL)
1430 return YACA_ERROR_INVALID_PARAMETER;
1432 ret = yaca_key_get_type(params, ¶ms_type);
1433 if (ret != YACA_ERROR_NONE)
1436 ret = convert_params_to_priv(params_type, &key_type);
1437 if (ret != YACA_ERROR_NONE)
1440 ret = generate_evp(key_type, 0, evp_params, &nk_evp);
1441 if (ret != YACA_ERROR_NONE)
1444 assert(nk_evp != NULL);
1446 nk_evp->key.type = key_type;
1447 *prv_key = (yaca_key_h)nk_evp;
1449 return YACA_ERROR_NONE;
1452 API int yaca_key_extract_public(const yaca_key_h prv_key, yaca_key_h *pub_key)
1455 struct yaca_key_evp_s *evp_key = key_get_evp(prv_key);
1456 struct yaca_key_evp_s *nk;
1458 EVP_PKEY *pkey = NULL;
1460 if (prv_key == YACA_KEY_NULL || evp_key == NULL || pub_key == NULL)
1461 return YACA_ERROR_INVALID_PARAMETER;
1463 ret = yaca_zalloc(sizeof(struct yaca_key_evp_s), (void**)&nk);
1464 if (ret != YACA_ERROR_NONE)
1467 mem = BIO_new(BIO_s_mem());
1469 ret = YACA_ERROR_INTERNAL;
1474 ret = i2d_PUBKEY_bio(mem, evp_key->evp);
1476 ret = YACA_ERROR_INTERNAL;
1481 pkey = d2i_PUBKEY_bio(mem, NULL);
1483 ret = YACA_ERROR_INTERNAL;
1491 switch (prv_key->type) {
1492 case YACA_KEY_TYPE_RSA_PRIV:
1493 nk->key.type = YACA_KEY_TYPE_RSA_PUB;
1495 case YACA_KEY_TYPE_DSA_PRIV:
1496 nk->key.type = YACA_KEY_TYPE_DSA_PUB;
1498 case YACA_KEY_TYPE_DH_PRIV:
1499 nk->key.type = YACA_KEY_TYPE_DH_PUB;
1501 case YACA_KEY_TYPE_EC_PRIV:
1502 nk->key.type = YACA_KEY_TYPE_EC_PUB;
1505 ret = YACA_ERROR_INVALID_PARAMETER;
1511 *pub_key = (yaca_key_h)nk;
1513 ret = YACA_ERROR_NONE;
1516 EVP_PKEY_free(pkey);
1523 API void yaca_key_destroy(yaca_key_h key)
1525 struct yaca_key_simple_s *simple_key = key_get_simple(key);
1526 struct yaca_key_evp_s *evp_key = key_get_evp(key);
1528 if (simple_key != NULL)
1529 yaca_free(simple_key);
1531 if (evp_key != NULL) {
1532 EVP_PKEY_free(evp_key->evp);
1537 API int yaca_key_derive_dh(const yaca_key_h prv_key,
1538 const yaca_key_h pub_key,
1539 yaca_key_h *sym_key)
1542 struct yaca_key_evp_s *lprv_key = key_get_evp(prv_key);
1543 struct yaca_key_evp_s *lpub_key = key_get_evp(pub_key);
1544 struct yaca_key_simple_s *nk = NULL;
1548 if (lprv_key == NULL || lpub_key == NULL || sym_key == NULL ||
1549 (!(lprv_key->key.type == YACA_KEY_TYPE_DH_PRIV &&
1550 lpub_key->key.type == YACA_KEY_TYPE_DH_PUB)
1552 !(lprv_key->key.type == YACA_KEY_TYPE_EC_PRIV &&
1553 lpub_key->key.type == YACA_KEY_TYPE_EC_PUB)))
1554 return YACA_ERROR_INVALID_PARAMETER;
1556 ctx = EVP_PKEY_CTX_new(lprv_key->evp, NULL);
1558 ret = YACA_ERROR_INTERNAL;
1563 ret = EVP_PKEY_derive_init(ctx);
1565 ret = YACA_ERROR_INTERNAL;
1570 ret = EVP_PKEY_derive_set_peer(ctx, lpub_key->evp);
1572 ret = YACA_ERROR_INTERNAL;
1577 ret = EVP_PKEY_derive(ctx, NULL, &nk_len);
1579 ret = YACA_ERROR_INTERNAL;
1584 if (nk_len == 0 || nk_len > SIZE_MAX / 8) {
1585 ret = YACA_ERROR_INVALID_PARAMETER;
1589 ret = yaca_zalloc(sizeof(struct yaca_key_simple_s) + nk_len, (void**)&nk);
1590 if (ret != YACA_ERROR_NONE)
1593 ret = EVP_PKEY_derive(ctx, (unsigned char*)nk->d, &nk_len);
1595 ret = YACA_ERROR_INTERNAL;
1600 nk->bit_len = nk_len * 8;
1601 nk->key.type = YACA_KEY_TYPE_SYMMETRIC;
1602 *sym_key = (yaca_key_h)nk;
1604 ret = YACA_ERROR_NONE;
1607 EVP_PKEY_CTX_free(ctx);
1612 API int yaca_key_derive_pbkdf2(const char *password,
1616 yaca_digest_algorithm_e algo,
1621 struct yaca_key_simple_s *nk;
1622 size_t key_byte_len = key_bit_len / 8;
1625 if (password == NULL ||
1626 (salt == NULL && salt_len > 0) || (salt != NULL && salt_len == 0) ||
1627 iterations == 0 || key_bit_len == 0 || key == NULL)
1628 return YACA_ERROR_INVALID_PARAMETER;
1630 if (key_bit_len % 8) /* Key length must be multiple of 8-bit_len */
1631 return YACA_ERROR_INVALID_PARAMETER;
1633 if (iterations > INT_MAX) /* OpenSSL limitation */
1634 return YACA_ERROR_INVALID_PARAMETER;
1636 ret = digest_get_algorithm(algo, &md);
1637 if (ret != YACA_ERROR_NONE)
1640 ret = yaca_zalloc(sizeof(struct yaca_key_simple_s) + key_byte_len, (void**)&nk);
1641 if (ret != YACA_ERROR_NONE)
1644 nk->bit_len = key_bit_len;
1645 nk->key.type = YACA_KEY_TYPE_SYMMETRIC; // TODO: how to handle other keys?
1647 ret = PKCS5_PBKDF2_HMAC(password, -1, (const unsigned char*)salt,
1648 salt_len, iterations, md, key_byte_len,
1649 (unsigned char*)nk->d);
1651 ret = YACA_ERROR_INTERNAL;
1656 *key = (yaca_key_h)nk;
1658 ret = YACA_ERROR_NONE;