fix(ext/node): implement KeyObject.equals, fix createCipheriv with KeyObject/null IV (#32409)
## Summary
Builds on top of #32267 (must be merged first). Implements
`KeyObject.prototype.equals()` and fixes
`createCipheriv`/`createDecipheriv` to accept `KeyObject` keys and
`null` IVs.
Closes #27211
Closes #27295
Closes #28405
## What changed
### `KeyObject.prototype.equals` (new)
- Added `PartialEq` implementations for all key types in the Rust layer
(`EcPublicKey`, `EcPrivateKey`, `RsaPssPublicKey`, `RsaPssPrivateKey`,
`DhPublicKey`, `DhPrivateKey`, `AsymmetricPublicKey`,
`AsymmetricPrivateKey`, `KeyObjectHandle`)
- Added `op_node_key_equals` op that compares two `KeyObjectHandle`
cppgc references
- Wired up the JS `equals()` method to call the new op instead of
throwing `ERR_NOT_IMPLEMENTED`
### `createCipheriv` / `createDecipheriv` fixes
- `toU8()` in cipher.ts now handles `KeyObject` inputs by extracting
secret key bytes via `op_node_export_secret_key`
- `toU8()` now handles `null` IV (used by ECB mode) by converting to an
empty `Uint8Array`
- This fixes the `@aws-crypto/client-node` crash reported in #28405
### Other fixes
- `symmetricKeySize` now returns **bytes** instead of bits, matching
Node.js behavior
- `symmetricKeySize` returns `undefined` for asymmetric keys instead of
throwing `notImplemented`
- `KeyObject` constructor now validates the `handle` argument type
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>