Esempio n. 1
0
PKCS8_PRIV_KEY_INFO *
EVP_PKEY2PKCS8_broken(EVP_PKEY *pkey, int broken)
{
	PKCS8_PRIV_KEY_INFO *p8;

	if (!(p8 = PKCS8_PRIV_KEY_INFO_new())) {
		EVPerror(ERR_R_MALLOC_FAILURE);
		return NULL;
	}
	p8->broken = broken;

	if (pkey->ameth) {
		if (pkey->ameth->priv_encode) {
			if (!pkey->ameth->priv_encode(p8, pkey)) {
				EVPerror(EVP_R_PRIVATE_KEY_ENCODE_ERROR);
				goto error;
			}
		} else {
			EVPerror(EVP_R_METHOD_NOT_SUPPORTED);
			goto error;
		}
	} else {
		EVPerror(EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM);
		goto error;
	}
	return p8;

error:
	PKCS8_PRIV_KEY_INFO_free(p8);
	return NULL;
}
Esempio n. 2
0
static int
aead_aes_gcm_open(const EVP_AEAD_CTX *ctx, unsigned char *out, size_t *out_len,
    size_t max_out_len, const unsigned char *nonce, size_t nonce_len,
    const unsigned char *in, size_t in_len, const unsigned char *ad,
    size_t ad_len)
{
	const struct aead_aes_gcm_ctx *gcm_ctx = ctx->aead_state;
	unsigned char tag[EVP_AEAD_AES_GCM_TAG_LEN];
	GCM128_CONTEXT gcm;
	size_t plaintext_len;
	size_t bulk = 0;

	if (in_len < gcm_ctx->tag_len) {
		EVPerror(EVP_R_BAD_DECRYPT);
		return 0;
	}

	plaintext_len = in_len - gcm_ctx->tag_len;

	if (max_out_len < plaintext_len) {
		EVPerror(EVP_R_BUFFER_TOO_SMALL);
		return 0;
	}

	memcpy(&gcm, &gcm_ctx->gcm, sizeof(gcm));
	CRYPTO_gcm128_setiv(&gcm, nonce, nonce_len);

	if (CRYPTO_gcm128_aad(&gcm, ad, ad_len))
		return 0;

	if (gcm_ctx->ctr) {
		if (CRYPTO_gcm128_decrypt_ctr32(&gcm, in + bulk, out + bulk,
		    in_len - bulk - gcm_ctx->tag_len, gcm_ctx->ctr))
			return 0;
	} else {
		if (CRYPTO_gcm128_decrypt(&gcm, in + bulk, out + bulk,
		    in_len - bulk - gcm_ctx->tag_len))
			return 0;
	}

	CRYPTO_gcm128_tag(&gcm, tag, gcm_ctx->tag_len);
	if (timingsafe_memcmp(tag, in + plaintext_len, gcm_ctx->tag_len) != 0) {
		EVPerror(EVP_R_BAD_DECRYPT);
		return 0;
	}

	*out_len = plaintext_len;

	return 1;
}
Esempio n. 3
0
static int
aesni_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
    const unsigned char *iv, int enc)
{
	int ret, mode;
	EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data;

	mode = ctx->cipher->flags & EVP_CIPH_MODE;
	if ((mode == EVP_CIPH_ECB_MODE || mode == EVP_CIPH_CBC_MODE) &&
	    !enc) {
		ret = aesni_set_decrypt_key(key, ctx->key_len * 8,
		    ctx->cipher_data);
		dat->block = (block128_f)aesni_decrypt;
		dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ?
		    (cbc128_f)aesni_cbc_encrypt : NULL;
	} else {
		ret = aesni_set_encrypt_key(key, ctx->key_len * 8,
		    ctx->cipher_data);
		dat->block = (block128_f)aesni_encrypt;
		if (mode == EVP_CIPH_CBC_MODE)
			dat->stream.cbc = (cbc128_f)aesni_cbc_encrypt;
		else if (mode == EVP_CIPH_CTR_MODE)
			dat->stream.ctr = (ctr128_f)aesni_ctr32_encrypt_blocks;
		else
			dat->stream.cbc = NULL;
	}

	if (ret < 0) {
		EVPerror(EVP_R_AES_KEY_SETUP_FAILED);
		return 0;
	}

	return 1;
}
Esempio n. 4
0
static int
aead_aes_gcm_init(EVP_AEAD_CTX *ctx, const unsigned char *key, size_t key_len,
    size_t tag_len)
{
	struct aead_aes_gcm_ctx *gcm_ctx;
	const size_t key_bits = key_len * 8;

	/* EVP_AEAD_CTX_init should catch this. */
	if (key_bits != 128 && key_bits != 256) {
		EVPerror(EVP_R_BAD_KEY_LENGTH);
		return 0;
	}

	if (tag_len == EVP_AEAD_DEFAULT_TAG_LENGTH)
		tag_len = EVP_AEAD_AES_GCM_TAG_LEN;

	if (tag_len > EVP_AEAD_AES_GCM_TAG_LEN) {
		EVPerror(EVP_R_TAG_TOO_LARGE);
		return 0;
	}

	gcm_ctx = malloc(sizeof(struct aead_aes_gcm_ctx));
	if (gcm_ctx == NULL)
		return 0;

#ifdef AESNI_CAPABLE
	if (AESNI_CAPABLE) {
		aesni_set_encrypt_key(key, key_bits, &gcm_ctx->ks.ks);
		CRYPTO_gcm128_init(&gcm_ctx->gcm, &gcm_ctx->ks.ks,
		    (block128_f)aesni_encrypt);
		gcm_ctx->ctr = (ctr128_f) aesni_ctr32_encrypt_blocks;
	} else
#endif
	{
		gcm_ctx->ctr = aes_gcm_set_key(&gcm_ctx->ks.ks, &gcm_ctx->gcm,
		    key, key_len);
	}
	gcm_ctx->tag_len = tag_len;
	ctx->aead_state = gcm_ctx;

	return 1;
}
Esempio n. 5
0
EVP_PKEY *
EVP_PKCS82PKEY(PKCS8_PRIV_KEY_INFO *p8)
{
	EVP_PKEY *pkey = NULL;
	ASN1_OBJECT *algoid;
	char obj_tmp[80];

	if (!PKCS8_pkey_get0(&algoid, NULL, NULL, NULL, p8))
		return NULL;

	if (!(pkey = EVP_PKEY_new())) {
		EVPerror(ERR_R_MALLOC_FAILURE);
		return NULL;
	}

	if (!EVP_PKEY_set_type(pkey, OBJ_obj2nid(algoid))) {
		EVPerror(EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM);
		i2t_ASN1_OBJECT(obj_tmp, 80, algoid);
		ERR_asprintf_error_data("TYPE=%s", obj_tmp);
		goto error;
	}

	if (pkey->ameth->priv_decode) {
		if (!pkey->ameth->priv_decode(pkey, p8)) {
			EVPerror(EVP_R_PRIVATE_KEY_DECODE_ERROR);
			goto error;
		}
	} else {
		EVPerror(EVP_R_METHOD_NOT_SUPPORTED);
		goto error;
	}

	return pkey;

error:
	EVP_PKEY_free(pkey);
	return NULL;
}
Esempio n. 6
0
static int
do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, const EVP_MD *type,
    ENGINE *e, EVP_PKEY *pkey, int ver)
{
	if (ctx->pctx == NULL)
		ctx->pctx = EVP_PKEY_CTX_new(pkey, e);
	if (ctx->pctx == NULL)
		return 0;

	if (type == NULL) {
		int def_nid;
		if (EVP_PKEY_get_default_digest_nid(pkey, &def_nid) > 0)
			type = EVP_get_digestbynid(def_nid);
	}

	if (type == NULL) {
		EVPerror(EVP_R_NO_DEFAULT_DIGEST);
		return 0;
	}

	if (ver) {
		if (ctx->pctx->pmeth->verifyctx_init) {
			if (ctx->pctx->pmeth->verifyctx_init(ctx->pctx,
			    ctx) <=0)
				return 0;
			ctx->pctx->operation = EVP_PKEY_OP_VERIFYCTX;
		} else if (EVP_PKEY_verify_init(ctx->pctx) <= 0)
			return 0;
	} else {
		if (ctx->pctx->pmeth->signctx_init) {
			if (ctx->pctx->pmeth->signctx_init(ctx->pctx, ctx) <= 0)
				return 0;
			ctx->pctx->operation = EVP_PKEY_OP_SIGNCTX;
		} else if (EVP_PKEY_sign_init(ctx->pctx) <= 0)
			return 0;
	}
	if (EVP_PKEY_CTX_set_signature_md(ctx->pctx, type) <= 0)
		return 0;
	if (pctx)
		*pctx = ctx->pctx;
	if (!EVP_DigestInit_ex(ctx, type, e))
		return 0;
	return 1;
}
Esempio n. 7
0
PKCS8_PRIV_KEY_INFO *
PKCS8_set_broken(PKCS8_PRIV_KEY_INFO *p8, int broken)
{
	switch (broken) {
	case PKCS8_OK:
		p8->broken = PKCS8_OK;
		return p8;
		break;

	case PKCS8_NO_OCTET:
		p8->broken = PKCS8_NO_OCTET;
		p8->pkey->type = V_ASN1_SEQUENCE;
		return p8;
		break;

	default:
		EVPerror(EVP_R_PKCS8_UNKNOWN_BROKEN_TYPE);
		return NULL;
	}
}
Esempio n. 8
0
static int
aead_aes_gcm_seal(const EVP_AEAD_CTX *ctx, unsigned char *out, size_t *out_len,
    size_t max_out_len, const unsigned char *nonce, size_t nonce_len,
    const unsigned char *in, size_t in_len, const unsigned char *ad,
    size_t ad_len)
{
	const struct aead_aes_gcm_ctx *gcm_ctx = ctx->aead_state;
	GCM128_CONTEXT gcm;
	size_t bulk = 0;

	if (max_out_len < in_len + gcm_ctx->tag_len) {
		EVPerror(EVP_R_BUFFER_TOO_SMALL);
		return 0;
	}

	memcpy(&gcm, &gcm_ctx->gcm, sizeof(gcm));
	CRYPTO_gcm128_setiv(&gcm, nonce, nonce_len);

	if (ad_len > 0 && CRYPTO_gcm128_aad(&gcm, ad, ad_len))
		return 0;

	if (gcm_ctx->ctr) {
		if (CRYPTO_gcm128_encrypt_ctr32(&gcm, in + bulk, out + bulk,
		    in_len - bulk, gcm_ctx->ctr))
			return 0;
	} else {
		if (CRYPTO_gcm128_encrypt(&gcm, in + bulk, out + bulk,
		    in_len - bulk))
			return 0;
	}

	CRYPTO_gcm128_tag(&gcm, out + in_len, gcm_ctx->tag_len);
	*out_len = in_len + gcm_ctx->tag_len;

	return 1;
}
Esempio n. 9
0
int
HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len, const EVP_MD *md,
    ENGINE *impl)
{
	int i, j, reset = 0;
	unsigned char pad[HMAC_MAX_MD_CBLOCK];

	/* If we are changing MD then we must have a key */
	if (md != NULL && md != ctx->md && (key == NULL || len < 0))
		return 0;

	if (md != NULL) {
		reset = 1;
		ctx->md = md;
	} else if (ctx->md != NULL)
		md = ctx->md;
	else
		return 0;

	if (key != NULL) {
		reset = 1;
		j = EVP_MD_block_size(md);
		if ((size_t)j > sizeof(ctx->key)) {
			EVPerror(EVP_R_BAD_BLOCK_LENGTH);
			goto err;
		}
		if (j < len) {
			if (!EVP_DigestInit_ex(&ctx->md_ctx, md, impl))
				goto err;
			if (!EVP_DigestUpdate(&ctx->md_ctx, key, len))
				goto err;
			if (!EVP_DigestFinal_ex(&(ctx->md_ctx), ctx->key,
			    &ctx->key_length))
				goto err;
		} else {
			if (len < 0 || (size_t)len > sizeof(ctx->key)) {
				EVPerror(EVP_R_BAD_KEY_LENGTH);
				goto err;
			}
			memcpy(ctx->key, key, len);
			ctx->key_length = len;
		}
		if (ctx->key_length != HMAC_MAX_MD_CBLOCK)
			memset(&ctx->key[ctx->key_length], 0,
			    HMAC_MAX_MD_CBLOCK - ctx->key_length);
	}

	if (reset) {
		for (i = 0; i < HMAC_MAX_MD_CBLOCK; i++)
			pad[i] = 0x36 ^ ctx->key[i];
		if (!EVP_DigestInit_ex(&ctx->i_ctx, md, impl))
			goto err;
		if (!EVP_DigestUpdate(&ctx->i_ctx, pad, EVP_MD_block_size(md)))
			goto err;

		for (i = 0; i < HMAC_MAX_MD_CBLOCK; i++)
			pad[i] = 0x5c ^ ctx->key[i];
		if (!EVP_DigestInit_ex(&ctx->o_ctx, md, impl))
			goto err;
		if (!EVP_DigestUpdate(&ctx->o_ctx, pad, EVP_MD_block_size(md)))
			goto err;
	}
	if (!EVP_MD_CTX_copy_ex(&ctx->md_ctx, &ctx->i_ctx))
		goto err;
	return 1;
err:
	return 0;
}
Esempio n. 10
0
static int
aes_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
    const unsigned char *iv, int enc)
{
	int ret, mode;
	EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data;

	mode = ctx->cipher->flags & EVP_CIPH_MODE;
	if ((mode == EVP_CIPH_ECB_MODE || mode == EVP_CIPH_CBC_MODE) &&
	    !enc)
#ifdef BSAES_CAPABLE
		if (BSAES_CAPABLE && mode == EVP_CIPH_CBC_MODE) {
			ret = AES_set_decrypt_key(key, ctx->key_len * 8,
			    &dat->ks);
			dat->block = (block128_f)AES_decrypt;
			dat->stream.cbc = (cbc128_f)bsaes_cbc_encrypt;
		} else
#endif
#ifdef VPAES_CAPABLE
		if (VPAES_CAPABLE) {
			ret = vpaes_set_decrypt_key(key, ctx->key_len * 8,
			    &dat->ks);
			dat->block = (block128_f)vpaes_decrypt;
			dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ?
			    (cbc128_f)vpaes_cbc_encrypt : NULL;
		} else
#endif
		{
			ret = AES_set_decrypt_key(key, ctx->key_len * 8,
			    &dat->ks);
			dat->block = (block128_f)AES_decrypt;
			dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ?
			    (cbc128_f)AES_cbc_encrypt : NULL;
		} else
#ifdef BSAES_CAPABLE
		if (BSAES_CAPABLE && mode == EVP_CIPH_CTR_MODE) {
			ret = AES_set_encrypt_key(key, ctx->key_len * 8,
			    &dat->ks);
			dat->block = (block128_f)AES_encrypt;
			dat->stream.ctr = (ctr128_f)bsaes_ctr32_encrypt_blocks;
		} else
#endif
#ifdef VPAES_CAPABLE
		if (VPAES_CAPABLE) {
			ret = vpaes_set_encrypt_key(key, ctx->key_len * 8,
			    &dat->ks);
			dat->block = (block128_f)vpaes_encrypt;
			dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ?
			    (cbc128_f)vpaes_cbc_encrypt : NULL;
		} else
#endif
		{
			ret = AES_set_encrypt_key(key, ctx->key_len * 8,
			    &dat->ks);
			dat->block = (block128_f)AES_encrypt;
			dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ?
			    (cbc128_f)AES_cbc_encrypt : NULL;
#ifdef AES_CTR_ASM
			if (mode == EVP_CIPH_CTR_MODE)
				dat->stream.ctr = (ctr128_f)AES_ctr32_encrypt;
#endif
		}

	if (ret < 0) {
		EVPerror(EVP_R_AES_KEY_SETUP_FAILED);
		return 0;
	}

	return 1;
}