int tls1_change_cipher_state(SSL *s, int which) { static const unsigned char empty[]=""; unsigned char *p,*key_block,*mac_secret; unsigned char *exp_label; unsigned char tmp1[EVP_MAX_KEY_LENGTH]; unsigned char tmp2[EVP_MAX_KEY_LENGTH]; unsigned char iv1[EVP_MAX_IV_LENGTH*2]; unsigned char iv2[EVP_MAX_IV_LENGTH*2]; unsigned char *ms,*key,*iv,*er1,*er2; int client_write; EVP_CIPHER_CTX *dd; const EVP_CIPHER *c; #ifndef OPENSSL_NO_COMP const SSL_COMP *comp; #endif const EVP_MD *m; int mac_type; int *mac_secret_size; EVP_MD_CTX *mac_ctx; EVP_PKEY *mac_key; int is_export,n,i,j,k,exp_label_len,cl; int reuse_dd = 0; is_export=SSL_C_IS_EXPORT(s->s3->tmp.new_cipher); c=s->s3->tmp.new_sym_enc; m=s->s3->tmp.new_hash; mac_type = s->s3->tmp.new_mac_pkey_type; #ifndef OPENSSL_NO_COMP comp=s->s3->tmp.new_compression; #endif key_block=s->s3->tmp.key_block; #ifdef KSSL_DEBUG printf("tls1_change_cipher_state(which= %d) w/\n", which); printf("\talg= %ld/%ld, comp= %p\n", s->s3->tmp.new_cipher->algorithm_mkey, s->s3->tmp.new_cipher->algorithm_auth, comp); printf("\tevp_cipher == %p ==? &d_cbc_ede_cipher3\n", c); printf("\tevp_cipher: nid, blksz= %d, %d, keylen=%d, ivlen=%d\n", c->nid,c->block_size,c->key_len,c->iv_len); printf("\tkey_block: len= %d, data= ", s->s3->tmp.key_block_length); { int i; for (i=0; i<s->s3->tmp.key_block_length; i++) printf("%02x", key_block[i]); printf("\n"); } #endif /* KSSL_DEBUG */ if (which & SSL3_CC_READ) { if (s->s3->tmp.new_cipher->algorithm2 & TLS1_STREAM_MAC) s->mac_flags |= SSL_MAC_FLAG_READ_MAC_STREAM; else s->mac_flags &= ~SSL_MAC_FLAG_READ_MAC_STREAM; if (s->enc_read_ctx != NULL) reuse_dd = 1; else if ((s->enc_read_ctx=OPENSSL_malloc(sizeof(EVP_CIPHER_CTX))) == NULL) goto err; else /* make sure it's intialized in case we exit later with an error */ EVP_CIPHER_CTX_init(s->enc_read_ctx); dd= s->enc_read_ctx; mac_ctx=ssl_replace_hash(&s->read_hash,NULL); #ifndef OPENSSL_NO_COMP if (s->expand != NULL) { COMP_CTX_free(s->expand); s->expand=NULL; } if (comp != NULL) { s->expand=COMP_CTX_new(comp->method); if (s->expand == NULL) { SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE,SSL_R_COMPRESSION_LIBRARY_ERROR); goto err2; } if (s->s3->rrec.comp == NULL) s->s3->rrec.comp=(unsigned char *) OPENSSL_malloc(SSL3_RT_MAX_ENCRYPTED_LENGTH); if (s->s3->rrec.comp == NULL) goto err; } #endif /* this is done by dtls1_reset_seq_numbers for DTLS1_VERSION */ if (s->version != DTLS1_VERSION) memset(&(s->s3->read_sequence[0]),0,8); mac_secret= &(s->s3->read_mac_secret[0]); mac_secret_size=&(s->s3->read_mac_secret_size); } else { if (s->s3->tmp.new_cipher->algorithm2 & TLS1_STREAM_MAC) s->mac_flags |= SSL_MAC_FLAG_WRITE_MAC_STREAM; else s->mac_flags &= ~SSL_MAC_FLAG_WRITE_MAC_STREAM; if (s->enc_write_ctx != NULL) reuse_dd = 1; else if ((s->enc_write_ctx=OPENSSL_malloc(sizeof(EVP_CIPHER_CTX))) == NULL) goto err; else /* make sure it's intialized in case we exit later with an error */ EVP_CIPHER_CTX_init(s->enc_write_ctx); dd= s->enc_write_ctx; mac_ctx = ssl_replace_hash(&s->write_hash,NULL); #ifndef OPENSSL_NO_COMP if (s->compress != NULL) { COMP_CTX_free(s->compress); s->compress=NULL; } if (comp != NULL) { s->compress=COMP_CTX_new(comp->method); if (s->compress == NULL) { SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE,SSL_R_COMPRESSION_LIBRARY_ERROR); goto err2; } } #endif /* this is done by dtls1_reset_seq_numbers for DTLS1_VERSION */ if (s->version != DTLS1_VERSION) memset(&(s->s3->write_sequence[0]),0,8); mac_secret= &(s->s3->write_mac_secret[0]); mac_secret_size = &(s->s3->write_mac_secret_size); } if (reuse_dd) EVP_CIPHER_CTX_cleanup(dd); p=s->s3->tmp.key_block; i=*mac_secret_size=s->s3->tmp.new_mac_secret_size; cl=EVP_CIPHER_key_length(c); j=is_export ? (cl < SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher) ? cl : SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher)) : cl; /* Was j=(exp)?5:EVP_CIPHER_key_length(c); */ k=EVP_CIPHER_iv_length(c); er1= &(s->s3->client_random[0]); er2= &(s->s3->server_random[0]); if ( (which == SSL3_CHANGE_CIPHER_CLIENT_WRITE) || (which == SSL3_CHANGE_CIPHER_SERVER_READ)) { ms= &(p[ 0]); n=i+i; key= &(p[ n]); n+=j+j; iv= &(p[ n]); n+=k+k; exp_label=(unsigned char *)TLS_MD_CLIENT_WRITE_KEY_CONST; exp_label_len=TLS_MD_CLIENT_WRITE_KEY_CONST_SIZE; client_write=1; } else { n=i; ms= &(p[ n]); n+=i+j; key= &(p[ n]); n+=j+k; iv= &(p[ n]); n+=k; exp_label=(unsigned char *)TLS_MD_SERVER_WRITE_KEY_CONST; exp_label_len=TLS_MD_SERVER_WRITE_KEY_CONST_SIZE; client_write=0; } if (n > s->s3->tmp.key_block_length) { SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE,ERR_R_INTERNAL_ERROR); goto err2; } memcpy(mac_secret,ms,i); mac_key = EVP_PKEY_new_mac_key(mac_type, NULL, mac_secret,*mac_secret_size); EVP_DigestSignInit(mac_ctx,NULL,m,NULL,mac_key); EVP_PKEY_free(mac_key); #ifdef TLS_DEBUG printf("which = %04X\nmac key=",which); { int z; for (z=0; z<i; z++) printf("%02X%c",ms[z],((z+1)%16)?' ':'\n'); } #endif if (is_export) { /* In here I set both the read and write key/iv to the * same value since only the correct one will be used :-). */ tls1_PRF(s->s3->tmp.new_cipher->algorithm2, exp_label,exp_label_len, s->s3->client_random,SSL3_RANDOM_SIZE, s->s3->server_random,SSL3_RANDOM_SIZE, NULL,0,NULL,0, key,j,tmp1,tmp2,EVP_CIPHER_key_length(c)); key=tmp1; if (k > 0) { tls1_PRF(s->s3->tmp.new_cipher->algorithm2, TLS_MD_IV_BLOCK_CONST,TLS_MD_IV_BLOCK_CONST_SIZE, s->s3->client_random,SSL3_RANDOM_SIZE, s->s3->server_random,SSL3_RANDOM_SIZE, NULL,0,NULL,0, empty,0,iv1,iv2,k*2); if (client_write) iv=iv1; else iv= &(iv1[k]); } } s->session->key_arg_length=0; #ifdef KSSL_DEBUG { int i; printf("EVP_CipherInit_ex(dd,c,key=,iv=,which)\n"); printf("\tkey= "); for (i=0; i<c->key_len; i++) printf("%02x", key[i]); printf("\n"); printf("\t iv= "); for (i=0; i<c->iv_len; i++) printf("%02x", iv[i]); printf("\n"); } #endif /* KSSL_DEBUG */ EVP_CipherInit_ex(dd,c,NULL,key,iv,(which & SSL3_CC_WRITE)); #ifdef TLS_DEBUG printf("which = %04X\nkey=",which); { int z; for (z=0; z<EVP_CIPHER_key_length(c); z++) printf("%02X%c",key[z],((z+1)%16)?' ':'\n'); } printf("\niv="); { int z; for (z=0; z<k; z++) printf("%02X%c",iv[z],((z+1)%16)?' ':'\n'); } printf("\n"); #endif OPENSSL_cleanse(tmp1,sizeof(tmp1)); OPENSSL_cleanse(tmp2,sizeof(tmp1)); OPENSSL_cleanse(iv1,sizeof(iv1)); OPENSSL_cleanse(iv2,sizeof(iv2)); return(1); err: SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE,ERR_R_MALLOC_FAILURE); err2: return(0); }
SARC4::SARC4(uint8 len) { EVP_CIPHER_CTX_init(&m_ctx); EVP_EncryptInit_ex(&m_ctx, EVP_rc4(), NULL, NULL, NULL); EVP_CIPHER_CTX_set_key_length(&m_ctx, len); }
bool crypto_aes_decrypt(struct string *ciphertext, struct string *aes_key, struct string *aes_iv, struct string *decrypted) { bool retval = false; EVP_CIPHER_CTX ctx; int decryptspace; int decryptdone; EVP_CIPHER_CTX_init(&ctx); if (!EVP_DecryptInit_ex(&ctx, EVP_aes_256_cbc(), NULL, (unsigned char *)string_get(aes_key), (unsigned char *)string_get(aes_iv))) { log_err("crypto_aes_decrypt: init failed\n"); ERR_print_errors_fp(stderr); goto bail_out; } EVP_CIPHER_CTX_set_padding(&ctx, 1); if (string_length(aes_key) != EVP_CIPHER_CTX_key_length(&ctx)) { log_err("crypto_aes_decrypt: invalid key size (%" PRIuPTR " vs expected %d)\n", string_length(aes_key), EVP_CIPHER_CTX_key_length(&ctx)); goto bail_out; } if (string_length(aes_iv) != EVP_CIPHER_CTX_iv_length(&ctx)) { log_err("crypto_aes_decrypt: invalid iv size (%" PRIuPTR " vs expected %d)\n", string_length(aes_iv), EVP_CIPHER_CTX_iv_length(&ctx)); goto bail_out; } decryptspace = string_length(ciphertext) + EVP_MAX_BLOCK_LENGTH; string_free(decrypted); /* free previous buffer */ string_init(decrypted, decryptspace, 1024); if (string_size(decrypted) < decryptspace) { log_err("crypto_aes_decrypt: decrypt buffer malloc error\n"); goto bail_out; } if (EVP_DecryptUpdate(&ctx, (unsigned char*)string_get(decrypted), &decryptdone, (unsigned char*)string_get(ciphertext), string_length(ciphertext))) { /* TODO: need cleaner way: */ decrypted->_u._s.length = decryptdone; } else { log_err("crypto_aes_decrypt: decrypt failed\n"); ERR_print_errors_fp(stderr); goto bail_out; } if (EVP_DecryptFinal_ex(&ctx, (unsigned char*)string_get(decrypted)+string_length(decrypted), &decryptdone)) { /* TODO: need cleaner way: */ decrypted->_u._s.length += decryptdone; } else { log_err("crypto_aes_decrypt: decrypt final failed\n"); ERR_print_errors_fp(stderr); goto bail_out; } retval = true; bail_out: EVP_CIPHER_CTX_cleanup(&ctx); return retval; }
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_bytes(iv, EVP_CIPHER_iv_length(cipher))) 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; }
void AESCryptoKey::TransformBlock(bool encrypt, const uint8_t *pbIn, uint32_t cbIn, uint8_t *pbOut, uint32_t & cbOut, const uint8_t *pbIv, uint32_t cbIv) { if (pbIn == nullptr) { throw exceptions::RMSCryptoNullPointerException("Null pointer pbIn exception"); } if (pbOut == nullptr) { throw exceptions::RMSCryptoNullPointerException("Null pointer pbOut exception"); } if (((cbIv == 0) && (pbIv != nullptr)) || ((cbIv != 0) && (pbIv == nullptr))) { pbIv = nullptr; cbIv = 0; } int totalOut = static_cast<int>(cbOut); EVP_CIPHER_CTX ctx; EVP_CIPHER_CTX_init(&ctx); const EVP_CIPHER *cipher = nullptr; switch (m_algorithm) { case api::CRYPTO_ALGORITHM_AES_ECB: switch(m_key.size()) { case 16: cipher = EVP_aes_128_ecb(); break; case 24: cipher = EVP_aes_192_ecb(); break; case 32: cipher = EVP_aes_256_ecb(); break; default: throw exceptions::RMSCryptoInvalidArgumentException("Invalid key length"); } break; case api::CRYPTO_ALGORITHM_AES_CBC: case api::CRYPTO_ALGORITHM_AES_CBC_PKCS7: switch(m_key.size()) { case 16: cipher = EVP_aes_128_cbc(); break; case 24: cipher = EVP_aes_192_cbc(); break; case 32: cipher = EVP_aes_256_cbc(); break; default: throw exceptions::RMSCryptoInvalidArgumentException("Invalid key length"); } break; break; default: throw exceptions::RMSCryptoInvalidArgumentException("Unsupported algorithm"); } // check lengths if ((pbIv != nullptr) && (EVP_CIPHER_iv_length(cipher) != static_cast<int>(cbIv))) { throw exceptions::RMSCryptoInvalidArgumentException( "Invalid initial vector length"); } if (EVP_CIPHER_key_length(cipher) != static_cast<int>(m_key.size())) { throw exceptions::RMSCryptoInvalidArgumentException("Invalid key length"); } EVP_CipherInit_ex(&ctx, cipher, NULL, m_key.data(), pbIv, encrypt ? 1 : 0); if (m_algorithm == api::CRYPTO_ALGORITHM_AES_CBC_PKCS7) { EVP_CIPHER_CTX_set_padding(&ctx, 1); } else { EVP_CIPHER_CTX_set_padding(&ctx, 0); } if (!EVP_CipherUpdate(&ctx, pbOut, &totalOut, pbIn, static_cast<int>(cbIn))) { throw exceptions::RMSCryptoIOException( exceptions::RMSCryptoException::UnknownError, "Failed to transform data"); } pbOut += totalOut; // add padding if necessary if (m_algorithm == api::CRYPTO_ALGORITHM_AES_CBC_PKCS7) { int remain = cbOut - totalOut; if (remain < EVP_CIPHER_block_size(cipher)) { throw exceptions::RMSCryptoInsufficientBufferException( "No enough buffer size"); } if (!EVP_CipherFinal_ex(&ctx, pbOut, &remain)) { throw exceptions::RMSCryptoIOException( exceptions::RMSCryptoException::UnknownError, "Failed to transform final block"); } totalOut += remain; } EVP_CIPHER_CTX_cleanup(&ctx); // remember total size cbOut = static_cast<uint32_t>(totalOut); }
BST_STATIC BST_ERR_ENUM_UINT8 EncryptInternal ( BST_UINT8 *pucIn, BST_UINT32 ulInLen, BST_UINT8 *pucOut, BST_UINT32 *pulOutLen, BST_UINT8 *pucKey ) { BST_INT32 lLen; BST_UINT32 ulLenTest; BST_INT32 lRet; BST_UINT8 aucValue[8]; EVP_CIPHER_CTX Ctx; lLen = 0; ulLenTest = 0; lRet = 0; if ( ( BST_NULL_PTR == pucIn ) || ( BST_NULL_PTR == pucOut ) || ( BST_NULL_PTR == pucKey) || ( BST_NULL_PTR == pulOutLen ) ) { return BST_ERR_PARAM_ENCRYPTER; } EVP_CIPHER_CTX_init ( &Ctx ); lRet = EVP_EncryptInit_ex ( &Ctx, EVP_aes_128_ecb (), NULL, pucKey, aucValue ); if ( lRet != BST_CORE_OPENSSL_SUCCESS ) { return BST_ERR_PARAM_ENCRYPTER; } *pulOutLen = 0; lRet = EVP_EncryptUpdate ( &Ctx, pucOut + *pulOutLen, &lLen, pucIn + *pulOutLen, ulInLen ); if ( lRet != BST_CORE_OPENSSL_SUCCESS ) { return BST_ERR_PARAM_ENCRYPTER; } *pulOutLen += lLen; ulLenTest = ulInLen >> 4; if ( ulInLen != ulLenTest << 4 ) { lRet = EVP_EncryptFinal_ex ( &Ctx, pucOut + *pulOutLen, &lLen ); if ( lRet != BST_CORE_OPENSSL_SUCCESS ) { return BST_ERR_PARAM_ENCRYPTER; } *pulOutLen += lLen; } lRet = EVP_CIPHER_CTX_cleanup ( &Ctx ); if ( lRet != BST_CORE_OPENSSL_SUCCESS ) { return BST_ERR_PARAM_ENCRYPTER; } return BST_NO_ERROR_MSG; }
int ssl3_change_cipher_state(SSL *s, int which) { unsigned char *p, *mac_secret; unsigned char exp_key[EVP_MAX_KEY_LENGTH]; unsigned char exp_iv[EVP_MAX_IV_LENGTH]; unsigned char *ms, *key, *iv, *er1, *er2; EVP_CIPHER_CTX *dd; const EVP_CIPHER *c; #ifndef OPENSSL_NO_COMP COMP_METHOD *comp; #endif const EVP_MD *m; EVP_MD_CTX md; int is_exp, n, i, j, k, cl; int reuse_dd = 0; is_exp = SSL_C_IS_EXPORT(s->s3->tmp.new_cipher); c = s->s3->tmp.new_sym_enc; m = s->s3->tmp.new_hash; /* m == NULL will lead to a crash later */ OPENSSL_assert(m); #ifndef OPENSSL_NO_COMP if (s->s3->tmp.new_compression == NULL) comp = NULL; else comp = s->s3->tmp.new_compression->method; #endif if (which & SSL3_CC_READ) { if (s->enc_read_ctx != NULL) reuse_dd = 1; else if ((s->enc_read_ctx = OPENSSL_malloc(sizeof(*s->enc_read_ctx))) == NULL) goto err; else /* * make sure it's intialized in case we exit later with an error */ EVP_CIPHER_CTX_init(s->enc_read_ctx); dd = s->enc_read_ctx; if (ssl_replace_hash(&s->read_hash, m) == NULL) { SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE, ERR_R_INTERNAL_ERROR); goto err2; } #ifndef OPENSSL_NO_COMP /* COMPRESS */ COMP_CTX_free(s->expand); s->expand = NULL; if (comp != NULL) { s->expand = COMP_CTX_new(comp); if (s->expand == NULL) { SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE, SSL_R_COMPRESSION_LIBRARY_ERROR); goto err2; } if (!RECORD_LAYER_setup_comp_buffer(&s->rlayer)) goto err; } #endif RECORD_LAYER_reset_read_sequence(&s->rlayer); mac_secret = &(s->s3->read_mac_secret[0]); } else { if (s->enc_write_ctx != NULL) reuse_dd = 1; else if ((s->enc_write_ctx = OPENSSL_malloc(sizeof(*s->enc_write_ctx))) == NULL) goto err; else /* * make sure it's intialized in case we exit later with an error */ EVP_CIPHER_CTX_init(s->enc_write_ctx); dd = s->enc_write_ctx; if (ssl_replace_hash(&s->write_hash, m) == NULL) { SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE, ERR_R_INTERNAL_ERROR); goto err2; } #ifndef OPENSSL_NO_COMP /* COMPRESS */ COMP_CTX_free(s->compress); s->compress = NULL; if (comp != NULL) { s->compress = COMP_CTX_new(comp); if (s->compress == NULL) { SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE, SSL_R_COMPRESSION_LIBRARY_ERROR); goto err2; } } #endif RECORD_LAYER_reset_write_sequence(&s->rlayer); mac_secret = &(s->s3->write_mac_secret[0]); } if (reuse_dd) EVP_CIPHER_CTX_cleanup(dd); p = s->s3->tmp.key_block; i = EVP_MD_size(m); if (i < 0) goto err2; cl = EVP_CIPHER_key_length(c); j = is_exp ? (cl < SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher) ? cl : SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher)) : cl; /* Was j=(is_exp)?5:EVP_CIPHER_key_length(c); */ k = EVP_CIPHER_iv_length(c); if ((which == SSL3_CHANGE_CIPHER_CLIENT_WRITE) || (which == SSL3_CHANGE_CIPHER_SERVER_READ)) { ms = &(p[0]); n = i + i; key = &(p[n]); n += j + j; iv = &(p[n]); n += k + k; er1 = &(s->s3->client_random[0]); er2 = &(s->s3->server_random[0]); } else { n = i; ms = &(p[n]); n += i + j; key = &(p[n]); n += j + k; iv = &(p[n]); n += k; er1 = &(s->s3->server_random[0]); er2 = &(s->s3->client_random[0]); } if (n > s->s3->tmp.key_block_length) { SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE, ERR_R_INTERNAL_ERROR); goto err2; } EVP_MD_CTX_init(&md); memcpy(mac_secret, ms, i); if (is_exp) { /* * In here I set both the read and write key/iv to the same value * since only the correct one will be used :-). */ EVP_DigestInit_ex(&md, EVP_md5(), NULL); EVP_DigestUpdate(&md, key, j); EVP_DigestUpdate(&md, er1, SSL3_RANDOM_SIZE); EVP_DigestUpdate(&md, er2, SSL3_RANDOM_SIZE); EVP_DigestFinal_ex(&md, &(exp_key[0]), NULL); key = &(exp_key[0]); if (k > 0) { EVP_DigestInit_ex(&md, EVP_md5(), NULL); EVP_DigestUpdate(&md, er1, SSL3_RANDOM_SIZE); EVP_DigestUpdate(&md, er2, SSL3_RANDOM_SIZE); EVP_DigestFinal_ex(&md, &(exp_iv[0]), NULL); iv = &(exp_iv[0]); } } EVP_CipherInit_ex(dd, c, NULL, key, iv, (which & SSL3_CC_WRITE)); #ifdef OPENSSL_SSL_TRACE_CRYPTO if (s->msg_callback) { int wh = which & SSL3_CC_WRITE ? TLS1_RT_CRYPTO_WRITE : TLS1_RT_CRYPTO_READ; s->msg_callback(2, s->version, wh | TLS1_RT_CRYPTO_MAC, mac_secret, EVP_MD_size(m), s, s->msg_callback_arg); if (c->key_len) s->msg_callback(2, s->version, wh | TLS1_RT_CRYPTO_KEY, key, c->key_len, s, s->msg_callback_arg); if (k) { s->msg_callback(2, s->version, wh | TLS1_RT_CRYPTO_IV, iv, k, s, s->msg_callback_arg); } } #endif OPENSSL_cleanse(exp_key, sizeof(exp_key)); OPENSSL_cleanse(exp_iv, sizeof(exp_iv)); EVP_MD_CTX_cleanup(&md); return (1); err: SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE, ERR_R_MALLOC_FAILURE); err2: OPENSSL_cleanse(exp_key, sizeof(exp_key)); OPENSSL_cleanse(exp_iv, sizeof(exp_iv)); return (0); }
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)); } _gss_mg_decode_be_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->gk5c.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; }
/** * @brief Initialise a context for decrypting arbitrary data using the given key. * @note If *ctx is NULL, a apr_crypto_block_t will be created from a pool. If * *ctx is not NULL, *ctx must point at a previously created structure. * @param ctx The block context returned, see note. * @param blockSize The block size of the cipher. * @param iv Optional initialisation vector. If the buffer pointed to is NULL, * an IV will be created at random, in space allocated from the pool. * If the buffer is not NULL, the IV in the buffer will be used. * @param key The key structure. * @param p The pool to use. * @return Returns APR_ENOIV if an initialisation vector is required but not specified. * Returns APR_EINIT if the backend failed to initialise the context. Returns * APR_ENOTIMPL if not implemented. */ static apr_status_t crypto_block_decrypt_init(apr_crypto_block_t **ctx, apr_size_t *blockSize, const unsigned char *iv, const apr_crypto_key_t *key, apr_pool_t *p) { apr_crypto_config_t *config = key->f->config; apr_crypto_block_t *block = *ctx; if (!block) { *ctx = block = apr_pcalloc(p, sizeof(apr_crypto_block_t)); } if (!block) { return APR_ENOMEM; } block->f = key->f; block->pool = p; block->provider = key->provider; apr_pool_cleanup_register(p, block, crypto_block_cleanup_helper, apr_pool_cleanup_null); /* create a new context for encryption */ EVP_CIPHER_CTX_init(&block->cipherCtx); block->initialised = 1; /* generate an IV, if necessary */ if (key->ivSize) { if (iv == NULL) { return APR_ENOIV; } } /* set up our encryption context */ #if CRYPTO_OPENSSL_CONST_BUFFERS if (!EVP_DecryptInit_ex(&block->cipherCtx, key->cipher, config->engine, key->key, iv)) { #else if (!EVP_DecryptInit_ex(&block->cipherCtx, key->cipher, config->engine, (unsigned char *) key->key, (unsigned char *) iv)) { #endif return APR_EINIT; } /* Clear up any read padding */ if (!EVP_CIPHER_CTX_set_padding(&block->cipherCtx, key->doPad)) { return APR_EPADDING; } if (blockSize) { *blockSize = EVP_CIPHER_block_size(key->cipher); } return APR_SUCCESS; } /** * @brief Decrypt data provided by in, write it to out. * @note The number of bytes written will be written to outlen. If * out is NULL, outlen will contain the maximum size of the * buffer needed to hold the data, including any data * generated by apr_crypto_block_decrypt_finish below. If *out points * to NULL, a buffer sufficiently large will be created from * the pool provided. If *out points to a not-NULL value, this * value will be used as a buffer instead. * @param out Address of a buffer to which data will be written, * see note. * @param outlen Length of the output will be written here. * @param in Address of the buffer to read. * @param inlen Length of the buffer to read. * @param ctx The block context to use. * @return APR_ECRYPT if an error occurred. Returns APR_ENOTIMPL if * not implemented. */ static apr_status_t crypto_block_decrypt(unsigned char **out, apr_size_t *outlen, const unsigned char *in, apr_size_t inlen, apr_crypto_block_t *ctx) { int outl = *outlen; unsigned char *buffer; /* are we after the maximum size of the out buffer? */ if (!out) { *outlen = inlen + EVP_MAX_BLOCK_LENGTH; return APR_SUCCESS; } /* must we allocate the output buffer from a pool? */ if (!(*out)) { buffer = apr_palloc(ctx->pool, inlen + EVP_MAX_BLOCK_LENGTH); if (!buffer) { return APR_ENOMEM; } apr_crypto_clear(ctx->pool, buffer, inlen + EVP_MAX_BLOCK_LENGTH); *out = buffer; } #if CRYPT_OPENSSL_CONST_BUFFERS if (!EVP_DecryptUpdate(&ctx->cipherCtx, *out, &outl, in, inlen)) { #else if (!EVP_DecryptUpdate(&ctx->cipherCtx, *out, &outl, (unsigned char *) in, inlen)) { #endif return APR_ECRYPT; } *outlen = outl; return APR_SUCCESS; } /** * @brief Decrypt final data block, write it to out. * @note If necessary the final block will be written out after being * padded. Typically the final block will be written to the * same buffer used by apr_crypto_block_decrypt, offset by the * number of bytes returned as actually written by the * apr_crypto_block_decrypt() call. After this call, the context * is cleaned and can be reused by apr_crypto_block_decrypt_init(). * @param out Address of a buffer to which data will be written. This * buffer must already exist, and is usually the same * buffer used by apr_evp_crypt(). See note. * @param outlen Length of the output will be written here. * @param ctx The block context to use. * @return APR_ECRYPT if an error occurred. * @return APR_EPADDING if padding was enabled and the block was incorrectly * formatted. * @return APR_ENOTIMPL if not implemented. */ static apr_status_t crypto_block_decrypt_finish(unsigned char *out, apr_size_t *outlen, apr_crypto_block_t *ctx) { int len = *outlen; if (EVP_DecryptFinal_ex(&ctx->cipherCtx, out, &len) == 0) { return APR_EPADDING; } *outlen = len; return APR_SUCCESS; }
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)); } _gss_mg_decode_be_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->gk5c.order, seq_number); HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); if (omret) return omret; *minor_status = 0; return GSS_S_COMPLETE; }
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); _gss_mg_encode_be_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; }
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 */ _gss_mg_encode_be_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; }
int ssl3_change_cipher_state(SSL *s, int which) { unsigned char *p,*mac_secret; unsigned char exp_key[EVP_MAX_KEY_LENGTH]; unsigned char exp_iv[EVP_MAX_IV_LENGTH]; unsigned char *ms,*key,*iv,*er1,*er2; EVP_CIPHER_CTX *dd; const EVP_CIPHER *c; #ifndef OPENSSL_NO_COMP COMP_METHOD *comp; #endif const EVP_MD *m; EVP_MD_CTX md; int is_exp,n,i,j,k,cl; int reuse_dd = 0; is_exp=SSL_C_IS_EXPORT(s->s3->tmp.new_cipher); c=s->s3->tmp.new_sym_enc; m=s->s3->tmp.new_hash; #ifndef OPENSSL_NO_COMP if (s->s3->tmp.new_compression == NULL) comp=NULL; else comp=s->s3->tmp.new_compression->method; #endif if (which & SSL3_CC_READ) { if (s->enc_read_ctx != NULL) reuse_dd = 1; else if ((s->enc_read_ctx=OPENSSL_malloc(sizeof(EVP_CIPHER_CTX))) == NULL) goto err; else /* make sure it's intialized in case we exit later with an error */ EVP_CIPHER_CTX_init(s->enc_read_ctx); dd= s->enc_read_ctx; s->read_hash=m; #ifndef OPENSSL_NO_COMP /* COMPRESS */ if (s->expand != NULL) { COMP_CTX_free(s->expand); s->expand=NULL; } if (comp != NULL) { s->expand=COMP_CTX_new(comp); if (s->expand == NULL) { SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE,SSL_R_COMPRESSION_LIBRARY_ERROR); goto err2; } if (s->s3->rrec.comp == NULL) s->s3->rrec.comp=(unsigned char *) OPENSSL_malloc(SSL3_RT_MAX_PLAIN_LENGTH); if (s->s3->rrec.comp == NULL) goto err; } #endif memset(&(s->s3->read_sequence[0]),0,8); mac_secret= &(s->s3->read_mac_secret[0]); } else { if (s->enc_write_ctx != NULL) reuse_dd = 1; else if ((s->enc_write_ctx=OPENSSL_malloc(sizeof(EVP_CIPHER_CTX))) == NULL) goto err; else /* make sure it's intialized in case we exit later with an error */ EVP_CIPHER_CTX_init(s->enc_write_ctx); dd= s->enc_write_ctx; s->write_hash=m; #ifndef OPENSSL_NO_COMP /* COMPRESS */ if (s->compress != NULL) { COMP_CTX_free(s->compress); s->compress=NULL; } if (comp != NULL) { s->compress=COMP_CTX_new(comp); if (s->compress == NULL) { SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE,SSL_R_COMPRESSION_LIBRARY_ERROR); goto err2; } } #endif memset(&(s->s3->write_sequence[0]),0,8); mac_secret= &(s->s3->write_mac_secret[0]); } if (reuse_dd) EVP_CIPHER_CTX_cleanup(dd); p=s->s3->tmp.key_block; i=EVP_MD_size(m); cl=EVP_CIPHER_key_length(c); j=is_exp ? (cl < SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher) ? cl : SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher)) : cl; /* Was j=(is_exp)?5:EVP_CIPHER_key_length(c); */ k=EVP_CIPHER_iv_length(c); if ( (which == SSL3_CHANGE_CIPHER_CLIENT_WRITE) || (which == SSL3_CHANGE_CIPHER_SERVER_READ)) { ms= &(p[ 0]); n=i+i; key= &(p[ n]); n+=j+j; iv= &(p[ n]); n+=k+k; er1= &(s->s3->client_random[0]); er2= &(s->s3->server_random[0]); } else { n=i; ms= &(p[ n]); n+=i+j; key= &(p[ n]); n+=j+k; iv= &(p[ n]); n+=k; er1= &(s->s3->server_random[0]); er2= &(s->s3->client_random[0]); } if (n > s->s3->tmp.key_block_length) { SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE,ERR_R_INTERNAL_ERROR); goto err2; } EVP_MD_CTX_init(&md); memcpy(mac_secret,ms,i); if (is_exp) { /* In here I set both the read and write key/iv to the * same value since only the correct one will be used :-). */ EVP_DigestInit_ex(&md,EVP_md5(), NULL); EVP_DigestUpdate(&md,key,j); EVP_DigestUpdate(&md,er1,SSL3_RANDOM_SIZE); EVP_DigestUpdate(&md,er2,SSL3_RANDOM_SIZE); EVP_DigestFinal_ex(&md,&(exp_key[0]),NULL); key= &(exp_key[0]); if (k > 0) { EVP_DigestInit_ex(&md,EVP_md5(), NULL); EVP_DigestUpdate(&md,er1,SSL3_RANDOM_SIZE); EVP_DigestUpdate(&md,er2,SSL3_RANDOM_SIZE); EVP_DigestFinal_ex(&md,&(exp_iv[0]),NULL); iv= &(exp_iv[0]); } } s->session->key_arg_length=0; EVP_CipherInit_ex(dd,c,NULL,key,iv,(which & SSL3_CC_WRITE)); OPENSSL_cleanse(&(exp_key[0]),sizeof(exp_key)); OPENSSL_cleanse(&(exp_iv[0]),sizeof(exp_iv)); EVP_MD_CTX_cleanup(&md); return(1); err: SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE,ERR_R_MALLOC_FAILURE); err2: return(0); }
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, renew_ticket = 0; unsigned char tick_hmac[EVP_MAX_MD_SIZE]; HMAC_CTX hctx; EVP_CIPHER_CTX ctx; SSL_CTX *tctx = s->initial_ctx; /* Need at least keyname + iv + some encrypted data */ if (eticklen < 48) goto tickerr; /* Initialize session ticket encryption and HMAC contexts */ HMAC_CTX_init(&hctx); EVP_CIPHER_CTX_init(&ctx); if (tctx->tlsext_ticket_key_cb) { unsigned char *nctick = (unsigned char *)etick; int rv = tctx->tlsext_ticket_key_cb(s, nctick, nctick + 16, &ctx, &hctx, 0); if (rv < 0) return -1; if (rv == 0) goto tickerr; if (rv == 2) renew_ticket = 1; } else { /* Check key name matches */ if (memcmp(etick, tctx->tlsext_tick_key_name, 16)) goto tickerr; HMAC_Init_ex(&hctx, tctx->tlsext_tick_hmac_key, 16, tlsext_tick_md(), NULL); EVP_DecryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL, tctx->tlsext_tick_aes_key, etick + 16); } /* Attempt to process session ticket, first conduct sanity and * integrity checks on ticket. */ mlen = HMAC_size(&hctx); eticklen -= mlen; /* Check HMAC of encrypted ticket */ HMAC_Update(&hctx, etick, eticklen); HMAC_Final(&hctx, tick_hmac, NULL); HMAC_CTX_cleanup(&hctx); if (memcmp(tick_hmac, etick + eticklen, mlen)) goto tickerr; /* Attempt to decrypt session data */ /* Move p after IV to start of encrypted ticket, update length */ p = etick + 16 + EVP_CIPHER_CTX_iv_length(&ctx); eticklen -= 16 + EVP_CIPHER_CTX_iv_length(&ctx); 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 = renew_ticket; 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 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; p = malloc(outlen); if (!p) { PEMerror(ERR_R_MALLOC_FAILURE); return -1; } 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) { arc4random_buf(p, PVK_SALTLEN); salt = p; p += PVK_SALTLEN; } do_i2b(&p, pk, 0); if (enclevel == 0) { *out = p; 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) { PEMerror(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; explicit_bzero(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); *out = p; return outlen; error: EVP_CIPHER_CTX_cleanup(&cctx); free(p); return -1; }
static void import_dkek_share(sc_card_t *card, const char *inf, int iter, char *password, int num_of_password_shares) { sc_cardctl_sc_hsm_dkek_t dkekinfo; EVP_CIPHER_CTX ctx; FILE *in = NULL; u8 filebuff[64],key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH],outbuff[64]; char *pwd = NULL; int r, outlen, pwdlen; in = fopen(inf, "rb"); if (in == NULL) { perror(inf); return; } if (fread(filebuff, 1, sizeof(filebuff), in) != sizeof(filebuff)) { perror(inf); return; } fclose(in); if (memcmp(filebuff, magic, sizeof(magic) - 1)) { printf("File %s is not a DKEK share\n", inf); return; } if (password == NULL) { if (num_of_password_shares == -1) { printf("Enter password to decrypt DKEK share : "); util_getpass(&pwd, NULL, stdin); pwdlen = strlen(pwd); printf("\n"); } else { r = recreate_password_from_shares(&pwd, &pwdlen, num_of_password_shares); if (r < 0) { return; } } } else { pwd = password; pwdlen = strlen(password); } printf("Deciphering DKEK share, please wait...\n"); EVP_BytesToKey(EVP_aes_256_cbc(), EVP_md5(), filebuff + 8, (u8 *)pwd, pwdlen, iter, key, iv); OPENSSL_cleanse(pwd, strlen(pwd)); if (password == NULL) { free(pwd); } EVP_CIPHER_CTX_init(&ctx); EVP_DecryptInit_ex(&ctx, EVP_aes_256_cbc(), NULL, key, iv); if (!EVP_DecryptUpdate(&ctx, outbuff, &outlen, filebuff + 16, sizeof(filebuff) - 16)) { printf("Error decrypting DKEK share. Password correct ?\n"); return; } if (!EVP_DecryptFinal_ex(&ctx, outbuff + outlen, &r)) { printf("Error decrypting DKEK share. Password correct ?\n"); return; } memset(&dkekinfo, 0, sizeof(dkekinfo)); memcpy(dkekinfo.dkek_share, outbuff, sizeof(dkekinfo.dkek_share)); dkekinfo.importShare = 1; OPENSSL_cleanse(outbuff, sizeof(outbuff)); r = sc_card_ctl(card, SC_CARDCTL_SC_HSM_IMPORT_DKEK_SHARE, (void *)&dkekinfo); OPENSSL_cleanse(&dkekinfo.dkek_share, sizeof(dkekinfo.dkek_share)); EVP_CIPHER_CTX_cleanup(&ctx); if (r == SC_ERROR_INS_NOT_SUPPORTED) { // Not supported or not initialized for key shares printf("Not supported by card or card not initialized for key share usage\n"); return; } if (r < 0) { fprintf(stderr, "sc_card_ctl(*, SC_CARDCTL_SC_HSM_IMPORT_DKEK_SHARE, *) failed with %s\n", sc_strerror(r)); return; } printf("DKEK share imported\n"); print_dkek_info(&dkekinfo); }
BST_STATIC BST_ERR_ENUM_UINT8 DecryptInternal ( BST_UINT8 *pucIn, BST_UINT32 ulInLen, BST_UINT8 *pucOut, BST_UINT32 *pulOutLen, BST_UINT8 *pucKey ) { BST_INT32 lLen; BST_INT32 lRet; BST_INT32 lTmpLen; BST_UINT8 aucValue[8]; EVP_CIPHER_CTX Ctx; lLen = 0; lRet = 0; lTmpLen = 0; if ( ( BST_NULL_PTR == pucIn ) || ( BST_NULL_PTR == pucOut ) || ( BST_NULL_PTR == pucKey) || ( BST_NULL_PTR == pulOutLen ) ) { return BST_ERR_PARAM_DECRYPTER; } EVP_CIPHER_CTX_init ( &Ctx ); lRet = EVP_DecryptInit_ex ( &Ctx, EVP_aes_128_ecb(), BST_NULL_PTR, pucKey, aucValue ); if ( lRet != BST_CORE_OPENSSL_SUCCESS ) { return BST_ERR_PARAM_DECRYPTER; } lRet = EVP_DecryptUpdate ( &Ctx, pucOut + lLen, &lTmpLen, pucIn + lLen, ulInLen ); if ( lRet != BST_CORE_OPENSSL_SUCCESS ) { return BST_ERR_PARAM_DECRYPTER; } lLen += lTmpLen; lRet = EVP_DecryptFinal_ex ( &Ctx, pucOut + lLen, &lTmpLen ); if ( lRet != BST_CORE_OPENSSL_SUCCESS ) { return BST_ERR_PARAM_DECRYPTER; } lLen += lTmpLen; pucOut[lLen] = 0; *pulOutLen = lLen; lRet = EVP_CIPHER_CTX_cleanup ( &Ctx ); if ( lRet != BST_CORE_OPENSSL_SUCCESS ) { return BST_ERR_PARAM_DECRYPTER; } return BST_NO_ERROR_MSG; }
static void create_dkek_share(sc_card_t *card, const char *outf, int iter, char *password, int password_shares_threshold, int password_shares_total) { EVP_CIPHER_CTX ctx; FILE *out = NULL; u8 filebuff[64], key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH],outbuff[64]; u8 dkek_share[32]; char *pwd = NULL; int r = 0, outlen, pwdlen = 0; if (password == NULL) { if (password_shares_threshold == -1) { ask_for_password(&pwd, &pwdlen); } else { // create password using threshold scheme r = generate_pwd_shares(card, &pwd, &pwdlen, password_shares_threshold, password_shares_total); } } else { pwd = password; pwdlen = strlen(password); } if (r < 0) { printf("Creating DKEK share failed"); return; } memcpy(filebuff, magic, sizeof(magic) - 1); r = sc_get_challenge(card, filebuff + 8, 8); if (r < 0) { printf("Error generating random number failed with ", sc_strerror(r)); return; } printf("Enciphering DKEK share, please wait...\n"); EVP_BytesToKey(EVP_aes_256_cbc(), EVP_md5(), filebuff + 8, (u8 *)pwd, pwdlen, iter, key, iv); if (password == NULL) { OPENSSL_cleanse(pwd, pwdlen); free(pwd); } r = sc_get_challenge(card, dkek_share, sizeof(dkek_share)); if (r < 0) { printf("Error generating random number failed with ", sc_strerror(r)); return; } EVP_CIPHER_CTX_init(&ctx); EVP_EncryptInit_ex(&ctx, EVP_aes_256_cbc(), NULL, key, iv); if (!EVP_EncryptUpdate(&ctx, filebuff + 16, &outlen, dkek_share, sizeof(dkek_share))) { printf("Error encrypting DKEK share\n"); return; } if (!EVP_EncryptFinal_ex(&ctx, filebuff + 16 + outlen, &r)) { printf("Error encrypting DKEK share\n"); return; } out = fopen(outf, "wb"); if (out == NULL) { perror(outf); return; } if (fwrite(filebuff, 1, sizeof(filebuff), out) != sizeof(filebuff)) { perror(outf); return; } fclose(out); OPENSSL_cleanse(filebuff, sizeof(filebuff)); EVP_CIPHER_CTX_cleanup(&ctx); printf("DKEK share created and saved to %s\n", outf); }
static void test1(const EVP_CIPHER *c,const unsigned char *key,int kn, const unsigned char *iv,int in, const unsigned char *plaintext,int pn, const unsigned char *ciphertext,int cn, int encdec) { EVP_CIPHER_CTX ctx; unsigned char out[4096]; int outl,outl2; printf("Testing cipher %s%s\n",EVP_CIPHER_name(c), (encdec == 1 ? "(encrypt)" : (encdec == 0 ? "(decrypt)" : "(encrypt/decrypt)"))); hexdump(stdout,"Key",key,kn); if(in) hexdump(stdout,"IV",iv,in); hexdump(stdout,"Plaintext",plaintext,pn); hexdump(stdout,"Ciphertext",ciphertext,cn); if(kn != c->key_len) { fprintf(stderr,"Key length doesn't match, got %d expected %lu\n",kn, (unsigned long)c->key_len); test1_exit(5); } EVP_CIPHER_CTX_init(&ctx); if (encdec != 0) { if(!EVP_EncryptInit_ex(&ctx,c,NULL,key,iv)) { fprintf(stderr,"EncryptInit failed\n"); ERR_print_errors_fp(stderr); test1_exit(10); } EVP_CIPHER_CTX_set_padding(&ctx,0); if(!EVP_EncryptUpdate(&ctx,out,&outl,plaintext,pn)) { fprintf(stderr,"Encrypt failed\n"); ERR_print_errors_fp(stderr); test1_exit(6); } if(!EVP_EncryptFinal_ex(&ctx,out+outl,&outl2)) { fprintf(stderr,"EncryptFinal failed\n"); ERR_print_errors_fp(stderr); test1_exit(7); } if(outl+outl2 != cn) { fprintf(stderr,"Ciphertext length mismatch got %d expected %d\n", outl+outl2,cn); test1_exit(8); } if(memcmp(out,ciphertext,cn)) { fprintf(stderr,"Ciphertext mismatch\n"); hexdump(stderr,"Got",out,cn); hexdump(stderr,"Expected",ciphertext,cn); test1_exit(9); } } if (encdec <= 0) { if(!EVP_DecryptInit_ex(&ctx,c,NULL,key,iv)) { fprintf(stderr,"DecryptInit failed\n"); ERR_print_errors_fp(stderr); test1_exit(11); } EVP_CIPHER_CTX_set_padding(&ctx,0); if(!EVP_DecryptUpdate(&ctx,out,&outl,ciphertext,cn)) { fprintf(stderr,"Decrypt failed\n"); ERR_print_errors_fp(stderr); test1_exit(6); } if(!EVP_DecryptFinal_ex(&ctx,out+outl,&outl2)) { fprintf(stderr,"DecryptFinal failed\n"); ERR_print_errors_fp(stderr); test1_exit(7); } if(outl+outl2 != pn) { fprintf(stderr,"Plaintext length mismatch got %d expected %d\n", outl+outl2,pn); test1_exit(8); } if(memcmp(out,plaintext,pn)) { fprintf(stderr,"Plaintext mismatch\n"); hexdump(stderr,"Got",out,pn); hexdump(stderr,"Expected",plaintext,pn); test1_exit(9); } } EVP_CIPHER_CTX_cleanup(&ctx); printf("\n"); }
struct iked_cipher * cipher_new(uint8_t type, uint16_t id, uint16_t id_length) { struct iked_cipher *encr; const EVP_CIPHER *cipher = NULL; EVP_CIPHER_CTX *ctx = NULL; int length = 0, fixedkey = 0, ivlength = 0; switch (type) { case IKEV2_XFORMTYPE_ENCR: switch (id) { case IKEV2_XFORMENCR_3DES: cipher = EVP_des_ede3_cbc(); length = EVP_CIPHER_block_size(cipher); fixedkey = EVP_CIPHER_key_length(cipher); ivlength = EVP_CIPHER_iv_length(cipher); break; case IKEV2_XFORMENCR_AES_CBC: switch (id_length) { case 128: cipher = EVP_aes_128_cbc(); break; case 192: cipher = EVP_aes_192_cbc(); break; case 256: cipher = EVP_aes_256_cbc(); break; default: log_debug("%s: invalid key length %d" " for cipher %s", __func__, id_length, print_map(id, ikev2_xformencr_map)); break; } if (cipher == NULL) break; length = EVP_CIPHER_block_size(cipher); ivlength = EVP_CIPHER_iv_length(cipher); fixedkey = EVP_CIPHER_key_length(cipher); break; case IKEV2_XFORMENCR_DES_IV64: case IKEV2_XFORMENCR_DES: case IKEV2_XFORMENCR_RC5: case IKEV2_XFORMENCR_IDEA: case IKEV2_XFORMENCR_CAST: case IKEV2_XFORMENCR_BLOWFISH: case IKEV2_XFORMENCR_3IDEA: case IKEV2_XFORMENCR_DES_IV32: case IKEV2_XFORMENCR_NULL: case IKEV2_XFORMENCR_AES_CTR: /* FALLTHROUGH */ default: log_debug("%s: cipher %s not supported", __func__, print_map(id, ikev2_xformencr_map)); cipher = NULL; break; } break; default: log_debug("%s: cipher type %s not supported", __func__, print_map(id, ikev2_xformtype_map)); break; } if (cipher == NULL) return (NULL); if ((encr = calloc(1, sizeof(*encr))) == NULL) { log_debug("%s: alloc cipher", __func__); return (NULL); } encr->encr_id = id; encr->encr_priv = cipher; encr->encr_ctx = NULL; encr->encr_length = length; encr->encr_fixedkey = fixedkey; encr->encr_ivlength = ivlength ? ivlength : length; if ((ctx = calloc(1, sizeof(*ctx))) == NULL) { log_debug("%s: alloc cipher ctx", __func__); cipher_free(encr); return (NULL); } EVP_CIPHER_CTX_init(ctx); encr->encr_ctx = ctx; return (encr); }
void mexserver() //gestisco i job { long ret,quanti=0; char key[32] ; unsigned char * msg; long numblocchi; unsigned char **p; unsigned char zero[16]; int index; EVP_CIPHER_CTX* ctx; unsigned char ** ciphertext; unsigned char* L; printf("mexdalserver\n"); //key=malloc(32); ret = recv(sk, (void *)key, 32, 0);//key if(ret==-1) { printf("mexserver errore: errore in ricezione idjob dal server!\n"); exit(1); } printf("key : \n"); printf("key : %s\n",key); printf("\n"); if(ret==0) { //server si e' disconnesso printf("Il server ha chiuso la connessione!!/n"); exit(3); } ret = recv(sk, (void *)&index, sizeof(int), 0); //mi serve per il calcolo di p if(ret==-1) { printf("mexserver errore: errore in ricezione lunghezza dal server3!\n"); exit(1); } printf("ricevuto index: %d\n",index); ret = recv(sk, (void *)&quanti, sizeof(long), 0); //ricevo lunghezza stringa if(ret==-1) { printf("mexserver errore: errore in ricezione lunghezza dal server1!\n"); exit(1); } printf("ricevuto quanti: %ld\n",quanti); msg=malloc(quanti); ret = recv(sk, (void *)msg, quanti, 0); //ricevo file da cifrare if(ret==-1) { printf("mexserver errore: errore in ricezione lunghezza dal server2!\n"); exit(1); } printf("ricevuto msg\n"); printf("\n MSG %s\n",msg); numblocchi=quanti/16; printf("stai elaborando %ld\n",numblocchi); printf("blocchi \n"); //************************** exit(1);//****************crush************************ //**************************** p=malloc(sizeof(unsigned char*)* numblocchi ); #pragma omp parallel for for (int z=1; z<numblocchi; z++) { p[z]=malloc(16); //l'ultimo carattere mi dice se completato.. } ciphertext=malloc(sizeof(unsigned char*)*numblocchi); ctx = (EVP_CIPHER_CTX*)malloc(sizeof(EVP_CIPHER_CTX)); EVP_CIPHER_CTX_init(ctx); int outlen=0; L=malloc(16); /* Context setup for encryption */ EVP_EncryptInit(ctx, EVP_aes_256_ecb(), key, NULL); EVP_CIPHER_CTX_set_padding(ctx, 0); EVP_EncryptUpdate(ctx, L, &outlen, (unsigned char*)zero, 16); if (!EVP_EncryptFinal(ctx, L+outlen, &outlen)) { // se == 0 -> errore printf("Errore in EVP_EncryptFinal\n"); exit(-1); } EVP_CIPHER_CTX_cleanup(ctx); EVP_CIPHER_CTX_free(ctx); for (int i=0; i<16; i++) printf(" %02X", (unsigned char)L[i]); printf("\n"); memset(zero, 0, 16); zero[15]=1; for (int i; i<16; i++) L[i]|=zero[i]; //L trovata adessi IL; calcolaLI(numblocchi, L, p,index); char carry=0; char ris; #pragma omp parallel for private(ctx, outlen) for (int i=0;i<numblocchi ; i++) { //fa il cipher for(int z=0;z <16;z++){ // msg[i*16+z]+=p[i][z];{ ris = msg[i*16+z]&127 || p[i][z]&127; msg[i*16+z]+= p[i][z] + carry; if (ris==1 && (msg[i*16+z]&127)==0) carry=1; else carry=0; } ciphertext[i]=malloc(16); carry=0; ctx = (EVP_CIPHER_CTX*)malloc(sizeof(EVP_CIPHER_CTX)); EVP_CIPHER_CTX_init(ctx); outlen = 0; EVP_EncryptInit(ctx, EVP_aes_256_ecb(), key, NULL); EVP_CIPHER_CTX_set_padding(ctx, 0); EVP_EncryptUpdate(ctx, ciphertext[i], &outlen, &msg[i*16], 16); if (!EVP_EncryptFinal(ctx, ciphertext[i]+outlen, &outlen)) { // se == 0 -> errore printf("Errore in EVP_EncryptFinal\n"); exit(-1); } EVP_CIPHER_CTX_cleanup(ctx); EVP_CIPHER_CTX_free(ctx); } #pragma omp parallel for for (int i=0;i<numblocchi ; i++) { //xor tra i cipher calcolati for(int z=0;z <16;z++) zero[z]^=ciphertext[i][z]; } char x='a'; ret=send(sk,(void*)&x,sizeof(char),0);//mando risultato if (ret ==-1) { printf ("errore nel mandare comando e' il mex d'uscita"); exit(1); } printf("zero : \n"); for (int i=0; i<16; i++) printf(" %02X", (unsigned char)zero[i]); printf("\n"); ret=send(sk,(void*)zero,16,0);//mando risultato if (ret ==-1) { printf ("errore nel mandare comando e' il mex d'uscita"); exit(1); } printf("finito un job\n"); }
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) { OPENSSL_PUT_ERROR(PEM, PEM_ASN1_write_bio, PEM_R_UNSUPPORTED_CIPHER); goto err; } } if ((dsize=i2d(x,NULL)) < 0) { OPENSSL_PUT_ERROR(PEM, 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) { OPENSSL_PUT_ERROR(PEM, PEM_ASN1_write_bio, ERR_R_MALLOC_FAILURE); goto err; } p=data; i=i2d(x,&p); if (enc != NULL) { const unsigned iv_len = EVP_CIPHER_iv_length(enc); if (kstr == NULL) { klen = 0; if (callback) klen=(*callback)(buf,PEM_BUFSIZE,1,u); if (klen <= 0) { OPENSSL_PUT_ERROR(PEM, PEM_ASN1_write_bio, PEM_R_READ_KEY); goto err; } kstr=(unsigned char *)buf; } assert(iv_len <= (int)sizeof(iv)); if (RAND_pseudo_bytes(iv,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); assert(strlen(objstr)+23+2*iv_len+13 <= sizeof buf); buf[0]='\0'; PEM_proc_type(buf,PEM_TYPE_ENCRYPTED); PEM_dek_info(buf,objstr,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); }
int spp_init_slice_st(SSL *s, SPP_SLICE *slice, int which) { const EVP_CIPHER *c; const EVP_MD *m; int is_exp,cl,k; unsigned char key_ex[EVP_MAX_KEY_LENGTH]; unsigned char iv_ex[EVP_MAX_KEY_LENGTH]; unsigned char *key, *iv; int mac_type; EVP_PKEY *mac_key; EVP_MD_CTX md; mac_type = s->s3->tmp.new_mac_pkey_type; m=s->s3->tmp.new_hash; key = &(key_ex[0]); iv = &(iv_ex[0]); is_exp=SSL_C_IS_EXPORT(s->s3->tmp.new_cipher); c=s->s3->tmp.new_sym_enc; cl=EVP_CIPHER_key_length(c); k=EVP_CIPHER_iv_length(c); //printf("Init slice %d\n", slice->slice_id); if (which & SSL3_CC_READ) { //printf("which=read\n"); if (slice->read_access) { // Secret is computed by XORing the material generated by the client and server xor_array(key, slice->read_mat, slice->other_read_mat, EVP_MAX_KEY_LENGTH); // Generate the encryption contexts. //printf("encryption init\n"); if (slice->read_ciph == NULL) { if ((slice->read_ciph=OPENSSL_malloc(sizeof(SPP_CIPH))) == NULL) goto err; } if ((slice->read_ciph->enc_read_ctx=OPENSSL_malloc(sizeof(EVP_CIPHER_CTX))) == NULL) goto err; EVP_CIPHER_CTX_init(slice->read_ciph->enc_read_ctx); EVP_CipherInit_ex(slice->read_ciph->enc_read_ctx,c,NULL,key,iv,(which & SSL3_CC_WRITE)); // And the read mac contexts //printf("read mac init\n"); if ((slice->read_mac=spp_init_mac_st(s, slice->read_mac, key, which)) == NULL) { goto err; } } else { if (slice->read_ciph == NULL) { if ((slice->read_ciph=OPENSSL_malloc(sizeof(SPP_CIPH))) == NULL) goto err; } slice->read_ciph->enc_read_ctx = NULL; } if (slice->write_access) { xor_array(key, slice->write_mat, slice->other_write_mat, EVP_MAX_KEY_LENGTH); // Generate the write mac context //printf("write mac init\n"); if ((slice->write_mac=spp_init_mac_st(s, slice->write_mac, key, which)) == NULL) { goto err; } } } else { //printf("which=write\n"); if (slice->read_access) { // Secret is computed by XORing the material generated by the client and server xor_array(key, slice->read_mat, slice->other_read_mat, EVP_MAX_KEY_LENGTH); // Generate the encryption contexts. if (slice->read_ciph == NULL) { if ((slice->read_ciph=OPENSSL_malloc(sizeof(SPP_CIPH))) == NULL) goto err; } //printf("encryption init\n"); if ((slice->read_ciph->enc_write_ctx=OPENSSL_malloc(sizeof(EVP_CIPHER_CTX))) == NULL) goto err; EVP_CIPHER_CTX_init(slice->read_ciph->enc_write_ctx); EVP_CipherInit_ex(slice->read_ciph->enc_write_ctx,c,NULL,key,iv,(which & SSL3_CC_WRITE)); // And the read mac contexts //printf("read mac init\n"); if ((slice->read_mac=spp_init_mac_st(s, slice->read_mac, key, which)) == NULL) { goto err; } } else { if (slice->read_ciph == NULL) { if ((slice->read_ciph=OPENSSL_malloc(sizeof(SPP_CIPH))) == NULL) goto err; } slice->read_ciph->enc_write_ctx = NULL; } if (slice->write_access) { xor_array(key, slice->write_mat, slice->other_write_mat, EVP_MAX_KEY_LENGTH); // Generate the write mac context //printf("write mac init\n"); if ((slice->write_mac=spp_init_mac_st(s, slice->write_mac, key, which)) == NULL) { goto err; } } } return 1; err: printf("Error in slice init\n"); return -1; }
static OM_uint32 verify_mic_des (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, char *type ) { u_char *p; EVP_MD_CTX *md5; u_char hash[16], *seq; DES_key_schedule schedule; EVP_CIPHER_CTX des_ctx; DES_cblock zero; DES_cblock deskey; uint32_t seq_number; OM_uint32 ret; int cmp; p = token_buffer->value; ret = _gsskrb5_verify_header (&p, token_buffer->length, type, GSS_KRB5_MECHANISM); if (ret) return ret; if (memcmp(p, "\x00\x00", 2) != 0) return GSS_S_BAD_SIG; p += 2; if (memcmp (p, "\xff\xff\xff\xff", 4) != 0) return GSS_S_BAD_MIC; p += 4; p += 16; /* verify checksum */ md5 = EVP_MD_CTX_create(); EVP_DigestInit_ex(md5, EVP_md5(), NULL); EVP_DigestUpdate(md5, p - 24, 8); EVP_DigestUpdate(md5, message_buffer->value, message_buffer->length); EVP_DigestFinal_ex(md5, hash, NULL); EVP_MD_CTX_destroy(md5); memset (&zero, 0, sizeof(zero)); memcpy (&deskey, key->keyvalue.data, sizeof(deskey)); DES_set_key_unchecked (&deskey, &schedule); DES_cbc_cksum ((void *)hash, (void *)hash, sizeof(hash), &schedule, &zero); if (ct_memcmp (p - 8, hash, 8) != 0) { memset (deskey, 0, sizeof(deskey)); memset (&schedule, 0, sizeof(schedule)); return GSS_S_BAD_MIC; } /* verify sequence number */ HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex); p -= 16; EVP_CIPHER_CTX_init(&des_ctx); EVP_CipherInit_ex(&des_ctx, EVP_des_cbc(), NULL, key->keyvalue.data, hash, 0); EVP_Cipher(&des_ctx, p, p, 8); EVP_CIPHER_CTX_cleanup(&des_ctx); memset (deskey, 0, sizeof(deskey)); memset (&schedule, 0, sizeof(schedule)); seq = p; _gsskrb5_decode_om_uint32(seq, &seq_number); if (context_handle->more_flags & LOCAL) cmp = ct_memcmp(&seq[4], "\xff\xff\xff\xff", 4); else cmp = ct_memcmp(&seq[4], "\x00\x00\x00\x00", 4); if (cmp != 0) { HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); return GSS_S_BAD_MIC; } ret = _gssapi_msg_order_check(context_handle->order, seq_number); if (ret) { HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); return ret; } HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); return GSS_S_COMPLETE; }
// Translates |input| of |input_len| using aes-gcm-128. The |input| will either // be encrypted or decrypted based on |direction|. The |key|, which must be of // size |kAesGcmKeyBytes|, and the |nonce|, which must be of size // |kAesGcmNonceBytes|, will be used for the translation. A new zend string will // be returned on success, or NULL (with a visible warning) on failure. static zend_string* AesGcm128Translate( int direction, char* input, size_t input_len, char* key, char* nonce) { const EVP_CIPHER* aead = EVP_aes_128_gcm(); zend_string* result = NULL; int expected_len = 0; int result_len = 0; EVP_CIPHER_CTX context; EVP_CIPHER_CTX_init(&context); do { if (direction == TRANSLATE_ENCRYPT) { if (EVP_EncryptInit_ex(&context, aead, 0, 0, 0) != 1) { php_error_docref(NULL, E_ERROR, kTranslateInitGcmError); break; } if (EVP_CIPHER_CTX_ctrl(&context, EVP_CTRL_GCM_SET_IVLEN, 12, 0) != 1 || EVP_EncryptInit_ex(&context, 0, 0, key, nonce) != 1) { php_error_docref(NULL, E_ERROR, kTranslateKeyNonceError); break; } expected_len = input_len + 16 /* authentication tag */; result = zend_string_alloc(expected_len, 0); if (!result) { php_error_docref(NULL, E_ERROR, kTranslateAllocationError); break; } if (EVP_EncryptUpdate(&context, result->val, &result_len, input, input_len) != 1 || EVP_EncryptFinal_ex(&context, result->val, &result_len) != 1) { php_error_docref(NULL, E_ERROR, kTranslateEncryptInputError); zend_string_release(result); result = NULL; break; } if (EVP_CIPHER_CTX_ctrl(&context, EVP_CTRL_GCM_GET_TAG, 16, result->val + input_len) != 1) { php_error_docref(NULL, E_ERROR, kTranslateEncryptAuthError); zend_string_release(result); result = NULL; break; } // Encryption successful! } else { if (EVP_DecryptInit_ex(&context, aead, 0, 0, 0) != 1) { php_error_docref(NULL, E_ERROR, kTranslateInitGcmError); break; } expected_len = input_len - 16; if (EVP_CIPHER_CTX_ctrl(&context, EVP_CTRL_GCM_SET_TAG, 16, input + expected_len) != 1) { php_error_docref(NULL, E_ERROR, kTranslateDecryptAuthError); break; } if (EVP_CIPHER_CTX_ctrl(&context, EVP_CTRL_GCM_SET_IVLEN, 12, 0) != 1 || EVP_DecryptInit_ex(&context, 0, 0, key, nonce) != 1) { php_error_docref(NULL, E_ERROR, kTranslateKeyNonceError); break; } result = zend_string_alloc(expected_len, 0); if (!result) { php_error_docref(NULL, E_ERROR, kTranslateAllocationError); break; } if (EVP_DecryptUpdate(&context, result->val, &result_len, input, expected_len) != 1 || EVP_DecryptFinal_ex(&context, result->val + expected_len, &result_len) != 1) { php_error_docref(NULL, E_WARNING, kTranslateDecryptionWarning); zend_string_release(result); result = NULL; break; } // Decryption successful! } } while(0); EVP_CIPHER_CTX_cleanup(&context); return result; }
QString Nicookie::chromeDecrypt(const QByteArray &encrypt_data) { QString data; #ifdef Q_OS_WIN DATA_BLOB encrypt_data_blob; encrypt_data_blob.pbData = (BYTE*)(encrypt_data.data()); encrypt_data_blob.cbData = static_cast<DWORD>(encrypt_data.size()); DATA_BLOB plain_data_blob; BOOL result = CryptUnprotectData(&encrypt_data_blob, NULL, NULL, NULL, NULL, 0, &plain_data_blob); if (!result) { setError(Nicookie::FailedDecrytError); return QString(); } data = (QByteArray((char *)(plain_data_blob.pbData), plain_data_blob.cbData)); LocalFree(plain_data_blob.pbData); #else // O_QS_WIN #ifdef Q_OS_OSX // https://developer.apple.com/library/mac/documentation/Security/Reference/keychainservices/index.html#//apple_ref/c/func/SecKeychainFindGenericPassword UInt32 password_size = 0; void *password = NULL; OSStatus os_status; os_status = SecKeychainFindGenericPassword(NULL, 19, "Chrome Safe Storage", 6, "Chrome", &password_size, &password, NULL); if (password_size == 0) { setError(Nicookie::FailedDecrytError); SecKeychainItemFreeContent(NULL, password); return data; } #else // Q_OS_OSX int password_size = 7; void *password = (void *)"peanuts"; #endif // Q_OS_OSX const int enc_key_size = 16; unsigned char enc_key[enc_key_size]; #ifdef Q_OS_OSX int iterations = 1003; #else // Q_OS_OSX int iterations = 1; #endif // Q_OS_OSX const char *salt = "saltysalt"; int pbkdf2_r = PKCS5_PBKDF2_HMAC_SHA1((char *)password, password_size, (unsigned char *)salt, strlen(salt), iterations, enc_key_size, enc_key); if (!pbkdf2_r) { setError(Nicookie::FailedDecrytError); #ifdef Q_OS_OSX SecKeychainItemFreeContent(NULL, password); #endif // Q_OS_OSX return data; } const int iv_size = 16; unsigned char iv[iv_size]; for (int i = 0; i < iv_size; i++) iv[i] = ' '; // alwayes enc size >= dec size int plain_value_size = encrypt_data.size(); char *plain_value = (char *)malloc(plain_value_size); if (plain_value == NULL) { setError(Nicookie::FailedDecrytError); #ifdef Q_OS_OSX SecKeychainItemFreeContent(NULL, password); #endif // Q_OS_OSX return data; } int result = 1; EVP_CIPHER_CTX ctx; EVP_CIPHER_CTX_init(&ctx); result = EVP_DecryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL, enc_key, iv); if (!result) { setError(Nicookie::FailedDecrytError); EVP_CIPHER_CTX_cleanup(&ctx); free(plain_value); #ifdef Q_OS_OSX SecKeychainItemFreeContent(NULL, password); #endif // Q_OS_OSX return data; } result = EVP_DecryptUpdate(&ctx, (unsigned char *)plain_value, &plain_value_size, (unsigned char *)(encrypt_data.data() + 3), encrypt_data.size() - 3); if (!result) { setError(Nicookie::FailedDecrytError); EVP_CIPHER_CTX_cleanup(&ctx); free(plain_value); #ifdef Q_OS_OSX SecKeychainItemFreeContent(NULL, password); #endif // Q_OS_OSX return data; } int fin_size = 0; result = EVP_DecryptFinal_ex(&ctx, (unsigned char *)(plain_value + plain_value_size), &fin_size); if (!result) { setError(Nicookie::FailedDecrytError); EVP_CIPHER_CTX_cleanup(&ctx); free(plain_value); #ifdef Q_OS_OSX SecKeychainItemFreeContent(NULL, password); #endif // Q_OS_OSX return data; } EVP_CIPHER_CTX_cleanup(&ctx); plain_value[plain_value_size + fin_size] = '\0'; data = plain_value; free(plain_value); #ifdef Q_OS_OSX SecKeychainItemFreeContent(NULL, password); #endif // Q_OS_OSX #endif // O_QS_WIN return data; }
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 }
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) { PEMerror(PEM_R_BAD_PASSWORD_READ); goto err; } enctmp = malloc(keylen + 8); if (!enctmp) { PEMerror(ERR_R_MALLOC_FAILURE); goto err; } if (!derive_pvk_key(keybuf, p, saltlen, (unsigned char *)psbuf, inlen)) { goto err; } p += saltlen; /* Copy BLOBHEADER across, decrypt rest */ memcpy(enctmp, p, 8); p += 8; if (keylen < 8) { PEMerror(PEM_R_PVK_TOO_SHORT); goto err; } 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; explicit_bzero(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) { PEMerror(PEM_R_BAD_DECRYPT); goto err; } } else explicit_bzero(keybuf, 20); p = enctmp; } ret = b2i_PrivateKey(&p, keylen); err: EVP_CIPHER_CTX_cleanup(&cctx); if (enctmp && saltlen) free(enctmp); return ret; }
extern int do_crypt(FILE* in, FILE* out, int action, char* key_str) { /* Local Vars */ /* Buffers */ unsigned char inbuf[BLOCKSIZE]; int inlen; /* Allow enough space in output buffer for additional cipher block */ unsigned char outbuf[BLOCKSIZE + EVP_MAX_BLOCK_LENGTH]; int outlen; int writelen; /* OpenSSL libcrypto vars */ EVP_CIPHER_CTX ctx; unsigned char key[32]; unsigned char iv[32]; int nrounds = 5; /* tmp vars */ int i; /* Setup Encryption Key and Cipher Engine if in cipher mode */ if(action >= 0) { if(!key_str) { /* Error */ fprintf(stderr, "Key_str must not be NULL\n"); return 0; } /* Build Key from String */ i = EVP_BytesToKey(EVP_aes_256_cbc(), EVP_sha1(), NULL, (unsigned char*)key_str, strlen(key_str), nrounds, key, iv); if (i != 32) { /* Error */ fprintf(stderr, "Key size is %d bits - should be 256 bits\n", i*8); return 0; } /* Init Engine */ EVP_CIPHER_CTX_init(&ctx); EVP_CipherInit_ex(&ctx, EVP_aes_256_cbc(), NULL, key, iv, action); } /* Loop through Input File*/ for(;;) { /* Read Block */ inlen = fread(inbuf, sizeof(*inbuf), BLOCKSIZE, in); if(inlen <= 0) { /* EOF -> Break Loop */ break; } /* If in cipher mode, perform cipher transform on block */ if(action >= 0) { if(!EVP_CipherUpdate(&ctx, outbuf, &outlen, inbuf, inlen)) { /* Error */ EVP_CIPHER_CTX_cleanup(&ctx); fprintf(stderr, "error that idk!\n"); return 0; } } /* If in pass-through mode. copy block as is */ else { memcpy(outbuf, inbuf, inlen); outlen = inlen; } /* Write Block */ writelen = fwrite(outbuf, sizeof(*outbuf), outlen, out); if(writelen != outlen) { /* Error */ perror("fwrite error"); fprintf(stderr, "fwrite error\n"); EVP_CIPHER_CTX_cleanup(&ctx); return 0; } } /* If in cipher mode, handle necessary padding */ if(action >= 0) { /* Handle remaining cipher block + padding */ if(!EVP_CipherFinal_ex(&ctx, outbuf, &outlen)) { /* Error */ EVP_CIPHER_CTX_cleanup(&ctx); fprintf(stderr, "EVP_CipherFinal_ex() FAILURE!\n"); return 0; } /* Write remainign cipher block + padding*/ fwrite(outbuf, sizeof(*inbuf), outlen, out); EVP_CIPHER_CTX_cleanup(&ctx); } /* Success */ return 1; }
static void test1(const EVP_CIPHER *c,const unsigned char *key,int kn, const unsigned char *iv,int in, const unsigned char *plaintext,int pn, const unsigned char *ciphertext,int cn, const unsigned char *aad,int an, const unsigned char *tag,int tn, int encdec) { EVP_CIPHER_CTX ctx; unsigned char out[4096]; int outl,outl2,mode; printf("Testing cipher %s%s\n",EVP_CIPHER_name(c), (encdec == 1 ? "(encrypt)" : (encdec == 0 ? "(decrypt)" : "(encrypt/decrypt)"))); hexdump(stdout,"Key",key,kn); if(in) hexdump(stdout,"IV",iv,in); hexdump(stdout,"Plaintext",plaintext,pn); hexdump(stdout,"Ciphertext",ciphertext,cn); if (an) hexdump(stdout,"AAD",aad,an); if (tn) hexdump(stdout,"Tag",tag,tn); mode = EVP_CIPHER_mode(c); if(kn != EVP_CIPHER_key_length(c)) { fprintf(stderr,"Key length doesn't match, got %d expected %lu\n",kn, (unsigned long)EVP_CIPHER_key_length(c)); test1_exit(5); } EVP_CIPHER_CTX_init(&ctx); if (encdec != 0) { if (mode == EVP_CIPH_GCM_MODE) { if(!EVP_EncryptInit_ex(&ctx,c,NULL,NULL,NULL)) { fprintf(stderr,"EncryptInit failed\n"); ERR_print_errors_fp(stderr); test1_exit(10); } if(!EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_GCM_SET_IVLEN, in, NULL)) { fprintf(stderr,"IV length set failed\n"); ERR_print_errors_fp(stderr); test1_exit(11); } if(!EVP_EncryptInit_ex(&ctx,NULL,NULL,key,iv)) { fprintf(stderr,"Key/IV set failed\n"); ERR_print_errors_fp(stderr); test1_exit(12); } if (an && !EVP_EncryptUpdate(&ctx,NULL,&outl,aad,an)) { fprintf(stderr,"AAD set failed\n"); ERR_print_errors_fp(stderr); test1_exit(13); } } else if (mode == EVP_CIPH_CCM_MODE) { if(!EVP_EncryptInit_ex(&ctx,c,NULL,NULL,NULL)) { fprintf(stderr,"EncryptInit failed\n"); ERR_print_errors_fp(stderr); test1_exit(10); } if(!EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_CCM_SET_IVLEN, in, NULL)) { fprintf(stderr,"IV length set failed\n"); ERR_print_errors_fp(stderr); test1_exit(11); } if(!EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_CCM_SET_TAG, tn, NULL)) { fprintf(stderr,"Tag length set failed\n"); ERR_print_errors_fp(stderr); test1_exit(11); } if(!EVP_EncryptInit_ex(&ctx,NULL,NULL,key,iv)) { fprintf(stderr,"Key/IV set failed\n"); ERR_print_errors_fp(stderr); test1_exit(12); } if (!EVP_EncryptUpdate(&ctx,NULL,&outl,NULL,pn)) { fprintf(stderr,"Plaintext length set failed\n"); ERR_print_errors_fp(stderr); test1_exit(12); } if (an && !EVP_EncryptUpdate(&ctx,NULL,&outl,aad,an)) { fprintf(stderr,"AAD set failed\n"); ERR_print_errors_fp(stderr); test1_exit(13); } } else if(!EVP_EncryptInit_ex(&ctx,c,NULL,key,iv)) { fprintf(stderr,"EncryptInit failed\n"); ERR_print_errors_fp(stderr); test1_exit(10); } EVP_CIPHER_CTX_set_padding(&ctx,0); if(!EVP_EncryptUpdate(&ctx,out,&outl,plaintext,pn)) { fprintf(stderr,"Encrypt failed\n"); ERR_print_errors_fp(stderr); test1_exit(6); } if(!EVP_EncryptFinal_ex(&ctx,out+outl,&outl2)) { fprintf(stderr,"EncryptFinal failed\n"); ERR_print_errors_fp(stderr); test1_exit(7); } if(outl+outl2 != cn) { fprintf(stderr,"Ciphertext length mismatch got %d expected %d\n", outl+outl2,cn); test1_exit(8); } if(memcmp(out,ciphertext,cn)) { fprintf(stderr,"Ciphertext mismatch\n"); hexdump(stderr,"Got",out,cn); hexdump(stderr,"Expected",ciphertext,cn); test1_exit(9); } if (mode == EVP_CIPH_GCM_MODE || mode == EVP_CIPH_CCM_MODE) { unsigned char rtag[16]; /* Note: EVP_CTRL_CCM_GET_TAG has same value as * EVP_CTRL_GCM_GET_TAG */ if (!EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_GCM_GET_TAG, tn, rtag)) { fprintf(stderr,"Get tag failed\n"); ERR_print_errors_fp(stderr); test1_exit(14); } if (memcmp(rtag, tag, tn)) { fprintf(stderr,"Tag mismatch\n"); hexdump(stderr,"Got",rtag,tn); hexdump(stderr,"Expected",tag,tn); test1_exit(9); } } } if (encdec <= 0) { if (mode == EVP_CIPH_GCM_MODE) { if(!EVP_DecryptInit_ex(&ctx,c,NULL,NULL,NULL)) { fprintf(stderr,"EncryptInit failed\n"); ERR_print_errors_fp(stderr); test1_exit(10); } if(!EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_GCM_SET_IVLEN, in, NULL)) { fprintf(stderr,"IV length set failed\n"); ERR_print_errors_fp(stderr); test1_exit(11); } if(!EVP_DecryptInit_ex(&ctx,NULL,NULL,key,iv)) { fprintf(stderr,"Key/IV set failed\n"); ERR_print_errors_fp(stderr); test1_exit(12); } if (!EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_GCM_SET_TAG, tn, (void *)tag)) { fprintf(stderr,"Set tag failed\n"); ERR_print_errors_fp(stderr); test1_exit(14); } if (an && !EVP_DecryptUpdate(&ctx,NULL,&outl,aad,an)) { fprintf(stderr,"AAD set failed\n"); ERR_print_errors_fp(stderr); test1_exit(13); } } else if (mode == EVP_CIPH_CCM_MODE) { if(!EVP_DecryptInit_ex(&ctx,c,NULL,NULL,NULL)) { fprintf(stderr,"DecryptInit failed\n"); ERR_print_errors_fp(stderr); test1_exit(10); } if(!EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_CCM_SET_IVLEN, in, NULL)) { fprintf(stderr,"IV length set failed\n"); ERR_print_errors_fp(stderr); test1_exit(11); } if(!EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_CCM_SET_TAG, tn, (void *)tag)) { fprintf(stderr,"Tag length set failed\n"); ERR_print_errors_fp(stderr); test1_exit(11); } if(!EVP_DecryptInit_ex(&ctx,NULL,NULL,key,iv)) { fprintf(stderr,"Key/Nonce set failed\n"); ERR_print_errors_fp(stderr); test1_exit(12); } if (!EVP_DecryptUpdate(&ctx,NULL,&outl,NULL,pn)) { fprintf(stderr,"Plaintext length set failed\n"); ERR_print_errors_fp(stderr); test1_exit(12); } if (an && !EVP_EncryptUpdate(&ctx,NULL,&outl,aad,an)) { fprintf(stderr,"AAD set failed\n"); ERR_print_errors_fp(stderr); test1_exit(13); } } else if(!EVP_DecryptInit_ex(&ctx,c,NULL,key,iv)) { fprintf(stderr,"DecryptInit failed\n"); ERR_print_errors_fp(stderr); test1_exit(11); } EVP_CIPHER_CTX_set_padding(&ctx,0); if(!EVP_DecryptUpdate(&ctx,out,&outl,ciphertext,cn)) { fprintf(stderr,"Decrypt failed\n"); ERR_print_errors_fp(stderr); test1_exit(6); } if(mode != EVP_CIPH_CCM_MODE && !EVP_DecryptFinal_ex(&ctx,out+outl,&outl2)) { fprintf(stderr,"DecryptFinal failed\n"); ERR_print_errors_fp(stderr); test1_exit(7); } if(outl+outl2 != pn) { fprintf(stderr,"Plaintext length mismatch got %d expected %d\n", outl+outl2,pn); test1_exit(8); } if(memcmp(out,plaintext,pn)) { fprintf(stderr,"Plaintext mismatch\n"); hexdump(stderr,"Got",out,pn); hexdump(stderr,"Expected",plaintext,pn); test1_exit(9); } } EVP_CIPHER_CTX_cleanup(&ctx); printf("\n"); }