int main(int argc, char **argv) { int encryptp = 1; const char *ifn = NULL, *ofn = NULL; FILE *in, *out; void *ibuf, *obuf; int ilen, olen; size_t block_size = 0; const EVP_CIPHER *c = EVP_aes_128_cbc(); EVP_CIPHER_CTX ctx; int ret; setprogname(argv[0]); if (argc == 2) { if (strcmp(argv[1], "--version") == 0) { printf("version"); exit(0); } if (strcmp(argv[1], "--help") == 0) usage(0); usage(1); } else if (argc == 4) { block_size = atoi(argv[1]); if (block_size == 0) errx(1, "invalid blocksize %s", argv[1]); ifn = argv[2]; ofn = argv[3]; } else usage(1); in = fopen(ifn, "r"); if (in == NULL) errx(1, "failed to open input file"); out = fopen(ofn, "w+"); if (out == NULL) errx(1, "failed to open output file"); /* Check that key and ivec are long enough */ assert(EVP_CIPHER_key_length(c) <= sizeof(key)); assert(EVP_CIPHER_iv_length(c) <= sizeof(ivec)); /* * Allocate buffer, the output buffer is at least * EVP_CIPHER_block_size() longer */ ibuf = malloc(block_size); obuf = malloc(block_size + EVP_CIPHER_block_size(c)); /* * Init the memory used for EVP_CIPHER_CTX and set the key and * ivec. */ EVP_CIPHER_CTX_init(&ctx); EVP_CipherInit_ex(&ctx, c, NULL, key, ivec, encryptp); /* read in buffer */ while ((ilen = fread(ibuf, 1, block_size, in)) > 0) { /* encrypto/decrypt */ ret = EVP_CipherUpdate(&ctx, obuf, &olen, ibuf, ilen); if (ret != 1) { EVP_CIPHER_CTX_cleanup(&ctx); errx(1, "EVP_CipherUpdate failed"); } /* write out to output file */ fwrite(obuf, 1, olen, out); } /* done reading */ fclose(in); /* clear up any last bytes left in the output buffer */ ret = EVP_CipherFinal_ex(&ctx, obuf, &olen); EVP_CIPHER_CTX_cleanup(&ctx); if (ret != 1) errx(1, "EVP_CipherFinal_ex failed"); /* write the last bytes out and close */ fwrite(obuf, 1, olen, out); fclose(out); return 0; }
unsigned char *rncryptorc_decrypt_data_with_password(const unsigned char *indata, int indata_len, int kdf_iter, const char *password, int password_length, int *outdata_len, char *errbuf, int errbuf_len) { MutilsBlob *blob = NULL; RNCryptorInfo *ci = NULL; int rc, outlen1=0, outlen2=0; EVP_CIPHER_CTX cipher_ctx; unsigned char *outdata = NULL; if (errbuf_len <= 0) { log_err("ERROR:Invalid errbuf len %d",errbuf_len); goto ExitProcessing; } if (indata == NULL) { (void)snprintf(errbuf,errbuf_len-1,"%s", "Input data is NULL"); goto ExitProcessing; } if (password == NULL || *password == '\0') { (void)snprintf(errbuf,errbuf_len-1,"%s", "Password is NULL"); goto ExitProcessing; } if (password_length <= 0) { (void)snprintf(errbuf,errbuf_len-1, "Invalid password length %d",password_length); goto ExitProcessing; } *outdata_len = 0; /* convert input data to our blob */ blob = mutils_data_to_blob((unsigned char *)indata,indata_len); CHECK_MALLOC(blob); /* decode */ log_debug("%s:%d - Decoding ..",MCFL); ci = decode_encrypted_blob(blob); if (!ci) { goto ExitProcessing; } ci->options = 0x01; rc = verify_rncryptor_format(ci->version,ci->options); if (rc != SUCCESS) { (void)snprintf(errbuf,errbuf_len-1,"%s", "Unknown RNCryptor Data Format"); goto ExitProcessing; } log_debug("%s:%d - Decoded version 0x%02x options 0x%02x", MCFL, ci->version, ci->options); log_debug("%s:%d - Verifying HMAC-SHA256 digest",MCFL); /* very hmac */ if (verify_hmac(ci,password,password_length) != SUCCESS) { (void)snprintf(errbuf,errbuf_len-1,"%s", "Could not verify HMAC"); goto ExitProcessing; } log_debug("%s:%d - HMAC verified",MCFL); /* Derive cipher key from password using encr salt and iteration as per RFC2898 */ log_debug("%s:%d - Deriving Cipher key with salt, iteration %d", MCFL, kdf_iter); rc = PKCS5_PBKDF2_HMAC_SHA1(password,password_length, ci->encryption_salt, sizeof(ci->encryption_salt), ci->kdf_iter, sizeof(ci->encr_key), ci->encr_key); /* ci->encr_key is returend */ if (rc != 1) { log_err("ERROR: Could not derive key from password with encr salt and iter"); goto ExitProcessing; } log_debug("%s:%d - Encryption key derived",MCFL); /* decrypt */ outdata = (unsigned char *)malloc(ci->cipher_text_length *sizeof(unsigned char)); CHECK_MALLOC(outdata); log_debug("%s:%d - Decrypting..",MCFL); EVP_DecryptInit(&cipher_ctx,EVP_aes_256_cbc(),ci->encr_key,ci->iv); EVP_DecryptUpdate(&cipher_ctx,outdata,&outlen1,ci->cipher_text, ci->cipher_text_length); EVP_DecryptFinal(&cipher_ctx,outdata + outlen1,&outlen2); EVP_CIPHER_CTX_cleanup(&cipher_ctx); *outdata_len = outlen1 + outlen2; log_debug("%s:%d - Done decrypting, output length %d bytes",MCFL,*outdata_len); ExitProcessing: if (ci) { free_rncryptor_info(ci); } if (blob) { mutils_destroy_blob(blob); } return(outdata); }
int PEM_ASN1_write_bio(i2d_of_void *i2d, const char *name, BIO *bp, void *x, const EVP_CIPHER *enc, unsigned char *kstr, int klen, pem_password_cb *callback, void *u) { EVP_CIPHER_CTX ctx; int dsize=0,i,j,ret=0; unsigned char *p,*data=NULL; const char *objstr=NULL; char buf[PEM_BUFSIZE]; unsigned char key[EVP_MAX_KEY_LENGTH]; unsigned char iv[EVP_MAX_IV_LENGTH]; if (enc != NULL) { objstr=OBJ_nid2sn(EVP_CIPHER_nid(enc)); if (objstr == NULL) { PEMerr(PEM_F_PEM_ASN1_WRITE_BIO,PEM_R_UNSUPPORTED_CIPHER); goto err; } } if ((dsize=i2d(x,NULL)) < 0) { PEMerr(PEM_F_PEM_ASN1_WRITE_BIO,ERR_R_ASN1_LIB); dsize=0; goto err; } /* dzise + 8 bytes are needed */ /* actually it needs the cipher block size extra... */ data=(unsigned char *)OPENSSL_malloc((unsigned int)dsize+20); if (data == NULL) { PEMerr(PEM_F_PEM_ASN1_WRITE_BIO,ERR_R_MALLOC_FAILURE); goto err; } p=data; i=i2d(x,&p); if (enc != NULL) { if (kstr == NULL) { if (callback == NULL) klen=PEM_def_callback(buf,PEM_BUFSIZE,1,u); else klen=(*callback)(buf,PEM_BUFSIZE,1,u); if (klen <= 0) { PEMerr(PEM_F_PEM_ASN1_WRITE_BIO,PEM_R_READ_KEY); goto err; } #ifdef CHARSET_EBCDIC /* Convert the pass phrase from EBCDIC */ ebcdic2ascii(buf, buf, klen); #endif kstr=(unsigned char *)buf; } RAND_add(data,i,0);/* put in the RSA key. */ OPENSSL_assert(enc->iv_len <= (int)sizeof(iv)); if (RAND_pseudo_bytes(iv,enc->iv_len) < 0) /* Generate a salt */ goto err; /* The 'iv' is used as the iv and as a salt. It is * NOT taken from the BytesToKey function */ if (!EVP_BytesToKey(enc,EVP_md5(),iv,kstr,klen,1,key,NULL)) goto err; if (kstr == (unsigned char *)buf) OPENSSL_cleanse(buf,PEM_BUFSIZE); OPENSSL_assert(strlen(objstr)+23+2*enc->iv_len+13 <= sizeof buf); buf[0]='\0'; PEM_proc_type(buf,PEM_TYPE_ENCRYPTED); PEM_dek_info(buf,objstr,enc->iv_len,(char *)iv); /* k=strlen(buf); */ EVP_CIPHER_CTX_init(&ctx); ret = 1; if (!EVP_EncryptInit_ex(&ctx,enc,NULL,key,iv) || !EVP_EncryptUpdate(&ctx,data,&j,data,i) || !EVP_EncryptFinal_ex(&ctx,&(data[j]),&i)) ret = 0; EVP_CIPHER_CTX_cleanup(&ctx); if (ret == 0) goto err; i+=j; } else { ret=1; buf[0]='\0'; } i=PEM_write_bio(bp,name,buf,data,i); if (i <= 0) ret=0; err: OPENSSL_cleanse(key,sizeof(key)); OPENSSL_cleanse(iv,sizeof(iv)); OPENSSL_cleanse((char *)&ctx,sizeof(ctx)); OPENSSL_cleanse(buf,PEM_BUFSIZE); if (data != NULL) { OPENSSL_cleanse(data,(unsigned int)dsize); OPENSSL_free(data); } return(ret); }
OM_uint32 _gssapi_unwrap_arcfour(OM_uint32 *minor_status, const gsskrb5_ctx context_handle, krb5_context context, const gss_buffer_t input_message_buffer, gss_buffer_t output_message_buffer, int *conf_state, gss_qop_t *qop_state, krb5_keyblock *key) { u_char Klocaldata[16]; krb5_keyblock Klocal; krb5_error_code ret; uint32_t seq_number; size_t datalen; OM_uint32 omret; u_char k6_data[16], SND_SEQ[8], Confounder[8]; u_char cksum_data[8]; u_char *p, *p0; int cmp; int conf_flag; size_t padlen = 0, len; if (conf_state) *conf_state = 0; if (qop_state) *qop_state = 0; p0 = input_message_buffer->value; if (IS_DCE_STYLE(context_handle)) { len = GSS_ARCFOUR_WRAP_TOKEN_SIZE + GSS_ARCFOUR_WRAP_TOKEN_DCE_DER_HEADER_SIZE; if (input_message_buffer->length < len) return GSS_S_BAD_MECH; } else { len = input_message_buffer->length; } omret = _gssapi_verify_mech_header(&p0, len, GSS_KRB5_MECHANISM); if (omret) return omret; /* length of mech header */ len = (p0 - (u_char *)input_message_buffer->value) + GSS_ARCFOUR_WRAP_TOKEN_SIZE; if (len > input_message_buffer->length) return GSS_S_BAD_MECH; /* length of data */ datalen = input_message_buffer->length - len; p = p0; if (memcmp(p, "\x02\x01", 2) != 0) return GSS_S_BAD_SIG; p += 2; if (memcmp(p, "\x11\x00", 2) != 0) /* SGN_ALG = HMAC MD5 ARCFOUR */ return GSS_S_BAD_SIG; p += 2; if (memcmp (p, "\x10\x00", 2) == 0) conf_flag = 1; else if (memcmp (p, "\xff\xff", 2) == 0) conf_flag = 0; else return GSS_S_BAD_SIG; p += 2; if (memcmp (p, "\xff\xff", 2) != 0) return GSS_S_BAD_MIC; p = NULL; ret = arcfour_mic_key(context, key, p0 + 16, 8, /* SGN_CKSUM */ k6_data, sizeof(k6_data)); if (ret) { *minor_status = ret; return GSS_S_FAILURE; } { EVP_CIPHER_CTX rc4_key; EVP_CIPHER_CTX_init(&rc4_key); EVP_CipherInit_ex(&rc4_key, EVP_rc4(), NULL, k6_data, NULL, 1); EVP_Cipher(&rc4_key, SND_SEQ, p0 + 8, 8); EVP_CIPHER_CTX_cleanup(&rc4_key); memset(k6_data, 0, sizeof(k6_data)); } _gsskrb5_decode_be_om_uint32(SND_SEQ, &seq_number); if (context_handle->more_flags & LOCAL) cmp = memcmp(&SND_SEQ[4], "\xff\xff\xff\xff", 4); else cmp = memcmp(&SND_SEQ[4], "\x00\x00\x00\x00", 4); if (cmp != 0) { *minor_status = 0; return GSS_S_BAD_MIC; } { int i; Klocal.keytype = key->keytype; Klocal.keyvalue.data = Klocaldata; Klocal.keyvalue.length = sizeof(Klocaldata); for (i = 0; i < 16; i++) Klocaldata[i] = ((u_char *)key->keyvalue.data)[i] ^ 0xF0; } ret = arcfour_mic_key(context, &Klocal, SND_SEQ, 4, k6_data, sizeof(k6_data)); memset(Klocaldata, 0, sizeof(Klocaldata)); if (ret) { *minor_status = ret; return GSS_S_FAILURE; } output_message_buffer->value = malloc(datalen); if (output_message_buffer->value == NULL) { *minor_status = ENOMEM; return GSS_S_FAILURE; } output_message_buffer->length = datalen; if(conf_flag) { EVP_CIPHER_CTX rc4_key; EVP_CIPHER_CTX_init(&rc4_key); EVP_CipherInit_ex(&rc4_key, EVP_rc4(), NULL, k6_data, NULL, 1); EVP_Cipher(&rc4_key, Confounder, p0 + 24, 8); EVP_Cipher(&rc4_key, output_message_buffer->value, p0 + GSS_ARCFOUR_WRAP_TOKEN_SIZE, datalen); EVP_CIPHER_CTX_cleanup(&rc4_key); } else { memcpy(Confounder, p0 + 24, 8); /* Confounder */ memcpy(output_message_buffer->value, p0 + GSS_ARCFOUR_WRAP_TOKEN_SIZE, datalen); } memset(k6_data, 0, sizeof(k6_data)); if (!IS_DCE_STYLE(context_handle)) { ret = _gssapi_verify_pad(output_message_buffer, datalen, &padlen); if (ret) { _gsskrb5_release_buffer(minor_status, output_message_buffer); *minor_status = 0; return ret; } output_message_buffer->length -= padlen; } ret = arcfour_mic_cksum(context, key, KRB5_KU_USAGE_SEAL, cksum_data, sizeof(cksum_data), p0, 8, Confounder, sizeof(Confounder), output_message_buffer->value, output_message_buffer->length + padlen); if (ret) { _gsskrb5_release_buffer(minor_status, output_message_buffer); *minor_status = ret; return GSS_S_FAILURE; } cmp = ct_memcmp(cksum_data, p0 + 16, 8); /* SGN_CKSUM */ if (cmp) { _gsskrb5_release_buffer(minor_status, output_message_buffer); *minor_status = 0; return GSS_S_BAD_MIC; } HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex); omret = _gssapi_msg_order_check(context_handle->order, seq_number); HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); if (omret) return omret; if (conf_state) *conf_state = conf_flag; *minor_status = 0; return GSS_S_COMPLETE; }
unsigned char *rncryptorc_encrypt_data_with_password_with_salts_and_iv(const unsigned char *indata, int indata_len, int kdf_iter, const char *password, int password_length, unsigned char *encr_salt_8, unsigned char *hmac_salt_8, unsigned char *iv_16, int *outdata_len, char *errbuf, int errbuf_len) { RNCryptorInfo *ci = NULL; MutilsBlob *blob = NULL; EVP_CIPHER_CTX cipher_ctx; HMAC_CTX hmac_ctx; int rc=FAILURE; const EVP_MD *sha256 = NULL; int outlen1 = 0, outlen2 = 0; unsigned int hmac_len; unsigned char hmac_sha256[32]; unsigned char *output = NULL; unsigned int blocksize = 16; unsigned char *ciphertext = NULL; unsigned char encr_key[32], hmac_key[32]; int ciphertext_len; log_debug("%s:%d - verifying input",MCFL); if (errbuf_len <= 0) { log_err("ERROR:Invalid errbuf len %d",errbuf_len); goto ExitProcessing; } memset(errbuf,0,errbuf_len); memset(encr_key,0,sizeof(encr_key)); memset(hmac_key,0,sizeof(hmac_key)); if (password == NULL || *password == '\0') { (void)snprintf(errbuf,errbuf_len-1,"%s", "Password can not be NULL"); goto ExitProcessing; } if (password_length <= 0) { (void)snprintf(errbuf,errbuf_len-1,"Invalid password length %d",password_length); goto ExitProcessing; } ci = allocate_rncryptor_info(); if (!ci) { goto ExitProcessing; } ci->options = 0x01; /* Derive cipher key from password using encr salt and iteration as per RFC2898 */ log_debug("%s:%d - Deriving Cipher key with salt, iterations %d", MCFL, kdf_iter); rc = PKCS5_PBKDF2_HMAC_SHA1(password,password_length, encr_salt_8, 8, kdf_iter, 32, encr_key); /* encr_key is returend */ if (rc != 1) { log_err("ERROR: Could not derive key from password with encr salt and iter"); (void)snprintf(errbuf,errbuf_len-1,"%s", "Could not derive key from password with encr salt and iter"); goto ExitProcessing; } EVP_EncryptInit(&cipher_ctx,EVP_aes_256_cbc(),encr_key,iv_16); blocksize = EVP_CIPHER_CTX_block_size(&cipher_ctx); log_debug("%s:%d - Block size: %ld",MCFL,blocksize); if (indata == NULL && indata_len == 0) { blob = mutils_allocate_blob(blocksize); } else { blob = mutils_allocate_blob(indata_len); } CHECK_MALLOC(blob); log_debug("%s:%d - input data size %d bytes", MCFL, indata_len); log_debug("%s:%d - Encoding",MCFL); /* ** Encode. memory will be re-allocated for blob if needed. */ /* version */ mutils_write_blob_byte(blob,ci->version); /* options */ mutils_write_blob_byte(blob,ci->options); /* 8 byte encryption salt, we're using password */ mutils_write_blob(blob,8,encr_salt_8); /* 8 byte hmac salt */ mutils_write_blob(blob,8,hmac_salt_8); /* 16 byte iv */ mutils_write_blob(blob,16,iv_16); log_debug("%s:%d - Deriving HMAC key with salt, iterations %d", MCFL, kdf_iter); /* Derive HMAC key from password using hmac salt and iteration as per RFC2898 */ rc = PKCS5_PBKDF2_HMAC_SHA1(password,password_length, hmac_salt_8, 8, kdf_iter, 32, hmac_key); /* hmac_key is returend */ if (rc != 1) { log_err("ERROR: Could not derive key from password with hmac salt and iter"); (void)snprintf(errbuf,errbuf_len-1,"%s", "Could not derive key from password with hmac salt and iter"); goto ExitProcessing; } log_debug("%s:%d - Encrypting..",MCFL); /* allocate space for cipher text */ ciphertext_len = indata_len + blocksize - (indata_len % blocksize); ciphertext = (unsigned char *) malloc(ciphertext_len * sizeof(unsigned char)); CHECK_MALLOC(ciphertext); EVP_EncryptUpdate(&cipher_ctx,ciphertext,&outlen1,indata,indata_len); EVP_EncryptFinal(&cipher_ctx,ciphertext + outlen1,&outlen2); EVP_CIPHER_CTX_cleanup(&cipher_ctx); mutils_write_blob(blob,outlen1 + outlen2,ciphertext); log_debug("%s:%d - Plain text length: %d",MCFL,indata_len); log_debug("%s:%d - Cipther text length: %d",MCFL,outlen1 + outlen2); log_debug("%s:%d - Padding %d bytes", MCFL, (ciphertext_len - indata_len)); log_debug("%s:%d - outdata len: %d",MCFL,outlen1 + outlen2); log_debug("%s:%d - calculating HMAC-SHA256",MCFL); /* calculate HMAC-SHA256 */ sha256 = EVP_sha256(); HMAC_CTX_init(&hmac_ctx); HMAC_Init(&hmac_ctx,hmac_key,sizeof(hmac_key),sha256); HMAC_Update(&hmac_ctx,blob->data,blob->length); HMAC_Final(&hmac_ctx,hmac_sha256,&hmac_len); HMAC_CTX_cleanup(&hmac_ctx); mutils_write_blob(blob,hmac_len,hmac_sha256); log_debug("%s:%d - Output lenth %lu",MCFL,blob->length); output = (unsigned char *)malloc(blob->length * sizeof(unsigned char)); CHECK_MALLOC(output); memcpy(output,blob->data,blob->length); *outdata_len = blob->length; ExitProcessing: if (ci) { free_rncryptor_info(ci); } if (blob) { mutils_destroy_blob(blob); } if (ciphertext) { (void)free((char *)ciphertext); } return(output); }
static int i2b_PVK(unsigned char **out, EVP_PKEY *pk, int enclevel, pem_password_cb *cb, void *u) { int outlen = 24, pklen; unsigned char *p, *salt = NULL; EVP_CIPHER_CTX cctx; EVP_CIPHER_CTX_init(&cctx); if (enclevel) outlen += PVK_SALTLEN; pklen = do_i2b(NULL, pk, 0); if (pklen < 0) return -1; outlen += pklen; if (!out) return outlen; if (*out) p = *out; else { p = OPENSSL_malloc(outlen); if (!p) { PEMerr(PEM_F_I2B_PVK, ERR_R_MALLOC_FAILURE); return -1; } *out = p; } write_ledword(&p, MS_PVKMAGIC); write_ledword(&p, 0); if (pk->type == EVP_PKEY_DSA) write_ledword(&p, MS_KEYTYPE_SIGN); else write_ledword(&p, MS_KEYTYPE_KEYX); write_ledword(&p, enclevel ? 1 : 0); write_ledword(&p, enclevel ? PVK_SALTLEN : 0); write_ledword(&p, pklen); if (enclevel) { if (RAND_bytes(p, PVK_SALTLEN) <= 0) goto error; salt = p; p += PVK_SALTLEN; } do_i2b(&p, pk, 0); if (enclevel == 0) return outlen; else { char psbuf[PEM_BUFSIZE]; unsigned char keybuf[20]; int enctmplen, inlen; if (cb) inlen = cb(psbuf, PEM_BUFSIZE, 1, u); else inlen = PEM_def_callback(psbuf, PEM_BUFSIZE, 1, u); if (inlen <= 0) { PEMerr(PEM_F_I2B_PVK, PEM_R_BAD_PASSWORD_READ); goto error; } if (!derive_pvk_key(keybuf, salt, PVK_SALTLEN, (unsigned char *)psbuf, inlen)) goto error; if (enclevel == 1) memset(keybuf + 5, 0, 11); p = salt + PVK_SALTLEN + 8; if (!EVP_EncryptInit_ex(&cctx, EVP_rc4(), NULL, keybuf, NULL)) goto error; OPENSSL_cleanse(keybuf, 20); if (!EVP_DecryptUpdate(&cctx, p, &enctmplen, p, pklen - 8)) goto error; if (!EVP_DecryptFinal_ex(&cctx, p + enctmplen, &enctmplen)) goto error; } EVP_CIPHER_CTX_cleanup(&cctx); return outlen; error: EVP_CIPHER_CTX_cleanup(&cctx); return -1; }
OM_uint32 _gssapi_verify_mic_arcfour(OM_uint32 * minor_status, const gsskrb5_ctx context_handle, krb5_context context, const gss_buffer_t message_buffer, const gss_buffer_t token_buffer, gss_qop_t * qop_state, krb5_keyblock *key, const char *type) { krb5_error_code ret; uint32_t seq_number; OM_uint32 omret; u_char SND_SEQ[8], cksum_data[8], *p; char k6_data[16]; int cmp; if (qop_state) *qop_state = 0; p = token_buffer->value; omret = _gsskrb5_verify_header (&p, token_buffer->length, type, GSS_KRB5_MECHANISM); if (omret) return omret; if (memcmp(p, "\x11\x00", 2) != 0) /* SGN_ALG = HMAC MD5 ARCFOUR */ return GSS_S_BAD_SIG; p += 2; if (memcmp (p, "\xff\xff\xff\xff", 4) != 0) return GSS_S_BAD_MIC; p += 4; ret = arcfour_mic_cksum(context, key, KRB5_KU_USAGE_SIGN, cksum_data, sizeof(cksum_data), p - 8, 8, message_buffer->value, message_buffer->length, NULL, 0); if (ret) { *minor_status = ret; return GSS_S_FAILURE; } ret = arcfour_mic_key(context, key, cksum_data, sizeof(cksum_data), k6_data, sizeof(k6_data)); if (ret) { *minor_status = ret; return GSS_S_FAILURE; } cmp = ct_memcmp(cksum_data, p + 8, 8); if (cmp) { *minor_status = 0; return GSS_S_BAD_MIC; } { EVP_CIPHER_CTX rc4_key; EVP_CIPHER_CTX_init(&rc4_key); EVP_CipherInit_ex(&rc4_key, EVP_rc4(), NULL, (void *)k6_data, NULL, 0); EVP_Cipher(&rc4_key, SND_SEQ, p, 8); EVP_CIPHER_CTX_cleanup(&rc4_key); memset(k6_data, 0, sizeof(k6_data)); } _gsskrb5_decode_be_om_uint32(SND_SEQ, &seq_number); if (context_handle->more_flags & LOCAL) cmp = memcmp(&SND_SEQ[4], "\xff\xff\xff\xff", 4); else cmp = memcmp(&SND_SEQ[4], "\x00\x00\x00\x00", 4); memset(SND_SEQ, 0, sizeof(SND_SEQ)); if (cmp != 0) { *minor_status = 0; return GSS_S_BAD_MIC; } HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex); omret = _gssapi_msg_order_check(context_handle->order, seq_number); HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); if (omret) return omret; *minor_status = 0; return GSS_S_COMPLETE; }
void cipher_ctx_cleanup (EVP_CIPHER_CTX *ctx) { EVP_CIPHER_CTX_cleanup (ctx); }
long _IKED::packet_ike_decrypt( IDB_PH1 * sa, PACKET_IKE & packet, BDATA * iv ) { log.txt( LLOG_INFO, "=< : cookies %08x%08x:%08x%08x\n", htonl( *( long * ) &sa->cookies.i[ 0 ] ), htonl( *( long * ) &sa->cookies.i[ 4 ] ), htonl( *( long * ) &sa->cookies.r[ 0 ] ), htonl( *( long * ) &sa->cookies.r[ 4 ] ) ); log.txt( LLOG_INFO, "=< : message %08x\n", htonl( packet.get_msgid() ) ); // // check if decrypt is required // unsigned char * data = packet.buff(); size_t size = packet.size(); if( !( data[ ISAKMP_FLAGS_OFFSET ] & ISAKMP_FLAG_ENCRYPT ) ) return LIBIKE_OK; log.bin( LLOG_DEBUG, LLOG_DECODE, iv->buff(), iv->size(), "=< : decrypt iv" ); // // temporarily save enough // of the packet to store // as iv data post decrypt // unsigned char iv_data[ HMAC_MAX_MD_CBLOCK ]; memcpy( iv_data, data + size - iv->size(), iv->size() ); // // init cipher key and iv // EVP_CIPHER_CTX ctx_cipher; EVP_CIPHER_CTX_init( &ctx_cipher ); EVP_CipherInit_ex( &ctx_cipher, sa->evp_cipher, NULL, NULL, NULL, 0 ); EVP_CIPHER_CTX_set_key_length( &ctx_cipher, ( int ) sa->key.size() ); EVP_CipherInit_ex( &ctx_cipher, NULL, NULL, sa->key.buff(), iv->buff(), 0 ); // // decrypt all but header // EVP_Cipher( &ctx_cipher, data + sizeof( IKE_HEADER ), data + sizeof( IKE_HEADER ), ( int ) size - sizeof( IKE_HEADER ) ); EVP_CIPHER_CTX_cleanup( &ctx_cipher ); log.bin( LLOG_DEBUG, LLOG_DECODE, data, size, "== : decrypt packet" ); // // validate the packet integrity // IKE_HEADER * header = ( IKE_HEADER * ) packet.buff(); size = sizeof( IKE_HEADER ); if( packet.size() < size ) { log.txt( LLOG_ERROR, "!! : validate packet failed ( truncated header )\n" ); return LIBIKE_FAILED; } while( true ) { IKE_PAYLOAD * payload = ( IKE_PAYLOAD * )( packet.buff() + size ); if( packet.size() < ( size + sizeof( IKE_PAYLOAD ) ) ) { log.txt( LLOG_ERROR, "!! : validate packet failed ( truncated payload )\n" ); return LIBIKE_FAILED; } if( payload->reserved ) { log.txt( LLOG_ERROR, "!! : validate packet failed ( reserved value is non-null )\n" ); return LIBIKE_FAILED; } size += ntohs( payload->length ); if( packet.size() < size ) { log.txt( LLOG_ERROR, "!! : validate packet failed ( payload length is invalid )\n" ); return LIBIKE_FAILED; } if( payload->next == ISAKMP_PAYLOAD_NONE ) break; } // // validate packet padding. if the encrypted // packet size is equal to the ike message // length, we can skip this step. although the // RFC states there should at least be one pad // byte that describes the padding length, if // we are strict we will break compatibility // with many implementations including cisco // if( size < packet.size() ) { // // trim packet padding // size_t diff = packet.size() - size; packet.size( size ); log.txt( LLOG_DEBUG, "<= : trimmed packet padding ( %i bytes )\n", diff ); header = ( IKE_HEADER * ) packet.buff(); header->length = htonl( ( uint32_t ) size ); } // // store cipher iv data // memcpy( iv->buff(), iv_data, iv->size() ); log.bin( LLOG_DEBUG, LLOG_DECODE, iv->buff(), iv->size(), "<= : stored iv" ); return LIBIKE_OK; }
static int tls_decrypt_ticket(SSL *s, const unsigned char *etick, int eticklen, const unsigned char *sess_id, int sesslen, SSL_SESSION **psess) { SSL_SESSION *sess; unsigned char *sdec; const unsigned char *p; int slen, mlen; unsigned char tick_hmac[EVP_MAX_MD_SIZE]; HMAC_CTX hctx; EVP_CIPHER_CTX ctx; /* Attempt to process session ticket, first conduct sanity and * integrity checks on ticket. */ mlen = EVP_MD_size(tlsext_tick_md()); eticklen -= mlen; /* Need at least keyname + iv + some encrypted data */ if (eticklen < 48) goto tickerr; /* Check key name matches */ if (memcmp(etick, s->ctx->tlsext_tick_key_name, 16)) goto tickerr; /* Check HMAC of encrypted ticket */ HMAC_CTX_init(&hctx); HMAC_Init_ex(&hctx, s->ctx->tlsext_tick_hmac_key, 16, tlsext_tick_md(), NULL); HMAC_Update(&hctx, etick, eticklen); HMAC_Final(&hctx, tick_hmac, NULL); HMAC_CTX_cleanup(&hctx); if (memcmp(tick_hmac, etick + eticklen, mlen)) goto tickerr; /* Set p to start of IV */ p = etick + 16; EVP_CIPHER_CTX_init(&ctx); /* Attempt to decrypt session data */ EVP_DecryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL, s->ctx->tlsext_tick_aes_key, p); /* Move p after IV to start of encrypted ticket, update length */ p += 16; eticklen -= 32; sdec = OPENSSL_malloc(eticklen); if (!sdec) { EVP_CIPHER_CTX_cleanup(&ctx); return -1; } EVP_DecryptUpdate(&ctx, sdec, &slen, p, eticklen); if (EVP_DecryptFinal(&ctx, sdec + slen, &mlen) <= 0) goto tickerr; slen += mlen; EVP_CIPHER_CTX_cleanup(&ctx); p = sdec; sess = d2i_SSL_SESSION(NULL, &p, slen); OPENSSL_free(sdec); if (sess) { /* The session ID if non-empty is used by some clients to * detect that the ticket has been accepted. So we copy it to * the session structure. If it is empty set length to zero * as required by standard. */ if (sesslen) memcpy(sess->session_id, sess_id, sesslen); sess->session_id_length = sesslen; *psess = sess; s->tlsext_ticket_expected = 0; return 1; } /* If session decrypt failure indicate a cache miss and set state to * send a new ticket */ tickerr: s->tlsext_ticket_expected = 1; return 0; }
static int try_decrypt(hx509_context context, struct hx509_collector *collector, const AlgorithmIdentifier *alg, const EVP_CIPHER *c, const void *ivdata, const void *password, size_t passwordlen, const void *cipher, size_t len) { heim_octet_string clear; size_t keylen; void *key; int ret; keylen = EVP_CIPHER_key_length(c); key = malloc(keylen); if (key == NULL) { hx509_clear_error_string(context); return ENOMEM; } ret = EVP_BytesToKey(c, EVP_md5(), ivdata, password, passwordlen, 1, key, NULL); if (ret <= 0) { hx509_set_error_string(context, 0, HX509_CRYPTO_INTERNAL_ERROR, "Failed to do string2key for private key"); return HX509_CRYPTO_INTERNAL_ERROR; } clear.data = malloc(len); if (clear.data == NULL) { hx509_set_error_string(context, 0, ENOMEM, "Out of memory to decrypt for private key"); ret = ENOMEM; goto out; } clear.length = len; { EVP_CIPHER_CTX ctx; EVP_CIPHER_CTX_init(&ctx); EVP_CipherInit_ex(&ctx, c, NULL, key, ivdata, 0); EVP_Cipher(&ctx, clear.data, cipher, len); EVP_CIPHER_CTX_cleanup(&ctx); } ret = _hx509_collector_private_key_add(context, collector, alg, NULL, &clear, NULL); memset(clear.data, 0, clear.length); free(clear.data); out: memset(key, 0, keylen); free(key); return ret; }
static int entersafe_mac_apdu(sc_card_t *card, sc_apdu_t *apdu, u8 * key,size_t keylen, u8 * buff,size_t buffsize) { int r; u8 iv[8]; u8 *tmp=0,*tmp_rounded=NULL; size_t tmpsize=0,tmpsize_rounded=0; int outl=0; EVP_CIPHER_CTX ctx; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); assert(card); assert(apdu); assert(key); assert(buff); if(apdu->cse != SC_APDU_CASE_3_SHORT) return SC_ERROR_INTERNAL; if(keylen!=8 && keylen!=16) return SC_ERROR_INTERNAL; r=entersafe_gen_random(card,iv,sizeof(iv)); SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL,r,"entersafe gen random failed"); /* encode the APDU in the buffer */ if ((r=sc_apdu_get_octets(card->ctx, apdu, &tmp, &tmpsize,SC_PROTO_RAW)) != SC_SUCCESS) goto out; /* round to 8 */ tmpsize_rounded=(tmpsize/8+1)*8; tmp_rounded = malloc(tmpsize_rounded); if (tmp_rounded == NULL) { r = SC_ERROR_OUT_OF_MEMORY; goto out; } /*build content and padded buffer by 0x80 0x00 0x00..... */ memset(tmp_rounded,0,tmpsize_rounded); memcpy(tmp_rounded,tmp,tmpsize); tmp_rounded[4]+=4; tmp_rounded[tmpsize]=0x80; /* block_size-1 blocks*/ EVP_CIPHER_CTX_init(&ctx); EVP_CIPHER_CTX_set_padding(&ctx,0); EVP_EncryptInit_ex(&ctx, EVP_des_cbc(), NULL, key, iv); if(tmpsize_rounded>8){ if(!EVP_EncryptUpdate(&ctx,tmp_rounded,&outl,tmp_rounded,tmpsize_rounded-8)){ r = SC_ERROR_INTERNAL; goto out; } } /* last block */ if(keylen==8) { if(!EVP_EncryptUpdate(&ctx,tmp_rounded+outl,&outl,tmp_rounded+outl,8)){ r = SC_ERROR_INTERNAL; goto out; } } else { EVP_EncryptInit_ex(&ctx, EVP_des_ede_cbc(), NULL, key,tmp_rounded+outl-8); if(!EVP_EncryptUpdate(&ctx,tmp_rounded+outl,&outl,tmp_rounded+outl,8)){ r = SC_ERROR_INTERNAL; goto out; } } if (!EVP_CIPHER_CTX_cleanup(&ctx)){ r = SC_ERROR_INTERNAL; goto out; } memcpy(buff,apdu->data,apdu->lc); /* use first 4 bytes of last block as mac value*/ memcpy(buff+apdu->lc,tmp_rounded+tmpsize_rounded-8,4); apdu->data=buff; apdu->lc+=4; apdu->datalen=apdu->lc; out: if(tmp) free(tmp); if(tmp_rounded) free(tmp_rounded); SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r); }
int AesFileEnc::do_crypt(FILE *in, FILE *out, int do_encrypt) { /* Allow enough space in output buffer for additional block */ unsigned char inbuf[1024], outbuf[1024 + EVP_MAX_BLOCK_LENGTH]; int inlen, outlen; EVP_CIPHER_CTX ctx; std::cout << "tutaj"; unsigned char* key = this->key(); // std::cout <<key<<std::endl; //unsigned char key[] = "0123456789abcdeF"; std::cout <<key<< std::endl; //unsigned char iv[] = "1234567887654321"; EVP_CIPHER_CTX_init(&ctx); switch(this->type) { case cbc128: EVP_CipherInit_ex(&ctx, EVP_aes_128_cbc(), NULL, NULL, NULL, do_encrypt); break; case cbc192: EVP_CipherInit_ex(&ctx, EVP_aes_192_cbc(), NULL, NULL, NULL, do_encrypt); break; case cbc256: EVP_CipherInit_ex(&ctx, EVP_aes_256_cbc(), NULL, NULL, NULL, do_encrypt); break; case ecb128: EVP_CipherInit_ex(&ctx, EVP_aes_128_ecb(), NULL, NULL, NULL, do_encrypt); break; case ecb192: EVP_CipherInit_ex(&ctx, EVP_aes_192_ecb(), NULL, NULL, NULL, do_encrypt); break; case ecb256: EVP_CipherInit_ex(&ctx, EVP_aes_256_ecb(), NULL, NULL, NULL, do_encrypt); break; case cfb128: EVP_CipherInit_ex(&ctx, EVP_aes_128_cfb(), NULL, NULL, NULL, do_encrypt); break; case cfb192: EVP_CipherInit_ex(&ctx, EVP_aes_192_cfb(), NULL, NULL, NULL, do_encrypt); break; case cfb256: EVP_CipherInit_ex(&ctx, EVP_aes_256_cfb(), NULL, NULL, NULL, do_encrypt); break; case ofb128: EVP_CipherInit_ex(&ctx, EVP_aes_128_ofb(), NULL, NULL, NULL, do_encrypt); break; case ofb192: EVP_CipherInit_ex(&ctx, EVP_aes_192_ofb(), NULL, NULL, NULL, do_encrypt); break; case ofb256: EVP_CipherInit_ex(&ctx, EVP_aes_256_ofb(), NULL, NULL, NULL, do_encrypt); break; } unsigned char *iv = this->iv(EVP_CIPHER_CTX_iv_length(&ctx)); std::cout<< this->keyLength << std::endl; std::cout<< EVP_CIPHER_CTX_iv_length(&ctx) <<std::endl; OPENSSL_assert(EVP_CIPHER_CTX_key_length(&ctx) == this->keyLength); //OPENSSL_assert(EVP_CIPHER_CTX_iv_length(&ctx) == this->keyLength); EVP_CipherInit_ex(&ctx, NULL, NULL, key, iv, do_encrypt); for(;;) { inlen = fread(inbuf, 1, 1024, in); if(inlen <= 0) break; if(!EVP_CipherUpdate(&ctx, outbuf, &outlen, inbuf, inlen)) { EVP_CIPHER_CTX_cleanup(&ctx); return 0; } fwrite(outbuf, 1, outlen, out); } if(!EVP_CipherFinal_ex(&ctx, outbuf, &outlen)) { EVP_CIPHER_CTX_cleanup(&ctx); return 0; } fwrite(outbuf, 1, outlen, out); EVP_CIPHER_CTX_cleanup(&ctx); return 1; }
void crypto_aes_close (crypto_aes_t *crypto) { EVP_CIPHER_CTX_cleanup(&(crypto->enc)); EVP_CIPHER_CTX_cleanup(&(crypto->dec)); pthread_mutex_destroy(&(crypto->lock)); free(crypto); }
int ciphers_valid(const char *names) { const Cipher *c; char *cipher_list, *cp; char *p; if (names == NULL || strcmp(names, "") == 0) return 0; cipher_list = cp = xstrdup(names); for ((p = strsep(&cp, CIPHER_SEP)); p && *p != '\0'; (p = strsep(&cp, CIPHER_SEP))) { c = cipher_by_name(p); #ifdef NONE_CIPHER_ENABLED if (c == NULL || (c->number != SSH_CIPHER_SSH2 && c->number != SSH_CIPHER_NONE)) { #else if (c == NULL || (c->number != SSH_CIPHER_SSH2)) { #endif debug("bad cipher %s [%s]", p, names); free(cipher_list); return 0; } } debug3("ciphers ok: [%s]", names); free(cipher_list); return 1; } /* * Parses the name of the cipher. Returns the number of the corresponding * cipher, or -1 on error. */ int cipher_number(const char *name) { const Cipher *c; if (name == NULL) return -1; for (c = ciphers; c->name != NULL; c++) if (strcasecmp(c->name, name) == 0) return c->number; return -1; } char * cipher_name(int id) { const Cipher *c = cipher_by_number(id); return (c==NULL) ? "<unknown>" : c->name; } void cipher_init(CipherContext *cc, const Cipher *cipher, const u_char *key, u_int keylen, const u_char *iv, u_int ivlen, int do_encrypt) { static int dowarn = 1; #ifdef SSH_OLD_EVP EVP_CIPHER *type; #else const EVP_CIPHER *type; int klen; #endif u_char *junk, *discard; if (cipher->number == SSH_CIPHER_DES) { if (dowarn) { error("Warning: use of DES is strongly discouraged " "due to cryptographic weaknesses"); dowarn = 0; } if (keylen > 8) keylen = 8; } cc->plaintext = (cipher->number == SSH_CIPHER_NONE); cc->encrypt = do_encrypt; if (keylen < cipher->key_len) fatal("cipher_init: key length %d is insufficient for %s.", keylen, cipher->name); if (iv != NULL && ivlen < cipher_ivlen(cipher)) fatal("cipher_init: iv length %d is insufficient for %s.", ivlen, cipher->name); cc->cipher = cipher; if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) { chachapoly_init(&cc->cp_ctx, key, keylen); return; } type = (*cipher->evptype)(); EVP_CIPHER_CTX_init(&cc->evp); #ifdef SSH_OLD_EVP if (type->key_len > 0 && type->key_len != keylen) { debug("cipher_init: set keylen (%d -> %d)", type->key_len, keylen); type->key_len = keylen; } EVP_CipherInit(&cc->evp, type, (u_char *)key, (u_char *)iv, (do_encrypt == CIPHER_ENCRYPT)); #else if (EVP_CipherInit(&cc->evp, type, NULL, (u_char *)iv, (do_encrypt == CIPHER_ENCRYPT)) == 0) fatal("cipher_init: EVP_CipherInit failed for %s", cipher->name); if (cipher_authlen(cipher) && !EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_SET_IV_FIXED, -1, (u_char *)iv)) fatal("cipher_init: EVP_CTRL_GCM_SET_IV_FIXED failed for %s", cipher->name); klen = EVP_CIPHER_CTX_key_length(&cc->evp); if (klen > 0 && keylen != (u_int)klen) { debug2("cipher_init: set keylen (%d -> %d)", klen, keylen); if (EVP_CIPHER_CTX_set_key_length(&cc->evp, keylen) == 0) fatal("cipher_init: set keylen failed (%d -> %d)", klen, keylen); } if (EVP_CipherInit(&cc->evp, NULL, (u_char *)key, NULL, -1) == 0) fatal("cipher_init: EVP_CipherInit: set key failed for %s", cipher->name); #endif if (cipher->discard_len > 0) { junk = xmalloc(cipher->discard_len); discard = xmalloc(cipher->discard_len); if (EVP_Cipher(&cc->evp, discard, junk, cipher->discard_len) == 0) fatal("evp_crypt: EVP_Cipher failed during discard"); explicit_bzero(discard, cipher->discard_len); free(junk); free(discard); } } /* * cipher_crypt() operates as following: * Copy 'aadlen' bytes (without en/decryption) from 'src' to 'dest'. * Theses bytes are treated as additional authenticated data for * authenticated encryption modes. * En/Decrypt 'len' bytes at offset 'aadlen' from 'src' to 'dest'. * Use 'authlen' bytes at offset 'len'+'aadlen' as the authentication tag. * This tag is written on encryption and verified on decryption. * Both 'aadlen' and 'authlen' can be set to 0. * cipher_crypt() returns 0 on success and -1 if the decryption integrity * check fails. */ int cipher_crypt(CipherContext *cc, u_int seqnr, u_char *dest, const u_char *src, u_int len, u_int aadlen, u_int authlen) { if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) return chachapoly_crypt(&cc->cp_ctx, seqnr, dest, src, len, aadlen, authlen, cc->encrypt); if (authlen) { u_char lastiv[1]; if (authlen != cipher_authlen(cc->cipher)) fatal("%s: authlen mismatch %d", __func__, authlen); /* increment IV */ if (!EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_IV_GEN, 1, lastiv)) fatal("%s: EVP_CTRL_GCM_IV_GEN", __func__); /* set tag on decyption */ if (!cc->encrypt && !EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_SET_TAG, authlen, (u_char *)src + aadlen + len)) fatal("%s: EVP_CTRL_GCM_SET_TAG", __func__); } if (aadlen) { if (authlen && EVP_Cipher(&cc->evp, NULL, (u_char *)src, aadlen) < 0) fatal("%s: EVP_Cipher(aad) failed", __func__); memcpy(dest, src, aadlen); } if (len % cc->cipher->block_size) fatal("%s: bad plaintext length %d", __func__, len); if (EVP_Cipher(&cc->evp, dest + aadlen, (u_char *)src + aadlen, len) < 0) fatal("%s: EVP_Cipher failed", __func__); if (authlen) { /* compute tag (on encrypt) or verify tag (on decrypt) */ if (EVP_Cipher(&cc->evp, NULL, NULL, 0) < 0) { if (cc->encrypt) fatal("%s: EVP_Cipher(final) failed", __func__); else return -1; } if (cc->encrypt && !EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_GET_TAG, authlen, dest + aadlen + len)) fatal("%s: EVP_CTRL_GCM_GET_TAG", __func__); } return 0; } /* Extract the packet length, including any decryption necessary beforehand */ int cipher_get_length(CipherContext *cc, u_int *plenp, u_int seqnr, const u_char *cp, u_int len) { if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) return chachapoly_get_length(&cc->cp_ctx, plenp, seqnr, cp, len); if (len < 4) return -1; *plenp = get_u32(cp); return 0; } void cipher_cleanup(CipherContext *cc) { if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) explicit_bzero(&cc->cp_ctx, sizeof(cc->cp_ctx)); else if (EVP_CIPHER_CTX_cleanup(&cc->evp) == 0) error("cipher_cleanup: EVP_CIPHER_CTX_cleanup failed"); } /* * Selects the cipher, and keys if by computing the MD5 checksum of the * passphrase and using the resulting 16 bytes as the key. */ void cipher_set_key_string(CipherContext *cc, const Cipher *cipher, const char *passphrase, int do_encrypt) { u_char digest[16]; if (ssh_digest_memory(SSH_DIGEST_MD5, passphrase, strlen(passphrase), digest, sizeof(digest)) < 0) fatal("%s: md5 failed", __func__); cipher_init(cc, cipher, digest, 16, NULL, 0, do_encrypt); explicit_bzero(digest, sizeof(digest)); }
long _IKED::packet_ike_encrypt( IDB_PH1 * sa, PACKET_IKE & packet, BDATA * iv ) { log.txt( LLOG_INFO, ">= : cookies %08x%08x:%08x%08x\n", htonl( *( long * ) &sa->cookies.i[ 0 ] ), htonl( *( long * ) &sa->cookies.i[ 4 ] ), htonl( *( long * ) &sa->cookies.r[ 0 ] ), htonl( *( long * ) &sa->cookies.r[ 4 ] ) ); log.txt( LLOG_INFO, ">= : message %08x\n", htonl( packet.get_msgid() ) ); // // check if encrypt is required // unsigned char * data = packet.buff(); size_t size = packet.size(); if( !( data[ ISAKMP_FLAGS_OFFSET ] & ISAKMP_FLAG_ENCRYPT ) ) return LIBIKE_OK; log.bin( LLOG_DEBUG, LLOG_DECODE, iv->buff(), iv->size(), ">= : encrypt iv" ); log.bin( LLOG_DEBUG, LLOG_DECODE, packet.buff(), packet.size(), "== : encrypt packet" ); // // determine pad length // size_t plen = size - sizeof( IKE_HEADER ); size_t blen = EVP_CIPHER_block_size( sa->evp_cipher ); size_t padd = 0; if( plen % blen ) padd += blen - ( plen % blen ); packet.add_null( padd ); data = packet.buff(); size = packet.size(); // // set new packet length in header // IKE_HEADER * header = ( IKE_HEADER * ) packet.buff(); header->length = htonl( ( uint32_t ) size ); // // init cipher key and iv and // encrypt all but header // EVP_CIPHER_CTX ctx_cipher; EVP_CIPHER_CTX_init( &ctx_cipher ); EVP_CipherInit_ex( &ctx_cipher, sa->evp_cipher, NULL, NULL, NULL, 1 ); EVP_CIPHER_CTX_set_key_length( &ctx_cipher, ( int ) sa->key.size() ); EVP_CipherInit_ex( &ctx_cipher, NULL, NULL, sa->key.buff(), iv->buff(), 1 ); EVP_Cipher( &ctx_cipher, data + sizeof( IKE_HEADER ), data + sizeof( IKE_HEADER ), ( int ) size - sizeof( IKE_HEADER ) ); EVP_CIPHER_CTX_cleanup( &ctx_cipher ); // // store cipher iv data // memcpy( iv->buff(), data + size - iv->size(), iv->size() ); log.bin( LLOG_DEBUG, LLOG_DECODE, iv->buff(), iv->size(), "== : stored iv" ); return LIBIKE_OK; }
static EVP_PKEY *do_PVK_body(const unsigned char **in, unsigned int saltlen, unsigned int keylen, pem_password_cb *cb, void *u) { EVP_PKEY *ret = NULL; const unsigned char *p = *in; unsigned int magic; unsigned char *enctmp = NULL, *q; EVP_CIPHER_CTX cctx; EVP_CIPHER_CTX_init(&cctx); if (saltlen) { char psbuf[PEM_BUFSIZE]; unsigned char keybuf[20]; int enctmplen, inlen; if (cb) inlen = cb(psbuf, PEM_BUFSIZE, 0, u); else inlen = PEM_def_callback(psbuf, PEM_BUFSIZE, 0, u); if (inlen <= 0) { PEMerr(PEM_F_DO_PVK_BODY, PEM_R_BAD_PASSWORD_READ); return NULL; } enctmp = OPENSSL_malloc(keylen + 8); if (!enctmp) { PEMerr(PEM_F_DO_PVK_BODY, ERR_R_MALLOC_FAILURE); return NULL; } if (!derive_pvk_key(keybuf, p, saltlen, (unsigned char *)psbuf, inlen)) return NULL; p += saltlen; /* Copy BLOBHEADER across, decrypt rest */ memcpy(enctmp, p, 8); p += 8; if (keylen < 8) { PEMerr(PEM_F_DO_PVK_BODY, PEM_R_PVK_TOO_SHORT); return NULL; } inlen = keylen - 8; q = enctmp + 8; if (!EVP_DecryptInit_ex(&cctx, EVP_rc4(), NULL, keybuf, NULL)) goto err; if (!EVP_DecryptUpdate(&cctx, q, &enctmplen, p, inlen)) goto err; if (!EVP_DecryptFinal_ex(&cctx, q + enctmplen, &enctmplen)) goto err; magic = read_ledword((const unsigned char **)&q); if (magic != MS_RSA2MAGIC && magic != MS_DSS2MAGIC) { q = enctmp + 8; memset(keybuf + 5, 0, 11); if (!EVP_DecryptInit_ex(&cctx, EVP_rc4(), NULL, keybuf, NULL)) goto err; OPENSSL_cleanse(keybuf, 20); if (!EVP_DecryptUpdate(&cctx, q, &enctmplen, p, inlen)) goto err; if (!EVP_DecryptFinal_ex(&cctx, q + enctmplen, &enctmplen)) goto err; magic = read_ledword((const unsigned char **)&q); if (magic != MS_RSA2MAGIC && magic != MS_DSS2MAGIC) { PEMerr(PEM_F_DO_PVK_BODY, PEM_R_BAD_DECRYPT); goto err; } } else OPENSSL_cleanse(keybuf, 20); p = enctmp; } ret = b2i_PrivateKey(&p, keylen); err: EVP_CIPHER_CTX_cleanup(&cctx); OPENSSL_free(enctmp); return ret; }
void cipher_context_init(cipher_ctx_t *ctx, int method, int enc) { if (method <= TABLE || method >= CIPHER_NUM) { LOGE("cipher_context_init(): Illegal method"); return; } if (method >= SALSA20) { enc_iv_len = supported_ciphers_iv_size[method]; return; } const char *ciphername = supported_ciphers[method]; #if defined(USE_CRYPTO_APPLECC) cipher_cc_t *cc = &ctx->cc; cc->cryptor = NULL; cc->cipher = supported_ciphers_applecc[method]; if (cc->cipher == kCCAlgorithmInvalid) { cc->valid = kCCContextInvalid; } else { cc->valid = kCCContextValid; if (cc->cipher == kCCAlgorithmRC4) { cc->mode = kCCModeRC4; cc->padding = ccNoPadding; } else { cc->mode = kCCModeCFB; cc->padding = ccPKCS7Padding; } return; } #endif cipher_evp_t *evp = &ctx->evp; const cipher_kt_t *cipher = get_cipher_type(method); #if defined(USE_CRYPTO_OPENSSL) if (cipher == NULL) { LOGE("Cipher %s not found in OpenSSL library", ciphername); FATAL("Cannot initialize cipher"); } EVP_CIPHER_CTX_init(evp); if (!EVP_CipherInit_ex(evp, cipher, NULL, NULL, NULL, enc)) { LOGE("Cannot initialize cipher %s", ciphername); exit(EXIT_FAILURE); } if (!EVP_CIPHER_CTX_set_key_length(evp, enc_key_len)) { EVP_CIPHER_CTX_cleanup(evp); LOGE("Invalid key length: %d", enc_key_len); exit(EXIT_FAILURE); } if (method > RC4_MD5) { EVP_CIPHER_CTX_set_padding(evp, 1); } #elif defined(USE_CRYPTO_POLARSSL) if (cipher == NULL) { LOGE("Cipher %s not found in PolarSSL library", ciphername); FATAL("Cannot initialize PolarSSL cipher"); } if (cipher_init_ctx(evp, cipher) != 0) { FATAL("Cannot initialize PolarSSL cipher context"); } #elif defined(USE_CRYPTO_MBEDTLS) // XXX: mbedtls_cipher_setup future change // NOTE: Currently also clears structure. In future versions you will be required to call // mbedtls_cipher_init() on the structure first. // void mbedtls_cipher_init( mbedtls_cipher_context_t *ctx ); if (cipher == NULL) { LOGE("Cipher %s not found in mbed TLS library", ciphername); FATAL("Cannot initialize mbed TLS cipher"); } mbedtls_cipher_init(evp); if (mbedtls_cipher_setup(evp, cipher) != 0) { FATAL("Cannot initialize mbed TLS cipher context"); } #endif }
OM_uint32 _gssapi_get_mic_arcfour(OM_uint32 * minor_status, const gsskrb5_ctx context_handle, krb5_context context, gss_qop_t qop_req, const gss_buffer_t message_buffer, gss_buffer_t message_token, krb5_keyblock *key) { krb5_error_code ret; int32_t seq_number; size_t len, total_len; u_char k6_data[16], *p0, *p; EVP_CIPHER_CTX rc4_key; _gsskrb5_encap_length (22, &len, &total_len, GSS_KRB5_MECHANISM); message_token->length = total_len; message_token->value = malloc (total_len); if (message_token->value == NULL) { *minor_status = ENOMEM; return GSS_S_FAILURE; } p0 = _gssapi_make_mech_header(message_token->value, len, GSS_KRB5_MECHANISM); p = p0; *p++ = 0x01; /* TOK_ID */ *p++ = 0x01; *p++ = 0x11; /* SGN_ALG */ *p++ = 0x00; *p++ = 0xff; /* Filler */ *p++ = 0xff; *p++ = 0xff; *p++ = 0xff; p = NULL; ret = arcfour_mic_cksum(context, key, KRB5_KU_USAGE_SIGN, p0 + 16, 8, /* SGN_CKSUM */ p0, 8, /* TOK_ID, SGN_ALG, Filer */ message_buffer->value, message_buffer->length, NULL, 0); if (ret) { _gsskrb5_release_buffer(minor_status, message_token); *minor_status = ret; return GSS_S_FAILURE; } ret = arcfour_mic_key(context, key, p0 + 16, 8, /* SGN_CKSUM */ k6_data, sizeof(k6_data)); if (ret) { _gsskrb5_release_buffer(minor_status, message_token); *minor_status = ret; return GSS_S_FAILURE; } HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex); krb5_auth_con_getlocalseqnumber (context, context_handle->auth_context, &seq_number); p = p0 + 8; /* SND_SEQ */ _gsskrb5_encode_be_om_uint32(seq_number, p); krb5_auth_con_setlocalseqnumber (context, context_handle->auth_context, ++seq_number); HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); memset (p + 4, (context_handle->more_flags & LOCAL) ? 0 : 0xff, 4); EVP_CIPHER_CTX_init(&rc4_key); EVP_CipherInit_ex(&rc4_key, EVP_rc4(), NULL, k6_data, NULL, 1); EVP_Cipher(&rc4_key, p, p, 8); EVP_CIPHER_CTX_cleanup(&rc4_key); memset(k6_data, 0, sizeof(k6_data)); *minor_status = 0; return GSS_S_COMPLETE; }
void cipher_context_set_iv(cipher_ctx_t *ctx, uint8_t *iv, size_t iv_len, int enc) { const unsigned char *true_key; if (iv == NULL) { LOGE("cipher_context_set_iv(): IV is null"); return; } if (!enc) { memcpy(ctx->iv, iv, iv_len); } if (enc_method >= SALSA20) { return; } if (enc_method == RC4_MD5) { unsigned char key_iv[32]; memcpy(key_iv, enc_key, 16); memcpy(key_iv + 16, iv, 16); true_key = enc_md5(key_iv, 32, NULL); iv_len = 0; } else { true_key = enc_key; } #ifdef USE_CRYPTO_APPLECC cipher_cc_t *cc = &ctx->cc; if (cc->valid == kCCContextValid) { memcpy(cc->iv, iv, iv_len); memcpy(cc->key, true_key, enc_key_len); cc->iv_len = iv_len; cc->key_len = enc_key_len; cc->encrypt = enc ? kCCEncrypt : kCCDecrypt; if (cc->cryptor != NULL) { CCCryptorRelease(cc->cryptor); cc->cryptor = NULL; } CCCryptorStatus ret; ret = CCCryptorCreateWithMode( cc->encrypt, cc->mode, cc->cipher, cc->padding, cc->iv, cc->key, cc->key_len, NULL, 0, 0, 0, &cc->cryptor); if (ret != kCCSuccess) { if (cc->cryptor != NULL) { CCCryptorRelease(cc->cryptor); cc->cryptor = NULL; } FATAL("Cannot set CommonCrypto key and IV"); } return; } #endif cipher_evp_t *evp = &ctx->evp; if (evp == NULL) { LOGE("cipher_context_set_iv(): Cipher context is null"); return; } #if defined(USE_CRYPTO_OPENSSL) if (!EVP_CipherInit_ex(evp, NULL, NULL, true_key, iv, enc)) { EVP_CIPHER_CTX_cleanup(evp); FATAL("Cannot set key and IV"); } #elif defined(USE_CRYPTO_POLARSSL) // XXX: PolarSSL 1.3.11: cipher_free_ctx deprecated, Use cipher_free() instead. if (cipher_setkey(evp, true_key, enc_key_len * 8, enc) != 0) { cipher_free_ctx(evp); FATAL("Cannot set PolarSSL cipher key"); } #if POLARSSL_VERSION_NUMBER >= 0x01030000 if (cipher_set_iv(evp, iv, iv_len) != 0) { cipher_free_ctx(evp); FATAL("Cannot set PolarSSL cipher IV"); } if (cipher_reset(evp) != 0) { cipher_free_ctx(evp); FATAL("Cannot finalize PolarSSL cipher context"); } #else if (cipher_reset(evp, iv) != 0) { cipher_free_ctx(evp); FATAL("Cannot set PolarSSL cipher IV"); } #endif #elif defined(USE_CRYPTO_MBEDTLS) if (mbedtls_cipher_setkey(evp, true_key, enc_key_len * 8, enc) != 0) { mbedtls_cipher_free(evp); FATAL("Cannot set mbed TLS cipher key"); } if (mbedtls_cipher_set_iv(evp, iv, iv_len) != 0) { mbedtls_cipher_free(evp); FATAL("Cannot set mbed TLS cipher IV"); } if (mbedtls_cipher_reset(evp) != 0) { mbedtls_cipher_free(evp); FATAL("Cannot finalize mbed TLS cipher context"); } #endif #ifdef DEBUG dump("IV", (char *)iv, iv_len); #endif }
OM_uint32 _gssapi_wrap_arcfour(OM_uint32 * minor_status, const gsskrb5_ctx context_handle, krb5_context context, int conf_req_flag, gss_qop_t qop_req, const gss_buffer_t input_message_buffer, int * conf_state, gss_buffer_t output_message_buffer, krb5_keyblock *key) { u_char Klocaldata[16], k6_data[16], *p, *p0; size_t len, total_len, datalen; krb5_keyblock Klocal; krb5_error_code ret; int32_t seq_number; if (conf_state) *conf_state = 0; datalen = input_message_buffer->length; if (IS_DCE_STYLE(context_handle)) { len = GSS_ARCFOUR_WRAP_TOKEN_SIZE; _gssapi_encap_length(len, &len, &total_len, GSS_KRB5_MECHANISM); total_len += datalen; } else { datalen += 1; /* padding */ len = datalen + GSS_ARCFOUR_WRAP_TOKEN_SIZE; _gssapi_encap_length(len, &len, &total_len, GSS_KRB5_MECHANISM); } output_message_buffer->length = total_len; output_message_buffer->value = malloc (total_len); if (output_message_buffer->value == NULL) { *minor_status = ENOMEM; return GSS_S_FAILURE; } p0 = _gssapi_make_mech_header(output_message_buffer->value, len, GSS_KRB5_MECHANISM); p = p0; *p++ = 0x02; /* TOK_ID */ *p++ = 0x01; *p++ = 0x11; /* SGN_ALG */ *p++ = 0x00; if (conf_req_flag) { *p++ = 0x10; /* SEAL_ALG */ *p++ = 0x00; } else { *p++ = 0xff; /* SEAL_ALG */ *p++ = 0xff; } *p++ = 0xff; /* Filler */ *p++ = 0xff; p = NULL; HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex); krb5_auth_con_getlocalseqnumber (context, context_handle->auth_context, &seq_number); _gsskrb5_encode_be_om_uint32(seq_number, p0 + 8); krb5_auth_con_setlocalseqnumber (context, context_handle->auth_context, ++seq_number); HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); memset (p0 + 8 + 4, (context_handle->more_flags & LOCAL) ? 0 : 0xff, 4); krb5_generate_random_block(p0 + 24, 8); /* fill in Confounder */ /* p points to data */ p = p0 + GSS_ARCFOUR_WRAP_TOKEN_SIZE; memcpy(p, input_message_buffer->value, input_message_buffer->length); if (!IS_DCE_STYLE(context_handle)) p[input_message_buffer->length] = 1; /* padding */ ret = arcfour_mic_cksum(context, key, KRB5_KU_USAGE_SEAL, p0 + 16, 8, /* SGN_CKSUM */ p0, 8, /* TOK_ID, SGN_ALG, SEAL_ALG, Filler */ p0 + 24, 8, /* Confounder */ p0 + GSS_ARCFOUR_WRAP_TOKEN_SIZE, datalen); if (ret) { *minor_status = ret; _gsskrb5_release_buffer(minor_status, output_message_buffer); return GSS_S_FAILURE; } { int i; Klocal.keytype = key->keytype; Klocal.keyvalue.data = Klocaldata; Klocal.keyvalue.length = sizeof(Klocaldata); for (i = 0; i < 16; i++) Klocaldata[i] = ((u_char *)key->keyvalue.data)[i] ^ 0xF0; } ret = arcfour_mic_key(context, &Klocal, p0 + 8, 4, /* SND_SEQ */ k6_data, sizeof(k6_data)); memset(Klocaldata, 0, sizeof(Klocaldata)); if (ret) { _gsskrb5_release_buffer(minor_status, output_message_buffer); *minor_status = ret; return GSS_S_FAILURE; } if(conf_req_flag) { EVP_CIPHER_CTX rc4_key; EVP_CIPHER_CTX_init(&rc4_key); EVP_CipherInit_ex(&rc4_key, EVP_rc4(), NULL, k6_data, NULL, 1); EVP_Cipher(&rc4_key, p0 + 24, p0 + 24, 8 + datalen); EVP_CIPHER_CTX_cleanup(&rc4_key); } memset(k6_data, 0, sizeof(k6_data)); ret = arcfour_mic_key(context, key, p0 + 16, 8, /* SGN_CKSUM */ k6_data, sizeof(k6_data)); if (ret) { _gsskrb5_release_buffer(minor_status, output_message_buffer); *minor_status = ret; return GSS_S_FAILURE; } { EVP_CIPHER_CTX rc4_key; EVP_CIPHER_CTX_init(&rc4_key); EVP_CipherInit_ex(&rc4_key, EVP_rc4(), NULL, k6_data, NULL, 1); EVP_Cipher(&rc4_key, p0 + 8, p0 + 8 /* SND_SEQ */, 8); EVP_CIPHER_CTX_cleanup(&rc4_key); memset(k6_data, 0, sizeof(k6_data)); } if (conf_state) *conf_state = conf_req_flag; *minor_status = 0; return GSS_S_COMPLETE; }
static void gst_hls_demux_decrypt_end (GstHLSDemux * demux) { EVP_CIPHER_CTX_cleanup (&demux->aes_ctx); }
unsigned char *rncryptorc_decrypt_data_with_key(const unsigned char *indata, int indata_len, int kdf_iter, const unsigned char *encr_key, const unsigned char *hmac_key, int *outdata_len, char *errbuf, int errbuf_len) { MutilsBlob *blob = NULL; RNCryptorInfo *ci = NULL; int outlen1=0, outlen2=0; EVP_CIPHER_CTX cipher_ctx; unsigned char *outdata = NULL; if (errbuf_len <= 0) { log_err("ERROR:Invalid errbuf len %d",errbuf_len); goto ExitProcessing; } memset(errbuf,0,errbuf_len); if (indata == NULL) { (void)snprintf(errbuf,errbuf_len-1,"%s", "input data is NULL"); goto ExitProcessing; } if (encr_key == NULL) { (void)snprintf(errbuf,errbuf_len-1,"%s", "Encryption key is NULL"); goto ExitProcessing; } if (hmac_key == NULL) { (void)snprintf(errbuf,errbuf_len-1,"%s", "HMAC key is NULL"); goto ExitProcessing; } *outdata_len = 0; /* convert input data to our blob */ blob = mutils_data_to_blob((unsigned char *)indata,indata_len); CHECK_MALLOC(blob); /* decode */ ci = decode_encrypted_blob(blob); if (!ci) { goto ExitProcessing; } log_debug("Decoded successfully"); /* ** copy the keys to our data structure, this way we don't have ** to change code for decryptiion */ memcpy(ci->encr_key,encr_key,32); memcpy(ci->hmac_key,hmac_key,32); /* ** pass password as NULL and length of password as 0 because we don't ** have to derive HMAC key */ if (verify_hmac(ci,NULL,0) != SUCCESS) { (void)snprintf(errbuf,errbuf_len-1,"%s", "Could not verify HMAC"); goto ExitProcessing; } log_debug("HMAC verified"); /* malloc for returned data */ outdata = (unsigned char *)malloc(ci->cipher_text_length *sizeof(unsigned char)); CHECK_MALLOC(outdata); /* decrypt */ EVP_DecryptInit(&cipher_ctx,EVP_aes_256_cbc(),ci->encr_key,ci->iv); EVP_DecryptUpdate(&cipher_ctx,outdata,&outlen1,ci->cipher_text, ci->cipher_text_length); EVP_DecryptFinal(&cipher_ctx,outdata + outlen1,&outlen2); EVP_CIPHER_CTX_cleanup(&cipher_ctx); *outdata_len = outlen1 + outlen2; ExitProcessing: if (ci) { free_rncryptor_info(ci); } if (blob) { mutils_destroy_blob(blob); } return(outdata); }
void crypto_des3_free(CryptoDes3 des3) { EVP_CIPHER_CTX_cleanup(&des3->des3_ctx); xfree(des3); }
unsigned char *rncryptorc_encrypt_data_with_key_iv(const unsigned char *indata, int indata_len, int kdf_iter, const unsigned char *encr_key_32, const unsigned char *hmac_key_32, const unsigned char *iv_16, int *outdata_len, char *errbuf, int errbuf_len) { RNCryptorInfo *ci = NULL; MutilsBlob *blob = NULL; EVP_CIPHER_CTX cipher_ctx; HMAC_CTX hmac_ctx; const EVP_MD *sha256 = NULL; int outlen1 = 0, outlen2 = 0; unsigned int hmac_len; unsigned char hmac_sha256[32]; unsigned char *output = NULL; unsigned int blocksize = 16; unsigned char *ciphertext = NULL; int ciphertext_length; log_debug("%s:%d - verifying input",MCFL); if (errbuf_len <= 0) { log_err("ERROR:Invalid errbuf len %d",errbuf_len); goto ExitProcessing; } memset(errbuf,0,errbuf_len); EVP_EncryptInit(&cipher_ctx,EVP_aes_256_cbc(),encr_key_32,iv_16); blocksize = EVP_CIPHER_CTX_block_size(&cipher_ctx); log_debug("%s:%d - Block size: %ld",MCFL,blocksize); if (indata == NULL && indata_len == 0) { /* memory will be re-allocated as needed */ blob = mutils_allocate_blob(blocksize); } else { /* memory will be re-allocated as needed */ blob = mutils_allocate_blob(indata_len); } CHECK_MALLOC(blob); log_debug("%s:%d - input data size %d bytes", MCFL, indata_len); ci = allocate_rncryptor_info(); if (!ci) { goto ExitProcessing; } /* version */ mutils_write_blob_byte(blob,ci->version); /* options */ ci->options = 0x00; mutils_write_blob_byte(blob,ci->options); /* 16 byte iv */ mutils_write_blob(blob,16,iv_16); log_debug(":%s:%d - Encrypting,",MCFL); /* allocate space for cipher text */ ciphertext_length = indata_len + blocksize - (indata_len % blocksize); ciphertext = (unsigned char *) malloc(ciphertext_length * sizeof(unsigned char)); CHECK_MALLOC(ciphertext); log_debug("%s:%d - Plain text length: %d",MCFL,indata_len); log_debug("%s:%d - Cipther text length: %d",MCFL,ciphertext_length); log_debug("%s:%d - Padding %d bytes", MCFL,(ciphertext_length - indata_len)); EVP_EncryptUpdate(&cipher_ctx,ciphertext,&outlen1,indata,indata_len); EVP_EncryptFinal(&cipher_ctx,ciphertext + outlen1,&outlen2); EVP_CIPHER_CTX_cleanup(&cipher_ctx); mutils_write_blob(blob,outlen1 + outlen2,ciphertext); /* calculate HMAC-SHA256 */ sha256 = EVP_sha256(); HMAC_CTX_init(&hmac_ctx); HMAC_Init(&hmac_ctx,hmac_key_32,32,sha256); HMAC_Update(&hmac_ctx,blob->data,blob->length); HMAC_Final(&hmac_ctx,hmac_sha256,&hmac_len); HMAC_CTX_cleanup(&hmac_ctx); mutils_write_blob(blob,hmac_len,hmac_sha256); output = (unsigned char *)malloc(blob->length * sizeof(unsigned char)); CHECK_MALLOC(output); memcpy(output,blob->data,blob->length); *outdata_len = blob->length; ExitProcessing: if (ci) { free_rncryptor_info(ci); } if (blob) { mutils_destroy_blob(blob); } if (ciphertext) { (void) free((char *)ciphertext); } return(output); }
void psAesClearCBC(psAesCbc_t *ctx) { EVP_CIPHER_CTX_cleanup(ctx); }
static int s2n_cbc_cipher_3des_destroy_key(struct s2n_session_key *key) { EVP_CIPHER_CTX_cleanup(key->evp_cipher_ctx); return 0; }
X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter, unsigned char *salt, int saltlen, unsigned char *aiv, int prf_nid) { X509_ALGOR *scheme = NULL, *kalg = NULL, *ret = NULL; int alg_nid, keylen; EVP_CIPHER_CTX ctx; unsigned char iv[EVP_MAX_IV_LENGTH]; PBE2PARAM *pbe2 = NULL; const ASN1_OBJECT *obj; alg_nid = EVP_CIPHER_nid(cipher); if(alg_nid == NID_undef) { OPENSSL_PUT_ERROR(PKCS8, PKCS5_pbe2_set_iv, PKCS8_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER); goto err; } obj = OBJ_nid2obj(alg_nid); if(!(pbe2 = PBE2PARAM_new())) goto merr; /* Setup the AlgorithmIdentifier for the encryption scheme */ scheme = pbe2->encryption; scheme->algorithm = (ASN1_OBJECT*) obj; if(!(scheme->parameter = ASN1_TYPE_new())) goto merr; /* Create random IV */ if (EVP_CIPHER_iv_length(cipher)) { if (aiv) memcpy(iv, aiv, EVP_CIPHER_iv_length(cipher)); else if (RAND_pseudo_bytes(iv, EVP_CIPHER_iv_length(cipher)) < 0) goto err; } EVP_CIPHER_CTX_init(&ctx); /* Dummy cipherinit to just setup the IV, and PRF */ if (!EVP_CipherInit_ex(&ctx, cipher, NULL, NULL, iv, 0)) goto err; if(param_to_asn1(&ctx, scheme->parameter) < 0) { OPENSSL_PUT_ERROR(PKCS8, PKCS5_pbe2_set_iv, PKCS8_R_ERROR_SETTING_CIPHER_PARAMS); EVP_CIPHER_CTX_cleanup(&ctx); goto err; } /* If prf NID unspecified see if cipher has a preference. * An error is OK here: just means use default PRF. */ if ((prf_nid == -1) && EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_PBE_PRF_NID, 0, &prf_nid) <= 0) { ERR_clear_error(); prf_nid = NID_hmacWithSHA1; } EVP_CIPHER_CTX_cleanup(&ctx); /* If its RC2 then we'd better setup the key length */ if(alg_nid == NID_rc2_cbc) keylen = EVP_CIPHER_key_length(cipher); else keylen = -1; /* Setup keyfunc */ X509_ALGOR_free(pbe2->keyfunc); pbe2->keyfunc = PKCS5_pbkdf2_set(iter, salt, saltlen, prf_nid, keylen); if (!pbe2->keyfunc) goto merr; /* Now set up top level AlgorithmIdentifier */ if(!(ret = X509_ALGOR_new())) goto merr; if(!(ret->parameter = ASN1_TYPE_new())) goto merr; ret->algorithm = (ASN1_OBJECT*) OBJ_nid2obj(NID_pbes2); /* Encode PBE2PARAM into parameter */ if(!ASN1_item_pack(pbe2, ASN1_ITEM_rptr(PBE2PARAM), &ret->parameter->value.sequence)) goto merr; ret->parameter->type = V_ASN1_SEQUENCE; PBE2PARAM_free(pbe2); pbe2 = NULL; return ret; merr: OPENSSL_PUT_ERROR(PKCS8, PKCS5_pbe2_set_iv, ERR_R_MALLOC_FAILURE); err: PBE2PARAM_free(pbe2); /* Note 'scheme' is freed as part of pbe2 */ X509_ALGOR_free(kalg); X509_ALGOR_free(ret); return NULL; }
static void aes_cbc_encrypt_cleanup(aes_cbc_encrypt_context_t* state) { EVP_CIPHER_CTX_cleanup(&state->cipher); }
Blob decryptECIES (const openssl::ec_key& secretKey, const openssl::ec_key& publicKey, Blob const& ciphertext) { // minimum ciphertext = IV + HMAC + 1 block if (ciphertext.size () < ((2 * ECIES_ENC_BLK_SIZE) + ECIES_HMAC_SIZE) ) throw std::runtime_error ("ciphertext too short"); // extract IV ECIES_ENC_IV_TYPE iv; memcpy (iv.begin (), & (ciphertext.front ()), ECIES_ENC_BLK_SIZE); // begin decrypting EVP_CIPHER_CTX ctx; EVP_CIPHER_CTX_init (&ctx); ECIES_ENC_KEY_TYPE secret; ECIES_HMAC_KEY_TYPE hmacKey; getECIESSecret (secretKey, publicKey, secret, hmacKey); if (EVP_DecryptInit_ex (&ctx, ECIES_ENC_ALGO, nullptr, secret.begin (), iv.begin ()) != 1) { secret.zero (); hmacKey.zero (); EVP_CIPHER_CTX_cleanup (&ctx); throw std::runtime_error ("unable to init cipher"); } // decrypt mac ECIES_HMAC_TYPE hmac; int outlen = ECIES_HMAC_SIZE; if ( (EVP_DecryptUpdate (&ctx, hmac.begin (), &outlen, & (ciphertext.front ()) + ECIES_ENC_BLK_SIZE, ECIES_HMAC_SIZE + 1) != 1) || (outlen != ECIES_HMAC_SIZE) ) { secret.zero (); hmacKey.zero (); EVP_CIPHER_CTX_cleanup (&ctx); throw std::runtime_error ("unable to extract hmac"); } // decrypt plaintext (after IV and encrypted mac) Blob plaintext (ciphertext.size () - ECIES_HMAC_SIZE - ECIES_ENC_BLK_SIZE); outlen = plaintext.size (); if (EVP_DecryptUpdate (&ctx, & (plaintext.front ()), &outlen, & (ciphertext.front ()) + ECIES_ENC_BLK_SIZE + ECIES_HMAC_SIZE + 1, ciphertext.size () - ECIES_ENC_BLK_SIZE - ECIES_HMAC_SIZE - 1) != 1) { secret.zero (); hmacKey.zero (); EVP_CIPHER_CTX_cleanup (&ctx); throw std::runtime_error ("unable to extract plaintext"); } // decrypt padding int flen = 0; if (EVP_DecryptFinal (&ctx, & (plaintext.front ()) + outlen, &flen) != 1) { secret.zero (); hmacKey.zero (); EVP_CIPHER_CTX_cleanup (&ctx); throw std::runtime_error ("plaintext had bad padding"); } plaintext.resize (flen + outlen); // verify integrity if (hmac != makeHMAC (hmacKey, plaintext)) { secret.zero (); hmacKey.zero (); EVP_CIPHER_CTX_cleanup (&ctx); throw std::runtime_error ("plaintext had bad hmac"); } secret.zero (); hmacKey.zero (); EVP_CIPHER_CTX_cleanup (&ctx); return plaintext; }