1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-11-21 15:04:11 -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:
diachedelic 2022-07-24 03:04:37 +10:00 committed by GitHub
parent 504d2936ec
commit 2843160fc7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 61 additions and 29 deletions

View file

@ -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);
}
});

View file

@ -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 => {