Index: content/child/webcrypto/platform_crypto_nss.cc |
diff --git a/content/child/webcrypto/platform_crypto_nss.cc b/content/child/webcrypto/platform_crypto_nss.cc |
index 7c3c10b91dcdde04c58b13f9bdc1f00f06214ad9..11c84fc87bbf17018f9c7f58fb0e8646827a4798 100644 |
--- a/content/child/webcrypto/platform_crypto_nss.cc |
+++ b/content/child/webcrypto/platform_crypto_nss.cc |
@@ -584,29 +584,28 @@ Status WebCryptoAlgorithmToNssMechFlags( |
if (*mechanism == CKM_INVALID_MECHANISM) |
return Status::ErrorUnsupported(); |
*flags = CKF_SIGN | CKF_VERIFY; |
- break; |
+ return Status::Success(); |
} |
case blink::WebCryptoAlgorithmIdAesCbc: { |
*mechanism = CKM_AES_CBC; |
*flags = CKF_ENCRYPT | CKF_DECRYPT; |
- break; |
+ return Status::Success(); |
} |
case blink::WebCryptoAlgorithmIdAesKw: { |
*mechanism = CKM_NSS_AES_KEY_WRAP; |
*flags = CKF_WRAP | CKF_WRAP; |
- break; |
+ return Status::Success(); |
} |
case blink::WebCryptoAlgorithmIdAesGcm: { |
if (!g_nss_runtime_support.Get().IsAesGcmSupported()) |
return Status::ErrorUnsupported(); |
*mechanism = CKM_AES_GCM; |
*flags = CKF_ENCRYPT | CKF_DECRYPT; |
- break; |
+ return Status::Success(); |
} |
default: |
return Status::ErrorUnsupported(); |
} |
- return Status::Success(); |
} |
Status DoUnwrapSymKeyAesKw(const CryptoData& wrapped_key_data, |
@@ -883,8 +882,8 @@ Status ImportKeyRaw(const blink::WebCryptoAlgorithm& algorithm, |
blink::WebCryptoKey* key) { |
DCHECK(!algorithm.isNull()); |
- CK_MECHANISM_TYPE mechanism; |
- CK_FLAGS flags; |
+ CK_MECHANISM_TYPE mechanism = CKM_INVALID_MECHANISM; |
+ CK_FLAGS flags = 0; |
Status status = |
WebCryptoAlgorithmToNssMechFlags(algorithm, &mechanism, &flags); |
if (status.IsError()) |
@@ -1764,7 +1763,7 @@ Status ImportRsaPrivateKey(const blink::WebCryptoAlgorithm& algorithm, |
return Status::Success(); |
} |
-Status WrapSymKeyAesKw(SymKey* key, |
+Status WrapSymKeyAesKw(PK11SymKey* key, |
SymKey* wrapping_key, |
std::vector<uint8>* buffer) { |
// The data size must be at least 16 bytes and a multiple of 8 bytes. |
@@ -1772,13 +1771,11 @@ Status WrapSymKeyAesKw(SymKey* key, |
// keys are being wrapped in this application (which are small), a reasonable |
// max limit is whatever will fit into an unsigned. For the max size test, |
// note that AES Key Wrap always adds 8 bytes to the input data size. |
- const unsigned int input_length = PK11_GetKeyLength(key->key()); |
- if (input_length < 16) |
- return Status::ErrorDataTooSmall(); |
+ const unsigned int input_length = PK11_GetKeyLength(key); |
+ DCHECK_GE(input_length, 16u); |
+ DCHECK((input_length % 8) == 0); |
if (input_length > UINT_MAX - 8) |
return Status::ErrorDataTooLarge(); |
- if (input_length % 8) |
- return Status::ErrorInvalidAesKwDataLength(); |
SECItem iv_item = MakeSECItemForBuffer(CryptoData(kAesIv, sizeof(kAesIv))); |
crypto::ScopedSECItem param_item( |
@@ -1793,7 +1790,7 @@ Status WrapSymKeyAesKw(SymKey* key, |
if (SECSuccess != PK11_WrapSymKey(CKM_NSS_AES_KEY_WRAP, |
param_item.get(), |
wrapping_key->key(), |
- key->key(), |
+ key, |
&wrapped_key_item)) { |
return Status::OperationError(); |
} |
@@ -1803,44 +1800,6 @@ Status WrapSymKeyAesKw(SymKey* key, |
return Status::Success(); |
} |
-Status UnwrapSymKeyAesKw(const CryptoData& wrapped_key_data, |
- SymKey* wrapping_key, |
- const blink::WebCryptoAlgorithm& algorithm, |
- bool extractable, |
- blink::WebCryptoKeyUsageMask usage_mask, |
- blink::WebCryptoKey* key) { |
- // Determine the proper NSS key properties from the input algorithm. |
- CK_MECHANISM_TYPE mechanism; |
- CK_FLAGS flags; |
- Status status = |
- WebCryptoAlgorithmToNssMechFlags(algorithm, &mechanism, &flags); |
- if (status.IsError()) |
- return status; |
- |
- crypto::ScopedPK11SymKey unwrapped_key; |
- status = DoUnwrapSymKeyAesKw( |
- wrapped_key_data, wrapping_key, mechanism, flags, &unwrapped_key); |
- if (status.IsError()) |
- return status; |
- |
- blink::WebCryptoKeyAlgorithm key_algorithm; |
- if (!CreateSecretKeyAlgorithm( |
- algorithm, PK11_GetKeyLength(unwrapped_key.get()), &key_algorithm)) |
- return Status::ErrorUnexpected(); |
- |
- scoped_ptr<SymKey> key_handle; |
- status = SymKey::Create(unwrapped_key.Pass(), &key_handle); |
- if (status.IsError()) |
- return status; |
- |
- *key = blink::WebCryptoKey::create(key_handle.release(), |
- blink::WebCryptoKeyTypeSecret, |
- extractable, |
- key_algorithm, |
- usage_mask); |
- return Status::Success(); |
-} |
- |
Status DecryptAesKw(SymKey* wrapping_key, |
const CryptoData& data, |
std::vector<uint8>* buffer) { |
@@ -1864,6 +1823,33 @@ Status DecryptAesKw(SymKey* wrapping_key, |
return Status::Success(); |
} |
+Status EncryptAesKw(SymKey* wrapping_key, |
+ const CryptoData& data, |
+ std::vector<uint8>* buffer) { |
+ // Due to limitations in the NSS API for the AES-KW algorithm, |data| must be |
+ // temporarily viewed as a symmetric key to be wrapped (encrypted). |
+ SECItem data_item = MakeSECItemForBuffer(data); |
+ crypto::ScopedPK11Slot slot(PK11_GetInternalSlot()); |
+ crypto::ScopedPK11SymKey data_as_sym_key(PK11_ImportSymKey(slot.get(), |
+ CKK_GENERIC_SECRET, |
+ PK11_OriginUnwrap, |
+ CKA_SIGN, |
+ &data_item, |
+ NULL)); |
+ if (!data_as_sym_key) |
+ return Status::OperationError(); |
+ |
+ return WrapSymKeyAesKw(data_as_sym_key.get(), wrapping_key, buffer); |
+} |
+ |
+Status EncryptDecryptAesKw(EncryptOrDecrypt mode, |
+ SymKey* wrapping_key, |
+ const CryptoData& data, |
+ std::vector<uint8>* buffer) { |
+ return mode == ENCRYPT ? EncryptAesKw(wrapping_key, data, buffer) |
+ : DecryptAesKw(wrapping_key, data, buffer); |
+} |
+ |
} // namespace platform |
} // namespace webcrypto |