]> git.saurik.com Git - apple/security.git/blob - SecurityTests/cspxutils/utilLib/ssleayUtils.cpp
Security-57031.1.35.tar.gz
[apple/security.git] / SecurityTests / cspxutils / utilLib / ssleayUtils.cpp
1 /*
2 * ssleayUtils.c - common routines for CDSA/openssl compatibility testing
3 */
4
5 #include <stdlib.h>
6 #include <stdio.h>
7 #include <string.h>
8 #include <openssl/blowfish.h>
9 #include <openssl/cast.h>
10 #include <openssl/evp.h>
11 #include "ssleayUtils.h"
12 #include <Security/cssmerr.h>
13 #include "common.h"
14
15 /*
16 * Caller sees EAY_KEY, we see a pointer to this.
17 */
18 typedef struct {
19 CSSM_ALGORITHMS alg;
20 union {
21 BF_KEY bf; // blowfish
22 CAST_KEY cast;
23 } key;
24 } EayKeyPriv;
25
26 /*
27 * Create a symmetric key.
28 */
29 CSSM_RETURN eayGenSymKey(
30 CSSM_ALGORITHMS alg,
31 CSSM_BOOL forEncr,
32 const CSSM_DATA *keyData,
33 EAY_KEY *key) // RETURNED
34 {
35 EayKeyPriv *ekp = (EayKeyPriv *)malloc(sizeof(EayKeyPriv));
36 memset(ekp, 0, sizeof(*ekp));
37 switch(alg) {
38 case CSSM_ALGID_BLOWFISH:
39 BF_set_key(&ekp->key.bf, keyData->Length, keyData->Data);
40 break;
41 case CSSM_ALGID_CAST: // cast128 only
42 CAST_set_key(&ekp->key.cast, keyData->Length, keyData->Data);
43 break;
44 default:
45 printf("***eayGenSymKey: bad alg\n");
46 return -1;
47 }
48 ekp->alg = alg;
49 *key = (EAY_KEY)ekp;
50 return CSSM_OK;
51 }
52
53 /*
54 * Free a key created in eayGenSymKey
55 */
56 CSSM_RETURN eayFreeKey(
57 EAY_KEY key)
58 {
59 memset(key, 0, sizeof(EayKeyPriv));
60 free(key);
61 return CSSM_OK;
62 }
63
64 /*
65 * encrypt/decrypt
66 */
67 CSSM_RETURN eayEncryptDecrypt(
68 EAY_KEY key,
69 CSSM_BOOL forEncrypt,
70 CSSM_ALGORITHMS encrAlg,
71 CSSM_ENCRYPT_MODE mode, // CSSM_ALGMODE_CBC ONLY!
72 const CSSM_DATA *iv, //ĂŠoptional per mode
73 const CSSM_DATA *inData,
74 CSSM_DATA_PTR outData) // CSSM_MALLOCd and RETURNED
75 {
76 EayKeyPriv *ekp = (EayKeyPriv *)key;
77 if((mode != CSSM_ALGMODE_CBC_IV8) && (mode != CSSM_ALGMODE_ECB)) {
78 printf("***eayEncryptDecrypt only does CBC_IV8, ECB\n");
79 return -1;
80 }
81
82 bool cbc = (mode == CSSM_ALGMODE_ECB) ? false : true;
83
84 outData->Data = (uint8 *)CSSM_MALLOC(inData->Length);
85 outData->Length = inData->Length;
86
87 /* BF_cbc_encrypt actually writes to IV */
88 CSSM_DATA ivc = {0, NULL};
89 if(cbc) {
90 ivc.Data = (uint8 *)malloc(iv->Length);
91 ivc.Length = iv->Length;
92 memmove(ivc.Data, iv->Data, ivc.Length);
93 }
94 switch(encrAlg) {
95 case CSSM_ALGID_BLOWFISH:
96 if(cbc) {
97 BF_cbc_encrypt(inData->Data,
98 outData->Data,
99 inData->Length,
100 &ekp->key.bf,
101 ivc.Data,
102 forEncrypt ? BF_ENCRYPT : BF_DECRYPT);
103 }
104 else {
105 CSSM_DATA intext = *inData;
106 CSSM_DATA outtext = *outData;
107 while(intext.Length) {
108 BF_ecb_encrypt(intext.Data,
109 outtext.Data,
110 &ekp->key.bf,
111 forEncrypt ? BF_ENCRYPT : BF_DECRYPT);
112 intext.Data += 8;
113 outtext.Data += 8;
114 intext.Length -= 8;
115 }
116 }
117 break;
118 case CSSM_ALGID_CAST: // cast128 only
119 CAST_cbc_encrypt(inData->Data,
120 outData->Data,
121 inData->Length,
122 &ekp->key.cast,
123 ivc.Data,
124 forEncrypt ? CAST_ENCRYPT : CAST_DECRYPT);
125 break;
126 default:
127 printf("***eayEncryptDecrypt: bad alg\n");
128 return -1;
129 }
130 if(ivc.Data) {
131 free(ivc.Data);
132 }
133 return CSSM_OK;
134 }
135
136 /*** EVP-based encrypt/decrypt ***/
137
138 int evpEncryptDecrypt(
139 CSSM_ALGORITHMS alg, // AES 128 only for now
140 CSSM_BOOL forEncr,
141 const CSSM_DATA *keyData, // may be larger than the key size we use
142 unsigned keyLengthInBits,
143 CSSM_ENCRYPT_MODE mode, // CSSM_ALGMODE_CBC_IV8, ECB, always padding
144 const CSSM_DATA *iv, // optional per mode
145 const CSSM_DATA *inData,
146 CSSM_DATA_PTR outData) // CSSM_MALLOCd and RETURNED
147 {
148 EVP_CIPHER_CTX ctx;
149 const EVP_CIPHER *cipher;
150 unsigned blockSize;
151 unsigned outLen = inData->Length;
152 bool noPad = false;
153
154 switch(alg) {
155 case CSSM_ALGID_AES:
156 switch(mode) {
157 case CSSM_ALGMODE_CBCPadIV8:
158 switch(keyLengthInBits) {
159 case 128:
160 cipher = EVP_aes_128_cbc();
161 break;
162 case 192:
163 cipher = EVP_aes_192_cbc();
164 break;
165 case 256:
166 cipher = EVP_aes_256_cbc();
167 break;
168 default:
169 printf("***Bad AES key length (%u)\n", keyLengthInBits);
170 return -1;
171 }
172 break;
173 case CSSM_ALGMODE_ECB:
174 switch(keyLengthInBits) {
175 case 128:
176 cipher = EVP_aes_128_ecb();
177 break;
178 case 192:
179 cipher = EVP_aes_192_ecb();
180 break;
181 case 256:
182 cipher = EVP_aes_256_ecb();
183 break;
184 default:
185 printf("***Bad AES key length (%u)\n", keyLengthInBits);
186 return -1;
187 }
188 noPad = true;
189 break;
190 default:
191 printf("***evpEncryptDecrypt only does CBC and ECB for now\n");
192 return -1;
193 }
194 blockSize = 16;
195 break;
196 case CSSM_ALGID_DES:
197 switch(mode) {
198 case CSSM_ALGMODE_CBCPadIV8:
199 cipher = EVP_des_cbc();
200 break;
201 case CSSM_ALGMODE_ECB:
202 cipher = EVP_des_ecb();
203 noPad = true;
204 break;
205 default:
206 printf("***evpEncryptDecrypt only does CBC and ECB for now\n");
207 return -1;
208 }
209 blockSize = 8;
210 break;
211 default:
212 printf("***evpEncryptDecrypt only does DES and AES 128 for now\n");
213 return -1;
214 }
215 outLen += blockSize;
216 unsigned char *outp = (uint8 *)CSSM_MALLOC(outLen);
217 int outl = outLen;
218 outData->Data = outp;
219
220 if(forEncr) {
221 int rtn = EVP_EncryptInit(&ctx, cipher, keyData->Data, iv ? iv->Data : NULL);
222 if(!rtn) {
223 printf("EVP_EncryptInit error\n");
224 return -1;
225 }
226 if(noPad) {
227 EVP_CIPHER_CTX_set_padding(&ctx, 0);
228 }
229 if(!EVP_EncryptUpdate(&ctx, outp, &outl, inData->Data, inData->Length)) {
230 printf("EVP_EncryptUpdate error\n");
231 return -1;
232 }
233 }
234 else {
235 int rtn = EVP_DecryptInit(&ctx, cipher, keyData->Data, iv ? iv->Data : NULL);
236 if(!rtn) {
237 printf("EVP_DecryptInit error\n");
238 return -1;
239 }
240 if(noPad) {
241 EVP_CIPHER_CTX_set_padding(&ctx, 0);
242 }
243
244 if(!EVP_DecryptUpdate(&ctx, outp, &outl, inData->Data, inData->Length)) {
245 printf("EVP_DecryptUpdate error\n");
246 return -1;
247 }
248 }
249 outData->Length = outl;
250 outp += outl;
251 outl = outLen - outl;
252 if(forEncr) {
253 if(!EVP_EncryptFinal(&ctx, outp, &outl)) {
254 printf("EVP_EncryptFinal error\n");
255 return -1;
256 }
257 }
258 else {
259 if(!EVP_DecryptFinal(&ctx, outp, &outl)) {
260 printf("EVP_DecryptFinal error\n");
261 return -1;
262 }
263 }
264 outData->Length += outl;
265 return 0;
266 }