3 #endif /* ifdef HAVE_CONFIG_H */
8 # define alloca __builtin_alloca
10 # define alloca __alloca
11 #elif defined _MSC_VER
13 # define alloca _alloca
14 #else /* ifdef HAVE_ALLOCA_H */
18 # endif /* ifdef __cplusplus */
20 #endif /* ifdef HAVE_ALLOCA_H */
24 #include <sys/types.h>
29 #endif /* ifdef HAVE_UNISTD_H */
31 #ifdef HAVE_NETINET_IN_H
32 # include <netinet/in.h>
33 #endif /* ifdef HAVE_NETINET_IN_H */
36 # include <sys/mman.h>
38 # include <gnutls/gnutls.h>
39 # include <gnutls/x509.h>
40 # else /* ifdef HAVE_GNUTLS */
41 # include <openssl/rsa.h>
42 # include <openssl/objects.h>
43 # include <openssl/err.h>
44 # include <openssl/ssl.h>
45 # include <openssl/dh.h>
46 # include <openssl/dsa.h>
47 # include <openssl/evp.h>
48 # include <openssl/x509.h>
49 # include <openssl/pem.h>
50 # endif /* ifdef HAVE_GNUTLS */
51 #endif /* ifdef HAVE_SIGNATURE */
54 # include <openssl/sha.h>
55 #endif /* ifdef HAVE_OPENSSL */
59 # if defined EET_USE_NEW_PUBKEY_VERIFY_HASH || defined EET_USE_NEW_PRIVKEY_SIGN_DATA
60 # include <gnutls/abstract.h>
62 # include <gnutls/x509.h>
64 # else /* ifdef HAVE_GNUTLS */
65 # include <openssl/evp.h>
66 # include <openssl/hmac.h>
67 # include <openssl/rand.h>
68 # endif /* ifdef HAVE_GNUTLS */
69 #endif /* ifdef HAVE_CIPHER */
72 #include "Eet_private.h"
74 #define EET_MAGIC_SIGN 0x1ee74271
77 # define MAX_KEY_LEN 32
78 # define MAX_IV_LEN 16
79 #else /* ifdef HAVE_GNUTLS */
80 # define MAX_KEY_LEN EVP_MAX_KEY_LENGTH
81 # define MAX_IV_LEN EVP_MAX_IV_LENGTH
82 #endif /* ifdef HAVE_GNUTLS */
87 eet_hmac_sha1(const void *key,
92 # endif /* ifdef HAVE_GNUTLS */
94 eet_pbkdf2_sha1(const char *key,
96 const unsigned char *salt,
97 unsigned int salt_len,
101 #endif /* ifdef HAVE_CIPHER */
106 #ifdef HAVE_SIGNATURE
108 gnutls_x509_crt_t certificate;
109 gnutls_x509_privkey_t private_key;
110 # else /* ifdef HAVE_GNUTLS */
112 EVP_PKEY *private_key;
113 # endif /* ifdef HAVE_GNUTLS */
114 #endif /* ifdef HAVE_SIGNATURE */
118 eet_identity_open(const char *certificate_file,
119 const char *private_key_file,
120 Eet_Key_Password_Callback cb)
122 #ifdef HAVE_SIGNATURE
123 /* Signature declarations */
126 /* Gnutls private declarations */
129 gnutls_datum_t load_file = { NULL, 0 };
133 if (!(key = malloc(sizeof(Eet_Key))))
138 if (gnutls_x509_crt_init(&(key->certificate)))
141 if (gnutls_x509_privkey_init(&(key->private_key)))
144 /* Mmap certificate_file */
145 f = eina_file_open(certificate_file, 0);
149 /* let's make mmap safe and just get 0 pages for IO erro */
150 eina_mmap_safety_enabled_set(EINA_TRUE);
152 data = eina_file_map_all(f, EINA_FILE_SEQUENTIAL);
153 if (!data) goto on_error;
155 /* Import the certificate in Eet_Key structure */
156 load_file.data = data;
157 load_file.size = eina_file_size_get(f);
158 if (gnutls_x509_crt_import(key->certificate, &load_file,
159 GNUTLS_X509_FMT_PEM) < 0)
162 eina_file_map_free(f, data);
168 load_file.data = NULL;
171 /* Mmap private_key_file */
172 f = eina_file_open(private_key_file, 0);
176 /* let's make mmap safe and just get 0 pages for IO erro */
177 eina_mmap_safety_enabled_set(EINA_TRUE);
179 data = eina_file_map_all(f, EINA_FILE_SEQUENTIAL);
183 /* Import the private key in Eet_Key structure */
184 load_file.data = data;
185 load_file.size = eina_file_size_get(f);
186 /* Try to directly import the PEM encoded private key */
187 if (gnutls_x509_privkey_import(key->private_key, &load_file,
188 GNUTLS_X509_FMT_PEM) < 0)
190 /* Else ask for the private key pass */
191 if (cb && cb(pass, 1024, 0, NULL))
193 /* If pass then try to decode the pkcs 8 private key */
194 if (gnutls_x509_privkey_import_pkcs8(key->private_key, &load_file,
195 GNUTLS_X509_FMT_PEM, pass, 0))
199 /* Else try to import the pkcs 8 private key without pass */
200 if (gnutls_x509_privkey_import_pkcs8(key->private_key, &load_file,
201 GNUTLS_X509_FMT_PEM, NULL, 1))
205 eina_file_map_free(f, data);
211 if (data) eina_file_map_free(f, data);
212 if (f) eina_file_close(f);
216 if (key->certificate)
217 gnutls_x509_crt_deinit(key->certificate);
219 if (key->private_key)
220 gnutls_x509_privkey_deinit(key->private_key);
225 # else /* ifdef HAVE_GNUTLS */
226 /* Openssl private declarations */
228 EVP_PKEY *pkey = NULL;
231 /* Load the X509 certificate in memory. */
232 fp = fopen(certificate_file, "r");
236 cert = PEM_read_X509(fp, NULL, NULL, NULL);
241 /* Check the presence of the public key. Just in case. */
242 pkey = X509_get_pubkey(cert);
246 /* Load the private key in memory. */
247 fp = fopen(private_key_file, "r");
251 pkey = PEM_read_PrivateKey(fp, NULL, cb, NULL);
256 /* Load the certificate and the private key in Eet_Key structure */
257 key = malloc(sizeof(Eet_Key));
262 key->certificate = cert;
263 key->private_key = pkey;
274 # endif /* ifdef HAVE_GNUTLS */
276 certificate_file = NULL;
277 private_key_file = NULL;
279 #endif /* ifdef HAVE_SIGNATURE */
284 eet_identity_close(Eet_Key *key)
286 #ifdef HAVE_SIGNATURE
287 if (!key || (key->references > 0))
291 gnutls_x509_crt_deinit(key->certificate);
292 gnutls_x509_privkey_deinit(key->private_key);
293 # else /* ifdef HAVE_GNUTLS */
294 X509_free(key->certificate);
295 EVP_PKEY_free(key->private_key);
296 # endif /* ifdef HAVE_GNUTLS */
300 #endif /* ifdef HAVE_SIGNATURE */
304 eet_identity_print(Eet_Key *key,
307 #ifdef HAVE_SIGNATURE
309 const char *names[6] = {
318 gnutls_datum_t data = { NULL, 0 };
319 gnutls_datum_t rsa_raw[6];
328 if (key->private_key)
330 if (gnutls_x509_privkey_export_rsa_raw(key->private_key,
331 rsa_raw + 0, /* Modulus */
332 rsa_raw + 1, /* Public exponent */
333 rsa_raw + 2, /* Private exponent */
334 rsa_raw + 3, /* First prime */
335 rsa_raw + 4, /* Second prime */
336 rsa_raw + 5)) /* Coefficient */
339 if (!(res = malloc(size)))
342 fprintf(out, "Private Key:\n");
345 for (i = 0; i < 6; i++)
347 while ((err = gnutls_hex_encode(rsa_raw + i, res, &size)) ==
348 GNUTLS_E_SHORT_MEMORY_BUFFER)
351 if (!(res = realloc(res, size)))
357 fprintf(out, "\t%s:\n", names[i]);
358 for (j = 0; strlen(res) > j; j += 32)
360 snprintf(buf, 32, "%s", res + j);
361 fprintf(out, "\t\t%s\n", buf);
368 if (key->certificate)
370 fprintf(out, "Public certificate:\n");
371 if (gnutls_x509_crt_print(key->certificate, GNUTLS_X509_CRT_FULL,
375 fprintf(out, "%s\n", data.data);
376 gnutls_free(data.data);
385 gnutls_free(data.data);
388 # else /* ifdef HAVE_GNUTLS */
396 rsa = EVP_PKEY_get1_RSA(key->private_key);
399 fprintf(out, "Private key (RSA):\n");
400 RSA_print_fp(out, rsa, 0);
403 dsa = EVP_PKEY_get1_DSA(key->private_key);
406 fprintf(out, "Private key (DSA):\n");
407 DSA_print_fp(out, dsa, 0);
410 dh = EVP_PKEY_get1_DH(key->private_key);
413 fprintf(out, "Private key (DH):\n");
414 DHparams_print_fp(out, dh);
417 fprintf(out, "Public certificate:\n");
418 X509_print_fp(out, key->certificate);
419 # endif /* ifdef HAVE_GNUTLS */
420 #else /* ifdef HAVE_SIGNATURE */
423 ERR("You need to compile signature support in EET.");
424 #endif /* ifdef HAVE_SIGNATURE */
428 eet_identity_ref(Eet_Key *key)
437 eet_identity_unref(Eet_Key *key)
443 eet_identity_close(key);
447 eet_identity_compute_sha1(const void *data_base,
448 unsigned int data_length,
453 #ifdef HAVE_SIGNATURE
455 result = malloc(gcry_md_get_algo_dlen(GCRY_MD_SHA1));
459 gcry_md_hash_buffer(GCRY_MD_SHA1, result, data_base, data_length);
461 *sha1_length = gcry_md_get_algo_dlen(GCRY_MD_SHA1);
463 # else /* ifdef HAVE_GNUTLS */
465 result = malloc(SHA_DIGEST_LENGTH);
469 SHA1(data_base, data_length, result);
471 *sha1_length = SHA_DIGEST_LENGTH;
473 # else /* ifdef HAVE_OPENSSL */
475 # endif /* ifdef HAVE_OPENSSL */
476 # endif /* ifdef HAVE_GNUTLS */
477 #else /* ifdef HAVE_SIGNATURE */
482 #endif /* ifdef HAVE_SIGNATURE */
488 eet_identity_sign(FILE *fp,
491 #ifdef HAVE_SIGNATURE
492 Eet_Error err = EET_ERROR_NONE;
497 unsigned char *sign = NULL;
498 unsigned char *cert = NULL;
500 gnutls_datum_t datum = { NULL, 0 };
503 #ifdef EET_USE_NEW_PRIVKEY_SIGN_DATA
504 gnutls_datum_t signum = { NULL, 0 };
505 gnutls_privkey_t privkey;
507 # else /* ifdef HAVE_GNUTLS */
509 unsigned int sign_len = 0;
511 # endif /* ifdef HAVE_GNUTLS */
513 /* A few check and flush pending write. */
514 if (!fp || !key || !key->certificate || !key->private_key)
515 return EET_ERROR_BAD_OBJECT;
517 /* Get the file size. */
520 return EET_ERROR_BAD_OBJECT;
522 if (fstat(fd, &st_buf) < 0)
523 return EET_ERROR_MMAP_FAILED;
525 /* let's make mmap safe and just get 0 pages for IO erro */
526 eina_mmap_safety_enabled_set(EINA_TRUE);
528 /* Map the file in memory. */
529 data = mmap(NULL, st_buf.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
530 if (data == MAP_FAILED)
531 return EET_ERROR_MMAP_FAILED;
535 datum.size = st_buf.st_size;
537 /* Get the signature length */
538 #ifdef EET_USE_NEW_PRIVKEY_SIGN_DATA
539 if (gnutls_privkey_init(&privkey) < 0)
541 err = EET_ERROR_SIGNATURE_FAILED;
545 if (gnutls_privkey_import_x509(privkey, key->private_key, 0) < 0)
547 err = EET_ERROR_SIGNATURE_FAILED;
551 if (gnutls_privkey_sign_data(privkey, GNUTLS_DIG_SHA1, 0, &datum, &signum) < 0)
553 err = EET_ERROR_SIGNATURE_FAILED;
558 sign_len = signum.size;
560 if (gnutls_x509_privkey_sign_data(key->private_key, GNUTLS_DIG_SHA1, 0,
561 &datum, sign, &sign_len) &&
564 err = EET_ERROR_SIGNATURE_FAILED;
568 /* Get the signature */
569 sign = malloc(sign_len);
571 gnutls_x509_privkey_sign_data(key->private_key, GNUTLS_DIG_SHA1, 0,
576 err = EET_ERROR_OUT_OF_MEMORY;
578 err = EET_ERROR_SIGNATURE_FAILED;
584 /* Get the certificate length */
585 if (gnutls_x509_crt_export(key->certificate, GNUTLS_X509_FMT_DER, cert,
589 err = EET_ERROR_SIGNATURE_FAILED;
593 /* Get the certificate */
594 cert = malloc(cert_len);
596 gnutls_x509_crt_export(key->certificate, GNUTLS_X509_FMT_DER, cert,
600 err = EET_ERROR_OUT_OF_MEMORY;
602 err = EET_ERROR_SIGNATURE_FAILED;
607 # else /* ifdef HAVE_GNUTLS */
608 sign_len = EVP_PKEY_size(key->private_key);
609 sign = malloc(sign_len);
612 err = EET_ERROR_OUT_OF_MEMORY;
616 /* Do the signature. */
617 EVP_SignInit(&md_ctx, EVP_sha1());
618 EVP_SignUpdate(&md_ctx, data, st_buf.st_size);
619 err = EVP_SignFinal(&md_ctx,
621 (unsigned int *)&sign_len,
625 ERR_print_errors_fp(stdout);
626 err = EET_ERROR_SIGNATURE_FAILED;
630 /* Give me the der (binary form for X509). */
631 cert_len = i2d_X509(key->certificate, &cert);
634 ERR_print_errors_fp(stdout);
635 err = EET_ERROR_X509_ENCODING_FAILED;
639 # endif /* ifdef HAVE_GNUTLS */
640 /* Append the signature at the end of the file. */
641 head[0] = (int)htonl ((unsigned int)EET_MAGIC_SIGN);
642 head[1] = (int)htonl ((unsigned int)sign_len);
643 head[2] = (int)htonl ((unsigned int)cert_len);
645 if (fwrite(head, sizeof(head), 1, fp) != 1)
647 err = EET_ERROR_WRITE_ERROR;
651 if (fwrite(sign, sign_len, 1, fp) != 1)
653 err = EET_ERROR_WRITE_ERROR;
657 if (fwrite(cert, cert_len, 1, fp) != 1)
659 err = EET_ERROR_WRITE_ERROR;
668 # else /* ifdef HAVE_GNUTLS */
672 # endif /* ifdef HAVE_GNUTLS */
676 munmap(data, st_buf.st_size);
678 #else /* ifdef HAVE_SIGNATURE */
681 return EET_ERROR_NOT_IMPLEMENTED;
682 #endif /* ifdef HAVE_SIGNATURE */
686 eet_identity_check(const void *data_base,
687 unsigned int data_length,
690 const void *signature_base,
691 unsigned int signature_length,
692 const void **raw_signature_base,
693 unsigned int *raw_signature_length,
696 #ifdef HAVE_SIGNATURE
697 const int *header = signature_base;
698 const unsigned char *sign;
699 const unsigned char *cert_der;
704 /* At least the header size */
705 if (signature_length < sizeof(int) * 3)
709 magic = ntohl(header[0]);
710 sign_len = ntohl(header[1]);
711 cert_len = ntohl(header[2]);
713 /* Verify the header */
714 if (magic != EET_MAGIC_SIGN)
717 if (sign_len + cert_len + sizeof(int) * 3 > signature_length)
720 /* Update the signature and certificate pointer */
721 sign = (unsigned char *)signature_base + sizeof(int) * 3;
722 cert_der = sign + sign_len;
725 gnutls_x509_crt_t cert;
726 gnutls_datum_t datum;
727 gnutls_datum_t signature;
728 # if EET_USE_NEW_GNUTLS_API
729 # if EET_USE_NEW_PUBKEY_VERIFY_HASH
730 gnutls_pubkey_t pubkey;
731 gnutls_digest_algorithm_t hash_algo;
736 # endif /* if EET_USE_NEW_GNUTLS_API */
738 /* Create an understanding certificate structure for gnutls */
739 datum.data = (void *)cert_der;
740 datum.size = cert_len;
741 gnutls_x509_crt_init(&cert);
742 gnutls_x509_crt_import(cert, &datum, GNUTLS_X509_FMT_DER);
744 signature.data = (void *)sign;
745 signature.size = sign_len;
747 /* Verify the signature */
748 # if EET_USE_NEW_GNUTLS_API
750 I am waiting for my patch being accepted in GnuTLS release.
751 But we now have a way to prevent double computation of SHA1.
753 err = gcry_md_open (&md, GCRY_MD_SHA1, 0);
757 gcry_md_write(md, data_base, data_length);
759 hash = gcry_md_read(md, GCRY_MD_SHA1);
763 datum.size = gcry_md_get_algo_dlen(GCRY_MD_SHA1);
766 # ifdef EET_USE_NEW_PUBKEY_VERIFY_HASH
767 if (gnutls_pubkey_init(&pubkey) < 0)
770 if (gnutls_pubkey_import_x509(pubkey, cert, 0) < 0)
773 if (gnutls_pubkey_get_verify_algorithm(pubkey, &signature, &hash_algo) < 0)
776 if (gnutls_pubkey_verify_hash(pubkey, 0, &datum, &signature) < 0)
779 if (!gnutls_x509_crt_verify_hash(cert, 0, &datum, &signature))
785 *sha1 = malloc(datum.size);
786 if (!*sha1) goto on_error;
788 memcpy(*sha1, hash, datum.size);
789 *sha1_length = datum.size;
793 # else /* if EET_USE_NEW_GNUTLS_API */
794 datum.data = (void *)data_base;
795 datum.size = data_length;
797 if (!gnutls_x509_crt_verify_data(cert, 0, &datum, &signature))
806 # endif /* if EET_USE_NEW_GNUTLS_API */
807 gnutls_x509_crt_deinit(cert);
809 # else /* ifdef HAVE_GNUTLS */
810 const unsigned char *tmp;
816 /* Strange but d2i_X509 seems to put 0 all over the place. */
817 tmp = alloca(cert_len);
818 memcpy((char *)tmp, cert_der, cert_len);
819 x509 = d2i_X509(NULL, &tmp, cert_len);
823 /* Get public key - eay */
824 pkey = X509_get_pubkey(x509);
831 /* Verify the signature */
832 EVP_VerifyInit(&md_ctx, EVP_sha1());
833 EVP_VerifyUpdate(&md_ctx, data_base, data_length);
834 err = EVP_VerifyFinal(&md_ctx, sign, sign_len, pkey);
848 # endif /* ifdef HAVE_GNUTLS */
850 *x509_length = cert_len;
852 if (raw_signature_base)
853 *raw_signature_base = sign;
855 if (raw_signature_length)
856 *raw_signature_length = sign_len;
860 # if EET_USE_NEW_GNUTLS_API
866 #else /* ifdef HAVE_SIGNATURE */
871 signature_base = NULL;
872 signature_length = 0;
873 raw_signature_base = NULL;
874 raw_signature_length = NULL;
877 #endif /* ifdef HAVE_SIGNATURE */
881 eet_identity_certificate_print(const unsigned char *certificate,
885 #ifdef HAVE_SIGNATURE
886 if (!certificate || !out || der_length <= 0)
888 ERR("No certificate provided.");
893 gnutls_datum_t datum;
894 gnutls_x509_crt_t cert;
896 /* Create an understanding certificate structure for gnutls */
897 datum.data = (void *)certificate;
898 datum.size = der_length;
899 if (gnutls_x509_crt_init(&cert))
902 if (gnutls_x509_crt_import(cert, &datum, GNUTLS_X509_FMT_DER))
905 /* Pretty print the certificate */
908 if (gnutls_x509_crt_print(cert, GNUTLS_X509_CRT_FULL, &datum))
911 INF("Public certificate :");
912 INF("%s", datum.data);
916 gnutls_free(datum.data);
918 gnutls_x509_crt_deinit(cert);
919 # else /* ifdef HAVE_GNUTLS */
920 const unsigned char *tmp;
923 /* Strange but d2i_X509 seems to put 0 all over the place. */
924 tmp = alloca(der_length);
925 memcpy((char *)tmp, certificate, der_length);
926 x509 = d2i_X509(NULL, &tmp, der_length);
929 INF("Not a valid certificate.");
933 INF("Public certificate :");
934 X509_print_fp(out, x509);
937 # endif /* ifdef HAVE_GNUTLS */
938 #else /* ifdef HAVE_SIGNATURE */
942 ERR("You need to compile signature support in EET.");
943 #endif /* ifdef HAVE_SIGNATURE */
947 eet_cipher(const void *data,
952 unsigned int *result_length)
955 /* Cipher declarations */
956 unsigned int *ret = NULL;
957 unsigned char iv[MAX_IV_LEN];
958 unsigned char ik[MAX_KEY_LEN];
959 unsigned char key_material[MAX_IV_LEN + MAX_KEY_LEN];
961 unsigned int tmp = 0;
965 /* Gcrypt declarations */
966 gcry_error_t err = 0;
967 gcry_cipher_hd_t cipher;
968 # else /* ifdef HAVE_GNUTLS */
969 /* Openssl declarations*/
971 unsigned int *buffer = NULL;
973 # endif /* ifdef HAVE_GNUTLS */
976 /* Gcrypt salt generation */
977 gcry_create_nonce((unsigned char *)&salt, sizeof(salt));
978 # else /* ifdef HAVE_GNUTLS */
979 /* Openssl salt generation */
980 if (!RAND_bytes((unsigned char *)&salt, sizeof (unsigned int)))
981 return EET_ERROR_PRNG_NOT_SEEDED;
983 # endif /* ifdef HAVE_GNUTLS */
987 (unsigned char *)&salt,
988 sizeof(unsigned int),
991 MAX_KEY_LEN + MAX_IV_LEN);
993 memcpy(iv, key_material, MAX_IV_LEN);
994 memcpy(ik, key_material + MAX_IV_LEN, MAX_KEY_LEN);
996 memset(key_material, 0, sizeof (key_material));
998 crypted_length = ((((size + sizeof (unsigned int)) >> 5) + 1) << 5);
999 ret = malloc(crypted_length + sizeof(unsigned int));
1002 memset(iv, 0, sizeof (iv));
1003 memset(ik, 0, sizeof (ik));
1004 memset(&salt, 0, sizeof (salt));
1005 return EET_ERROR_OUT_OF_MEMORY;
1009 memset(&salt, 0, sizeof (salt));
1014 memcpy(ret + 2, data, size);
1016 /* Gcrypt create the corresponding cipher
1017 AES with a 256 bit key, Cipher Block Chaining mode */
1018 err = gcry_cipher_open(&cipher, GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC, 0);
1023 err = gcry_cipher_setiv(cipher, iv, MAX_IV_LEN);
1027 err = gcry_cipher_setkey(cipher, ik, MAX_KEY_LEN);
1031 memset(iv, 0, sizeof (iv));
1032 memset(ik, 0, sizeof (ik));
1034 /* Gcrypt encrypt */
1035 err = gcry_cipher_encrypt(cipher,
1036 (unsigned char *)(ret + 1),
1043 /* Gcrypt close the cipher */
1044 gcry_cipher_close(cipher);
1045 # else /* ifdef HAVE_GNUTLS */
1046 buffer = malloc(crypted_length);
1047 if (!buffer) goto on_error;
1050 memcpy(buffer + 1, data, size);
1052 /* Openssl create the corresponding cipher
1053 AES with a 256 bit key, Cipher Block Chaining mode */
1054 EVP_CIPHER_CTX_init(&ctx);
1055 if (!EVP_EncryptInit_ex(&ctx, EVP_aes_256_cbc(), NULL, ik, iv))
1060 memset(iv, 0, sizeof (iv));
1061 memset(ik, 0, sizeof (ik));
1063 /* Openssl encrypt */
1064 if (!EVP_EncryptUpdate(&ctx, (unsigned char *)(ret + 1), &tmp_len,
1065 (unsigned char *)buffer,
1066 size + sizeof(unsigned int)))
1069 /* Openssl close the cipher */
1070 if (!EVP_EncryptFinal_ex(&ctx, ((unsigned char *)(ret + 1)) + tmp_len,
1074 EVP_CIPHER_CTX_cleanup(&ctx);
1076 # endif /* ifdef HAVE_GNUTLS */
1078 /* Set return values */
1080 *result_length = crypted_length + sizeof(unsigned int);
1087 return EET_ERROR_NONE;
1090 memset(iv, 0, sizeof (iv));
1091 memset(ik, 0, sizeof (ik));
1096 gcry_cipher_close(cipher);
1098 # else /* ifdef HAVE_GNUTLS */
1101 EVP_CIPHER_CTX_cleanup(&ctx);
1105 # endif /* ifdef HAVE_GNUTLS */
1114 return EET_ERROR_ENCRYPT_FAILED;
1115 #else /* ifdef HAVE_CIPHER */
1116 /* Cipher not supported */
1122 (void)result_length;
1123 return EET_ERROR_NOT_IMPLEMENTED;
1124 #endif /* ifdef HAVE_CIPHER */
1128 eet_decipher(const void *data,
1131 unsigned int length,
1133 unsigned int *result_length)
1136 const unsigned int *over = data;
1137 unsigned int *ret = NULL;
1138 unsigned char ik[MAX_KEY_LEN];
1139 unsigned char iv[MAX_IV_LEN];
1140 unsigned char key_material[MAX_KEY_LEN + MAX_IV_LEN];
1145 /* At least the salt and an AES block */
1146 if (size < sizeof(unsigned int) + 16)
1147 return EET_ERROR_BAD_OBJECT;
1152 /* Generate the iv and the key with the salt */
1153 eet_pbkdf2_sha1(key, length, (unsigned char *)&salt,
1154 sizeof(unsigned int), 2048, key_material,
1155 MAX_KEY_LEN + MAX_IV_LEN);
1157 memcpy(iv, key_material, MAX_IV_LEN);
1158 memcpy(ik, key_material + MAX_IV_LEN, MAX_KEY_LEN);
1160 memset(key_material, 0, sizeof (key_material));
1161 memset(&salt, 0, sizeof (salt));
1163 /* Align to AES block size if size is not align */
1164 tmp_len = size - sizeof (unsigned int);
1165 if ((tmp_len & 0x1F) != 0)
1168 ret = malloc(tmp_len);
1173 gcry_error_t err = 0;
1174 gcry_cipher_hd_t cipher;
1176 /* Gcrypt create the corresponding cipher */
1177 err = gcry_cipher_open(&cipher, GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC, 0);
1179 return EET_ERROR_DECRYPT_FAILED;
1181 err = gcry_cipher_setiv(cipher, iv, MAX_IV_LEN);
1185 err = gcry_cipher_setkey(cipher, ik, MAX_KEY_LEN);
1189 memset(iv, 0, sizeof (iv));
1190 memset(ik, 0, sizeof (ik));
1192 /* Gcrypt decrypt */
1193 err = gcry_cipher_decrypt(cipher, ret, tmp_len,
1194 ((unsigned int *)data) + 1, tmp_len);
1198 /* Gcrypt close the cipher */
1199 gcry_cipher_close(cipher);
1201 # else /* ifdef HAVE_GNUTLS */
1205 /* Openssl create the corresponding cipher */
1206 EVP_CIPHER_CTX_init(&ctx);
1209 if (!EVP_DecryptInit_ex(&ctx, EVP_aes_256_cbc(), NULL, ik, iv))
1212 memset(iv, 0, sizeof (iv));
1213 memset(ik, 0, sizeof (ik));
1215 /* Openssl decrypt */
1216 if (!EVP_DecryptUpdate(&ctx, (unsigned char *)ret, &tmp,
1217 (unsigned char *)(over + 1), tmp_len))
1220 /* Openssl close the cipher*/
1221 EVP_CIPHER_CTX_cleanup(&ctx);
1222 # endif /* ifdef HAVE_GNUTLS */
1223 /* Get the decrypted data size */
1226 if (tmp > tmp_len || tmp <= 0)
1229 /* Update the return values */
1231 *result_length = tmp;
1236 *result = malloc(tmp);
1240 memcpy(*result, ret + 1, tmp);
1245 return EET_ERROR_NONE;
1248 memset(iv, 0, sizeof (iv));
1249 memset(ik, 0, sizeof (ik));
1254 EVP_CIPHER_CTX_cleanup(&ctx);
1256 # endif /* ifdef HAVE_GNUTLS */
1266 return EET_ERROR_DECRYPT_FAILED;
1267 #else /* ifdef HAVE_CIPHER */
1273 (void)result_length;
1274 return EET_ERROR_NOT_IMPLEMENTED;
1275 #endif /* ifdef HAVE_CIPHER */
1281 eet_hmac_sha1(const void *key,
1287 size_t hlen = gcry_md_get_algo_dlen (GCRY_MD_SHA1);
1289 unsigned char *hash;
1292 err = gcry_md_open(&mdh, GCRY_MD_SHA1, GCRY_MD_FLAG_HMAC);
1293 if (err != GPG_ERR_NO_ERROR)
1296 err = gcry_md_setkey(mdh, key, key_len);
1297 if (err != GPG_ERR_NO_ERROR)
1303 gcry_md_write(mdh, data, data_len);
1305 hash = gcry_md_read(mdh, GCRY_MD_SHA1);
1312 memcpy(res, hash, hlen);
1319 # endif /* ifdef HAVE_GNUTLS */
1322 eet_pbkdf2_sha1(const char *key,
1324 const unsigned char *salt,
1325 unsigned int salt_len,
1330 unsigned char digest[20];
1331 unsigned char tab[4];
1332 unsigned char *p = res;
1335 int digest_len = 20;
1342 # endif /* ifdef HAVE_GNUTLS */
1344 buf = alloca(salt_len + 4);
1348 for (i = 1; len; len -= tmp_len, p += tmp_len, i++)
1350 if (len > digest_len)
1351 tmp_len = digest_len;
1355 tab[0] = (unsigned char)(i & 0xff000000) >> 24;
1356 tab[1] = (unsigned char)(i & 0x00ff0000) >> 16;
1357 tab[2] = (unsigned char)(i & 0x0000ff00) >> 8;
1358 tab[3] = (unsigned char)(i & 0x000000ff) >> 0;
1361 memcpy(buf, salt, salt_len);
1362 memcpy(buf + salt_len, tab, 4);
1363 eet_hmac_sha1(key, key_len, buf, salt_len + 4, digest);
1364 # else /* ifdef HAVE_GNUTLS */
1365 HMAC_Init(&hctx, key, key_len, EVP_sha1());
1366 HMAC_Update(&hctx, salt, salt_len);
1367 HMAC_Update(&hctx, tab, 4);
1368 HMAC_Final(&hctx, digest, NULL);
1369 # endif /* ifdef HAVE_GNUTLS */
1370 memcpy(p, digest, tmp_len);
1372 for (j = 1; j < iter; j++)
1375 eet_hmac_sha1(key, key_len, digest, 20, digest);
1376 # else /* ifdef HAVE_GNUTLS */
1377 HMAC(EVP_sha1(), key, key_len, digest, 20, digest, NULL);
1378 # endif /* ifdef HAVE_GNUTLS */
1379 for (k = 0; k < tmp_len; k++)
1386 HMAC_cleanup(&hctx);
1387 # endif /* ifdef HAVE_GNUTLS */
1391 #endif /* ifdef HAVE_CIPHER */