OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <secerr.h> | 5 #include <secerr.h> |
6 | 6 |
| 7 #include "base/numerics/safe_math.h" |
7 #include "content/child/webcrypto/crypto_data.h" | 8 #include "content/child/webcrypto/crypto_data.h" |
8 #include "content/child/webcrypto/nss/aes_key_nss.h" | 9 #include "content/child/webcrypto/nss/aes_key_nss.h" |
9 #include "content/child/webcrypto/nss/key_nss.h" | 10 #include "content/child/webcrypto/nss/key_nss.h" |
10 #include "content/child/webcrypto/nss/sym_key_nss.h" | 11 #include "content/child/webcrypto/nss/sym_key_nss.h" |
11 #include "content/child/webcrypto/nss/util_nss.h" | 12 #include "content/child/webcrypto/nss/util_nss.h" |
12 #include "content/child/webcrypto/status.h" | 13 #include "content/child/webcrypto/status.h" |
13 #include "content/child/webcrypto/webcrypto_util.h" | 14 #include "content/child/webcrypto/webcrypto_util.h" |
14 #include "crypto/scoped_nss_types.h" | 15 #include "crypto/scoped_nss_types.h" |
15 #include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h" | 16 #include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h" |
16 #include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h" | 17 #include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h" |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
90 PK11SymKey* wrapping_key, | 91 PK11SymKey* wrapping_key, |
91 std::vector<uint8_t>* buffer) { | 92 std::vector<uint8_t>* buffer) { |
92 // The data size must be at least 16 bytes and a multiple of 8 bytes. | 93 // The data size must be at least 16 bytes and a multiple of 8 bytes. |
93 // RFC 3394 does not specify a maximum allowed data length, but since only | 94 // RFC 3394 does not specify a maximum allowed data length, but since only |
94 // keys are being wrapped in this application (which are small), a reasonable | 95 // keys are being wrapped in this application (which are small), a reasonable |
95 // max limit is whatever will fit into an unsigned. For the max size test, | 96 // max limit is whatever will fit into an unsigned. For the max size test, |
96 // note that AES Key Wrap always adds 8 bytes to the input data size. | 97 // note that AES Key Wrap always adds 8 bytes to the input data size. |
97 const unsigned int input_length = PK11_GetKeyLength(key); | 98 const unsigned int input_length = PK11_GetKeyLength(key); |
98 DCHECK_GE(input_length, 16u); | 99 DCHECK_GE(input_length, 16u); |
99 DCHECK((input_length % 8) == 0); | 100 DCHECK((input_length % 8) == 0); |
100 if (input_length > UINT_MAX - 8) | |
101 return Status::ErrorDataTooLarge(); | |
102 | 101 |
103 SECItem iv_item = MakeSECItemForBuffer(CryptoData(kAesIv, sizeof(kAesIv))); | 102 SECItem iv_item = MakeSECItemForBuffer(CryptoData(kAesIv, sizeof(kAesIv))); |
104 crypto::ScopedSECItem param_item( | 103 crypto::ScopedSECItem param_item( |
105 PK11_ParamFromIV(CKM_NSS_AES_KEY_WRAP, &iv_item)); | 104 PK11_ParamFromIV(CKM_NSS_AES_KEY_WRAP, &iv_item)); |
106 if (!param_item) | 105 if (!param_item) |
107 return Status::ErrorUnexpected(); | 106 return Status::ErrorUnexpected(); |
108 | 107 |
109 const unsigned int output_length = input_length + 8; | 108 base::CheckedNumeric<unsigned int> output_length = input_length; |
110 buffer->resize(output_length); | 109 output_length += 8; |
| 110 if (!output_length.IsValid()) |
| 111 return Status::ErrorDataTooLarge(); |
| 112 |
| 113 buffer->resize(output_length.ValueOrDie()); |
111 SECItem wrapped_key_item = MakeSECItemForBuffer(CryptoData(*buffer)); | 114 SECItem wrapped_key_item = MakeSECItemForBuffer(CryptoData(*buffer)); |
112 | 115 |
113 if (SECSuccess != PK11_WrapSymKey(CKM_NSS_AES_KEY_WRAP, | 116 if (SECSuccess != PK11_WrapSymKey(CKM_NSS_AES_KEY_WRAP, |
114 param_item.get(), | 117 param_item.get(), |
115 wrapping_key, | 118 wrapping_key, |
116 key, | 119 key, |
117 &wrapped_key_item)) { | 120 &wrapped_key_item)) { |
118 return Status::OperationError(); | 121 return Status::OperationError(); |
119 } | 122 } |
120 if (output_length != wrapped_key_item.len) | 123 if (output_length.ValueOrDie() != wrapped_key_item.len) |
121 return Status::ErrorUnexpected(); | 124 return Status::ErrorUnexpected(); |
122 | 125 |
123 return Status::Success(); | 126 return Status::Success(); |
124 } | 127 } |
125 | 128 |
126 class AesKwCryptoAlgorithmNss : public AesAlgorithm { | 129 class AesKwCryptoAlgorithmNss : public AesAlgorithm { |
127 public: | 130 public: |
128 AesKwCryptoAlgorithmNss() | 131 AesKwCryptoAlgorithmNss() |
129 : AesAlgorithm( | 132 : AesAlgorithm( |
130 CKM_NSS_AES_KEY_WRAP, | 133 CKM_NSS_AES_KEY_WRAP, |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
194 | 197 |
195 } // namespace | 198 } // namespace |
196 | 199 |
197 AlgorithmImplementation* CreatePlatformAesKwImplementation() { | 200 AlgorithmImplementation* CreatePlatformAesKwImplementation() { |
198 return new AesKwCryptoAlgorithmNss; | 201 return new AesKwCryptoAlgorithmNss; |
199 } | 202 } |
200 | 203 |
201 } // namespace webcrypto | 204 } // namespace webcrypto |
202 | 205 |
203 } // namespace content | 206 } // namespace content |
OLD | NEW |