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// cryptoclient - client interface to CSSM CSP encryption/decryption operations
21//
22#include <security_cdsa_client/cryptoclient.h>
23
24using namespace CssmClient;
25
26
27Crypt::Crypt(const CSP &csp, CSSM_ALGORITHMS alg)
28	: Context(csp, alg), mMode(CSSM_ALGMODE_NONE), mInitVector(NULL),
29	  mPadding(CSSM_PADDING_NONE)
30{
31}
32
33void Crypt::key(const Key &key)
34{
35	mKey = key;
36	set(CSSM_ATTRIBUTE_KEY, static_cast<const CssmKey &>(key));
37}
38
39
40void
41Crypt::activate()
42{
43    StLock<Mutex> _(mActivateMutex);
44	if (!mActive)
45	{
46        // Key is required unless we have a NULL algorithm (cleartext wrap/unwrap),
47        // in which case we'll make a symmetric context (it shouldn't matter then).
48		if (!mKey && mAlgorithm != CSSM_ALGID_NONE)
49			CssmError::throwMe(CSSMERR_CSP_MISSING_ATTR_KEY);
50		if (!mKey || mKey->keyClass() == CSSM_KEYCLASS_SESSION_KEY)
51		{	// symmetric key
52			check(CSSM_CSP_CreateSymmetricContext(attachment()->handle(), mAlgorithm,
53				mMode, neededCred(), mKey, mInitVector, mPadding, NULL,
54				&mHandle));
55		}
56		else
57		{
58			check(CSSM_CSP_CreateAsymmetricContext(attachment()->handle(), mAlgorithm,
59				neededCred(), mKey, mPadding, &mHandle));
60			//@@@ stick mode and initVector explicitly into the context?
61		}
62		mActive = true;
63	}
64}
65
66
67//
68// Manage encryption contexts
69//
70CSSM_SIZE
71Encrypt::encrypt(const CssmData *in, uint32 inCount,
72						CssmData *out, uint32 outCount, CssmData &remData)
73{
74	unstaged();
75	CSSM_SIZE total;
76	check(CSSM_EncryptData(handle(), in, inCount, out, outCount, &total, &remData));
77	return total;
78}
79
80void
81Encrypt::init()
82{
83	check(CSSM_EncryptDataInit(handle()));
84	mStaged = true;
85}
86
87CSSM_SIZE
88Encrypt::encrypt(const CssmData *in, uint32 inCount,
89	CssmData *out, uint32 outCount)
90{
91	staged();
92	CSSM_SIZE total;
93	check(CSSM_EncryptDataUpdate(handle(), in, inCount, out, outCount, &total));
94	return total;
95}
96
97void
98Encrypt::final(CssmData &remData)
99{
100	staged();
101	check(CSSM_EncryptDataFinal(handle(), &remData));
102	mStaged = false;
103}
104
105
106//
107// Manage Decryption contexts
108//
109
110CSSM_SIZE
111Decrypt::decrypt(const CssmData *in, uint32 inCount,
112	CssmData *out, uint32 outCount, CssmData &remData)
113{
114	unstaged();
115	CSSM_SIZE total;
116	check(CSSM_DecryptData(handle(), in, inCount, out, outCount, &total, &remData));
117	return total;
118}
119
120void
121Decrypt::init()
122{
123	check(CSSM_DecryptDataInit(handle()));
124	mStaged = true;
125}
126
127CSSM_SIZE
128Decrypt::decrypt(const CssmData *in, uint32 inCount,
129	CssmData *out, uint32 outCount)
130{
131	staged();
132	CSSM_SIZE total;
133	check(CSSM_DecryptDataUpdate(handle(), in, inCount, out, outCount, &total));
134	return total;
135}
136
137void
138Decrypt::final(CssmData &remData)
139{
140	staged();
141	check(CSSM_DecryptDataFinal(handle(), &remData));
142	mStaged = false;
143}
144