]> 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>
Fri, 1 May 2020 06:00:52 +0000 (08:00 +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.

(cherry picked from commit 2e6b7a56cc6261582811fc2b14d2160303b4d039)

lib/dns/pkcs11eddsa_link.c

index 63542f5d4009347a6755856092f8c350e653b88e..76b81c9d52c55e5517ead8433477792c5387102d 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;  \
@@ -254,7 +257,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;
@@ -294,7 +297,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,
@@ -479,7 +482,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];
@@ -503,7 +506,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),
@@ -614,7 +616,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);
        }
 
@@ -622,7 +627,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);
@@ -669,9 +674,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;
@@ -770,6 +777,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;
@@ -777,6 +785,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;
@@ -984,7 +993,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) {
@@ -1030,7 +1039,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,