mirror of
https://github.com/denoland/deno.git
synced 2024-11-25 15:29:32 -05:00
feat(ext/crypto): deriveBits P-384 (#15138)
This commit adds P-384 curve support for crypto.subtle.deriveBits. Co-authored-by: James Diacono <james@diacono.com.au>
This commit is contained in:
parent
504d2936ec
commit
2843160fc7
2 changed files with 61 additions and 29 deletions
|
@ -716,27 +716,28 @@ Deno.test(async function testAesCtrEncryptDecrypt() {
|
|||
});
|
||||
|
||||
Deno.test(async function testECDH() {
|
||||
const namedCurve = "P-256";
|
||||
const keyPair = await crypto.subtle.generateKey(
|
||||
{
|
||||
name: "ECDH",
|
||||
namedCurve,
|
||||
},
|
||||
true,
|
||||
["deriveBits"],
|
||||
);
|
||||
for (const keySize of [256, 384]) {
|
||||
const keyPair = await crypto.subtle.generateKey(
|
||||
{
|
||||
name: "ECDH",
|
||||
namedCurve: "P-" + keySize,
|
||||
},
|
||||
true,
|
||||
["deriveBits"],
|
||||
);
|
||||
|
||||
const derivedKey = await crypto.subtle.deriveBits(
|
||||
{
|
||||
name: "ECDH",
|
||||
public: keyPair.publicKey,
|
||||
},
|
||||
keyPair.privateKey,
|
||||
256,
|
||||
);
|
||||
const derivedKey = await crypto.subtle.deriveBits(
|
||||
{
|
||||
name: "ECDH",
|
||||
public: keyPair.publicKey,
|
||||
},
|
||||
keyPair.privateKey,
|
||||
keySize,
|
||||
);
|
||||
|
||||
assert(derivedKey instanceof ArrayBuffer);
|
||||
assertEquals(derivedKey.byteLength, 256 / 8);
|
||||
assert(derivedKey instanceof ArrayBuffer);
|
||||
assertEquals(derivedKey.byteLength, keySize / 8);
|
||||
}
|
||||
});
|
||||
|
||||
Deno.test(async function testWrapKey() {
|
||||
|
@ -1299,22 +1300,17 @@ Deno.test(async function testImportEcDhJwk() {
|
|||
);
|
||||
assert(equalJwk(publicJWK, expPublicKeyJWK as JWK));
|
||||
|
||||
// deriveBits still not implemented for P384
|
||||
if (size != 256) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const derivedKey = await subtle.deriveBits(
|
||||
{
|
||||
name: "ECDH",
|
||||
public: publicKeyECDH,
|
||||
},
|
||||
privateKeyECDH,
|
||||
256,
|
||||
size,
|
||||
);
|
||||
|
||||
assert(derivedKey instanceof ArrayBuffer);
|
||||
assertEquals(derivedKey.byteLength, 256 / 8);
|
||||
assertEquals(derivedKey.byteLength, size / 8);
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -556,9 +556,45 @@ pub async fn op_crypto_derive_bits(
|
|||
// raw serialized x-coordinate of the computed point
|
||||
Ok(shared_secret.raw_secret_bytes().to_vec().into())
|
||||
}
|
||||
// TODO(@littledivy): support for P384
|
||||
// https://github.com/RustCrypto/elliptic-curves/issues/240
|
||||
_ => Err(type_error("Unsupported namedCurve".to_string())),
|
||||
CryptoNamedCurve::P384 => {
|
||||
let secret_key = p384::SecretKey::from_pkcs8_der(&args.key.data)
|
||||
.map_err(|_| type_error("Unexpected error decoding private key"))?;
|
||||
|
||||
let public_key = match public_key.r#type {
|
||||
KeyType::Private => {
|
||||
p384::SecretKey::from_pkcs8_der(&public_key.data)
|
||||
.map_err(|_| {
|
||||
type_error("Unexpected error decoding private key")
|
||||
})?
|
||||
.public_key()
|
||||
}
|
||||
KeyType::Public => {
|
||||
let point = p384::EncodedPoint::from_bytes(public_key.data)
|
||||
.map_err(|_| {
|
||||
type_error("Unexpected error decoding private key")
|
||||
})?;
|
||||
|
||||
let pk = p384::PublicKey::from_encoded_point(&point);
|
||||
// pk is a constant time Option.
|
||||
if pk.is_some().into() {
|
||||
pk.unwrap()
|
||||
} else {
|
||||
return Err(type_error(
|
||||
"Unexpected error decoding private key",
|
||||
));
|
||||
}
|
||||
}
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
let shared_secret = p384::elliptic_curve::ecdh::diffie_hellman(
|
||||
secret_key.to_nonzero_scalar(),
|
||||
public_key.as_affine(),
|
||||
);
|
||||
|
||||
// raw serialized x-coordinate of the computed point
|
||||
Ok(shared_secret.raw_secret_bytes().to_vec().into())
|
||||
}
|
||||
}
|
||||
}
|
||||
Algorithm::Hkdf => {
|
||||
|
|
Loading…
Reference in a new issue