Beispiel #1
0
int
main(int argc, char **argv)
{
    int encryptp = 1;
    const char *ifn = NULL, *ofn = NULL;
    FILE *in, *out;
    void *ibuf, *obuf;
    int ilen, olen;
    size_t block_size = 0;
    const EVP_CIPHER *c = EVP_aes_128_cbc();
    EVP_CIPHER_CTX ctx;
    int ret;

    setprogname(argv[0]);

    if (argc == 2) {
	if (strcmp(argv[1], "--version") == 0) {
	    printf("version");
	    exit(0);
	}
	if (strcmp(argv[1], "--help") == 0)
	    usage(0);
	usage(1);
    } else if (argc == 4) {
	block_size = atoi(argv[1]);
	if (block_size == 0)
	    errx(1, "invalid blocksize %s", argv[1]);
	ifn = argv[2];
	ofn = argv[3];
    } else
	usage(1);

    in = fopen(ifn, "r");
    if (in == NULL)
	errx(1, "failed to open input file");
    out = fopen(ofn, "w+");
    if (out == NULL)
	errx(1, "failed to open output file");

    /* Check that key and ivec are long enough */
    assert(EVP_CIPHER_key_length(c) <= sizeof(key));
    assert(EVP_CIPHER_iv_length(c) <= sizeof(ivec));

    /*
     * Allocate buffer, the output buffer is at least
     * EVP_CIPHER_block_size() longer
     */
    ibuf = malloc(block_size);
    obuf = malloc(block_size + EVP_CIPHER_block_size(c));

    /*
     * Init the memory used for EVP_CIPHER_CTX and set the key and
     * ivec.
     */
    EVP_CIPHER_CTX_init(&ctx);
    EVP_CipherInit_ex(&ctx, c, NULL, key, ivec, encryptp);

    /* read in buffer */
    while ((ilen = fread(ibuf, 1, block_size, in)) > 0) {
	/* encrypto/decrypt */
	ret = EVP_CipherUpdate(&ctx, obuf, &olen, ibuf, ilen);
	if (ret != 1) {
	    EVP_CIPHER_CTX_cleanup(&ctx);
	    errx(1, "EVP_CipherUpdate failed");
	}
	/* write out to output file */
	fwrite(obuf, 1, olen, out);
    }
    /* done reading */
    fclose(in);

    /* clear up any last bytes left in the output buffer */
    ret = EVP_CipherFinal_ex(&ctx, obuf, &olen);
    EVP_CIPHER_CTX_cleanup(&ctx);
    if (ret != 1)
	errx(1, "EVP_CipherFinal_ex failed");

    /* write the last bytes out and close */
    fwrite(obuf, 1, olen, out);
    fclose(out);

    return 0;
}
Beispiel #2
0
unsigned char *rncryptorc_decrypt_data_with_password(const unsigned char *indata,
        int indata_len,
        int kdf_iter,
        const char *password,
        int password_length,
        int *outdata_len,
        char *errbuf,
        int errbuf_len)
{
    MutilsBlob
        *blob = NULL;

    RNCryptorInfo
        *ci = NULL;

    int
        rc,
        outlen1=0,
        outlen2=0;

    EVP_CIPHER_CTX
        cipher_ctx;

    unsigned char
        *outdata = NULL;

    if (errbuf_len <= 0)
    {
        log_err("ERROR:Invalid errbuf len %d",errbuf_len);
        goto ExitProcessing;
    }

    if (indata == NULL)
    {
        (void)snprintf(errbuf,errbuf_len-1,"%s",
                "Input data is NULL");
        goto ExitProcessing;
    }
    if (password == NULL || *password == '\0')
    {
        (void)snprintf(errbuf,errbuf_len-1,"%s",
                "Password is NULL");
        goto ExitProcessing;
    }
    if (password_length <= 0)
    {
        (void)snprintf(errbuf,errbuf_len-1,
                "Invalid password length %d",password_length);
        goto ExitProcessing;
    }

    *outdata_len = 0;

    /* convert input data to our blob */
    blob = mutils_data_to_blob((unsigned char *)indata,indata_len);
    CHECK_MALLOC(blob);

    /* decode */
    log_debug("%s:%d - Decoding ..",MCFL);
    ci = decode_encrypted_blob(blob);
    if (!ci)
    {
        goto ExitProcessing;
    }
    ci->options = 0x01;

    rc = verify_rncryptor_format(ci->version,ci->options);
    if (rc != SUCCESS)
    {
        (void)snprintf(errbuf,errbuf_len-1,"%s",
                "Unknown RNCryptor Data Format");
        goto ExitProcessing;
    }
    log_debug("%s:%d - Decoded version 0x%02x options 0x%02x",
            MCFL,
            ci->version,
            ci->options);

    log_debug("%s:%d - Verifying HMAC-SHA256 digest",MCFL);
    /* very hmac */
    if (verify_hmac(ci,password,password_length) != SUCCESS)
    {
        (void)snprintf(errbuf,errbuf_len-1,"%s",
                "Could not verify HMAC");
        goto ExitProcessing;
    }
    log_debug("%s:%d - HMAC verified",MCFL);

    /* Derive cipher key from password using encr salt and iteration as per RFC2898 */
    log_debug("%s:%d - Deriving Cipher key with salt, iteration %d",
            MCFL,
            kdf_iter);
    rc = PKCS5_PBKDF2_HMAC_SHA1(password,password_length,
            ci->encryption_salt,
            sizeof(ci->encryption_salt),
            ci->kdf_iter,
            sizeof(ci->encr_key),
            ci->encr_key); /* ci->encr_key is returend */
    if (rc != 1)
    {
        log_err("ERROR: Could not derive key from password with encr salt and iter");
        goto ExitProcessing;
    }
    log_debug("%s:%d - Encryption key derived",MCFL);

    /* decrypt */
    outdata = (unsigned char *)malloc(ci->cipher_text_length *sizeof(unsigned char));
    CHECK_MALLOC(outdata);

    log_debug("%s:%d - Decrypting..",MCFL);
    EVP_DecryptInit(&cipher_ctx,EVP_aes_256_cbc(),ci->encr_key,ci->iv);
    EVP_DecryptUpdate(&cipher_ctx,outdata,&outlen1,ci->cipher_text,
            ci->cipher_text_length);
    EVP_DecryptFinal(&cipher_ctx,outdata + outlen1,&outlen2);
    EVP_CIPHER_CTX_cleanup(&cipher_ctx);

    *outdata_len = outlen1 + outlen2;
    log_debug("%s:%d - Done decrypting, output length %d bytes",MCFL,*outdata_len);
ExitProcessing:
    if (ci)
    {
        free_rncryptor_info(ci);
    }
    if (blob)
    {
        mutils_destroy_blob(blob);
    }

    return(outdata);
}
Beispiel #3
0
int PEM_ASN1_write_bio(i2d_of_void *i2d, const char *name, BIO *bp,
		       void *x, const EVP_CIPHER *enc, unsigned char *kstr,
		       int klen, pem_password_cb *callback, void *u)
	{
	EVP_CIPHER_CTX ctx;
	int dsize=0,i,j,ret=0;
	unsigned char *p,*data=NULL;
	const char *objstr=NULL;
	char buf[PEM_BUFSIZE];
	unsigned char key[EVP_MAX_KEY_LENGTH];
	unsigned char iv[EVP_MAX_IV_LENGTH];
	
	if (enc != NULL)
		{
		objstr=OBJ_nid2sn(EVP_CIPHER_nid(enc));
		if (objstr == NULL)
			{
			PEMerr(PEM_F_PEM_ASN1_WRITE_BIO,PEM_R_UNSUPPORTED_CIPHER);
			goto err;
			}
		}

	if ((dsize=i2d(x,NULL)) < 0)
		{
		PEMerr(PEM_F_PEM_ASN1_WRITE_BIO,ERR_R_ASN1_LIB);
		dsize=0;
		goto err;
		}
	/* dzise + 8 bytes are needed */
	/* actually it needs the cipher block size extra... */
	data=(unsigned char *)OPENSSL_malloc((unsigned int)dsize+20);
	if (data == NULL)
		{
		PEMerr(PEM_F_PEM_ASN1_WRITE_BIO,ERR_R_MALLOC_FAILURE);
		goto err;
		}
	p=data;
	i=i2d(x,&p);

	if (enc != NULL)
		{
		if (kstr == NULL)
			{
			if (callback == NULL)
				klen=PEM_def_callback(buf,PEM_BUFSIZE,1,u);
			else
				klen=(*callback)(buf,PEM_BUFSIZE,1,u);
			if (klen <= 0)
				{
				PEMerr(PEM_F_PEM_ASN1_WRITE_BIO,PEM_R_READ_KEY);
				goto err;
				}
#ifdef CHARSET_EBCDIC
			/* Convert the pass phrase from EBCDIC */
			ebcdic2ascii(buf, buf, klen);
#endif
			kstr=(unsigned char *)buf;
			}
		RAND_add(data,i,0);/* put in the RSA key. */
		OPENSSL_assert(enc->iv_len <= (int)sizeof(iv));
		if (RAND_pseudo_bytes(iv,enc->iv_len) < 0) /* Generate a salt */
			goto err;
		/* The 'iv' is used as the iv and as a salt.  It is
		 * NOT taken from the BytesToKey function */
		if (!EVP_BytesToKey(enc,EVP_md5(),iv,kstr,klen,1,key,NULL))
			goto err;

		if (kstr == (unsigned char *)buf) OPENSSL_cleanse(buf,PEM_BUFSIZE);

		OPENSSL_assert(strlen(objstr)+23+2*enc->iv_len+13 <= sizeof buf);

		buf[0]='\0';
		PEM_proc_type(buf,PEM_TYPE_ENCRYPTED);
		PEM_dek_info(buf,objstr,enc->iv_len,(char *)iv);
		/* k=strlen(buf); */

		EVP_CIPHER_CTX_init(&ctx);
		ret = 1;
		if (!EVP_EncryptInit_ex(&ctx,enc,NULL,key,iv)
			|| !EVP_EncryptUpdate(&ctx,data,&j,data,i)
			|| !EVP_EncryptFinal_ex(&ctx,&(data[j]),&i))
			ret = 0;
		EVP_CIPHER_CTX_cleanup(&ctx);
		if (ret == 0)
			goto err;
		i+=j;
		}
	else
		{
		ret=1;
		buf[0]='\0';
		}
	i=PEM_write_bio(bp,name,buf,data,i);
	if (i <= 0) ret=0;
err:
	OPENSSL_cleanse(key,sizeof(key));
	OPENSSL_cleanse(iv,sizeof(iv));
	OPENSSL_cleanse((char *)&ctx,sizeof(ctx));
	OPENSSL_cleanse(buf,PEM_BUFSIZE);
	if (data != NULL)
		{
		OPENSSL_cleanse(data,(unsigned int)dsize);
		OPENSSL_free(data);
		}
	return(ret);
	}
Beispiel #4
0
OM_uint32 _gssapi_unwrap_arcfour(OM_uint32 *minor_status,
				 const gsskrb5_ctx context_handle,
				 krb5_context context,
				 const gss_buffer_t input_message_buffer,
				 gss_buffer_t output_message_buffer,
				 int *conf_state,
				 gss_qop_t *qop_state,
				 krb5_keyblock *key)
{
    u_char Klocaldata[16];
    krb5_keyblock Klocal;
    krb5_error_code ret;
    uint32_t seq_number;
    size_t datalen;
    OM_uint32 omret;
    u_char k6_data[16], SND_SEQ[8], Confounder[8];
    u_char cksum_data[8];
    u_char *p, *p0;
    int cmp;
    int conf_flag;
    size_t padlen = 0, len;

    if (conf_state)
	*conf_state = 0;
    if (qop_state)
	*qop_state = 0;

    p0 = input_message_buffer->value;

    if (IS_DCE_STYLE(context_handle)) {
	len = GSS_ARCFOUR_WRAP_TOKEN_SIZE +
	    GSS_ARCFOUR_WRAP_TOKEN_DCE_DER_HEADER_SIZE;
	if (input_message_buffer->length < len)
	    return GSS_S_BAD_MECH;
    } else {
	len = input_message_buffer->length;
    }

    omret = _gssapi_verify_mech_header(&p0,
				       len,
				       GSS_KRB5_MECHANISM);
    if (omret)
	return omret;

    /* length of mech header */
    len = (p0 - (u_char *)input_message_buffer->value) +
	GSS_ARCFOUR_WRAP_TOKEN_SIZE;

    if (len > input_message_buffer->length)
	return GSS_S_BAD_MECH;

    /* length of data */
    datalen = input_message_buffer->length - len;

    p = p0;

    if (memcmp(p, "\x02\x01", 2) != 0)
	return GSS_S_BAD_SIG;
    p += 2;
    if (memcmp(p, "\x11\x00", 2) != 0) /* SGN_ALG = HMAC MD5 ARCFOUR */
	return GSS_S_BAD_SIG;
    p += 2;

    if (memcmp (p, "\x10\x00", 2) == 0)
	conf_flag = 1;
    else if (memcmp (p, "\xff\xff", 2) == 0)
	conf_flag = 0;
    else
	return GSS_S_BAD_SIG;

    p += 2;
    if (memcmp (p, "\xff\xff", 2) != 0)
	return GSS_S_BAD_MIC;
    p = NULL;

    ret = arcfour_mic_key(context, key,
			  p0 + 16, 8, /* SGN_CKSUM */
			  k6_data, sizeof(k6_data));
    if (ret) {
	*minor_status = ret;
	return GSS_S_FAILURE;
    }

    {
	EVP_CIPHER_CTX rc4_key;

	EVP_CIPHER_CTX_init(&rc4_key);
	EVP_CipherInit_ex(&rc4_key, EVP_rc4(), NULL, k6_data, NULL, 1);
	EVP_Cipher(&rc4_key, SND_SEQ, p0 + 8, 8);
	EVP_CIPHER_CTX_cleanup(&rc4_key);
	memset(k6_data, 0, sizeof(k6_data));
    }

    _gsskrb5_decode_be_om_uint32(SND_SEQ, &seq_number);

    if (context_handle->more_flags & LOCAL)
	cmp = memcmp(&SND_SEQ[4], "\xff\xff\xff\xff", 4);
    else
	cmp = memcmp(&SND_SEQ[4], "\x00\x00\x00\x00", 4);

    if (cmp != 0) {
	*minor_status = 0;
	return GSS_S_BAD_MIC;
    }

    {
	int i;

	Klocal.keytype = key->keytype;
	Klocal.keyvalue.data = Klocaldata;
	Klocal.keyvalue.length = sizeof(Klocaldata);

	for (i = 0; i < 16; i++)
	    Klocaldata[i] = ((u_char *)key->keyvalue.data)[i] ^ 0xF0;
    }
    ret = arcfour_mic_key(context, &Klocal,
			  SND_SEQ, 4,
			  k6_data, sizeof(k6_data));
    memset(Klocaldata, 0, sizeof(Klocaldata));
    if (ret) {
	*minor_status = ret;
	return GSS_S_FAILURE;
    }

    output_message_buffer->value = malloc(datalen);
    if (output_message_buffer->value == NULL) {
	*minor_status = ENOMEM;
	return GSS_S_FAILURE;
    }
    output_message_buffer->length = datalen;

    if(conf_flag) {
	EVP_CIPHER_CTX rc4_key;

	EVP_CIPHER_CTX_init(&rc4_key);
	EVP_CipherInit_ex(&rc4_key, EVP_rc4(), NULL, k6_data, NULL, 1);
	EVP_Cipher(&rc4_key, Confounder, p0 + 24, 8);
	EVP_Cipher(&rc4_key, output_message_buffer->value, p0 + GSS_ARCFOUR_WRAP_TOKEN_SIZE, datalen);
	EVP_CIPHER_CTX_cleanup(&rc4_key);
    } else {
	memcpy(Confounder, p0 + 24, 8); /* Confounder */
	memcpy(output_message_buffer->value,
	       p0 + GSS_ARCFOUR_WRAP_TOKEN_SIZE,
	       datalen);
    }
    memset(k6_data, 0, sizeof(k6_data));

    if (!IS_DCE_STYLE(context_handle)) {
	ret = _gssapi_verify_pad(output_message_buffer, datalen, &padlen);
	if (ret) {
	    _gsskrb5_release_buffer(minor_status, output_message_buffer);
	    *minor_status = 0;
	    return ret;
	}
	output_message_buffer->length -= padlen;
    }

    ret = arcfour_mic_cksum(context,
			    key, KRB5_KU_USAGE_SEAL,
			    cksum_data, sizeof(cksum_data),
			    p0, 8,
			    Confounder, sizeof(Confounder),
			    output_message_buffer->value,
			    output_message_buffer->length + padlen);
    if (ret) {
	_gsskrb5_release_buffer(minor_status, output_message_buffer);
	*minor_status = ret;
	return GSS_S_FAILURE;
    }

    cmp = ct_memcmp(cksum_data, p0 + 16, 8); /* SGN_CKSUM */
    if (cmp) {
	_gsskrb5_release_buffer(minor_status, output_message_buffer);
	*minor_status = 0;
	return GSS_S_BAD_MIC;
    }

    HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
    omret = _gssapi_msg_order_check(context_handle->order, seq_number);
    HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
    if (omret)
	return omret;

    if (conf_state)
	*conf_state = conf_flag;

    *minor_status = 0;
    return GSS_S_COMPLETE;
}
Beispiel #5
0
unsigned char *rncryptorc_encrypt_data_with_password_with_salts_and_iv(const unsigned char *indata,
        int indata_len,
        int kdf_iter,
        const char *password,
        int password_length,
        unsigned char *encr_salt_8,
        unsigned char *hmac_salt_8,
        unsigned char *iv_16,
        int *outdata_len,
        char *errbuf,
        int errbuf_len)
{
    RNCryptorInfo
        *ci = NULL;

    MutilsBlob
        *blob = NULL;

    EVP_CIPHER_CTX
        cipher_ctx;

    HMAC_CTX
        hmac_ctx;

    int
        rc=FAILURE;

    const EVP_MD
        *sha256 = NULL;

    int
        outlen1 = 0,
        outlen2 = 0;

    unsigned int
        hmac_len;

    unsigned char
        hmac_sha256[32];

    unsigned char
        *output = NULL;

    unsigned int
        blocksize = 16;

    unsigned char
        *ciphertext = NULL;

    unsigned char
        encr_key[32],
        hmac_key[32];

    int
        ciphertext_len;


    log_debug("%s:%d - verifying input",MCFL);
    if (errbuf_len <= 0)
    {
        log_err("ERROR:Invalid errbuf len %d",errbuf_len);
        goto ExitProcessing;
    }

    memset(errbuf,0,errbuf_len);
    memset(encr_key,0,sizeof(encr_key));
    memset(hmac_key,0,sizeof(hmac_key));
    if (password == NULL || *password == '\0')
    {
        (void)snprintf(errbuf,errbuf_len-1,"%s",
                "Password can not be NULL");
        goto ExitProcessing;
    }
    if (password_length <= 0)
    {
        (void)snprintf(errbuf,errbuf_len-1,"Invalid password length %d",password_length);
        goto ExitProcessing;
    }

    ci = allocate_rncryptor_info();
    if (!ci)
    {
        goto ExitProcessing;
    }
    ci->options = 0x01;

    /* Derive cipher key from password using encr salt and iteration as per RFC2898 */
    log_debug("%s:%d - Deriving Cipher key with salt, iterations %d",
            MCFL,
            kdf_iter);

    rc = PKCS5_PBKDF2_HMAC_SHA1(password,password_length,
            encr_salt_8,
            8,
            kdf_iter,
            32,
            encr_key); /* encr_key is returend */
    if (rc != 1)
    {
        log_err("ERROR: Could not derive key from password with encr salt and iter");
        (void)snprintf(errbuf,errbuf_len-1,"%s",
                "Could not derive key from password with encr salt and iter");
        goto ExitProcessing;
    }
    EVP_EncryptInit(&cipher_ctx,EVP_aes_256_cbc(),encr_key,iv_16);
    blocksize = EVP_CIPHER_CTX_block_size(&cipher_ctx);
    log_debug("%s:%d - Block size: %ld",MCFL,blocksize);

    if (indata == NULL && indata_len == 0)
    {
        blob = mutils_allocate_blob(blocksize);
    }
    else
    {
        blob = mutils_allocate_blob(indata_len);
    }
    CHECK_MALLOC(blob);
    log_debug("%s:%d - input data size %d bytes",
            MCFL,
            indata_len);
    log_debug("%s:%d - Encoding",MCFL);

    /*
    ** Encode. memory will be re-allocated for blob if needed.
    */

    /* version */
    mutils_write_blob_byte(blob,ci->version);

    /* options */
    mutils_write_blob_byte(blob,ci->options);

    /* 8 byte encryption salt, we're using password */
    mutils_write_blob(blob,8,encr_salt_8);

    /* 8 byte hmac salt */
    mutils_write_blob(blob,8,hmac_salt_8);

    /* 16 byte iv */
    mutils_write_blob(blob,16,iv_16);

    log_debug("%s:%d - Deriving HMAC key with salt, iterations %d",
            MCFL,
            kdf_iter);
    /* Derive HMAC key from password using hmac salt and iteration as per RFC2898 */
    rc = PKCS5_PBKDF2_HMAC_SHA1(password,password_length,
            hmac_salt_8,
            8,
            kdf_iter,
            32,
            hmac_key); /* hmac_key is returend */
    if (rc != 1)
    {
        log_err("ERROR: Could not derive key from password with hmac salt and iter");
        (void)snprintf(errbuf,errbuf_len-1,"%s",
                "Could not derive key from password with hmac salt and iter");
        goto ExitProcessing;
    }

    log_debug("%s:%d - Encrypting..",MCFL);
    /* allocate space for cipher text */
    ciphertext_len = indata_len + blocksize - (indata_len % blocksize);
    ciphertext = (unsigned char *) malloc(ciphertext_len * sizeof(unsigned char));
    CHECK_MALLOC(ciphertext);

    EVP_EncryptUpdate(&cipher_ctx,ciphertext,&outlen1,indata,indata_len);
    EVP_EncryptFinal(&cipher_ctx,ciphertext + outlen1,&outlen2);
    EVP_CIPHER_CTX_cleanup(&cipher_ctx);
    mutils_write_blob(blob,outlen1 + outlen2,ciphertext);

    log_debug("%s:%d - Plain text length: %d",MCFL,indata_len);
    log_debug("%s:%d - Cipther text length: %d",MCFL,outlen1 + outlen2);
    log_debug("%s:%d - Padding %d bytes",
            MCFL,
            (ciphertext_len - indata_len));
    log_debug("%s:%d - outdata len: %d",MCFL,outlen1 + outlen2);

    log_debug("%s:%d - calculating HMAC-SHA256",MCFL);
    /* calculate HMAC-SHA256 */
    sha256 = EVP_sha256();
    HMAC_CTX_init(&hmac_ctx);
    HMAC_Init(&hmac_ctx,hmac_key,sizeof(hmac_key),sha256);
    HMAC_Update(&hmac_ctx,blob->data,blob->length);
    HMAC_Final(&hmac_ctx,hmac_sha256,&hmac_len);
    HMAC_CTX_cleanup(&hmac_ctx);

    mutils_write_blob(blob,hmac_len,hmac_sha256);
    log_debug("%s:%d - Output lenth %lu",MCFL,blob->length);

    output = (unsigned char *)malloc(blob->length * sizeof(unsigned char));
    CHECK_MALLOC(output);

    memcpy(output,blob->data,blob->length);
    *outdata_len = blob->length;
ExitProcessing:
    if (ci)
    {
        free_rncryptor_info(ci);
    }

    if (blob)
    {
        mutils_destroy_blob(blob);
    }
    if (ciphertext)
    {
        (void)free((char *)ciphertext);
    }
    return(output);
}
Beispiel #6
0
static int i2b_PVK(unsigned char **out, EVP_PKEY *pk, int enclevel,
                   pem_password_cb *cb, void *u)
{
    int outlen = 24, pklen;
    unsigned char *p, *salt = NULL;
    EVP_CIPHER_CTX cctx;
    EVP_CIPHER_CTX_init(&cctx);
    if (enclevel)
        outlen += PVK_SALTLEN;
    pklen = do_i2b(NULL, pk, 0);
    if (pklen < 0)
        return -1;
    outlen += pklen;
    if (!out)
        return outlen;
    if (*out)
        p = *out;
    else {
        p = OPENSSL_malloc(outlen);
        if (!p) {
            PEMerr(PEM_F_I2B_PVK, ERR_R_MALLOC_FAILURE);
            return -1;
        }
        *out = p;
    }

    write_ledword(&p, MS_PVKMAGIC);
    write_ledword(&p, 0);
    if (pk->type == EVP_PKEY_DSA)
        write_ledword(&p, MS_KEYTYPE_SIGN);
    else
        write_ledword(&p, MS_KEYTYPE_KEYX);
    write_ledword(&p, enclevel ? 1 : 0);
    write_ledword(&p, enclevel ? PVK_SALTLEN : 0);
    write_ledword(&p, pklen);
    if (enclevel) {
        if (RAND_bytes(p, PVK_SALTLEN) <= 0)
            goto error;
        salt = p;
        p += PVK_SALTLEN;
    }
    do_i2b(&p, pk, 0);
    if (enclevel == 0)
        return outlen;
    else {
        char psbuf[PEM_BUFSIZE];
        unsigned char keybuf[20];
        int enctmplen, inlen;
        if (cb)
            inlen = cb(psbuf, PEM_BUFSIZE, 1, u);
        else
            inlen = PEM_def_callback(psbuf, PEM_BUFSIZE, 1, u);
        if (inlen <= 0) {
            PEMerr(PEM_F_I2B_PVK, PEM_R_BAD_PASSWORD_READ);
            goto error;
        }
        if (!derive_pvk_key(keybuf, salt, PVK_SALTLEN,
                            (unsigned char *)psbuf, inlen))
            goto error;
        if (enclevel == 1)
            memset(keybuf + 5, 0, 11);
        p = salt + PVK_SALTLEN + 8;
        if (!EVP_EncryptInit_ex(&cctx, EVP_rc4(), NULL, keybuf, NULL))
            goto error;
        OPENSSL_cleanse(keybuf, 20);
        if (!EVP_DecryptUpdate(&cctx, p, &enctmplen, p, pklen - 8))
            goto error;
        if (!EVP_DecryptFinal_ex(&cctx, p + enctmplen, &enctmplen))
            goto error;
    }
    EVP_CIPHER_CTX_cleanup(&cctx);
    return outlen;

 error:
    EVP_CIPHER_CTX_cleanup(&cctx);
    return -1;
}
Beispiel #7
0
OM_uint32
_gssapi_verify_mic_arcfour(OM_uint32 * minor_status,
			   const gsskrb5_ctx context_handle,
			   krb5_context context,
			   const gss_buffer_t message_buffer,
			   const gss_buffer_t token_buffer,
			   gss_qop_t * qop_state,
			   krb5_keyblock *key,
			   const char *type)
{
    krb5_error_code ret;
    uint32_t seq_number;
    OM_uint32 omret;
    u_char SND_SEQ[8], cksum_data[8], *p;
    char k6_data[16];
    int cmp;

    if (qop_state)
	*qop_state = 0;

    p = token_buffer->value;
    omret = _gsskrb5_verify_header (&p,
				       token_buffer->length,
				       type,
				       GSS_KRB5_MECHANISM);
    if (omret)
	return omret;

    if (memcmp(p, "\x11\x00", 2) != 0) /* SGN_ALG = HMAC MD5 ARCFOUR */
	return GSS_S_BAD_SIG;
    p += 2;
    if (memcmp (p, "\xff\xff\xff\xff", 4) != 0)
	return GSS_S_BAD_MIC;
    p += 4;

    ret = arcfour_mic_cksum(context,
			    key, KRB5_KU_USAGE_SIGN,
			    cksum_data, sizeof(cksum_data),
			    p - 8, 8,
			    message_buffer->value, message_buffer->length,
			    NULL, 0);
    if (ret) {
	*minor_status = ret;
	return GSS_S_FAILURE;
    }

    ret = arcfour_mic_key(context, key,
			  cksum_data, sizeof(cksum_data),
			  k6_data, sizeof(k6_data));
    if (ret) {
	*minor_status = ret;
	return GSS_S_FAILURE;
    }

    cmp = ct_memcmp(cksum_data, p + 8, 8);
    if (cmp) {
	*minor_status = 0;
	return GSS_S_BAD_MIC;
    }

    {
	EVP_CIPHER_CTX rc4_key;

	EVP_CIPHER_CTX_init(&rc4_key);
	EVP_CipherInit_ex(&rc4_key, EVP_rc4(), NULL, (void *)k6_data, NULL, 0);
	EVP_Cipher(&rc4_key, SND_SEQ, p, 8);
	EVP_CIPHER_CTX_cleanup(&rc4_key);

	memset(k6_data, 0, sizeof(k6_data));
    }

    _gsskrb5_decode_be_om_uint32(SND_SEQ, &seq_number);

    if (context_handle->more_flags & LOCAL)
	cmp = memcmp(&SND_SEQ[4], "\xff\xff\xff\xff", 4);
    else
	cmp = memcmp(&SND_SEQ[4], "\x00\x00\x00\x00", 4);

    memset(SND_SEQ, 0, sizeof(SND_SEQ));
    if (cmp != 0) {
	*minor_status = 0;
	return GSS_S_BAD_MIC;
    }

    HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
    omret = _gssapi_msg_order_check(context_handle->order, seq_number);
    HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
    if (omret)
	return omret;

    *minor_status = 0;
    return GSS_S_COMPLETE;
}
Beispiel #8
0
void
cipher_ctx_cleanup (EVP_CIPHER_CTX *ctx)
{
  EVP_CIPHER_CTX_cleanup (ctx);
}
Beispiel #9
0
long _IKED::packet_ike_decrypt( IDB_PH1 * sa, PACKET_IKE & packet, BDATA * iv )
{
	log.txt( LLOG_INFO,
		"=< : cookies %08x%08x:%08x%08x\n",
		htonl( *( long * ) &sa->cookies.i[ 0 ] ),
		htonl( *( long * ) &sa->cookies.i[ 4 ] ),
		htonl( *( long * ) &sa->cookies.r[ 0 ] ),
		htonl( *( long * ) &sa->cookies.r[ 4 ] ) );

	log.txt( LLOG_INFO,
		"=< : message %08x\n",
		htonl( packet.get_msgid() ) );

	//
	// check if decrypt is required
	//

	unsigned char *	data = packet.buff();
	size_t		    size = packet.size();

	if( !( data[ ISAKMP_FLAGS_OFFSET ] & ISAKMP_FLAG_ENCRYPT ) )
		return LIBIKE_OK;

	log.bin(
		LLOG_DEBUG,
		LLOG_DECODE,
		iv->buff(),
		iv->size(),
		"=< : decrypt iv" );

	//
	// temporarily save enough
	// of the packet to store
	// as iv data post decrypt
	//

	unsigned char iv_data[ HMAC_MAX_MD_CBLOCK ];

	memcpy(
		iv_data,
		data + size - iv->size(),
		iv->size() );

	//
	// init cipher key and iv
	//

	EVP_CIPHER_CTX ctx_cipher;
	EVP_CIPHER_CTX_init( &ctx_cipher );

	EVP_CipherInit_ex(
		&ctx_cipher,
		sa->evp_cipher,
		NULL,
		NULL,
		NULL,
		0 );

	EVP_CIPHER_CTX_set_key_length(
		&ctx_cipher,
		( int ) sa->key.size() );

	EVP_CipherInit_ex(
		&ctx_cipher,
		NULL,
		NULL,
		sa->key.buff(),
		iv->buff(),
		0 );

	//
	// decrypt all but header
	//

	EVP_Cipher(
		&ctx_cipher,
		data + sizeof( IKE_HEADER ),
		data + sizeof( IKE_HEADER ),
		( int ) size - sizeof( IKE_HEADER ) );

	EVP_CIPHER_CTX_cleanup( &ctx_cipher );

	log.bin(
		LLOG_DEBUG,
		LLOG_DECODE,
		data,
		size,
		"== : decrypt packet" );

	//
	// validate the packet integrity
	//

	IKE_HEADER * header = ( IKE_HEADER * ) packet.buff();

	size = sizeof( IKE_HEADER );

	if( packet.size() < size )
	{
		log.txt( LLOG_ERROR,
			"!! : validate packet failed ( truncated header )\n" );

		return LIBIKE_FAILED;
	}

	while( true )
	{
		IKE_PAYLOAD * payload = ( IKE_PAYLOAD * )( packet.buff() + size );

		if( packet.size() < ( size + sizeof( IKE_PAYLOAD ) ) )
		{
			log.txt( LLOG_ERROR,
				"!! : validate packet failed ( truncated payload )\n" );

			return LIBIKE_FAILED;
		}

		if( payload->reserved )
		{
			log.txt( LLOG_ERROR,
				"!! : validate packet failed ( reserved value is non-null )\n" );

			return LIBIKE_FAILED;
		}

		size += ntohs( payload->length );

		if( packet.size() < size )
		{
			log.txt( LLOG_ERROR,
				"!! : validate packet failed ( payload length is invalid )\n" );

			return LIBIKE_FAILED;
		}

		if( payload->next == ISAKMP_PAYLOAD_NONE )
			break;
	}

	//
	// validate packet padding. if the encrypted
	// packet size is equal to the ike message
	// length, we can skip this step. although the
	// RFC states there should at least be one pad
	// byte that describes the padding length, if
	// we are strict we will break compatibility
	// with many implementations including cisco
	//

	if( size < packet.size() )
	{
		//
		// trim packet padding
		//

		size_t diff = packet.size() - size;

		packet.size( size );

		log.txt( LLOG_DEBUG,
			"<= : trimmed packet padding ( %i bytes )\n",
			 diff );

		header = ( IKE_HEADER * ) packet.buff();
		header->length = htonl( ( uint32_t ) size );
	}

	//
	// store cipher iv data
	//

	memcpy(
		iv->buff(),
		iv_data,
		iv->size() );

	log.bin(
		LLOG_DEBUG,
		LLOG_DECODE,
		iv->buff(),
		iv->size(),
		"<= : stored iv" );
	
	return LIBIKE_OK;
}
Beispiel #10
0
static int tls_decrypt_ticket(SSL *s, const unsigned char *etick, int eticklen,
				const unsigned char *sess_id, int sesslen,
				SSL_SESSION **psess)
	{
	SSL_SESSION *sess;
	unsigned char *sdec;
	const unsigned char *p;
	int slen, mlen;
	unsigned char tick_hmac[EVP_MAX_MD_SIZE];
	HMAC_CTX hctx;
	EVP_CIPHER_CTX ctx;
	/* Attempt to process session ticket, first conduct sanity and
 	 * integrity checks on ticket.
 	 */
	mlen = EVP_MD_size(tlsext_tick_md());
	eticklen -= mlen;
	/* Need at least keyname + iv + some encrypted data */
	if (eticklen < 48)
		goto tickerr;
	/* Check key name matches */
	if (memcmp(etick, s->ctx->tlsext_tick_key_name, 16))
		goto tickerr;
	/* Check HMAC of encrypted ticket */
	HMAC_CTX_init(&hctx);
	HMAC_Init_ex(&hctx, s->ctx->tlsext_tick_hmac_key, 16,
				tlsext_tick_md(), NULL);
	HMAC_Update(&hctx, etick, eticklen);
	HMAC_Final(&hctx, tick_hmac, NULL);
	HMAC_CTX_cleanup(&hctx);
	if (memcmp(tick_hmac, etick + eticklen, mlen))
		goto tickerr;
	/* Set p to start of IV */
	p = etick + 16;
	EVP_CIPHER_CTX_init(&ctx);
	/* Attempt to decrypt session data */
	EVP_DecryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL,
					s->ctx->tlsext_tick_aes_key, p);
	/* Move p after IV to start of encrypted ticket, update length */
	p += 16;
	eticklen -= 32;
	sdec = OPENSSL_malloc(eticklen);
	if (!sdec)
		{
		EVP_CIPHER_CTX_cleanup(&ctx);
		return -1;
		}
	EVP_DecryptUpdate(&ctx, sdec, &slen, p, eticklen);
	if (EVP_DecryptFinal(&ctx, sdec + slen, &mlen) <= 0)
		goto tickerr;
	slen += mlen;
	EVP_CIPHER_CTX_cleanup(&ctx);
	p = sdec;
		
	sess = d2i_SSL_SESSION(NULL, &p, slen);
	OPENSSL_free(sdec);
	if (sess)
		{
		/* The session ID if non-empty is used by some clients to
 		 * detect that the ticket has been accepted. So we copy it to
 		 * the session structure. If it is empty set length to zero
 		 * as required by standard.
 		 */
		if (sesslen)
			memcpy(sess->session_id, sess_id, sesslen);
		sess->session_id_length = sesslen;
		*psess = sess;
		s->tlsext_ticket_expected = 0;
		return 1;
		}
	/* If session decrypt failure indicate a cache miss and set state to
 	 * send a new ticket
 	 */
	tickerr:	
	s->tlsext_ticket_expected = 1;
	return 0;
	}
Beispiel #11
0
static int
try_decrypt(hx509_context context,
	    struct hx509_collector *collector,
	    const AlgorithmIdentifier *alg,
	    const EVP_CIPHER *c,
	    const void *ivdata,
	    const void *password,
	    size_t passwordlen,
	    const void *cipher,
	    size_t len)
{
    heim_octet_string clear;
    size_t keylen;
    void *key;
    int ret;

    keylen = EVP_CIPHER_key_length(c);

    key = malloc(keylen);
    if (key == NULL) {
	hx509_clear_error_string(context);
	return ENOMEM;
    }

    ret = EVP_BytesToKey(c, EVP_md5(), ivdata,
			 password, passwordlen,
			 1, key, NULL);
    if (ret <= 0) {
	hx509_set_error_string(context, 0, HX509_CRYPTO_INTERNAL_ERROR,
			       "Failed to do string2key for private key");
	return HX509_CRYPTO_INTERNAL_ERROR;
    }

    clear.data = malloc(len);
    if (clear.data == NULL) {
	hx509_set_error_string(context, 0, ENOMEM,
			       "Out of memory to decrypt for private key");
	ret = ENOMEM;
	goto out;
    }
    clear.length = len;

    {
	EVP_CIPHER_CTX ctx;
	EVP_CIPHER_CTX_init(&ctx);
	EVP_CipherInit_ex(&ctx, c, NULL, key, ivdata, 0);
	EVP_Cipher(&ctx, clear.data, cipher, len);
	EVP_CIPHER_CTX_cleanup(&ctx);
    }	

    ret = _hx509_collector_private_key_add(context,
					   collector,
					   alg,
					   NULL,
					   &clear,
					   NULL);

    memset(clear.data, 0, clear.length);
    free(clear.data);
out:
    memset(key, 0, keylen);
    free(key);
    return ret;
}
Beispiel #12
0
static int entersafe_mac_apdu(sc_card_t *card, sc_apdu_t *apdu,
							  u8 * key,size_t keylen,
							  u8 * buff,size_t buffsize)
{
	 int r;
	 u8 iv[8];
	 u8 *tmp=0,*tmp_rounded=NULL;
	 size_t tmpsize=0,tmpsize_rounded=0;
	 int outl=0;
	 EVP_CIPHER_CTX ctx;

	SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);

	 assert(card);
	 assert(apdu);
	 assert(key);
	 assert(buff);

	 if(apdu->cse != SC_APDU_CASE_3_SHORT)
		  return SC_ERROR_INTERNAL;
	 if(keylen!=8 && keylen!=16)
		  return SC_ERROR_INTERNAL;

	 r=entersafe_gen_random(card,iv,sizeof(iv));
	 SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL,r,"entersafe gen random failed");

	 /* encode the APDU in the buffer */
	 if ((r=sc_apdu_get_octets(card->ctx, apdu, &tmp, &tmpsize,SC_PROTO_RAW)) != SC_SUCCESS)
		  goto out;

	 /* round to 8 */
	 tmpsize_rounded=(tmpsize/8+1)*8;

	 tmp_rounded = malloc(tmpsize_rounded);
	 if (tmp_rounded == NULL)
	 {
		  r =  SC_ERROR_OUT_OF_MEMORY;
		  goto out;
	 }
	 
	 /*build content and padded buffer by 0x80 0x00 0x00..... */
	 memset(tmp_rounded,0,tmpsize_rounded);
	 memcpy(tmp_rounded,tmp,tmpsize);
	 tmp_rounded[4]+=4;
	 tmp_rounded[tmpsize]=0x80;

	 /* block_size-1 blocks*/
	 EVP_CIPHER_CTX_init(&ctx);
	 EVP_CIPHER_CTX_set_padding(&ctx,0);
	 EVP_EncryptInit_ex(&ctx, EVP_des_cbc(), NULL, key, iv);

	 if(tmpsize_rounded>8){
		  if(!EVP_EncryptUpdate(&ctx,tmp_rounded,&outl,tmp_rounded,tmpsize_rounded-8)){
			   r = SC_ERROR_INTERNAL;
			   goto out;			   
		  }
	 }
	 /* last block */
	 if(keylen==8)
	 {
		  if(!EVP_EncryptUpdate(&ctx,tmp_rounded+outl,&outl,tmp_rounded+outl,8)){
			   r = SC_ERROR_INTERNAL;
			   goto out;			   
		  }
	 }
	 else
	 {
		  EVP_EncryptInit_ex(&ctx, EVP_des_ede_cbc(), NULL, key,tmp_rounded+outl-8);
		  if(!EVP_EncryptUpdate(&ctx,tmp_rounded+outl,&outl,tmp_rounded+outl,8)){
			   r = SC_ERROR_INTERNAL;
			   goto out;			   
		  }
	 }

	 if (!EVP_CIPHER_CTX_cleanup(&ctx)){
		  r = SC_ERROR_INTERNAL;
		  goto out;			   
	 }

	 memcpy(buff,apdu->data,apdu->lc);
	 /* use first 4 bytes of last block as mac value*/
	 memcpy(buff+apdu->lc,tmp_rounded+tmpsize_rounded-8,4);
	 apdu->data=buff;
	 apdu->lc+=4;
	 apdu->datalen=apdu->lc;

out:
	 if(tmp)
		  free(tmp);
	 if(tmp_rounded)
		  free(tmp_rounded);

	 SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r);
}
int AesFileEnc::do_crypt(FILE *in, FILE *out, int do_encrypt)
{
	/* Allow enough space in output buffer for additional block */
	unsigned char inbuf[1024], outbuf[1024 + EVP_MAX_BLOCK_LENGTH];
	int inlen, outlen;
	EVP_CIPHER_CTX ctx;

	std::cout << "tutaj";
	unsigned char* key = this->key();
	//	std::cout <<key<<std::endl;
	//unsigned char key[] = "0123456789abcdeF";
	std::cout <<key<< std::endl;


	//unsigned char iv[] = "1234567887654321";
	EVP_CIPHER_CTX_init(&ctx);
	
	switch(this->type)
	{
		case cbc128:
			EVP_CipherInit_ex(&ctx, EVP_aes_128_cbc(), NULL, NULL, NULL,
				do_encrypt);
			break;
		case cbc192:
			EVP_CipherInit_ex(&ctx, EVP_aes_192_cbc(), NULL, NULL, NULL,
				do_encrypt);
		break;
		case cbc256:
			EVP_CipherInit_ex(&ctx, EVP_aes_256_cbc(), NULL, NULL, NULL,
				do_encrypt);
			break;
		case ecb128:
			EVP_CipherInit_ex(&ctx, EVP_aes_128_ecb(), NULL, NULL, NULL,
				do_encrypt);
			break;
		case ecb192:
			EVP_CipherInit_ex(&ctx, EVP_aes_192_ecb(), NULL, NULL, NULL,
				do_encrypt);
			break;
		case ecb256:
			EVP_CipherInit_ex(&ctx, EVP_aes_256_ecb(), NULL, NULL, NULL,
				do_encrypt);
			break;
		case cfb128:
			EVP_CipherInit_ex(&ctx, EVP_aes_128_cfb(), NULL, NULL, NULL,
				do_encrypt);
			break;
		case cfb192:
			EVP_CipherInit_ex(&ctx, EVP_aes_192_cfb(), NULL, NULL, NULL,
				do_encrypt);
			break;
		case cfb256:
			EVP_CipherInit_ex(&ctx, EVP_aes_256_cfb(), NULL, NULL, NULL,
				do_encrypt);
			break;
		case ofb128:
			EVP_CipherInit_ex(&ctx, EVP_aes_128_ofb(), NULL, NULL, NULL,
				do_encrypt);

			break;
		case ofb192:
			EVP_CipherInit_ex(&ctx, EVP_aes_192_ofb(), NULL, NULL, NULL,
				do_encrypt);
			break;
		case ofb256:
			EVP_CipherInit_ex(&ctx, EVP_aes_256_ofb(), NULL, NULL, NULL,
				do_encrypt);
			break;
	}
	unsigned char *iv = this->iv(EVP_CIPHER_CTX_iv_length(&ctx));	
			std::cout<< this->keyLength << std::endl;
			std::cout<< EVP_CIPHER_CTX_iv_length(&ctx) <<std::endl;
			OPENSSL_assert(EVP_CIPHER_CTX_key_length(&ctx) == this->keyLength);
			//OPENSSL_assert(EVP_CIPHER_CTX_iv_length(&ctx) == this->keyLength);
			EVP_CipherInit_ex(&ctx, NULL, NULL, key, iv, do_encrypt);
	
			for(;;)
					{
					inlen = fread(inbuf, 1, 1024, in);
					if(inlen <= 0) break;
					if(!EVP_CipherUpdate(&ctx, outbuf, &outlen, inbuf, inlen))
							{
	
							EVP_CIPHER_CTX_cleanup(&ctx);
							return 0;
							}
					fwrite(outbuf, 1, outlen, out);
					}
			if(!EVP_CipherFinal_ex(&ctx, outbuf, &outlen))
					{

					EVP_CIPHER_CTX_cleanup(&ctx);
					return 0;
					}
			fwrite(outbuf, 1, outlen, out);

			EVP_CIPHER_CTX_cleanup(&ctx);
			return 1;
			}
Beispiel #14
0
void crypto_aes_close (crypto_aes_t *crypto) {
    EVP_CIPHER_CTX_cleanup(&(crypto->enc));
    EVP_CIPHER_CTX_cleanup(&(crypto->dec));
    pthread_mutex_destroy(&(crypto->lock));
    free(crypto);
}
Beispiel #15
0
int
ciphers_valid(const char *names)
{
	const Cipher *c;
	char *cipher_list, *cp;
	char *p;

	if (names == NULL || strcmp(names, "") == 0)
		return 0;
	cipher_list = cp = xstrdup(names);
	for ((p = strsep(&cp, CIPHER_SEP)); p && *p != '\0';
	    (p = strsep(&cp, CIPHER_SEP))) {
		c = cipher_by_name(p);
#ifdef NONE_CIPHER_ENABLED
		if (c == NULL || (c->number != SSH_CIPHER_SSH2 &&
		    c->number != SSH_CIPHER_NONE)) {
#else
		if (c == NULL || (c->number != SSH_CIPHER_SSH2)) {
#endif
			debug("bad cipher %s [%s]", p, names);
			free(cipher_list);
			return 0;
		}
	}
	debug3("ciphers ok: [%s]", names);
	free(cipher_list);
	return 1;
}

/*
 * Parses the name of the cipher.  Returns the number of the corresponding
 * cipher, or -1 on error.
 */

int
cipher_number(const char *name)
{
	const Cipher *c;
	if (name == NULL)
		return -1;
	for (c = ciphers; c->name != NULL; c++)
		if (strcasecmp(c->name, name) == 0)
			return c->number;
	return -1;
}

char *
cipher_name(int id)
{
	const Cipher *c = cipher_by_number(id);
	return (c==NULL) ? "<unknown>" : c->name;
}

void
cipher_init(CipherContext *cc, const Cipher *cipher,
    const u_char *key, u_int keylen, const u_char *iv, u_int ivlen,
    int do_encrypt)
{
	static int dowarn = 1;
#ifdef SSH_OLD_EVP
	EVP_CIPHER *type;
#else
	const EVP_CIPHER *type;
	int klen;
#endif
	u_char *junk, *discard;

	if (cipher->number == SSH_CIPHER_DES) {
		if (dowarn) {
			error("Warning: use of DES is strongly discouraged "
			    "due to cryptographic weaknesses");
			dowarn = 0;
		}
		if (keylen > 8)
			keylen = 8;
	}
	cc->plaintext = (cipher->number == SSH_CIPHER_NONE);
	cc->encrypt = do_encrypt;

	if (keylen < cipher->key_len)
		fatal("cipher_init: key length %d is insufficient for %s.",
		    keylen, cipher->name);
	if (iv != NULL && ivlen < cipher_ivlen(cipher))
		fatal("cipher_init: iv length %d is insufficient for %s.",
		    ivlen, cipher->name);
	cc->cipher = cipher;

	if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) {
		chachapoly_init(&cc->cp_ctx, key, keylen);
		return;
	}
	type = (*cipher->evptype)();
	EVP_CIPHER_CTX_init(&cc->evp);
#ifdef SSH_OLD_EVP
	if (type->key_len > 0 && type->key_len != keylen) {
		debug("cipher_init: set keylen (%d -> %d)",
		    type->key_len, keylen);
		type->key_len = keylen;
	}
	EVP_CipherInit(&cc->evp, type, (u_char *)key, (u_char *)iv,
	    (do_encrypt == CIPHER_ENCRYPT));
#else
	if (EVP_CipherInit(&cc->evp, type, NULL, (u_char *)iv,
	    (do_encrypt == CIPHER_ENCRYPT)) == 0)
		fatal("cipher_init: EVP_CipherInit failed for %s",
		    cipher->name);
	if (cipher_authlen(cipher) &&
	    !EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_SET_IV_FIXED,
	    -1, (u_char *)iv))
		fatal("cipher_init: EVP_CTRL_GCM_SET_IV_FIXED failed for %s",
		    cipher->name);
	klen = EVP_CIPHER_CTX_key_length(&cc->evp);
	if (klen > 0 && keylen != (u_int)klen) {
		debug2("cipher_init: set keylen (%d -> %d)", klen, keylen);
		if (EVP_CIPHER_CTX_set_key_length(&cc->evp, keylen) == 0)
			fatal("cipher_init: set keylen failed (%d -> %d)",
			    klen, keylen);
	}
	if (EVP_CipherInit(&cc->evp, NULL, (u_char *)key, NULL, -1) == 0)
		fatal("cipher_init: EVP_CipherInit: set key failed for %s",
		    cipher->name);
#endif

	if (cipher->discard_len > 0) {
		junk = xmalloc(cipher->discard_len);
		discard = xmalloc(cipher->discard_len);
		if (EVP_Cipher(&cc->evp, discard, junk,
		    cipher->discard_len) == 0)
			fatal("evp_crypt: EVP_Cipher failed during discard");
		explicit_bzero(discard, cipher->discard_len);
		free(junk);
		free(discard);
	}
}

/*
 * cipher_crypt() operates as following:
 * Copy 'aadlen' bytes (without en/decryption) from 'src' to 'dest'.
 * Theses bytes are treated as additional authenticated data for
 * authenticated encryption modes.
 * En/Decrypt 'len' bytes at offset 'aadlen' from 'src' to 'dest'.
 * Use 'authlen' bytes at offset 'len'+'aadlen' as the authentication tag.
 * This tag is written on encryption and verified on decryption.
 * Both 'aadlen' and 'authlen' can be set to 0.
 * cipher_crypt() returns 0 on success and -1 if the decryption integrity
 * check fails.
 */
int
cipher_crypt(CipherContext *cc, u_int seqnr, u_char *dest, const u_char *src,
    u_int len, u_int aadlen, u_int authlen)
{
	if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0)
		return chachapoly_crypt(&cc->cp_ctx, seqnr, dest, src, len,
		    aadlen, authlen, cc->encrypt);
	if (authlen) {
		u_char lastiv[1];

		if (authlen != cipher_authlen(cc->cipher))
			fatal("%s: authlen mismatch %d", __func__, authlen);
		/* increment IV */
		if (!EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_IV_GEN,
		    1, lastiv))
			fatal("%s: EVP_CTRL_GCM_IV_GEN", __func__);
		/* set tag on decyption */
		if (!cc->encrypt &&
		    !EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_SET_TAG,
		    authlen, (u_char *)src + aadlen + len))
			fatal("%s: EVP_CTRL_GCM_SET_TAG", __func__);
	}
	if (aadlen) {
		if (authlen &&
		    EVP_Cipher(&cc->evp, NULL, (u_char *)src, aadlen) < 0)
			fatal("%s: EVP_Cipher(aad) failed", __func__);
		memcpy(dest, src, aadlen);
	}
	if (len % cc->cipher->block_size)
		fatal("%s: bad plaintext length %d", __func__, len);
	if (EVP_Cipher(&cc->evp, dest + aadlen, (u_char *)src + aadlen,
	    len) < 0)
		fatal("%s: EVP_Cipher failed", __func__);
	if (authlen) {
		/* compute tag (on encrypt) or verify tag (on decrypt) */
		if (EVP_Cipher(&cc->evp, NULL, NULL, 0) < 0) {
			if (cc->encrypt)
				fatal("%s: EVP_Cipher(final) failed", __func__);
			else
				return -1;
		}
		if (cc->encrypt &&
		    !EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_GET_TAG,
		    authlen, dest + aadlen + len))
			fatal("%s: EVP_CTRL_GCM_GET_TAG", __func__);
	}
	return 0;
}

/* Extract the packet length, including any decryption necessary beforehand */
int
cipher_get_length(CipherContext *cc, u_int *plenp, u_int seqnr,
    const u_char *cp, u_int len)
{
	if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0)
		return chachapoly_get_length(&cc->cp_ctx, plenp, seqnr,
		    cp, len);
	if (len < 4)
		return -1;
	*plenp = get_u32(cp);
	return 0;
}

void
cipher_cleanup(CipherContext *cc)
{
	if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0)
		explicit_bzero(&cc->cp_ctx, sizeof(cc->cp_ctx));
	else if (EVP_CIPHER_CTX_cleanup(&cc->evp) == 0)
		error("cipher_cleanup: EVP_CIPHER_CTX_cleanup failed");
}

/*
 * Selects the cipher, and keys if by computing the MD5 checksum of the
 * passphrase and using the resulting 16 bytes as the key.
 */

void
cipher_set_key_string(CipherContext *cc, const Cipher *cipher,
    const char *passphrase, int do_encrypt)
{
	u_char digest[16];

	if (ssh_digest_memory(SSH_DIGEST_MD5, passphrase, strlen(passphrase),
	    digest, sizeof(digest)) < 0)
		fatal("%s: md5 failed", __func__);

	cipher_init(cc, cipher, digest, 16, NULL, 0, do_encrypt);

	explicit_bzero(digest, sizeof(digest));
}
Beispiel #16
0
long _IKED::packet_ike_encrypt( IDB_PH1 * sa, PACKET_IKE & packet, BDATA * iv )
{
	log.txt( LLOG_INFO,
		">= : cookies %08x%08x:%08x%08x\n",
		htonl( *( long * ) &sa->cookies.i[ 0 ] ),
		htonl( *( long * ) &sa->cookies.i[ 4 ] ),
		htonl( *( long * ) &sa->cookies.r[ 0 ] ),
		htonl( *( long * ) &sa->cookies.r[ 4 ] ) );

	log.txt( LLOG_INFO,
		">= : message %08x\n",
		htonl( packet.get_msgid() ) );

	//
	// check if encrypt is required
	//

	unsigned char *	data = packet.buff();
	size_t		    size = packet.size();

	if( !( data[ ISAKMP_FLAGS_OFFSET ] & ISAKMP_FLAG_ENCRYPT ) )
		return LIBIKE_OK;

	log.bin(
		LLOG_DEBUG,
		LLOG_DECODE,
		iv->buff(),
		iv->size(),
		">= : encrypt iv" );

	log.bin(
		LLOG_DEBUG,
		LLOG_DECODE,
		packet.buff(),
		packet.size(),
		"== : encrypt packet" );

	//
	// determine pad length
	//

	size_t plen = size - sizeof( IKE_HEADER );
	size_t blen = EVP_CIPHER_block_size( sa->evp_cipher );
	size_t padd = 0;

	if( plen % blen )
		padd += blen - ( plen % blen );

	packet.add_null( padd );

	data = packet.buff();
	size = packet.size();

	//
	// set new packet length in header
	//

	IKE_HEADER * header = ( IKE_HEADER * ) packet.buff();
	header->length = htonl( ( uint32_t ) size );

	//
	// init cipher key and iv and
	// encrypt all but header
	//

	EVP_CIPHER_CTX ctx_cipher;
	EVP_CIPHER_CTX_init( &ctx_cipher );

	EVP_CipherInit_ex(
		&ctx_cipher,
		sa->evp_cipher,
		NULL,
		NULL,
		NULL,
		1 );

	EVP_CIPHER_CTX_set_key_length(
		&ctx_cipher,
		( int ) sa->key.size() );

	EVP_CipherInit_ex(
		&ctx_cipher,
		NULL,
		NULL,
		sa->key.buff(),
		iv->buff(),
		1 );

	EVP_Cipher(
		&ctx_cipher,
		data + sizeof( IKE_HEADER ),
		data + sizeof( IKE_HEADER ),
		( int ) size - sizeof( IKE_HEADER ) );

	EVP_CIPHER_CTX_cleanup( &ctx_cipher );

	//
	// store cipher iv data
	//

	memcpy(
		iv->buff(),
		data + size - iv->size(),
		iv->size() );

	log.bin(
		LLOG_DEBUG,
		LLOG_DECODE,
		iv->buff(),
		iv->size(),
		"== : stored iv" );

	return LIBIKE_OK;
}
Beispiel #17
0
static EVP_PKEY *do_PVK_body(const unsigned char **in,
                             unsigned int saltlen, unsigned int keylen,
                             pem_password_cb *cb, void *u)
{
    EVP_PKEY *ret = NULL;
    const unsigned char *p = *in;
    unsigned int magic;
    unsigned char *enctmp = NULL, *q;

    EVP_CIPHER_CTX cctx;
    EVP_CIPHER_CTX_init(&cctx);
    if (saltlen) {
        char psbuf[PEM_BUFSIZE];
        unsigned char keybuf[20];
        int enctmplen, inlen;
        if (cb)
            inlen = cb(psbuf, PEM_BUFSIZE, 0, u);
        else
            inlen = PEM_def_callback(psbuf, PEM_BUFSIZE, 0, u);
        if (inlen <= 0) {
            PEMerr(PEM_F_DO_PVK_BODY, PEM_R_BAD_PASSWORD_READ);
            return NULL;
        }
        enctmp = OPENSSL_malloc(keylen + 8);
        if (!enctmp) {
            PEMerr(PEM_F_DO_PVK_BODY, ERR_R_MALLOC_FAILURE);
            return NULL;
        }
        if (!derive_pvk_key(keybuf, p, saltlen,
                            (unsigned char *)psbuf, inlen))
            return NULL;
        p += saltlen;
        /* Copy BLOBHEADER across, decrypt rest */
        memcpy(enctmp, p, 8);
        p += 8;
        if (keylen < 8) {
            PEMerr(PEM_F_DO_PVK_BODY, PEM_R_PVK_TOO_SHORT);
            return NULL;
        }
        inlen = keylen - 8;
        q = enctmp + 8;
        if (!EVP_DecryptInit_ex(&cctx, EVP_rc4(), NULL, keybuf, NULL))
            goto err;
        if (!EVP_DecryptUpdate(&cctx, q, &enctmplen, p, inlen))
            goto err;
        if (!EVP_DecryptFinal_ex(&cctx, q + enctmplen, &enctmplen))
            goto err;
        magic = read_ledword((const unsigned char **)&q);
        if (magic != MS_RSA2MAGIC && magic != MS_DSS2MAGIC) {
            q = enctmp + 8;
            memset(keybuf + 5, 0, 11);
            if (!EVP_DecryptInit_ex(&cctx, EVP_rc4(), NULL, keybuf, NULL))
                goto err;
            OPENSSL_cleanse(keybuf, 20);
            if (!EVP_DecryptUpdate(&cctx, q, &enctmplen, p, inlen))
                goto err;
            if (!EVP_DecryptFinal_ex(&cctx, q + enctmplen, &enctmplen))
                goto err;
            magic = read_ledword((const unsigned char **)&q);
            if (magic != MS_RSA2MAGIC && magic != MS_DSS2MAGIC) {
                PEMerr(PEM_F_DO_PVK_BODY, PEM_R_BAD_DECRYPT);
                goto err;
            }
        } else
            OPENSSL_cleanse(keybuf, 20);
        p = enctmp;
    }

    ret = b2i_PrivateKey(&p, keylen);
 err:
    EVP_CIPHER_CTX_cleanup(&cctx);
    OPENSSL_free(enctmp);
    return ret;
}
Beispiel #18
0
void cipher_context_init(cipher_ctx_t *ctx, int method, int enc)
{
    if (method <= TABLE || method >= CIPHER_NUM) {
        LOGE("cipher_context_init(): Illegal method");
        return;
    }

    if (method >= SALSA20) {
        enc_iv_len = supported_ciphers_iv_size[method];
        return;
    }

    const char *ciphername = supported_ciphers[method];
#if defined(USE_CRYPTO_APPLECC)
    cipher_cc_t *cc = &ctx->cc;
    cc->cryptor = NULL;
    cc->cipher  = supported_ciphers_applecc[method];
    if (cc->cipher == kCCAlgorithmInvalid) {
        cc->valid = kCCContextInvalid;
    } else {
        cc->valid = kCCContextValid;
        if (cc->cipher == kCCAlgorithmRC4) {
            cc->mode    = kCCModeRC4;
            cc->padding = ccNoPadding;
        } else {
            cc->mode    = kCCModeCFB;
            cc->padding = ccPKCS7Padding;
        }
        return;
    }
#endif

    cipher_evp_t *evp         = &ctx->evp;
    const cipher_kt_t *cipher = get_cipher_type(method);
#if defined(USE_CRYPTO_OPENSSL)
    if (cipher == NULL) {
        LOGE("Cipher %s not found in OpenSSL library", ciphername);
        FATAL("Cannot initialize cipher");
    }
    EVP_CIPHER_CTX_init(evp);
    if (!EVP_CipherInit_ex(evp, cipher, NULL, NULL, NULL, enc)) {
        LOGE("Cannot initialize cipher %s", ciphername);
        exit(EXIT_FAILURE);
    }
    if (!EVP_CIPHER_CTX_set_key_length(evp, enc_key_len)) {
        EVP_CIPHER_CTX_cleanup(evp);
        LOGE("Invalid key length: %d", enc_key_len);
        exit(EXIT_FAILURE);
    }
    if (method > RC4_MD5) {
        EVP_CIPHER_CTX_set_padding(evp, 1);
    }
#elif defined(USE_CRYPTO_POLARSSL)
    if (cipher == NULL) {
        LOGE("Cipher %s not found in PolarSSL library", ciphername);
        FATAL("Cannot initialize PolarSSL cipher");
    }
    if (cipher_init_ctx(evp, cipher) != 0) {
        FATAL("Cannot initialize PolarSSL cipher context");
    }
#elif defined(USE_CRYPTO_MBEDTLS)
    // XXX: mbedtls_cipher_setup future change
    // NOTE:  Currently also clears structure. In future versions you will be required to call
    //        mbedtls_cipher_init() on the structure first.
    //        void mbedtls_cipher_init( mbedtls_cipher_context_t *ctx );
    if (cipher == NULL) {
        LOGE("Cipher %s not found in mbed TLS library", ciphername);
        FATAL("Cannot initialize mbed TLS cipher");
    }
    mbedtls_cipher_init(evp);
    if (mbedtls_cipher_setup(evp, cipher) != 0) {
        FATAL("Cannot initialize mbed TLS cipher context");
    }
#endif
}
Beispiel #19
0
OM_uint32
_gssapi_get_mic_arcfour(OM_uint32 * minor_status,
			const gsskrb5_ctx context_handle,
			krb5_context context,
			gss_qop_t qop_req,
			const gss_buffer_t message_buffer,
			gss_buffer_t message_token,
			krb5_keyblock *key)
{
    krb5_error_code ret;
    int32_t seq_number;
    size_t len, total_len;
    u_char k6_data[16], *p0, *p;
    EVP_CIPHER_CTX rc4_key;

    _gsskrb5_encap_length (22, &len, &total_len, GSS_KRB5_MECHANISM);

    message_token->length = total_len;
    message_token->value  = malloc (total_len);
    if (message_token->value == NULL) {
	*minor_status = ENOMEM;
	return GSS_S_FAILURE;
    }

    p0 = _gssapi_make_mech_header(message_token->value,
				  len,
				  GSS_KRB5_MECHANISM);
    p = p0;

    *p++ = 0x01; /* TOK_ID */
    *p++ = 0x01;
    *p++ = 0x11; /* SGN_ALG */
    *p++ = 0x00;
    *p++ = 0xff; /* Filler */
    *p++ = 0xff;
    *p++ = 0xff;
    *p++ = 0xff;

    p = NULL;

    ret = arcfour_mic_cksum(context,
			    key, KRB5_KU_USAGE_SIGN,
			    p0 + 16, 8,  /* SGN_CKSUM */
			    p0, 8, /* TOK_ID, SGN_ALG, Filer */
			    message_buffer->value, message_buffer->length,
			    NULL, 0);
    if (ret) {
	_gsskrb5_release_buffer(minor_status, message_token);
	*minor_status = ret;
	return GSS_S_FAILURE;
    }

    ret = arcfour_mic_key(context, key,
			  p0 + 16, 8, /* SGN_CKSUM */
			  k6_data, sizeof(k6_data));
    if (ret) {
	_gsskrb5_release_buffer(minor_status, message_token);
	*minor_status = ret;
	return GSS_S_FAILURE;
    }

    HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
    krb5_auth_con_getlocalseqnumber (context,
				     context_handle->auth_context,
				     &seq_number);
    p = p0 + 8; /* SND_SEQ */
    _gsskrb5_encode_be_om_uint32(seq_number, p);

    krb5_auth_con_setlocalseqnumber (context,
				     context_handle->auth_context,
				     ++seq_number);
    HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);

    memset (p + 4, (context_handle->more_flags & LOCAL) ? 0 : 0xff, 4);

    EVP_CIPHER_CTX_init(&rc4_key);
    EVP_CipherInit_ex(&rc4_key, EVP_rc4(), NULL, k6_data, NULL, 1);
    EVP_Cipher(&rc4_key, p, p, 8);
    EVP_CIPHER_CTX_cleanup(&rc4_key);

    memset(k6_data, 0, sizeof(k6_data));

    *minor_status = 0;
    return GSS_S_COMPLETE;
}
Beispiel #20
0
void cipher_context_set_iv(cipher_ctx_t *ctx, uint8_t *iv, size_t iv_len,
                           int enc)
{
    const unsigned char *true_key;

    if (iv == NULL) {
        LOGE("cipher_context_set_iv(): IV is null");
        return;
    }

    if (!enc) {
        memcpy(ctx->iv, iv, iv_len);
    }

    if (enc_method >= SALSA20) {
        return;
    }

    if (enc_method == RC4_MD5) {
        unsigned char key_iv[32];
        memcpy(key_iv, enc_key, 16);
        memcpy(key_iv + 16, iv, 16);
        true_key = enc_md5(key_iv, 32, NULL);
        iv_len   = 0;
    } else {
        true_key = enc_key;
    }

#ifdef USE_CRYPTO_APPLECC
    cipher_cc_t *cc = &ctx->cc;
    if (cc->valid == kCCContextValid) {
        memcpy(cc->iv, iv, iv_len);
        memcpy(cc->key, true_key, enc_key_len);
        cc->iv_len  = iv_len;
        cc->key_len = enc_key_len;
        cc->encrypt = enc ? kCCEncrypt : kCCDecrypt;
        if (cc->cryptor != NULL) {
            CCCryptorRelease(cc->cryptor);
            cc->cryptor = NULL;
        }

        CCCryptorStatus ret;
        ret = CCCryptorCreateWithMode(
            cc->encrypt,
            cc->mode,
            cc->cipher,
            cc->padding,
            cc->iv, cc->key, cc->key_len,
            NULL, 0, 0, 0,
            &cc->cryptor);
        if (ret != kCCSuccess) {
            if (cc->cryptor != NULL) {
                CCCryptorRelease(cc->cryptor);
                cc->cryptor = NULL;
            }
            FATAL("Cannot set CommonCrypto key and IV");
        }
        return;
    }
#endif

    cipher_evp_t *evp = &ctx->evp;
    if (evp == NULL) {
        LOGE("cipher_context_set_iv(): Cipher context is null");
        return;
    }
#if defined(USE_CRYPTO_OPENSSL)
    if (!EVP_CipherInit_ex(evp, NULL, NULL, true_key, iv, enc)) {
        EVP_CIPHER_CTX_cleanup(evp);
        FATAL("Cannot set key and IV");
    }
#elif defined(USE_CRYPTO_POLARSSL)
    // XXX: PolarSSL 1.3.11: cipher_free_ctx deprecated, Use cipher_free() instead.
    if (cipher_setkey(evp, true_key, enc_key_len * 8, enc) != 0) {
        cipher_free_ctx(evp);
        FATAL("Cannot set PolarSSL cipher key");
    }
#if POLARSSL_VERSION_NUMBER >= 0x01030000
    if (cipher_set_iv(evp, iv, iv_len) != 0) {
        cipher_free_ctx(evp);
        FATAL("Cannot set PolarSSL cipher IV");
    }
    if (cipher_reset(evp) != 0) {
        cipher_free_ctx(evp);
        FATAL("Cannot finalize PolarSSL cipher context");
    }
#else
    if (cipher_reset(evp, iv) != 0) {
        cipher_free_ctx(evp);
        FATAL("Cannot set PolarSSL cipher IV");
    }
#endif
#elif defined(USE_CRYPTO_MBEDTLS)
    if (mbedtls_cipher_setkey(evp, true_key, enc_key_len * 8, enc) != 0) {
        mbedtls_cipher_free(evp);
        FATAL("Cannot set mbed TLS cipher key");
    }

    if (mbedtls_cipher_set_iv(evp, iv, iv_len) != 0) {
        mbedtls_cipher_free(evp);
        FATAL("Cannot set mbed TLS cipher IV");
    }
    if (mbedtls_cipher_reset(evp) != 0) {
        mbedtls_cipher_free(evp);
        FATAL("Cannot finalize mbed TLS cipher context");
    }
#endif

#ifdef DEBUG
    dump("IV", (char *)iv, iv_len);
#endif
}
Beispiel #21
0
OM_uint32
_gssapi_wrap_arcfour(OM_uint32 * minor_status,
		     const gsskrb5_ctx context_handle,
		     krb5_context context,
		     int conf_req_flag,
		     gss_qop_t qop_req,
		     const gss_buffer_t input_message_buffer,
		     int * conf_state,
		     gss_buffer_t output_message_buffer,
		     krb5_keyblock *key)
{
    u_char Klocaldata[16], k6_data[16], *p, *p0;
    size_t len, total_len, datalen;
    krb5_keyblock Klocal;
    krb5_error_code ret;
    int32_t seq_number;

    if (conf_state)
	*conf_state = 0;

    datalen = input_message_buffer->length;

    if (IS_DCE_STYLE(context_handle)) {
	len = GSS_ARCFOUR_WRAP_TOKEN_SIZE;
	_gssapi_encap_length(len, &len, &total_len, GSS_KRB5_MECHANISM);
	total_len += datalen;
    } else {
	datalen += 1; /* padding */
	len = datalen + GSS_ARCFOUR_WRAP_TOKEN_SIZE;
	_gssapi_encap_length(len, &len, &total_len, GSS_KRB5_MECHANISM);
    }

    output_message_buffer->length = total_len;
    output_message_buffer->value  = malloc (total_len);
    if (output_message_buffer->value == NULL) {
	*minor_status = ENOMEM;
	return GSS_S_FAILURE;
    }

    p0 = _gssapi_make_mech_header(output_message_buffer->value,
				  len,
				  GSS_KRB5_MECHANISM);
    p = p0;

    *p++ = 0x02; /* TOK_ID */
    *p++ = 0x01;
    *p++ = 0x11; /* SGN_ALG */
    *p++ = 0x00;
    if (conf_req_flag) {
	*p++ = 0x10; /* SEAL_ALG */
	*p++ = 0x00;
    } else {
	*p++ = 0xff; /* SEAL_ALG */
	*p++ = 0xff;
    }
    *p++ = 0xff; /* Filler */
    *p++ = 0xff;

    p = NULL;

    HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
    krb5_auth_con_getlocalseqnumber (context,
				     context_handle->auth_context,
				     &seq_number);

    _gsskrb5_encode_be_om_uint32(seq_number, p0 + 8);

    krb5_auth_con_setlocalseqnumber (context,
				     context_handle->auth_context,
				     ++seq_number);
    HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);

    memset (p0 + 8 + 4,
	    (context_handle->more_flags & LOCAL) ? 0 : 0xff,
	    4);

    krb5_generate_random_block(p0 + 24, 8); /* fill in Confounder */

    /* p points to data */
    p = p0 + GSS_ARCFOUR_WRAP_TOKEN_SIZE;
    memcpy(p, input_message_buffer->value, input_message_buffer->length);

    if (!IS_DCE_STYLE(context_handle))
	p[input_message_buffer->length] = 1; /* padding */

    ret = arcfour_mic_cksum(context,
			    key, KRB5_KU_USAGE_SEAL,
			    p0 + 16, 8, /* SGN_CKSUM */
			    p0, 8, /* TOK_ID, SGN_ALG, SEAL_ALG, Filler */
			    p0 + 24, 8, /* Confounder */
			    p0 + GSS_ARCFOUR_WRAP_TOKEN_SIZE,
			    datalen);
    if (ret) {
	*minor_status = ret;
	_gsskrb5_release_buffer(minor_status, output_message_buffer);
	return GSS_S_FAILURE;
    }

    {
	int i;

	Klocal.keytype = key->keytype;
	Klocal.keyvalue.data = Klocaldata;
	Klocal.keyvalue.length = sizeof(Klocaldata);

	for (i = 0; i < 16; i++)
	    Klocaldata[i] = ((u_char *)key->keyvalue.data)[i] ^ 0xF0;
    }
    ret = arcfour_mic_key(context, &Klocal,
			  p0 + 8, 4, /* SND_SEQ */
			  k6_data, sizeof(k6_data));
    memset(Klocaldata, 0, sizeof(Klocaldata));
    if (ret) {
	_gsskrb5_release_buffer(minor_status, output_message_buffer);
	*minor_status = ret;
	return GSS_S_FAILURE;
    }


    if(conf_req_flag) {
	EVP_CIPHER_CTX rc4_key;

	EVP_CIPHER_CTX_init(&rc4_key);
	EVP_CipherInit_ex(&rc4_key, EVP_rc4(), NULL, k6_data, NULL, 1);
	EVP_Cipher(&rc4_key, p0 + 24, p0 + 24, 8 + datalen);
	EVP_CIPHER_CTX_cleanup(&rc4_key);
    }
    memset(k6_data, 0, sizeof(k6_data));

    ret = arcfour_mic_key(context, key,
			  p0 + 16, 8, /* SGN_CKSUM */
			  k6_data, sizeof(k6_data));
    if (ret) {
	_gsskrb5_release_buffer(minor_status, output_message_buffer);
	*minor_status = ret;
	return GSS_S_FAILURE;
    }

    {
	EVP_CIPHER_CTX rc4_key;

	EVP_CIPHER_CTX_init(&rc4_key);
	EVP_CipherInit_ex(&rc4_key, EVP_rc4(), NULL, k6_data, NULL, 1);
	EVP_Cipher(&rc4_key, p0 + 8, p0 + 8 /* SND_SEQ */, 8);
	EVP_CIPHER_CTX_cleanup(&rc4_key);
	memset(k6_data, 0, sizeof(k6_data));
    }

    if (conf_state)
	*conf_state = conf_req_flag;

    *minor_status = 0;
    return GSS_S_COMPLETE;
}
Beispiel #22
0
static void
gst_hls_demux_decrypt_end (GstHLSDemux * demux)
{
  EVP_CIPHER_CTX_cleanup (&demux->aes_ctx);
}
Beispiel #23
0
unsigned char *rncryptorc_decrypt_data_with_key(const unsigned char *indata,
        int indata_len,
        int kdf_iter,
        const unsigned char *encr_key,
        const unsigned char *hmac_key,
        int *outdata_len,
        char *errbuf,
        int errbuf_len)
{
    MutilsBlob
        *blob = NULL;

    RNCryptorInfo
        *ci = NULL;

    int
        outlen1=0,
        outlen2=0;

    EVP_CIPHER_CTX
        cipher_ctx;

    unsigned char
        *outdata = NULL;

    if (errbuf_len <= 0)
    {
        log_err("ERROR:Invalid errbuf len %d",errbuf_len);
        goto ExitProcessing;
    }

    memset(errbuf,0,errbuf_len);

    if (indata == NULL)
    {
        (void)snprintf(errbuf,errbuf_len-1,"%s",
                "input data is NULL");
        goto ExitProcessing;
    }
    if (encr_key == NULL)
    {
        (void)snprintf(errbuf,errbuf_len-1,"%s",
                "Encryption key is NULL");
        goto ExitProcessing;
    }
    if (hmac_key == NULL)
    {
        (void)snprintf(errbuf,errbuf_len-1,"%s",
                "HMAC key is NULL");
        goto ExitProcessing;
    }

    *outdata_len = 0;

    /* convert input data to our blob */
    blob = mutils_data_to_blob((unsigned char *)indata,indata_len);
    CHECK_MALLOC(blob);

    /* decode */
    ci = decode_encrypted_blob(blob);
    if (!ci)
    {
        goto ExitProcessing;
    }
    log_debug("Decoded successfully");

    /*
    ** copy the keys to our data structure, this way we don't have
    ** to change code for decryptiion
    */
    memcpy(ci->encr_key,encr_key,32);
    memcpy(ci->hmac_key,hmac_key,32);
    /*
    ** pass password as NULL and length of password as 0 because we don't
    ** have to derive HMAC key
    */
    if (verify_hmac(ci,NULL,0) != SUCCESS)
    {
        (void)snprintf(errbuf,errbuf_len-1,"%s",
                "Could not verify HMAC");
        goto ExitProcessing;
    }
    log_debug("HMAC verified");


    /* malloc for returned data */
    outdata = (unsigned char *)malloc(ci->cipher_text_length *sizeof(unsigned char));
    CHECK_MALLOC(outdata);

    /* decrypt */
    EVP_DecryptInit(&cipher_ctx,EVP_aes_256_cbc(),ci->encr_key,ci->iv);
    EVP_DecryptUpdate(&cipher_ctx,outdata,&outlen1,ci->cipher_text,
            ci->cipher_text_length);
    EVP_DecryptFinal(&cipher_ctx,outdata + outlen1,&outlen2);
    EVP_CIPHER_CTX_cleanup(&cipher_ctx);

    *outdata_len = outlen1 + outlen2;

ExitProcessing:
    if (ci)
    {
        free_rncryptor_info(ci);
    }
    if (blob)
    {
        mutils_destroy_blob(blob);
    }

    return(outdata);
}
Beispiel #24
0
void crypto_des3_free(CryptoDes3 des3)
{
	EVP_CIPHER_CTX_cleanup(&des3->des3_ctx);
	xfree(des3);
}
Beispiel #25
0
unsigned char *rncryptorc_encrypt_data_with_key_iv(const unsigned char *indata,
        int indata_len,
        int kdf_iter,
        const unsigned char *encr_key_32,
        const unsigned char *hmac_key_32,
        const unsigned char *iv_16,
        int *outdata_len,
        char *errbuf,
        int errbuf_len)
{
    RNCryptorInfo
        *ci = NULL;

    MutilsBlob
        *blob = NULL;

    EVP_CIPHER_CTX
        cipher_ctx;

    HMAC_CTX
        hmac_ctx;

    const EVP_MD
        *sha256 = NULL;

    int
        outlen1 = 0,
        outlen2 = 0;

    unsigned int
        hmac_len;

    unsigned char
        hmac_sha256[32];

    unsigned char
        *output = NULL;

    unsigned int
        blocksize = 16;

    unsigned char
        *ciphertext = NULL;

    int
        ciphertext_length;



    log_debug("%s:%d - verifying input",MCFL);
    if (errbuf_len <= 0)
    {
        log_err("ERROR:Invalid errbuf len %d",errbuf_len);
        goto ExitProcessing;
    }

    memset(errbuf,0,errbuf_len);
    EVP_EncryptInit(&cipher_ctx,EVP_aes_256_cbc(),encr_key_32,iv_16);
    blocksize = EVP_CIPHER_CTX_block_size(&cipher_ctx);
    log_debug("%s:%d - Block size: %ld",MCFL,blocksize);

    if (indata == NULL && indata_len == 0)
    {
        /* memory will be re-allocated as needed */
        blob = mutils_allocate_blob(blocksize);
    }
    else
    {
        /* memory will be re-allocated as needed */
        blob = mutils_allocate_blob(indata_len);
    }
    CHECK_MALLOC(blob);
    log_debug("%s:%d - input data size %d bytes",
            MCFL,
            indata_len);

    ci = allocate_rncryptor_info();
    if (!ci)
    {
        goto ExitProcessing;
    }

    /* version */
    mutils_write_blob_byte(blob,ci->version);

    /* options */
    ci->options = 0x00;
    mutils_write_blob_byte(blob,ci->options);

    /* 16 byte iv */
    mutils_write_blob(blob,16,iv_16);

    log_debug(":%s:%d - Encrypting,",MCFL);

    /* allocate space for cipher text */
    ciphertext_length =
          indata_len + blocksize - (indata_len % blocksize);
    ciphertext =
        (unsigned char *) malloc(ciphertext_length * sizeof(unsigned char));
    CHECK_MALLOC(ciphertext);
    log_debug("%s:%d - Plain text length: %d",MCFL,indata_len);
    log_debug("%s:%d - Cipther text length: %d",MCFL,ciphertext_length);
    log_debug("%s:%d - Padding %d bytes",
            MCFL,(ciphertext_length - indata_len));

    EVP_EncryptUpdate(&cipher_ctx,ciphertext,&outlen1,indata,indata_len);
    EVP_EncryptFinal(&cipher_ctx,ciphertext + outlen1,&outlen2);
    EVP_CIPHER_CTX_cleanup(&cipher_ctx);

    mutils_write_blob(blob,outlen1 + outlen2,ciphertext);

    /* calculate HMAC-SHA256 */
    sha256 = EVP_sha256();
    HMAC_CTX_init(&hmac_ctx);
    HMAC_Init(&hmac_ctx,hmac_key_32,32,sha256);
    HMAC_Update(&hmac_ctx,blob->data,blob->length);
    HMAC_Final(&hmac_ctx,hmac_sha256,&hmac_len);
    HMAC_CTX_cleanup(&hmac_ctx);

    mutils_write_blob(blob,hmac_len,hmac_sha256);
    output = (unsigned char *)malloc(blob->length * sizeof(unsigned char));
    CHECK_MALLOC(output);

    memcpy(output,blob->data,blob->length);
    *outdata_len = blob->length;
ExitProcessing:
    if (ci)
    {
        free_rncryptor_info(ci);
    }

    if (blob)
    {
        mutils_destroy_blob(blob);
    }
    if (ciphertext)
    {
        (void) free((char *)ciphertext);
    }
    return(output);
}
Beispiel #26
0
void psAesClearCBC(psAesCbc_t *ctx)
{
    EVP_CIPHER_CTX_cleanup(ctx);
}
Beispiel #27
0
static int s2n_cbc_cipher_3des_destroy_key(struct s2n_session_key *key)
{
    EVP_CIPHER_CTX_cleanup(key->evp_cipher_ctx);

    return 0;
}
Beispiel #28
0
X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter,
				 unsigned char *salt, int saltlen,
				 unsigned char *aiv, int prf_nid)
{
	X509_ALGOR *scheme = NULL, *kalg = NULL, *ret = NULL;
	int alg_nid, keylen;
	EVP_CIPHER_CTX ctx;
	unsigned char iv[EVP_MAX_IV_LENGTH];
	PBE2PARAM *pbe2 = NULL;
	const ASN1_OBJECT *obj;

	alg_nid = EVP_CIPHER_nid(cipher);
	if(alg_nid == NID_undef) {
		OPENSSL_PUT_ERROR(PKCS8, PKCS5_pbe2_set_iv, PKCS8_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER);
		goto err;
	}
	obj = OBJ_nid2obj(alg_nid);

	if(!(pbe2 = PBE2PARAM_new())) goto merr;

	/* Setup the AlgorithmIdentifier for the encryption scheme */
	scheme = pbe2->encryption;

	scheme->algorithm = (ASN1_OBJECT*) obj;
	if(!(scheme->parameter = ASN1_TYPE_new())) goto merr;

	/* Create random IV */
	if (EVP_CIPHER_iv_length(cipher))
		{
		if (aiv)
			memcpy(iv, aiv, EVP_CIPHER_iv_length(cipher));
		else if (RAND_pseudo_bytes(iv, EVP_CIPHER_iv_length(cipher)) < 0)
  			goto err;
		}

	EVP_CIPHER_CTX_init(&ctx);

	/* Dummy cipherinit to just setup the IV, and PRF */
	if (!EVP_CipherInit_ex(&ctx, cipher, NULL, NULL, iv, 0))
		goto err;
	if(param_to_asn1(&ctx, scheme->parameter) < 0) {
		OPENSSL_PUT_ERROR(PKCS8, PKCS5_pbe2_set_iv, PKCS8_R_ERROR_SETTING_CIPHER_PARAMS);
		EVP_CIPHER_CTX_cleanup(&ctx);
		goto err;
	}
	/* If prf NID unspecified see if cipher has a preference.
	 * An error is OK here: just means use default PRF.
	 */
	if ((prf_nid == -1) && 
	EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_PBE_PRF_NID, 0, &prf_nid) <= 0)
		{
		ERR_clear_error();
		prf_nid = NID_hmacWithSHA1;
		}
	EVP_CIPHER_CTX_cleanup(&ctx);

	/* If its RC2 then we'd better setup the key length */

	if(alg_nid == NID_rc2_cbc)
		keylen = EVP_CIPHER_key_length(cipher);
	else
		keylen = -1;

	/* Setup keyfunc */

	X509_ALGOR_free(pbe2->keyfunc);

	pbe2->keyfunc = PKCS5_pbkdf2_set(iter, salt, saltlen, prf_nid, keylen);

	if (!pbe2->keyfunc)
		goto merr;

	/* Now set up top level AlgorithmIdentifier */

	if(!(ret = X509_ALGOR_new())) goto merr;
	if(!(ret->parameter = ASN1_TYPE_new())) goto merr;

	ret->algorithm = (ASN1_OBJECT*) OBJ_nid2obj(NID_pbes2);

	/* Encode PBE2PARAM into parameter */

	if(!ASN1_item_pack(pbe2, ASN1_ITEM_rptr(PBE2PARAM),
				 &ret->parameter->value.sequence)) goto merr;
	ret->parameter->type = V_ASN1_SEQUENCE;

	PBE2PARAM_free(pbe2);
	pbe2 = NULL;

	return ret;

	merr:
	OPENSSL_PUT_ERROR(PKCS8, PKCS5_pbe2_set_iv, ERR_R_MALLOC_FAILURE);

	err:
	PBE2PARAM_free(pbe2);
	/* Note 'scheme' is freed as part of pbe2 */
	X509_ALGOR_free(kalg);
	X509_ALGOR_free(ret);

	return NULL;

}
static void 
aes_cbc_encrypt_cleanup(aes_cbc_encrypt_context_t* state)
{
	EVP_CIPHER_CTX_cleanup(&state->cipher);
}
Beispiel #30
0
Blob decryptECIES (const openssl::ec_key& secretKey, const openssl::ec_key& publicKey, Blob const& ciphertext)
{
    // minimum ciphertext = IV + HMAC + 1 block
    if (ciphertext.size () < ((2 * ECIES_ENC_BLK_SIZE) + ECIES_HMAC_SIZE) )
        throw std::runtime_error ("ciphertext too short");

    // extract IV
    ECIES_ENC_IV_TYPE iv;
    memcpy (iv.begin (), & (ciphertext.front ()), ECIES_ENC_BLK_SIZE);

    // begin decrypting
    EVP_CIPHER_CTX ctx;
    EVP_CIPHER_CTX_init (&ctx);

    ECIES_ENC_KEY_TYPE secret;
    ECIES_HMAC_KEY_TYPE hmacKey;
    getECIESSecret (secretKey, publicKey, secret, hmacKey);

    if (EVP_DecryptInit_ex (&ctx, ECIES_ENC_ALGO, nullptr, secret.begin (), iv.begin ()) != 1)
    {
        secret.zero ();
        hmacKey.zero ();
        EVP_CIPHER_CTX_cleanup (&ctx);
        throw std::runtime_error ("unable to init cipher");
    }

    // decrypt mac
    ECIES_HMAC_TYPE hmac;
    int outlen = ECIES_HMAC_SIZE;

    if ( (EVP_DecryptUpdate (&ctx, hmac.begin (), &outlen,
                             & (ciphertext.front ()) + ECIES_ENC_BLK_SIZE, ECIES_HMAC_SIZE + 1) != 1) || (outlen != ECIES_HMAC_SIZE) )
    {
        secret.zero ();
        hmacKey.zero ();
        EVP_CIPHER_CTX_cleanup (&ctx);
        throw std::runtime_error ("unable to extract hmac");
    }

    // decrypt plaintext (after IV and encrypted mac)
    Blob plaintext (ciphertext.size () - ECIES_HMAC_SIZE - ECIES_ENC_BLK_SIZE);
    outlen = plaintext.size ();

    if (EVP_DecryptUpdate (&ctx, & (plaintext.front ()), &outlen,
                           & (ciphertext.front ()) + ECIES_ENC_BLK_SIZE + ECIES_HMAC_SIZE + 1,
                           ciphertext.size () - ECIES_ENC_BLK_SIZE - ECIES_HMAC_SIZE - 1) != 1)
    {
        secret.zero ();
        hmacKey.zero ();
        EVP_CIPHER_CTX_cleanup (&ctx);
        throw std::runtime_error ("unable to extract plaintext");
    }

    // decrypt padding
    int flen = 0;

    if (EVP_DecryptFinal (&ctx, & (plaintext.front ()) + outlen, &flen) != 1)
    {
        secret.zero ();
        hmacKey.zero ();
        EVP_CIPHER_CTX_cleanup (&ctx);
        throw std::runtime_error ("plaintext had bad padding");
    }

    plaintext.resize (flen + outlen);

    // verify integrity
    if (hmac != makeHMAC (hmacKey, plaintext))
    {
        secret.zero ();
        hmacKey.zero ();
        EVP_CIPHER_CTX_cleanup (&ctx);
        throw std::runtime_error ("plaintext had bad hmac");
    }

    secret.zero ();
    hmacKey.zero ();

    EVP_CIPHER_CTX_cleanup (&ctx);
    return plaintext;
}