Skip to content
Merged
2 changes: 1 addition & 1 deletion scripts/build/deps/boringssl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

import type { Dependency } from "../source.ts";

const BORINGSSL_COMMIT = "4f4f5ef8ebc6e23cbf393428f0ab1b526773f7ac";
const BORINGSSL_COMMIT = "0c5fce43b7ed5eb6001487ee48ac65766f5ddcd1";

export const boringssl: Dependency = {
name: "boringssl",
Expand Down
9 changes: 5 additions & 4 deletions scripts/verify-baseline-static/allowlist-x64.txt
Original file line number Diff line number Diff line change
Expand Up @@ -584,11 +584,12 @@ rsaz_1024_sqr_avx2 [AVX, AVX2]

# ----------------------------------------------------------------------------
# BoringSSL Curve25519.
# (3 symbols)
# (4 symbols)
# ----------------------------------------------------------------------------
fiat_curve25519_adx_mul [ADX, BMI2]
fiat_curve25519_adx_square [ADX, BMI2]
x25519_scalar_mult_adx [BMI2]
fiat_curve25519_adx_mul [ADX, BMI2]
fiat_curve25519_adx_square [ADX, BMI2]
_ZN4bssl22x25519_scalar_mult_adxEPhPKhS2_ [ADX, BMI2]
_ZN4bssl29x25519_ge_scalarmult_base_adxEPA32_hPKh [ADX, BMI2]


# ----------------------------------------------------------------------------
Expand Down
4 changes: 0 additions & 4 deletions src/bun.js/api/crypto/CryptoHasher.zig
Original file line number Diff line number Diff line change
Expand Up @@ -273,10 +273,6 @@ pub const CryptoHasher = union(enum) {
return CryptoHasher.new(brk: {
if (hmac_key) |*key| {
const chosen_algorithm = try algorithm_name.toEnumFromMap(globalThis, "algorithm", EVP.Algorithm, EVP.Algorithm.map);
if (chosen_algorithm == .ripemd160) {
// crashes at runtime.
return globalThis.throw("ripemd160 is not supported", .{});
}

break :brk .{
.hmac = HMAC.init(chosen_algorithm, key.slice()) orelse {
Expand Down
4 changes: 4 additions & 0 deletions src/bun.js/api/crypto/EVP.zig
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ pub const Algorithm = enum {
.sha512 => BoringSSL.EVP_sha512(),
.@"sha512-224" => BoringSSL.EVP_sha512_224(),
.@"sha512-256" => BoringSSL.EVP_sha512_256(),
.@"sha3-224" => BoringSSL.EVP_sha3_224(),
.@"sha3-256" => BoringSSL.EVP_sha3_256(),
.@"sha3-384" => BoringSSL.EVP_sha3_384(),
.@"sha3-512" => BoringSSL.EVP_sha3_512(),
else => null,
};
}
Expand Down
2 changes: 1 addition & 1 deletion src/bun.js/api/crypto/PBKDF2.zig
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ pub fn fromJS(globalThis: *jsc.JSGlobalObject, callFrame: *jsc.CallFrame, is_asy

invalid: {
switch (try EVP.Algorithm.map.fromJSCaseInsensitive(globalThis, arg4) orelse break :invalid) {
.shake128, .shake256, .@"sha3-224", .@"sha3-256", .@"sha3-384", .@"sha3-512" => break :invalid,
.shake128, .shake256 => break :invalid,
else => |alg| break :brk alg,
}
}
Comment on lines 163 to 169
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟣 Calling pbkdf2Sync('pw', 'salt', 1000, 32, 'blake2s256') panics the Zig runtime because blake2s256 passes the PBKDF2 blocklist check (only .shake128 and .shake256 are blocked) but EVP.Algorithm.md() returns null for it — and PBKDF2.run() force-unwraps that null via .? at line 25. This is a pre-existing bug (blake2s256 was never blocked before this PR either), but this PR modifies the exact switch statement that should also guard it.

Extended reasoning...

What the bug is and how it manifests

blake2s256 is a valid entry in EVP.Algorithm.map (EVP.zig line ~77), so PBKDF2.fromJS resolves it to the .blake2s256 algorithm variant and proceeds past the invalid-algorithm gate. However, EVP.Algorithm.md() only handles .blake2b256 and .blake2b512 in its explicit match arms; .blake2s256 falls through to the else => null branch and returns null. PBKDF2.run() then calls algorithm.md().? (line 25), which force-unwraps an optional null — a Zig runtime panic that crashes the entire process.

The specific code path that triggers it

  1. pbkdf2Sync('pw', 'salt', 1000, 32, 'blake2s256') calls PBKDF2.fromJS.
  2. EVP.Algorithm.map.fromJSCaseInsensitive resolves 'blake2s256' to .blake2s256.
  3. The blocklist switch (lines 163-169, as modified by this PR) only matches .shake128 and .shake256; .blake2s256 falls to the else => |alg| break :brk alg arm and is accepted.
  4. PBKDF2.run() calls algorithm.md().?md() returns null for .blake2s256 — Zig panics.

Why existing code doesn't prevent it

Before this PR, sha3 variants were also listed in the blocklist. The PR correctly removed them (since sha3 now has real EVP implementations). However, blake2s256 was also never blocked, and the modification to this switch statement is the exact right place to also block it. EVP.Algorithm.md() has no blake2s256 case because BoringSSL does not expose an EVP_blake2s256() function (only EVP_blake2b256/EVP_blake2b512 exist in BoringSSL's public API).

Impact

Any call to Node's pbkdf2 / pbkdf2Sync with digest 'blake2s256' will terminate the process with a Zig panic. This is a process-crashing denial-of-service if user-supplied digest names flow into PBKDF2.

How to fix it

Add .blake2s256 to the break :invalid list in PBKDF2.fromJS:

.shake128, .shake256, .blake2s256 => break :invalid,

Alternatively, change PBKDF2.run() to handle a null md() gracefully instead of force-unwrapping.

Step-by-step proof

  1. EVP.Algorithm.map includes "blake2s256" => .blake2s256 — the name resolves successfully.
  2. EVP.Algorithm.md() match arms: .blake2b256, .blake2b512, .md4, ..., .@"sha3-512" — no .blake2s256 case; hits else => null.
  3. PBKDF2.fromJS blocklist: .shake128, .shake256 => break :invalid; .blake2s256 is not listed, falls to else => |alg| break :brk alg.
  4. PBKDF2.run() line 25: algorithm.md().? force-unwraps null → Zig runtime panic, process terminates.

Expand Down
3 changes: 3 additions & 0 deletions src/bun.js/bindings/AsymmetricKeyValue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,9 @@ AsymmetricKeyValue::AsymmetricKeyValue(WebCore::CryptoKey& cryptoKey)
case CryptoAlgorithmIdentifier::SHA_256:
case CryptoAlgorithmIdentifier::SHA_384:
case CryptoAlgorithmIdentifier::SHA_512:
case CryptoAlgorithmIdentifier::SHA3_256:
case CryptoAlgorithmIdentifier::SHA3_384:
case CryptoAlgorithmIdentifier::SHA3_512:
case CryptoAlgorithmIdentifier::HKDF:
case CryptoAlgorithmIdentifier::PBKDF2:
case CryptoAlgorithmIdentifier::None:
Expand Down
23 changes: 22 additions & 1 deletion src/bun.js/bindings/webcore/SerializedScriptValue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -520,9 +520,12 @@ enum class CryptoAlgorithmIdentifierTag {
PBKDF2 = 21,
ED25519 = 22,
X25519 = 23,
SHA3_256 = 24,
SHA3_384 = 25,
SHA3_512 = 26,
};

const uint8_t cryptoAlgorithmIdentifierTagMaximumValue = 22;
const uint8_t cryptoAlgorithmIdentifierTagMaximumValue = 26;

static unsigned countUsages(CryptoKeyUsageBitmap usages)
{
Expand Down Expand Up @@ -2394,6 +2397,15 @@ class CloneSerializer : public CloneBase {
case CryptoAlgorithmIdentifier::SHA_512:
write(CryptoAlgorithmIdentifierTag::SHA_512);
break;
case CryptoAlgorithmIdentifier::SHA3_256:
write(CryptoAlgorithmIdentifierTag::SHA3_256);
break;
case CryptoAlgorithmIdentifier::SHA3_384:
write(CryptoAlgorithmIdentifierTag::SHA3_384);
break;
case CryptoAlgorithmIdentifier::SHA3_512:
write(CryptoAlgorithmIdentifierTag::SHA3_512);
break;
case CryptoAlgorithmIdentifier::HKDF:
write(CryptoAlgorithmIdentifierTag::HKDF);
break;
Expand Down Expand Up @@ -3880,6 +3892,15 @@ class CloneDeserializer : public CloneBase {
case CryptoAlgorithmIdentifierTag::SHA_512:
result = CryptoAlgorithmIdentifier::SHA_512;
break;
case CryptoAlgorithmIdentifierTag::SHA3_256:
result = CryptoAlgorithmIdentifier::SHA3_256;
break;
case CryptoAlgorithmIdentifierTag::SHA3_384:
result = CryptoAlgorithmIdentifier::SHA3_384;
break;
case CryptoAlgorithmIdentifierTag::SHA3_512:
result = CryptoAlgorithmIdentifier::SHA3_512;
break;
case CryptoAlgorithmIdentifierTag::HKDF:
result = CryptoAlgorithmIdentifier::HKDF;
break;
Expand Down
8 changes: 8 additions & 0 deletions src/bun.js/bindings/webcrypto/CryptoAlgorithmHMAC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,10 @@ void CryptoAlgorithmHMAC::importKey(CryptoKeyFormat format, KeyData&& data, cons
return alg.isNull() || alg == ALG384;
case CryptoAlgorithmIdentifier::SHA_512:
return alg.isNull() || alg == ALG512;
case CryptoAlgorithmIdentifier::SHA3_256:
case CryptoAlgorithmIdentifier::SHA3_384:
case CryptoAlgorithmIdentifier::SHA3_512:
return alg.isNull();
default:
return false;
}
Comment on lines 125 to 134
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 When exporting an HMAC-SHA3-256/384/512 key as JWK, no alg field is emitted (the switch in exportKey falls through with a bare break at lines 182-188 of CryptoAlgorithmHMAC.cpp), and the import checkAlgCallback at lines 125-131 accepts any SHA3 JWK whenever alg is null — so a SHA3-256 key exported to JWK can be silently re-imported as SHA3-512. The JWK roundtrip is lossy with respect to the hash variant; consider throwing NotSupportedError for SHA3 HMAC JWK export/import, or documenting that JWK does not preserve the SHA3 hash variant.

Extended reasoning...

What the bug is and how it manifests

When exportKey('jwk', hmacSha3Key) is called, CryptoAlgorithmHMAC.cpp lines 182-188 match all three SHA3 variants and execute a bare break without setting jwk.alg. This is intentional — no IANA-registered JWK alg identifiers exist for HMAC-SHA3. The exported JWK therefore looks like {kty:'oct', k:'...'} with no alg field for any SHA3 variant.

The specific code path that triggers it

During importKey('jwk', jwkData, {name:'HMAC', hash:'SHA3-512'}), the code reaches CryptoKeyHMAC::importJwk which calls the checkAlgCallback lambda at lines 125-131. For all three SHA3 identifiers the callback returns alg.isNull(). Since the exported JWK never sets alg regardless of which SHA3 variant was used, alg.isNull() is always true — the check passes silently. The import then proceeds with SHA3_512 as the hash but with the key material of the original SHA3-256 key.

Why existing code does not prevent it

For SHA-2 HMAC, exportKey always sets jwk.alg to a specific string (HS256, HS384, etc.), and the import callback verifies alg == 'HS512' (for example). Cross-variant confusion is rejected at import time. For SHA3, no analogous IANA-registered alg string exists, so the export produces no alg field and the import check is reduced to the vacuous alg.isNull() condition — which is true for all SHA3 export JWKs and therefore cannot distinguish between variants.

What the impact would be

The JWK roundtrip does not preserve the SHA3 hash variant. A developer who exports a SHA3-256 HMAC key, transmits the JWK, and re-imports it with hash:'SHA3-512' will get an HMAC-SHA3-512 key backed by 32-byte key material without any error. HMAC values computed with the original key will not match those from the re-imported key, silently breaking correctness guarantees.

Step-by-step proof

  1. const key256 = await crypto.subtle.generateKey({name:'HMAC', hash:'SHA3-256'}, true, ['sign','verify']); — creates a SHA3-256 HMAC key (default 1088 bits per CryptoKeyHMAC.cpp line 46, i.e. 136 bytes).
  2. const jwk = await crypto.subtle.exportKey('jwk', key256); — the switch in exportKey hits SHA3_256 case at line 182 and breaks; jwk.alg is never set (null/absent).
  3. const key512 = await crypto.subtle.importKey('jwk', jwk, {name:'HMAC', hash:'SHA3-512'}, true, ['sign','verify']); — importJwk calls checkAlgCallback(SHA3_512, null_string); the case at line 128 returns alg.isNull() == true; import succeeds.
  4. key512 is now an HMAC-SHA3-512 key backed by the 136-byte key material of the original SHA3-256 key — wrong variant, no error.

How to fix it

Option A (clean): Return NotSupportedError from exportKey and importKey for SHA3 HMAC in JWK format, making the limitation explicit and consistent with the existing rejection of SHA3 as a standalone importKey algorithm in SubtleCrypto.cpp lines 381-387.

Option B (best-effort): Emit a non-standard alg string (e.g. HS3-256) and verify it in the import callback, preventing cross-variant confusion at the cost of interoperability with other implementations that follow the JWK spec strictly.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This matches Node.js's webcrypto behavior:

> const k = await crypto.subtle.generateKey({name:"HMAC",hash:"SHA3-256",length:256},true,["sign"])
> (await crypto.subtle.exportKey("jwk", k)).alg
undefined

There's no IETF-registered JWK alg value for HMAC-SHA3 or RSA-SHA3, so omitting it is the only correct behavior — emitting a made-up identifier would break import in other implementations. The hash variant must be supplied at import time, same as it would be for an alg-less JWK from any source. Throwing on export would make the feature useless for key persistence with no real safety benefit (re-importing with wrong hash → wrong-size signatures → fails immediately on first verify, not silent corruption).

Expand Down Expand Up @@ -178,6 +182,10 @@ void CryptoAlgorithmHMAC::exportKey(CryptoKeyFormat format, Ref<CryptoKey>&& key
case CryptoAlgorithmIdentifier::SHA_512:
jwk.alg = String(ALG512);
break;
case CryptoAlgorithmIdentifier::SHA3_256:
case CryptoAlgorithmIdentifier::SHA3_384:
case CryptoAlgorithmIdentifier::SHA3_512:
break;
default:
ASSERT_NOT_REACHED();
}
Expand Down
3 changes: 3 additions & 0 deletions src/bun.js/bindings/webcrypto/CryptoAlgorithmIdentifier.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ enum class CryptoAlgorithmIdentifier : uint8_t {
SHA_256,
SHA_384,
SHA_512,
SHA3_256,
SHA3_384,
SHA3_512,
HKDF,
PBKDF2,
Ed25519,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,11 @@ void CryptoAlgorithmRSASSA_PKCS1_v1_5::importKey(CryptoKeyFormat format, KeyData
case CryptoAlgorithmIdentifier::SHA_512:
isMatched = key.alg.isNull() || key.alg == ALG512;
break;
case CryptoAlgorithmIdentifier::SHA3_256:
case CryptoAlgorithmIdentifier::SHA3_384:
case CryptoAlgorithmIdentifier::SHA3_512:
isMatched = key.alg.isNull();
break;
default:
break;
}
Expand Down Expand Up @@ -208,6 +213,10 @@ void CryptoAlgorithmRSASSA_PKCS1_v1_5::exportKey(CryptoKeyFormat format, Ref<Cry
case CryptoAlgorithmIdentifier::SHA_512:
jwk.alg = String(ALG512);
break;
case CryptoAlgorithmIdentifier::SHA3_256:
case CryptoAlgorithmIdentifier::SHA3_384:
case CryptoAlgorithmIdentifier::SHA3_512:
break;
default:
ASSERT_NOT_REACHED();
}
Expand Down
9 changes: 9 additions & 0 deletions src/bun.js/bindings/webcrypto/CryptoAlgorithmRSA_OAEP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,11 @@ void CryptoAlgorithmRSA_OAEP::importKey(CryptoKeyFormat format, KeyData&& data,
case CryptoAlgorithmIdentifier::SHA_512:
isMatched = key.alg.isNull() || key.alg == ALG512;
break;
case CryptoAlgorithmIdentifier::SHA3_256:
case CryptoAlgorithmIdentifier::SHA3_384:
case CryptoAlgorithmIdentifier::SHA3_512:
isMatched = key.alg.isNull();
break;
default:
break;
}
Expand Down Expand Up @@ -222,6 +227,10 @@ void CryptoAlgorithmRSA_OAEP::exportKey(CryptoKeyFormat format, Ref<CryptoKey>&&
case CryptoAlgorithmIdentifier::SHA_512:
jwk.alg = String(ALG512);
break;
case CryptoAlgorithmIdentifier::SHA3_256:
case CryptoAlgorithmIdentifier::SHA3_384:
case CryptoAlgorithmIdentifier::SHA3_512:
break;
default:
ASSERT_NOT_REACHED();
}
Expand Down
9 changes: 9 additions & 0 deletions src/bun.js/bindings/webcrypto/CryptoAlgorithmRSA_PSS.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,11 @@ void CryptoAlgorithmRSA_PSS::importKey(CryptoKeyFormat format, KeyData&& data, c
case CryptoAlgorithmIdentifier::SHA_512:
isMatched = key.alg.isNull() || key.alg == ALG512;
break;
case CryptoAlgorithmIdentifier::SHA3_256:
case CryptoAlgorithmIdentifier::SHA3_384:
case CryptoAlgorithmIdentifier::SHA3_512:
isMatched = key.alg.isNull();
break;
default:
break;
}
Expand Down Expand Up @@ -210,6 +215,10 @@ void CryptoAlgorithmRSA_PSS::exportKey(CryptoKeyFormat format, Ref<CryptoKey>&&
case CryptoAlgorithmIdentifier::SHA_512:
jwk.alg = String(ALG512);
break;
case CryptoAlgorithmIdentifier::SHA3_256:
case CryptoAlgorithmIdentifier::SHA3_384:
case CryptoAlgorithmIdentifier::SHA3_512:
break;
default:
ASSERT_NOT_REACHED();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
#include "CryptoAlgorithmSHA256.h"
#include "CryptoAlgorithmSHA384.h"
#include "CryptoAlgorithmSHA512.h"
#include "CryptoAlgorithmSHA3.h"
#include "CryptoAlgorithmX25519.h"

namespace WebCore {
Expand All @@ -73,6 +74,9 @@ void CryptoAlgorithmRegistry::platformRegisterAlgorithms()
registerAlgorithmWithAlternativeName<CryptoAlgorithmSHA256>();
registerAlgorithmWithAlternativeName<CryptoAlgorithmSHA384>();
registerAlgorithmWithAlternativeName<CryptoAlgorithmSHA512>();
registerAlgorithm<CryptoAlgorithmSHA3_256>();
registerAlgorithm<CryptoAlgorithmSHA3_384>();
registerAlgorithm<CryptoAlgorithmSHA3_512>();
registerAlgorithm<CryptoAlgorithmEd25519>();
registerAlgorithm<CryptoAlgorithmX25519>();
}
Expand Down
90 changes: 90 additions & 0 deletions src/bun.js/bindings/webcrypto/CryptoAlgorithmSHA3.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/*
* Copyright (C) 2024 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/

#include "config.h"
#include "CryptoAlgorithmSHA3.h"

#if ENABLE(WEB_CRYPTO)

#include "CryptoDigest.h"
#include "ScriptExecutionContext.h"

namespace WebCore {

static void dispatchDigest(PAL::CryptoDigest::Algorithm algorithm,
Vector<uint8_t>&& message, CryptoAlgorithm::VectorCallback&& callback,
CryptoAlgorithm::ExceptionCallback&& exceptionCallback,
ScriptExecutionContext& context, WorkQueue& workQueue)
{
auto digest = PAL::CryptoDigest::create(algorithm);
if (!digest) {
exceptionCallback(OperationError, ""_s);
return;
}

if (message.size() < 64) {
auto moved = WTF::move(message);
digest->addBytes(moved.begin(), moved.size());
auto result = digest->computeHash();
ScriptExecutionContext::postTaskTo(context.identifier(),
[callback = WTF::move(callback), result = WTF::move(result)](auto&) {
callback(result);
});
return;
}

workQueue.dispatch(context.globalObject(),
[digest = WTF::move(digest), message = WTF::move(message),
callback = WTF::move(callback),
contextIdentifier = context.identifier()]() mutable {
digest->addBytes(message.begin(), message.size());
auto result = digest->computeHash();
ScriptExecutionContext::postTaskTo(contextIdentifier,
[callback = WTF::move(callback), result = WTF::move(result)](auto&) {
callback(result);
});
});
}

#define DEFINE_SHA3(ClassName, DigestAlgo) \
Ref<CryptoAlgorithm> ClassName::create() { return adoptRef(*new ClassName); } \
CryptoAlgorithmIdentifier ClassName::identifier() const { return s_identifier; } \
void ClassName::digest(Vector<uint8_t>&& message, VectorCallback&& callback, \
ExceptionCallback&& exceptionCallback, ScriptExecutionContext& context, \
WorkQueue& workQueue) \
{ \
dispatchDigest(DigestAlgo, WTF::move(message), WTF::move(callback), \
WTF::move(exceptionCallback), context, workQueue); \
}

DEFINE_SHA3(CryptoAlgorithmSHA3_256, PAL::CryptoDigest::Algorithm::SHA3_256)
DEFINE_SHA3(CryptoAlgorithmSHA3_384, PAL::CryptoDigest::Algorithm::SHA3_384)
DEFINE_SHA3(CryptoAlgorithmSHA3_512, PAL::CryptoDigest::Algorithm::SHA3_512)

#undef DEFINE_SHA3

} // namespace WebCore

#endif // ENABLE(WEB_CRYPTO)
72 changes: 72 additions & 0 deletions src/bun.js/bindings/webcrypto/CryptoAlgorithmSHA3.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/*
* Copyright (C) 2024 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/

#pragma once

#if ENABLE(WEB_CRYPTO)

#include "CryptoAlgorithm.h"

namespace WebCore {

class CryptoAlgorithmSHA3_256 final : public CryptoAlgorithm {
public:
static constexpr ASCIILiteral s_name = "SHA3-256"_s;
static constexpr CryptoAlgorithmIdentifier s_identifier = CryptoAlgorithmIdentifier::SHA3_256;
static Ref<CryptoAlgorithm> create();

private:
CryptoAlgorithmSHA3_256() = default;
CryptoAlgorithmIdentifier identifier() const final;
void digest(Vector<uint8_t>&&, VectorCallback&&, ExceptionCallback&&, ScriptExecutionContext&, WorkQueue&) final;
};

class CryptoAlgorithmSHA3_384 final : public CryptoAlgorithm {
public:
static constexpr ASCIILiteral s_name = "SHA3-384"_s;
static constexpr CryptoAlgorithmIdentifier s_identifier = CryptoAlgorithmIdentifier::SHA3_384;
static Ref<CryptoAlgorithm> create();

private:
CryptoAlgorithmSHA3_384() = default;
CryptoAlgorithmIdentifier identifier() const final;
void digest(Vector<uint8_t>&&, VectorCallback&&, ExceptionCallback&&, ScriptExecutionContext&, WorkQueue&) final;
};

class CryptoAlgorithmSHA3_512 final : public CryptoAlgorithm {
public:
static constexpr ASCIILiteral s_name = "SHA3-512"_s;
static constexpr CryptoAlgorithmIdentifier s_identifier = CryptoAlgorithmIdentifier::SHA3_512;
static Ref<CryptoAlgorithm> create();

private:
CryptoAlgorithmSHA3_512() = default;
CryptoAlgorithmIdentifier identifier() const final;
void digest(Vector<uint8_t>&&, VectorCallback&&, ExceptionCallback&&, ScriptExecutionContext&, WorkQueue&) final;
};

} // namespace WebCore

#endif // ENABLE(WEB_CRYPTO)
Loading
Loading