/** * @brief Decipher a buffer using AES-128 with CBC. */ int crypt_aes_dec(crypt_context_t *context, char *encBuffer, char *outBuffer, unsigned int buffLen, char *iniVector) { int rv; ASSERT(context, rv, CRYPT_FAILED, "crypt_aes_dec: Argument is NULL.\n"); ASSERT(encBuffer, rv, CRYPT_FAILED, "crypt_aes_dec: Argument is NULL.\n"); ASSERT(outBuffer, rv, CRYPT_FAILED, "crypt_aes_dec: Argument is NULL.\n"); ASSERT(iniVector, rv, CRYPT_FAILED, "crypt_aes_dec: Argument is NULL.\n"); ASSERT(context->initialised, rv, CRYPT_FAILED, "crypt_aes_dec: Context is not initialised.\n"); gcry_error_t gcryError; gcry_cipher_hd_t gcryCipherHd = NULL; size_t keyLength = gcry_cipher_get_algo_keylen(GCRY_CIPHER_AES128); size_t blkLength = gcry_cipher_get_algo_blklen(GCRY_CIPHER_AES128); gcryError = gcry_cipher_open(&gcryCipherHd, GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC, 0); ASSERT(!gcryError, rv, CRYPT_FAILED, "crypt_aes_dec: %s: %s\n", gcry_strsource(gcryError), gcry_strerror(gcryError)); gcryError = gcry_cipher_setkey(gcryCipherHd, context->secretKey, keyLength); ASSERT(!gcryError, rv, CRYPT_FAILED, "crypt_aes_dec: %s: %s\n", gcry_strsource(gcryError), gcry_strerror(gcryError)); gcryError = gcry_cipher_setiv(gcryCipherHd, iniVector, blkLength); ASSERT(!gcryError, rv, CRYPT_FAILED, "crypt_aes_dec: %s: %s\n", gcry_strsource(gcryError), gcry_strerror(gcryError)); gcryError = gcry_cipher_decrypt(gcryCipherHd, outBuffer, buffLen, encBuffer, buffLen); ASSERT(!gcryError, rv, CRYPT_FAILED, "crypt_aes_dec: %s: %s\n", gcry_strsource(gcryError), gcry_strerror(gcryError)); _err: if(gcryCipherHd) gcry_cipher_close(gcryCipherHd); return rv; }
static void test_generate_key_pbe (void) { int i; gboolean ret; guchar *key; for (i = 0; i < N_GENERATION_TESTS; ++i) { if (!all_generation_tests[i].result_pbe) continue; ret = egg_symkey_generate_pbe (all_generation_tests[i].cipher_algo, all_generation_tests[i].hash_algo, all_generation_tests[i].password, -1, (guchar*)all_generation_tests[i].salt, 8, all_generation_tests[i].iterations, &key, NULL); g_assert ("failed to generate pbe key" && ret); ret = (memcmp (key, all_generation_tests[i].result_pbe, gcry_cipher_get_algo_keylen (all_generation_tests[i].cipher_algo)) == 0); g_assert ("invalid pbe key generated" && ret); } }
guchar * egg_openssl_decrypt_block (const gchar *dekinfo, const gchar *password, gssize n_password, GBytes *data, gsize *n_decrypted) { gcry_cipher_hd_t ch; guchar *key = NULL; guchar *iv = NULL; int gcry, ivlen; int algo = 0; int mode = 0; guchar *decrypted; if (!parse_dekinfo (dekinfo, &algo, &mode, &iv)) return FALSE; ivlen = gcry_cipher_get_algo_blklen (algo); /* We assume the iv is at least as long as at 8 byte salt */ g_return_val_if_fail (ivlen >= 8, FALSE); /* IV is already set from the DEK info */ if (!egg_symkey_generate_simple (algo, GCRY_MD_MD5, password, n_password, iv, 8, 1, &key, NULL)) { g_free (iv); return NULL; } gcry = gcry_cipher_open (&ch, algo, mode, 0); g_return_val_if_fail (!gcry, NULL); gcry = gcry_cipher_setkey (ch, key, gcry_cipher_get_algo_keylen (algo)); g_return_val_if_fail (!gcry, NULL); egg_secure_free (key); /* 16 = 128 bits */ gcry = gcry_cipher_setiv (ch, iv, ivlen); g_return_val_if_fail (!gcry, NULL); g_free (iv); /* Allocate output area */ *n_decrypted = g_bytes_get_size (data); decrypted = egg_secure_alloc (*n_decrypted); gcry = gcry_cipher_decrypt (ch, decrypted, *n_decrypted, g_bytes_get_data (data, NULL), g_bytes_get_size (data)); if (gcry) { egg_secure_free (decrypted); g_return_val_if_reached (NULL); } gcry_cipher_close (ch); return decrypted; }
static gboolean decrypt_buffer (EggBuffer *buffer, GkmSecret *master, guchar salt[8], int iterations) { const gchar *password = NULL; gcry_cipher_hd_t cih; gcry_error_t gerr; guchar *key, *iv; gsize n_password = 0; size_t pos; g_assert (buffer->len % 16 == 0); g_assert (16 == gcry_cipher_get_algo_blklen (GCRY_CIPHER_AES128)); g_assert (16 == gcry_cipher_get_algo_keylen (GCRY_CIPHER_AES128)); /* No password is set, try an null password */ if (master == NULL) { password = NULL; n_password = 0; } else { password = gkm_secret_get_password (master, &n_password); } if (!egg_symkey_generate_simple (GCRY_CIPHER_AES128, GCRY_MD_SHA256, password, n_password, salt, 8, iterations, &key, &iv)) return FALSE; gerr = gcry_cipher_open (&cih, GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC, 0); if (gerr) { g_warning ("couldn't create aes cipher context: %s", gcry_strerror (gerr)); egg_secure_free (key); g_free (iv); return FALSE; } /* 16 = 128 bits */ gerr = gcry_cipher_setkey (cih, key, 16); g_return_val_if_fail (!gerr, FALSE); egg_secure_free (key); /* 16 = 128 bits */ gerr = gcry_cipher_setiv (cih, iv, 16); g_return_val_if_fail (!gerr, FALSE); g_free (iv); for (pos = 0; pos < buffer->len; pos += 16) { /* In place encryption */ gerr = gcry_cipher_decrypt (cih, buffer->buf + pos, 16, NULL, 0); g_return_val_if_fail (!gerr, FALSE); } gcry_cipher_close (cih); return TRUE; }
int main(int argc, const char *argv[]) { const char *libgcrypt_version = gcry_check_version(GCRYPT_VERSION); gcry_error_t err = 0; //char key[32]; const char *key; int keylen; int algo = GCRY_CIPHER_SERPENT128; const char *filename; const char *filename2; if (argc != 4) { printf("Wrong parameter quantity\n"); exit(1); } filename = argv[1]; filename2 = argv[2]; key = argv[3]; //filename3 = argv[3]; // cipher initialization if (!libgcrypt_version) { fputs ("libgcrypt version mismatch or not installed\n", stderr); exit (2); } else { printf("Using libgcrypt version: %s\n", libgcrypt_version); } // cipher settings gcry_control(GCRYCTL_INITIALIZATION_FINISHED, 0); keylen = gcry_cipher_get_algo_keylen(algo); // Open cipher handler gcry_cipher_hd_t hd; gcry_cipher_open(&hd, algo, GCRY_CIPHER_MODE_OFB, 0); err = gcry_cipher_setkey(hd, key, keylen); if (err) { printf("grcy_cipher_setkey failed: %s\n", gpg_strerror(err)); exit(2); } //gcry_cipher_setiv //decryptFile(hd, filename); //encryptDecryptTest(hd, filename); //encryptFileToFile(hd, filename, filename2); decryptFileToFile(hd, filename, filename2); // Release handler gcry_cipher_close(hd); return 0; }
/* Function to decrypt the ciphertext passed to it, it also takes the lenght of the file as input. function returns palintext*/ char * decryptfunction(char *textbuffer, char * aeskey, size_t textlen, char *iv) { gcry_error_t err; gcry_cipher_hd_t handle; size_t keylength = gcry_cipher_get_algo_keylen(CIPHER); /* For aes256 keylength is 32 */ size_t blklength = gcry_cipher_get_algo_blklen(CIPHER); /*For aes256 blklength is 16 */ size_t i,result; char *decbuffer = malloc(textlen); /*buffer to hold decrypted data */ printf("Starting Decryption Process\n"); err = gcry_cipher_open( &handle, CIPHER, MODE, GCRY_CIPHER_CBC_CTS); if(err) { printf("Error creating cipher handle\n"); exit(0); } printf("Cipher handle created successfully\n"); err= gcry_cipher_setkey(handle, aeskey, keylength); if(err) { printf("Error setting cipher key\n"); } printf("Cipher key created successfully\n"); err = gcry_cipher_setiv(handle, iv , blklength); if(err) { printf("Error setting initialization vector\n"); } printf("Initialization vector set successfully\n"); err = gcry_cipher_decrypt( handle, decbuffer, textlen, textbuffer, textlen); if(err) { printf("Error while decrypting\n"); } printf("Text successfully decrypted\n"); gcry_cipher_close(handle); printf("Cipher handle closed successfully\n"); return decbuffer; }
static gsti_error_t construct_keys (gsti_ctx_t ctx) { gsti_error_t err; gcry_md_hd_t md; int algo = GCRY_MD_SHA1; int keylen, blksize, maclen; if (ctx->kex.iv_a) return 0; /* already constructed */ err = gcry_md_open (&md, algo, 0); if (err) return err; hash_mpi (md, ctx->kex.k); gcry_md_write (md, gsti_bstr_data (ctx->kex.h), gsti_bstr_length (ctx->kex.h)); blksize = ctx->ciph_blksize; maclen = ctx->mac_len; keylen = gcry_cipher_get_algo_keylen (ctx->ciph_algo); ctx->kex.iv_a = construct_one_key (ctx, md, algo, (const unsigned char*)"\x41", blksize); ctx->kex.iv_b = construct_one_key (ctx, md, algo, (const unsigned char*)"\x42", blksize); ctx->kex.key_c = construct_one_key (ctx, md, algo, (const unsigned char*)"\x43", keylen); ctx->kex.key_d = construct_one_key (ctx, md, algo, (const unsigned char*)"\x44", keylen); ctx->kex.mac_e = construct_one_key (ctx, md, algo, (const unsigned char*)"\x45", maclen); ctx->kex.mac_f = construct_one_key (ctx, md, algo, (const unsigned char*)"\x46", maclen); gcry_md_close (md); _gsti_dump_hexbuf (ctx, "key A=", gsti_bstr_data (ctx->kex.iv_a), gsti_bstr_length (ctx->kex.iv_a)); _gsti_dump_hexbuf (ctx, "key B=", gsti_bstr_data (ctx->kex.iv_b), gsti_bstr_length (ctx->kex.iv_b)); _gsti_dump_hexbuf (ctx, "key C=", gsti_bstr_data (ctx->kex.key_c), gsti_bstr_length (ctx->kex.key_c)); _gsti_dump_hexbuf (ctx, "key D=", gsti_bstr_data (ctx->kex.key_d), gsti_bstr_length (ctx->kex.key_d)); _gsti_dump_hexbuf (ctx, "key E=", gsti_bstr_data (ctx->kex.mac_e), gsti_bstr_length (ctx->kex.mac_e)); _gsti_dump_hexbuf (ctx, "key F=", gsti_bstr_data (ctx->kex.mac_f), gsti_bstr_length (ctx->kex.mac_f)); return 0; }
static int bench_encrypt_init (struct bench_obj *obj) { struct bench_cipher_mode *mode = obj->priv; gcry_cipher_hd_t hd; int err, keylen; obj->min_bufsize = BUF_START_SIZE; obj->max_bufsize = BUF_END_SIZE; obj->step_size = BUF_STEP_SIZE; obj->num_measure_repetitions = num_measurement_repetitions; err = gcry_cipher_open (&hd, mode->algo, mode->mode, 0); if (err) { fprintf (stderr, PGM ": error opening cipher `%s'\n", gcry_cipher_algo_name (mode->algo)); exit (1); } keylen = gcry_cipher_get_algo_keylen (mode->algo); if (keylen) { char key[keylen]; int i; for (i = 0; i < keylen; i++) key[i] = 0x33 ^ (11 - i); err = gcry_cipher_setkey (hd, key, keylen); if (err) { fprintf (stderr, PGM ": gcry_cipher_setkey failed: %s\n", gpg_strerror (err)); gcry_cipher_close (hd); exit (1); } } else { fprintf (stderr, PGM ": failed to get key length for algorithm `%s'\n", gcry_cipher_algo_name (mode->algo)); gcry_cipher_close (hd); exit (1); } obj->priv = hd; return 0; }
static int initCrypt(FILE *eifp) { int r = 0; gcry_error_t gcryError; char iv[4096]; blkLength = gcry_cipher_get_algo_blklen(cry_algo); if(blkLength > sizeof(iv)) { fprintf(stderr, "internal error[%s:%d]: block length %d too large for " "iv buffer\n", __FILE__, __LINE__, blkLength); r = 1; goto done; } if((r = eiGetIV(eifp, iv, blkLength)) != 0) goto done; size_t keyLength = gcry_cipher_get_algo_keylen(cry_algo); if(strlen(cry_key) != keyLength) { fprintf(stderr, "invalid key length; key is %u characters, but " "exactly %u characters are required\n", cry_keylen, keyLength); r = 1; goto done; } gcryError = gcry_cipher_open(&gcry_chd, cry_algo, cry_mode, 0); if (gcryError) { printf("gcry_cipher_open failed: %s/%s\n", gcry_strsource(gcryError), gcry_strerror(gcryError)); r = 1; goto done; } gcryError = gcry_cipher_setkey(gcry_chd, cry_key, keyLength); if (gcryError) { printf("gcry_cipher_setkey failed: %s/%s\n", gcry_strsource(gcryError), gcry_strerror(gcryError)); r = 1; goto done; } gcryError = gcry_cipher_setiv(gcry_chd, iv, blkLength); if (gcryError) { printf("gcry_cipher_setiv failed: %s/%s\n", gcry_strsource(gcryError), gcry_strerror(gcryError)); r = 1; goto done; } done: return r; }
/* returns 0 on succes, positive if key length does not match and key * of return value size is required. */ int rsgcrySetKey(gcryctx ctx, unsigned char *key, uint16_t keyLen) { uint16_t reqKeyLen; int r; reqKeyLen = gcry_cipher_get_algo_keylen(ctx->algo); if(keyLen != reqKeyLen) { r = reqKeyLen; goto done; } ctx->keyLen = keyLen; ctx->key = malloc(keyLen); memcpy(ctx->key, key, keyLen); r = 0; done: return r; }
static crypto_t _setkey(crypto_t c, gchar *key) { gcry_error_t e; gsize keylen; #ifdef _1 g_message("[%s] key=%s", __func__, key); #endif c->cipher.key = (gchar*) crypto_hex2bytes(key, &keylen); if (c->cipher.key == NULL || keylen ==0) { return (_fail(c, g_strdup("crypto_hex2bytes failed: invalid " "hexadecimal string length"))); } #ifdef _1 crypto_dump("c->cipher.key", (guchar*) c->cipher.key, keylen); #endif c->cipher.keylen = gcry_cipher_get_algo_keylen(c->algo); if (c->cipher.keylen ==0) { return (_fail(c, g_strdup_printf("gcry_cipher_get_algo_keylen failed " "c->cipher.keylen=%" G_GSIZE_FORMAT", " "keylen=%" G_GSIZE_FORMAT, c->cipher.keylen, keylen))); } #ifdef _1 if (keylen > c->cipher.keylen) { g_warning("key length exceeds %lu, ignoring the exceeding bytes",keylen); keylen = c->cipher.keylen; } #endif e = gcry_cipher_setkey(c->cipher.h, c->cipher.key, keylen); if (e != 0) { return (_fail(c, g_strdup_printf("gcry_cipher_setkey failed: %s", gpg_strerror(e)))); } c->rc = EXIT_SUCCESS; return (c); }
int _libssh2_cipher_init(_libssh2_cipher_ctx * h, _libssh2_cipher_type(algo), unsigned char *iv, unsigned char *secret, int encrypt) { int ret; int cipher = _libssh2_gcry_cipher(algo); int mode = _libssh2_gcry_mode(algo); int keylen = gcry_cipher_get_algo_keylen(cipher); (void) encrypt; ret = gcry_cipher_open(h, cipher, mode, 0); if(ret) { return -1; } ret = gcry_cipher_setkey(*h, secret, keylen); if(ret) { gcry_cipher_close(*h); return -1; } if(mode != GCRY_CIPHER_MODE_STREAM) { int blklen = gcry_cipher_get_algo_blklen(cipher); if(mode == GCRY_CIPHER_MODE_CTR) ret = gcry_cipher_setctr(*h, iv, blklen); else ret = gcry_cipher_setiv(*h, iv, blklen); if(ret) { gcry_cipher_close(*h); return -1; } } return 0; }
int _libssh2_cipher_init(_libssh2_cipher_ctx * h, _libssh2_cipher_type(algo), unsigned char *iv, unsigned char *secret, int encrypt) { int mode = 0, ret; int keylen = gcry_cipher_get_algo_keylen(algo); (void) encrypt; if (algo != GCRY_CIPHER_ARCFOUR) { mode = GCRY_CIPHER_MODE_CBC; } ret = gcry_cipher_open(h, algo, mode, 0); if (ret) { return -1; } ret = gcry_cipher_setkey(*h, secret, keylen); if (ret) { gcry_cipher_close(*h); return -1; } if (algo != GCRY_CIPHER_ARCFOUR) { int blklen = gcry_cipher_get_algo_blklen(algo); ret = gcry_cipher_setiv(*h, iv, blklen); if (ret) { gcry_cipher_close(*h); return -1; } } return 0; }
static void decrypt (Metadata *header_metadata, CryptoKeys *dec_keys, GFile *enc_data, goffset enc_data_size, GFileOutputStream *ostream) { gcry_cipher_hd_t hd; gcry_cipher_open (&hd, header_metadata->algo, header_metadata->algo_mode, 0); gcry_cipher_setkey (hd, dec_keys->crypto_key, gcry_cipher_get_algo_keylen (header_metadata->algo)); if (header_metadata->algo_mode == GCRY_CIPHER_MODE_CBC) { gcry_cipher_setiv (hd, header_metadata->iv, header_metadata->iv_size); } else { gcry_cipher_setctr (hd, header_metadata->iv, header_metadata->iv_size); } GError *err = NULL; GFileInputStream *in_stream = g_file_read (enc_data, NULL, &err); if (err != NULL) { g_printerr ("%s\n", err->message); // TODO return; } if (!g_seekable_seek (G_SEEKABLE (in_stream), sizeof (Metadata), G_SEEK_SET, NULL, &err)) { g_printerr ("Couldn't set the position, exiting...\n"); //TODO return; } guchar *enc_buf = g_try_malloc0 (FILE_BUFFER); guchar *dec_buf = g_try_malloc0 (FILE_BUFFER); if (enc_buf == NULL || dec_buf == NULL) { g_printerr ("Error during memory allocation\n"); // TODO return; } goffset done_size = 0; gssize read_len; while (done_size < enc_data_size) { if ((enc_data_size - done_size) <= FILE_BUFFER) { read_len = g_input_stream_read (G_INPUT_STREAM (in_stream), enc_buf, enc_data_size - done_size, NULL, &err); gcry_cipher_decrypt (hd, dec_buf, read_len, enc_buf, read_len); g_output_stream_write (G_OUTPUT_STREAM (ostream), dec_buf, read_len - header_metadata->padding_value, NULL, &err); } else { read_len = g_input_stream_read (G_INPUT_STREAM (in_stream), enc_buf, FILE_BUFFER, NULL, &err); gcry_cipher_decrypt (hd, dec_buf, read_len, enc_buf, read_len); g_output_stream_write (G_OUTPUT_STREAM (ostream), dec_buf, read_len, NULL, &err); } memset (dec_buf, 0, FILE_BUFFER); memset (enc_buf, 0, FILE_BUFFER); done_size += read_len; } gcry_cipher_close (hd); multiple_free (2, (gpointer) &enc_buf, (gpointer) &dec_buf); g_input_stream_close (G_INPUT_STREAM (in_stream), NULL, NULL); g_object_unref (in_stream); }
void decrypt_file (const gchar *input_file_path, const gchar *pwd) { GError *err = NULL; goffset file_size = get_file_size (input_file_path); if (file_size == -1) { return; } if (file_size < (goffset) (sizeof (Metadata) + SHA512_DIGEST_SIZE)) { g_printerr ("The selected file is not encrypted.\n"); return; } GFile *in_file = g_file_new_for_path (input_file_path); GFileInputStream *in_stream = g_file_read (in_file, NULL, &err); if (err != NULL) { g_printerr ("%s\n", err->message); // TODO return; } gchar *output_file_path; if (!g_str_has_suffix (input_file_path, ".enc")) { g_printerr ("The selected file may not be encrypted\n"); output_file_path = g_strconcat (input_file_path, ".decrypted", NULL); } else { output_file_path = g_strndup (input_file_path, (gsize) g_utf8_strlen (input_file_path, -1) - 4); // remove .enc } GFile *out_file = g_file_new_for_path (output_file_path); GFileOutputStream *out_stream = g_file_append_to (out_file, G_FILE_CREATE_REPLACE_DESTINATION, NULL, &err); if (err != NULL) { g_printerr ("%s\n", err->message); // TODO return; } Metadata *header_metadata = g_new0 (Metadata, 1); CryptoKeys *decryption_keys = g_new0 (CryptoKeys, 1); gssize rw_len = g_input_stream_read (G_INPUT_STREAM (in_stream), header_metadata, sizeof (Metadata), NULL, &err); if (rw_len == -1) { g_printerr ("%s\n", err->message); // TODO return; } guchar *original_hmac = g_malloc (SHA512_DIGEST_SIZE); if (!g_seekable_seek (G_SEEKABLE (in_stream), file_size - SHA512_DIGEST_SIZE, G_SEEK_SET, NULL, &err)) { g_printerr ("Couldn't set the position, exiting...\n"); //TODO return; } rw_len = g_input_stream_read (G_INPUT_STREAM (in_stream), original_hmac, SHA512_DIGEST_SIZE, NULL, &err); if (rw_len == -1) { g_printerr ("%s\n", err->message); // TODO return; } if (!g_seekable_seek (G_SEEKABLE (in_stream), 0, G_SEEK_SET, NULL, &err)) { g_printerr ("Couldn't set the position, exiting...\n"); //TODO return; } GFile *file_encrypted_data = get_g_file_with_encrypted_data (in_stream, file_size); if (file_encrypted_data == NULL) { // TODO return; } if (!setup_keys (pwd, gcry_cipher_get_algo_keylen (header_metadata->algo), header_metadata, decryption_keys)) { g_printerr ("Error during key derivation or during memory allocation\n"); //TODO return; } if (!compare_hmac (decryption_keys->hmac_key, original_hmac, file_encrypted_data)) { g_printerr ("HMAC differs from the one stored inside the file.\nEither the password is wrong or the file has been corrupted.\n"); // TODO return; } decrypt (header_metadata, decryption_keys, file_encrypted_data, file_size - sizeof (Metadata) - SHA512_DIGEST_SIZE, out_stream); g_unlink (g_file_get_path (file_encrypted_data)); // TODO remove encrypted file? Give option to the user multiple_unref (5, (gpointer) &file_encrypted_data, (gpointer) &in_stream, (gpointer) &out_stream, (gpointer) &in_file, (gpointer) &out_file); multiple_gcry_free (3, (gpointer) &decryption_keys->crypto_key, (gpointer) &decryption_keys->derived_key, (gpointer) &decryption_keys->hmac_key); multiple_free (4, (gpointer) &header_metadata, (gpointer) &output_file_path, (gpointer) &original_hmac, (gpointer) &decryption_keys); }
gboolean egg_symkey_generate_simple (int cipher_algo, int hash_algo, const gchar *password, gssize n_password, const guchar *salt, gsize n_salt, int iterations, guchar **key, guchar **iv) { gcry_md_hd_t mdh; gcry_error_t gcry; guchar *digest; guchar *digested; guint n_digest; gint pass, i; gint needed_iv, needed_key; guchar *at_iv, *at_key; g_assert (cipher_algo); g_assert (hash_algo); g_return_val_if_fail (iterations >= 1, FALSE); if (!password) n_password = 0; if (n_password == -1) n_password = strlen (password); /* * If cipher algo needs more bytes than hash algo has available * then the entire hashing process is done again (with the previous * hash bytes as extra input), and so on until satisfied. */ needed_key = gcry_cipher_get_algo_keylen (cipher_algo); needed_iv = gcry_cipher_get_algo_blklen (cipher_algo); gcry = gcry_md_open (&mdh, hash_algo, 0); if (gcry) { g_warning ("couldn't create '%s' hash context: %s", gcry_md_algo_name (hash_algo), gcry_strerror (gcry)); return FALSE; } n_digest = gcry_md_get_algo_dlen (hash_algo); g_return_val_if_fail (n_digest > 0, FALSE); digest = egg_secure_alloc (n_digest); g_return_val_if_fail (digest, FALSE); if (key) { *key = egg_secure_alloc (needed_key); g_return_val_if_fail (*key, FALSE); } if (iv) *iv = g_new0 (guchar, needed_iv); at_key = key ? *key : NULL; at_iv = iv ? *iv : NULL; for (pass = 0; TRUE; ++pass) { gcry_md_reset (mdh); /* Hash in the previous buffer on later passes */ if (pass > 0) gcry_md_write (mdh, digest, n_digest); if (password) gcry_md_write (mdh, password, n_password); if (salt && n_salt) gcry_md_write (mdh, salt, n_salt); gcry_md_final (mdh); digested = gcry_md_read (mdh, 0); g_return_val_if_fail (digested, FALSE); memcpy (digest, digested, n_digest); for (i = 1; i < iterations; ++i) { gcry_md_reset (mdh); gcry_md_write (mdh, digest, n_digest); gcry_md_final (mdh); digested = gcry_md_read (mdh, 0); g_return_val_if_fail (digested, FALSE); memcpy (digest, digested, n_digest); } /* Copy as much as possible into the destinations */ i = 0; while (needed_key && i < n_digest) { if (at_key) *(at_key++) = digest[i]; needed_key--; i++; } while (needed_iv && i < n_digest) { if (at_iv) *(at_iv++) = digest[i]; needed_iv--; i++; } if (needed_key == 0 && needed_iv == 0) break; } egg_secure_free (digest); gcry_md_close (mdh); return TRUE; }
gboolean egg_symkey_generate_pbe (int cipher_algo, int hash_algo, const gchar *password, gssize n_password, const guchar *salt, gsize n_salt, int iterations, guchar **key, guchar **iv) { gcry_md_hd_t mdh; gcry_error_t gcry; guchar *digest; guchar *digested; guint i, n_digest; gint needed_iv, needed_key; g_assert (cipher_algo); g_assert (hash_algo); g_return_val_if_fail (iterations >= 1, FALSE); if (!password) n_password = 0; if (n_password == -1) n_password = strlen (password); /* * We only do one pass here. * * The key ends up as the first needed_key bytes of the hash buffer. * The iv ends up as the last needed_iv bytes of the hash buffer. * * The IV may overlap the key (which is stupid) if the wrong pair of * hash/cipher algorithms are chosen. */ n_digest = gcry_md_get_algo_dlen (hash_algo); g_return_val_if_fail (n_digest > 0, FALSE); needed_key = gcry_cipher_get_algo_keylen (cipher_algo); needed_iv = gcry_cipher_get_algo_blklen (cipher_algo); if (needed_iv + needed_key > 16 || needed_iv + needed_key > n_digest) { g_warning ("using PBE symkey generation with %s using an algorithm that needs " "too many bytes of key and/or IV: %s", gcry_cipher_algo_name (hash_algo), gcry_cipher_algo_name (cipher_algo)); return FALSE; } gcry = gcry_md_open (&mdh, hash_algo, 0); if (gcry) { g_warning ("couldn't create '%s' hash context: %s", gcry_md_algo_name (hash_algo), gcry_strerror (gcry)); return FALSE; } digest = egg_secure_alloc (n_digest); g_return_val_if_fail (digest, FALSE); if (key) { *key = egg_secure_alloc (needed_key); g_return_val_if_fail (*key, FALSE); } if (iv) *iv = g_new0 (guchar, needed_iv); if (password) gcry_md_write (mdh, password, n_password); if (salt && n_salt) gcry_md_write (mdh, salt, n_salt); gcry_md_final (mdh); digested = gcry_md_read (mdh, 0); g_return_val_if_fail (digested, FALSE); memcpy (digest, digested, n_digest); for (i = 1; i < iterations; ++i) gcry_md_hash_buffer (hash_algo, digest, digest, n_digest); /* The first x bytes are the key */ if (key) { g_assert (needed_key <= n_digest); memcpy (*key, digest, needed_key); } /* The last 16 - x bytes are the iv */ if (iv) { g_assert (needed_iv <= n_digest && n_digest >= 16); memcpy (*iv, digest + (16 - needed_iv), needed_iv); } egg_secure_free (digest); gcry_md_close (mdh); return TRUE; }
static void check_cbc_mac_cipher (void) { struct tv { int algo; char key[MAX_DATA_LEN]; char plaintext[MAX_DATA_LEN]; size_t plaintextlen; char mac[MAX_DATA_LEN]; } tv[] = { { GCRY_CIPHER_AES, "chicken teriyaki", "This is a sample plaintext for CBC MAC of sixtyfour bytes.......", 0, "\x23\x8f\x6d\xc7\x53\x6a\x62\x97\x11\xc4\xa5\x16\x43\xea\xb0\xb6" }, { GCRY_CIPHER_3DES, "abcdefghABCDEFGH01234567", "This is a sample plaintext for CBC MAC of sixtyfour bytes.......", 0, "\x5c\x11\xf0\x01\x47\xbd\x3d\x3a" }, { GCRY_CIPHER_DES, "abcdefgh", "This is a sample plaintext for CBC MAC of sixtyfour bytes.......", 0, "\xfa\x4b\xdf\x9d\xfa\xab\x01\x70" } }; gcry_cipher_hd_t hd; char out[MAX_DATA_LEN]; int i, blklen, keylen; gcry_error_t err = 0; for (i = 0; i < sizeof (tv) / sizeof (tv[0]); i++) { err = gcry_cipher_open (&hd, tv[i].algo, GCRY_CIPHER_MODE_CBC, GCRY_CIPHER_CBC_MAC); if (!hd) { fail ("cbc-mac algo %d, grcy_open_cipher failed: %s\n", tv[i].algo, gpg_strerror (err)); return; } blklen = gcry_cipher_get_algo_blklen(tv[i].algo); if (!blklen) { fail ("cbc-mac algo %d, gcry_cipher_get_algo_blklen failed\n", tv[i].algo); gcry_cipher_close (hd); return; } keylen = gcry_cipher_get_algo_keylen (tv[i].algo); if (!keylen) { fail ("cbc-mac algo %d, gcry_cipher_get_algo_keylen failed\n", tv[i].algo); return; } err = gcry_cipher_setkey (hd, tv[i].key, keylen); if (err) { fail ("cbc-mac algo %d, gcry_cipher_setkey failed: %s\n", tv[i].algo, gpg_strerror (err)); gcry_cipher_close (hd); return; } err = gcry_cipher_setiv (hd, NULL, 0); if (err) { fail ("cbc-mac algo %d, gcry_cipher_setiv failed: %s\n", tv[i].algo, gpg_strerror (err)); gcry_cipher_close (hd); return; } err = gcry_cipher_encrypt (hd, out, blklen, tv[i].plaintext, tv[i].plaintextlen ? tv[i].plaintextlen : strlen (tv[i].plaintext)); if (err) { fail ("cbc-mac algo %d, gcry_cipher_encrypt failed: %s\n", tv[i].algo, gpg_strerror (err)); gcry_cipher_close (hd); return; } #if 0 { int j; for (j = 0; j < gcry_cipher_get_algo_blklen (tv[i].algo); j++) printf ("\\x%02x", out[j] & 0xFF); printf ("\n"); } #endif if (memcmp (tv[i].mac, out, blklen)) fail ("cbc-mac algo %d, encrypt mismatch entry %d\n", tv[i].algo, i); gcry_cipher_close (hd); } }
extern void io_encryption_init(IO_HANDLE ptr, enum gcry_cipher_algos c, enum gcry_md_algos h, enum gcry_cipher_modes m, const uint8_t *k, size_t l, io_extra_t x) { io_private_t *io_ptr = ptr; if (!io_ptr || io_ptr->fd < 0) return errno = EBADF , (void)NULL; /* * start setting up the encryption buffer */ if (!(io_ptr->buffer_crypt = gcry_malloc_secure(sizeof( buffer_t )))) die(_("Out of memory @ %s:%d:%s [%zu]"), __FILE__, __LINE__, __func__, sizeof( buffer_t )); gcry_md_open(&io_ptr->hash_handle, h, GCRY_MD_FLAG_SECURE); gcry_cipher_open(&io_ptr->cipher_handle, c, m, GCRY_CIPHER_SECURE); /* * generate a hash of the supplied key data */ size_t hash_length = gcry_md_get_algo_dlen(h); uint8_t *hash = gcry_malloc_secure(hash_length); if (!hash) die(_("Out of memory @ %s:%d:%s [%zu]"), __FILE__, __LINE__, __func__, hash_length); gcry_md_hash_buffer(gcry_md_get_algo(io_ptr->hash_handle), hash, k, l); /* * set the key as the hash of supplied data */ size_t key_length = gcry_cipher_get_algo_keylen(c); uint8_t *key = gcry_calloc_secure(key_length, sizeof( byte_t )); if (!key) die(_("Out of memory @ %s:%d:%s [%zu]"), __FILE__, __LINE__, __func__, key_length); memcpy(key, hash, key_length < hash_length ? key_length : hash_length); gcry_cipher_setkey(io_ptr->cipher_handle, key, key_length); /* here is where it blows-up on Windows 8, using AES */ gcry_free(key); /* * the 2011.* versions (incorrectly) used key length instead of block * length; versions after 2014.06 randomly generate the IV instead */ io_ptr->buffer_crypt->block = gcry_cipher_get_algo_blklen(c); uint8_t *iv = gcry_calloc_secure(x.x_iv == IV_BROKEN ? key_length : io_ptr->buffer_crypt->block, sizeof( byte_t )); if (!iv) die(_("Out of memory @ %s:%d:%s [%zu]"), __FILE__, __LINE__, __func__, io_ptr->buffer_crypt->block); if (x.x_iv == IV_RANDOM) { if (x.x_encrypt) { gcry_create_nonce(iv, io_ptr->buffer_crypt->block); io_write(ptr, iv, io_ptr->buffer_crypt->block); } else io_read(ptr, iv, io_ptr->buffer_crypt->block); } else { uint8_t *iv_hash = gcry_malloc_secure(hash_length); if (!iv_hash) die(_("Out of memory @ %s:%d:%s [%zu]"), __FILE__, __LINE__, __func__, hash_length); /* * set the IV as the hash of the hash */ gcry_md_hash_buffer(gcry_md_get_algo(io_ptr->hash_handle), iv_hash, hash, hash_length); memcpy(iv, iv_hash, io_ptr->buffer_crypt->block < hash_length ? io_ptr->buffer_crypt->block : hash_length); gcry_free(iv_hash); } gcry_free(hash); if (m == GCRY_CIPHER_MODE_CTR) gcry_cipher_setctr(io_ptr->cipher_handle, iv, io_ptr->buffer_crypt->block); else gcry_cipher_setiv(io_ptr->cipher_handle, iv, io_ptr->buffer_crypt->block); gcry_free(iv); /* * set the rest of the buffer */ if (!(io_ptr->buffer_crypt->stream = gcry_malloc_secure(io_ptr->buffer_crypt->block))) die(_("Out of memory @ %s:%d:%s [%zu]"), __FILE__, __LINE__, __func__, io_ptr->buffer_crypt->block); /* * when encrypting/writing data: * 0: length of data buffered so far (in stream) * 1: length of data processed (from d) * when decrypting/reading data: * 0: length of available data in input buffer (stream) * 1: available space in read buffer (d) * 2: next available memory location for data (from d) */ for (unsigned i = 0; i < OFFSET_SLOTS; i++) io_ptr->buffer_crypt->offset[i] = 0; io_ptr->cipher_init = true; io_ptr->hash_init = true; io_ptr->operation = IO_ENCRYPT; return; }
/* Initialize the data encryption key (session key). */ static int init_dek (DEK dek) { int rc=0, mode, i; dek->algo = gcry_cipher_map_name (dek->algoid); mode = gcry_cipher_mode_from_oid (dek->algoid); if (!dek->algo || !mode) { log_error ("unsupported algorithm `%s'\n", dek->algoid); return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM); } /* Extra check for algorithms we consider to be too weak for encryption, although we support them for decryption. Note that there is another check below discriminating on the key length. */ switch (dek->algo) { case GCRY_CIPHER_DES: case GCRY_CIPHER_RFC2268_40: log_error ("cipher algorithm `%s' not allowed: too weak\n", gcry_cipher_algo_name (dek->algo)); return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM); default: break; } dek->keylen = gcry_cipher_get_algo_keylen (dek->algo); if (!dek->keylen || dek->keylen > sizeof (dek->key)) return gpg_error (GPG_ERR_BUG); dek->ivlen = gcry_cipher_get_algo_blklen (dek->algo); if (!dek->ivlen || dek->ivlen > sizeof (dek->iv)) return gpg_error (GPG_ERR_BUG); /* Make sure we don't use weak keys. */ if (dek->keylen < 100/8) { log_error ("key length of `%s' too small\n", dek->algoid); return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM); } rc = gcry_cipher_open (&dek->chd, dek->algo, mode, GCRY_CIPHER_SECURE); if (rc) { log_error ("failed to create cipher context: %s\n", gpg_strerror (rc)); return rc; } for (i=0; i < 8; i++) { gcry_randomize (dek->key, dek->keylen, GCRY_STRONG_RANDOM ); rc = gcry_cipher_setkey (dek->chd, dek->key, dek->keylen); if (gpg_err_code (rc) != GPG_ERR_WEAK_KEY) break; log_info(_("weak key created - retrying\n") ); } if (rc) { log_error ("failed to set the key: %s\n", gpg_strerror (rc)); gcry_cipher_close (dek->chd); dek->chd = NULL; return rc; } gcry_create_nonce (dek->iv, dek->ivlen); rc = gcry_cipher_setiv (dek->chd, dek->iv, dek->ivlen); if (rc) { log_error ("failed to set the IV: %s\n", gpg_strerror (rc)); gcry_cipher_close (dek->chd); dek->chd = NULL; return rc; } return 0; }
void decrypt(char *outfile, char *inpfile) { gcry_err_code_t err = 0; gcry_cipher_hd_t gchandle; const int blks = gcry_cipher_get_algo_blklen(GCRY_CIPHER_AES256); const int keyl = gcry_cipher_get_algo_keylen(GCRY_CIPHER_AES256); long outfileSize = 0; char key[keyl]; const char* salt = "iuyjdbnbtaqonbgt"; //open output file FILE *fout = fopen(outfile, "r"); if (!fout) { printf("output file name : %s\n", outfile); fout = fopen(outfile, "w"); } else { printf("Output file already exist on disk.\n"); return;; } char password[100]; do { printf("Please enter password between 8-20 chars :"); scanf("%s", password); } while (strlen(password) > 20 || strlen(password) < 8); err = gcry_kdf_derive(password, strlen(password), GCRY_KDF_PBKDF2, GCRY_MD_SHA256, salt, strlen(salt), 937, keyl, key); if (err) { fprintf(stderr, "Failure: %s/%s\n", gcry_strsource(err), gcry_strerror(err)); exit(EXIT_FAILURE); } char ctext[blks]; char extractedIV[blks]; FILE *finp = fopen(inpfile, "r"); fseek(finp, 0, SEEK_SET); unsigned char extractedHMAC[keyl + 1]; fread(extractedHMAC, 1, keyl, finp); //extract HMAC from received file extractedHMAC[keyl] = '\0'; // Compare calculated HMAC with extracted HMAC ---> start long cipherSize = 0; fseek(finp, 0, SEEK_END); cipherSize = ftell(finp) - keyl; fseek(finp, keyl, SEEK_SET); unsigned char *hmacBuffer = malloc(cipherSize + 1); fread(hmacBuffer, 1, cipherSize, finp); gcry_md_hd_t hd; err = gcry_md_open(&hd, GCRY_MD_SHA256, GCRY_MD_FLAG_HMAC); if (err) { fprintf(stderr, "Failure: %s/%s\n", gcry_strsource(err), gcry_strerror(err)); fclose(finp); fclose(fout); exit(EXIT_FAILURE); } err = gcry_md_setkey(hd, key, keyl); if (err) { fprintf(stderr, "Failure: %s/%s\n", gcry_strsource(err), gcry_strerror(err)); fclose(finp); fclose(fout); exit(EXIT_FAILURE); } err = gcry_md_enable(hd, GCRY_MD_SHA256); if (err) { fprintf(stderr, "Failure: %s/%s\n", gcry_strsource(err), gcry_strerror(err)); fclose(finp); fclose(fout); exit(EXIT_FAILURE); } gcry_md_write(hd, hmacBuffer, cipherSize); char thmac[keyl]; unsigned char *hmac = thmac; hmac = gcry_md_read(hd, GCRY_MD_SHA256); int i = 0; int hflag = 1; for (; i < keyl; i++) { if (hmac[i] != extractedHMAC[i]) hflag = 0; } if (hflag) printf("HMAC successfully matched\n"); else printf("HMAC not matched\n"); fseek(finp, keyl, SEEK_SET); // Compare calculated HMAC with extracted HMAC ---> end //Decryption algo ------> start fread(extractedIV, 1, blks, finp); // read IV err = gcry_cipher_open(&gchandle, GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC, 0); if (err) { fprintf(stderr, "Failure: %s/%s\n", gcry_strsource(err), gcry_strerror(err)); exit(EXIT_FAILURE); } err = gcry_cipher_setkey(gchandle, key, keyl); if (err) { fprintf(stderr, "Failure: %s/%s\n", gcry_strsource(err), gcry_strerror(err)); exit(EXIT_FAILURE); } err = gcry_cipher_setiv(gchandle, extractedIV, blks); if (err) { fprintf(stderr, "Failure: %s/%s\n", gcry_strsource(err), gcry_strerror(err)); exit(EXIT_FAILURE); } if (!finp) { printf("Could not open input text file\n"); } else { int x = 0; char plaintext[blks]; while ((x = fread(plaintext, 1, blks, finp))) { if (x < blks) // add padding to last block outfileSize += x; err = gcry_cipher_decrypt(gchandle, ctext, blks, plaintext, x); if (err && x == blks) { fprintf(stderr, "Failure: %s/%s\n", gcry_strsource(err), gcry_strerror(err)); fclose(finp); fclose(fout); exit(EXIT_FAILURE); } fwrite(ctext, 1, blks, fout); } gcry_cipher_close(gchandle); gcry_md_close(hd); fclose(finp); fclose(fout); } free(hmacBuffer); //Decryption algo ------> end }
static void cipher_bench ( const char *algoname ) { static int header_printed; int algo; gcry_cipher_hd_t hd; int i; int keylen, blklen; char key[128]; char outbuf[1000], buf[1000]; size_t buflen; static struct { int mode; const char *name; int blocked; } modes[] = { { GCRY_CIPHER_MODE_ECB, "ECB", 1 }, { GCRY_CIPHER_MODE_CBC, "CBC", 1 }, { GCRY_CIPHER_MODE_CFB, "CFB", 0 }, { GCRY_CIPHER_MODE_CTR, "CTR", 0 }, { GCRY_CIPHER_MODE_STREAM, "STREAM", 0 }, {0} }; int modeidx; gcry_error_t err = GPG_ERR_NO_ERROR; if (!algoname) { for (i=1; i < 400; i++) if ( !gcry_cipher_test_algo (i) ) cipher_bench (gcry_cipher_algo_name (i)); return; } if (!header_printed) { printf ("%-10s", ""); for (modeidx=0; modes[modeidx].mode; modeidx++) printf (" %-15s", modes[modeidx].name ); putchar ('\n'); printf ("%-10s", ""); for (modeidx=0; modes[modeidx].mode; modeidx++) printf (" ---------------" ); putchar ('\n'); header_printed = 1; } algo = gcry_cipher_map_name (algoname); if (!algo) { fprintf (stderr, PGM ": invalid cipher algorithm `%s'\n", algoname); exit (1); } keylen = gcry_cipher_get_algo_keylen (algo); if (!keylen) { fprintf (stderr, PGM ": failed to get key length for algorithm `%s'\n", algoname); exit (1); } if ( keylen > sizeof key ) { fprintf (stderr, PGM ": algo %d, keylength problem (%d)\n", algo, keylen ); exit (1); } for (i=0; i < keylen; i++) key[i] = i + (clock () & 0xff); blklen = gcry_cipher_get_algo_blklen (algo); if (!blklen) { fprintf (stderr, PGM ": failed to get block length for algorithm `%s'\n", algoname); exit (1); } printf ("%-10s", gcry_cipher_algo_name (algo)); fflush (stdout); for (modeidx=0; modes[modeidx].mode; modeidx++) { if ((blklen > 1 && modes[modeidx].mode == GCRY_CIPHER_MODE_STREAM) | (blklen == 1 && modes[modeidx].mode != GCRY_CIPHER_MODE_STREAM)) { printf (" " ); continue; } for (i=0; i < sizeof buf; i++) buf[i] = i; err = gcry_cipher_open (&hd, algo, modes[modeidx].mode, 0); if (err) { fprintf (stderr, PGM ": error opening cipher `%s'\n", algoname); exit (1); } err = gcry_cipher_setkey (hd, key, keylen); if (err) { fprintf (stderr, "gcry_cipher_setkey failed: %s\n", gpg_strerror (err)); gcry_cipher_close (hd); exit (1); } buflen = sizeof buf; if (modes[modeidx].blocked) buflen = (buflen / blklen) * blklen; start_timer (); for (i=err=0; !err && i < 1000; i++) err = gcry_cipher_encrypt ( hd, outbuf, buflen, buf, buflen); stop_timer (); printf (" %s", elapsed_time ()); fflush (stdout); gcry_cipher_close (hd); if (err) { fprintf (stderr, "gcry_cipher_encrypt failed: %s\n", gpg_strerror (err) ); exit (1); } err = gcry_cipher_open (&hd, algo, modes[modeidx].mode, 0); if (err) { fprintf (stderr, PGM ": error opening cipher `%s'/n", algoname); exit (1); } err = gcry_cipher_setkey (hd, key, keylen); if (err) { fprintf (stderr, "gcry_cipher_setkey failed: %s\n", gpg_strerror (err)); gcry_cipher_close (hd); exit (1); } start_timer (); for (i=err=0; !err && i < 1000; i++) err = gcry_cipher_decrypt ( hd, outbuf, buflen, buf, buflen); stop_timer (); printf (" %s", elapsed_time ()); fflush (stdout); gcry_cipher_close (hd); if (err) { fprintf (stderr, "gcry_cipher_decrypt failed: %s\n", gpg_strerror (err) ); exit (1); } } putchar ('\n'); }
static void check_ctr_cipher (void) { struct tv { int algo; char key[MAX_DATA_LEN]; char ctr[MAX_DATA_LEN]; struct data { char plaintext[MAX_DATA_LEN]; int inlen; char out[MAX_DATA_LEN]; } data[MAX_DATA_LEN]; } tv[] = { /* http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf */ { GCRY_CIPHER_AES, "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c", "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff", { { "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a", 16, "\x87\x4d\x61\x91\xb6\x20\xe3\x26\x1b\xef\x68\x64\x99\x0d\xb6\xce" }, { "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51", 16, "\x98\x06\xf6\x6b\x79\x70\xfd\xff\x86\x17\x18\x7b\xb9\xff\xfd\xff" }, { "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef", 16, "\x5a\xe4\xdf\x3e\xdb\xd5\xd3\x5e\x5b\x4f\x09\x02\x0d\xb0\x3e\xab" }, { "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10", 16, "\x1e\x03\x1d\xda\x2f\xbe\x03\xd1\x79\x21\x70\xa0\xf3\x00\x9c\xee" }, } }, { GCRY_CIPHER_AES192, "\x8e\x73\xb0\xf7\xda\x0e\x64\x52\xc8\x10\xf3\x2b" "\x80\x90\x79\xe5\x62\xf8\xea\xd2\x52\x2c\x6b\x7b", "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff", { { "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a", 16, "\x1a\xbc\x93\x24\x17\x52\x1c\xa2\x4f\x2b\x04\x59\xfe\x7e\x6e\x0b" }, { "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51", 16, "\x09\x03\x39\xec\x0a\xa6\xfa\xef\xd5\xcc\xc2\xc6\xf4\xce\x8e\x94" }, { "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef", 16, "\x1e\x36\xb2\x6b\xd1\xeb\xc6\x70\xd1\xbd\x1d\x66\x56\x20\xab\xf7" }, { "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10", 16, "\x4f\x78\xa7\xf6\xd2\x98\x09\x58\x5a\x97\xda\xec\x58\xc6\xb0\x50" }, } }, { GCRY_CIPHER_AES256, "\x60\x3d\xeb\x10\x15\xca\x71\xbe\x2b\x73\xae\xf0\x85\x7d\x77\x81" "\x1f\x35\x2c\x07\x3b\x61\x08\xd7\x2d\x98\x10\xa3\x09\x14\xdf\xf4", "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff", { { "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a", 16, "\x60\x1e\xc3\x13\x77\x57\x89\xa5\xb7\xa7\xf5\x04\xbb\xf3\xd2\x28" }, { "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51", 16, "\xf4\x43\xe3\xca\x4d\x62\xb5\x9a\xca\x84\xe9\x90\xca\xca\xf5\xc5" }, { "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef", 16, "\x2b\x09\x30\xda\xa2\x3d\xe9\x4c\xe8\x70\x17\xba\x2d\x84\x98\x8d" }, { "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10", 16, "\xdf\xc9\xc5\x8d\xb6\x7a\xad\xa6\x13\xc2\xdd\x08\x45\x79\x41\xa6" } } } }; gcry_cipher_hd_t hde, hdd; char out[MAX_DATA_LEN]; int i, j, keylen, blklen; gcry_error_t err = 0; for (i = 0; i < sizeof (tv) / sizeof (tv[0]); i++) { err = gcry_cipher_open (&hde, tv[i].algo, GCRY_CIPHER_MODE_CTR, 0); if (!err) err = gcry_cipher_open (&hdd, tv[i].algo, GCRY_CIPHER_MODE_CTR, 0); if (err) { fail ("aes-ctr, grcy_open_cipher failed: %s\n", gpg_strerror (err)); return; } keylen = gcry_cipher_get_algo_keylen(tv[i].algo); if (!keylen) { fail ("aes-ctr, gcry_cipher_get_algo_keylen failed\n"); return; } err = gcry_cipher_setkey (hde, tv[i].key, keylen); if (!err) err = gcry_cipher_setkey (hdd, tv[i].key, keylen); if (err) { fail ("aes-ctr, gcry_cipher_setkey failed: %s\n", gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } blklen = gcry_cipher_get_algo_blklen(tv[i].algo); if (!blklen) { fail ("aes-ctr, gcry_cipher_get_algo_blklen failed\n"); return; } err = gcry_cipher_setctr (hde, tv[i].ctr, blklen); if (!err) err = gcry_cipher_setctr (hdd, tv[i].ctr, blklen); if (err) { fail ("aes-ctr, gcry_cipher_setctr failed: %s\n", gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } for (j = 0; tv[i].data[j].inlen; j++) { err = gcry_cipher_encrypt (hde, out, MAX_DATA_LEN, tv[i].data[j].plaintext, tv[i].data[j].inlen == -1 ? strlen (tv[i].data[j].plaintext) : tv[i].data[j].inlen); if (err) { fail ("aes-ctr, gcry_cipher_encrypt (%d, %d) failed: %s\n", i, j, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } if (memcmp (tv[i].data[j].out, out, tv[i].data[j].inlen)) fail ("aes-ctr, encrypt mismatch entry %d:%d\n", i, j); err = gcry_cipher_decrypt (hdd, out, tv[i].data[j].inlen, NULL, 0); if (err) { fail ("aes-ctr, gcry_cipher_decrypt (%d, %d) failed: %s\n", i, j, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } if (memcmp (tv[i].data[j].plaintext, out, tv[i].data[j].inlen)) fail ("aes-ctr, decrypt mismatch entry %d:%d\n", i, j); } gcry_cipher_close (hde); gcry_cipher_close (hdd); } }
int tls_process_record_handshake(struct SSLConnection *conn, const opaque *fragment) { struct Handshake *handshake; struct ClientHello *clienthello; struct ServerHello *serverhello; struct ClientKeyExchange *clientkeyex; const opaque *body; // Get Handshake data handshake = (struct Handshake *) fragment; if (UINT24_INT(handshake->length) > 0) { // Hanshake body pointer body = fragment + sizeof(struct Handshake); switch (handshake->type) { case hello_request: break; case client_hello: // Store client random clienthello = (struct ClientHello *) body; memcpy(&conn->client_random, &clienthello->random, sizeof(struct Random)); // Check we have a TLS handshake if (!(clienthello->client_version.major == 0x03 && clienthello->client_version.minor == 0x01)) { tls_connection_destroy(conn); return 1; } break; case server_hello: // Store server random serverhello = (struct ServerHello *) body; memcpy(&conn->server_random, &serverhello->random, sizeof(struct Random)); // Get the selected cipher memcpy(&conn->cipher_suite, body + sizeof(struct ServerHello) + serverhello->session_id_length, sizeof(uint16_t)); // Check if we have a handled cipher if (tls_connection_load_cipher(conn) != 0) { tls_connection_destroy(conn); return 1; } break; case certificate: case certificate_request: case server_hello_done: case certificate_verify: break; case client_key_exchange: // Decrypt PreMasterKey clientkeyex = (struct ClientKeyExchange *) body; gnutls_datum_t exkeys, pms; exkeys.size = UINT16_INT(clientkeyex->length); exkeys.data = (unsigned char *)&clientkeyex->exchange_keys; gnutls_privkey_decrypt_data(conn->server_private_key, 0, &exkeys, &pms); memcpy(&conn->pre_master_secret, pms.data, pms.size); // Get MasterSecret unsigned char *seed = sng_malloc(sizeof(struct Random) * 2); memcpy(seed, &conn->client_random, sizeof(struct Random)); memcpy(seed + sizeof(struct Random), &conn->server_random, sizeof(struct Random)); PRF((unsigned char *) &conn->master_secret, sizeof(struct MasterSecret), (unsigned char *) &conn->pre_master_secret, sizeof(struct PreMasterSecret), (unsigned char *) "master secret", seed, sizeof(struct Random) * 2); memcpy(seed, &conn->server_random, sizeof(struct Random)); memcpy(seed + sizeof(struct Random), &conn->client_random, sizeof(struct Random)); // Generate MACs, Write Keys and IVs PRF((unsigned char *) &conn->key_material, sizeof(struct tls_data), (unsigned char *) &conn->master_secret, sizeof(struct MasterSecret), (unsigned char *) "key expansion", seed, sizeof(struct Random) * 2); // Done with the seed sng_free(seed); // Create Client decoder gcry_cipher_open(&conn->client_cipher_ctx, conn->ciph, GCRY_CIPHER_MODE_CBC, 0); gcry_cipher_setkey(conn->client_cipher_ctx, conn->key_material.client_write_key, gcry_cipher_get_algo_keylen(conn->ciph)); gcry_cipher_setiv(conn->client_cipher_ctx, conn->key_material.client_write_IV, gcry_cipher_get_algo_blklen(conn->ciph)); // Create Server decoder gcry_cipher_open(&conn->server_cipher_ctx, conn->ciph, GCRY_CIPHER_MODE_CBC, 0); gcry_cipher_setkey(conn->server_cipher_ctx, conn->key_material.server_write_key, gcry_cipher_get_algo_keylen(conn->ciph)); gcry_cipher_setiv(conn->server_cipher_ctx, conn->key_material.server_write_IV, gcry_cipher_get_algo_blklen(conn->ciph)); break; case finished: break; default: if (conn->encrypted) { // Encrypted Hanshake Message unsigned char *decoded = sng_malloc(48); uint32_t decodedlen; tls_process_record_data(conn, fragment, 48, &decoded, &decodedlen); sng_free(decoded); } break; } } return 0; }
static int xmlSecGCryptKWDes3Encrypt(const xmlSecByte *key, xmlSecSize keySize, const xmlSecByte *iv, xmlSecSize ivSize, const xmlSecByte *in, xmlSecSize inSize, xmlSecByte *out, xmlSecSize outSize, int enc) { size_t key_len = gcry_cipher_get_algo_keylen(GCRY_CIPHER_3DES); size_t block_len = gcry_cipher_get_algo_blklen(GCRY_CIPHER_3DES); gcry_cipher_hd_t cipherCtx; gcry_error_t err; xmlSecAssert2(key != NULL, -1); xmlSecAssert2(keySize >= key_len, -1); xmlSecAssert2(iv != NULL, -1); xmlSecAssert2(ivSize >= block_len, -1); xmlSecAssert2(in != NULL, -1); xmlSecAssert2(inSize > 0, -1); xmlSecAssert2(out != NULL, -1); xmlSecAssert2(outSize >= inSize, -1); err = gcry_cipher_open(&cipherCtx, GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CBC, GCRY_CIPHER_SECURE); /* we are paranoid */ if(err != GPG_ERR_NO_ERROR) { xmlSecError(XMLSEC_ERRORS_HERE, NULL, "gcry_cipher_open(GCRY_CIPHER_3DES)", XMLSEC_ERRORS_R_CRYPTO_FAILED, XMLSEC_GCRYPT_REPORT_ERROR(err)); return(-1); } err = gcry_cipher_setkey(cipherCtx, key, keySize); if(err != GPG_ERR_NO_ERROR) { xmlSecError(XMLSEC_ERRORS_HERE, NULL, "gcry_cipher_setkey", XMLSEC_ERRORS_R_CRYPTO_FAILED, XMLSEC_GCRYPT_REPORT_ERROR(err)); return(-1); } err = gcry_cipher_setiv(cipherCtx, iv, ivSize); if(err != GPG_ERR_NO_ERROR) { xmlSecError(XMLSEC_ERRORS_HERE, NULL, "gcry_cipher_setiv", XMLSEC_ERRORS_R_CRYPTO_FAILED, XMLSEC_GCRYPT_REPORT_ERROR(err)); return(-1); } if(enc) { err = gcry_cipher_encrypt(cipherCtx, out, outSize, in, inSize); if(err != GPG_ERR_NO_ERROR) { xmlSecError(XMLSEC_ERRORS_HERE, NULL, "gcry_cipher_encrypt", XMLSEC_ERRORS_R_CRYPTO_FAILED, XMLSEC_GCRYPT_REPORT_ERROR(err)); gcry_cipher_close(cipherCtx); return(-1); } } else { err = gcry_cipher_decrypt(cipherCtx, out, outSize, in, inSize); if(err != GPG_ERR_NO_ERROR) { xmlSecError(XMLSEC_ERRORS_HERE, NULL, "gcry_cipher_decrypt", XMLSEC_ERRORS_R_CRYPTO_FAILED, XMLSEC_GCRYPT_REPORT_ERROR(err)); gcry_cipher_close(cipherCtx); return(-1); } } /* done */ gcry_cipher_close(cipherCtx); return((int)inSize); /* out size == in size */ }
static void check_one_cipher (int algo, int mode, int flags) { gcry_cipher_hd_t hd; char key[32], plain[16], in[16], out[16]; int keylen; gcry_error_t err = 0; memcpy (key, "0123456789abcdef.,;/[]{}-=ABCDEF", 32); memcpy (plain, "foobar42FOOBAR17", 16); keylen = gcry_cipher_get_algo_keylen (algo); if (!keylen) { fail ("algo %d, mode %d, gcry_cipher_get_algo_keylen failed\n", algo, mode); return; } if (keylen < 40 / 8 || keylen > 32) { fail ("algo %d, mode %d, keylength problem (%d)\n", algo, mode, keylen); return; } err = gcry_cipher_open (&hd, algo, mode, flags); if (err) { fail ("algo %d, mode %d, grcy_open_cipher failed: %s\n", algo, mode, gpg_strerror (err)); return; } err = gcry_cipher_setkey (hd, key, keylen); if (err) { fail ("algo %d, mode %d, gcry_cipher_setkey failed: %s\n", algo, mode, gpg_strerror (err)); gcry_cipher_close (hd); return; } err = gcry_cipher_encrypt (hd, out, 16, plain, 16); if (err) { fail ("algo %d, mode %d, gcry_cipher_encrypt failed: %s\n", algo, mode, gpg_strerror (err)); gcry_cipher_close (hd); return; } gcry_cipher_reset (hd); err = gcry_cipher_decrypt (hd, in, 16, out, 16); if (err) { fail ("algo %d, mode %d, gcry_cipher_decrypt failed: %s\n", algo, mode, gpg_strerror (err)); gcry_cipher_close (hd); return; } gcry_cipher_close (hd); if (memcmp (plain, in, 16)) fail ("algo %d, mode %d, encrypt-decrypt mismatch\n", algo, mode); }
gpointer encrypt_file (const gchar *input_file_path, const gchar *pwd, const gchar *algo, const gchar *algo_mode) { Metadata *header_metadata = g_new0 (Metadata, 1); CryptoKeys *encryption_keys = g_new0 (CryptoKeys, 1); set_algo_and_mode (header_metadata, algo, algo_mode); gsize algo_key_len = gcry_cipher_get_algo_keylen (header_metadata->algo); gsize algo_blk_len = gcry_cipher_get_algo_blklen (header_metadata->algo); header_metadata->iv_size = algo_blk_len; // iv must be the same size as the block size gcry_create_nonce (header_metadata->iv, header_metadata->iv_size); gcry_create_nonce (header_metadata->salt, KDF_SALT_SIZE); if (!setup_keys (pwd, algo_key_len, header_metadata, encryption_keys)) { multiple_free (2, (gpointer) &encryption_keys, (gpointer) &header_metadata); return g_strdup ("Couldn't setup the encryption keys, exiting..."); } goffset filesize = get_file_size (input_file_path); GError *err = NULL; GFile *in_file = g_file_new_for_path (input_file_path); GFileInputStream *in_stream = g_file_read (in_file, NULL, &err); if (err != NULL) { multiple_gcry_free (3, (gpointer) &encryption_keys->derived_key, (gpointer) &encryption_keys->crypto_key, (gpointer) &encryption_keys->hmac_key); multiple_free (2, (gpointer) &encryption_keys, (gpointer) &header_metadata); g_object_unref (in_file); return g_strdup (err->message); } gchar *output_file_path = g_strconcat (input_file_path, ".enc", NULL); GFile *out_file = g_file_new_for_path (output_file_path); GFileOutputStream *out_stream = g_file_append_to (out_file, G_FILE_CREATE_REPLACE_DESTINATION, NULL, &err); if (err != NULL) { multiple_gcry_free (3, (gpointer) &encryption_keys->derived_key, (gpointer) &encryption_keys->crypto_key, (gpointer) &encryption_keys->hmac_key); multiple_free (3, (gpointer) &encryption_keys, (gpointer) &header_metadata, (gpointer) &output_file_path); multiple_unref (3, (gpointer) &in_file, (gpointer) &out_file, (gpointer) &in_stream); g_input_stream_close (G_INPUT_STREAM (in_stream), NULL, NULL); return g_strdup (err->message); } gcry_cipher_hd_t hd; gcry_cipher_open (&hd, header_metadata->algo, header_metadata->algo_mode, 0); gcry_cipher_setkey (hd, encryption_keys->crypto_key, algo_key_len); gint64 number_of_blocks; gint number_of_padding_bytes; gchar *ret_msg; if (header_metadata->algo_mode == GCRY_CIPHER_MODE_CBC) { set_number_of_blocks_and_padding_bytes (filesize, algo_blk_len, &number_of_blocks, &number_of_padding_bytes); gcry_cipher_setiv (hd, header_metadata->iv, header_metadata->iv_size); ret_msg = encrypt_using_cbc_mode (header_metadata, &hd, number_of_blocks, number_of_padding_bytes, algo_blk_len, in_stream, out_stream); } else { gcry_cipher_setctr (hd, header_metadata->iv, header_metadata->iv_size); ret_msg = encrypt_using_ctr_mode (header_metadata, &hd, filesize, in_stream, out_stream); } if (ret_msg != NULL) { multiple_gcry_free (3, (gpointer) &encryption_keys->derived_key, (gpointer) &encryption_keys->crypto_key, (gpointer) &encryption_keys->hmac_key); multiple_free (3, (gpointer) &encryption_keys, (gpointer) &header_metadata, (gpointer) &output_file_path); multiple_unref (4, (gpointer) &in_file, (gpointer) &out_file, (gpointer) &in_stream, (gpointer) &out_stream); g_input_stream_close (G_INPUT_STREAM (in_stream), NULL, NULL); g_output_stream_close (G_OUTPUT_STREAM (out_stream), NULL, NULL); return g_strdup (ret_msg); } gcry_cipher_close (hd); guchar *hmac = calculate_hmac (output_file_path, encryption_keys->hmac_key, NULL); gssize written_bytes = g_output_stream_write (G_OUTPUT_STREAM (out_stream), hmac, SHA512_DIGEST_SIZE, NULL, &err); if (written_bytes == -1) { multiple_gcry_free (3, (gpointer) &encryption_keys->derived_key, (gpointer) &encryption_keys->crypto_key, (gpointer) &encryption_keys->hmac_key); multiple_free (4, (gpointer) &encryption_keys, (gpointer) &header_metadata, (gpointer) &output_file_path, (gpointer) &hmac); multiple_unref (4, (gpointer) &in_file, (gpointer) &out_file, (gpointer) &in_stream, (gpointer) &out_stream); g_output_stream_close (G_OUTPUT_STREAM (out_stream), NULL, NULL); return g_strdup (err->message); } g_input_stream_close (G_INPUT_STREAM (in_stream), NULL, NULL); g_output_stream_close (G_OUTPUT_STREAM (out_stream), NULL, NULL); multiple_gcry_free (3, (gpointer) &encryption_keys->derived_key, (gpointer) &encryption_keys->crypto_key, (gpointer) &encryption_keys->hmac_key); multiple_free (4, (gpointer) &output_file_path, (gpointer) &encryption_keys, (gpointer) &header_metadata, (gpointer) &hmac); multiple_unref (4, (gpointer) &in_file, (gpointer) &out_file, (gpointer) &in_stream, (gpointer) &out_stream); return NULL; }
size_t _encryption_key_size(SINGLE_QSP_ARG_DECL) { /* Retrieve the key length in bytes used with algorithm A. */ return gcry_cipher_get_algo_keylen (the_crypt_algo); }
gboolean egg_openssl_encrypt_block (const gchar *dekinfo, const gchar *password, gssize n_password, const guchar *data, gsize n_data, guchar **encrypted, gsize *n_encrypted) { gsize n_overflow, n_batch, n_padding; gcry_cipher_hd_t ch; guchar *key = NULL; guchar *iv = NULL; guchar *padded = NULL; int gcry, ivlen; int algo = 0; int mode = 0; if (!parse_dekinfo (dekinfo, &algo, &mode, &iv)) g_return_val_if_reached (FALSE); ivlen = gcry_cipher_get_algo_blklen (algo); /* We assume the iv is at least as long as at 8 byte salt */ g_return_val_if_fail (ivlen >= 8, FALSE); /* IV is already set from the DEK info */ if (!egg_symkey_generate_simple (algo, GCRY_MD_MD5, password, n_password, iv, 8, 1, &key, NULL)) g_return_val_if_reached (FALSE); gcry = gcry_cipher_open (&ch, algo, mode, 0); g_return_val_if_fail (!gcry, FALSE); gcry = gcry_cipher_setkey (ch, key, gcry_cipher_get_algo_keylen (algo)); g_return_val_if_fail (!gcry, FALSE); egg_secure_free (key); /* 16 = 128 bits */ gcry = gcry_cipher_setiv (ch, iv, ivlen); g_return_val_if_fail (!gcry, FALSE); g_free (iv); /* Allocate output area */ n_overflow = (n_data % ivlen); n_padding = n_overflow ? (ivlen - n_overflow) : 0; n_batch = n_data - n_overflow; *n_encrypted = n_data + n_padding; *encrypted = g_malloc0 (*n_encrypted); g_assert (*n_encrypted % ivlen == 0); g_assert (*n_encrypted >= n_data); g_assert (*n_encrypted == n_batch + n_overflow + n_padding); /* Encrypt everything but the last bit */ gcry = gcry_cipher_encrypt (ch, *encrypted, n_batch, (void*)data, n_batch); if (gcry) { g_free (*encrypted); g_return_val_if_reached (FALSE); } /* Encrypt the padded block */ if (n_overflow) { padded = egg_secure_alloc (ivlen); memset (padded, 0, ivlen); memcpy (padded, data + n_batch, n_overflow); gcry = gcry_cipher_encrypt (ch, *encrypted + n_batch, ivlen, padded, ivlen); egg_secure_free (padded); if (gcry) { g_free (*encrypted); g_return_val_if_reached (FALSE); } } gcry_cipher_close (ch); return TRUE; }
static void cipher_bench ( const char *algoname ) { static int header_printed; int algo; gcry_cipher_hd_t hd; int i; int keylen, blklen; char key[128]; char *outbuf, *buf; char *raw_outbuf, *raw_buf; size_t allocated_buflen, buflen; int repetitions; static struct { int mode; const char *name; int blocked; } modes[] = { { GCRY_CIPHER_MODE_ECB, " ECB/Stream", 1 }, { GCRY_CIPHER_MODE_CBC, " CBC", 1 }, { GCRY_CIPHER_MODE_CFB, " CFB", 0 }, { GCRY_CIPHER_MODE_OFB, " OFB", 0 }, { GCRY_CIPHER_MODE_CTR, " CTR", 0 }, { GCRY_CIPHER_MODE_STREAM, "", 0 }, {0} }; int modeidx; gcry_error_t err = GPG_ERR_NO_ERROR; if (!algoname) { for (i=1; i < 400; i++) if ( !gcry_cipher_test_algo (i) ) cipher_bench (gcry_cipher_algo_name (i)); return; } if (large_buffers) { allocated_buflen = 1024 * 100; repetitions = 10; } else { allocated_buflen = 1024; repetitions = 1000; } repetitions *= cipher_repetitions; raw_buf = gcry_xmalloc (allocated_buflen+15); buf = (raw_buf + ((16 - ((size_t)raw_buf & 0x0f)) % buffer_alignment)); outbuf = raw_outbuf = gcry_xmalloc (allocated_buflen+15); outbuf = (raw_outbuf + ((16 - ((size_t)raw_outbuf & 0x0f)) % buffer_alignment)); if (!header_printed) { if (cipher_repetitions != 1) printf ("Running each test %d times.\n", cipher_repetitions); printf ("%-12s", ""); for (modeidx=0; modes[modeidx].mode; modeidx++) if (*modes[modeidx].name) printf (" %-15s", modes[modeidx].name ); putchar ('\n'); printf ("%-12s", ""); for (modeidx=0; modes[modeidx].mode; modeidx++) if (*modes[modeidx].name) printf (" ---------------" ); putchar ('\n'); header_printed = 1; } algo = gcry_cipher_map_name (algoname); if (!algo) { fprintf (stderr, PGM ": invalid cipher algorithm `%s'\n", algoname); exit (1); } keylen = gcry_cipher_get_algo_keylen (algo); if (!keylen) { fprintf (stderr, PGM ": failed to get key length for algorithm `%s'\n", algoname); exit (1); } if ( keylen > sizeof key ) { fprintf (stderr, PGM ": algo %d, keylength problem (%d)\n", algo, keylen ); exit (1); } for (i=0; i < keylen; i++) key[i] = i + (clock () & 0xff); blklen = gcry_cipher_get_algo_blklen (algo); if (!blklen) { fprintf (stderr, PGM ": failed to get block length for algorithm `%s'\n", algoname); exit (1); } printf ("%-12s", gcry_cipher_algo_name (algo)); fflush (stdout); for (modeidx=0; modes[modeidx].mode; modeidx++) { if ((blklen > 1 && modes[modeidx].mode == GCRY_CIPHER_MODE_STREAM) | (blklen == 1 && modes[modeidx].mode != GCRY_CIPHER_MODE_STREAM)) continue; for (i=0; i < sizeof buf; i++) buf[i] = i; err = gcry_cipher_open (&hd, algo, modes[modeidx].mode, 0); if (err) { fprintf (stderr, PGM ": error opening cipher `%s'\n", algoname); exit (1); } if (!cipher_with_keysetup) { err = gcry_cipher_setkey (hd, key, keylen); if (err) { fprintf (stderr, "gcry_cipher_setkey failed: %s\n", gpg_strerror (err)); gcry_cipher_close (hd); exit (1); } } buflen = allocated_buflen; if (modes[modeidx].blocked) buflen = (buflen / blklen) * blklen; start_timer (); for (i=err=0; !err && i < repetitions; i++) { if (cipher_with_keysetup) { err = gcry_cipher_setkey (hd, key, keylen); if (err) { fprintf (stderr, "gcry_cipher_setkey failed: %s\n", gpg_strerror (err)); gcry_cipher_close (hd); exit (1); } } err = gcry_cipher_encrypt ( hd, outbuf, buflen, buf, buflen); } stop_timer (); printf (" %s", elapsed_time ()); fflush (stdout); gcry_cipher_close (hd); if (err) { fprintf (stderr, "gcry_cipher_encrypt failed: %s\n", gpg_strerror (err) ); exit (1); } err = gcry_cipher_open (&hd, algo, modes[modeidx].mode, 0); if (err) { fprintf (stderr, PGM ": error opening cipher `%s'/n", algoname); exit (1); } if (!cipher_with_keysetup) { err = gcry_cipher_setkey (hd, key, keylen); if (err) { fprintf (stderr, "gcry_cipher_setkey failed: %s\n", gpg_strerror (err)); gcry_cipher_close (hd); exit (1); } } start_timer (); for (i=err=0; !err && i < repetitions; i++) { if (cipher_with_keysetup) { err = gcry_cipher_setkey (hd, key, keylen); if (err) { fprintf (stderr, "gcry_cipher_setkey failed: %s\n", gpg_strerror (err)); gcry_cipher_close (hd); exit (1); } } err = gcry_cipher_decrypt ( hd, outbuf, buflen, buf, buflen); } stop_timer (); printf (" %s", elapsed_time ()); fflush (stdout); gcry_cipher_close (hd); if (err) { fprintf (stderr, "gcry_cipher_decrypt failed: %s\n", gpg_strerror (err) ); exit (1); } } putchar ('\n'); gcry_free (raw_buf); gcry_free (raw_outbuf); }