]> git.saurik.com Git - apple/security.git/blob - AppleCSP/AES/gladmanContext.cpp
Security-54.tar.gz
[apple/security.git] / AppleCSP / AES / gladmanContext.cpp
1 /*
2 * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
3 *
4 * The contents of this file constitute Original Code as defined in and are
5 * subject to the Apple Public Source License Version 1.2 (the 'License').
6 * You may not use this file except in compliance with the License. Please obtain
7 * a copy of the License at http://www.apple.com/publicsource and read it before
8 * using this file.
9 *
10 * This Original Code and all software distributed under the License are
11 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
12 * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
13 * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
14 * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the
15 * specific language governing rights and limitations under the License.
16 */
17
18
19 /*
20 * gladmanContext.cpp - glue between BlockCryptor and Gladman AES implementation
21 * Written by Doug Mitchell 12/12/2001
22 */
23
24 #include "gladmanContext.h"
25 #include "cspdebugging.h"
26
27 /*
28 * Global singleton to perform one-time-only init of AES tables.
29 */
30 class GladmanInit
31 {
32 public:
33 GladmanInit() : mTablesGenerated(false) { }
34 void genTables();
35 private:
36 bool mTablesGenerated;
37 Mutex mLock;
38 };
39
40 void GladmanInit::genTables()
41 {
42 StLock<Mutex> _(mLock);
43 if(mTablesGenerated) {
44 return;
45 }
46
47 /* allocate the tables */
48 CssmAllocator &alloc = CssmAllocator::standard(CssmAllocator::sensitive);
49 pow_tab = (u1byte *)alloc.malloc(POW_TAB_SIZE * sizeof(u1byte));
50 log_tab = (u1byte *)alloc.malloc(LOG_TAB_SIZE * sizeof(u1byte));
51 sbx_tab = (u1byte *)alloc.malloc(SBX_TAB_SIZE * sizeof(u1byte));
52 isb_tab = (u1byte *)alloc.malloc(ISB_TAB_SIZE * sizeof(u1byte));
53 rco_tab = (u4byte *)alloc.malloc(RCO_TAB_SIZE * sizeof(u4byte));
54 ft_tab = (u4byte (*)[FT_TAB_SIZE_LS])alloc.malloc(
55 FT_TAB_SIZE_LS * FT_TAB_SIZE_MS * sizeof(u4byte));
56 it_tab = (u4byte (*)[IT_TAB_SIZE_LS])alloc.malloc(
57 IT_TAB_SIZE_LS * IT_TAB_SIZE_MS * sizeof(u4byte));
58 #ifdef LARGE_TABLES
59 fl_tab = (u4byte (*)[FL_TAB_SIZE_LS])alloc.malloc(
60 FL_TAB_SIZE_LS * FL_TAB_SIZE_MS * sizeof(u4byte));
61 il_tab = (u4byte (*)[IL_TAB_SIZE_LS])alloc.malloc(
62 IL_TAB_SIZE_LS * IL_TAB_SIZE_MS * sizeof(u4byte));
63 #endif
64
65 /* now fill them */
66 gen_tabs();
67 mTablesGenerated = true;
68 }
69
70 static ModuleNexus<GladmanInit> gladmanInit;
71
72 /*
73 * AES encrypt/decrypt.
74 */
75 GAESContext::GAESContext(AppleCSPSession &session) :
76 BlockCryptor(session),
77 mKeyValid(false),
78 mInitFlag(false),
79 mRawKeySize(0)
80 {
81 /* one-time only init */
82 gladmanInit().genTables();
83 }
84
85 GAESContext::~GAESContext()
86 {
87 deleteKey();
88 memset(mRawKey, 0, MAX_AES_KEY_BITS / 8);
89 mInitFlag = false;
90 }
91
92 void GAESContext::deleteKey()
93 {
94 memset(&mAesKey, 0, sizeof(GAesKey));
95 mKeyValid = false;
96 }
97
98 /*
99 * Standard CSPContext init, called from CSPFullPluginSession::init().
100 * Reusable, e.g., query followed by en/decrypt. Even reusable after context
101 * changed (i.e., new IV in Encrypted File System).
102 */
103 void GAESContext::init(
104 const Context &context,
105 bool encrypting)
106 {
107 if(mInitFlag && !opStarted()) {
108 return;
109 }
110
111 UInt32 keyLen;
112 UInt8 *keyData = NULL;
113 bool sameKeySize = false;
114
115 /* obtain key from context */
116 symmetricKeyBits(context, CSSM_ALGID_AES,
117 encrypting ? CSSM_KEYUSE_ENCRYPT : CSSM_KEYUSE_DECRYPT,
118 keyData, keyLen);
119
120 /*
121 * Delete existing key if key size changed
122 */
123 if(mRawKeySize == keyLen) {
124 sameKeySize = true;
125 }
126 else {
127 deleteKey();
128 }
129
130 /* init key only if key size or key bits have changed */
131 if(!sameKeySize || memcmp(mRawKey, keyData, mRawKeySize)) {
132 set_key((u4byte *)keyData, keyLen * 8, &mAesKey);
133
134 /* save this raw key data */
135 memmove(mRawKey, keyData, mRawKeySize);
136 mRawKeySize = keyLen;
137 }
138
139 /* Finally, have BlockCryptor do its setup */
140 setup(GLADMAN_BLOCK_SIZE_BYTES, context);
141 mInitFlag = true;
142 }
143
144 /*
145 * Functions called by BlockCryptor
146 */
147 void GAESContext::encryptBlock(
148 const void *plainText, // length implied (one block)
149 size_t plainTextLen,
150 void *cipherText,
151 size_t &cipherTextLen, // in/out, throws on overflow
152 bool final) // ignored
153 {
154 if(plainTextLen != GLADMAN_BLOCK_SIZE_BYTES) {
155 CssmError::throwMe(CSSMERR_CSP_INPUT_LENGTH_ERROR);
156 }
157 if(cipherTextLen < GLADMAN_BLOCK_SIZE_BYTES) {
158 CssmError::throwMe(CSSMERR_CSP_OUTPUT_LENGTH_ERROR);
159 }
160 rEncrypt((u4byte *)plainText, (u4byte *)cipherText, &mAesKey);
161 cipherTextLen = GLADMAN_BLOCK_SIZE_BYTES;
162 }
163
164 void GAESContext::decryptBlock(
165 const void *cipherText, // length implied (one cipher block)
166 void *plainText,
167 size_t &plainTextLen, // in/out, throws on overflow
168 bool final) // ignored
169 {
170 if(plainTextLen < GLADMAN_BLOCK_SIZE_BYTES) {
171 CssmError::throwMe(CSSMERR_CSP_OUTPUT_LENGTH_ERROR);
172 }
173 rDecrypt((u4byte *)cipherText, (u4byte *)plainText, &mAesKey);
174 plainTextLen = GLADMAN_BLOCK_SIZE_BYTES;
175 }
176