Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(122)

Side by Side Diff: content/renderer/webcrypto/platform_crypto_nss.cc

Issue 188363002: [webcrypto] Add raw symmetric key RSAES-PKCS1-v1_5 wrap/unwrap for NSS. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@wcAesKw_nss1
Patch Set: removed new NSS function calls Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 "content/renderer/webcrypto/platform_crypto.h" 5 #include "content/renderer/webcrypto/platform_crypto.h"
6 6
7 #include <cryptohi.h> 7 #include <cryptohi.h>
8 #include <pk11pub.h> 8 #include <pk11pub.h>
9 #include <sechash.h> 9 #include <sechash.h>
10 10
(...skipping 1108 matching lines...) Expand 10 before | Expand all | Expand 10 after
1119 // max limit is whatever will fit into an unsigned. For the max size test, 1119 // max limit is whatever will fit into an unsigned. For the max size test,
1120 // note that AES Key Wrap always adds 8 bytes to the input data size. 1120 // note that AES Key Wrap always adds 8 bytes to the input data size.
1121 const unsigned int input_length = PK11_GetKeyLength(key->key()); 1121 const unsigned int input_length = PK11_GetKeyLength(key->key());
1122 if (input_length < 16) 1122 if (input_length < 16)
1123 return Status::ErrorDataTooSmall(); 1123 return Status::ErrorDataTooSmall();
1124 if (input_length > UINT_MAX - 8) 1124 if (input_length > UINT_MAX - 8)
1125 return Status::ErrorDataTooLarge(); 1125 return Status::ErrorDataTooLarge();
1126 if (input_length % 8) 1126 if (input_length % 8)
1127 return Status::ErrorInvalidAesKwDataLength(); 1127 return Status::ErrorInvalidAesKwDataLength();
1128 1128
1129 SECItem iv_item = 1129 SECItem iv_item = MakeSECItemForBuffer(CryptoData(kAesIv, sizeof(kAesIv)));
1130 MakeSECItemForBuffer(CryptoData(kAesIv, sizeof(kAesIv)));
1131 crypto::ScopedSECItem param_item( 1130 crypto::ScopedSECItem param_item(
1132 PK11_ParamFromIV(CKM_NSS_AES_KEY_WRAP, &iv_item)); 1131 PK11_ParamFromIV(CKM_NSS_AES_KEY_WRAP, &iv_item));
1133 if (!param_item) 1132 if (!param_item)
1134 return Status::ErrorUnexpected(); 1133 return Status::ErrorUnexpected();
1135 1134
1136 const unsigned int output_length = input_length + 8; 1135 const unsigned int output_length = input_length + 8;
1137 *buffer = blink::WebArrayBuffer::create(output_length, 1); 1136 *buffer = blink::WebArrayBuffer::create(output_length, 1);
1138 unsigned char* buffer_data = reinterpret_cast<unsigned char*>(buffer->data()); 1137 SECItem wrapped_key_item = MakeSECItemForBuffer(CryptoData(*buffer));
1139 SECItem wrapped_key_item = {siBuffer, buffer_data, output_length};
1140 1138
1141 if (SECSuccess != PK11_WrapSymKey(CKM_NSS_AES_KEY_WRAP, 1139 if (SECSuccess != PK11_WrapSymKey(CKM_NSS_AES_KEY_WRAP,
1142 param_item.get(), 1140 param_item.get(),
1143 wrapping_key->key(), 1141 wrapping_key->key(),
1144 key->key(), 1142 key->key(),
1145 &wrapped_key_item)) { 1143 &wrapped_key_item)) {
1146 return Status::Error(); 1144 return Status::Error();
1147 } 1145 }
1148 if (output_length != wrapped_key_item.len) 1146 if (output_length != wrapped_key_item.len)
1149 return Status::ErrorUnexpected(); 1147 return Status::ErrorUnexpected();
1150 1148
1151 return Status::Success(); 1149 return Status::Success();
1152 } 1150 }
1153 1151
1154 Status UnwrapSymKeyAesKw(const CryptoData& wrapped_key_data, 1152 Status UnwrapSymKeyAesKw(const CryptoData& wrapped_key_data,
1155 SymKey* wrapping_key, 1153 SymKey* wrapping_key,
1156 const blink::WebCryptoAlgorithm& algorithm, 1154 const blink::WebCryptoAlgorithm& algorithm,
1157 bool extractable, 1155 bool extractable,
1158 blink::WebCryptoKeyUsageMask usage_mask, 1156 blink::WebCryptoKeyUsageMask usage_mask,
1159 blink::WebCryptoKey* key) { 1157 blink::WebCryptoKey* key) {
1160 DCHECK_GE(wrapped_key_data.byte_length(), 24u); 1158 DCHECK_GE(wrapped_key_data.byte_length(), 24u);
1161 DCHECK_EQ(wrapped_key_data.byte_length() % 8, 0u); 1159 DCHECK_EQ(wrapped_key_data.byte_length() % 8, 0u);
1162 1160
1163 SECItem iv_item = 1161 SECItem iv_item = MakeSECItemForBuffer(CryptoData(kAesIv, sizeof(kAesIv)));
1164 MakeSECItemForBuffer(CryptoData(kAesIv, sizeof(kAesIv)));
1165 crypto::ScopedSECItem param_item( 1162 crypto::ScopedSECItem param_item(
1166 PK11_ParamFromIV(CKM_NSS_AES_KEY_WRAP, &iv_item)); 1163 PK11_ParamFromIV(CKM_NSS_AES_KEY_WRAP, &iv_item));
1167 if (!param_item) 1164 if (!param_item)
1168 return Status::ErrorUnexpected(); 1165 return Status::ErrorUnexpected();
1169 1166
1170 SECItem cipher_text = MakeSECItemForBuffer(wrapped_key_data); 1167 SECItem cipher_text = MakeSECItemForBuffer(wrapped_key_data);
1171 1168
1172 // The plaintext length is always 64 bits less than the data size. 1169 // The plaintext length is always 64 bits less than the data size.
1173 const unsigned int plaintext_length = wrapped_key_data.byte_length() - 8; 1170 const unsigned int plaintext_length = wrapped_key_data.byte_length() - 8;
1174 1171
(...skipping 22 matching lines...) Expand all
1197 return Status::ErrorUnexpected(); 1194 return Status::ErrorUnexpected();
1198 1195
1199 *key = blink::WebCryptoKey::create(new SymKey(unwrapped_key.Pass()), 1196 *key = blink::WebCryptoKey::create(new SymKey(unwrapped_key.Pass()),
1200 blink::WebCryptoKeyTypeSecret, 1197 blink::WebCryptoKeyTypeSecret,
1201 extractable, 1198 extractable,
1202 key_algorithm, 1199 key_algorithm,
1203 usage_mask); 1200 usage_mask);
1204 return Status::Success(); 1201 return Status::Success();
1205 } 1202 }
1206 1203
1204 Status WrapSymKeyRsaEs(PublicKey* wrapping_key,
1205 SymKey* key,
1206 blink::WebArrayBuffer* buffer) {
1207 // Check the raw length of the key to be wrapped against the max size allowed
1208 // by the RSA wrapping key. With PKCS#1 v1.5 padding used in this function,
1209 // the maximum data length that can be encrypted is the wrapping_key's modulus
1210 // byte length minus eleven bytes.
1211 const unsigned int input_length_bytes = PK11_GetKeyLength(key->key());
1212 const unsigned int modulus_length_bytes =
1213 SECKEY_PublicKeyStrength(wrapping_key->key());
1214 if (input_length_bytes > modulus_length_bytes - 11)
eroman 2014/03/06 04:31:16 Is it possible for modulus_length_bytes to be < 11
padolph 2014/03/10 19:02:54 Extremely unlikely as it would be very bad securit
1215 return Status::ErrorDataTooLarge();
1216
1217 *buffer = blink::WebArrayBuffer::create(modulus_length_bytes, 1);
1218 SECItem wrapped_key_item = MakeSECItemForBuffer(CryptoData(*buffer));
1219
1220 if (SECSuccess !=
1221 PK11_PubWrapSymKey(
eroman 2014/03/06 04:31:16 is this the automated formatting? I think it needs
padolph 2014/03/10 19:02:54 Yes. I run 'git cl format' before upload now. Will
1222 CKM_RSA_PKCS, wrapping_key->key(), key->key(), &wrapped_key_item)) {
1223 return Status::Error();
1224 }
1225 if (wrapped_key_item.len != modulus_length_bytes)
1226 return Status::ErrorUnexpected();
1227
1228 return Status::Success();
1229 }
1230
1231 Status UnwrapSymKeyRsaEs(const CryptoData& wrapped_key_data,
1232 PrivateKey* wrapping_key,
1233 const blink::WebCryptoAlgorithm& algorithm,
1234 bool extractable,
1235 blink::WebCryptoKeyUsageMask usage_mask,
1236 blink::WebCryptoKey* key) {
1237
1238 // Verify wrapped_key_data size does not exceed the modulus of the RSA key.
1239 const int modulus_length_bytes =
1240 PK11_GetPrivateModulusLen(wrapping_key->key());
1241 if (modulus_length_bytes <= 0)
1242 return Status::ErrorUnexpected();
1243 if (wrapped_key_data.byte_length() >
1244 static_cast<unsigned int>(modulus_length_bytes))
1245 return Status::ErrorDataTooLarge();
1246
1247 // Determine the proper NSS key properties from the input algorithm.
1248 CK_MECHANISM_TYPE mechanism;
1249 CK_FLAGS flags;
1250 Status status =
1251 WebCryptoAlgorithmToNssMechFlags(algorithm, &mechanism, &flags);
1252 if (status.IsError())
1253 return status;
1254
1255 SECItem wrapped_key_item = MakeSECItemForBuffer(wrapped_key_data);
1256
1257 crypto::ScopedPK11SymKey unwrapped_key(
1258 PK11_PubUnwrapSymKeyWithFlagsPerm(wrapping_key->key(),
1259 &wrapped_key_item,
1260 mechanism,
1261 CKA_DECRYPT,
1262 0,
1263 flags,
1264 false));
1265 if (!unwrapped_key)
1266 return Status::Error();
1267
1268 const unsigned int key_length = PK11_GetKeyLength(unwrapped_key.get());
1269
1270 blink::WebCryptoKeyAlgorithm key_algorithm;
1271 if (!CreateSecretKeyAlgorithm(algorithm, key_length, &key_algorithm))
1272 return Status::ErrorUnexpected();
1273
1274 *key = blink::WebCryptoKey::create(new SymKey(unwrapped_key.Pass()),
1275 blink::WebCryptoKeyTypeSecret,
1276 extractable,
1277 key_algorithm,
1278 usage_mask);
1279 return Status::Success();
1280 }
1281
1207 } // namespace platform 1282 } // namespace platform
1208 1283
1209 } // namespace webcrypto 1284 } // namespace webcrypto
1210 1285
1211 } // namespace content 1286 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698