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; }
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; }
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; }
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; }
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; }
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; }
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; } }
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; }
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; }
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; }