1/* 2 * Copyright (C) 2013 Apple Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' 14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS 17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 23 * THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26#include "config.h" 27#include "CryptoAlgorithmAES_CBC.h" 28 29#if ENABLE(SUBTLE_CRYPTO) 30 31#include "CryptoAlgorithmAesCbcParams.h" 32#include "CryptoKeyAES.h" 33#include "ExceptionCode.h" 34#include <CommonCrypto/CommonCrypto.h> 35 36namespace WebCore { 37 38static void transformAES_CBC(CCOperation operation, const CryptoAlgorithmAesCbcParams& parameters, const CryptoKeyAES& key, const CryptoOperationData& data, CryptoAlgorithm::VectorCallback callback, CryptoAlgorithm::VoidCallback failureCallback) 39{ 40 static_assert(sizeof(parameters.iv) == kCCBlockSizeAES128, "Initialization vector size must be the same as algorithm block size"); 41 42 size_t keyLengthInBytes = key.key().size(); 43 if (keyLengthInBytes != 16 && keyLengthInBytes != 24 && keyLengthInBytes != 32) { 44 failureCallback(); 45 return; 46 } 47 48 CCCryptorRef cryptor; 49#if PLATFORM(IOS) || __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090 50 CCAlgorithm aesAlgorithm = kCCAlgorithmAES; 51#else 52 CCAlgorithm aesAlgorithm = kCCAlgorithmAES128; 53#endif 54 CCCryptorStatus status = CCCryptorCreate(operation, aesAlgorithm, kCCOptionPKCS7Padding, key.key().data(), keyLengthInBytes, parameters.iv.data(), &cryptor); 55 if (status) { 56 failureCallback(); 57 return; 58 } 59 60 Vector<uint8_t> result(CCCryptorGetOutputLength(cryptor, data.second, true)); 61 62 size_t bytesWritten; 63 status = CCCryptorUpdate(cryptor, data.first, data.second, result.data(), result.size(), &bytesWritten); 64 if (status) { 65 failureCallback(); 66 return; 67 } 68 69 uint8_t* p = result.data() + bytesWritten; 70 status = CCCryptorFinal(cryptor, p, result.end() - p, &bytesWritten); 71 p += bytesWritten; 72 if (status) { 73 failureCallback(); 74 return; 75 } 76 77 ASSERT(p <= result.end()); 78 result.shrink(p - result.begin()); 79 80 CCCryptorRelease(cryptor); 81 82 callback(result); 83} 84 85void CryptoAlgorithmAES_CBC::platformEncrypt(const CryptoAlgorithmAesCbcParams& parameters, const CryptoKeyAES& key, const CryptoOperationData& data, VectorCallback callback, VoidCallback failureCallback, ExceptionCode&) 86{ 87 transformAES_CBC(kCCEncrypt, parameters, key, data, WTF::move(callback), WTF::move(failureCallback)); 88} 89 90void CryptoAlgorithmAES_CBC::platformDecrypt(const CryptoAlgorithmAesCbcParams& parameters, const CryptoKeyAES& key, const CryptoOperationData& data, VectorCallback callback, VoidCallback failureCallback, ExceptionCode&) 91{ 92 transformAES_CBC(kCCDecrypt, parameters, key, data, WTF::move(callback), WTF::move(failureCallback)); 93} 94 95} // namespace WebCore 96 97#endif // ENABLE(SUBTLE_CRYPTO) 98