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 "base/numerics/safe_math.h" |
5 #include "content/child/webcrypto/crypto_data.h" | 6 #include "content/child/webcrypto/crypto_data.h" |
6 #include "content/child/webcrypto/nss/aes_key_nss.h" | 7 #include "content/child/webcrypto/nss/aes_key_nss.h" |
7 #include "content/child/webcrypto/nss/key_nss.h" | 8 #include "content/child/webcrypto/nss/key_nss.h" |
8 #include "content/child/webcrypto/nss/util_nss.h" | 9 #include "content/child/webcrypto/nss/util_nss.h" |
9 #include "content/child/webcrypto/status.h" | 10 #include "content/child/webcrypto/status.h" |
10 #include "content/child/webcrypto/webcrypto_util.h" | 11 #include "content/child/webcrypto/webcrypto_util.h" |
11 #include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h" | 12 #include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h" |
12 | 13 |
13 // At the time of this writing: | 14 // At the time of this writing: |
14 // * Windows and Mac builds ship with their own copy of NSS (3.15+) | 15 // * Windows and Mac builds ship with their own copy of NSS (3.15+) |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
82 gcm_params.pAAD = const_cast<unsigned char*>(additional_data.bytes()); | 83 gcm_params.pAAD = const_cast<unsigned char*>(additional_data.bytes()); |
83 gcm_params.ulAADLen = additional_data.byte_length(); | 84 gcm_params.ulAADLen = additional_data.byte_length(); |
84 | 85 |
85 gcm_params.ulTagBits = tag_length_bits; | 86 gcm_params.ulTagBits = tag_length_bits; |
86 | 87 |
87 SECItem param; | 88 SECItem param; |
88 param.type = siBuffer; | 89 param.type = siBuffer; |
89 param.data = reinterpret_cast<unsigned char*>(&gcm_params); | 90 param.data = reinterpret_cast<unsigned char*>(&gcm_params); |
90 param.len = sizeof(gcm_params); | 91 param.len = sizeof(gcm_params); |
91 | 92 |
92 unsigned int buffer_size = 0; | 93 base::CheckedNumeric<unsigned int> buffer_size(data.byte_length()); |
93 | 94 |
94 // Calculate the output buffer size. | 95 // Calculate the output buffer size. |
95 if (mode == ENCRYPT) { | 96 if (mode == ENCRYPT) { |
96 // TODO(eroman): This is ugly, abstract away the safe integer arithmetic. | 97 buffer_size += tag_length_bytes; |
97 if (data.byte_length() > (UINT_MAX - tag_length_bytes)) | 98 if (!buffer_size.IsValid()) |
98 return Status::ErrorDataTooLarge(); | 99 return Status::ErrorDataTooLarge(); |
99 buffer_size = data.byte_length() + tag_length_bytes; | |
100 } else { | |
101 // TODO(eroman): In theory the buffer allocated for the plain text should be | |
102 // sized as |data.byte_length() - tag_length_bytes|. | |
103 // | |
104 // However NSS has a bug whereby it will fail if the output buffer size is | |
105 // not at least as large as the ciphertext: | |
106 // | |
107 // https://bugzilla.mozilla.org/show_bug.cgi?id=%20853674 | |
108 // | |
109 // From the analysis of that bug it looks like it might be safe to pass a | |
110 // correctly sized buffer but lie about its size. Since resizing the | |
111 // WebCryptoArrayBuffer is expensive that hack may be worth looking into. | |
112 buffer_size = data.byte_length(); | |
113 } | 100 } |
114 | 101 |
115 buffer->resize(buffer_size); | 102 // TODO(eroman): In theory the buffer allocated for the plain text should be |
| 103 // sized as |data.byte_length() - tag_length_bytes|. |
| 104 // |
| 105 // However NSS has a bug whereby it will fail if the output buffer size is |
| 106 // not at least as large as the ciphertext: |
| 107 // |
| 108 // https://bugzilla.mozilla.org/show_bug.cgi?id=%20853674 |
| 109 // |
| 110 // From the analysis of that bug it looks like it might be safe to pass a |
| 111 // correctly sized buffer but lie about its size. Since resizing the |
| 112 // WebCryptoArrayBuffer is expensive that hack may be worth looking into. |
| 113 |
| 114 buffer->resize(buffer_size.ValueOrDie()); |
116 unsigned char* buffer_data = Uint8VectorStart(buffer); | 115 unsigned char* buffer_data = Uint8VectorStart(buffer); |
117 | 116 |
118 PK11_EncryptDecryptFunction encrypt_or_decrypt_func = | 117 PK11_EncryptDecryptFunction encrypt_or_decrypt_func = |
119 (mode == ENCRYPT) ? NssRuntimeSupport::Get()->pk11_encrypt_func() | 118 (mode == ENCRYPT) ? NssRuntimeSupport::Get()->pk11_encrypt_func() |
120 : NssRuntimeSupport::Get()->pk11_decrypt_func(); | 119 : NssRuntimeSupport::Get()->pk11_decrypt_func(); |
121 | 120 |
122 unsigned int output_len = 0; | 121 unsigned int output_len = 0; |
123 SECStatus result = encrypt_or_decrypt_func(sym_key, | 122 SECStatus result = encrypt_or_decrypt_func(sym_key, |
124 CKM_AES_GCM, | 123 CKM_AES_GCM, |
125 ¶m, | 124 ¶m, |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
179 | 178 |
180 } // namespace | 179 } // namespace |
181 | 180 |
182 AlgorithmImplementation* CreatePlatformAesGcmImplementation() { | 181 AlgorithmImplementation* CreatePlatformAesGcmImplementation() { |
183 return new AesGcmImplementation; | 182 return new AesGcmImplementation; |
184 } | 183 } |
185 | 184 |
186 } // namespace webcrypto | 185 } // namespace webcrypto |
187 | 186 |
188 } // namespace content | 187 } // namespace content |
OLD | NEW |