1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
|
/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an
unpublished work protected as such under copyright law. This work
contains proprietary, confidential, and trade secret information of
RSA Data Security, Inc. Use, disclosure or reproduction without the
express written authorization of RSA Data Security, Inc. is
prohibited.
*/
/* Define this so that the type of the 'this' pointer in the
virtual functions will be correct for this derived class.
*/
struct AH_RSAEncryption;
#define THIS_ENCRYPT_DECRYPT struct AH_RSAEncryption
#include "global.h"
#include "bsafe2.h"
#include "bkey.h"
#include "balg.h"
#include "ahrsaenc.h"
static int AH_RSAEncryptionInitHelper PROTO_LIST ((AH_RSAEncryption *, int));
static AHEncryptDecryptVTable V_TABLE = {
AH_RSAEncryptionDestructor, AH_RSAEncryptionGetBlockLen,
AH_RSAEncryptionEncryptInit, AH_RSAEncryptionDecryptInit,
AH_RSAEncryptionUpdate, AH_RSAEncryptionUpdate,
AH_RSAEncryptionEncryptFinal, AH_RSAEncryptionDecryptFinal
};
void AH_RSAEncryptionConstructor1 (handler, infoType)
AH_RSAEncryption *handler;
struct B_AlgorithmInfoType *infoType;
{
/* Construct base class with the infoType. Assume info is NULL_PTR. */
AHChooseEncryptConstructor2
(&handler->chooseEncryptDecrypt, infoType, NULL_PTR);
T_memset ((POINTER)&handler->z, 0, sizeof (handler->z));
/* Set the AHEncryptDecrypt vTable, but don't set the RSAEncryption vTable
since it is pure virtual. */
handler->chooseEncryptDecrypt.encryptDecrypt.vTable = &V_TABLE;
}
void AH_RSAEncryptionDestructor (handler)
AH_RSAEncryption *handler;
{
T_memset ((POINTER)handler->z.block, 0, handler->z.blockLen);
T_free ((POINTER)handler->z.block);
/* Call base class destructor */
AHChooseEncryptDestructor (handler);
}
int AH_RSAEncryptionGetBlockLen (handler, blockLen)
AH_RSAEncryption *handler;
unsigned int *blockLen;
{
UNUSED_ARG (handler)
UNUSED_ARG (blockLen)
return (BE_NOT_SUPPORTED);
}
int AH_RSAEncryptionEncryptInit (handler, key, chooser, surrenderContext)
AH_RSAEncryption *handler;
B_Key *key;
B_ALGORITHM_CHOOSER chooser;
A_SURRENDER_CTX *surrenderContext;
{
int status;
if ((status = AHChooseEncryptEncryptInit
(handler, key, chooser, surrenderContext)) != 0)
return (status);
return (AH_RSAEncryptionInitHelper (handler, 1));
}
int AH_RSAEncryptionDecryptInit (handler, key, chooser, surrenderContext)
AH_RSAEncryption *handler;
B_Key *key;
B_ALGORITHM_CHOOSER chooser;
A_SURRENDER_CTX *surrenderContext;
{
int status;
if ((status = AHChooseEncryptDecryptInit
(handler, key, chooser, surrenderContext)) != 0)
return (status);
return (AH_RSAEncryptionInitHelper (handler, 0));
}
/* Accumulate into the z.block.
*/
int AH_RSAEncryptionUpdate
(handler, partOut, partOutLen, maxPartOutLen, partIn, partInLen,
randomAlgorithm, surrenderContext)
AH_RSAEncryption *handler;
unsigned char *partOut;
unsigned int *partOutLen;
unsigned int maxPartOutLen;
unsigned char *partIn;
unsigned int partInLen;
B_Algorithm *randomAlgorithm;
A_SURRENDER_CTX *surrenderContext;
{
UNUSED_ARG (partOut)
UNUSED_ARG (maxPartOutLen)
UNUSED_ARG (randomAlgorithm)
UNUSED_ARG (surrenderContext)
*partOutLen = 0;
if (handler->_inputLen + partInLen > handler->_maxInputLen)
return (BE_INPUT_LEN);
T_memcpy
((POINTER)(handler->z.block + handler->_inputLen), (POINTER)partIn,
partInLen);
handler->_inputLen += partInLen;
return (0);
}
int AH_RSAEncryptionEncryptFinal
(handler, partOut, partOutLen, maxPartOutLen, randomAlgorithm,
surrenderContext)
AH_RSAEncryption *handler;
unsigned char *partOut;
unsigned int *partOutLen;
unsigned int maxPartOutLen;
B_Algorithm *randomAlgorithm;
A_SURRENDER_CTX *surrenderContext;
{
int status;
unsigned int dummyPartOutLen;
/* Encode methodContext in place. */
if ((status = (*handler->vTable->EncodeBlock)
(handler, randomAlgorithm, surrenderContext)) != 0)
return (status);
/* This should not return BE_INPUT_DATA since it is well-formatted. */
if ((status = AHChooseEncryptEncryptUpdate
(handler, partOut, partOutLen, maxPartOutLen, handler->z.block,
handler->z.blockLen, (B_Algorithm *)NULL_PTR, surrenderContext)) != 0)
return (status);
/* Expect final to return zero bytes. */
if ((status = AHChooseEncryptEncryptFinal
(handler, (unsigned char *)NULL_PTR, &dummyPartOutLen, 0,
(B_Algorithm *)NULL_PTR, surrenderContext)) != 0)
return (status);
/* Restart the handle for new input. */
handler->_inputLen = 0;
return (0);
}
int AH_RSAEncryptionDecryptFinal
(handler, partOut, partOutLen, maxPartOutLen, randomAlgorithm,
surrenderContext)
AH_RSAEncryption *handler;
unsigned char *partOut;
unsigned int *partOutLen;
unsigned int maxPartOutLen;
B_Algorithm *randomAlgorithm;
A_SURRENDER_CTX *surrenderContext;
{
ITEM output;
int status;
unsigned int decryptedLen, dummyPartOutLen;
UNUSED_ARG (randomAlgorithm)
/* Decrypt block in place. The block lenghts are already within limits.
*/
if ((status = AHChooseEncryptDecryptUpdate
(handler, handler->z.block, &decryptedLen, handler->z.blockLen,
handler->z.block, handler->_inputLen, (B_Algorithm *)NULL_PTR,
surrenderContext)) != 0)
return (status);
/* Expect final to return zero bytes. */
if ((status = AHChooseEncryptDecryptFinal
(handler, (unsigned char *)NULL_PTR, &dummyPartOutLen, 0,
(B_Algorithm *)NULL_PTR, surrenderContext)) != 0)
return (status);
/* Restart the handle for new input. */
handler->_inputLen = 0;
/* Now decode the block and copy the result to the partOut.
*/
if ((status = (*handler->vTable->DecodeBlock)
(handler, &output, decryptedLen)) != 0)
return (status);
if (output.len > handler->z.blockLen - 11)
/* This implies that the block was encrypted with less than
8 bytes of padding */
return (BE_INPUT_DATA);
if ((*partOutLen = output.len) > maxPartOutLen)
return (BE_OUTPUT_LEN);
T_memcpy ((POINTER)partOut, (POINTER)output.data, output.len);
return (0);
}
static int AH_RSAEncryptionInitHelper (handler, encryptFlag)
AH_RSAEncryption *handler;
int encryptFlag;
{
int status;
unsigned int newBlockLen;
if ((status = AHChooseEncryptGetBlockLen (handler, &newBlockLen)) != 0)
return (status);
if (newBlockLen < 12)
/* PKCS Requires at least 12 bytes of modulus */
return (BE_NOT_SUPPORTED);
/* During encrypt, this will ensure that there are 8 bytes of padding.
During decrypt, the DecodeBlock procedure must check that the block
was encrypted with 8 bytes of padding.
*/
handler->_maxInputLen = encryptFlag ? (newBlockLen - 11) : newBlockLen;
handler->_inputLen = 0;
/* Zeroize old block and realloc to new size.
*/
T_memset ((POINTER)handler->z.block, 0, handler->z.blockLen);
if ((handler->z.block = (unsigned char *)T_realloc
((POINTER)handler->z.block, newBlockLen))
== (unsigned char *)NULL_PTR) {
handler->z.blockLen = 0;
return (BE_ALLOC);
}
handler->z.blockLen = newBlockLen;
return (0);
}
|