2 * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
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
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.
20 * gladmanContext.cpp - glue between BlockCryptor and Gladman AES implementation
21 * Written by Doug Mitchell 12/12/2001
24 #include "gladmanContext.h"
25 #include "cspdebugging.h"
28 * Global singleton to perform one-time-only init of AES tables.
33 GladmanInit() : mTablesGenerated(false) { }
36 bool mTablesGenerated
;
40 void GladmanInit::genTables()
42 StLock
<Mutex
> _(mLock
);
43 if(mTablesGenerated
) {
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
));
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
));
67 mTablesGenerated
= true;
70 static ModuleNexus
<GladmanInit
> gladmanInit
;
73 * AES encrypt/decrypt.
75 GAESContext::GAESContext(AppleCSPSession
&session
) :
76 BlockCryptor(session
),
81 /* one-time only init */
82 gladmanInit().genTables();
85 GAESContext::~GAESContext()
88 memset(mRawKey
, 0, MAX_AES_KEY_BITS
/ 8);
92 void GAESContext::deleteKey()
94 memset(&mAesKey
, 0, sizeof(GAesKey
));
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).
103 void GAESContext::init(
104 const Context
&context
,
107 if(mInitFlag
&& !opStarted()) {
112 UInt8
*keyData
= NULL
;
113 bool sameKeySize
= false;
115 /* obtain key from context */
116 symmetricKeyBits(context
, CSSM_ALGID_AES
,
117 encrypting
? CSSM_KEYUSE_ENCRYPT
: CSSM_KEYUSE_DECRYPT
,
121 * Delete existing key if key size changed
123 if(mRawKeySize
== keyLen
) {
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
);
134 /* save this raw key data */
135 memmove(mRawKey
, keyData
, mRawKeySize
);
136 mRawKeySize
= keyLen
;
139 /* Finally, have BlockCryptor do its setup */
140 setup(GLADMAN_BLOCK_SIZE_BYTES
, context
);
145 * Functions called by BlockCryptor
147 void GAESContext::encryptBlock(
148 const void *plainText
, // length implied (one block)
151 size_t &cipherTextLen
, // in/out, throws on overflow
152 bool final
) // ignored
154 if(plainTextLen
!= GLADMAN_BLOCK_SIZE_BYTES
) {
155 CssmError::throwMe(CSSMERR_CSP_INPUT_LENGTH_ERROR
);
157 if(cipherTextLen
< GLADMAN_BLOCK_SIZE_BYTES
) {
158 CssmError::throwMe(CSSMERR_CSP_OUTPUT_LENGTH_ERROR
);
160 rEncrypt((u4byte
*)plainText
, (u4byte
*)cipherText
, &mAesKey
);
161 cipherTextLen
= GLADMAN_BLOCK_SIZE_BYTES
;
164 void GAESContext::decryptBlock(
165 const void *cipherText
, // length implied (one cipher block)
167 size_t &plainTextLen
, // in/out, throws on overflow
168 bool final
) // ignored
170 if(plainTextLen
< GLADMAN_BLOCK_SIZE_BYTES
) {
171 CssmError::throwMe(CSSMERR_CSP_OUTPUT_LENGTH_ERROR
);
173 rDecrypt((u4byte
*)cipherText
, (u4byte
*)plainText
, &mAesKey
);
174 plainTextLen
= GLADMAN_BLOCK_SIZE_BYTES
;