]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Update EdDSA implementation to PKCS#11 v3.0.
authorAaron Thompson <dev@aaront.org>
Sun, 29 Mar 2020 06:04:08 +0000 (06:04 +0000)
committerOndřej Surý <ondrej@isc.org>
Thu, 30 Apr 2020 16:40:45 +0000 (18:40 +0200)
Per Current Mechanisms 2.3.5, the curve name is DER-encoded in the
EC_PARAMS attribute, and the public key value is DER-encoded in the
EC_POINT attribute.

lib/dns/pkcs11eddsa_link.c

index 52cb01a6522415c3c9c0461eeb835b557fd160c2..e2d69eada162d9191af86e3864a82b97b8656c80 100644 (file)
  *    object class CKO_PUBLIC_KEY
  *    key type CKK_EC_EDWARDS
  *    attribute CKA_EC_PARAMS (choice with OID namedCurve)
- *    attribute CKA_EC_POINT (big int A, CKA_VALUE on the token)
+ *    attribute CKA_EC_POINT (big int A)
  *  private keys:
  *    object class CKO_PRIVATE_KEY
  *    key type CKK_EC_EDWARDS
  *    attribute CKA_EC_PARAMS (choice with OID namedCurve)
  *    attribute CKA_VALUE (big int k)
+ *  point format: 0x04 (octet-string) <size> <A>
  */
 
+#define TAG_OCTECT_STRING 0x04
+
 #define DST_RET(a)        \
        {                 \
                ret = a;  \
@@ -252,7 +255,7 @@ pkcs11eddsa_verify(dst_context_t *dctx, const isc_region_t *sig) {
                { CKA_PRIVATE, &falsevalue, (CK_ULONG)sizeof(falsevalue) },
                { CKA_VERIFY, &truevalue, (CK_ULONG)sizeof(truevalue) },
                { CKA_EC_PARAMS, NULL, 0 },
-               { CKA_VALUE, NULL, 0 }
+               { CKA_EC_POINT, NULL, 0 }
        };
        CK_ATTRIBUTE *attr;
        CK_SLOT_ID slotid;
@@ -292,7 +295,7 @@ pkcs11eddsa_verify(dst_context_t *dctx, const isc_region_t *sig) {
                        keyTemplate[5].ulValueLen = attr->ulValueLen;
                        break;
                case CKA_EC_POINT:
-                       /* keyTemplate[6].type is CKA_VALUE */
+                       INSIST(keyTemplate[6].type == attr->type);
                        keyTemplate[6].pValue = isc_mem_get(dctx->mctx,
                                                            attr->ulValueLen);
                        memmove(keyTemplate[6].pValue, attr->pValue,
@@ -477,7 +480,7 @@ pkcs11eddsa_generate(dst_key_t *key, int unused, void (*callback)(int)) {
 
        attr = ec->repr;
        attr[0].type = CKA_EC_PARAMS;
-       attr[1].type = CKA_VALUE;
+       attr[1].type = CKA_EC_POINT;
        attr[2].type = CKA_VALUE;
 
        attr = &pubTemplate[5];
@@ -501,7 +504,6 @@ pkcs11eddsa_generate(dst_key_t *key, int unused, void (*callback)(int)) {
        memset(attr->pValue, 0, attr->ulValueLen);
        PK11_RET(pkcs_C_GetAttributeValue, (pk11_ctx->session, pub, attr, 1),
                 DST_R_CRYPTOFAILURE);
-       attr->type = CKA_EC_POINT;
 
        attr++;
        PK11_RET(pkcs_C_GetAttributeValue, (pk11_ctx->session, priv, attr, 1),
@@ -612,7 +614,10 @@ pkcs11eddsa_todns(const dst_key_t *key, isc_buffer_t *data) {
 
        ec = key->keydata.pkey;
        attr = pk11_attribute_bytype(ec, CKA_EC_POINT);
-       if ((attr == NULL) || (attr->ulValueLen != len)) {
+       if ((attr == NULL) || (attr->ulValueLen != len + 2) ||
+           (((CK_BYTE_PTR)attr->pValue)[0] != TAG_OCTECT_STRING) ||
+           (((CK_BYTE_PTR)attr->pValue)[1] != len))
+       {
                return (ISC_R_FAILURE);
        }
 
@@ -620,7 +625,7 @@ pkcs11eddsa_todns(const dst_key_t *key, isc_buffer_t *data) {
        if (r.length < len) {
                return (ISC_R_NOSPACE);
        }
-       memmove(r.base, (CK_BYTE_PTR)attr->pValue, len);
+       memmove(r.base, (CK_BYTE_PTR)attr->pValue + 2, len);
        isc_buffer_add(data, len);
 
        return (ISC_R_SUCCESS);
@@ -667,9 +672,11 @@ pkcs11eddsa_fromdns(dst_key_t *key, isc_buffer_t *data) {
 
        attr++;
        attr->type = CKA_EC_POINT;
-       attr->pValue = isc_mem_get(key->mctx, len);
-       memmove((CK_BYTE_PTR)attr->pValue, r.base, len);
-       attr->ulValueLen = len;
+       attr->pValue = isc_mem_get(key->mctx, len + 2);
+       ((CK_BYTE_PTR)attr->pValue)[0] = TAG_OCTECT_STRING;
+       ((CK_BYTE_PTR)attr->pValue)[1] = len;
+       memmove((CK_BYTE_PTR)attr->pValue + 2, r.base, len);
+       attr->ulValueLen = len + 2;
 
        isc_buffer_forward(data, len);
        key->keydata.pkey = ec;
@@ -768,6 +775,7 @@ pkcs11eddsa_fetch(dst_key_t *key, const char *engine, const char *label,
 
        attr->type = CKA_EC_PARAMS;
        pubattr = pk11_attribute_bytype(pubec, CKA_EC_PARAMS);
+       INSIST(pubattr != NULL);
        attr->pValue = isc_mem_get(key->mctx, pubattr->ulValueLen);
        memmove(attr->pValue, pubattr->pValue, pubattr->ulValueLen);
        attr->ulValueLen = pubattr->ulValueLen;
@@ -775,6 +783,7 @@ pkcs11eddsa_fetch(dst_key_t *key, const char *engine, const char *label,
 
        attr->type = CKA_EC_POINT;
        pubattr = pk11_attribute_bytype(pubec, CKA_EC_POINT);
+       INSIST(pubattr != NULL);
        attr->pValue = isc_mem_get(key->mctx, pubattr->ulValueLen);
        memmove(attr->pValue, pubattr->pValue, pubattr->ulValueLen);
        attr->ulValueLen = pubattr->ulValueLen;
@@ -982,7 +991,7 @@ pkcs11eddsa_fromlabel(dst_key_t *key, const char *engine, const char *label,
        ec->attrcnt = 2;
        attr = ec->repr;
        attr[0].type = CKA_EC_PARAMS;
-       attr[1].type = CKA_VALUE;
+       attr[1].type = CKA_EC_POINT;
 
        ret = pk11_parse_uri(ec, label, key->mctx, OP_EDDSA);
        if (ret != ISC_R_SUCCESS) {
@@ -1028,7 +1037,6 @@ pkcs11eddsa_fromlabel(dst_key_t *key, const char *engine, const char *label,
        }
        PK11_RET(pkcs_C_GetAttributeValue, (pk11_ctx->session, hKey, attr, 2),
                 DST_R_CRYPTOFAILURE);
-       attr[1].type = CKA_EC_POINT;
 
        keyClass = CKO_PRIVATE_KEY;
        PK11_RET(pkcs_C_FindObjectsInit,