Пример #1
0
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;

}
Пример #2
0
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);
Пример #3
0
int
cipher_kt_key_size (const EVP_CIPHER *cipher_kt)
{
  return EVP_CIPHER_key_length (cipher_kt);
}
Пример #4
0
X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter,
                              unsigned char *salt, int saltlen,
                              unsigned char *aiv, int prf_nid)
{
    X509_ALGOR *scheme = NULL, *kalg = NULL, *ret = NULL;
    int alg_nid, keylen;
    EVP_CIPHER_CTX ctx;
    unsigned char iv[EVP_MAX_IV_LENGTH];
    PBE2PARAM *pbe2 = NULL;
    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;

}
Пример #5
0
// return EVP cipher key size
static int cryptoGetEVPCipherSize(struct s_crypto_cipher *st_cipher) {
	return EVP_CIPHER_key_length(st_cipher->cipher);
}
Пример #6
0
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);
	}
Пример #7
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);
	}
Пример #8
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);
}
Пример #9
0
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;
}
Пример #10
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;
}
Пример #11
0
static int sqlcipher_openssl_get_key_sz(void *ctx) {
  return EVP_CIPHER_key_length(((openssl_ctx *)ctx)->evp_cipher);
}
Пример #12
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;
    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;
}
Пример #13
0
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;
}
Пример #14
0
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);
	}
Пример #16
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);
}
Пример #17
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);
	}
Пример #18
0
/* 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);
}
Пример #19
0
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);
	}
Пример #20
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);
}
Пример #21
0
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);
	}
Пример #22
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;
}
Пример #23
0
// 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;
}
Пример #24
0
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;
}
Пример #25
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);
    }
}
Пример #26
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;
}
Пример #27
0
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;
}
Пример #29
0
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));
	}
Пример #30
0
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);
}