X509_ALGOR *PKCS5_pbe2_set(const EVP_CIPHER *cipher, int iter, unsigned char *salt, int saltlen) { X509_ALGOR *scheme = NULL, *kalg = NULL, *ret = NULL; int alg_nid; EVP_CIPHER_CTX ctx; unsigned char iv[EVP_MAX_IV_LENGTH]; PBKDF2PARAM *kdf = NULL; PBE2PARAM *pbe2 = NULL; ASN1_OCTET_STRING *osalt = NULL; ASN1_OBJECT *obj; alg_nid = EVP_CIPHER_type(cipher); if (alg_nid == NID_undef) { ASN1err(ASN1_F_PKCS5_PBE2_SET, ASN1_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 = obj; if (!(scheme->parameter = ASN1_TYPE_new())) goto merr; /* Create random IV */ if (EVP_CIPHER_iv_length(cipher) && RAND_pseudo_bytes(iv, EVP_CIPHER_iv_length(cipher)) < 0) goto err; EVP_CIPHER_CTX_init(&ctx); /* Dummy cipherinit to just setup the IV */ EVP_CipherInit_ex(&ctx, cipher, NULL, NULL, iv, 0); if (EVP_CIPHER_param_to_asn1(&ctx, scheme->parameter) < 0) { ASN1err(ASN1_F_PKCS5_PBE2_SET, ASN1_R_ERROR_SETTING_CIPHER_PARAMS); EVP_CIPHER_CTX_cleanup(&ctx); goto err; } EVP_CIPHER_CTX_cleanup(&ctx); if (!(kdf = PBKDF2PARAM_new())) goto merr; if (!(osalt = M_ASN1_OCTET_STRING_new())) goto merr; if (!saltlen) saltlen = PKCS5_SALT_LEN; if (!(osalt->data = OPENSSL_malloc(saltlen))) goto merr; osalt->length = saltlen; if (salt) memcpy(osalt->data, salt, saltlen); else if (RAND_pseudo_bytes(osalt->data, saltlen) < 0) goto merr; if (iter <= 0) iter = PKCS5_DEFAULT_ITER; if (!ASN1_INTEGER_set(kdf->iter, iter)) goto merr; /* Now include salt in kdf structure */ kdf->salt->value.octet_string = osalt; kdf->salt->type = V_ASN1_OCTET_STRING; osalt = NULL; /* If its RC2 then we'd better setup the key length */ if (alg_nid == NID_rc2_cbc) { if (!(kdf->keylength = M_ASN1_INTEGER_new())) goto merr; if (!ASN1_INTEGER_set(kdf->keylength, EVP_CIPHER_key_length(cipher))) goto merr; } /* prf can stay NULL because we are using hmacWithSHA1 */ /* Now setup the PBE2PARAM keyfunc structure */ pbe2->keyfunc->algorithm = OBJ_nid2obj(NID_id_pbkdf2); /* Encode PBKDF2PARAM into parameter of pbe2 */ if (!(pbe2->keyfunc->parameter = ASN1_TYPE_new())) goto merr; if (!ASN1_pack_string_of(PBKDF2PARAM, kdf, i2d_PBKDF2PARAM, &pbe2->keyfunc->parameter->value.sequence)) goto merr; pbe2->keyfunc->parameter->type = V_ASN1_SEQUENCE; PBKDF2PARAM_free(kdf); kdf = NULL; /* Now set up top level AlgorithmIdentifier */ if (!(ret = X509_ALGOR_new())) goto merr; if (!(ret->parameter = ASN1_TYPE_new())) goto merr; ret->algorithm = OBJ_nid2obj(NID_pbes2); /* Encode PBE2PARAM into parameter */ if (!ASN1_pack_string_of(PBE2PARAM, pbe2, i2d_PBE2PARAM, &ret->parameter->value.sequence)) goto merr; ret->parameter->type = V_ASN1_SEQUENCE; PBE2PARAM_free(pbe2); pbe2 = NULL; return ret; merr: ASN1err(ASN1_F_PKCS5_PBE2_SET, ERR_R_MALLOC_FAILURE); err: PBE2PARAM_free(pbe2); /* Note 'scheme' is freed as part of pbe2 */ M_ASN1_OCTET_STRING_free(osalt); PBKDF2PARAM_free(kdf); X509_ALGOR_free(kalg); X509_ALGOR_free(ret); return NULL; }
int cmeCipherByteString (const unsigned char *srcBuf, unsigned char **dstBuf, unsigned char **salt, const int srcLen, int *dstWritten, const char *algorithm, const char *ctPassword, const char mode) { int result; int cont=0; int exitcode=0; int written=0; int cipherBlockLen=0; int keyLen=0; int ivLen=0; unsigned char *key=NULL; unsigned char *iv=NULL; unsigned char *byteSalt=NULL; unsigned char hexStrbyteSalt[evpSaltBufferSize*2+1]; //Space for an hex str representation of an evpSaltBufferSize long, byte salt EVP_CIPHER_CTX *ctx=NULL; const EVP_CIPHER *cipher=NULL; //Note that cipher is a pointer to a constant cipher function in OPENSSL. #define cmeCipherByteStringFree() \ do { \ if (key) \ { \ memset(key,0,keyLen); \ cmeFree(key); \ } \ if (iv) \ { \ memset(iv,0,ivLen); \ cmeFree(iv); \ } \ if (byteSalt) \ { \ memset(byteSalt,0,evpSaltBufferSize); \ cmeFree(byteSalt); \ } \ cmeFree(ctx); \ } while (0); //Local free() macro if (srcBuf==NULL) //Error, source buffer can't be null! { #ifdef ERROR_LOG fprintf(stderr,"CaumeDSE Error: cmeCipherByteString(), srcBuf is NULL!\n"); #endif cmeCipherByteStringFree(); return(1); } if (cmeGetCipher(&cipher,algorithm)) //Verify algorithm and get cipher object. { #ifdef ERROR_LOG fprintf(stderr,"CaumeDSE Error: cmeCipherByteString(), incorrect cipher algorithm: %s!\n",algorithm); #endif cmeCipherByteStringFree(); return(2); } cipherBlockLen=EVP_CIPHER_block_size(cipher); //Get cipher block length. keyLen=EVP_CIPHER_key_length(cipher); //Get cipher key length. ivLen=EVP_CIPHER_iv_length(cipher); //Get cipher iv length. if (mode=='e') //Encryption mode { if (!(*salt)) //if salt==NULL, We need to generate salt and return it in hexStr format. { //Otherwise we use the salt provided by the caller. cmePrngGetBytes(&byteSalt,evpSaltBufferSize); cmeBytesToHexstr(byteSalt,salt,evpSaltBufferSize); //We need to return str representation of salt. //Note:Caller must free memory for salt! #ifdef DEBUG fprintf(stdout,"CaumeDSE Debug: cmeCipherByteString(), salt parameter is NULL; " "defining new random salt: %s.\n",*salt); #endif } else { strncpy((char *)hexStrbyteSalt,(char *)*salt,evpSaltBufferSize*2); hexStrbyteSalt[evpSaltBufferSize*2]='\0'; if ((cmeHexstrToBytes(&byteSalt,hexStrbyteSalt))) // Error, salt is not a hexStr representation! { #ifdef ERROR_LOG fprintf(stderr,"CaumeDSE Error: cmeCipherByteString(), salt is not a " "hexStr representation; string: %s !\n",hexStrbyteSalt); #endif cmeCipherByteStringFree(); return(3); } } } else if (mode=='d') //Decryption mode { strncpy((char *)hexStrbyteSalt,(char *)*salt,evpSaltBufferSize*2); hexStrbyteSalt[evpSaltBufferSize*2]='\0'; if ((cmeHexstrToBytes(&byteSalt,hexStrbyteSalt))) // Error, salt is not a hexStr representation! { cmeCipherByteStringFree(); return(4); } } else //Error, unknown mode! { #ifdef ERROR_LOG fprintf(stderr,"CaumeDSE Error: cmeCipherByteString(), Unknown cipher mode %c !\n",mode); #endif return(5); } if(!(*dstBuf=(unsigned char *)malloc(srcLen+cipherBlockLen+1))) //Error allocating memory! { //Note: Caller must free *dstBuf! #ifdef ERROR_LOG fprintf(stderr,"CaumeDSE Error: cmeCipherByteString(), Error in memory allocation!\n"); #endif cmeCipherByteStringFree(); return(6); } memset(*dstBuf,0,srcLen+cipherBlockLen+1); // we add 1 block more (for encryption padding). + 1 for null ending for unencrypted strings key=(unsigned char *)malloc(keyLen); iv=(unsigned char *)malloc(ivLen); if ((cmePBKDF(cipher,byteSalt,evpSaltBufferSize,(unsigned char *)ctPassword,strlen(ctPassword),key,iv))) //Error setting key & IV. { cmeCipherByteStringFree(); return(7); } else //Key & IV set; proceed. { cmeCipherInit(&ctx,NULL,cipher,key,iv,mode); cont=0; cmeCipherUpdate(ctx,(*dstBuf),&written,(unsigned char *)srcBuf,srcLen,mode); cont+=written; result=cmeCipherFinal(&ctx,((*dstBuf)+cont),&written,mode); exitcode+=result; cont += written; *dstWritten=cont; (*dstBuf)[cont]='\0'; //Decryption does not guarantee that an unencrypted string will be null terminated. } cmeCipherByteStringFree(); return (exitcode);
int cipher_kt_key_size (const EVP_CIPHER *cipher_kt) { return EVP_CIPHER_key_length (cipher_kt); }
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; ASN1_OBJECT *obj; alg_nid = EVP_CIPHER_type(cipher); if (alg_nid == NID_undef) { ASN1err(ASN1_F_PKCS5_PBE2_SET_IV, ASN1_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 = 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)) <= 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 (EVP_CIPHER_param_to_asn1(&ctx, scheme->parameter) < 0) { ASN1err(ASN1_F_PKCS5_PBE2_SET_IV, ASN1_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 = 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: ASN1err(ASN1_F_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; }
// return EVP cipher key size static int cryptoGetEVPCipherSize(struct s_crypto_cipher *st_cipher) { return EVP_CIPHER_key_length(st_cipher->cipher); }
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); }
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 void sl_generate_key (void){ char* pass, *ctype, *dtype; SLang_BString_Type* salta; const EVP_CIPHER *cipher; const EVP_MD *md; unsigned char *salt; unsigned char *key; unsigned char *iv; SLang_BString_Type* outkey, *outiv; int count,i,keylen,ivlen,saltlen; if (SLang_Num_Function_Args != 5 || SLang_pop_slstring(&dtype) == -1 || SLang_pop_slstring(&ctype) == -1 ){ return; } cipher = EVP_get_cipherbyname(ctype); if (!cipher){ SLang_verror(SL_UNDEFINED_NAME,"could not find cipher %s",ctype); SLang_free_slstring(ctype); return; } md = EVP_get_digestbyname(dtype); if (!md){ SLang_verror(SL_UNDEFINED_NAME,"could not find digest %s",dtype); SLang_free_slstring(ctype); SLang_free_slstring(dtype); return; } if (SLang_pop_integer(&count) == -1 || SLang_pop_bstring(&salta) == -1 || SLang_pop_slstring(&pass) == -1 ){ return; } keylen = EVP_CIPHER_key_length(cipher); ivlen = EVP_CIPHER_iv_length(cipher); key = (char*)malloc(keylen); iv = (char*)malloc(ivlen); salt = SLbstring_get_pointer(salta,&saltlen); if (saltlen==0){ salt=NULL; } else if (saltlen!=8){ SLang_verror(SL_USAGE_ERROR,"Salt must not exceed 8 bytes"); SLbstring_free(salta); SLang_free_slstring(pass); SLang_free_slstring(ctype); SLang_free_slstring(dtype); return; } EVP_BytesToKey(cipher,md,salt,pass,(int)strlen(pass),count,key,iv); outkey = SLbstring_create(key, keylen); outiv = SLbstring_create(iv, ivlen); SLang_push_bstring(outkey); SLang_push_bstring(outiv); SLbstring_free(salta); SLbstring_free(outkey); SLbstring_free(outiv); SLang_free_slstring(pass); SLang_free_slstring(ctype); SLang_free_slstring(dtype); free(key);free(iv); }
int enc_main(const int argc, const char *argv[]) { //fprintf(stderr, "Calling encryption main with args:\n"); if (argc < 4) { fprintf(stderr, "Insufficient arguments."); printUsage(); } const char *startup_path = argv[0]; const char *cipher_name = argv[1]; const char *digest_name = argv[2]; const char *rootDir = argv[3]; int maxKey = 0; int i = 0; for (i = 0; i < argc; i++) { char arg[strlen(argv[i]) + 1]; strcpy(arg, argv[i]); strcat(arg, "\n"); fprintf(stderr, arg); } /* cipher_name is used as it's position is the first argument */ if (strcmp(cipher_name, "-lc") == 0) { printAvailableCiphers(); return 0; } else if (strcmp(cipher_name, "-ld") == 0) { printAvailableDigests(); return 0; } /* Load the human readable error strings for libcrypto */ ERR_load_crypto_strings(); /* Load all digest and cipher algorithms */ OpenSSL_add_all_algorithms(); /* Load config file, and other important initialisation */ OPENSSL_config(NULL); /*TODO: ... Do some crypto stuff here ... */ const EVP_CIPHER *cipher = EVP_get_cipherbyname(cipher_name); const EVP_MD *dgst = EVP_get_digestbyname(digest_name); unsigned char key[EVP_MAX_KEY_LENGTH]; unsigned char iv[EVP_MAX_IV_LENGTH]; const char* password = "******"; const unsigned char *salt = NULL; if (!cipher) { fprintf(stderr, "Error loading %s algorithm, please use a different one.\n" "Use -lc to view a list of available ciphers.\n" "Example: %s -enc -lc\n", cipher_name, startup_path); } else { fprintf(stdout, "Successfully loaded %s algorithm.\n", cipher_name); maxKey = EVP_CIPHER_key_length(cipher) * 8; fprintf(stdout, "Using a %d bit key.\n", maxKey); } if (!dgst) { fprintf(stderr, "Couldn't load digest %s.\n" "Use -ld to view a list of available ciphers.\n" "Example: %s -enc -ld\n", digest_name, startup_path); } else { fprintf(stdout, "Successfully loaded %s digest.\n", digest_name); } if (!EVP_BytesToKey(cipher, dgst, salt, (unsigned char *) password, strlen(password), 1, key, iv)) { fprintf(stderr, "Key creation failed.\n"); return 1; } else { //printf("Key: "); for(i=0; i<cipher->key_len; ++i) { printf("%02x", key[i]); } printf("\n"); //printf("IV: "); for(i=0; i<cipher->iv_len; ++i) { printf("%02x", iv[i]); } printf("\n"); fprintf(stdout,"Key succesfully generated\n"); } if(enc_dir_recursive(rootDir)) { } else { fprintf(stderr,"Encryption failed.\n"); } /* Clean up */ /* Removes all digests and ciphers */ EVP_cleanup(); /* if you omit the next, a small leak may be left when you make use of the BIO (low level API) for e.g. base64 transformations */ CRYPTO_cleanup_all_ex_data(); /* Remove error strings */ ERR_free_strings(); 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) { ret = HX509_CRYPTO_INTERNAL_ERROR; hx509_set_error_string(context, 0, ret, "Failed to do string2key for private key"); goto out; } 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; #if OPENSSL_VERSION_NUMBER < 0x10100000UL EVP_CIPHER_CTX ctxst; ctx = &ctxst; EVP_CIPHER_CTX_init(ctx); #else ctx = EVP_CIPHER_CTX_new(); #endif EVP_CipherInit_ex(ctx, c, NULL, key, ivdata, 0); EVP_Cipher(ctx, clear.data, cipher, len); #if OPENSSL_VERSION_NUMBER < 0x10100000UL EVP_CIPHER_CTX_cleanup(ctx); #else EVP_CIPHER_CTX_free(ctx); #endif } 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 sqlcipher_openssl_get_key_sz(void *ctx) { return EVP_CIPHER_key_length(((openssl_ctx *)ctx)->evp_cipher); }
BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio) { int i; BIO *out = NULL, *btmp = NULL; X509_ALGOR *xa = NULL; const EVP_CIPHER *evp_cipher = NULL; STACK_OF(X509_ALGOR) *md_sk = NULL; STACK_OF(PKCS7_RECIP_INFO) *rsk = NULL; X509_ALGOR *xalg = NULL; PKCS7_RECIP_INFO *ri = NULL; ASN1_OCTET_STRING *os = NULL; if (p7 == NULL) { PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_INVALID_NULL_POINTER); return NULL; } /* * The content field in the PKCS7 ContentInfo is optional, but that really * only applies to inner content (precisely, detached signatures). * * When reading content, missing outer content is therefore treated as an * error. * * When creating content, PKCS7_content_new() must be called before * calling this method, so a NULL p7->d is always an error. */ if (p7->d.ptr == NULL) { PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_NO_CONTENT); return NULL; } i = OBJ_obj2nid(p7->type); p7->state = PKCS7_S_HEADER; switch (i) { case NID_pkcs7_signed: md_sk = p7->d.sign->md_algs; os = PKCS7_get_octet_string(p7->d.sign->contents); break; case NID_pkcs7_signedAndEnveloped: rsk = p7->d.signed_and_enveloped->recipientinfo; md_sk = p7->d.signed_and_enveloped->md_algs; xalg = p7->d.signed_and_enveloped->enc_data->algorithm; evp_cipher = p7->d.signed_and_enveloped->enc_data->cipher; if (evp_cipher == NULL) { PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_CIPHER_NOT_INITIALIZED); goto err; } break; case NID_pkcs7_enveloped: rsk = p7->d.enveloped->recipientinfo; xalg = p7->d.enveloped->enc_data->algorithm; evp_cipher = p7->d.enveloped->enc_data->cipher; if (evp_cipher == NULL) { PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_CIPHER_NOT_INITIALIZED); goto err; } break; case NID_pkcs7_digest: xa = p7->d.digest->md; os = PKCS7_get_octet_string(p7->d.digest->contents); break; case NID_pkcs7_data: break; default: PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_UNSUPPORTED_CONTENT_TYPE); goto err; } for (i = 0; i < sk_X509_ALGOR_num(md_sk); i++) if (!PKCS7_bio_add_digest(&out, sk_X509_ALGOR_value(md_sk, i))) goto err; if (xa && !PKCS7_bio_add_digest(&out, xa)) goto err; if (evp_cipher != NULL) { unsigned char key[EVP_MAX_KEY_LENGTH]; unsigned char iv[EVP_MAX_IV_LENGTH]; int keylen, ivlen; EVP_CIPHER_CTX *ctx; if ((btmp = BIO_new(BIO_f_cipher())) == NULL) { PKCS7err(PKCS7_F_PKCS7_DATAINIT, ERR_R_BIO_LIB); goto err; } BIO_get_cipher_ctx(btmp, &ctx); keylen = EVP_CIPHER_key_length(evp_cipher); ivlen = EVP_CIPHER_iv_length(evp_cipher); xalg->algorithm = OBJ_nid2obj(EVP_CIPHER_type(evp_cipher)); if (ivlen > 0) if (RAND_bytes(iv, ivlen) <= 0) goto err; if (EVP_CipherInit_ex(ctx, evp_cipher, NULL, NULL, NULL, 1) <= 0) goto err; if (EVP_CIPHER_CTX_rand_key(ctx, key) <= 0) goto err; if (EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, 1) <= 0) goto err; if (ivlen > 0) { if (xalg->parameter == NULL) { xalg->parameter = ASN1_TYPE_new(); if (xalg->parameter == NULL) goto err; } if (EVP_CIPHER_param_to_asn1(ctx, xalg->parameter) < 0) goto err; } /* Lets do the pub key stuff :-) */ for (i = 0; i < sk_PKCS7_RECIP_INFO_num(rsk); i++) { ri = sk_PKCS7_RECIP_INFO_value(rsk, i); if (pkcs7_encode_rinfo(ri, key, keylen) <= 0) goto err; } OPENSSL_cleanse(key, keylen); if (out == NULL) out = btmp; else BIO_push(out, btmp); btmp = NULL; } if (bio == NULL) { if (PKCS7_is_detached(p7)) bio = BIO_new(BIO_s_null()); else if (os && os->length > 0) bio = BIO_new_mem_buf(os->data, os->length); if (bio == NULL) { bio = BIO_new(BIO_s_mem()); if (bio == NULL) goto err; BIO_set_mem_eof_return(bio, 0); } } if (out) BIO_push(out, bio); else out = bio; return out; err: BIO_free_all(out); BIO_free_all(btmp); return NULL; }
int main(int argc, char **argv) { TSS_HKEY hSrk, hKey; TSS_HENCDATA hEncdata; TSS_HPOLICY hPolicy; int iRc = -1; struct option opts[] = { {"infile", required_argument, NULL, 'i'}, {"outfile", required_argument, NULL, 'o'}, {"pcr", required_argument, NULL, 'p'}, {"unicode", no_argument, NULL, 'u'}, {"well-known", no_argument, NULL, 'z'} }; unsigned char line[EVP_CIPHER_block_size(EVP_aes_256_cbc()) * 16]; int lineLen; unsigned char encData[sizeof(line) + EVP_CIPHER_block_size(EVP_aes_256_cbc())]; int encDataLen; UINT32 encLen, i; BYTE *encKey; BYTE *randKey = NULL; UINT32 sealKeyLen; BYTE *sealKey; TSS_FLAG keyFlags = TSS_KEY_TYPE_STORAGE | TSS_KEY_SIZE_2048 | TSS_KEY_VOLATILE | TSS_KEY_AUTHORIZATION | TSS_KEY_NOT_MIGRATABLE; TSS_HPOLICY hSrkPolicy; char *passwd = NULL; int pswd_len; BYTE wellKnown[TCPA_SHA1_160_HASH_LEN] = TSS_WELL_KNOWN_SECRET; BIO *bin = NULL, *bdata=NULL, *b64=NULL; initIntlSys(); if (genericOptHandler(argc, argv, "i:o:p:uz", opts, sizeof(opts) / sizeof(struct option), parse, help) != 0) goto out; if (contextCreate(&hContext) != TSS_SUCCESS) goto out; if (contextConnect(hContext) != TSS_SUCCESS) goto out_close; if (contextGetTpm(hContext, &hTpm) != TSS_SUCCESS) goto out_close; /* Create a BIO for the input file */ if ((bin = BIO_new(BIO_s_file())) == NULL) { logError(_("Unable to open input BIO\n")); goto out_close; } /* Assign the input file to the BIO */ if (strlen(in_filename) == 0) BIO_set_fp(bin, stdin, BIO_NOCLOSE); else if (!BIO_read_filename(bin, in_filename)) { logError(_("Unable to open input file: %s\n"), in_filename); goto out_close; } /* Create the PCRs object. If any PCRs above 15 are selected, this will need to be * a 1.2 TSS/TPM */ if (selectedPcrsLen) { TSS_FLAG initFlag = 0; UINT32 pcrSize; BYTE *pcrValue; for (i = 0; i < selectedPcrsLen; i++) { if (selectedPcrs[i] > 15) { #ifdef TSS_LIB_IS_12 initFlag |= TSS_PCRS_STRUCT_INFO_LONG; #else logError(_("This version of %s was compiled for a v1.1 TSS, which " "can only seal\n data to PCRs 0-15. PCR %u is out of range" "\n"), argv[0], selectedPcrs[i]); goto out_close; #endif } } if (contextCreateObject(hContext, TSS_OBJECT_TYPE_PCRS, initFlag, &hPcrs) != TSS_SUCCESS) goto out_close; for (i = 0; i < selectedPcrsLen; i++) { if (tpmPcrRead(hTpm, selectedPcrs[i], &pcrSize, &pcrValue) != TSS_SUCCESS) goto out_close; if (pcrcompositeSetPcrValue(hPcrs, selectedPcrs[i], pcrSize, pcrValue) != TSS_SUCCESS) goto out_close; } #ifdef TSS_LIB_IS_12 if (initFlag) { UINT32 localityValue = TPM_LOC_ZERO | TPM_LOC_ONE | TPM_LOC_TWO | TPM_LOC_THREE | TPM_LOC_FOUR; if (pcrcompositeSetPcrLocality(hPcrs, localityValue) != TSS_SUCCESS) goto out_close; } #endif } /* Retrieve random data to be used as the symmetric key (this key will encrypt the input file contents) */ if (tpmGetRandom(hTpm, EVP_CIPHER_key_length(EVP_aes_256_cbc()), &randKey) != TSS_SUCCESS) goto out_close; /* Load the SRK and set the SRK policy (no password) */ if (keyLoadKeyByUUID(hContext, TSS_PS_TYPE_SYSTEM, SRK_UUID, &hSrk) != TSS_SUCCESS) goto out_close; /* Use the context's default policy for the SRK secret */ if (policyGet(hSrk, &hSrkPolicy) != TSS_SUCCESS) goto out_close; /* Prompt for SRK password */ if (!isWellKnown) { passwd = _GETPASSWD(_("Enter SRK password: "******"Failed to get SRK password\n")); goto out_close; } } else { passwd = (char *)wellKnown; pswd_len = sizeof(wellKnown); } if (policySetSecret(hSrkPolicy, (UINT32)pswd_len, (BYTE *)passwd) != TSS_SUCCESS) goto out_close; if (!isWellKnown) shredPasswd(passwd); passwd = NULL; /* Build an RSA key object that will be created by the TPM (this will encrypt and protect the symmetric key) */ if (contextCreateObject (hContext, TSS_OBJECT_TYPE_RSAKEY, keyFlags, &hKey) != TSS_SUCCESS) goto out_close; if (contextCreateObject (hContext, TSS_OBJECT_TYPE_POLICY, TSS_POLICY_USAGE, &hPolicy) != TSS_SUCCESS) goto out_close; if (policySetSecret(hPolicy, strlen(TPMSEAL_SECRET), (BYTE *)TPMSEAL_SECRET) != TSS_SUCCESS) goto out_close; if (policyAssign(hPolicy, hKey) != TSS_SUCCESS) goto out_close; /* Create the RSA key (under the SRK) */ if (keyCreateKey(hKey, hSrk, NULL_HPCRS) != TSS_SUCCESS) goto out_close; /* Load the newly created RSA key */ if (keyLoadKey(hKey, hSrk) != TSS_SUCCESS) goto out_close; /* Build an encrypted data object that will hold the encrypted version of the symmetric key */ if (contextCreateObject (hContext, TSS_OBJECT_TYPE_ENCDATA, TSS_ENCDATA_SEAL, &hEncdata) != TSS_SUCCESS) goto out_close; if (contextCreateObject (hContext, TSS_OBJECT_TYPE_POLICY, TSS_POLICY_USAGE, &hPolicy) != TSS_SUCCESS) goto out_close; if (policySetSecret(hPolicy, strlen(TPMSEAL_SECRET), (BYTE *)TPMSEAL_SECRET) != TSS_SUCCESS) goto out_close; if (policyAssign(hPolicy, hEncdata) != TSS_SUCCESS) goto out_close; /* Encrypt and seal the symmetric key */ if (dataSeal (hEncdata, hKey, EVP_CIPHER_key_length(EVP_aes_256_cbc()), randKey, hPcrs) != TSS_SUCCESS) goto out_close; if (getAttribData(hEncdata, TSS_TSPATTRIB_ENCDATA_BLOB, TSS_TSPATTRIB_ENCDATABLOB_BLOB, &encLen, &encKey) != TSS_SUCCESS) goto out_close; if (getAttribData (hKey, TSS_TSPATTRIB_KEY_BLOB, TSS_TSPATTRIB_KEYBLOB_BLOB, &sealKeyLen, &sealKey) != TSS_SUCCESS) goto out_close; /* Create a BIO to perform base64 encoding */ if ((b64 = BIO_new(BIO_f_base64())) == NULL) { logError(_("Unable to open base64 BIO\n")); goto out_close; } /* Create a BIO for the output file */ if ((bdata = BIO_new(BIO_s_file())) == NULL) { logError(_("Unable to open output BIO\n")); goto out_close; } /* Assign the output file to the BIO */ if (strlen(out_filename) == 0) BIO_set_fp(bdata, stdout, BIO_NOCLOSE); else if (BIO_write_filename(bdata, out_filename) <= 0) { logError(_("Unable to open output file: %s\n"), out_filename); goto out_close; } /* Output the sealed data header string */ BIO_puts(bdata, TPMSEAL_HDR_STRING); /* Sealing key used on the TPM */ BIO_puts(bdata, TPMSEAL_TSS_STRING); bdata = BIO_push(b64, bdata); BIO_write(bdata, sealKey, sealKeyLen); if (BIO_flush(bdata) != 1) { logError(_("Unable to flush output\n")); goto out_close; } bdata = BIO_pop(b64); /* Sealed EVP Symmetric Key */ BIO_puts(bdata, TPMSEAL_EVP_STRING); BIO_puts(bdata, TPMSEAL_KEYTYPE_SYM); BIO_puts(bdata, TPMSEAL_CIPHER_AES256CBC); bdata = BIO_push(b64, bdata); BIO_write(bdata, encKey, encLen); if (BIO_flush(bdata) != 1) { logError(_("Unable to flush output\n")); goto out_close; } bdata = BIO_pop(b64); /* Encrypted Data */ BIO_puts(bdata, TPMSEAL_ENC_STRING); bdata = BIO_push(b64, bdata); EVP_CIPHER_CTX ctx; EVP_EncryptInit(&ctx, EVP_aes_256_cbc(), randKey, (unsigned char *)TPMSEAL_IV); while ((lineLen = BIO_read(bin, line, sizeof(line))) > 0) { EVP_EncryptUpdate(&ctx, encData, &encDataLen, line, lineLen); BIO_write(bdata, encData, encDataLen); } EVP_EncryptFinal(&ctx, encData, &encDataLen); BIO_write(bdata, encData, encDataLen); if (BIO_flush(bdata) != 1) { logError(_("Unable to flush output\n")); goto out_close; } bdata = BIO_pop(b64); BIO_puts( bdata, TPMSEAL_FTR_STRING); iRc = 0; logSuccess(argv[0]); out_close: contextClose(hContext); out: if (bin) BIO_free(bin); if (bdata) BIO_free(bdata); if (b64) BIO_free(b64); return iRc; }
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); EVP_CIPHER_CTX_set_flags(&ctx, EVP_CIPHER_CTX_FLAG_WRAP_ALLOW); 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 (mode == EVP_CIPH_WRAP_MODE) { if (!EVP_EncryptInit_ex(&ctx, c, NULL, key, in ? iv : NULL)) { fprintf(stderr, "EncryptInit failed\n"); ERR_print_errors_fp(stderr); test1_exit(10); } } 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 (mode == EVP_CIPH_WRAP_MODE) { if (!EVP_DecryptInit_ex(&ctx, c, NULL, key, in ? iv : NULL)) { fprintf(stderr, "EncryptInit failed\n"); ERR_print_errors_fp(stderr); test1_exit(10); } } 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"); }
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,buf[TLS_MD_MAX_CONST_SIZE+ SSL3_RANDOM_SIZE*2]; 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; const SSL_COMP *comp; const EVP_MD *m; int _exp,n,i,j,k,exp_label_len,cl; _exp=SSL_C_IS_EXPORT(s->s3->tmp.new_cipher); c=s->s3->tmp.new_sym_enc; m=s->s3->tmp.new_hash; comp=s->s3->tmp.new_compression; key_block=s->s3->tmp.key_block; if (which & SSL3_CC_READ) { if ((s->enc_read_ctx == NULL) && ((s->enc_read_ctx=(EVP_CIPHER_CTX *) OPENSSL_malloc(sizeof(EVP_CIPHER_CTX))) == NULL)) goto err; dd= s->enc_read_ctx; s->read_hash=m; 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; } memset(&(s->s3->read_sequence[0]),0,8); mac_secret= &(s->s3->read_mac_secret[0]); } else { if ((s->enc_write_ctx == NULL) && ((s->enc_write_ctx=(EVP_CIPHER_CTX *) OPENSSL_malloc(sizeof(EVP_CIPHER_CTX))) == NULL)) goto err; dd= s->enc_write_ctx; s->write_hash=m; 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; } } memset(&(s->s3->write_sequence[0]),0,8); mac_secret= &(s->s3->write_mac_secret[0]); } EVP_CIPHER_CTX_init(dd); p=s->s3->tmp.key_block; i=EVP_MD_size(m); cl=EVP_CIPHER_key_length(c); j=_exp ? (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,SSL_R_INTERNAL_ERROR); goto err2; } memcpy(mac_secret,ms,i); #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 (_exp) { /* In here I set both the read and write key/iv to the * same value since only the correct one will be used :-). */ p=buf; memcpy(p,exp_label,exp_label_len); p+=exp_label_len; memcpy(p,s->s3->client_random,SSL3_RANDOM_SIZE); p+=SSL3_RANDOM_SIZE; memcpy(p,s->s3->server_random,SSL3_RANDOM_SIZE); p+=SSL3_RANDOM_SIZE; tls1_PRF(s->ctx->md5,s->ctx->sha1,buf,(int)(p-buf),key,j, tmp1,tmp2,EVP_CIPHER_key_length(c)); key=tmp1; if (k > 0) { p=buf; memcpy(p,TLS_MD_IV_BLOCK_CONST, TLS_MD_IV_BLOCK_CONST_SIZE); p+=TLS_MD_IV_BLOCK_CONST_SIZE; memcpy(p,s->s3->client_random,SSL3_RANDOM_SIZE); p+=SSL3_RANDOM_SIZE; memcpy(p,s->s3->server_random,SSL3_RANDOM_SIZE); p+=SSL3_RANDOM_SIZE; tls1_PRF(s->ctx->md5,s->ctx->sha1,buf,p-buf,empty,0, iv1,iv2,k*2); if (client_write) iv=iv1; else iv= &(iv1[k]); } } s->session->key_arg_length=0; EVP_CipherInit(dd,c,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 memset(tmp1,0,sizeof(tmp1)); memset(tmp2,0,sizeof(tmp1)); memset(iv1,0,sizeof(iv1)); memset(iv2,0,sizeof(iv2)); return(1); err: SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE,ERR_R_MALLOC_FAILURE); err2: return(0); }
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; EVP_CIPHER_CTX *dd; const EVP_CIPHER *c; #ifndef OPENSSL_NO_COMP COMP_METHOD *comp; #endif const EVP_MD *m; int n, i, j, k, cl; int reuse_dd = 0; 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 = EVP_CIPHER_CTX_new()) == NULL) goto err; else /* * make sure it's intialized in case we exit later with an error */ EVP_CIPHER_CTX_reset(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 = EVP_CIPHER_CTX_new()) == NULL) goto err; else /* * make sure it's intialized in case we exit later with an error */ EVP_CIPHER_CTX_reset(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_reset(dd); p = s->s3->tmp.key_block; i = EVP_MD_size(m); if (i < 0) goto err2; cl = EVP_CIPHER_key_length(c); j = cl; 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; } else { n = i; ms = &(p[n]); n += i + j; key = &(p[n]); n += j + k; iv = &(p[n]); n += k; } if (n > s->s3->tmp.key_block_length) { SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE, ERR_R_INTERNAL_ERROR); goto err2; } memcpy(mac_secret, ms, i); 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)); 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); }
BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio) { int i; BIO *out=NULL,*btmp=NULL; X509_ALGOR *xa = NULL; const EVP_CIPHER *evp_cipher=NULL; STACK_OF(X509_ALGOR) *md_sk=NULL; STACK_OF(PKCS7_RECIP_INFO) *rsk=NULL; X509_ALGOR *xalg=NULL; PKCS7_RECIP_INFO *ri=NULL; EVP_PKEY *pkey; ASN1_OCTET_STRING *os=NULL; i=OBJ_obj2nid(p7->type); p7->state=PKCS7_S_HEADER; switch (i) { case NID_pkcs7_signed: md_sk=p7->d.sign->md_algs; os = PKCS7_get_octet_string(p7->d.sign->contents); break; case NID_pkcs7_signedAndEnveloped: rsk=p7->d.signed_and_enveloped->recipientinfo; md_sk=p7->d.signed_and_enveloped->md_algs; xalg=p7->d.signed_and_enveloped->enc_data->algorithm; evp_cipher=p7->d.signed_and_enveloped->enc_data->cipher; if (evp_cipher == NULL) { PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_CIPHER_NOT_INITIALIZED); goto err; } break; case NID_pkcs7_enveloped: rsk=p7->d.enveloped->recipientinfo; xalg=p7->d.enveloped->enc_data->algorithm; evp_cipher=p7->d.enveloped->enc_data->cipher; if (evp_cipher == NULL) { PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_CIPHER_NOT_INITIALIZED); goto err; } break; case NID_pkcs7_digest: xa = p7->d.digest->md; os = PKCS7_get_octet_string(p7->d.digest->contents); break; default: PKCS7err(PKCS7_F_PKCS7_DATAINIT,PKCS7_R_UNSUPPORTED_CONTENT_TYPE); goto err; } for (i=0; i<sk_X509_ALGOR_num(md_sk); i++) if (!PKCS7_bio_add_digest(&out, sk_X509_ALGOR_value(md_sk, i))) goto err; if (xa && !PKCS7_bio_add_digest(&out, xa)) goto err; if (evp_cipher != NULL) { unsigned char key[EVP_MAX_KEY_LENGTH]; unsigned char iv[EVP_MAX_IV_LENGTH]; int keylen,ivlen; int jj,max; unsigned char *tmp; EVP_CIPHER_CTX *ctx; if ((btmp=BIO_new(BIO_f_cipher())) == NULL) { PKCS7err(PKCS7_F_PKCS7_DATAINIT,ERR_R_BIO_LIB); goto err; } BIO_get_cipher_ctx(btmp, &ctx); keylen=EVP_CIPHER_key_length(evp_cipher); ivlen=EVP_CIPHER_iv_length(evp_cipher); xalg->algorithm = OBJ_nid2obj(EVP_CIPHER_type(evp_cipher)); if (ivlen > 0) RAND_pseudo_bytes(iv,ivlen); if (EVP_CipherInit_ex(ctx, evp_cipher, NULL, NULL, NULL, 1)<=0) goto err; if (EVP_CIPHER_CTX_rand_key(ctx, key) <= 0) goto err; if (EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, 1) <= 0) goto err; if (ivlen > 0) { if (xalg->parameter == NULL) xalg->parameter=ASN1_TYPE_new(); if(EVP_CIPHER_param_to_asn1(ctx, xalg->parameter) < 0) goto err; } /* Lets do the pub key stuff :-) */ max=0; for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++) { ri=sk_PKCS7_RECIP_INFO_value(rsk,i); if (ri->cert == NULL) { PKCS7err(PKCS7_F_PKCS7_DATAINIT,PKCS7_R_MISSING_CERIPEND_INFO); goto err; } pkey=X509_get_pubkey(ri->cert); jj=EVP_PKEY_size(pkey); EVP_PKEY_free(pkey); if (max < jj) max=jj; } if ((tmp=(unsigned char *)OPENSSL_malloc(max)) == NULL) { PKCS7err(PKCS7_F_PKCS7_DATAINIT,ERR_R_MALLOC_FAILURE); goto err; } for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++) { ri=sk_PKCS7_RECIP_INFO_value(rsk,i); pkey=X509_get_pubkey(ri->cert); jj=EVP_PKEY_encrypt(tmp,key,keylen,pkey); EVP_PKEY_free(pkey); if (jj <= 0) { PKCS7err(PKCS7_F_PKCS7_DATAINIT,ERR_R_EVP_LIB); OPENSSL_free(tmp); goto err; } if (!M_ASN1_OCTET_STRING_set(ri->enc_key,tmp,jj)) { PKCS7err(PKCS7_F_PKCS7_DATAINIT, ERR_R_MALLOC_FAILURE); OPENSSL_free(tmp); goto err; } } OPENSSL_free(tmp); OPENSSL_cleanse(key, keylen); if (out == NULL) out=btmp; else BIO_push(out,btmp); btmp=NULL; } if (bio == NULL) { if (PKCS7_is_detached(p7)) bio=BIO_new(BIO_s_null()); else if (os && os->length > 0) bio = BIO_new_mem_buf(os->data, os->length); if(bio == NULL) { bio=BIO_new(BIO_s_mem()); BIO_set_mem_eof_return(bio,0); } } BIO_push(out,bio); bio=NULL; if (0) { err: if (out != NULL) BIO_free_all(out); if (btmp != NULL) BIO_free_all(btmp); out=NULL; } return(out); }
/* The decryption_func_bruteforce thread function tests all the passwords of the form: * prefix + x + combination + suffix * where x is a character in the range charset[dfargs.index_start] -> charset[dfargs.index_end]. */ void * decryption_func_bruteforce(void *arg) { struct decryption_func_locals *dfargs; wchar_t *password; unsigned char *pwd, *key, *iv, *masterkey, *seckey, hash[32]; unsigned int password_len, pwd_len, index_start, index_end, len, i, j, k; unsigned int masterkey_len1, masterkey_len2, seckey_len1, seckey_len2; int ret; unsigned int *tab; EVP_CIPHER_CTX ctx; dfargs = (struct decryption_func_locals *) arg; index_start = dfargs->index_start; index_end = dfargs->index_end; sha256d(pubkey, pubkey_len, hash); key = (unsigned char *) malloc(EVP_CIPHER_key_length(cipher)); iv = (unsigned char *) malloc(EVP_CIPHER_iv_length(cipher)); masterkey = (unsigned char *) malloc(encrypted_masterkey_len + EVP_CIPHER_block_size(EVP_aes_256_cbc())); seckey = (unsigned char *) malloc(encrypted_seckey_len + EVP_CIPHER_block_size(EVP_aes_256_cbc())); if((key == NULL) || (iv == NULL) || (masterkey == NULL) || (seckey == NULL)) { fprintf(stderr, "Error: memory allocation failed.\n\n"); exit(EXIT_FAILURE); } /* For every possible length */ for(len = min_len - prefix_len - 1 - suffix_len; len + 1 <= max_len - prefix_len - suffix_len; len++) { /* For every first character in the range we were given */ for(k = index_start; k <= index_end; k++) { password_len = prefix_len + 1 + len + suffix_len; password = (wchar_t *) calloc(password_len + 1, sizeof(wchar_t)); tab = (unsigned int *) calloc(len + 1, sizeof(unsigned int)); if((password == NULL) || (tab == NULL)) { fprintf(stderr, "Error: memory allocation failed.\n\n"); exit(EXIT_FAILURE); } wcsncpy(password, prefix, prefix_len); password[prefix_len] = charset[k]; wcsncpy(password + prefix_len + 1 + len, suffix, suffix_len); password[password_len] = '\0'; for(i = 0; i <= len; i++) tab[i] = 0; /* Test all the combinations */ while((tab[len] == 0) && (stop == 0)) { for(i = 0; i < len; i++) password[prefix_len + 1 + i] = charset[tab[len - 1 - i]]; pwd_len = wcstombs(NULL, password, 0); pwd = (unsigned char *) malloc(pwd_len + 1); if(pwd == NULL) { fprintf(stderr, "Error: memory allocation failed.\n\n"); exit(EXIT_FAILURE); } wcstombs(pwd, password, pwd_len + 1); /* Decrypt the master key with the password */ EVP_BytesToKey(cipher, digest, salt, pwd, pwd_len, rounds, key, iv); EVP_DecryptInit(&ctx, EVP_aes_256_cbc(), key, iv); EVP_DecryptUpdate(&ctx, masterkey, &masterkey_len1, encrypted_masterkey, encrypted_masterkey_len); ret = EVP_DecryptFinal(&ctx, masterkey + masterkey_len1, &masterkey_len2); dfargs->counter++; if(ret == 1) { /* Decrypt the secret key with the master key */ EVP_CIPHER_CTX_cleanup(&ctx); EVP_DecryptInit(&ctx, EVP_aes_256_cbc(), masterkey, hash); EVP_DecryptUpdate(&ctx, seckey, &seckey_len1, encrypted_seckey, encrypted_seckey_len); ret = EVP_DecryptFinal(&ctx, seckey + seckey_len1, &seckey_len2); if((ret == 1) && valid_seckey(seckey, seckey_len1 + seckey_len2, pubkey, pubkey_len)) { /* We have a positive result */ handle_signal(SIGUSR1); /* Print some stats */ pthread_mutex_lock(&found_password_lock); found_password = 1; printf("Password found: %ls\n", password); stop = 1; pthread_mutex_unlock(&found_password_lock); } } EVP_CIPHER_CTX_cleanup(&ctx); free(pwd); if(len == 0) break; tab[0]++; if(tab[0] == charset_len) tab[0] = 0; j = 0; while((j < len) && (tab[j] == 0)) { j++; tab[j]++; if(tab[j] == charset_len) tab[j] = 0; } } free(tab); free(password); } } free(masterkey); free(seckey); free(iv); free(key); pthread_exit(NULL); }
int tls1_setup_key_block(SSL *s) { unsigned char *p1,*p2; const EVP_CIPHER *c; const EVP_MD *hash; int num; SSL_COMP *comp; int mac_type= NID_undef,mac_secret_size=0; #ifdef KSSL_DEBUG printf ("tls1_setup_key_block()\n"); #endif /* KSSL_DEBUG */ if (s->s3->tmp.key_block_length != 0) return(1); if (!ssl_cipher_get_evp(s->session,&c,&hash,&mac_type,&mac_secret_size,&comp)) { SSLerr(SSL_F_TLS1_SETUP_KEY_BLOCK,SSL_R_CIPHER_OR_HASH_UNAVAILABLE); return(0); } s->s3->tmp.new_sym_enc=c; s->s3->tmp.new_hash=hash; s->s3->tmp.new_mac_pkey_type = mac_type; s->s3->tmp.new_mac_secret_size = mac_secret_size; num=EVP_CIPHER_key_length(c)+mac_secret_size+EVP_CIPHER_iv_length(c); num*=2; ssl3_cleanup_key_block(s); if ((p1=(unsigned char *)OPENSSL_malloc(num)) == NULL) goto err; if ((p2=(unsigned char *)OPENSSL_malloc(num)) == NULL) goto err; s->s3->tmp.key_block_length=num; s->s3->tmp.key_block=p1; #ifdef TLS_DEBUG printf("client random\n"); { int z; for (z=0; z<SSL3_RANDOM_SIZE; z++) printf("%02X%c",s->s3->client_random[z],((z+1)%16)?' ':'\n'); } printf("server random\n"); { int z; for (z=0; z<SSL3_RANDOM_SIZE; z++) printf("%02X%c",s->s3->server_random[z],((z+1)%16)?' ':'\n'); } printf("pre-master\n"); { int z; for (z=0; z<s->session->master_key_length; z++) printf("%02X%c",s->session->master_key[z],((z+1)%16)?' ':'\n'); } #endif tls1_generate_key_block(s,p1,p2,num); OPENSSL_cleanse(p2,num); OPENSSL_free(p2); #ifdef TLS_DEBUG printf("\nkey block\n"); { int z; for (z=0; z<num; z++) printf("%02X%c",p1[z],((z+1)%16)?' ':'\n'); } #endif if (!(s->options & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS)) { /* enable vulnerability countermeasure for CBC ciphers with * known-IV problem (http://www.openssl.org/~bodo/tls-cbc.txt) */ s->s3->need_empty_fragments = 1; if (s->session->cipher != NULL) { if (s->session->cipher->algorithm_enc == SSL_eNULL) s->s3->need_empty_fragments = 0; #ifndef OPENSSL_NO_RC4 if (s->session->cipher->algorithm_enc == SSL_RC4) s->s3->need_empty_fragments = 0; #endif } } return(1); err: SSLerr(SSL_F_TLS1_SETUP_KEY_BLOCK,ERR_R_MALLOC_FAILURE); return(0); }
void * decryption_func_dictionary(void *arg) { struct decryption_func_locals *dfargs; unsigned char *pwd, *key, *iv, *masterkey, *seckey, hash[32]; unsigned int pwd_len, masterkey_len1, masterkey_len2, seckey_len1, seckey_len2; int ret; EVP_CIPHER_CTX ctx; dfargs = (struct decryption_func_locals *) arg; sha256d(pubkey, pubkey_len, hash); key = (unsigned char *) malloc(EVP_CIPHER_key_length(cipher)); iv = (unsigned char *) malloc(EVP_CIPHER_iv_length(cipher)); masterkey = (unsigned char *) malloc(encrypted_masterkey_len + EVP_CIPHER_block_size(EVP_aes_256_cbc())); seckey = (unsigned char *) malloc(encrypted_seckey_len + EVP_CIPHER_block_size(EVP_aes_256_cbc())); if((key == NULL) || (iv == NULL) || (masterkey == NULL) || (seckey == NULL)) { fprintf(stderr, "Error: memory allocation failed.\n\n"); exit(EXIT_FAILURE); } do { ret = read_dictionary_line(&pwd, &pwd_len); if(ret == 0) break; /* Decrypt the master key with the password */ EVP_BytesToKey(cipher, digest, salt, pwd, pwd_len, rounds, key, iv); EVP_DecryptInit(&ctx, EVP_aes_256_cbc(), key, iv); EVP_DecryptUpdate(&ctx, masterkey, &masterkey_len1, encrypted_masterkey, encrypted_masterkey_len); ret = EVP_DecryptFinal(&ctx, masterkey + masterkey_len1, &masterkey_len2); dfargs->counter++; if(ret == 1) { /* Decrypt the secret key with the master key */ EVP_CIPHER_CTX_cleanup(&ctx); EVP_DecryptInit(&ctx, EVP_aes_256_cbc(), masterkey, hash); EVP_DecryptUpdate(&ctx, seckey, &seckey_len1, encrypted_seckey, encrypted_seckey_len); ret = EVP_DecryptFinal(&ctx, seckey + seckey_len1, &seckey_len2); if((ret == 1) && valid_seckey(seckey, seckey_len1 + seckey_len2, pubkey, pubkey_len)) { /* We have a positive result */ handle_signal(SIGUSR1); /* Print some stats */ pthread_mutex_lock(&found_password_lock); found_password = 1; printf("Password found: %s\n", pwd); stop = 1; pthread_mutex_unlock(&found_password_lock); } } EVP_CIPHER_CTX_cleanup(&ctx); free(pwd); } while(stop == 0); free(masterkey); free(seckey); free(iv); free(key); pthread_exit(NULL); }
int ssl3_setup_key_block(SSL *s) { unsigned char *p; const EVP_CIPHER *c; const EVP_MD *hash; int num; int ret = 0; SSL_COMP *comp; if (s->s3->tmp.key_block_length != 0) return(1); if (!ssl_cipher_get_evp(s->session,&c,&hash,&comp)) { SSLerr(SSL_F_SSL3_SETUP_KEY_BLOCK,SSL_R_CIPHER_OR_HASH_UNAVAILABLE); return(0); } s->s3->tmp.new_sym_enc=c; s->s3->tmp.new_hash=hash; #ifdef OPENSSL_NO_COMP s->s3->tmp.new_compression=NULL; #else s->s3->tmp.new_compression=comp; #endif num=EVP_CIPHER_key_length(c)+EVP_MD_size(hash)+EVP_CIPHER_iv_length(c); num*=2; ssl3_cleanup_key_block(s); if ((p=OPENSSL_malloc(num)) == NULL) goto err; s->s3->tmp.key_block_length=num; s->s3->tmp.key_block=p; ret = ssl3_generate_key_block(s,p,num); if (!(s->options & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS)) { /* enable vulnerability countermeasure for CBC ciphers with * known-IV problem (http://www.openssl.org/~bodo/tls-cbc.txt) */ s->s3->need_empty_fragments = 1; if (s->session->cipher != NULL) { if ((s->session->cipher->algorithms & SSL_ENC_MASK) == SSL_eNULL) s->s3->need_empty_fragments = 0; #ifndef OPENSSL_NO_RC4 if ((s->session->cipher->algorithms & SSL_ENC_MASK) == SSL_RC4) s->s3->need_empty_fragments = 0; #endif } } return ret; err: SSLerr(SSL_F_SSL3_SETUP_KEY_BLOCK,ERR_R_MALLOC_FAILURE); return(0); }
/* sqlite3_rekey ** Given a database, this will reencrypt the database using a new key. ** There are two possible modes of operation. The first is rekeying ** an existing database that was not previously encrypted. The second ** is to change the key on an existing database. ** ** The proposed logic for this function follows: ** 1. Determine if there is already a key present ** 2. If there is NOT already a key present, create one and attach a codec (key would be null) ** 3. Initialize a ctx->rekey parameter of the codec ** ** Note: this will require modifications to the sqlite3Codec to support rekey ** */ int sqlite3_rekey(sqlite3 *db, const void *pKey, int nKey) { if(db && pKey && nKey) { int i, prepared_key_sz; int key_sz = EVP_CIPHER_key_length(CIPHER); void *key = sqlite3Malloc(key_sz); if(key == NULL) return SQLITE_NOMEM; for(i=0; i<db->nDb; i++){ struct Db *pDb = &db->aDb[i]; if(pDb->pBt) { codec_ctx *ctx; int rc, page_count; Pgno pgno; PgHdr *page; Pager *pPager = pDb->pBt->pBt->pPager; sqlite3pager_get_codec(pDb->pBt->pBt->pPager, (void **) &ctx); if(ctx == NULL) { /* there was no codec attached to this database,so attach one now with a null password */ char *error; db->nextPagesize = sqlite3BtreeGetPageSize(pDb->pBt); pDb->pBt->pBt->pageSizeFixed = 0; /* required for sqlite3BtreeSetPageSize to modify pagesize setting */ sqlite3BtreeSetPageSize(pDb->pBt, db->nextPagesize, EVP_CIPHER_iv_length(CIPHER), 0); sqlite3RunVacuum(&error, db); sqlite3CodecAttach(db, i, pKey, nKey); sqlite3pager_get_codec(pDb->pBt->pBt->pPager, (void **) &ctx); /* prepare this setup as if it had already been initialized */ RAND_pseudo_bytes(ctx->salt, FILE_HEADER_SZ); ctx->rekey_plaintext = 1; } codec_prepare_key(db, pKey, nKey, ctx->salt, FILE_HEADER_SZ, key, &prepared_key_sz); assert(prepared_key_sz == key_sz); ctx->rekey = key; /* set rekey to new key data - note that ctx->key is original encryption key */ /* do stuff here to rewrite the database ** 1. Create a transaction on the database ** 2. Iterate through each page, reading it and then writing it. ** 3. If that goes ok then commit and put ctx->rekey into ctx->key ** note: don't deallocate rekey since it may be used in a subsequent iteration */ rc = sqlite3BtreeBeginTrans(pDb->pBt, 1); /* begin write transaction */ rc = sqlite3PagerPagecount(pPager, &page_count); for(pgno = 1; rc == SQLITE_OK && pgno <= page_count; pgno++) { /* pgno's start at 1 see pager.c:pagerAcquire */ if(!sqlite3pager_is_mj_pgno(pPager, pgno)) { /* skip this page (see pager.c:pagerAcquire for reasoning) */ rc = sqlite3PagerGet(pPager, pgno, &page); if(rc == SQLITE_OK) { /* write page see pager_incr_changecounter for example */ rc = sqlite3PagerWrite(page); //printf("sqlite3PagerWrite(%d)\n", pgno); if(rc == SQLITE_OK) { sqlite3PagerUnref(page); } } } } /* if commit was successful commit and copy the rekey data to current key, else rollback to release locks */ if(rc == SQLITE_OK) { rc = sqlite3BtreeCommit(pDb->pBt); memcpy(ctx->key, ctx->rekey, key_sz); if(ctx->pass) { memset(ctx->pass, 0, ctx->pass_sz); sqlite3_free(ctx->pass); } ctx->pass = sqlite3Malloc(nKey); if(ctx->pass == NULL) return SQLITE_NOMEM; memcpy(ctx->pass, pKey, nKey); ctx->pass_sz = nKey; } else { printf("error\n"); sqlite3BtreeRollback(pDb->pBt); } /* cleanup rekey data, make sure to overwrite rekey_plaintext or read errors will ensue */ ctx->rekey = NULL; ctx->rekey_plaintext = 0; } } /* clear and free temporary key data */ memset(key, 0, key_sz); sqlite3_free(key); return SQLITE_OK; } return SQLITE_ERROR; }
// generate keys static int cryptoSetKeys(struct s_crypto *ctxs, const int count, const unsigned char *secret_buf, const int secret_len, const unsigned char *nonce_buf, const int nonce_len) { int cur_key_len; unsigned char cur_key[EVP_MAX_MD_SIZE]; int seed_key_len; unsigned char seed_key[EVP_MAX_MD_SIZE]; const EVP_MD *keygen_md = EVP_sha512(); const EVP_MD *out_md = EVP_sha256(); const EVP_CIPHER *out_cipher = EVP_aes_256_cbc(); const int key_size = EVP_CIPHER_key_length(out_cipher); HMAC_CTX hmac_ctx; int16_t i; unsigned char in[2]; int j,k; // setup hmac as the pseudorandom function HMAC_CTX_init(&hmac_ctx); // calculate seed key HMAC_Init_ex(&hmac_ctx, nonce_buf, nonce_len, keygen_md, NULL); HMAC_Update(&hmac_ctx, secret_buf, secret_len); HMAC_Final(&hmac_ctx, seed_key, (unsigned int *)&seed_key_len); // calculate derived keys HMAC_Init_ex(&hmac_ctx, seed_key, seed_key_len, keygen_md, NULL); HMAC_Update(&hmac_ctx, nonce_buf, nonce_len); HMAC_Final(&hmac_ctx, cur_key, (unsigned int *)&cur_key_len); i = 0; j = 0; k = 0; while(k < count) { // calculate next key utilWriteInt16(in, i); HMAC_Init_ex(&hmac_ctx, NULL, -1, NULL, NULL); HMAC_Update(&hmac_ctx, cur_key, cur_key_len); HMAC_Update(&hmac_ctx, nonce_buf, nonce_len); HMAC_Update(&hmac_ctx, in, 2); HMAC_Final(&hmac_ctx, cur_key, (unsigned int *)&cur_key_len); if(cur_key_len < key_size) return 0; // check if key is long enough switch(j) { case 1: // save this key as the decryption and encryption key if(!EVP_EncryptInit_ex(&ctxs[k].enc_ctx, out_cipher, NULL, cur_key, NULL)) return 0; if(!EVP_DecryptInit_ex(&ctxs[k].dec_ctx, out_cipher, NULL, cur_key, NULL)) return 0; break; case 2: // save this key as the hmac key HMAC_Init_ex(&ctxs[k].hmac_ctx, cur_key, cur_key_len, out_md, NULL); break; default: // throw this key away break; } if(j > 3) { j = 0; k++; } j++; i++; } // clean up HMAC_CTX_cleanup(&hmac_ctx); return 1; }
int main(int argc, char *argv[]) { int clobbered_key_fd, cipher_of_secret_text_fd, cipher_of_signed_key_fd, plain_fd; FILE *rsapub_key_fp; unsigned char *cam128_key, *cam128_iv; unsigned char *cipher_of_secret_text, *cipher_of_signed_key, *signed_key, *secret_text, *clobbered_key; EVP_PKEY *rsapub_key; unsigned char *rc4_40_key; const EVP_CIPHER *cam128_cfb8, *rc4_40; EVP_CIPHER_CTX cam128_cfb8_ctx, rc4_40_ctx; const EVP_MD *sha; EVP_MD_CTX sha_ctx; int cam128_cfb8_keylen, cam128_cfb8_ivlen, rc4_40_keylen, signed_key_size; int ret, count; struct stat file_prop; long cipher_of_signed_key_size, clobbered_key_size, cipher_of_secret_text_size, secret_text_size; // get the parameters for CAMELLIA128_cfb8 cam128_cfb8 = EVP_camellia_128_cfb8(); cam128_cfb8_keylen = EVP_CIPHER_key_length(cam128_cfb8); cam128_cfb8_ivlen = EVP_CIPHER_iv_length(cam128_cfb8); // get the parameters for RC4_40 rc4_40 = EVP_rc4_40(); rc4_40_keylen = EVP_CIPHER_key_length(rc4_40); // get the parameters for sha sha = EVP_sha(); printf("cam128_cfb8_keylen: %d, cam128_cfb8_ivlen: %d\n", cam128_cfb8_keylen, cam128_cfb8_ivlen); printf("rc4_40_keylen: %d\n", rc4_40_keylen); // read the s67766-clobbered-key.bin and store the key and iv for CAMELLIA128-cfb8 cam128_key = malloc(cam128_cfb8_keylen); cam128_iv = malloc(cam128_cfb8_ivlen); clobbered_key_size = read_file(clobbered_key_file, &clobbered_key); if(clobbered_key_size != cam128_cfb8_keylen+cam128_cfb8_ivlen) { printf("reading file %s returned not enough Bytes: %ld, instead of: %d\n", clobbered_key_file, clobbered_key_size, cam128_cfb8_keylen+cam128_cfb8_ivlen); perror(""); } memcpy(cam128_key, clobbered_key, cam128_cfb8_keylen); memcpy(cam128_iv, clobbered_key+cam128_cfb8_keylen, cam128_cfb8_ivlen); printf("cam128_key: "); print_bytes(cam128_key, cam128_cfb8_keylen); printf(", cam128_iv: "); print_bytes(cam128_iv, cam128_cfb8_ivlen); printf("\n"); // read the s67766-cipher-of-signed-key.bin cipher_of_signed_key_size = read_file(cipher_of_signed_key_file, &cipher_of_signed_key); printf("cipher_of_signed_key: "); print_bytes(cipher_of_signed_key, cipher_of_signed_key_size); printf("\n"); // read the public key from rsapub.pem rsapub_key_fp = fopen(rsapub_key_file, "r"); if (!rsapub_key_fp) { printf("opening file %s returned error\n", rsapub_key_file); perror(""); } rsapub_key = PEM_read_PUBKEY(rsapub_key_fp, NULL, NULL, NULL); if (!rsapub_key) { printf("PEM_read_PUBKEY returned error for RSA\n"); } if(fclose(rsapub_key_fp) != 0) { printf("closing file %s returned error\n", rsapub_key_file); perror(""); } // restore the clobbered key with bruteforce signed_key = malloc(cipher_of_signed_key_size); for(count = 0; count<=255; count++) { memset(cam128_key, count, 1); //print_bytes(cam128_key, cam128_cfb8_keylen); //printf("\n"); //decrypt the cipher with guessed key signed_key_size = decrypt(cam128_cfb8, &signed_key, cipher_of_signed_key, cipher_of_signed_key_size, cam128_key, cam128_iv); if(signed_key_size==-1) { return -1; } printf("signed_key_size: %d\n", signed_key_size); if(EVP_VerifyInit(&sha_ctx, sha) == 0) { printf("EVP_VerifyInit returned error for SHA\n"); } if(EVP_VerifyUpdate(&sha_ctx, signed_key, rc4_40_keylen) == 0) { printf("EVP_VerifyUpdate returned error for SHA\n"); } ret = EVP_VerifyFinal(&sha_ctx, signed_key+rc4_40_keylen, signed_key_size-rc4_40_keylen, rsapub_key); switch(ret) { case -1: printf("EVP_VerifyFinal returned error for SHA\n"); break; case 0: printf("EVP_VerifyFinal failed with byte: %02X\n", count); break; case 1: printf("EVP_VerifyFinal succeeded with byte: %02X\n", count); count = 255; break; } } // extract the key for RC-4 40 rc4_40_key = malloc(rc4_40_keylen); memcpy(rc4_40_key, signed_key, rc4_40_keylen); printf("rc4_40_key: "); print_bytes(rc4_40_key, rc4_40_keylen); printf("\n"); // read the s67766-cipher-of-secret-text.bin cipher_of_secret_text_size = read_file(cipher_of_secret_text_file, &cipher_of_secret_text); printf("cipher_of_secret_text: "); print_bytes(cipher_of_secret_text, cipher_of_secret_text_size); printf("\n"); // decrypt s67766-cipher-of-secret-text.bin secret_text = malloc(cipher_of_secret_text_size); secret_text_size = 0; //decrypt the cipher with extracted key secret_text_size = decrypt(rc4_40, &secret_text, cipher_of_secret_text, cipher_of_secret_text_size, rc4_40_key, NULL); printf("secret_text_size: %ld\n", secret_text_size); printf("secret_text: %s %s\n", secret_text, secret_text+11); // write the s67766-plain.bin if(write_file(plain_file, secret_text, secret_text_size)==-1) { return -1; } return 0; }
int cmePBKDF (const EVP_CIPHER *cipher, const unsigned char *salt, int saltLen, const unsigned char *password,int passwordLen,unsigned char *key,unsigned char *iv) { int result; EVP_MD *md=NULL; unsigned char *HexStrToByteBuffer=NULL; unsigned char *buf=NULL; //Max. size of key+IV buffer = 2 * max. length for symmetric key or IV. int keyLen=EVP_CIPHER_key_length(cipher); //Get cipher key length. int ivLen=EVP_CIPHER_iv_length(cipher); //Get cipher iv length. #define cmePBKDFFree() \ do { \ if (HexStrToByteBuffer) \ { \ memset(HexStrToByteBuffer,0,strlen(passwordLen)/2); \ cmeFree(HexStrToByteBuffer); \ } \ if (buf) \ { \ memset(buf,0,keyLen+ivLen); \ cmeFree(buf); \ } \ } while (0); //Local free() macro if (cmeDefaultPBKDFVersion==1) //PBKDF1 { //Use PBKDF1 with cipher=cmeDefaultEncAlg + MD5 + count=1 (compatible with command line password KDF from OpenSSL): md = (EVP_MD *)EVP_get_digestbyname("md5"); result=EVP_BytesToKey(cipher,md,salt,password,passwordLen,1,key,iv); } else //PBKDF2 { result=cmeHexstrToBytes(&HexStrToByteBuffer,password); if ((result)||(passwordLen/2<keyLen)) //Password is not a HexStr representation of a binary key in cipher's keyspace -> Use PBKDF2 with several iterations for password expansion into full keyspace. { // (Very slow, but provides a good security level for keys derived from human generated passwords). //Use PBKDF2 with HMAC_SHA1 + count=cmeDefaultPBKDFCount (not compatible with command line password KDF from OpenSSL): buf=(unsigned char*)malloc(sizeof(unsigned char)*(keyLen+ivLen)); result=PKCS5_PBKDF2_HMAC_SHA1((const char *)password,passwordLen,salt,saltLen,cmeDefaultPBKDFCount,keyLen+ivLen,buf); memcpy(key,buf,keyLen); memcpy(iv,buf+keyLen,ivLen); } else //Password is a HexStr representation of a binary key in cipher's keyspace -> Use PBKDF2 with 1 iteration as a permutation in keyspace using the provided salt. { // (Fast; provides equivalent security level as a random key selected from crypto algorithm's full keyspace). //Use PBKDF2 with HMAC_SHA1 + count=cmeDefaultPBKDFCount (not compatible with command line password KDF from OpenSSL): buf=(unsigned char*)malloc(sizeof(unsigned char)*(keyLen+ivLen)); result=PKCS5_PBKDF2_HMAC_SHA1((const char *)password,passwordLen,salt,saltLen,1,keyLen+ivLen,buf); memcpy(key,buf,keyLen); memcpy(iv,buf+keyLen,ivLen); } } if (result==0) //0= failure, n=size of generated key (success) { #ifdef ERROR_LOG fprintf(stderr,"CaumeDSE Error: cmePBKDF(), PBKDF ver. %d -> 0 length key!\n",cmeDefaultPBKDFVersion); #endif return (1); } else { #ifdef DEBUG fprintf(stdout,"CaumeDSE Debug: cmePBKDF(), PBKDF ver. %d -> %d bytes key, %d bytes iv.\n",cmeDefaultPBKDFVersion,keyLen,ivLen); #endif return(0); } }
int dh_im_compute_key(PACE_CTX * ctx, const BUF_MEM * s, const BUF_MEM * in, BN_CTX *bn_ctx) { int ret = 0; BUF_MEM * x_mem = NULL; BIGNUM * x_bn = NULL, *a = NULL, *p_1 = NULL, *q = NULL; DH *static_key = NULL, *ephemeral_key = NULL; check((ctx && in && ctx->ka_ctx), "Invalid arguments"); if (in->length < (size_t) EVP_CIPHER_key_length(ctx->ka_ctx->cipher) || !ctx->static_key) goto err; BN_CTX_start(bn_ctx); static_key = EVP_PKEY_get1_DH(ctx->static_key); if (!static_key) goto err; /* Initialize ephemeral parameters with parameters from the static key */ ephemeral_key = DHparams_dup_with_q(static_key); if (!ephemeral_key) goto err; /* Perform the actual mapping */ x_mem = cipher_no_pad(ctx->ka_ctx, NULL, in, s, 1); if (!x_mem) goto err; x_bn = BN_bin2bn((unsigned char *) x_mem->data, x_mem->length, x_bn); a = BN_CTX_get(bn_ctx); q = DH_get_q(static_key, bn_ctx); p_1 = BN_dup(static_key->p); if (!x_bn || !a || !q || !p_1 || /* p_1 = p-1 */ !BN_sub_word(p_1, 1) || /* a = p-1 / q */ !BN_div(a, NULL, p_1, q, bn_ctx) || /* g~ = x^a mod p */ !BN_mod_exp(ephemeral_key->g, x_bn, a, static_key->p, bn_ctx)) goto err; /* check if g~ != 1 */ check((!BN_is_one(ephemeral_key->g)), "Bad DH generator"); /* Copy ephemeral key to context structure */ if (!EVP_PKEY_set1_DH(ctx->ka_ctx->key, ephemeral_key)) goto err; ret = 1; err: if (q) BN_clear_free(q); if (p_1) BN_clear_free(p_1); if (x_bn) BN_clear_free(x_bn); if (x_mem) BUF_MEM_free(x_mem); /* Decrement reference count, keys are still available via PACE_CTX */ if (static_key) DH_free(static_key); if (ephemeral_key) DH_free(ephemeral_key); BN_CTX_end(bn_ctx); return ret; }
int cmeHMACByteString (const unsigned char *srcBuf, unsigned char **dstBuf, const int srcLen, int *dstWritten, const char *algorithm, char **salt, const char *userKey) { int result=0; int cont=0; int cont2=0; int exitcode=0; int written=0; int keyLen=0; int ivLen=0; unsigned char *key=NULL; unsigned char *iv=NULL; unsigned char *digestBytes=NULL; unsigned char *byteSalt=NULL; unsigned char hexStrbyteSalt[evpSaltBufferSize*2+1]; //Space for an hex str representation of an evpSaltBufferSize long, byte salt HMAC_CTX *ctx=NULL; //Note that ctx will be freed normally by cmeHMACFinal(), but we need to free it if we exit before cmeHMACFinal() is called. EVP_MD *digest=NULL; //Note that digest is a pointer to a constant digest function in OPENSSL. const EVP_CIPHER *cipher=NULL; //Note that cipher is a pointer to a constant cipher function in OPENSSL. #define cmeHMACByteStringFree() \ do { \ cmeFree(ctx); \ cmeFree(digestBytes); \ if (key) \ { \ memset(key,0,keyLen); \ cmeFree(key); \ } \ if (iv) \ { \ memset(iv,0,ivLen); \ cmeFree(iv); \ } \ if (byteSalt) \ { \ memset(byteSalt,0,evpSaltBufferSize); \ cmeFree(byteSalt); \ } \ } while (0); //Local free() macro if (srcBuf==NULL) //Error, source buffer can't be null! { #ifdef ERROR_LOG fprintf(stderr,"CaumeDSE Error: cmeHMACByteString(), srcBuf is NULL!\n"); #endif cmeDigestByteStringFree(); return(1); } if ((cmeGetCipher(&cipher,cmeDefaultEncAlg))) //Use default encryption algorithm's key length for PBKDF. { #ifdef ERROR_LOG fprintf(stderr,"CaumeDSE Error: cmeHMACByteString(), incorrect digest algorithm; %s!\n",algorithm); #endif cmeDigestByteStringFree(); return(2); } if ((cmeGetDigest(&digest,algorithm))) //Verify algorithm and create digest object. { #ifdef ERROR_LOG fprintf(stderr,"CaumeDSE Error: cmeHMACByteString(), incorrect digest algorithm; %s!\n",algorithm); #endif cmeDigestByteStringFree(); return(3); } digestBytes=(unsigned char *)malloc(EVP_MAX_MD_SIZE); if(!(*dstBuf=(unsigned char *)malloc(evpMaxHashStrLen))) //Error allocating memory! { //Note that Caller must free *dstBuf! #ifdef ERROR_LOG fprintf(stderr,"CaumeDSE Error: cmeHMACByteString(), Error in memory allocation!\n"); #endif cmeDigestByteStringFree(); return(4); } memset(*dstBuf,0,evpMaxHashStrLen); if (!(*salt)) //if salt==NULL, We need to generate salt and return it in hexStr format. { //Otherwise we use the salt provided by the caller. cmePrngGetBytes(&byteSalt,evpSaltBufferSize); cmeBytesToHexstr(byteSalt,(unsigned char **)salt,evpSaltBufferSize); //We need to return str representation of salt. //Note:Caller must free memory for salt! #ifdef DEBUG fprintf(stdout,"CaumeDSE Debug: cmeHMACByteString(), salt parameter is NULL; " "defining new random salt: %s.\n",*salt); #endif } else { strncpy((char *)hexStrbyteSalt,(char *)*salt,evpSaltBufferSize*2); hexStrbyteSalt[evpSaltBufferSize*2]='\0'; if ((cmeHexstrToBytes(&byteSalt,hexStrbyteSalt))) // Error, salt is not a hexStr representation! { #ifdef ERROR_LOG fprintf(stderr,"CaumeDSE Error: cmeHMACByteString(), salt is not a " "hexStr representation; string: %s !\n",hexStrbyteSalt); #endif cmeDigestByteStringFree(); return(3); } } keyLen=EVP_CIPHER_key_length(cipher); //Get cipher key length. ivLen=EVP_CIPHER_iv_length(cipher); //Get cipher iv length. key=(unsigned char *)malloc(keyLen); iv=(unsigned char *)malloc(ivLen); if ((cmePBKDF(cipher,byteSalt,evpSaltBufferSize,(unsigned char *)userKey,strlen(userKey),key,iv))) //Error setting key & IV. { cmeDigestByteStringFree(); return(7); } ///keyLen=strlen(key); cmeHMACInit(&ctx,NULL,digest,(const char *)key,keyLen); cont2=0; for (cont=0; cont<(srcLen/evpBufferSize); cont++) //Process all blocks of size evpBufferSize. { cmeHMACUpdate(ctx,srcBuf+cont2,evpBufferSize); cont2 += evpBufferSize; } if (srcLen%evpBufferSize) //Process last chunk with size < evpBufferSize. { cmeHMACUpdate(ctx,srcBuf+cont2,(srcLen%evpBufferSize)); cont2 += (srcLen%evpBufferSize); } result=cmeHMACFinal(&ctx,digestBytes,(unsigned int *)&written); exitcode+=result; cmeBytesToHexstr(digestBytes,dstBuf,written); //Convert byte array to Byte HexStr. *dstWritten=strlen((const char *)*dstBuf); memset(digestBytes,0,EVP_MAX_MD_SIZE); //Clear memory of resulting MAC bytes. cmeDigestByteStringFree(); return (exitcode);
RTDECL(int) RTCrCipherDecrypt(RTCRCIPHER hCipher, void const *pvKey, size_t cbKey, void const *pvInitVector, size_t cbInitVector, void const *pvEncrypted, size_t cbEncrypted, void *pvPlainText, size_t cbPlainText, size_t *pcbPlainText) { /* * Validate input. */ RTCRCIPHERINT *pThis = hCipher; AssertPtrReturn(pThis, VERR_INVALID_HANDLE); AssertReturn(pThis->u32Magic == RTCRCIPHERINT_MAGIC, VERR_INVALID_HANDLE); AssertMsgReturn((ssize_t)cbKey == EVP_CIPHER_key_length(pThis->pCipher), ("%zu, expected %d\n", cbKey, EVP_CIPHER_key_length(pThis->pCipher)), VERR_CR_CIPHER_INVALID_KEY_LENGTH); AssertMsgReturn((ssize_t)cbInitVector == EVP_CIPHER_iv_length(pThis->pCipher), ("%zu, expected %d\n", cbInitVector, EVP_CIPHER_iv_length(pThis->pCipher)), VERR_CR_CIPHER_INVALID_INITIALIZATION_VECTOR_LENGTH); AssertReturn(cbPlainText > 0, VERR_NO_DATA); Assert(EVP_CIPHER_block_size(pThis->pCipher) <= 1); /** @todo more complicated ciphers later */ size_t const cbNeeded = cbEncrypted; if (pcbPlainText) { *pcbPlainText = cbNeeded; AssertReturn(cbPlainText >= cbNeeded, VERR_BUFFER_OVERFLOW); } else AssertReturn(cbPlainText == cbNeeded, VERR_INVALID_PARAMETER); AssertReturn((size_t)(int)cbEncrypted == cbEncrypted && (int)cbEncrypted > 0, VERR_OUT_OF_RANGE); /* * Allocate and initialize the cipher context. */ int rc = VERR_NO_MEMORY; # if OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(LIBRESSL_VERSION_NUMBER) EVP_CIPHER_CTX *pCipherCtx = EVP_CIPHER_CTX_new(); if (pCipherCtx) # else EVP_CIPHER_CTX CipherCtx; EVP_CIPHER_CTX *pCipherCtx = &CipherCtx; RT_ZERO(CipherCtx); # endif { int rcOssl = EVP_DecryptInit(pCipherCtx, pThis->pCipher, (unsigned char const *)pvKey, (unsigned char const *)pvInitVector); if (rcOssl > 0) { /* * Do the decryption. */ int cbDecrypted1 = 0; rcOssl = EVP_DecryptUpdate(pCipherCtx, (unsigned char *)pvPlainText, &cbDecrypted1, (unsigned char const *)pvEncrypted, (int)cbEncrypted); if (rcOssl > 0) { Assert(cbDecrypted1 <= (ssize_t)cbNeeded); int cbDecrypted2 = 0; rcOssl = EVP_DecryptFinal(pCipherCtx, (unsigned char *)pvPlainText + cbDecrypted1, &cbDecrypted2); if (rcOssl > 0) { Assert(cbDecrypted1 + cbDecrypted2 == (ssize_t)cbNeeded); if (pcbPlainText) *pcbPlainText = cbDecrypted1 + cbDecrypted2; rc = VINF_SUCCESS; } else rc = VERR_CR_CIPHER_OSSL_DECRYPT_FINAL_FAILED; } else rc = VERR_CR_CIPHER_OSSL_DECRYPT_UPDATE_FAILED; } else rc = VERR_CR_CIPHER_OSSL_DECRYPT_INIT_FAILED; # if OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(LIBRESSL_VERSION_NUMBER) EVP_CIPHER_CTX_free(pCipherCtx); # else EVP_CIPHER_CTX_cleanup(&CipherCtx); # endif } return rc; }
static int client_master_key(SSL *s) { unsigned char *buf; unsigned char *p,*d; int clear,enc,karg,i; SSL_SESSION *sess; const EVP_CIPHER *c; const EVP_MD *md; buf=(unsigned char *)s->init_buf->data; if (s->state == SSL2_ST_SEND_CLIENT_MASTER_KEY_A) { if (!ssl_cipher_get_evp(s->session,&c,&md,NULL,NULL,NULL)) { ssl2_return_error(s,SSL2_PE_NO_CIPHER); SSLerr(SSL_F_CLIENT_MASTER_KEY,SSL_R_PROBLEMS_MAPPING_CIPHER_FUNCTIONS); return(-1); } sess=s->session; p=buf; d=p+10; *(p++)=SSL2_MT_CLIENT_MASTER_KEY;/* type */ i=ssl_put_cipher_by_char(s,sess->cipher,p); p+=i; /* make key_arg data */ i=EVP_CIPHER_iv_length(c); sess->key_arg_length=i; if (i > SSL_MAX_KEY_ARG_LENGTH) { ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); SSLerr(SSL_F_CLIENT_MASTER_KEY, ERR_R_INTERNAL_ERROR); return -1; } if (i > 0) if (RAND_pseudo_bytes(sess->key_arg,i) <= 0) return -1; /* make a master key */ i=EVP_CIPHER_key_length(c); sess->master_key_length=i; if (i > 0) { if (i > (int)sizeof(sess->master_key)) { ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); SSLerr(SSL_F_CLIENT_MASTER_KEY, ERR_R_INTERNAL_ERROR); return -1; } if (RAND_bytes(sess->master_key,i) <= 0) { ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR); return(-1); } } if (sess->cipher->algorithm2 & SSL2_CF_8_BYTE_ENC) enc=8; else if (SSL_C_IS_EXPORT(sess->cipher)) enc=5; else enc=i; if ((int)i < enc) { ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR); SSLerr(SSL_F_CLIENT_MASTER_KEY,SSL_R_CIPHER_TABLE_SRC_ERROR); return(-1); } clear=i-enc; s2n(clear,p); memcpy(d,sess->master_key,(unsigned int)clear); d+=clear; enc=ssl_rsa_public_encrypt(sess->sess_cert,enc, &(sess->master_key[clear]),d, (s->s2->ssl2_rollback)?RSA_SSLV23_PADDING:RSA_PKCS1_PADDING); if (enc <= 0) { ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR); SSLerr(SSL_F_CLIENT_MASTER_KEY,SSL_R_PUBLIC_KEY_ENCRYPT_ERROR); return(-1); } #ifdef PKCS1_CHECK if (s->options & SSL_OP_PKCS1_CHECK_1) d[1]++; if (s->options & SSL_OP_PKCS1_CHECK_2) sess->master_key[clear]++; #endif s2n(enc,p); d+=enc; karg=sess->key_arg_length; s2n(karg,p); /* key arg size */ if (karg > (int)sizeof(sess->key_arg)) { ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR); SSLerr(SSL_F_CLIENT_MASTER_KEY, ERR_R_INTERNAL_ERROR); return -1; } memcpy(d,sess->key_arg,(unsigned int)karg); d+=karg; s->state=SSL2_ST_SEND_CLIENT_MASTER_KEY_B; s->init_num=d-buf; s->init_off=0; } /* SSL2_ST_SEND_CLIENT_MASTER_KEY_B */ return(ssl2_do_write(s)); }
bool metakey_h(connection_t *c) { char buffer[MAX_STRING_SIZE]; int cipher, digest, maclength, compression; int len; if(sscanf(c->buffer, "%*d %d %d %d %d " MAX_STRING, &cipher, &digest, &maclength, &compression, buffer) != 5) { logger(LOG_ERR, "Got bad %s from %s (%s)", "METAKEY", c->name, c->hostname); return false; } len = RSA_size(myself->connection->rsa_key); /* Check if the length of the meta key is all right */ if(strlen(buffer) != (size_t)len * 2) { logger(LOG_ERR, "Possible intruder %s (%s): %s", c->name, c->hostname, "wrong keylength"); return false; } /* Allocate buffers for the meta key */ c->inkey = xrealloc(c->inkey, len); if(!c->inctx) { c->inctx = EVP_CIPHER_CTX_new(); if(!c->inctx) { abort(); } } /* Convert the challenge from hexadecimal back to binary */ if(!hex2bin(buffer, buffer, len)) { logger(LOG_ERR, "Got bad %s from %s(%s): %s", "METAKEY", c->name, c->hostname, "invalid key"); return false; } /* Decrypt the meta key */ if(RSA_private_decrypt(len, (unsigned char *)buffer, (unsigned char *)c->inkey, myself->connection->rsa_key, RSA_NO_PADDING) != len) { /* See challenge() */ logger(LOG_ERR, "Error during decryption of meta key for %s (%s): %s", c->name, c->hostname, ERR_error_string(ERR_get_error(), NULL)); return false; } ifdebug(SCARY_THINGS) { bin2hex(c->inkey, buffer, len); buffer[len * 2] = '\0'; logger(LOG_DEBUG, "Received random meta key (unencrypted): %s", buffer); } /* All incoming requests will now be encrypted. */ /* Check and lookup cipher and digest algorithms */ if(cipher) { c->incipher = EVP_get_cipherbynid(cipher); if(!c->incipher) { logger(LOG_ERR, "%s (%s) uses unknown cipher!", c->name, c->hostname); return false; } if(!EVP_DecryptInit(c->inctx, c->incipher, (unsigned char *)c->inkey + len - EVP_CIPHER_key_length(c->incipher), (unsigned char *)c->inkey + len - EVP_CIPHER_key_length(c->incipher) - EVP_CIPHER_iv_length(c->incipher))) { logger(LOG_ERR, "Error during initialisation of cipher from %s (%s): %s", c->name, c->hostname, ERR_error_string(ERR_get_error(), NULL)); return false; } c->inbudget = byte_budget(c->incipher); c->status.decryptin = true; } else { logger(LOG_ERR, "%s (%s) uses null cipher!", c->name, c->hostname); return false; } c->inmaclength = maclength; if(digest) { c->indigest = EVP_get_digestbynid(digest); if(!c->indigest) { logger(LOG_ERR, "Node %s (%s) uses unknown digest!", c->name, c->hostname); return false; } if(c->inmaclength > EVP_MD_size(c->indigest) || c->inmaclength < 0) { logger(LOG_ERR, "%s (%s) uses bogus MAC length!", c->name, c->hostname); return false; } } else { logger(LOG_ERR, "%s (%s) uses null digest!", c->name, c->hostname); return false; } c->incompression = compression; c->allow_request = CHALLENGE; return send_challenge(c); }