if (EVP_CIPHER_CTX_get_app_data(ctx) == NULL) {
EVP_CIPHER_CTX_set_app_data(ctx, EVP_CIPHER_CTX_get_cipher_data(ctx));
+ if (enc && c->type == GRASSHOPPER_CIPHER_CTRACPKM) {
+ gost_grasshopper_cipher_ctx_ctr *ctr = EVP_CIPHER_CTX_get_cipher_data(ctx);
+ if (init_zero_kdf_seed(ctr->kdf_seed) == 0)
+ return -1;
+ }
}
if (key != NULL) {
c->section_size = 4096;
if (key) {
- unsigned char keys[64];
- const EVP_MD *md = EVP_get_digestbynid(NID_kuznyechik_mac);
- EVP_PKEY *mac_key;
-
- if (md == NULL)
- return 0;
-
- if (enc) {
- if (RAND_bytes(c->kdf_seed, 8) != 1)
- return 0;
- }
-
- if (gost_kdftree2012_256(keys, 64, key, 32, (const unsigned char *)"kdf tree", 8, c->kdf_seed, 8, 1) <= 0)
- return 0;
-
+ unsigned char cipher_key[32];
c->omac_ctx = EVP_MD_CTX_new();
- mac_key = EVP_PKEY_new_mac_key(NID_kuznyechik_mac, NULL, keys+32, 32);
- if (mac_key == NULL || c->omac_ctx == NULL) {
- EVP_PKEY_free(mac_key);
- return 0;
+ if (c->omac_ctx == NULL) {
+ GOSTerr(GOST_F_GOST_GRASSHOPPER_CIPHER_INIT_CTRACPKM_OMAC, ERR_R_MALLOC_FAILURE);
+ return 0;
}
- if (EVP_DigestInit_ex(c->omac_ctx, md, NULL) <= 0 ||
- EVP_DigestSignInit(c->omac_ctx, NULL, md, NULL, mac_key) <= 0) {
- EVP_PKEY_free(mac_key);
- return 0;
+ if (gost2015_acpkm_omac_init(NID_kuznyechik_mac, enc, key,
+ c->omac_ctx, cipher_key, c->kdf_seed) != 1) {
+ EVP_MD_CTX_free(c->omac_ctx);
+ c->omac_ctx = NULL;
+ return 0;
}
- EVP_PKEY_free(mac_key);
- return gost_grasshopper_cipher_init(ctx, keys, iv, enc);
+ return gost_grasshopper_cipher_init(ctx, cipher_key, iv, enc);
}
+
return gost_grasshopper_cipher_init(ctx, key, iv, enc);
}
return 0;
}
-int gost_grasshopper_cipher_ctl(EVP_CIPHER_CTX *ctx, int type, int arg,
- void *ptr)
+int gost_grasshopper_cipher_ctl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr)
{
switch (type) {
case EVP_CTRL_RAND_KEY:{
}
#endif
case EVP_CTRL_PROCESS_UNPROTECTED:
- {
- gost_grasshopper_cipher_ctx_ctr *c = EVP_CIPHER_CTX_get_cipher_data(ctx);
- ASN1_OBJECT *cmsmacobj = NULL;
- if (c->c.type != GRASSHOPPER_CIPHER_CTRACPKMOMAC)
- return -1;
- cmsmacobj = OBJ_txt2obj(OID_GOST_CMS_MAC, 1);
- if (cmsmacobj == NULL) {
- GOSTerr(GOST_F_GOST_GRASSHOPPER_CIPHER_CTL, ERR_R_MALLOC_FAILURE);
- return -1;
- }
- if (arg == 0) /*Decrypting*/ {
- STACK_OF(X509_ATTRIBUTE) *x = ptr;
- ASN1_OCTET_STRING *osExpectedMac = X509at_get0_data_by_OBJ(x,
- cmsmacobj, -3, V_ASN1_OCTET_STRING);
- ASN1_OBJECT_free(cmsmacobj);
-
- if (ptr == NULL || osExpectedMac ==NULL || osExpectedMac->length != KUZNYECHIK_MAC_MAX_SIZE)
- return -1;
-
- memcpy(c->tag, osExpectedMac->data, osExpectedMac->length);
- return 1;
- } else {
- STACK_OF(X509_ATTRIBUTE) *x = ptr;
- return (X509at_add1_attr_by_OBJ(&x, cmsmacobj,
- V_ASN1_OCTET_STRING, c->tag, KUZNYECHIK_MAC_MAX_SIZE) == NULL) ? -1 : 1;
- }
- }
- return 1;
+ {
+ STACK_OF(X509_ATTRIBUTE) *x = ptr;
+ gost_grasshopper_cipher_ctx_ctr *c = EVP_CIPHER_CTX_get_cipher_data(ctx);
+
+ if (c->c.type != GRASSHOPPER_CIPHER_CTRACPKMOMAC)
+ return -1;
+
+ return gost2015_process_unprotected_attributes(x, arg, KUZNYECHIK_MAC_MAX_SIZE, c->tag);
+ }
+ return 1;
case EVP_CTRL_COPY: {
EVP_CIPHER_CTX *out = ptr;