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 * RSA_asymmetric.cpp - CSPContext for RSA asymmetric encryption
23 #include "RSA_asymmetric.h"
24 #include "RSA_DSA_utils.h"
25 #include <Security/debugging.h>
26 #include <open_ssl/opensslUtils/opensslUtils.h>
28 #define rsaCryptDebug(args...) debug("rsaCrypt", ## args)
29 #define rbprintf(args...) debug("rsaBuf", ## args)
31 RSA_CryptContext::~RSA_CryptContext()
34 assert(mRsaKey
!= NULL
);
37 mAllocdRsaKey
= false;
41 /* called by CSPFullPluginSession */
42 void RSA_CryptContext::init(const Context
&context
, bool encoding
= true)
44 if(mInitFlag
&& !opStarted()) {
45 /* reusing - e.g. query followed by encrypt */
49 /* optional mode to use alternate key class (e.g., decrypt with public key) */
50 CSSM_KEYCLASS keyClass
;
51 switch (context
.getInt(CSSM_ATTRIBUTE_MODE
)) {
52 case CSSM_ALGMODE_PUBLIC_KEY
:
53 keyClass
= CSSM_KEYCLASS_PUBLIC_KEY
;
55 case CSSM_ALGMODE_PRIVATE_KEY
:
56 keyClass
= CSSM_KEYCLASS_PRIVATE_KEY
;
58 case CSSM_ALGMODE_NONE
:
59 /* default, not present in context: infer from op type */
60 keyClass
= encoding
? CSSM_KEYCLASS_PUBLIC_KEY
: CSSM_KEYCLASS_PRIVATE_KEY
;
63 CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_MODE
);
66 /* fetch key from context */
69 mRsaKey
= contextToRsaKey(context
,
72 encoding
? CSSM_KEYUSE_ENCRYPT
: CSSM_KEYUSE_DECRYPT
,
79 unsigned cipherBlockSize
= RSA_size(mRsaKey
);
80 unsigned plainBlockSize
;
82 /* padding - not present means value zero, CSSM_PADDING_NONE */
83 uint32 padding
= context
.getInt(CSSM_ATTRIBUTE_PADDING
);
85 case CSSM_PADDING_NONE
:
86 mPadding
= RSA_NO_PADDING
;
87 plainBlockSize
= cipherBlockSize
;
89 case CSSM_PADDING_PKCS1
:
90 mPadding
= RSA_PKCS1_PADDING
;
91 plainBlockSize
= cipherBlockSize
- 11;
94 CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_PADDING
);
97 /* finally, have BlockCryptor set up its stuff. */
98 setup(encoding
? plainBlockSize
: cipherBlockSize
, // blockSizeIn
99 encoding
? cipherBlockSize
: plainBlockSize
, // blockSizeOut
107 /* called by BlockCryptor */
108 void RSA_CryptContext::encryptBlock(
109 const void *plainText
, // length implied (one block)
112 size_t &cipherTextLen
, // in/out, throws on overflow
117 if(mRsaKey
->d
== NULL
) {
118 irtn
= RSA_public_encrypt(plainTextLen
,
119 (unsigned char *)plainText
,
120 (unsigned char *)cipherText
,
125 irtn
= RSA_private_encrypt(plainTextLen
,
126 (unsigned char *)plainText
,
127 (unsigned char *)cipherText
,
132 throwRsaDsa("RSA_public_encrypt");
134 else if((unsigned)irtn
> cipherTextLen
) {
135 rsaCryptDebug("RSA_public_encrypt overflow");
136 CssmError::throwMe(CSSMERR_CSP_OUTPUT_LENGTH_ERROR
);
138 cipherTextLen
= (size_t)irtn
;
141 void RSA_CryptContext::decryptBlock(
142 const void *cipherText
, // length implied (one cipher block)
144 size_t &plainTextLen
, // in/out, throws on overflow
149 if(mRsaKey
->d
== NULL
) {
150 irtn
= RSA_public_decrypt(inBlockSize(),
151 (unsigned char *)cipherText
,
152 (unsigned char *)plainText
,
157 irtn
= RSA_private_decrypt(inBlockSize(),
158 (unsigned char *)cipherText
,
159 (unsigned char *)plainText
,
164 throwRsaDsa("RSA_private_decrypt");
166 else if((unsigned)irtn
> plainTextLen
) {
167 rsaCryptDebug("RSA_private_decrypt overflow");
168 CssmError::throwMe(CSSMERR_CSP_OUTPUT_LENGTH_ERROR
);
170 plainTextLen
= (size_t)irtn
;
173 size_t RSA_CryptContext::outputSize(
174 bool final
, // ignored
175 size_t inSize
= 0) // output for given input size
177 UInt32 rawBytes
= inSize
+ inBufSize();
178 UInt32 rawBlocks
= (rawBytes
+ inBlockSize() - 1) / inBlockSize();
179 rbprintf("--- RSA_CryptContext::outputSize inSize 0x%lx outSize 0x%lx mInBufSize 0x%lx",
180 inSize
, rawBlocks
* outBlockSize(), inBufSize());
181 return rawBlocks
* outBlockSize();