Title: [222316] trunk/Source/WebCore
Revision
222316
Author
[email protected]
Date
2017-09-21 02:51:47 -0700 (Thu, 21 Sep 2017)

Log Message

[WebCrypto] Support Elliptic Curve P-521
https://bugs.webkit.org/show_bug.cgi?id=169231
<rdar://problem/30881703>

Reviewed by Jiewen Tan.

Add support for the P-521 elliptic curve to the CryptoKeyEC class, but
allow the underlying platform-specific implementations to opt out of
supporting this feature.

This is achieved with the platformSupportedCurve() static function that
each platform has to implement, returning true if the passed-in curve
type is supported. The function is called at each CryptoKeyEC entrypoint,
that is in each static function that could generate a new CryptoKeyEC
object. These functions return a NotSupportedError exception in case the
platformSupportedCurve() call returns false.

While the libgcrypt-based implementation will support P-521 curves in
the near future, the CommonCrypto-based implementation might not. The use
of platformSupportedCurve() ensures that the implementations that don't
support EC P-521 continue to return the NotSupportedError exception at
these entrypoints, instead of the OperationError exception that's returned
when the platform-specific extensions of these entrypoints fail due to the
specified elliptic curve not being supported.

Both libgcrypt-based and CommonCrypto-based implementations mark P-256 and
P-384 curves as supported. Switch statements handling NamedCurve values
must now also handle the NamedCurve::P521 value, but both implementations
treat that as an unreachable case since support is not indicated in
platformSupportedCurve(), and all CryptoKeyEC operations should have
returned with an NotSupportedError exception before entering
platform-specific code. The common CryptoKeyEC constructor similarly asserts
that the specified curve is supported by the underlying implementation.

CryptoAlgorithmECDSA is modified to now also support 'ES512' as the algorithm
identifier, matching it against the 'P-521' curve value.

No new tests -- tests covering EC P-521 already exist, but no platform
runs them yet due to missing implementations.

* crypto/algorithms/CryptoAlgorithmECDSA.cpp:
(WebCore::CryptoAlgorithmECDSA::importKey):
* crypto/gcrypt/CryptoKeyECGCrypt.cpp:
(WebCore::curveName):
(WebCore::curveIdentifier):
(WebCore::curveSize):
(WebCore::curveUncompressedFieldElementSize):
(WebCore::CryptoKeyEC::platformSupportedCurve):
* crypto/keys/CryptoKeyEC.cpp:
(WebCore::toNamedCurve):
(WebCore::CryptoKeyEC::CryptoKeyEC):
(WebCore::CryptoKeyEC::generatePair):
(WebCore::CryptoKeyEC::importRaw):
(WebCore::CryptoKeyEC::importJwk):
(WebCore::CryptoKeyEC::importSpki):
(WebCore::CryptoKeyEC::importPkcs8):
(WebCore::CryptoKeyEC::exportJwk const):
(WebCore::CryptoKeyEC::namedCurveString const):
(WebCore::CryptoKeyEC::algorithm const):
* crypto/keys/CryptoKeyEC.h:
* crypto/mac/CryptoKeyECMac.cpp:
(WebCore::doesUncompressedPointMatchNamedCurve):
(WebCore::doesFieldElementMatchNamedCurve):
(WebCore::getKeySizeFromNamedCurve):
(WebCore::CryptoKeyEC::platformSupportedCurve):
(WebCore::getOID):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (222315 => 222316)


--- trunk/Source/WebCore/ChangeLog	2017-09-21 09:33:40 UTC (rev 222315)
+++ trunk/Source/WebCore/ChangeLog	2017-09-21 09:51:47 UTC (rev 222316)
@@ -1,3 +1,72 @@
+2017-09-21  Zan Dobersek  <[email protected]>
+
+        [WebCrypto] Support Elliptic Curve P-521
+        https://bugs.webkit.org/show_bug.cgi?id=169231
+        <rdar://problem/30881703>
+
+        Reviewed by Jiewen Tan.
+
+        Add support for the P-521 elliptic curve to the CryptoKeyEC class, but
+        allow the underlying platform-specific implementations to opt out of
+        supporting this feature.
+
+        This is achieved with the platformSupportedCurve() static function that
+        each platform has to implement, returning true if the passed-in curve
+        type is supported. The function is called at each CryptoKeyEC entrypoint,
+        that is in each static function that could generate a new CryptoKeyEC
+        object. These functions return a NotSupportedError exception in case the
+        platformSupportedCurve() call returns false.
+
+        While the libgcrypt-based implementation will support P-521 curves in
+        the near future, the CommonCrypto-based implementation might not. The use
+        of platformSupportedCurve() ensures that the implementations that don't
+        support EC P-521 continue to return the NotSupportedError exception at
+        these entrypoints, instead of the OperationError exception that's returned
+        when the platform-specific extensions of these entrypoints fail due to the
+        specified elliptic curve not being supported.
+
+        Both libgcrypt-based and CommonCrypto-based implementations mark P-256 and
+        P-384 curves as supported. Switch statements handling NamedCurve values
+        must now also handle the NamedCurve::P521 value, but both implementations
+        treat that as an unreachable case since support is not indicated in
+        platformSupportedCurve(), and all CryptoKeyEC operations should have
+        returned with an NotSupportedError exception before entering
+        platform-specific code. The common CryptoKeyEC constructor similarly asserts
+        that the specified curve is supported by the underlying implementation.
+
+        CryptoAlgorithmECDSA is modified to now also support 'ES512' as the algorithm
+        identifier, matching it against the 'P-521' curve value.
+
+        No new tests -- tests covering EC P-521 already exist, but no platform
+        runs them yet due to missing implementations.
+
+        * crypto/algorithms/CryptoAlgorithmECDSA.cpp:
+        (WebCore::CryptoAlgorithmECDSA::importKey):
+        * crypto/gcrypt/CryptoKeyECGCrypt.cpp:
+        (WebCore::curveName):
+        (WebCore::curveIdentifier):
+        (WebCore::curveSize):
+        (WebCore::curveUncompressedFieldElementSize):
+        (WebCore::CryptoKeyEC::platformSupportedCurve):
+        * crypto/keys/CryptoKeyEC.cpp:
+        (WebCore::toNamedCurve):
+        (WebCore::CryptoKeyEC::CryptoKeyEC):
+        (WebCore::CryptoKeyEC::generatePair):
+        (WebCore::CryptoKeyEC::importRaw):
+        (WebCore::CryptoKeyEC::importJwk):
+        (WebCore::CryptoKeyEC::importSpki):
+        (WebCore::CryptoKeyEC::importPkcs8):
+        (WebCore::CryptoKeyEC::exportJwk const):
+        (WebCore::CryptoKeyEC::namedCurveString const):
+        (WebCore::CryptoKeyEC::algorithm const):
+        * crypto/keys/CryptoKeyEC.h:
+        * crypto/mac/CryptoKeyECMac.cpp:
+        (WebCore::doesUncompressedPointMatchNamedCurve):
+        (WebCore::doesFieldElementMatchNamedCurve):
+        (WebCore::getKeySizeFromNamedCurve):
+        (WebCore::CryptoKeyEC::platformSupportedCurve):
+        (WebCore::getOID):
+
 2017-09-20  Antti Koivisto  <[email protected]>
 
         inspector/dom/content-node-region-info.html and inspector/dom/content-flow tests crashing

Modified: trunk/Source/WebCore/crypto/algorithms/CryptoAlgorithmECDSA.cpp (222315 => 222316)


--- trunk/Source/WebCore/crypto/algorithms/CryptoAlgorithmECDSA.cpp	2017-09-21 09:33:40 UTC (rev 222315)
+++ trunk/Source/WebCore/crypto/algorithms/CryptoAlgorithmECDSA.cpp	2017-09-21 09:51:47 UTC (rev 222316)
@@ -36,8 +36,10 @@
 
 static const char* const ALG256 = "ES256";
 static const char* const ALG384 = "ES384";
+static const char* const ALG512 = "ES512";
 static const char* const P256 = "P-256";
 static const char* const P384 = "P-384";
+static const char* const P521 = "P-521";
 
 Ref<CryptoAlgorithm> CryptoAlgorithmECDSA::create()
 {
@@ -120,6 +122,8 @@
             isMatched = key.alg.isNull() || key.alg == ALG256;
         if (key.crv == P384)
             isMatched = key.alg.isNull() || key.alg == ALG384;
+        if (key.crv == P521)
+            isMatched = key.alg.isNull() || key.alg == ALG512;
         if (!isMatched) {
             exceptionCallback(DataError);
             return;

Modified: trunk/Source/WebCore/crypto/gcrypt/CryptoKeyECGCrypt.cpp (222315 => 222316)


--- trunk/Source/WebCore/crypto/gcrypt/CryptoKeyECGCrypt.cpp	2017-09-21 09:33:40 UTC (rev 222315)
+++ trunk/Source/WebCore/crypto/gcrypt/CryptoKeyECGCrypt.cpp	2017-09-21 09:51:47 UTC (rev 222316)
@@ -45,6 +45,8 @@
         return "NIST P-256";
     case CryptoKeyEC::NamedCurve::P384:
         return "NIST P-384";
+    case CryptoKeyEC::NamedCurve::P521:
+        break;
     }
 
     ASSERT_NOT_REACHED();
@@ -58,6 +60,8 @@
         return CryptoConstants::s_secp256r1Identifier.data();
     case CryptoKeyEC::NamedCurve::P384:
         return CryptoConstants::s_secp384r1Identifier.data();
+    case CryptoKeyEC::NamedCurve::P521:
+        break;
     }
 
     ASSERT_NOT_REACHED();
@@ -71,6 +75,8 @@
         return 256;
     case CryptoKeyEC::NamedCurve::P384:
         return 384;
+    case CryptoKeyEC::NamedCurve::P521:
+        break;
     }
 
     ASSERT_NOT_REACHED();
@@ -84,6 +90,8 @@
         return 32;
     case CryptoKeyEC::NamedCurve::P384:
         return 48;
+    case CryptoKeyEC::NamedCurve::P521:
+        break;
     }
 
     ASSERT_NOT_REACHED();
@@ -108,6 +116,11 @@
     return size;
 }
 
+bool CryptoKeyEC::platformSupportedCurve(NamedCurve curve)
+{
+    return curve == NamedCurve::P256 || curve == NamedCurve::P384;
+}
+
 std::optional<CryptoKeyPair> CryptoKeyEC::platformGeneratePair(CryptoAlgorithmIdentifier identifier, NamedCurve curve, bool extractable, CryptoKeyUsageBitmap usages)
 {
     PAL::GCrypt::Handle<gcry_sexp_t> genkeySexp;

Modified: trunk/Source/WebCore/crypto/keys/CryptoKeyEC.cpp (222315 => 222316)


--- trunk/Source/WebCore/crypto/keys/CryptoKeyEC.cpp	2017-09-21 09:33:40 UTC (rev 222315)
+++ trunk/Source/WebCore/crypto/keys/CryptoKeyEC.cpp	2017-09-21 09:51:47 UTC (rev 222316)
@@ -36,6 +36,7 @@
 
 static const char* const P256 = "P-256";
 static const char* const P384 = "P-384";
+static const char* const P521 = "P-521";
 
 static std::optional<CryptoKeyEC::NamedCurve> toNamedCurve(const String& curve)
 {
@@ -43,6 +44,8 @@
         return CryptoKeyEC::NamedCurve::P256;
     if (curve == P384)
         return CryptoKeyEC::NamedCurve::P384;
+    if (curve == P521)
+        return CryptoKeyEC::NamedCurve::P521;
 
     return std::nullopt;
 }
@@ -52,12 +55,14 @@
     , m_platformKey(platformKey)
     , m_curve(curve)
 {
+    // Only CryptoKeyEC objects for supported curves should be created.
+    ASSERT(platformSupportedCurve(curve));
 }
 
 ExceptionOr<CryptoKeyPair> CryptoKeyEC::generatePair(CryptoAlgorithmIdentifier identifier, const String& curve, bool extractable, CryptoKeyUsageBitmap usages)
 {
     auto namedCurve = toNamedCurve(curve);
-    if (!namedCurve)
+    if (!namedCurve || !platformSupportedCurve(*namedCurve))
         return Exception { NotSupportedError };
 
     auto result = platformGeneratePair(identifier, *namedCurve, extractable, usages);
@@ -70,7 +75,7 @@
 RefPtr<CryptoKeyEC> CryptoKeyEC::importRaw(CryptoAlgorithmIdentifier identifier, const String& curve, Vector<uint8_t>&& keyData, bool extractable, CryptoKeyUsageBitmap usages)
 {
     auto namedCurve = toNamedCurve(curve);
-    if (!namedCurve)
+    if (!namedCurve || !platformSupportedCurve(*namedCurve))
         return nullptr;
 
     return platformImportRaw(identifier, *namedCurve, WTFMove(keyData), extractable, usages);
@@ -88,7 +93,7 @@
     if (keyData.crv.isNull() || curve != keyData.crv)
         return nullptr;
     auto namedCurve = toNamedCurve(keyData.crv);
-    if (!namedCurve)
+    if (!namedCurve || !platformSupportedCurve(*namedCurve))
         return nullptr;
 
     if (keyData.x.isNull() || keyData.y.isNull())
@@ -114,7 +119,7 @@
 RefPtr<CryptoKeyEC> CryptoKeyEC::importSpki(CryptoAlgorithmIdentifier identifier, const String& curve, Vector<uint8_t>&& keyData, bool extractable, CryptoKeyUsageBitmap usages)
 {
     auto namedCurve = toNamedCurve(curve);
-    if (!namedCurve)
+    if (!namedCurve || !platformSupportedCurve(*namedCurve))
         return nullptr;
 
     return platformImportSpki(identifier, *namedCurve, WTFMove(keyData), extractable, usages);
@@ -123,7 +128,7 @@
 RefPtr<CryptoKeyEC> CryptoKeyEC::importPkcs8(CryptoAlgorithmIdentifier identifier, const String& curve, Vector<uint8_t>&& keyData, bool extractable, CryptoKeyUsageBitmap usages)
 {
     auto namedCurve = toNamedCurve(curve);
-    if (!namedCurve)
+    if (!namedCurve || !platformSupportedCurve(*namedCurve))
         return nullptr;
 
     return platformImportPkcs8(identifier, *namedCurve, WTFMove(keyData), extractable, usages);
@@ -151,6 +156,9 @@
     case NamedCurve::P384:
         result.crv = P384;
         break;
+    case NamedCurve::P521:
+        result.crv = P521;
+        break;
     }
     result.key_ops = usages();
     result.ext = extractable();
@@ -188,6 +196,8 @@
         return String(P256);
     case NamedCurve::P384:
         return String(P384);
+    case NamedCurve::P521:
+        return String(P521);
     }
 
     ASSERT_NOT_REACHED();
@@ -211,6 +221,9 @@
     case NamedCurve::P384:
         result.namedCurve = ASCIILiteral(P384);
         break;
+    case NamedCurve::P521:
+        result.namedCurve = ASCIILiteral(P521);
+        break;
     }
 
     return result;

Modified: trunk/Source/WebCore/crypto/keys/CryptoKeyEC.h (222315 => 222316)


--- trunk/Source/WebCore/crypto/keys/CryptoKeyEC.h	2017-09-21 09:33:40 UTC (rev 222315)
+++ trunk/Source/WebCore/crypto/keys/CryptoKeyEC.h	2017-09-21 09:51:47 UTC (rev 222316)
@@ -49,10 +49,10 @@
 
 class CryptoKeyEC final : public CryptoKey {
 public:
-    // FIXME: Add support for Elliptic Curve P-521 (https://webkit.org/b/169231)
     enum class NamedCurve {
         P256,
         P384,
+        P521,
     };
 
     static Ref<CryptoKeyEC> create(CryptoAlgorithmIdentifier identifier, NamedCurve curve, CryptoKeyType type, PlatformECKey platformKey, bool extractable, CryptoKeyUsageBitmap usages)
@@ -85,6 +85,7 @@
 
     KeyAlgorithm algorithm() const final;
 
+    static bool platformSupportedCurve(NamedCurve);
     static std::optional<CryptoKeyPair> platformGeneratePair(CryptoAlgorithmIdentifier, NamedCurve, bool extractable, CryptoKeyUsageBitmap);
     static RefPtr<CryptoKeyEC> platformImportRaw(CryptoAlgorithmIdentifier, NamedCurve, Vector<uint8_t>&& keyData, bool extractable, CryptoKeyUsageBitmap);
     static RefPtr<CryptoKeyEC> platformImportJWKPublic(CryptoAlgorithmIdentifier, NamedCurve, Vector<uint8_t>&& x, Vector<uint8_t>&& y, bool extractable, CryptoKeyUsageBitmap);

Modified: trunk/Source/WebCore/crypto/mac/CryptoKeyECMac.cpp (222315 => 222316)


--- trunk/Source/WebCore/crypto/mac/CryptoKeyECMac.cpp	2017-09-21 09:33:40 UTC (rev 222315)
+++ trunk/Source/WebCore/crypto/mac/CryptoKeyECMac.cpp	2017-09-21 09:51:47 UTC (rev 222316)
@@ -56,6 +56,8 @@
         return size == 65;
     case CryptoKeyEC::NamedCurve::P384:
         return size == 97;
+    case CryptoKeyEC::NamedCurve::P521:
+        break;
     }
 
     ASSERT_NOT_REACHED();
@@ -70,6 +72,8 @@
         return size == 32;
     case CryptoKeyEC::NamedCurve::P384:
         return size == 48;
+    case CryptoKeyEC::NamedCurve::P521:
+        break;
     }
 
     ASSERT_NOT_REACHED();
@@ -83,6 +87,8 @@
         return 256;
     case CryptoKeyEC::NamedCurve::P384:
         return 384;
+    case CryptoKeyEC::NamedCurve::P521:
+        break;
     }
 
     ASSERT_NOT_REACHED();
@@ -100,6 +106,11 @@
     return result ? result : 0;
 }
 
+bool CryptoKeyEC::platformSupportedCurve(NamedCurve curve)
+{
+    return curve == NamedCurve::P256 || curve == NamedCurve::P384;
+}
+
 std::optional<CryptoKeyPair> CryptoKeyEC::platformGeneratePair(CryptoAlgorithmIdentifier identifier, NamedCurve curve, bool extractable, CryptoKeyUsageBitmap usages)
 {
     size_t size = getKeySizeFromNamedCurve(curve);
@@ -210,6 +221,12 @@
     case CryptoKeyEC::NamedCurve::P384:
         oid = Secp384r1;
         oidSize = sizeof(Secp384r1);
+        break;
+    case CryptoKeyEC::NamedCurve::P521:
+        ASSERT_NOT_REACHED();
+        oid = nullptr;
+        oidSize = 0;
+        break;
     }
     return oidSize;
 }
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to