X-Git-Url: https://wagner.pp.ru/gitweb/?a=blobdiff_plain;f=gost_gost2015.c;h=a47337509790550c0e33a907c08016b9eef34877;hb=3acdb02cede3259cb77b71368c8c581b1734c127;hp=c0a914d80da563b4d5f9280f3fdc49392cefe304;hpb=f1aa1602d4aa644a6944d7c01a808fea4947e4e8;p=openssl-gost%2Fengine.git diff --git a/gost_gost2015.c b/gost_gost2015.c index c0a914d..a473375 100644 --- a/gost_gost2015.c +++ b/gost_gost2015.c @@ -2,6 +2,7 @@ #include "gost_gost2015.h" #include "e_gost_err.h" #include +#include int gost2015_final_call(EVP_CIPHER_CTX *ctx, EVP_MD_CTX *omac_ctx, size_t mac_size, unsigned char *encrypted_mac, @@ -120,3 +121,73 @@ end: GOST2015_CIPHER_PARAMS_free(gcp); return ret; } + +int gost2015_process_unprotected_attributes(STACK_OF(X509_ATTRIBUTE) *attrs, + int encryption, size_t mac_len, unsigned char *final_tag) +{ + if (encryption == 0) /*Decrypting*/ { + ASN1_OCTET_STRING *osExpectedMac = X509at_get0_data_by_OBJ(attrs, + OBJ_txt2obj(OID_GOST_CMS_MAC, 1), -3, V_ASN1_OCTET_STRING); + + if (!osExpectedMac || osExpectedMac->length != (int)mac_len) + return -1; + + memcpy(final_tag, osExpectedMac->data, osExpectedMac->length); + } else { + if (attrs == NULL) + return -1; + return (X509at_add1_attr_by_OBJ(&attrs, OBJ_txt2obj(OID_GOST_CMS_MAC, 1), + V_ASN1_OCTET_STRING, final_tag, mac_len) == NULL) ? -1 : 1; + } + return 1; +} + +int gost2015_acpkm_omac_init(int nid, int enc, const unsigned char *inkey, + EVP_MD_CTX *omac_ctx, + unsigned char *outkey, unsigned char *kdf_seed) +{ + int ret = 0; + unsigned char keys[64]; + const EVP_MD *md = EVP_get_digestbynid(nid); + EVP_PKEY *mac_key; + + if (md == NULL) + return 0; + + if (enc) { + if (RAND_bytes(kdf_seed, 8) != 1) + return 0; + } + + if (gost_kdftree2012_256(keys, 64, inkey, 32, (const unsigned char *)"kdf tree", 8, kdf_seed, 8, 1) <= 0) + return 0; + + mac_key = EVP_PKEY_new_mac_key(nid, NULL, keys+32, 32); + + if (mac_key == NULL) + goto end; + + if (EVP_DigestInit_ex(omac_ctx, md, NULL) <= 0 || + EVP_DigestSignInit(omac_ctx, NULL, md, NULL, mac_key) <= 0) + goto end; + + memcpy(outkey, keys, 32); + + ret = 1; +end: + EVP_PKEY_free(mac_key); + OPENSSL_cleanse(keys, sizeof(keys)); + + return ret; +} + +int init_zero_kdf_seed(unsigned char *kdf_seed) +{ + int is_zero_kdfseed = 1, i; + for (i = 0; i < 8; i++) { + if (kdf_seed[i] != 0) + is_zero_kdfseed = 0; + } + + return is_zero_kdfseed ? RAND_bytes(kdf_seed, 8) : 1; +}