static void gcmtest(FILE *in, FILE *out, int encrypt) { char *keyword, *value; int keylen = -1, ivlen = -1, aadlen = -1, taglen = -1, ptlen = -1; int rv; long l; unsigned char *key = NULL, *iv = NULL, *aad = NULL, *tag = NULL; unsigned char *ct = NULL, *pt = NULL; EVP_CIPHER_CTX ctx; const EVP_CIPHER *gcm = NULL; FIPS_cipher_ctx_init(&ctx); while(fgets(buf,sizeof buf,in) != NULL) { fputs(buf,out); if (!parse_line(&keyword, &value, lbuf, buf)) continue; if(!strcmp(keyword,"[Keylen")) { keylen = atoi(value); if (keylen == 128) gcm = EVP_aes_128_gcm(); else if (keylen == 192) gcm = EVP_aes_192_gcm(); else if (keylen == 256) gcm = EVP_aes_256_gcm(); else { fprintf(stderr, "Unsupported keylen %d\n", keylen); } keylen >>= 3; } else if (!strcmp(keyword, "[IVlen"))
/* * aes_gcm_openssl_context_init(...) initializes the aes_gcm_context * using the value in key[]. * * the key is the secret key */ static srtp_err_status_t srtp_aes_gcm_openssl_context_init(void *cv, const uint8_t *key) { srtp_aes_gcm_ctx_t *c = (srtp_aes_gcm_ctx_t *)cv; const EVP_CIPHER *evp; c->dir = srtp_direction_any; debug_print(srtp_mod_aes_gcm, "key: %s", srtp_octet_string_hex_string(key, c->key_size)); switch (c->key_size) { case SRTP_AES_256_KEY_LEN: evp = EVP_aes_256_gcm(); break; case SRTP_AES_128_KEY_LEN: evp = EVP_aes_128_gcm(); break; default: return (srtp_err_status_bad_param); break; } if (!EVP_CipherInit_ex(c->ctx, evp, NULL, key, NULL, 0)) { return (srtp_err_status_init_fail); } return (srtp_err_status_ok); }
void aes_gcm_encrypt(void) { EVP_CIPHER_CTX *ctx; int outlen, tmplen; unsigned char outbuf[1024]; printf("AES GCM Encrypt:\n"); printf("Plaintext:\n"); BIO_dump_fp(stdout, gcm_pt, sizeof(gcm_pt)); ctx = EVP_CIPHER_CTX_new(); /* Set cipher type and mode */ EVP_EncryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL); /* Set IV length if default 96 bits is not appropriate */ EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, sizeof(gcm_iv), NULL); /* Initialise key and IV */ EVP_EncryptInit_ex(ctx, NULL, NULL, gcm_key, gcm_iv); /* Zero or more calls to specify any AAD */ EVP_EncryptUpdate(ctx, NULL, &outlen, gcm_aad, sizeof(gcm_aad)); /* Encrypt plaintext */ EVP_EncryptUpdate(ctx, outbuf, &outlen, gcm_pt, sizeof(gcm_pt)); /* Output encrypted block */ printf("Ciphertext:\n"); BIO_dump_fp(stdout, outbuf, outlen); /* Finalise: note get no output for GCM */ EVP_EncryptFinal_ex(ctx, outbuf, &outlen); /* Get tag */ EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, 16, outbuf); /* Output tag */ printf("Tag:\n"); BIO_dump_fp(stdout, outbuf, 16); EVP_CIPHER_CTX_free(ctx); }
void aes_gcm_decrypt(void) { EVP_CIPHER_CTX *ctx; int outlen, tmplen, rv; unsigned char outbuf[1024]; printf("AES GCM Derypt:\n"); printf("Ciphertext:\n"); BIO_dump_fp(stdout, gcm_ct, sizeof(gcm_ct)); ctx = EVP_CIPHER_CTX_new(); /* Select cipher */ EVP_DecryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL); /* Set IV length, omit for 96 bits */ EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, sizeof(gcm_iv), NULL); /* Specify key and IV */ EVP_DecryptInit_ex(ctx, NULL, NULL, gcm_key, gcm_iv); /* Zero or more calls to specify any AAD */ EVP_DecryptUpdate(ctx, NULL, &outlen, gcm_aad, sizeof(gcm_aad)); /* Decrypt plaintext */ EVP_DecryptUpdate(ctx, outbuf, &outlen, gcm_ct, sizeof(gcm_ct)); /* Output decrypted block */ printf("Plaintext:\n"); BIO_dump_fp(stdout, outbuf, outlen); /* Set expected tag value. */ EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, sizeof(gcm_tag), (void *)gcm_tag); /* Finalise: note get no output for GCM */ rv = EVP_DecryptFinal_ex(ctx, outbuf, &outlen); /* * Print out return value. If this is not successful authentication * failed and plaintext is not trustworthy. */ printf("Tag Verify %s\n", rv > 0 ? "Successful!" : "Failed!"); EVP_CIPHER_CTX_free(ctx); }
int encrypt(unsigned char *plaintext, int plaintext_len, unsigned char *aad, int aad_len, unsigned char *key, unsigned char *iv, unsigned char *ciphertext, unsigned char *tag) { EVP_CIPHER_CTX *ctx; int len; int ciphertext_len; /* Create and initialise the context */ if(!(ctx = EVP_CIPHER_CTX_new())) handleErrors(); /* Initialise the encryption operation. */ if(1 != EVP_EncryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL)) handleErrors(); /* Set IV length if default 12 bytes (96 bits) is not appropriate */ if(1 != EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, 16, NULL)) handleErrors(); /* Initialise key and IV */ if(1 != EVP_EncryptInit_ex(ctx, NULL, NULL, key, iv)) handleErrors(); /* Provide any AAD data. This can be called zero or more times as * required */ /* if(1 != EVP_EncryptUpdate(ctx, NULL, &len, aad, aad_len)) handleErrors(); */ /* Provide the message to be encrypted, and obtain the encrypted output. * EVP_EncryptUpdate can be called multiple times if necessary */ if(1 != EVP_EncryptUpdate(ctx, ciphertext, &len, plaintext, plaintext_len)) handleErrors(); ciphertext_len = len; /* Finalise the encryption. Normally ciphertext bytes may be written at * this stage, but this does not occur in GCM mode */ if(1 != EVP_EncryptFinal_ex(ctx, ciphertext + len, &len)) handleErrors(); ciphertext_len += len; /* Get the tag */ /* if(1 != EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, 16, tag)) handleErrors(); */ /* Clean up */ EVP_CIPHER_CTX_free(ctx); return ciphertext_len; }
int SSL_library_init(void) { #ifndef OPENSSL_NO_DES EVP_add_cipher(EVP_des_cbc()); EVP_add_cipher(EVP_des_ede3_cbc()); #endif #ifndef OPENSSL_NO_IDEA EVP_add_cipher(EVP_idea_cbc()); #endif #ifndef OPENSSL_NO_RC4 EVP_add_cipher(EVP_rc4()); #if !defined(OPENSSL_NO_MD5) && (defined(__x86_64) || defined(__x86_64__)) EVP_add_cipher(EVP_rc4_hmac_md5()); #endif #endif #ifndef OPENSSL_NO_RC2 EVP_add_cipher(EVP_rc2_cbc()); /* Not actually used for SSL/TLS but this makes PKCS#12 work * if an application only calls SSL_library_init(). */ EVP_add_cipher(EVP_rc2_40_cbc()); #endif EVP_add_cipher(EVP_aes_128_cbc()); EVP_add_cipher(EVP_aes_192_cbc()); EVP_add_cipher(EVP_aes_256_cbc()); EVP_add_cipher(EVP_aes_128_gcm()); EVP_add_cipher(EVP_aes_256_gcm()); EVP_add_cipher(EVP_aes_128_cbc_hmac_sha1()); EVP_add_cipher(EVP_aes_256_cbc_hmac_sha1()); #ifndef OPENSSL_NO_CAMELLIA EVP_add_cipher(EVP_camellia_128_cbc()); EVP_add_cipher(EVP_camellia_256_cbc()); #endif EVP_add_digest(EVP_md5()); EVP_add_digest_alias(SN_md5, "ssl2-md5"); EVP_add_digest_alias(SN_md5, "ssl3-md5"); EVP_add_digest(EVP_sha1()); /* RSA with sha1 */ EVP_add_digest_alias(SN_sha1, "ssl3-sha1"); EVP_add_digest_alias(SN_sha1WithRSAEncryption, SN_sha1WithRSA); EVP_add_digest(EVP_sha224()); EVP_add_digest(EVP_sha256()); EVP_add_digest(EVP_sha384()); EVP_add_digest(EVP_sha512()); EVP_add_digest(EVP_dss1()); /* DSA with sha1 */ EVP_add_digest_alias(SN_dsaWithSHA1, SN_dsaWithSHA1_2); EVP_add_digest_alias(SN_dsaWithSHA1, "DSS1"); EVP_add_digest_alias(SN_dsaWithSHA1, "dss1"); EVP_add_digest(EVP_ecdsa()); /* initialize cipher/digest methods table */ ssl_load_ciphers(); return (1); }
const EVP_CIPHER* algid_to_evp_aead(uint32_t alg){ switch(alg&(SOTER_SYM_ALG_MASK|SOTER_SYM_PADDING_MASK|SOTER_SYM_KEY_LENGTH_MASK)){ case SOTER_SYM_AES_GCM|SOTER_SYM_256_KEY_LENGTH: return EVP_aes_256_gcm(); case SOTER_SYM_AES_GCM|SOTER_SYM_192_KEY_LENGTH: return EVP_aes_192_gcm(); case SOTER_SYM_AES_GCM|SOTER_SYM_128_KEY_LENGTH: return EVP_aes_128_gcm(); } return NULL; }
size_t crypto_encrypt_buffer(const char *in, size_t inlen, char *out, size_t outlen) { EVP_CIPHER_CTX ctx; uint8_t iv[IV_SIZE]; uint8_t tag[GCM_TAG_SIZE]; uint8_t version = API_VERSION; off_t sz; int olen; int len = 0; int ret = 0; /* output buffer does not have enough room */ if (outlen < inlen + sizeof version + sizeof tag + sizeof iv) return 0; /* input should not exceed 64GB */ sz = inlen; if (sz >= 0x1000000000LL) return 0; /* prepend version */ *out = version; len++; /* generate IV */ memset(iv, 0, sizeof iv); arc4random_buf(iv, sizeof iv); memcpy(out + len, iv, sizeof iv); len += sizeof iv; EVP_CIPHER_CTX_init(&ctx); EVP_EncryptInit_ex(&ctx, EVP_aes_256_gcm(), NULL, cp.key, iv); /* encrypt buffer */ if (!EVP_EncryptUpdate(&ctx, out + len, &olen, in, inlen)) goto end; len += olen; /* finalize and write last chunk if any */ if (!EVP_EncryptFinal_ex(&ctx, out + len, &olen)) goto end; len += olen; /* get and append tag */ EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_GCM_GET_TAG, sizeof tag, tag); memcpy(out + len, tag, sizeof tag); ret = len + sizeof tag; end: EVP_CIPHER_CTX_cleanup(&ctx); return ret; }
void encrypt_gcm(uint8_t *key, uint8_t *iv, void *addr, size_t len, uint8_t *tag) { EVP_CIPHER_CTX ctx; int tmp; EVP_CIPHER_CTX_init(&ctx); assert(EVP_EncryptInit_ex(&ctx, EVP_aes_256_gcm(), NULL, NULL, NULL)); EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_GCM_SET_IVLEN, IV_LEN, NULL); assert(EVP_EncryptInit_ex(&ctx, NULL, NULL, key, iv)); assert(EVP_EncryptUpdate(&ctx, addr, &tmp, addr, len)); assert(EVP_EncryptFinal_ex(&ctx, NULL, &tmp)); EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_GCM_GET_TAG, TAG_LEN, tag); EVP_CIPHER_CTX_cleanup(&ctx); }
size_t crypto_decrypt_buffer(const char *in, size_t inlen, char *out, size_t outlen) { EVP_CIPHER_CTX ctx; uint8_t iv[IV_SIZE]; uint8_t tag[GCM_TAG_SIZE]; int olen; int len = 0; int ret = 0; /* out does not have enough room */ if (outlen < inlen - sizeof tag + sizeof iv) return 0; /* extract tag */ memcpy(tag, in + inlen - sizeof tag, sizeof tag); inlen -= sizeof tag; /* check version */ if (*in != API_VERSION) return 0; in++; inlen--; /* extract IV */ memset(iv, 0, sizeof iv); memcpy(iv, in, sizeof iv); inlen -= sizeof iv; in += sizeof iv; EVP_CIPHER_CTX_init(&ctx); EVP_DecryptInit_ex(&ctx, EVP_aes_256_gcm(), NULL, cp.key, iv); /* set expected tag */ EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_GCM_SET_TAG, sizeof tag, tag); /* decrypt buffer */ if (!EVP_DecryptUpdate(&ctx, out, &olen, in, inlen)) goto end; len += olen; /* finalize, write last chunk if any and perform authentication check */ if (!EVP_DecryptFinal_ex(&ctx, out + len, &olen)) goto end; ret = len + olen; end: EVP_CIPHER_CTX_cleanup(&ctx); return ret; }
bool decrypt_gcm(uint8_t *key, uint8_t *iv, void *addr, size_t len, uint8_t *tag) { EVP_CIPHER_CTX ctx; int rc, tmp; EVP_CIPHER_CTX_init(&ctx); assert(EVP_DecryptInit_ex(&ctx, EVP_aes_256_gcm(), NULL, NULL, NULL)); EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_GCM_SET_IVLEN, IV_LEN, NULL); EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_GCM_SET_TAG, TAG_LEN, tag); assert(EVP_DecryptInit_ex(&ctx, NULL, NULL, key, iv)); assert(EVP_DecryptUpdate(&ctx, addr, &tmp, addr, len)); rc = EVP_CipherFinal_ex(&ctx, NULL, &tmp); EVP_CIPHER_CTX_cleanup(&ctx); return rc == 1; }
static int encrypt_data(char *in, int len, char *out) { unsigned char outbuf[MAX_LEN]; unsigned char temp[MAX_LEN]; unsigned char iv[IV_SIZE]; unsigned char tag[16]; unsigned char *step; int tmplen=0, outlen=0; // copy plain text message into temp memset(temp,0x00,MAX_LEN); memcpy(temp,in,len); if (glob_key[0] == 0x00) // Generate key if its the first packet gen_key(); RAND_bytes(iv,IV_SIZE); // Generate random IV EVP_CIPHER_CTX *ctx; ctx = EVP_CIPHER_CTX_new(); EVP_CIPHER_CTX_init (ctx); EVP_EncryptInit_ex (ctx, EVP_aes_256_gcm() , NULL, (const unsigned char *)glob_key, (const unsigned char *)iv); if (!EVP_EncryptUpdate (ctx, outbuf, &outlen, (const unsigned char *)temp, len)) { fprintf(stderr, "[!] Error in EVP_EncryptUpdate()\n"); EVP_CIPHER_CTX_cleanup (ctx); return 0; } if (!EVP_EncryptFinal_ex (ctx, outbuf + outlen, &tmplen)) { fprintf(stderr, "[!] Error in EVP_EncryptFinal_ex()\n"); EVP_CIPHER_CTX_cleanup (ctx); return 0; } EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, 16, tag); // Add header information out[0]=PACKET_HEADER; step=(unsigned char *)&out[1]; memcpy(step,iv,IV_SIZE); step+=IV_SIZE; memcpy(step,tag,sizeof(tag)); step+=sizeof(tag); memcpy(step,outbuf,outlen+tmplen); EVP_CIPHER_CTX_cleanup (ctx); return outlen+tmplen+HEADER_SIZE; }
static int decrypt_data(char *in, int len, char *out) { unsigned char outbuf[MAX_LEN]; unsigned char iv[IV_SIZE]; unsigned char tag[16]; char *step; int tmplen=0, outlen=0; memset(outbuf,0x00,MAX_LEN); // header information step=in+1; memcpy(iv,step,IV_SIZE); // Extract the IV step+=IV_SIZE; memcpy(tag,step,16); // Extract the MAC step+=16; if (glob_key[0] == 0x00) // Generate key if its the first packet gen_key(); EVP_CIPHER_CTX *ctx; ctx = EVP_CIPHER_CTX_new(); EVP_CIPHER_CTX_init (ctx); EVP_DecryptInit_ex (ctx, EVP_aes_256_gcm() , NULL, (const unsigned char *)glob_key, (const unsigned char *)iv); EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, IV_SIZE, NULL); if (!EVP_DecryptUpdate (ctx, outbuf, &outlen, (const unsigned char *)step, len)) { fprintf(stderr, "[!] Error in EVP_DecryptUpdate()\n"); EVP_CIPHER_CTX_cleanup (ctx); return 0; } EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, sizeof(tag), tag); if (!EVP_DecryptFinal_ex (ctx, outbuf + outlen, &tmplen)) { fprintf(stderr, "[!] Error in EVP_DecryptFinal_ex(). Possible foul play involved.\n"); EVP_CIPHER_CTX_cleanup (ctx); return 0; } EVP_CIPHER_CTX_cleanup (ctx); memcpy(out,outbuf,outlen+tmplen); return len; }
/* * aes_gcm_openssl_set_iv(c, iv) sets the counter value to the exor of iv with * the offset */ err_status_t aes_gcm_openssl_set_iv (aes_gcm_ctx_t *c, void *iv, int direction) { const EVP_CIPHER *evp; v128_t *nonce = iv; if (direction != direction_encrypt && direction != direction_decrypt) { return (err_status_bad_param); } c->dir = direction; debug_print(mod_aes_gcm, "setting iv: %s", v128_hex_string(nonce)); switch (c->key_size) { case AES_256_KEYSIZE: evp = EVP_aes_256_gcm(); break; case AES_128_KEYSIZE: evp = EVP_aes_128_gcm(); break; default: return (err_status_bad_param); break; } if (!EVP_CipherInit_ex(&c->ctx, evp, NULL, (const unsigned char*)&c->key.v8, NULL, (c->dir == direction_encrypt ? 1 : 0))) { return (err_status_init_fail); } /* set IV len and the IV value, the followiong 3 calls are required */ if (!EVP_CIPHER_CTX_ctrl(&c->ctx, EVP_CTRL_GCM_SET_IVLEN, 12, 0)) { return (err_status_init_fail); } if (!EVP_CIPHER_CTX_ctrl(&c->ctx, EVP_CTRL_GCM_SET_IV_FIXED, -1, iv)) { return (err_status_init_fail); } if (!EVP_CIPHER_CTX_ctrl(&c->ctx, EVP_CTRL_GCM_IV_GEN, 0, iv)) { return (err_status_init_fail); } return (err_status_ok); }
void aes_gcm_decrypt(void) { EVP_CIPHER_CTX *ctx; int outlen, tmplen, rv; unsigned char outbuf[1024]; // printf("AES GCM Derypt:\n"); // printf("Ciphertext:\n"); // BIO_dump_fp(stdout, gcm_ct, sizeof(gcm_ct)); ctx = EVP_CIPHER_CTX_new(); /* Select cipher */ EVP_DecryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL); /* Set IV length, omit for 96 bits */ EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, sizeof(gcm_iv), NULL); /* Specify key and IV */ EVP_DecryptInit_ex(ctx, NULL, NULL, gcm_key, gcm_iv); #if 0 /* Set expected tag value. A restriction in OpenSSL 1.0.1c and earlier * required the tag before any AAD or ciphertext */ EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, sizeof(gcm_tag), gcm_tag); #endif /* Zero or more calls to specify any AAD */ EVP_DecryptUpdate(ctx, NULL, &outlen, gcm_aad, sizeof(gcm_aad)); /* Decrypt plaintext */ EVP_DecryptUpdate(ctx, debuf, &outlen, enbuf, pt_len); /* Output decrypted block */ // printf("Plaintext:\n"); // BIO_dump_fp(stdout, outbuf, outlen); /* Set expected tag value. Works in OpenSSL 1.0.1d and later */ EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, 16, tagbuf); /* Finalise: note get no output for GCM */ rv = EVP_DecryptFinal_ex(ctx, debuf, &outlen); /* Print out return value. If this is not successful authentication * failed and plaintext is not trustworthy. */ printf("Tag Verify %s\n", rv > 0 ? "Successful!" : "Failed!"); EVP_CIPHER_CTX_free(ctx); }
void OpenSSL_add_all_ciphers(void) { #ifndef OPENSSL_NO_DES EVP_add_cipher(EVP_des_cfb()); EVP_add_cipher(EVP_des_cfb1()); EVP_add_cipher(EVP_des_cfb8()); EVP_add_cipher(EVP_des_ede_cfb()); EVP_add_cipher(EVP_des_ede3_cfb()); EVP_add_cipher(EVP_des_ede3_cfb1()); EVP_add_cipher(EVP_des_ede3_cfb8()); EVP_add_cipher(EVP_des_ofb()); EVP_add_cipher(EVP_des_ede_ofb()); EVP_add_cipher(EVP_des_ede3_ofb()); EVP_add_cipher(EVP_desx_cbc()); EVP_add_cipher_alias(SN_desx_cbc, "DESX"); EVP_add_cipher_alias(SN_desx_cbc, "desx"); EVP_add_cipher(EVP_des_cbc()); EVP_add_cipher_alias(SN_des_cbc, "DES"); EVP_add_cipher_alias(SN_des_cbc, "des"); EVP_add_cipher(EVP_des_ede_cbc()); EVP_add_cipher(EVP_des_ede3_cbc()); EVP_add_cipher_alias(SN_des_ede3_cbc, "DES3"); EVP_add_cipher_alias(SN_des_ede3_cbc, "des3"); EVP_add_cipher(EVP_des_ecb()); EVP_add_cipher(EVP_des_ede()); EVP_add_cipher(EVP_des_ede3()); EVP_add_cipher(EVP_des_ede3_wrap()); #endif #ifndef OPENSSL_NO_RC4 EVP_add_cipher(EVP_rc4()); EVP_add_cipher(EVP_rc4_40()); # ifndef OPENSSL_NO_MD5 EVP_add_cipher(EVP_rc4_hmac_md5()); # endif #endif #ifndef OPENSSL_NO_IDEA EVP_add_cipher(EVP_idea_ecb()); EVP_add_cipher(EVP_idea_cfb()); EVP_add_cipher(EVP_idea_ofb()); EVP_add_cipher(EVP_idea_cbc()); EVP_add_cipher_alias(SN_idea_cbc, "IDEA"); EVP_add_cipher_alias(SN_idea_cbc, "idea"); #endif #ifndef OPENSSL_NO_SEED EVP_add_cipher(EVP_seed_ecb()); EVP_add_cipher(EVP_seed_cfb()); EVP_add_cipher(EVP_seed_ofb()); EVP_add_cipher(EVP_seed_cbc()); EVP_add_cipher_alias(SN_seed_cbc, "SEED"); EVP_add_cipher_alias(SN_seed_cbc, "seed"); #endif #ifndef OPENSSL_NO_RC2 EVP_add_cipher(EVP_rc2_ecb()); EVP_add_cipher(EVP_rc2_cfb()); EVP_add_cipher(EVP_rc2_ofb()); EVP_add_cipher(EVP_rc2_cbc()); EVP_add_cipher(EVP_rc2_40_cbc()); EVP_add_cipher(EVP_rc2_64_cbc()); EVP_add_cipher_alias(SN_rc2_cbc, "RC2"); EVP_add_cipher_alias(SN_rc2_cbc, "rc2"); #endif #ifndef OPENSSL_NO_BF EVP_add_cipher(EVP_bf_ecb()); EVP_add_cipher(EVP_bf_cfb()); EVP_add_cipher(EVP_bf_ofb()); EVP_add_cipher(EVP_bf_cbc()); EVP_add_cipher_alias(SN_bf_cbc, "BF"); EVP_add_cipher_alias(SN_bf_cbc, "bf"); EVP_add_cipher_alias(SN_bf_cbc, "blowfish"); #endif #ifndef OPENSSL_NO_CAST EVP_add_cipher(EVP_cast5_ecb()); EVP_add_cipher(EVP_cast5_cfb()); EVP_add_cipher(EVP_cast5_ofb()); EVP_add_cipher(EVP_cast5_cbc()); EVP_add_cipher_alias(SN_cast5_cbc, "CAST"); EVP_add_cipher_alias(SN_cast5_cbc, "cast"); EVP_add_cipher_alias(SN_cast5_cbc, "CAST-cbc"); EVP_add_cipher_alias(SN_cast5_cbc, "cast-cbc"); #endif #ifndef OPENSSL_NO_RC5 EVP_add_cipher(EVP_rc5_32_12_16_ecb()); EVP_add_cipher(EVP_rc5_32_12_16_cfb()); EVP_add_cipher(EVP_rc5_32_12_16_ofb()); EVP_add_cipher(EVP_rc5_32_12_16_cbc()); EVP_add_cipher_alias(SN_rc5_cbc, "rc5"); EVP_add_cipher_alias(SN_rc5_cbc, "RC5"); #endif #ifndef OPENSSL_NO_AES EVP_add_cipher(EVP_aes_128_ecb()); EVP_add_cipher(EVP_aes_128_cbc()); EVP_add_cipher(EVP_aes_128_cfb()); EVP_add_cipher(EVP_aes_128_cfb1()); EVP_add_cipher(EVP_aes_128_cfb8()); EVP_add_cipher(EVP_aes_128_ofb()); EVP_add_cipher(EVP_aes_128_ctr()); EVP_add_cipher(EVP_aes_128_gcm()); EVP_add_cipher(EVP_aes_128_xts()); EVP_add_cipher(EVP_aes_128_ccm()); EVP_add_cipher(EVP_aes_128_wrap()); EVP_add_cipher_alias(SN_aes_128_cbc, "AES128"); EVP_add_cipher_alias(SN_aes_128_cbc, "aes128"); EVP_add_cipher(EVP_aes_192_ecb()); EVP_add_cipher(EVP_aes_192_cbc()); EVP_add_cipher(EVP_aes_192_cfb()); EVP_add_cipher(EVP_aes_192_cfb1()); EVP_add_cipher(EVP_aes_192_cfb8()); EVP_add_cipher(EVP_aes_192_ofb()); EVP_add_cipher(EVP_aes_192_ctr()); EVP_add_cipher(EVP_aes_192_gcm()); EVP_add_cipher(EVP_aes_192_ccm()); EVP_add_cipher(EVP_aes_192_wrap()); EVP_add_cipher_alias(SN_aes_192_cbc, "AES192"); EVP_add_cipher_alias(SN_aes_192_cbc, "aes192"); EVP_add_cipher(EVP_aes_256_ecb()); EVP_add_cipher(EVP_aes_256_cbc()); EVP_add_cipher(EVP_aes_256_cfb()); EVP_add_cipher(EVP_aes_256_cfb1()); EVP_add_cipher(EVP_aes_256_cfb8()); EVP_add_cipher(EVP_aes_256_ofb()); EVP_add_cipher(EVP_aes_256_ctr()); EVP_add_cipher(EVP_aes_256_gcm()); EVP_add_cipher(EVP_aes_256_xts()); EVP_add_cipher(EVP_aes_256_ccm()); EVP_add_cipher(EVP_aes_256_wrap()); EVP_add_cipher_alias(SN_aes_256_cbc, "AES256"); EVP_add_cipher_alias(SN_aes_256_cbc, "aes256"); # if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA1) EVP_add_cipher(EVP_aes_128_cbc_hmac_sha1()); EVP_add_cipher(EVP_aes_256_cbc_hmac_sha1()); # endif # if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA256) EVP_add_cipher(EVP_aes_128_cbc_hmac_sha256()); EVP_add_cipher(EVP_aes_256_cbc_hmac_sha256()); # endif #endif #ifndef OPENSSL_NO_CAMELLIA EVP_add_cipher(EVP_camellia_128_ecb()); EVP_add_cipher(EVP_camellia_128_cbc()); EVP_add_cipher(EVP_camellia_128_cfb()); EVP_add_cipher(EVP_camellia_128_cfb1()); EVP_add_cipher(EVP_camellia_128_cfb8()); EVP_add_cipher(EVP_camellia_128_ofb()); EVP_add_cipher_alias(SN_camellia_128_cbc, "CAMELLIA128"); EVP_add_cipher_alias(SN_camellia_128_cbc, "camellia128"); EVP_add_cipher(EVP_camellia_192_ecb()); EVP_add_cipher(EVP_camellia_192_cbc()); EVP_add_cipher(EVP_camellia_192_cfb()); EVP_add_cipher(EVP_camellia_192_cfb1()); EVP_add_cipher(EVP_camellia_192_cfb8()); EVP_add_cipher(EVP_camellia_192_ofb()); EVP_add_cipher_alias(SN_camellia_192_cbc, "CAMELLIA192"); EVP_add_cipher_alias(SN_camellia_192_cbc, "camellia192"); EVP_add_cipher(EVP_camellia_256_ecb()); EVP_add_cipher(EVP_camellia_256_cbc()); EVP_add_cipher(EVP_camellia_256_cfb()); EVP_add_cipher(EVP_camellia_256_cfb1()); EVP_add_cipher(EVP_camellia_256_cfb8()); EVP_add_cipher(EVP_camellia_256_ofb()); EVP_add_cipher_alias(SN_camellia_256_cbc, "CAMELLIA256"); EVP_add_cipher_alias(SN_camellia_256_cbc, "camellia256"); #endif }
bool AES_GCM_Decrypt(COSE_Enveloped * pcose, const byte * pbKey, int cbKey, const byte * pbCrypto, size_t cbCrypto, const byte * pbAuthData, size_t cbAuthData, cose_errback * perr) { EVP_CIPHER_CTX ctx; int cbOut; byte * rgbOut = NULL; int outl = 0; byte rgbIV[15] = { 0 }; const cn_cbor * pIV = NULL; const EVP_CIPHER * cipher; #ifdef USE_CBOR_CONTEXT cn_cbor_context * context = &pcose->m_message.m_allocContext; #endif int TSize = 128 / 8; assert(perr != NULL); EVP_CIPHER_CTX_init(&ctx); // Setup the IV/Nonce and put it into the message pIV = _COSE_map_get_int(&pcose->m_message, COSE_Header_IV, COSE_BOTH, NULL); if ((pIV == NULL) || (pIV->type != CN_CBOR_BYTES)) { perr->err = COSE_ERR_INVALID_PARAMETER; errorReturn: if (rgbOut != NULL) COSE_FREE(rgbOut, context); EVP_CIPHER_CTX_cleanup(&ctx); return false; } CHECK_CONDITION(pIV->length == 96/8, COSE_ERR_INVALID_PARAMETER); memcpy(rgbIV, pIV->v.str, pIV->length); // Setup and run the OpenSSL code switch (cbKey) { case 128 / 8: cipher = EVP_aes_128_gcm(); break; case 192 / 8: cipher = EVP_aes_192_gcm(); break; case 256 / 8: cipher = EVP_aes_256_gcm(); break; default: FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER); break; } // Do the setup for OpenSSL CHECK_CONDITION(EVP_DecryptInit_ex(&ctx, cipher, NULL, NULL, NULL), COSE_ERR_DECRYPT_FAILED); CHECK_CONDITION(EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_CCM_SET_TAG, TSize, (void *)&pbCrypto[cbCrypto - TSize]), COSE_ERR_DECRYPT_FAILED); CHECK_CONDITION(EVP_DecryptInit(&ctx, 0, pbKey, rgbIV), COSE_ERR_DECRYPT_FAILED); // Pus in the AAD CHECK_CONDITION(EVP_DecryptUpdate(&ctx, NULL, &outl, pbAuthData, (int) cbAuthData), COSE_ERR_DECRYPT_FAILED); // cbOut = (int)cbCrypto - TSize; rgbOut = (byte *)COSE_CALLOC(cbOut, 1, context); CHECK_CONDITION(rgbOut != NULL, COSE_ERR_OUT_OF_MEMORY); // Process content CHECK_CONDITION(EVP_DecryptUpdate(&ctx, rgbOut, &cbOut, pbCrypto, (int)cbCrypto - TSize), COSE_ERR_DECRYPT_FAILED); // Process Tag CHECK_CONDITION(EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_GCM_SET_TAG, TSize, (byte *)pbCrypto + cbCrypto - TSize), COSE_ERR_DECRYPT_FAILED); // Check the result CHECK_CONDITION(EVP_DecryptFinal(&ctx, rgbOut + cbOut, &cbOut), COSE_ERR_DECRYPT_FAILED); EVP_CIPHER_CTX_cleanup(&ctx); pcose->pbContent = rgbOut; pcose->cbContent = cbOut; return true; }
bool AES_GCM_Encrypt(COSE_Enveloped * pcose, const byte * pbKey, size_t cbKey, const byte * pbAuthData, size_t cbAuthData, cose_errback * perr) { EVP_CIPHER_CTX ctx; int cbOut; byte * rgbOut = NULL; int outl = 0; byte rgbIV[16] = { 0 }; byte * pbIV = NULL; const cn_cbor * cbor_iv = NULL; cn_cbor * cbor_iv_t = NULL; const EVP_CIPHER * cipher; #ifdef USE_CBOR_CONTEXT cn_cbor_context * context = &pcose->m_message.m_allocContext; #endif cn_cbor_errback cbor_error; // Setup the IV/Nonce and put it into the message cbor_iv = _COSE_map_get_int(&pcose->m_message, COSE_Header_IV, COSE_BOTH, perr); if (cbor_iv == NULL) { pbIV = COSE_CALLOC(96, 1, context); CHECK_CONDITION(pbIV != NULL, COSE_ERR_OUT_OF_MEMORY); rand_bytes(pbIV, 96 / 8); memcpy(rgbIV, pbIV, 96 / 8); cbor_iv_t = cn_cbor_data_create(pbIV, 96 / 8, CBOR_CONTEXT_PARAM_COMMA &cbor_error); CHECK_CONDITION_CBOR(cbor_iv_t != NULL, cbor_error); pbIV = NULL; if (!_COSE_map_put(&pcose->m_message, COSE_Header_IV, cbor_iv_t, COSE_UNPROTECT_ONLY, perr)) goto errorReturn; cbor_iv_t = NULL; } else { CHECK_CONDITION(cbor_iv->type == CN_CBOR_BYTES, COSE_ERR_INVALID_PARAMETER); CHECK_CONDITION(cbor_iv->length == 96 / 8, COSE_ERR_INVALID_PARAMETER); memcpy(rgbIV, cbor_iv->v.str, cbor_iv->length); } switch (cbKey*8) { case 128: cipher = EVP_aes_128_gcm(); break; case 192: cipher = EVP_aes_192_gcm(); break; case 256: cipher = EVP_aes_256_gcm(); break; default: FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER); break; } // Setup and run the OpenSSL code EVP_CIPHER_CTX_init(&ctx); CHECK_CONDITION(EVP_EncryptInit_ex(&ctx, cipher, NULL, NULL, NULL), COSE_ERR_CRYPTO_FAIL); CHECK_CONDITION(EVP_EncryptInit(&ctx, 0, pbKey, rgbIV), COSE_ERR_CRYPTO_FAIL); CHECK_CONDITION(EVP_EncryptUpdate(&ctx, NULL, &outl, pbAuthData, (int) cbAuthData), COSE_ERR_CRYPTO_FAIL); rgbOut = (byte *)COSE_CALLOC(pcose->cbContent + 128/8, 1, context); CHECK_CONDITION(rgbOut != NULL, COSE_ERR_OUT_OF_MEMORY); CHECK_CONDITION(EVP_EncryptUpdate(&ctx, rgbOut, &cbOut, pcose->pbContent, (int)pcose->cbContent), COSE_ERR_CRYPTO_FAIL); CHECK_CONDITION(EVP_EncryptFinal_ex(&ctx, &rgbOut[cbOut], &cbOut), COSE_ERR_CRYPTO_FAIL); CHECK_CONDITION(EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_GCM_GET_TAG, 128/8, &rgbOut[pcose->cbContent]), COSE_ERR_CRYPTO_FAIL); cn_cbor * cnTmp = cn_cbor_data_create(rgbOut, (int)pcose->cbContent + 128/8, CBOR_CONTEXT_PARAM_COMMA NULL); CHECK_CONDITION(cnTmp != NULL, COSE_ERR_CBOR); rgbOut = NULL; CHECK_CONDITION(_COSE_array_replace(&pcose->m_message, cnTmp, INDEX_BODY, CBOR_CONTEXT_PARAM_COMMA NULL), COSE_ERR_CBOR); EVP_CIPHER_CTX_cleanup(&ctx); return true; errorReturn: if (pbIV != NULL) COSE_FREE(pbIV, context); if (cbor_iv_t != NULL) COSE_FREE(cbor_iv_t, context); if (rgbOut != NULL) COSE_FREE(rgbOut, context); EVP_CIPHER_CTX_cleanup(&ctx); return false; }
static bool _cjose_jwe_decrypt_dat_a256gcm( cjose_jwe_t *jwe, cjose_err *err) { EVP_CIPHER_CTX *ctx = NULL; // get A256GCM cipher const EVP_CIPHER *cipher = EVP_aes_256_gcm(); if (NULL == cipher) { CJOSE_ERROR(err, CJOSE_ERR_CRYPTO); goto _cjose_jwe_decrypt_dat_a256gcm_fail; } // instantiate and initialize a new openssl cipher context ctx = EVP_CIPHER_CTX_new(); if (NULL == ctx) { CJOSE_ERROR(err, CJOSE_ERR_CRYPTO); goto _cjose_jwe_decrypt_dat_a256gcm_fail; } EVP_CIPHER_CTX_init(ctx); // initialize context for decryption using A256GCM cipher and CEK and IV if (EVP_DecryptInit_ex(ctx, cipher, NULL, jwe->cek, jwe->part[2].raw) != 1) { CJOSE_ERROR(err, CJOSE_ERR_CRYPTO); goto _cjose_jwe_decrypt_dat_a256gcm_fail; } // set the expected GCM-mode authentication tag if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, jwe->part[4].raw_len, jwe->part[4].raw) != 1) { CJOSE_ERROR(err, CJOSE_ERR_CRYPTO); goto _cjose_jwe_decrypt_dat_a256gcm_fail; } // set GCM mode AAD data (hdr_b64u) by setting "out" to NULL int bytes_decrypted = 0; if (EVP_DecryptUpdate(ctx, NULL, &bytes_decrypted, (unsigned char *)jwe->part[0].b64u, jwe->part[0].b64u_len) != 1 || bytes_decrypted != jwe->part[0].b64u_len) { CJOSE_ERROR(err, CJOSE_ERR_CRYPTO); goto _cjose_jwe_decrypt_dat_a256gcm_fail; } // allocate buffer for the plaintext cjose_get_dealloc()(jwe->dat); jwe->dat_len = jwe->part[3].raw_len; if (!_cjose_jwe_malloc(jwe->dat_len, false, &jwe->dat, err)) { goto _cjose_jwe_decrypt_dat_a256gcm_fail; } // decrypt ciphertext to plaintext buffer if (EVP_DecryptUpdate(ctx, jwe->dat, &bytes_decrypted, jwe->part[3].raw, jwe->part[3].raw_len) != 1) { CJOSE_ERROR(err, CJOSE_ERR_CRYPTO); goto _cjose_jwe_decrypt_dat_a256gcm_fail; } jwe->dat_len = bytes_decrypted; // finalize the encryption if (EVP_DecryptFinal_ex(ctx, NULL, &bytes_decrypted) != 1) { CJOSE_ERROR(err, CJOSE_ERR_CRYPTO); goto _cjose_jwe_decrypt_dat_a256gcm_fail; } EVP_CIPHER_CTX_free(ctx); return true; _cjose_jwe_decrypt_dat_a256gcm_fail: if (NULL != ctx) { EVP_CIPHER_CTX_free(ctx); } return false; }
static bool _cjose_jwe_encrypt_dat_a256gcm( cjose_jwe_t *jwe, const uint8_t *plaintext, size_t plaintext_len, cjose_err *err) { EVP_CIPHER_CTX *ctx = NULL; if (NULL == plaintext) { CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG); goto _cjose_jwe_encrypt_dat_fail; } // get A256GCM cipher const EVP_CIPHER *cipher = EVP_aes_256_gcm(); if (NULL == cipher) { CJOSE_ERROR(err, CJOSE_ERR_CRYPTO); goto _cjose_jwe_encrypt_dat_fail; } // instantiate and initialize a new openssl cipher context ctx = EVP_CIPHER_CTX_new(); if (NULL == ctx) { CJOSE_ERROR(err, CJOSE_ERR_CRYPTO); goto _cjose_jwe_encrypt_dat_fail; } EVP_CIPHER_CTX_init(ctx); // initialize context for encryption using A256GCM cipher and CEK and IV if (EVP_EncryptInit_ex(ctx, cipher, NULL, jwe->cek, jwe->part[2].raw) != 1) { CJOSE_ERROR(err, CJOSE_ERR_CRYPTO); goto _cjose_jwe_encrypt_dat_fail; } // we need the header in base64url encoding as input for encryption if ((NULL == jwe->part[0].b64u) && (!cjose_base64url_encode( (const uint8_t *)jwe->part[0].raw, jwe->part[0].raw_len, &jwe->part[0].b64u, &jwe->part[0].b64u_len, err))) { goto _cjose_jwe_encrypt_dat_fail; } // set GCM mode AAD data (hdr_b64u) by setting "out" to NULL int bytes_encrypted = 0; if (EVP_EncryptUpdate(ctx, NULL, &bytes_encrypted, (unsigned char *)jwe->part[0].b64u, jwe->part[0].b64u_len) != 1 || bytes_encrypted != jwe->part[0].b64u_len) { CJOSE_ERROR(err, CJOSE_ERR_CRYPTO); goto _cjose_jwe_encrypt_dat_fail; } // allocate buffer for the ciphertext cjose_get_dealloc()(jwe->part[3].raw); jwe->part[3].raw_len = plaintext_len; if (!_cjose_jwe_malloc(jwe->part[3].raw_len, false, &jwe->part[3].raw, err)) { goto _cjose_jwe_encrypt_dat_fail; } // encrypt entire plaintext to ciphertext buffer if (EVP_EncryptUpdate(ctx, jwe->part[3].raw, &bytes_encrypted, plaintext, plaintext_len) != 1) { CJOSE_ERROR(err, CJOSE_ERR_CRYPTO); goto _cjose_jwe_encrypt_dat_fail; } jwe->part[3].raw_len = bytes_encrypted; // finalize the encryption and set the ciphertext length to correct value if (EVP_EncryptFinal_ex(ctx, NULL, &bytes_encrypted) != 1) { CJOSE_ERROR(err, CJOSE_ERR_CRYPTO); goto _cjose_jwe_encrypt_dat_fail; } // allocate buffer for the authentication tag cjose_get_dealloc()(jwe->part[4].raw); jwe->part[4].raw_len = 16; if (!_cjose_jwe_malloc(jwe->part[4].raw_len, false, &jwe->part[4].raw, err)) { goto _cjose_jwe_encrypt_dat_fail; } // get the GCM-mode authentication tag if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, jwe->part[4].raw_len, jwe->part[4].raw) != 1) { CJOSE_ERROR(err, CJOSE_ERR_CRYPTO); goto _cjose_jwe_encrypt_dat_fail; } EVP_CIPHER_CTX_free(ctx); return true; _cjose_jwe_encrypt_dat_fail: if (NULL != ctx) { EVP_CIPHER_CTX_free(ctx); } return false; }
int main(int argc, char **argv) { unsigned char *gcm_ivkey, *gcm_ct, *gcm_pt; int outlen, rv = 0, final_outlen, decrypt = 1; size_t read, actual_size = 0, total_size = INITIAL_BUFFER_SIZE; if (argc < 2) { fprintf(stderr, "Usage: %s <key> [enc]\n", argv[0]); return 1; } // this means we want to encrypt, not decrypt if (argc > 2 && strcmp("enc", argv[2]) == 0) decrypt = 0; unsigned int byte_length = hex2string(argv[1], &gcm_ivkey); unsigned int iv_length; if(byte_length == 48) { iv_length = 16; } else if(byte_length == 44) { iv_length = 12; } else { fprintf(stderr, "Invalid key length %d only 44 or 48 bytes supported\n", byte_length); return 1; } gcm_ct = malloc(total_size); while ((read = fread(gcm_ct + actual_size, 1, BYTES_PER_READ, stdin)) > 0) { actual_size += read; if ((actual_size + BYTES_PER_READ) > total_size) { total_size = total_size * 1.5; gcm_ct = realloc(gcm_ct,total_size); } } if (actual_size < (decrypt ? 17 : 1)) { fprintf(stderr, "File too small for %scryption\n", decrypt ? "de" : "en"); return 1; } if(decrypt) actual_size -= TAG_LENGTH; gcm_pt = malloc(decrypt ? actual_size : (actual_size + TAG_LENGTH)); EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new(); /* Select cipher */ if(decrypt) EVP_DecryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL); else EVP_EncryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL); /* Set IV length, omit for 96 bits */ EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, iv_length, NULL); if(decrypt) { /* Specify key and IV */ EVP_DecryptInit_ex(ctx, NULL, NULL, gcm_ivkey + iv_length, gcm_ivkey); /* Set expected tag value. */ EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, TAG_LENGTH, gcm_ct + actual_size); /* Decrypt plaintext */ EVP_DecryptUpdate(ctx, gcm_pt, &outlen, gcm_ct, actual_size); /* Finalise: note get no output for GCM */ rv = EVP_DecryptFinal_ex(ctx, gcm_pt, &final_outlen); } else { /* Specify key and IV */ EVP_EncryptInit_ex(ctx, NULL, NULL, gcm_ivkey + iv_length, gcm_ivkey); /* Encrypt plaintext */ EVP_EncryptUpdate(ctx, gcm_pt, &outlen, gcm_ct, actual_size); /* Finalise: note get no output for GCM */ rv = EVP_EncryptFinal_ex(ctx, gcm_pt, &final_outlen); /* Get expected tag value. */ EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, TAG_LENGTH, gcm_pt + actual_size); } EVP_CIPHER_CTX_free(ctx); free(gcm_ivkey); free(gcm_ct); if (rv > 0) { // success! fwrite(gcm_pt, 1, decrypt ? outlen : (outlen + TAG_LENGTH), stdout); free(gcm_pt); return 0; } else { fprintf(stderr, "File integrity check failed\n"); free(gcm_pt); return 1; } }
int crypto_encrypt_file(FILE * in, FILE * out) { EVP_CIPHER_CTX ctx; uint8_t ibuf[CRYPTO_BUFFER_SIZE]; uint8_t obuf[CRYPTO_BUFFER_SIZE]; uint8_t iv[IV_SIZE]; uint8_t tag[GCM_TAG_SIZE]; uint8_t version = API_VERSION; size_t r, w; int len; int ret = 0; struct stat sb; /* XXX - Do NOT encrypt files bigger than 64GB */ if (fstat(fileno(in), &sb) < 0) return 0; if (sb.st_size >= 0x1000000000LL) return 0; /* prepend version byte*/ if ((w = fwrite(&version, 1, sizeof version, out)) != sizeof version) return 0; /* generate and prepend IV */ memset(iv, 0, sizeof iv); arc4random_buf(iv, sizeof iv); if ((w = fwrite(iv, 1, sizeof iv, out)) != sizeof iv) return 0; EVP_CIPHER_CTX_init(&ctx); EVP_EncryptInit_ex(&ctx, EVP_aes_256_gcm(), NULL, cp.key, iv); /* encrypt until end of file */ while ((r = fread(ibuf, 1, CRYPTO_BUFFER_SIZE, in)) != 0) { if (!EVP_EncryptUpdate(&ctx, obuf, &len, ibuf, r)) goto end; if (len && (w = fwrite(obuf, len, 1, out)) != 1) goto end; } if (!feof(in)) goto end; /* finalize and write last chunk if any */ if (!EVP_EncryptFinal_ex(&ctx, obuf, &len)) goto end; if (len && (w = fwrite(obuf, len, 1, out)) != 1) goto end; /* get and append tag */ EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_GCM_GET_TAG, sizeof tag, tag); if ((w = fwrite(tag, sizeof tag, 1, out)) != 1) goto end; fflush(out); ret = 1; end: EVP_CIPHER_CTX_cleanup(&ctx); return ret; }
EncItem *aes_gcm_encrypt(Item *item, SymKey *key) { EVP_CIPHER_CTX *ctx; int len; int aad_len = sizeof(gcm_aad); if(key == NULL || item == NULL) { printf("%s :: Invalid input\n", __func__); return NULL; } EncItem *ct = new EncItem(CRYPT_ITEM_MAX_LEN, CryptAlg::AES); if(ct == NULL) { printf("%s :: no Memory\n", __func__); return NULL; } /* Create and initialise the context */ if(!(ctx = EVP_CIPHER_CTX_new())) { printf("error %s:%d\n", __func__, __LINE__); goto err_out; } /* Initialise the encryption operation. */ if(1 != EVP_EncryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL)) { printf("error %s:%d\n", __func__, __LINE__); goto err_out; } /* Set IV length if default 12 bytes (96 bits) is not appropriate */ if(1 != EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, 16, NULL)) { printf("error %s:%d\n", __func__, __LINE__); goto err_out; } /* Initialise key and IV */ if(1 != EVP_EncryptInit_ex(ctx, NULL, NULL, key->getData(), gcm_iv)) { printf("error %s:%d\n", __func__, __LINE__); goto err_out; } EVP_CIPHER_CTX_set_padding(ctx, 0); /* Provide any AAD data. This can be called zero or more times as * required */ if(1 != EVP_EncryptUpdate(ctx, NULL, &len, gcm_aad, aad_len)) { printf("error %s:%d\n", __func__, __LINE__); goto err_out; } /* Provide the message to be encrypted, and obtain the encrypted output. * EVP_EncryptUpdate can be called multiple times if necessary */ if(1 != EVP_EncryptUpdate(ctx, ct->getData(), &len, item->getData(), item->len)) { printf("error %s:%d\n", __func__, __LINE__); goto err_out; } ct->len = len; /* Finalise the encryption. Normally ciphertext bytes may be written at * this stage, but this does not occur in GCM mode */ if(1 != EVP_EncryptFinal_ex(ctx, ct->getData() + len, &len)) { printf("error %s:%d\n", __func__, __LINE__); goto err_out; } ct->len += len; /* Get the tag */ if(1 != EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, 16, ct->auth_tag)) { printf("error %s:%d\n", __func__, __LINE__); goto err_out; } /* Clean up */ EVP_CIPHER_CTX_free(ctx); return ct; err_out: delete ct; return NULL; }
static void ossl_init_ssl_base(void) { #ifdef OPENSSL_INIT_DEBUG fprintf(stderr, "OPENSSL_INIT: ossl_init_ssl_base: " "Adding SSL ciphers and digests\n"); #endif #ifndef OPENSSL_NO_DES EVP_add_cipher(EVP_des_cbc()); EVP_add_cipher(EVP_des_ede3_cbc()); #endif #ifndef OPENSSL_NO_IDEA EVP_add_cipher(EVP_idea_cbc()); #endif #ifndef OPENSSL_NO_RC4 EVP_add_cipher(EVP_rc4()); # ifndef OPENSSL_NO_MD5 EVP_add_cipher(EVP_rc4_hmac_md5()); # endif #endif #ifndef OPENSSL_NO_RC2 EVP_add_cipher(EVP_rc2_cbc()); /* * Not actually used for SSL/TLS but this makes PKCS#12 work if an * application only calls SSL_library_init(). */ EVP_add_cipher(EVP_rc2_40_cbc()); #endif #ifndef OPENSSL_NO_AES EVP_add_cipher(EVP_aes_128_cbc()); EVP_add_cipher(EVP_aes_192_cbc()); EVP_add_cipher(EVP_aes_256_cbc()); EVP_add_cipher(EVP_aes_128_gcm()); EVP_add_cipher(EVP_aes_256_gcm()); EVP_add_cipher(EVP_aes_128_ccm()); EVP_add_cipher(EVP_aes_256_ccm()); EVP_add_cipher(EVP_aes_128_cbc_hmac_sha1()); EVP_add_cipher(EVP_aes_256_cbc_hmac_sha1()); EVP_add_cipher(EVP_aes_128_cbc_hmac_sha256()); EVP_add_cipher(EVP_aes_256_cbc_hmac_sha256()); #endif #ifndef OPENSSL_NO_CAMELLIA EVP_add_cipher(EVP_camellia_128_cbc()); EVP_add_cipher(EVP_camellia_256_cbc()); #endif #if !defined(OPENSSL_NO_CHACHA) && !defined(OPENSSL_NO_POLY1305) EVP_add_cipher(EVP_chacha20_poly1305()); #endif #ifndef OPENSSL_NO_SEED EVP_add_cipher(EVP_seed_cbc()); #endif #ifndef OPENSSL_NO_MD5 EVP_add_digest(EVP_md5()); EVP_add_digest_alias(SN_md5, "ssl3-md5"); # ifndef OPENSSL_NO_SHA EVP_add_digest(EVP_md5_sha1()); # endif #endif EVP_add_digest(EVP_sha1()); /* RSA with sha1 */ EVP_add_digest_alias(SN_sha1, "ssl3-sha1"); EVP_add_digest_alias(SN_sha1WithRSAEncryption, SN_sha1WithRSA); EVP_add_digest(EVP_sha224()); EVP_add_digest(EVP_sha256()); EVP_add_digest(EVP_sha384()); EVP_add_digest(EVP_sha512()); #ifndef OPENSSL_NO_COMP #ifdef OPENSSL_INIT_DEBUG fprintf(stderr, "OPENSSL_INIT: ossl_init_ssl_base: " "SSL_COMP_get_compression_methods()\n"); #endif /* * This will initialise the built-in compression algorithms. The value * returned is a STACK_OF(SSL_COMP), but that can be discarded safely */ SSL_COMP_get_compression_methods(); #endif /* initialize cipher/digest methods table */ ssl_load_ciphers(); #ifdef OPENSSL_INIT_DEBUG fprintf(stderr, "OPENSSL_INIT: ossl_init_ssl_base: " "SSL_add_ssl_module()\n"); #endif SSL_add_ssl_module(); /* * We ignore an error return here. Not much we can do - but not that bad * either. We can still safely continue. */ OPENSSL_atexit(ssl_library_stop); ssl_base_inited = 1; }
static void evp_cipher_init(struct ssh_cipher_struct *cipher) { if (cipher->ctx == NULL) { cipher->ctx = EVP_CIPHER_CTX_new(); } switch(cipher->ciphertype){ case SSH_AES128_CBC: cipher->cipher = EVP_aes_128_cbc(); break; case SSH_AES192_CBC: cipher->cipher = EVP_aes_192_cbc(); break; case SSH_AES256_CBC: cipher->cipher = EVP_aes_256_cbc(); break; #ifdef HAVE_OPENSSL_EVP_AES_CTR case SSH_AES128_CTR: cipher->cipher = EVP_aes_128_ctr(); break; case SSH_AES192_CTR: cipher->cipher = EVP_aes_192_ctr(); break; case SSH_AES256_CTR: cipher->cipher = EVP_aes_256_ctr(); break; #else case SSH_AES128_CTR: case SSH_AES192_CTR: case SSH_AES256_CTR: SSH_LOG(SSH_LOG_WARNING, "This cipher is not available in evp_cipher_init"); break; #endif #ifdef HAVE_OPENSSL_EVP_AES_GCM case SSH_AEAD_AES128_GCM: cipher->cipher = EVP_aes_128_gcm(); break; case SSH_AEAD_AES256_GCM: cipher->cipher = EVP_aes_256_gcm(); break; #else case SSH_AEAD_AES128_GCM: case SSH_AEAD_AES256_GCM: SSH_LOG(SSH_LOG_WARNING, "This cipher is not available in evp_cipher_init"); break; #endif /* HAVE_OPENSSL_EVP_AES_GCM */ case SSH_3DES_CBC: cipher->cipher = EVP_des_ede3_cbc(); break; #ifdef WITH_BLOWFISH_CIPHER case SSH_BLOWFISH_CBC: cipher->cipher = EVP_bf_cbc(); break; /* ciphers not using EVP */ #endif case SSH_AEAD_CHACHA20_POLY1305: SSH_LOG(SSH_LOG_WARNING, "The ChaCha cipher cannot be handled here"); break; case SSH_NO_CIPHER: SSH_LOG(SSH_LOG_WARNING, "No valid ciphertype found"); break; } }
int SSL_library_init(void) { #ifndef OPENSSL_NO_DES EVP_add_cipher(EVP_des_cbc()); EVP_add_cipher(EVP_des_ede3_cbc()); #endif #ifndef OPENSSL_NO_IDEA EVP_add_cipher(EVP_idea_cbc()); #endif #ifndef OPENSSL_NO_RC4 EVP_add_cipher(EVP_rc4()); # if !defined(OPENSSL_NO_MD5) && (defined(__x86_64) || defined(__x86_64__)) EVP_add_cipher(EVP_rc4_hmac_md5()); # endif #endif #ifndef OPENSSL_NO_RC2 EVP_add_cipher(EVP_rc2_cbc()); /* * Not actually used for SSL/TLS but this makes PKCS#12 work if an * application only calls SSL_library_init(). */ EVP_add_cipher(EVP_rc2_40_cbc()); #endif #ifndef OPENSSL_NO_AES EVP_add_cipher(EVP_aes_128_cbc()); EVP_add_cipher(EVP_aes_192_cbc()); EVP_add_cipher(EVP_aes_256_cbc()); EVP_add_cipher(EVP_aes_128_gcm()); EVP_add_cipher(EVP_aes_256_gcm()); # if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA1) EVP_add_cipher(EVP_aes_128_cbc_hmac_sha1()); EVP_add_cipher(EVP_aes_256_cbc_hmac_sha1()); # endif # if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA256) EVP_add_cipher(EVP_aes_128_cbc_hmac_sha256()); EVP_add_cipher(EVP_aes_256_cbc_hmac_sha256()); # endif #endif #ifndef OPENSSL_NO_CAMELLIA EVP_add_cipher(EVP_camellia_128_cbc()); EVP_add_cipher(EVP_camellia_256_cbc()); #endif #ifndef OPENSSL_NO_SEED EVP_add_cipher(EVP_seed_cbc()); #endif #ifndef OPENSSL_NO_MD5 EVP_add_digest(EVP_md5()); EVP_add_digest_alias(SN_md5, "ssl2-md5"); EVP_add_digest_alias(SN_md5, "ssl3-md5"); #endif #ifndef OPENSSL_NO_SHA EVP_add_digest(EVP_sha1()); /* RSA with sha1 */ EVP_add_digest_alias(SN_sha1, "ssl3-sha1"); EVP_add_digest_alias(SN_sha1WithRSAEncryption, SN_sha1WithRSA); #endif #ifndef OPENSSL_NO_SHA256 EVP_add_digest(EVP_sha224()); EVP_add_digest(EVP_sha256()); #endif #ifndef OPENSSL_NO_SHA512 EVP_add_digest(EVP_sha384()); EVP_add_digest(EVP_sha512()); #endif #if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_DSA) EVP_add_digest(EVP_dss1()); /* DSA with sha1 */ EVP_add_digest_alias(SN_dsaWithSHA1, SN_dsaWithSHA1_2); EVP_add_digest_alias(SN_dsaWithSHA1, "DSS1"); EVP_add_digest_alias(SN_dsaWithSHA1, "dss1"); #endif #ifndef OPENSSL_NO_ECDSA EVP_add_digest(EVP_ecdsa()); #endif #ifndef NO_GMSSL EVP_add_cipher(EVP_sms4_cbc()); EVP_add_digest(EVP_sm3()); #endif /* If you want support for phased out ciphers, add the following */ #if 0 EVP_add_digest(EVP_sha()); EVP_add_digest(EVP_dss()); #endif #ifndef OPENSSL_NO_COMP /* * This will initialise the built-in compression algorithms. The value * returned is a STACK_OF(SSL_COMP), but that can be discarded safely */ (void)SSL_COMP_get_compression_methods(); #endif /* initialize cipher/digest methods table */ ssl_load_ciphers(); return (1); }
void AES256(PA_PluginParameters params) { sLONG_PTR *pResult = (sLONG_PTR *)params->fResult; PackagePtr pParams = (PackagePtr)params->fParameters; C_BLOB Param1; C_BLOB Param2; C_LONGINT Param3; C_LONGINT Param4; C_LONGINT Param5; C_LONGINT Param6; C_BLOB Param7; C_BLOB Param8; C_TEXT returnValue; Param1.fromParamAtIndex(pParams, 1); Param2.fromParamAtIndex(pParams, 2); Param3.fromParamAtIndex(pParams, 3); Param4.fromParamAtIndex(pParams, 4); Param5.fromParamAtIndex(pParams, 5); Param6.fromParamAtIndex(pParams, 6); Param7.fromParamAtIndex(pParams, 7); Param8.fromParamAtIndex(pParams, 8); const EVP_CIPHER *cipher; switch (Param4.getIntValue()) { case 0: cipher = EVP_aes_256_ecb(); break; case 1: cipher = EVP_aes_256_cbc(); break; case 2: cipher = EVP_aes_256_cfb1(); break; case 3: cipher = EVP_aes_256_cfb8(); break; case 4: cipher = EVP_aes_256_cfb128(); break; case 5: cipher = EVP_aes_256_ofb(); break; case 6: cipher = EVP_aes_256_ctr(); break; case 7: cipher = EVP_aes_256_gcm(); break; case 8: cipher = EVP_aes_256_ccm(); break; case 9: cipher = EVP_aes_256_xts(); break; default: cipher = EVP_aes_256_ecb(); break; } CC_AES(cipher, Param1, Param2, Param3, Param5, Param6, Param7, Param8, returnValue); returnValue.setReturn(pResult); }
void openssl_add_all_ciphers_int(void) { #ifndef OPENSSL_NO_DES EVP_add_cipher(EVP_des_cfb()); EVP_add_cipher(EVP_des_cfb1()); EVP_add_cipher(EVP_des_cfb8()); EVP_add_cipher(EVP_des_ede_cfb()); EVP_add_cipher(EVP_des_ede3_cfb()); EVP_add_cipher(EVP_des_ede3_cfb1()); EVP_add_cipher(EVP_des_ede3_cfb8()); EVP_add_cipher(EVP_des_ofb()); EVP_add_cipher(EVP_des_ede_ofb()); EVP_add_cipher(EVP_des_ede3_ofb()); EVP_add_cipher(EVP_desx_cbc()); EVP_add_cipher_alias(SN_desx_cbc, "DESX"); EVP_add_cipher_alias(SN_desx_cbc, "desx"); EVP_add_cipher(EVP_des_cbc()); EVP_add_cipher_alias(SN_des_cbc, "DES"); EVP_add_cipher_alias(SN_des_cbc, "des"); EVP_add_cipher(EVP_des_ede_cbc()); EVP_add_cipher(EVP_des_ede3_cbc()); EVP_add_cipher_alias(SN_des_ede3_cbc, "DES3"); EVP_add_cipher_alias(SN_des_ede3_cbc, "des3"); EVP_add_cipher(EVP_des_ecb()); EVP_add_cipher(EVP_des_ede()); EVP_add_cipher_alias(SN_des_ede_ecb, "DES-EDE-ECB"); EVP_add_cipher_alias(SN_des_ede_ecb, "des-ede-ecb"); EVP_add_cipher(EVP_des_ede3()); EVP_add_cipher_alias(SN_des_ede3_ecb, "DES-EDE3-ECB"); EVP_add_cipher_alias(SN_des_ede3_ecb, "des-ede3-ecb"); EVP_add_cipher(EVP_des_ede3_wrap()); EVP_add_cipher_alias(SN_id_smime_alg_CMS3DESwrap, "des3-wrap"); #endif #ifndef OPENSSL_NO_RC4 EVP_add_cipher(EVP_rc4()); EVP_add_cipher(EVP_rc4_40()); # ifndef OPENSSL_NO_MD5 EVP_add_cipher(EVP_rc4_hmac_md5()); # endif #endif #ifndef OPENSSL_NO_IDEA EVP_add_cipher(EVP_idea_ecb()); EVP_add_cipher(EVP_idea_cfb()); EVP_add_cipher(EVP_idea_ofb()); EVP_add_cipher(EVP_idea_cbc()); EVP_add_cipher_alias(SN_idea_cbc, "IDEA"); EVP_add_cipher_alias(SN_idea_cbc, "idea"); #endif #ifndef OPENSSL_NO_SEED EVP_add_cipher(EVP_seed_ecb()); EVP_add_cipher(EVP_seed_cfb()); EVP_add_cipher(EVP_seed_ofb()); EVP_add_cipher(EVP_seed_cbc()); EVP_add_cipher_alias(SN_seed_cbc, "SEED"); EVP_add_cipher_alias(SN_seed_cbc, "seed"); #endif #ifndef OPENSSL_NO_SM4 EVP_add_cipher(EVP_sm4_ecb()); EVP_add_cipher(EVP_sm4_cbc()); EVP_add_cipher(EVP_sm4_cfb()); EVP_add_cipher(EVP_sm4_ofb()); EVP_add_cipher(EVP_sm4_ctr()); EVP_add_cipher_alias(SN_sm4_cbc, "SM4"); EVP_add_cipher_alias(SN_sm4_cbc, "sm4"); #endif #ifndef OPENSSL_NO_RC2 EVP_add_cipher(EVP_rc2_ecb()); EVP_add_cipher(EVP_rc2_cfb()); EVP_add_cipher(EVP_rc2_ofb()); EVP_add_cipher(EVP_rc2_cbc()); EVP_add_cipher(EVP_rc2_40_cbc()); EVP_add_cipher(EVP_rc2_64_cbc()); EVP_add_cipher_alias(SN_rc2_cbc, "RC2"); EVP_add_cipher_alias(SN_rc2_cbc, "rc2"); EVP_add_cipher_alias(SN_rc2_cbc, "rc2-128"); EVP_add_cipher_alias(SN_rc2_64_cbc, "rc2-64"); EVP_add_cipher_alias(SN_rc2_40_cbc, "rc2-40"); #endif #ifndef OPENSSL_NO_BF EVP_add_cipher(EVP_bf_ecb()); EVP_add_cipher(EVP_bf_cfb()); EVP_add_cipher(EVP_bf_ofb()); EVP_add_cipher(EVP_bf_cbc()); EVP_add_cipher_alias(SN_bf_cbc, "BF"); EVP_add_cipher_alias(SN_bf_cbc, "bf"); EVP_add_cipher_alias(SN_bf_cbc, "blowfish"); #endif #ifndef OPENSSL_NO_CAST EVP_add_cipher(EVP_cast5_ecb()); EVP_add_cipher(EVP_cast5_cfb()); EVP_add_cipher(EVP_cast5_ofb()); EVP_add_cipher(EVP_cast5_cbc()); EVP_add_cipher_alias(SN_cast5_cbc, "CAST"); EVP_add_cipher_alias(SN_cast5_cbc, "cast"); EVP_add_cipher_alias(SN_cast5_cbc, "CAST-cbc"); EVP_add_cipher_alias(SN_cast5_cbc, "cast-cbc"); #endif #ifndef OPENSSL_NO_RC5 EVP_add_cipher(EVP_rc5_32_12_16_ecb()); EVP_add_cipher(EVP_rc5_32_12_16_cfb()); EVP_add_cipher(EVP_rc5_32_12_16_ofb()); EVP_add_cipher(EVP_rc5_32_12_16_cbc()); EVP_add_cipher_alias(SN_rc5_cbc, "rc5"); EVP_add_cipher_alias(SN_rc5_cbc, "RC5"); #endif EVP_add_cipher(EVP_aes_128_ecb()); EVP_add_cipher(EVP_aes_128_cbc()); EVP_add_cipher(EVP_aes_128_cfb()); EVP_add_cipher(EVP_aes_128_cfb1()); EVP_add_cipher(EVP_aes_128_cfb8()); EVP_add_cipher(EVP_aes_128_ofb()); EVP_add_cipher(EVP_aes_128_ctr()); EVP_add_cipher(EVP_aes_128_gcm()); #ifndef OPENSSL_NO_OCB EVP_add_cipher(EVP_aes_128_ocb()); #endif EVP_add_cipher(EVP_aes_128_xts()); EVP_add_cipher(EVP_aes_128_ccm()); EVP_add_cipher(EVP_aes_128_wrap()); EVP_add_cipher_alias(SN_id_aes128_wrap, "aes128-wrap"); EVP_add_cipher(EVP_aes_128_wrap_pad()); EVP_add_cipher_alias(SN_aes_128_cbc, "AES128"); EVP_add_cipher_alias(SN_aes_128_cbc, "aes128"); EVP_add_cipher(EVP_aes_192_ecb()); EVP_add_cipher(EVP_aes_192_cbc()); EVP_add_cipher(EVP_aes_192_cfb()); EVP_add_cipher(EVP_aes_192_cfb1()); EVP_add_cipher(EVP_aes_192_cfb8()); EVP_add_cipher(EVP_aes_192_ofb()); EVP_add_cipher(EVP_aes_192_ctr()); EVP_add_cipher(EVP_aes_192_gcm()); #ifndef OPENSSL_NO_OCB EVP_add_cipher(EVP_aes_192_ocb()); #endif EVP_add_cipher(EVP_aes_192_ccm()); EVP_add_cipher(EVP_aes_192_wrap()); EVP_add_cipher_alias(SN_id_aes192_wrap, "aes192-wrap"); EVP_add_cipher(EVP_aes_192_wrap_pad()); EVP_add_cipher_alias(SN_aes_192_cbc, "AES192"); EVP_add_cipher_alias(SN_aes_192_cbc, "aes192"); EVP_add_cipher(EVP_aes_256_ecb()); EVP_add_cipher(EVP_aes_256_cbc()); EVP_add_cipher(EVP_aes_256_cfb()); EVP_add_cipher(EVP_aes_256_cfb1()); EVP_add_cipher(EVP_aes_256_cfb8()); EVP_add_cipher(EVP_aes_256_ofb()); EVP_add_cipher(EVP_aes_256_ctr()); EVP_add_cipher(EVP_aes_256_gcm()); #ifndef OPENSSL_NO_OCB EVP_add_cipher(EVP_aes_256_ocb()); #endif EVP_add_cipher(EVP_aes_256_xts()); EVP_add_cipher(EVP_aes_256_ccm()); EVP_add_cipher(EVP_aes_256_wrap()); EVP_add_cipher_alias(SN_id_aes256_wrap, "aes256-wrap"); EVP_add_cipher(EVP_aes_256_wrap_pad()); EVP_add_cipher_alias(SN_aes_256_cbc, "AES256"); EVP_add_cipher_alias(SN_aes_256_cbc, "aes256"); EVP_add_cipher(EVP_aes_128_cbc_hmac_sha1()); EVP_add_cipher(EVP_aes_256_cbc_hmac_sha1()); EVP_add_cipher(EVP_aes_128_cbc_hmac_sha256()); EVP_add_cipher(EVP_aes_256_cbc_hmac_sha256()); #ifndef OPENSSL_NO_SIV EVP_add_cipher(EVP_aes_128_siv()); EVP_add_cipher(EVP_aes_192_siv()); EVP_add_cipher(EVP_aes_256_siv()); #endif #ifndef OPENSSL_NO_ARIA EVP_add_cipher(EVP_aria_128_ecb()); EVP_add_cipher(EVP_aria_128_cbc()); EVP_add_cipher(EVP_aria_128_cfb()); EVP_add_cipher(EVP_aria_128_cfb1()); EVP_add_cipher(EVP_aria_128_cfb8()); EVP_add_cipher(EVP_aria_128_ctr()); EVP_add_cipher(EVP_aria_128_ofb()); EVP_add_cipher(EVP_aria_128_gcm()); EVP_add_cipher(EVP_aria_128_ccm()); EVP_add_cipher_alias(SN_aria_128_cbc, "ARIA128"); EVP_add_cipher_alias(SN_aria_128_cbc, "aria128"); EVP_add_cipher(EVP_aria_192_ecb()); EVP_add_cipher(EVP_aria_192_cbc()); EVP_add_cipher(EVP_aria_192_cfb()); EVP_add_cipher(EVP_aria_192_cfb1()); EVP_add_cipher(EVP_aria_192_cfb8()); EVP_add_cipher(EVP_aria_192_ctr()); EVP_add_cipher(EVP_aria_192_ofb()); EVP_add_cipher(EVP_aria_192_gcm()); EVP_add_cipher(EVP_aria_192_ccm()); EVP_add_cipher_alias(SN_aria_192_cbc, "ARIA192"); EVP_add_cipher_alias(SN_aria_192_cbc, "aria192"); EVP_add_cipher(EVP_aria_256_ecb()); EVP_add_cipher(EVP_aria_256_cbc()); EVP_add_cipher(EVP_aria_256_cfb()); EVP_add_cipher(EVP_aria_256_cfb1()); EVP_add_cipher(EVP_aria_256_cfb8()); EVP_add_cipher(EVP_aria_256_ctr()); EVP_add_cipher(EVP_aria_256_ofb()); EVP_add_cipher(EVP_aria_256_gcm()); EVP_add_cipher(EVP_aria_256_ccm()); EVP_add_cipher_alias(SN_aria_256_cbc, "ARIA256"); EVP_add_cipher_alias(SN_aria_256_cbc, "aria256"); #endif #ifndef OPENSSL_NO_CAMELLIA EVP_add_cipher(EVP_camellia_128_ecb()); EVP_add_cipher(EVP_camellia_128_cbc()); EVP_add_cipher(EVP_camellia_128_cfb()); EVP_add_cipher(EVP_camellia_128_cfb1()); EVP_add_cipher(EVP_camellia_128_cfb8()); EVP_add_cipher(EVP_camellia_128_ofb()); EVP_add_cipher_alias(SN_camellia_128_cbc, "CAMELLIA128"); EVP_add_cipher_alias(SN_camellia_128_cbc, "camellia128"); EVP_add_cipher(EVP_camellia_192_ecb()); EVP_add_cipher(EVP_camellia_192_cbc()); EVP_add_cipher(EVP_camellia_192_cfb()); EVP_add_cipher(EVP_camellia_192_cfb1()); EVP_add_cipher(EVP_camellia_192_cfb8()); EVP_add_cipher(EVP_camellia_192_ofb()); EVP_add_cipher_alias(SN_camellia_192_cbc, "CAMELLIA192"); EVP_add_cipher_alias(SN_camellia_192_cbc, "camellia192"); EVP_add_cipher(EVP_camellia_256_ecb()); EVP_add_cipher(EVP_camellia_256_cbc()); EVP_add_cipher(EVP_camellia_256_cfb()); EVP_add_cipher(EVP_camellia_256_cfb1()); EVP_add_cipher(EVP_camellia_256_cfb8()); EVP_add_cipher(EVP_camellia_256_ofb()); EVP_add_cipher_alias(SN_camellia_256_cbc, "CAMELLIA256"); EVP_add_cipher_alias(SN_camellia_256_cbc, "camellia256"); EVP_add_cipher(EVP_camellia_128_ctr()); EVP_add_cipher(EVP_camellia_192_ctr()); EVP_add_cipher(EVP_camellia_256_ctr()); #endif #ifndef OPENSSL_NO_CHACHA EVP_add_cipher(EVP_chacha20()); # ifndef OPENSSL_NO_POLY1305 EVP_add_cipher(EVP_chacha20_poly1305()); # endif #endif }
Item *aes_gcm_decrypt(EncItem *ct, SymKey *key) { EVP_CIPHER_CTX *ctx; int aad_len = sizeof(gcm_aad); int len; int rc; if(key == NULL || ct == NULL) { printf("%s :: Invalid input\n", __func__); return NULL; } Item *pt = new Item(CRYPT_ITEM_MAX_LEN); if(pt == NULL) { printf("%s :: no Memory\n", __func__); return NULL; } /* Create and initialise the context */ if(!(ctx = EVP_CIPHER_CTX_new())) { printf("error %s:%d\n", __func__, __LINE__); goto err_out; } EVP_CIPHER_CTX_set_padding(ctx, 0); /* Initialise the decryption operation. */ if(!EVP_DecryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL)) { printf("error %s:%d\n", __func__, __LINE__); goto err_out; } /* Set IV length. Not necessary if this is 12 bytes (96 bits) */ if(!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, 16, NULL)) { printf("error %s:%d\n", __func__, __LINE__); goto err_out; } /* Initialise key and IV */ if(!EVP_DecryptInit_ex(ctx, NULL, NULL, key->getData(), gcm_iv)) { printf("error %s:%d\n", __func__, __LINE__); goto err_out; } /* Set expected tag value. Works in OpenSSL 1.0.1d and later */ if(!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, 16, ct->auth_tag)) { printf("error %s:%d\n", __func__, __LINE__); goto err_out; } /* Provide any AAD data. This can be called zero or more times as * required */ if(!EVP_DecryptUpdate(ctx, NULL, &len, gcm_aad, aad_len)) { printf("error %s:%d\n", __func__, __LINE__); goto err_out; } /* Provide the message to be decrypted, and obtain the plaintext output. * EVP_DecryptUpdate can be called multiple times if necessary */ if(!EVP_DecryptUpdate(ctx, pt->getData(), &len, ct->getData(), ct->len)) { printf("error %s:%d\n", __func__, __LINE__); goto err_out; } pt->len = len; /* Set expected tag value. Works in OpenSSL 1.0.1d and later */ if(!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, 16, ct->auth_tag)) { printf("error %s:%d\n", __func__, __LINE__); goto err_out; } /* Finalise the decryption. A positive return value indicates success, * anything else is a failure - the plaintext is not trustworthy. */ rc = EVP_DecryptFinal_ex(ctx, pt->getData() + len, &len); /* Clean up */ EVP_CIPHER_CTX_free(ctx); if(rc > 0) { /* Success */ pt->len += len; return pt; } else /* Verify failed */ printf("error %s:%d GCM verify failed\n", __func__, __LINE__); err_out: delete pt; return NULL; }
int decrypt(unsigned char *ciphertext, int ciphertext_len, unsigned char *aad, int aad_len, unsigned char *tag, unsigned char *key, unsigned char *iv, unsigned char *plaintext) { EVP_CIPHER_CTX *ctx; int len; int plaintext_len; int ret; /* Create and initialise the context */ if(!(ctx = EVP_CIPHER_CTX_new())) handleErrors(); /* Initialise the decryption operation. */ if(!EVP_DecryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL)) handleErrors(); /* Set IV length. Not necessary if this is 12 bytes (96 bits) */ if(!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, 16, NULL)) handleErrors(); /* Initialise key and IV */ if(!EVP_DecryptInit_ex(ctx, NULL, NULL, key, iv)) handleErrors(); /* Provide any AAD data. This can be called zero or more times as * required */ /* if(!EVP_DecryptUpdate(ctx, NULL, &len, aad, aad_len)) handleErrors(); */ /* Provide the message to be decrypted, and obtain the plaintext output. * EVP_DecryptUpdate can be called multiple times if necessary */ if(!EVP_DecryptUpdate(ctx, plaintext, &len, ciphertext, ciphertext_len)) handleErrors(); plaintext_len = len; /* Set expected tag value. Works in OpenSSL 1.0.1d and later */ /* if(!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, 16, tag)) handleErrors(); */ /* Finalise the decryption. A positive return value indicates success, * anything else is a failure - the plaintext is not trustworthy. */ ret = EVP_DecryptFinal_ex(ctx, plaintext + len, &len); /* Clean up */ EVP_CIPHER_CTX_free(ctx); if(ret > 0) { /* Success */ plaintext_len += len; return plaintext_len; } else { /* Verify failed */ return -1; } }