1/* 2 * Copyright (c) 2011-12 Apple Inc. All Rights Reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23 24#include "ossl-config.h" 25 26#ifdef HAVE_COMMONCRYPTO_COMMONCRYPTOR_H 27 28#include <sys/types.h> 29 30#include <assert.h> 31#include <stdio.h> 32#include <stdlib.h> 33#include <string.h> 34 35#include <CommonCrypto/CommonCryptor.h> 36 37#include "ossl-aes.h" 38 39/* 40 * CommonCrypto shims for OSSL AES lowlevel API 41 */ 42static int 43_AES_set_key(int enc, const unsigned char *userKey, const int bits, 44 AES_KEY *key) 45{ 46 CCCryptorStatus status; 47 size_t keysize = (size_t)(bits / 8); 48 49 if (!userKey || !key) { 50 return (-1); 51 } 52 53 if ((keysize < kCCKeySizeAES128) || (keysize > kCCKeySizeAES256)) { 54 return (-2); 55 } 56 57 /* 58 * XXX The headerdoc for CCCryptorCreateFromData() claims to "Create 59 * a cryptographic context using caller-supplied memory" and that 60 * calling CCCryptorRelease() "is not strictly necessary". Unfortunately, 61 * this is incorrect. CCCryptorCreateFromData() allocates 4K of memory 62 * that will never be release unless CCCryptorRelease() is called. 63 * See <rdr://problem/10867937>. 64 */ 65 status = CCCryptorCreateFromData(enc, kCCAlgorithmAES128, 66 kCCOptionECBMode, (const void *)userKey, keysize, NULL, 67 key->data, AES_KEYST_SIZE, &key->cref, NULL); 68 if (status != kCCSuccess) { 69 return (-3); 70 } 71 72 return (0); 73} 74 75/* 76 * XXX Unfortunately CCCryptorCreateFromData() still allocates memory even passing 77 * it a buffer to use. Therefore, we need to explicitly free that memory by calling 78 * CCCryptorRelease(). Also see the comment above and <rdr://problem/10867937>. 79 */ 80void 81AES_destroy_ctx(AES_KEY *key) 82{ 83 if (key && key->cref) { 84 CCCryptorRelease(key->cref); 85 key->cref = NULL; 86 } 87} 88 89int 90AES_set_encrypt_key(const unsigned char *userKey, const int bits, 91 AES_KEY *key) 92{ 93 return (_AES_set_key(kCCEncrypt, userKey, bits, key)); 94} 95 96int 97AES_set_decrypt_key(const unsigned char *userKey, const int bits, 98 AES_KEY *key) 99{ 100 return (_AES_set_key(kCCDecrypt, userKey, bits, key)); 101} 102 103 104void 105AES_encrypt(const unsigned char *in, unsigned char *out, 106 const AES_KEY *key) 107{ 108 (void)CCCryptorUpdate(key->cref, (const void *)in, kCCBlockSizeAES128, 109 (void *)out, kCCBlockSizeAES128, NULL); 110} 111 112 113void 114AES_decrypt(const unsigned char *in, unsigned char *out, 115 const AES_KEY *key) 116{ 117 (void)CCCryptorUpdate(key->cref, (const void *)in, kCCBlockSizeAES128, 118 (void *)out, kCCBlockSizeAES128, NULL); 119} 120 121#endif /* HAVE_COMMONCRYPTO_COMMONCRYPTOR_H */ 122