static int pkey_mac_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) { MAC_PKEY_CTX *sctx, *dctx; if (!pkey_mac_init(dst)) return 0; sctx = EVP_PKEY_CTX_get_data(src); dctx = EVP_PKEY_CTX_get_data(dst); if (!EVP_MAC_CTX_copy(dctx->ctx, sctx->ctx)) goto err; switch (dctx->type) { case MAC_TYPE_RAW: dctx->raw_data.md = sctx->raw_data.md; if (ASN1_STRING_get0_data(&sctx->raw_data.ktmp) != NULL && !ASN1_STRING_copy(&dctx->raw_data.ktmp, &sctx->raw_data.ktmp)) goto err; break; case MAC_TYPE_MAC: /* Nothing more to do */ break; default: /* This should be dead code */ return 0; } return 1; err: pkey_mac_cleanup (dst); return 0; }
static int pkey_gost_mac_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) { struct te_mac_pmeth_data *dst_data,*src_data; if (!pkey_gost_mac_init(dst)) return 0; src_data = EVP_PKEY_CTX_get_data(src); dst_data = EVP_PKEY_CTX_get_data(dst); *dst_data = *src_data; return 1; }
/* Copies contents of gost_pmeth_data structure */ static int pkey_gost_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) { struct gost_pmeth_data *dst_data, *src_data; if (!pkey_gost_init(dst)) { return 0; } src_data = EVP_PKEY_CTX_get_data(src); dst_data = EVP_PKEY_CTX_get_data(dst); *dst_data = *src_data; if (src_data->shared_ukm) { dst_data->shared_ukm = NULL; } return 1; }
static int pkey_mac_ctrl_str(EVP_PKEY_CTX *ctx, const char *type, const char *value) { MAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx); return EVP_MAC_ctrl_str(hctx->ctx, type, value); }
static int pkey_mac_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, EVP_MD_CTX *mctx) { MAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx); return EVP_MAC_final(hctx->ctx, sig, siglen); }
/* * EVP_PKEY_METHOD callback derive. * Implements VKO R 34.10-2001/2012 algorithms */ int pkey_gost_ec_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen) { /* * Public key of peer in the ctx field peerkey * Our private key in the ctx pkey * ukm is in the algorithm specific context data */ EVP_PKEY *my_key = EVP_PKEY_CTX_get0_pkey(ctx); EVP_PKEY *peer_key = EVP_PKEY_CTX_get0_peerkey(ctx); struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx); int dgst_nid = NID_undef; if (!data || !data->shared_ukm) { GOSTerr(GOST_F_PKEY_GOST_EC_DERIVE, GOST_R_UKM_NOT_SET); return 0; } if (key == NULL) { *keylen = 32; return 32; } EVP_PKEY_get_default_digest_nid(my_key, &dgst_nid); *keylen = VKO_compute_key(key, 32, EC_KEY_get0_public_key(EVP_PKEY_get0(peer_key)), (EC_KEY *)EVP_PKEY_get0(my_key), data->shared_ukm, dgst_nid); return (*keylen) ? 1 : 0; }
/* * EVP_PKEY_METHOD callback derive. Implements VKO R 34.10-2001 * algorithm */ int pkey_gost2001_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen) { /* * Public key of peer in the ctx field peerkey Our private key in the ctx * pkey ukm is in the algorithm specific context data */ EVP_PKEY *my_key = EVP_PKEY_CTX_get0_pkey(ctx); EVP_PKEY *peer_key = EVP_PKEY_CTX_get0_peerkey(ctx); struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx); if (!data->shared_ukm) { GOSTerr(GOST_F_PKEY_GOST2001_DERIVE, GOST_R_UKM_NOT_SET); return 0; } if (key == NULL) { *keylen = 32; return 32; } *keylen = VKO_compute_key(key, 32, EC_KEY_get0_public_key(EVP_PKEY_get0(peer_key)), (EC_KEY *)EVP_PKEY_get0(my_key), data->shared_ukm); return 1; }
/* Frees up gost_pmeth_data structure */ static void pkey_gost_cleanup(EVP_PKEY_CTX *ctx) { struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx); OPENSSL_free(data->shared_ukm); OPENSSL_free(data); }
static int pkey_gost_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) { struct gost_mac_pmeth_data *data = (struct gost_mac_pmeth_data*)EVP_PKEY_CTX_get_data(ctx); switch (type) { case EVP_PKEY_CTRL_MD: { if (EVP_MD_type((const EVP_MD *)p2) != NID_id_Gost28147_89_MAC) { GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL, GOST_R_INVALID_DIGEST_TYPE); return 0; } data->md = (EVP_MD *)p2; return 1; } break; case EVP_PKEY_CTRL_PKCS7_ENCRYPT: case EVP_PKEY_CTRL_PKCS7_DECRYPT: case EVP_PKEY_CTRL_PKCS7_SIGN: return 1; case EVP_PKEY_CTRL_SET_MAC_KEY: if (p1 != 32) { GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL, GOST_R_INVALID_MAC_KEY_LENGTH); return 0; } memcpy(data->key,p2,32); data->key_set = 1; return 1; case EVP_PKEY_CTRL_DIGESTINIT: { EVP_MD_CTX *mctx = p2; void *key; if (!data->key_set) { EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx); if (!pkey) { GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL,GOST_R_MAC_KEY_NOT_SET); return 0; } key = EVP_PKEY_get0(pkey); if (!key) { GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL,GOST_R_MAC_KEY_NOT_SET); return 0; } } else { key = &(data->key); } return mctx->digest->md_ctrl(mctx,EVP_MD_CTRL_SET_KEY,32,key); } } return -2; }
static int pkey_gost_mac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx) { struct gost_mac_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx); if (data == NULL) { pkey_gost_mac_init(ctx); } data = EVP_PKEY_CTX_get_data(ctx); if (!data) { GOSTerr(GOST_F_PKEY_GOST_MAC_SIGNCTX_INIT, GOST_R_MAC_KEY_NOT_SET); return 0; } return 1; }
static int ossl_int_update(EVP_MD_CTX *ctx, const void *data, size_t count) { OSSL_HMAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(EVP_MD_CTX_pkey_ctx(ctx)); if (!HMAC_Update(hctx->ctx, data, count)) return 0; return 1; }
static int ossl_hmac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) { OSSL_HMAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx); EVP_PKEY *pk; ASN1_OCTET_STRING *key; switch (type) { case EVP_PKEY_CTRL_SET_MAC_KEY: if ((!p2 && p1 > 0) || (p1 < -1)) return 0; if (!ASN1_OCTET_STRING_set(&hctx->ktmp, p2, p1)) return 0; break; case EVP_PKEY_CTRL_MD: hctx->md = p2; break; case EVP_PKEY_CTRL_DIGESTINIT: pk = EVP_PKEY_CTX_get0_pkey(ctx); key = EVP_PKEY_get0(pk); if (!HMAC_Init_ex(hctx->ctx, key->data, key->length, hctx->md, NULL)) return 0; break; default: return -2; } return 1; }
static void ossl_hmac_cleanup(EVP_PKEY_CTX *ctx) { OSSL_HMAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx); HMAC_CTX_free(hctx->ctx); OPENSSL_clear_free(hctx->ktmp.data, hctx->ktmp.length); OPENSSL_free(hctx); }
static int ossl_hmac_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) { OSSL_HMAC_PKEY_CTX *sctx, *dctx; if (!ossl_hmac_init(dst)) return 0; sctx = EVP_PKEY_CTX_get_data(src); dctx = EVP_PKEY_CTX_get_data(dst); dctx->md = sctx->md; if (!HMAC_CTX_copy(dctx->ctx, sctx->ctx)) return 0; if (sctx->ktmp.data) { if (!ASN1_OCTET_STRING_set(&dctx->ktmp, sctx->ktmp.data, sctx->ktmp.length)) return 0; } return 1; }
/* --------------------- control functions ------------------------------*/ static int pkey_gost_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) { struct gost_pmeth_data *pctx = (struct gost_pmeth_data*)EVP_PKEY_CTX_get_data(ctx); switch (type) { case EVP_PKEY_CTRL_MD: { if (EVP_MD_type((const EVP_MD *)p2) != NID_id_GostR3411_94) { GOSTerr(GOST_F_PKEY_GOST_CTRL, GOST_R_INVALID_DIGEST_TYPE); return 0; } pctx->md = (EVP_MD *)p2; return 1; } break; case EVP_PKEY_CTRL_GET_MD: *(const EVP_MD **)p2 = pctx->md; return 1; case EVP_PKEY_CTRL_PKCS7_ENCRYPT: case EVP_PKEY_CTRL_PKCS7_DECRYPT: case EVP_PKEY_CTRL_PKCS7_SIGN: case EVP_PKEY_CTRL_DIGESTINIT: #ifndef OPENSSL_NO_CMS case EVP_PKEY_CTRL_CMS_ENCRYPT: case EVP_PKEY_CTRL_CMS_DECRYPT: case EVP_PKEY_CTRL_CMS_SIGN: #endif return 1; case EVP_PKEY_CTRL_GOST_PARAMSET: pctx->sign_param_nid = (int)p1; return 1; case EVP_PKEY_CTRL_SET_IV: pctx->shared_ukm=OPENSSL_malloc((int)p1); if (pctx->shared_ukm == NULL) { GOSTerr(GOST_F_PKEY_GOST_CTRL, ERR_R_MALLOC_FAILURE); return 0; } memcpy(pctx->shared_ukm,p2,(int) p1); return 1; case EVP_PKEY_CTRL_PEER_KEY: if (p1 == 0 || p1 == 1) /* call from EVP_PKEY_derive_set_peer */ return 1; if (p1 == 2) /* TLS: peer key used? */ return pctx->peer_key_used; if (p1 == 3) /* TLS: peer key used! */ return (pctx->peer_key_used = 1); return -2; } return -2; }
static int pkey_gost_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) { struct gost_mac_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx); switch (type) { case EVP_PKEY_CTRL_MD: if (EVP_MD_type(p2) != NID_id_Gost28147_89_MAC) { GOSTerror(GOST_R_INVALID_DIGEST_TYPE); return 0; } data->md = p2; return 1; case EVP_PKEY_CTRL_SET_MAC_KEY: if (p1 != 32) { GOSTerror(GOST_R_INVALID_MAC_KEY_LENGTH); return 0; } memcpy(data->key, p2, 32); data->key_set = 1; return 1; case EVP_PKEY_CTRL_DIGESTINIT: { EVP_MD_CTX *mctx = p2; void *key; if (!data->key_set) { EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx); if (pkey == NULL) { GOSTerror(GOST_R_MAC_KEY_NOT_SET); return 0; } key = EVP_PKEY_get0(pkey); if (key == NULL) { GOSTerror(GOST_R_MAC_KEY_NOT_SET); return 0; } } else { key = &(data->key); } if (mctx->digest->md_ctrl == NULL) return 0; return mctx->digest->md_ctrl(mctx, EVP_MD_CTRL_SET_KEY, 32 * 8, key); } } return -2; }
static int pkey_gost_mac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) { struct gost_mac_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx); unsigned char *keydata; if (!data->key_set) { GOSTerr(GOST_F_PKEY_GOST_MAC_KEYGEN, GOST_R_MAC_KEY_NOT_SET); return 0; } keydata = OPENSSL_malloc(32); memcpy(keydata, data->key, 32); EVP_PKEY_assign(pkey, NID_id_Gost28147_89_MAC, keydata); return 1; }
//Generate or load key. Called very early static int pkey_gost_mac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) { printf("Keygen requested\n"); //we already have the key (or uid) in the context's data structure struct te_mac_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx); //now we must copy it to md context unsigned char *keydata; if (!data->key_set) { printf("Error: key isn't set\n"); return 0; } keydata = OPENSSL_malloc(data->key_ln); memcpy(keydata, data->key, data->key_ln); EVP_PKEY_assign(pkey, NID_hmac_sha1, keydata); return 1; }
static int ossl_hmac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) { ASN1_OCTET_STRING *hkey = NULL; OSSL_HMAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx); if (!hctx->ktmp.data) return 0; hkey = ASN1_OCTET_STRING_dup(&hctx->ktmp); if (!hkey) return 0; EVP_PKEY_assign(pkey, EVP_PKEY_HMAC, hkey); return 1; }
static int ossl_hmac_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) { OSSL_HMAC_PKEY_CTX *sctx, *dctx; /* allocate memory for dst->data and a new HMAC_CTX in dst->data->ctx */ if (!ossl_hmac_init(dst)) return 0; sctx = EVP_PKEY_CTX_get_data(src); dctx = EVP_PKEY_CTX_get_data(dst); dctx->md = sctx->md; if (!HMAC_CTX_copy(dctx->ctx, sctx->ctx)) goto err; if (sctx->ktmp.data) { if (!ASN1_OCTET_STRING_set(&dctx->ktmp, sctx->ktmp.data, sctx->ktmp.length)) goto err; } return 1; err: /* release HMAC_CTX in dst->data->ctx and memory allocated for dst->data */ ossl_hmac_cleanup(dst); return 0; }
//We can control the state of our engine by commands static int pkey_gost_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) { struct te_mac_pmeth_data *data = (struct te_mac_pmeth_data*)EVP_PKEY_CTX_get_data(ctx); switch (type) { case EVP_PKEY_CTRL_MD: if (EVP_MD_type((const EVP_MD *)p2) != NID_hmac_sha1) { printf("Error: unsupported digest type\n"); return 0; } data->md = (EVP_MD*)p2; return 1; case EVP_PKEY_CTRL_PKCS7_ENCRYPT: case EVP_PKEY_CTRL_PKCS7_DECRYPT: case EVP_PKEY_CTRL_PKCS7_SIGN: return 1; case EVP_PKEY_CTRL_SET_MAC_KEY: //here we can insert pkey extraction printf("Got set user id command: %s\n", (char*)p2); //or save user id for further operations if(strcmp((char*)p2, "123")) { printf("Error: unknown user (id = %s)\n", (char*)p2); return 0; } memcpy(data->uid, p2, p1); memcpy(data->key, "user_123_key\0", 13); data->key_ln = 12; data->key_set = 1; return 1; case EVP_PKEY_CTRL_DIGESTINIT: { //this request runs in different context (for unknown reason) printf("Got digest init command\n"); //but has the key that we have installed in keygen request void *key = 0; //in this request we must transfer the key into digest context int keyln = 0; //so digest must support control commands if(!data->key_set) { EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx); if (!pkey) { printf("Error: unable to set key\n"); return 0; } key = EVP_PKEY_get0(pkey); if (!key) { printf("Error: unable to set key\n"); return 0; } keyln = strlen((char *)key); //it's so dangerous } else { key = &(data->key); keyln = data->key_ln; } return ((EVP_MD_CTX*)p2)->digest->md_ctrl((EVP_MD_CTX*)p2, EVP_MD_CTRL_SET_KEY, keyln, key); } } return -2; }
static void pkey_mac_cleanup(EVP_PKEY_CTX *ctx) { MAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx); if (hctx != NULL) { switch (hctx->type) { case MAC_TYPE_RAW: OPENSSL_clear_free(hctx->raw_data.ktmp.data, hctx->raw_data.ktmp.length); break; } EVP_MAC_CTX_free(hctx->ctx); OPENSSL_free(hctx); EVP_PKEY_CTX_set_data(ctx, NULL); } }
static int pkey_gost94_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) { struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx); DSA *dsa = NULL; if (data->sign_param_nid == NID_undef) { GOSTerr(GOST_F_PKEY_GOST94_PARAMGEN, GOST_R_NO_PARAMETERS_SET); return 0; } dsa = DSA_new(); if (!fill_GOST94_params(dsa, data->sign_param_nid)) { DSA_free(dsa); return 0; } EVP_PKEY_assign(pkey, NID_id_GostR3410_94, dsa); return 1; }
static int pkey_gost_mac_keygen_base(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey, int mac_nid) { struct gost_mac_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx); struct gost_mac_key *keydata; if (!data || !data->key_set) { GOSTerr(GOST_F_PKEY_GOST_MAC_KEYGEN, GOST_R_MAC_KEY_NOT_SET); return 0; } keydata = OPENSSL_malloc(sizeof(struct gost_mac_key)); if (keydata == NULL) return 0; memcpy(keydata->key, data->key, 32); keydata->mac_param_nid = data->mac_param_nid; keydata->mac_size = data->mac_size; EVP_PKEY_assign(pkey, mac_nid, keydata); return 1; }
static int pkey_gost2001_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) { struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx); EC_KEY *ec = NULL; if (!data || data->sign_param_nid == NID_undef) { GOSTerr(GOST_F_PKEY_GOST01_PARAMGEN, GOST_R_NO_PARAMETERS_SET); return 0; } ec = EC_KEY_new(); if (!fill_GOST_EC_params(ec, data->sign_param_nid) || !EVP_PKEY_assign(pkey, NID_id_GostR3410_2001, ec)) { EC_KEY_free(ec); return 0; } return 1; }
static int ossl_hmac_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, EVP_MD_CTX *mctx) { unsigned int hlen; OSSL_HMAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx); int l = EVP_MD_CTX_size(mctx); if (l < 0) return 0; *siglen = l; if (!sig) return 1; if (!HMAC_Final(hctx->ctx, sig, &hlen)) return 0; *siglen = (size_t)hlen; return 1; }
static int pkey_gost2012_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) { struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx); EC_KEY *ec; int result = 0; if (!data || data->sign_param_nid == NID_undef) { GOSTerr(GOST_F_PKEY_GOST12_PARAMGEN, GOST_R_NO_PARAMETERS_SET); return 0; } ec = EC_KEY_new(); if (!fill_GOST_EC_params(ec, data->sign_param_nid)) { EC_KEY_free(ec); return 0; } switch (data->sign_param_nid) { case NID_id_tc26_gost_3410_2012_512_paramSetA: case NID_id_tc26_gost_3410_2012_512_paramSetB: result = (EVP_PKEY_assign(pkey, NID_id_GostR3410_2012_512, ec)) ? 1 : 0; break; case NID_id_GostR3410_2001_CryptoPro_A_ParamSet: case NID_id_GostR3410_2001_CryptoPro_B_ParamSet: case NID_id_GostR3410_2001_CryptoPro_C_ParamSet: case NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet: case NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet: case NID_id_GostR3410_2001_TestParamSet: result = (EVP_PKEY_assign(pkey, NID_id_GostR3410_2012_256, ec)) ? 1 : 0; break; default: result = 0; break; } if (result == 0) EC_KEY_free(ec); return result; }
static int pkey_gost_mac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) { struct gost_mac_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx); uint8_t *keydata; if (!data->key_set) { GOSTerr(GOST_F_PKEY_GOST_MAC_KEYGEN, GOST_R_MAC_KEY_NOT_SET); return 0; } keydata = malloc(32); if (keydata == NULL) { GOSTerr(GOST_F_PKEY_GOST_MAC_KEYGEN, ERR_R_MALLOC_FAILURE); return 0; } memcpy(keydata, data->key, 32); EVP_PKEY_assign(pkey, NID_id_Gost28147_89_MAC, keydata); return 1; }
/* --------------------- control functions ------------------------------*/ static int pkey_gost_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) { struct gost_pmeth_data *pctx = (struct gost_pmeth_data*)EVP_PKEY_CTX_get_data(ctx); switch (type) { case EVP_PKEY_CTRL_MD: { if (EVP_MD_type((const EVP_MD *)p2) != NID_id_GostR3411_94) { GOSTerr(GOST_F_PKEY_GOST_CTRL, GOST_R_INVALID_DIGEST_TYPE); return 0; } pctx->md = (EVP_MD *)p2; return 1; } break; case EVP_PKEY_CTRL_PKCS7_ENCRYPT: case EVP_PKEY_CTRL_PKCS7_DECRYPT: case EVP_PKEY_CTRL_PKCS7_SIGN: return 1; case EVP_PKEY_CTRL_GOST_PARAMSET: pctx->sign_param_nid = (int)p1; return 1; case EVP_PKEY_CTRL_SET_IV: pctx->shared_ukm=(unsigned char*)OPENSSL_malloc((int)p1); TINYCLR_SSL_MEMCPY(pctx->shared_ukm,p2,(int) p1); return 1; case EVP_PKEY_CTRL_PEER_KEY: if (p1 == 0 || p1 == 1) /* call from EVP_PKEY_derive_set_peer */ return 1; if (p1 == 2) /* TLS: peer key used? */ return pctx->peer_key_used; if (p1 == 3) /* TLS: peer key used! */ return (pctx->peer_key_used = 1); return -2; } return -2; }
static int pkey_mac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx) { MAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx); ASN1_OCTET_STRING *key = NULL; int rv = 1; /* * For MACs with the EVP_PKEY_FLAG_SIGCTX_CUSTOM flag set and that * gets the key passed as an ASN.1 OCTET STRING, we set the key here, * as this may be only time it's set during a DigestSign. * * MACs that pass around the key in form of EVP_MAC_CTX are setting * the key through other mechanisms. (this is only CMAC for now) */ int set_key = hctx->type == MAC_TYPE_RAW && (ctx->pmeth->flags & EVP_PKEY_FLAG_SIGCTX_CUSTOM) != 0; if (set_key) { if (EVP_PKEY_id(EVP_PKEY_CTX_get0_pkey(ctx)) != EVP_MAC_nid(EVP_MAC_CTX_mac(hctx->ctx))) return 0; key = EVP_PKEY_get0(EVP_PKEY_CTX_get0_pkey(ctx)); if (key == NULL) return 0; } /* Some MACs don't support this control... that's fine */ EVP_MAC_ctrl(hctx->ctx, EVP_MAC_CTRL_SET_FLAGS, EVP_MD_CTX_test_flags(mctx, ~EVP_MD_CTX_FLAG_NO_INIT)); EVP_MD_CTX_set_flags(mctx, EVP_MD_CTX_FLAG_NO_INIT); EVP_MD_CTX_set_update_fn(mctx, int_update); if (set_key) rv = EVP_MAC_ctrl(hctx->ctx, EVP_MAC_CTRL_SET_KEY, key->data, key->length); return rv > 0; }