]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
nettle: add support for GOST key derivation
authorDmitry Eremin-Solenikov <dbaryshkov@gmail.com>
Thu, 7 Jun 2018 10:19:55 +0000 (13:19 +0300)
committerDmitry Eremin-Solenikov <dbaryshkov@gmail.com>
Thu, 7 Nov 2019 15:41:28 +0000 (18:41 +0300)
Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
lib/nettle/pk.c

index bfa6ae437227a18930d14b257582df86c3e80c75..42d540cb460f63973bb44c1c53ce2a506827b765 100644 (file)
@@ -417,6 +417,57 @@ dh_cleanup:
                        }
                        break;
                }
+#if ENABLE_GOST
+       case GNUTLS_PK_GOST_01:
+       case GNUTLS_PK_GOST_12_256:
+       case GNUTLS_PK_GOST_12_512:
+       {
+               struct ecc_scalar ecc_priv;
+               struct ecc_point ecc_pub;
+               const struct ecc_curve *curve;
+
+               out->data = NULL;
+
+               curve = get_supported_gost_curve(priv->curve);
+               if (curve == NULL)
+                       return
+                           gnutls_assert_val
+                           (GNUTLS_E_ECC_UNSUPPORTED_CURVE);
+
+               if (nonce == NULL)
+                       return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+
+               ret = _gost_params_to_pubkey(pub, &ecc_pub, curve);
+               if (ret < 0)
+                       return gnutls_assert_val(ret);
+
+               ret = _gost_params_to_privkey(priv, &ecc_priv, curve);
+               if (ret < 0) {
+                       ecc_point_clear(&ecc_pub);
+                       return gnutls_assert_val(ret);
+               }
+
+               out->size = 2 * gnutls_ecc_curve_get_size(priv->curve);
+               out->data = gnutls_malloc(out->size);
+               if (out->data == NULL) {
+                       ret = gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
+                       goto gost_cleanup;
+               }
+
+               out->size = gostdsa_vko(&ecc_priv, &ecc_pub,
+                                       nonce->size, nonce->data,
+                                       out->size, out->data);
+               if (out->size == 0)
+                       ret = GNUTLS_E_INVALID_REQUEST;
+
+             gost_cleanup:
+               ecc_point_clear(&ecc_pub);
+               ecc_scalar_zclear(&ecc_priv);
+               if (ret < 0)
+                       goto cleanup;
+               break;
+       }
+#endif
        default:
                gnutls_assert();
                ret = GNUTLS_E_INTERNAL_ERROR;