]> wagner.pp.ru Git - openssl-gost/engine.git/blobdiff - gost_pmeth.c
links target
[openssl-gost/engine.git] / gost_pmeth.c
index a8252172dbb304722c9a6044bbc8d19f5849bb09..f07c4daadff710c964b091223399b60ebce86377 100644 (file)
@@ -466,10 +466,21 @@ static int pkey_gost_derive_init(EVP_PKEY_CTX *ctx)
 static int pkey_gost_mac_init(EVP_PKEY_CTX *ctx)
 {
     struct gost_mac_pmeth_data *data = OPENSSL_malloc(sizeof(*data));
+               EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx);
 
     if (!data)
         return 0;
     memset(data, 0, sizeof(*data));
+               data->mac_size = 4;
+               data->mac_param_nid = NID_undef;
+
+               if (pkey) {
+                       struct gost_mac_key *key = EVP_PKEY_get0(pkey);
+                       if (key) {
+                               data->mac_param_nid = key->mac_param_nid;
+      } 
+               }
+
     EVP_PKEY_CTX_set_data(ctx, data);
     return 1;
 }
@@ -531,10 +542,24 @@ static int pkey_gost_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
         memcpy(data->key, p2, 32);
         data->key_set = 1;
         return 1;
+    case EVP_PKEY_CTRL_GOST_PARAMSET:
+                 {
+                               struct gost_cipher_info *param = p2;
+                               data->mac_param_nid = param->nid;
+                               struct gost_mac_key *key = NULL;
+        EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx);
+        if (pkey) {
+               key = EVP_PKEY_get0(pkey);
+                                       if (key) {
+                                               key->mac_param_nid = param->nid;
+                                       }
+        } 
+         return 1;
+                       }
     case EVP_PKEY_CTRL_DIGESTINIT:
         {
             EVP_MD_CTX *mctx = p2;
-            void *key;
+            struct gost_mac_key *key;
             if (!data->key_set) {
                 EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx);
                 if (!pkey) {
@@ -548,11 +573,23 @@ static int pkey_gost_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
                             GOST_R_MAC_KEY_NOT_SET);
                     return 0;
                 }
+                return mctx->digest->md_ctrl(mctx, EVP_MD_CTRL_SET_KEY, 0, key);
             } else {
-                key = &(data->key);
+                return mctx->digest->md_ctrl(mctx, EVP_MD_CTRL_SET_KEY, 32, &(data->key));
             }
             return mctx->digest->md_ctrl(mctx, EVP_MD_CTRL_SET_KEY, 32, key);
         }
+       case EVP_PKEY_CTRL_MAC_LEN:     
+               {
+                       if (p1<1 || p1>8)
+                               {
+                                       
+                                       GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL,GOST_R_INVALID_MAC_SIZE);
+                                       return 0;
+                               }
+                               data->mac_size = p1;
+                               return 1;
+               }
     }
     return -2;
 }
@@ -584,6 +621,33 @@ static int pkey_gost_mac_ctrl_str(EVP_PKEY_CTX *ctx,
         return ret;
 
     }
+       if (!strcmp(type,maclen_ctrl_string)) {
+               char *endptr;
+               long size=strtol(value,&endptr,10);
+               if (*endptr!='\0') {
+                       GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL_STR,
+                                  GOST_R_INVALID_MAC_SIZE);
+                       return 0;
+               }
+               return pkey_gost_mac_ctrl(ctx, EVP_PKEY_CTRL_MAC_LEN,size,NULL);
+       }
+       if (strcmp(type, param_ctrl_string) == 0)
+               {
+                       ASN1_OBJECT *obj  = OBJ_txt2obj(value, 0);
+                       const struct gost_cipher_info *param = NULL;
+                       if (obj == NULL) {
+                               GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL_STR, GOST_R_INVALID_MAC_PARAMS);
+                               return 0;
+                       }
+
+                       param = get_encryption_params(obj);
+                       if (param == NULL) {
+                               GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL_STR, GOST_R_INVALID_MAC_PARAMS);
+                               return 0;
+                       }
+
+                       return pkey_gost_mac_ctrl(ctx, EVP_PKEY_CTRL_GOST_PARAMSET, 0, (void *)param);
+               }
     return -2;
 }
 
@@ -591,15 +655,16 @@ 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);
-    unsigned char *keydata;
+    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(32);
+    keydata = OPENSSL_malloc(sizeof(struct gost_mac_key));
     if (keydata == NULL)
         return 0;
-    memcpy(keydata, data->key, 32);
+    memcpy(keydata->key, data->key, 32);
+               keydata->mac_param_nid = data->mac_param_nid;
     EVP_PKEY_assign(pkey, mac_nid, keydata);
     return 1;
 }
@@ -624,6 +689,7 @@ static int pkey_gost_mac_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig,
 {
     unsigned int tmpsiglen;
     int ret;
+       struct gost_mac_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
 
     if (!siglen)
         return 0;
@@ -631,11 +697,13 @@ static int pkey_gost_mac_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig,
                                  * sizeof(size_t) */
 
     if (!sig) {
-        *siglen = 4;
+        *siglen = data->mac_size;
         return 1;
     }
+
+       mctx->digest->md_ctrl(mctx, EVP_MD_CTRL_MAC_LEN, data->mac_size, NULL);
     ret = EVP_DigestFinal_ex(mctx, sig, &tmpsiglen);
-    *siglen = tmpsiglen;
+    *siglen = data->mac_size;
     return ret;
 }