Changeset 222316 in webkit


Ignore:
Timestamp:
Sep 21, 2017 2:51:47 AM (7 years ago)
Author:
zandobersek@gmail.com
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):

Location:
trunk/Source/WebCore
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r222314 r222316  
     12017-09-21  Zan Dobersek  <zdobersek@igalia.com>
     2
     3        [WebCrypto] Support Elliptic Curve P-521
     4        https://bugs.webkit.org/show_bug.cgi?id=169231
     5        <rdar://problem/30881703>
     6
     7        Reviewed by Jiewen Tan.
     8
     9        Add support for the P-521 elliptic curve to the CryptoKeyEC class, but
     10        allow the underlying platform-specific implementations to opt out of
     11        supporting this feature.
     12
     13        This is achieved with the platformSupportedCurve() static function that
     14        each platform has to implement, returning true if the passed-in curve
     15        type is supported. The function is called at each CryptoKeyEC entrypoint,
     16        that is in each static function that could generate a new CryptoKeyEC
     17        object. These functions return a NotSupportedError exception in case the
     18        platformSupportedCurve() call returns false.
     19
     20        While the libgcrypt-based implementation will support P-521 curves in
     21        the near future, the CommonCrypto-based implementation might not. The use
     22        of platformSupportedCurve() ensures that the implementations that don't
     23        support EC P-521 continue to return the NotSupportedError exception at
     24        these entrypoints, instead of the OperationError exception that's returned
     25        when the platform-specific extensions of these entrypoints fail due to the
     26        specified elliptic curve not being supported.
     27
     28        Both libgcrypt-based and CommonCrypto-based implementations mark P-256 and
     29        P-384 curves as supported. Switch statements handling NamedCurve values
     30        must now also handle the NamedCurve::P521 value, but both implementations
     31        treat that as an unreachable case since support is not indicated in
     32        platformSupportedCurve(), and all CryptoKeyEC operations should have
     33        returned with an NotSupportedError exception before entering
     34        platform-specific code. The common CryptoKeyEC constructor similarly asserts
     35        that the specified curve is supported by the underlying implementation.
     36
     37        CryptoAlgorithmECDSA is modified to now also support 'ES512' as the algorithm
     38        identifier, matching it against the 'P-521' curve value.
     39
     40        No new tests -- tests covering EC P-521 already exist, but no platform
     41        runs them yet due to missing implementations.
     42
     43        * crypto/algorithms/CryptoAlgorithmECDSA.cpp:
     44        (WebCore::CryptoAlgorithmECDSA::importKey):
     45        * crypto/gcrypt/CryptoKeyECGCrypt.cpp:
     46        (WebCore::curveName):
     47        (WebCore::curveIdentifier):
     48        (WebCore::curveSize):
     49        (WebCore::curveUncompressedFieldElementSize):
     50        (WebCore::CryptoKeyEC::platformSupportedCurve):
     51        * crypto/keys/CryptoKeyEC.cpp:
     52        (WebCore::toNamedCurve):
     53        (WebCore::CryptoKeyEC::CryptoKeyEC):
     54        (WebCore::CryptoKeyEC::generatePair):
     55        (WebCore::CryptoKeyEC::importRaw):
     56        (WebCore::CryptoKeyEC::importJwk):
     57        (WebCore::CryptoKeyEC::importSpki):
     58        (WebCore::CryptoKeyEC::importPkcs8):
     59        (WebCore::CryptoKeyEC::exportJwk const):
     60        (WebCore::CryptoKeyEC::namedCurveString const):
     61        (WebCore::CryptoKeyEC::algorithm const):
     62        * crypto/keys/CryptoKeyEC.h:
     63        * crypto/mac/CryptoKeyECMac.cpp:
     64        (WebCore::doesUncompressedPointMatchNamedCurve):
     65        (WebCore::doesFieldElementMatchNamedCurve):
     66        (WebCore::getKeySizeFromNamedCurve):
     67        (WebCore::CryptoKeyEC::platformSupportedCurve):
     68        (WebCore::getOID):
     69
    1702017-09-20  Antti Koivisto  <antti@apple.com>
    271
  • trunk/Source/WebCore/crypto/algorithms/CryptoAlgorithmECDSA.cpp

    r221665 r222316  
    3737static const char* const ALG256 = "ES256";
    3838static const char* const ALG384 = "ES384";
     39static const char* const ALG512 = "ES512";
    3940static const char* const P256 = "P-256";
    4041static const char* const P384 = "P-384";
     42static const char* const P521 = "P-521";
    4143
    4244Ref<CryptoAlgorithm> CryptoAlgorithmECDSA::create()
     
    121123        if (key.crv == P384)
    122124            isMatched = key.alg.isNull() || key.alg == ALG384;
     125        if (key.crv == P521)
     126            isMatched = key.alg.isNull() || key.alg == ALG512;
    123127        if (!isMatched) {
    124128            exceptionCallback(DataError);
  • trunk/Source/WebCore/crypto/gcrypt/CryptoKeyECGCrypt.cpp

    r220933 r222316  
    4646    case CryptoKeyEC::NamedCurve::P384:
    4747        return "NIST P-384";
     48    case CryptoKeyEC::NamedCurve::P521:
     49        break;
    4850    }
    4951
     
    5961    case CryptoKeyEC::NamedCurve::P384:
    6062        return CryptoConstants::s_secp384r1Identifier.data();
     63    case CryptoKeyEC::NamedCurve::P521:
     64        break;
    6165    }
    6266
     
    7276    case CryptoKeyEC::NamedCurve::P384:
    7377        return 384;
     78    case CryptoKeyEC::NamedCurve::P521:
     79        break;
    7480    }
    7581
     
    8591    case CryptoKeyEC::NamedCurve::P384:
    8692        return 48;
     93    case CryptoKeyEC::NamedCurve::P521:
     94        break;
    8795    }
    8896
     
    107115    ASSERT(size == gcry_pk_get_nbits(m_platformKey));
    108116    return size;
     117}
     118
     119bool CryptoKeyEC::platformSupportedCurve(NamedCurve curve)
     120{
     121    return curve == NamedCurve::P256 || curve == NamedCurve::P384;
    109122}
    110123
  • trunk/Source/WebCore/crypto/keys/CryptoKeyEC.cpp

    r220954 r222316  
    3737static const char* const P256 = "P-256";
    3838static const char* const P384 = "P-384";
     39static const char* const P521 = "P-521";
    3940
    4041static std::optional<CryptoKeyEC::NamedCurve> toNamedCurve(const String& curve)
     
    4445    if (curve == P384)
    4546        return CryptoKeyEC::NamedCurve::P384;
     47    if (curve == P521)
     48        return CryptoKeyEC::NamedCurve::P521;
    4649
    4750    return std::nullopt;
     
    5356    , m_curve(curve)
    5457{
     58    // Only CryptoKeyEC objects for supported curves should be created.
     59    ASSERT(platformSupportedCurve(curve));
    5560}
    5661
     
    5863{
    5964    auto namedCurve = toNamedCurve(curve);
    60     if (!namedCurve)
     65    if (!namedCurve || !platformSupportedCurve(*namedCurve))
    6166        return Exception { NotSupportedError };
    6267
     
    7176{
    7277    auto namedCurve = toNamedCurve(curve);
    73     if (!namedCurve)
     78    if (!namedCurve || !platformSupportedCurve(*namedCurve))
    7479        return nullptr;
    7580
     
    8994        return nullptr;
    9095    auto namedCurve = toNamedCurve(keyData.crv);
    91     if (!namedCurve)
     96    if (!namedCurve || !platformSupportedCurve(*namedCurve))
    9297        return nullptr;
    9398
     
    115120{
    116121    auto namedCurve = toNamedCurve(curve);
    117     if (!namedCurve)
     122    if (!namedCurve || !platformSupportedCurve(*namedCurve))
    118123        return nullptr;
    119124
     
    124129{
    125130    auto namedCurve = toNamedCurve(curve);
    126     if (!namedCurve)
     131    if (!namedCurve || !platformSupportedCurve(*namedCurve))
    127132        return nullptr;
    128133
     
    152157        result.crv = P384;
    153158        break;
     159    case NamedCurve::P521:
     160        result.crv = P521;
     161        break;
    154162    }
    155163    result.key_ops = usages();
     
    189197    case NamedCurve::P384:
    190198        return String(P384);
     199    case NamedCurve::P521:
     200        return String(P521);
    191201    }
    192202
     
    212222        result.namedCurve = ASCIILiteral(P384);
    213223        break;
     224    case NamedCurve::P521:
     225        result.namedCurve = ASCIILiteral(P521);
     226        break;
    214227    }
    215228
  • trunk/Source/WebCore/crypto/keys/CryptoKeyEC.h

    r221293 r222316  
    5050class CryptoKeyEC final : public CryptoKey {
    5151public:
    52     // FIXME: Add support for Elliptic Curve P-521 (https://webkit.org/b/169231)
    5352    enum class NamedCurve {
    5453        P256,
    5554        P384,
     55        P521,
    5656    };
    5757
     
    8686    KeyAlgorithm algorithm() const final;
    8787
     88    static bool platformSupportedCurve(NamedCurve);
    8889    static std::optional<CryptoKeyPair> platformGeneratePair(CryptoAlgorithmIdentifier, NamedCurve, bool extractable, CryptoKeyUsageBitmap);
    8990    static RefPtr<CryptoKeyEC> platformImportRaw(CryptoAlgorithmIdentifier, NamedCurve, Vector<uint8_t>&& keyData, bool extractable, CryptoKeyUsageBitmap);
  • trunk/Source/WebCore/crypto/mac/CryptoKeyECMac.cpp

    r220933 r222316  
    5757    case CryptoKeyEC::NamedCurve::P384:
    5858        return size == 97;
     59    case CryptoKeyEC::NamedCurve::P521:
     60        break;
    5961    }
    6062
     
    7173    case CryptoKeyEC::NamedCurve::P384:
    7274        return size == 48;
     75    case CryptoKeyEC::NamedCurve::P521:
     76        break;
    7377    }
    7478
     
    8488    case CryptoKeyEC::NamedCurve::P384:
    8589        return 384;
     90    case CryptoKeyEC::NamedCurve::P521:
     91        break;
    8692    }
    8793
     
    99105    int result = CCECGetKeySize(m_platformKey);
    100106    return result ? result : 0;
     107}
     108
     109bool CryptoKeyEC::platformSupportedCurve(NamedCurve curve)
     110{
     111    return curve == NamedCurve::P256 || curve == NamedCurve::P384;
    101112}
    102113
     
    211222        oid = Secp384r1;
    212223        oidSize = sizeof(Secp384r1);
     224        break;
     225    case CryptoKeyEC::NamedCurve::P521:
     226        ASSERT_NOT_REACHED();
     227        oid = nullptr;
     228        oidSize = 0;
     229        break;
    213230    }
    214231    return oidSize;
Note: See TracChangeset for help on using the changeset viewer.