]> git.saurik.com Git - apple/security.git/blob - SecurityTests/cspxutils/utilLib/bsafeUtils.c
Security-57031.1.35.tar.gz
[apple/security.git] / SecurityTests / cspxutils / utilLib / bsafeUtils.c
1 /*
2 * bsafeUtils.c - common routines for CDSA/BSAFE compatibility testing
3 */
4
5
6 #include <stdlib.h>
7 #include <stdio.h>
8 #include <time.h>
9 #include <string.h>
10 //#include <security_bsafe/bsafe.h>
11 //#include <security_bsafe/aglobal.h>
12 #include "bsafeUtils.h"
13 #include <Security/cssmerr.h>
14 #include "common.h"
15
16 /*
17 * Convert between BSAFE ITEM and CSSM_DATA
18 */
19 #if 0
20 static inline void buItemToCssmData(
21 const ITEM *item,
22 CSSM_DATA_PTR cdata)
23 {
24 cdata->Data = item->data;
25 cdata->Length = item->len;
26 }
27
28 static inline void buCssmDataToItem(
29 const CSSM_DATA *cdata,
30 ITEM *item)
31 {
32 item->data = cdata->Data;
33 item->len = cdata->Length;
34 }
35
36 /*
37 * BSafe's Chooser table - all we'll ever need.
38 */
39 /*static*/ B_ALGORITHM_METHOD *BSAFE_ALGORITHM_CHOOSER[] = {
40 // digests
41 &AM_SHA,
42 &AM_MD5,
43 &AM_MD2,
44
45 // organizational
46 &AM_CBC_ENCRYPT,
47 &AM_CBC_DECRYPT,
48 &AM_ECB_ENCRYPT,
49 &AM_ECB_DECRYPT,
50 &AM_OFB_ENCRYPT,
51 &AM_OFB_DECRYPT,
52
53 // DES & variants
54 &AM_DES_ENCRYPT,
55 &AM_DES_DECRYPT,
56 &AM_DESX_ENCRYPT,
57 &AM_DESX_DECRYPT,
58 &AM_DES_EDE_ENCRYPT,
59 &AM_DES_EDE_DECRYPT,
60
61 // RCn stuff
62 &AM_RC2_CBC_ENCRYPT,
63 &AM_RC2_CBC_DECRYPT,
64 &AM_RC2_ENCRYPT,
65 &AM_RC2_DECRYPT,
66 &AM_RC4_ENCRYPT,
67 &AM_RC4_DECRYPT,
68 &AM_RC5_ENCRYPT,
69 &AM_RC5_DECRYPT,
70 &AM_RC5_CBC_ENCRYPT,
71 &AM_RC5_CBC_DECRYPT,
72
73 // RSA
74 &AM_RSA_STRONG_KEY_GEN,
75 &AM_RSA_KEY_GEN,
76 &AM_RSA_CRT_ENCRYPT_BLIND,
77 &AM_RSA_CRT_DECRYPT_BLIND,
78 &AM_RSA_ENCRYPT,
79 &AM_RSA_DECRYPT,
80
81 // DSA
82 &AM_DSA_PARAM_GEN,
83 &AM_DSA_KEY_GEN,
84
85 // signatures
86 &AM_DSA_SIGN,
87 &AM_DSA_VERIFY,
88
89 // random number generation
90 &AM_MD5_RANDOM,
91 &AM_SHA_RANDOM,
92
93 // sentinel
94 (B_ALGORITHM_METHOD *)NULL_PTR
95 };
96
97 /*
98 * Convert a BSAFE return to a CSSM error and optionally print the error msg with
99 * the op in which the error occurred.
100 */
101 static CSSM_RETURN buBsafeErrToCssm(
102 int brtn,
103 const char *op)
104 {
105 const char *errStr = NULL;
106 CSSM_RETURN crtn;
107
108 switch (brtn) {
109 case 0:
110 return CSSM_OK;
111 case BE_ALLOC:
112 crtn = CSSMERR_CSSM_MEMORY_ERROR;
113 errStr = "BE_ALLOC";
114 break;
115 case BE_SIGNATURE:
116 crtn = CSSMERR_CSP_VERIFY_FAILED;
117 errStr = "BE_SIGNATURE";
118 break;
119 case BE_OUTPUT_LEN:
120 crtn = CSSMERR_CSP_OUTPUT_LENGTH_ERROR;
121 errStr = "BE_OUTPUT_LEN";
122 break;
123 case BE_INPUT_LEN:
124 crtn = CSSMERR_CSP_INPUT_LENGTH_ERROR;
125 errStr = "BE_INPUT_LEN";
126 break;
127 case BE_EXPONENT_EVEN:
128 crtn = CSSMERR_CSP_INVALID_KEY;
129 errStr = "BE_EXPONENT_EVEN";
130 break;
131 case BE_EXPONENT_LEN:
132 crtn = CSSMERR_CSP_INVALID_KEY;
133 errStr = "BE_EXPONENT_LEN";
134 break;
135 case BE_EXPONENT_ONE:
136 crtn = CSSMERR_CSP_INVALID_KEY;
137 errStr = "BE_EXPONENT_ONE";
138 break;
139 case BE_DATA:
140 crtn = CSSMERR_CSP_INVALID_DATA;
141 errStr = "BE_DATA";
142 break;
143 case BE_INPUT_DATA:
144 crtn = CSSMERR_CSP_INVALID_DATA;
145 errStr = "BE_INPUT_DATA";
146 break;
147 case BE_WRONG_KEY_INFO:
148 crtn = CSSMERR_CSP_INVALID_KEY;
149 errStr = "BE_WRONG_KEY_INFO";
150 break;
151 default:
152 //@@@ translate BSafe errors intelligently
153 crtn = CSSM_ERRCODE_INTERNAL_ERROR;
154 errStr = "Other BSAFE error";
155 break;
156 }
157 if(op != NULL) {
158 printf("%s: BSAFE error %d (%s)\n", op, brtn, errStr);
159 }
160 return crtn;
161 }
162
163 /*
164 * Non-thread-safe global random B_ALGORITHM_OBJ and a reusable init for it.
165 */
166 static B_ALGORITHM_OBJ bsafeRng = NULL;
167 #define BSAFE_RANDSIZE 64
168
169 static B_ALGORITHM_OBJ buGetRng()
170 {
171 int brtn;
172 uint8 seed[BSAFE_RANDSIZE];
173
174 if(bsafeRng != NULL) {
175 return bsafeRng;
176 }
177 brtn = B_CreateAlgorithmObject(&bsafeRng);
178 if(brtn) {
179 buBsafeErrToCssm(brtn, "B_CreateAlgorithmObject(&bsafeRng)");
180 return NULL;
181 }
182 brtn = B_SetAlgorithmInfo(bsafeRng, AI_X962Random_V0, NULL_PTR);
183 if(brtn) {
184 buBsafeErrToCssm(brtn, "B_SetAlgorithmInfo(bsafeRng)");
185 return NULL;
186 }
187 brtn = B_RandomInit(bsafeRng, BSAFE_ALGORITHM_CHOOSER, NULL);
188 if(brtn) {
189 buBsafeErrToCssm(brtn, "B_SetAlgorithmInfo(bsafeRng)");
190 return NULL;
191 }
192 appGetRandomBytes(seed, BSAFE_RANDSIZE);
193 brtn = B_RandomUpdate(bsafeRng, seed, BSAFE_RANDSIZE, NULL);
194 if(brtn) {
195 buBsafeErrToCssm(brtn, "B_RandomUpdate");
196 return NULL;
197 }
198 return bsafeRng;
199 }
200 #endif
201
202 /*
203 * Create a symmetric key.
204 */
205 CSSM_RETURN buGenSymKey(
206 uint32 keySizeInBits,
207 const CSSM_DATA *keyData,
208 BU_KEY *key) // RETURNED
209 {
210 #if 0
211 int brtn;
212 B_KEY_OBJ bkey = NULL;
213 ITEM item;
214 unsigned keyBytes = (keySizeInBits + 7) / 8;
215
216 if(keyBytes > keyData->Length) {
217 /* note it's OK to give us too much key data */
218 printf("***buGenSymKey: Insufficient keyData\n");
219 return CSSM_ERRCODE_INTERNAL_ERROR;
220 }
221
222 /* create a BSAFE key */
223 brtn = B_CreateKeyObject(&bkey);
224 if(brtn) {
225 return buBsafeErrToCssm(brtn, "B_CreateKeyObject");
226 }
227
228 /* assign data to the key */
229 item.data = keyData->Data;
230 item.len = keyBytes;
231 brtn = B_SetKeyInfo(bkey, KI_Item, (POINTER)&item);
232 if(brtn) {
233 return buBsafeErrToCssm(brtn, "B_SetKeyInfo");
234 }
235 else {
236 *key = bkey;
237 return CSSM_OK;
238 }
239 #endif
240 return 0;
241 }
242
243 /*
244 * Create asymmetric key pair.
245 * FIXME - additional params (e.g. DSA params, RSA exponent)?
246 */
247 CSSM_RETURN buGenKeyPair(
248 uint32 keySizeInBits,
249 CSSM_ALGORITHMS keyAlg, // CSSM_ALGID_{RSA,DSA}
250 BU_KEY *pubKey, // RETURNED
251 BU_KEY *privKey) // RETURNED
252 {
253 #if 0 // NO MORE BSAFE
254 int brtn;
255 B_KEY_OBJ bPubkey = NULL;
256 B_KEY_OBJ bPrivkey = NULL;
257 B_ALGORITHM_OBJ keypairGen = NULL;
258 const char *op = NULL;
259 A_RSA_KEY_GEN_PARAMS params;
260 unsigned char exp[1] = { 3 };
261 B_ALGORITHM_OBJ genDsaAlg = NULL;
262 B_ALGORITHM_OBJ dsaResult = NULL;
263 B_DSA_PARAM_GEN_PARAMS dsaParams;
264 A_DSA_PARAMS *kParams = NULL;
265
266 /* create algorithm object */
267 brtn = B_CreateAlgorithmObject(&keypairGen);
268 if(brtn) {
269 return CSSMERR_CSSM_MEMORY_ERROR;
270 }
271
272 /* create two BSAFE keys */
273 brtn = B_CreateKeyObject(&bPubkey);
274 if(brtn) {
275 op ="B_CreateKeyObject";
276 goto abort;
277 }
278 brtn = B_CreateKeyObject(&bPrivkey);
279 if(brtn) {
280 op ="B_CreateKeyObject";
281 goto abort;
282 }
283 switch(keyAlg) {
284 case CSSM_ALGID_RSA:
285 {
286 /* set RSA-specific params */
287 params.modulusBits = keySizeInBits;
288 /* hack - parameterize? */
289 params.publicExponent.data = exp;
290 params.publicExponent.len = 1;
291 brtn = B_SetAlgorithmInfo(keypairGen, AI_RSAKeyGen,
292 (POINTER)&params);
293 if(brtn) {
294 op ="B_SetAlgorithmInfo(AI_RSAKeyGen)";
295 }
296 break;
297 }
298 case CSSM_ALGID_DSA:
299 {
300 /* jump through hoops generating parameters */
301 brtn = B_CreateAlgorithmObject(&genDsaAlg);
302 if(brtn) {
303 op ="B_CreateAlgorithmObject";
304 break;
305 }
306 dsaParams.primeBits = keySizeInBits;
307 brtn = B_SetAlgorithmInfo(genDsaAlg, AI_DSAParamGen, (POINTER)&dsaParams);
308 if(brtn) {
309 op = "B_SetAlgorithmInfo(AI_DSAParamGen)";
310 break;
311 }
312 brtn = B_GenerateInit(genDsaAlg, BSAFE_ALGORITHM_CHOOSER, NULL);
313 if(brtn) {
314 op = "B_GenerateInit(AI_DSAParamGen)";
315 break;
316 }
317 brtn = B_CreateAlgorithmObject(&dsaResult);
318 if(brtn) {
319 op = "B_CreateAlgorithmObject";
320 break;
321 }
322 brtn = B_GenerateParameters(genDsaAlg, dsaResult, buGetRng(), NULL);
323 if(brtn) {
324 op = "B_GenerateParameters";
325 break;
326 }
327
328 /* dsaResult now has the parameters, which we must extract and then
329 * apply to the keypairGen object. Cool, huh? */
330 brtn = B_GetAlgorithmInfo((POINTER *)&kParams, dsaResult, AI_DSAKeyGen);
331 if(brtn) {
332 op = "B_GetAlgorithmInfo(AI_DSAKeyGen)";
333 break;
334 }
335 brtn = B_SetAlgorithmInfo(keypairGen, AI_DSAKeyGen, (POINTER)kParams);
336 if(brtn) {
337 op ="B_SetAlgorithmInfo(AI_DSAKeyGen)";
338 }
339 break;
340 }
341 default:
342 printf("buGenKeyPair: algorithm not supported\n");
343 return CSSMERR_CSSM_FUNCTION_NOT_IMPLEMENTED;
344 }
345 if(brtn) {
346 goto abort;
347 }
348
349 /* keypairGen all set to go. */
350 brtn = B_GenerateInit(keypairGen,
351 BSAFE_ALGORITHM_CHOOSER,
352 (A_SURRENDER_CTX *)NULL);
353 if(brtn) {
354 op = "B_GenerateInit";
355 goto abort;
356 }
357 brtn = B_GenerateKeypair(keypairGen,
358 bPubkey,
359 bPrivkey,
360 buGetRng(),
361 NULL);
362 if(brtn) {
363 op = "B_GenerateInit";
364 }
365 abort:
366 B_DestroyAlgorithmObject(&keypairGen);
367 B_DestroyAlgorithmObject(&genDsaAlg);
368 B_DestroyAlgorithmObject(&dsaResult);
369 if(brtn) {
370 B_DestroyKeyObject(&bPubkey);
371 B_DestroyKeyObject(&bPrivkey);
372 return buBsafeErrToCssm(brtn, op);
373 }
374 else {
375 *pubKey = bPubkey;
376 *privKey = bPrivkey;
377 return CSSM_OK;
378 }
379 #endif
380 return CSSM_OK;
381 }
382
383 /*
384 * Free a key created in buGenSymKey or buGenKeyPair
385 */
386 CSSM_RETURN buFreeKey(
387 BU_KEY key)
388 {
389 #if 0 // NO MORE BSAFE
390 B_KEY_OBJ bkey = (B_KEY_OBJ)key;
391 B_DestroyKeyObject(&bkey);
392 #endif
393 return CSSM_OK;
394 }
395
396 /*
397 * encrypt/decrypt
398 */
399 CSSM_RETURN buEncryptDecrypt(
400 BU_KEY key,
401 CSSM_BOOL forEncrypt,
402 CSSM_ALGORITHMS encrAlg,
403 CSSM_ENCRYPT_MODE mode, // CSSM_ALGMODE_CBC, etc.
404 const CSSM_DATA *iv, //Êoptional per mode
405 uint32 effectiveKeyBits, // optional per key alg (actually just RC2)
406 // for RSA, key size in bits
407 uint32 rounds, // optional, RC5 only
408 const CSSM_DATA *inData,
409 CSSM_DATA_PTR outData) // mallocd and RETURNED
410 {
411 #if 0 // NO MORE BSAFE
412 B_ALGORITHM_OBJ alg;
413 int brtn;
414 char fbCipher = 1;
415 uint32 blockSize = 0;
416 unsigned outBufLen;
417 unsigned bytesMoved;
418 CSSM_RETURN crtn;
419 char useIv;
420
421 // these variables are used in the switch below and need to
422 // live until after setAlgorithm()
423 ITEM bsIv;
424 B_BLK_CIPHER_W_FEEDBACK_PARAMS spec;
425 A_RC5_PARAMS rc5Params;
426 A_RC2_PARAMS rc2Params;
427
428 brtn = B_CreateAlgorithmObject(&alg);
429 if(brtn) {
430 return buBsafeErrToCssm(brtn, "B_CreateAlgorithmObject");
431 }
432
433 /* per-alg setup */
434 switch(encrAlg) {
435 case CSSM_ALGID_RC4:
436 /* the easy one */
437 brtn = B_SetAlgorithmInfo(alg, AI_RC4, NULL);
438 if(brtn) {
439 crtn = buBsafeErrToCssm(brtn, "B_SetAlgorithmInfo");
440 goto abort;
441 }
442 fbCipher = 0;
443 break;
444
445 case CSSM_ALGID_RSA:
446 /* assume encrypt via publicm decrypt via private */
447 if(forEncrypt) {
448 brtn = B_SetAlgorithmInfo(alg, AI_PKCS_RSAPublic, NULL);
449 }
450 else {
451 brtn = B_SetAlgorithmInfo(alg, AI_PKCS_RSAPrivate, NULL);
452 }
453 if(brtn) {
454 crtn = buBsafeErrToCssm(brtn, "B_SetAlgorithmInfo(RSA)");
455 goto abort;
456 }
457 blockSize = (effectiveKeyBits + 7) / 8;
458 fbCipher = 0;
459 break;
460
461 /* common code using AI_FeebackCipher */
462 case CSSM_ALGID_DES:
463 spec.encryptionMethodName = (POINTER)"des";
464 blockSize = 8;
465 break;
466 case CSSM_ALGID_DESX:
467 spec.encryptionMethodName = (POINTER)"desx";
468 blockSize = 8;
469 break;
470 case CSSM_ALGID_3DES_3KEY_EDE:
471 spec.encryptionMethodName = (POINTER)"des_ede";
472 blockSize = 8;
473 break;
474 case CSSM_ALGID_RC5:
475 spec.encryptionMethodName = (POINTER)"rc5";
476 spec.encryptionParams = (POINTER)&rc5Params;
477 rc5Params.version = 0x10;
478 rc5Params.rounds = rounds;
479 rc5Params.wordSizeInBits = 32;
480 blockSize = 8;
481 break;
482 case CSSM_ALGID_RC2:
483 spec.encryptionMethodName = (POINTER)"rc2";
484 spec.encryptionParams = (POINTER)&rc2Params;
485 rc2Params.effectiveKeyBits = effectiveKeyBits;
486 blockSize = 8;
487 break;
488 /* add other non-AI_FeebackCipher algorithms here */
489 default:
490 printf("buEncryptDecrypt: unknown algorithm\n");
491 return CSSM_ERRCODE_INTERNAL_ERROR;
492 }
493 if(fbCipher) {
494 useIv = 1; // default, except for ECB
495 switch(mode) {
496 case CSSM_ALGMODE_CBCPadIV8:
497 spec.feedbackMethodName = (POINTER)"cbc";
498 spec.paddingMethodName = (POINTER)"pad";
499 break;
500 case CSSM_ALGMODE_CBC_IV8:
501 spec.feedbackMethodName = (POINTER)"cbc";
502 spec.paddingMethodName = (POINTER)"nopad";
503 break;
504 case CSSM_ALGMODE_OFB_IV8:
505 spec.feedbackMethodName = (POINTER)"cbc";
506 spec.paddingMethodName = (POINTER)"nopad";
507 break;
508 case CSSM_ALGMODE_ECB:
509 /* this does not seem to work yet - need info from
510 * RSA. Specify block size as the feedbackParams (per manual)
511 * and get a memmove error trying to copy from address 8; specify
512 * an IV and get BSAFE error 524 (BE_INPUT_DATA) error on the
513 * EncryptInit.
514 */
515 spec.feedbackMethodName = (POINTER)"ecb";
516 spec.paddingMethodName = (POINTER)"nopad";
517 //useIv = 0;
518 //spec.feedbackParams = (POINTER)8;
519 break;
520 default:
521 printf("buEncryptDecrypt: unknown mode\n");
522 return CSSM_ERRCODE_INTERNAL_ERROR;
523 }
524 if(useIv && (iv != NULL)) {
525 buCssmDataToItem(iv, &bsIv);
526 spec.feedbackParams = (POINTER)&bsIv;
527 }
528
529 brtn = B_SetAlgorithmInfo(alg, AI_FeedbackCipher, (POINTER)&spec);
530 if(brtn) {
531 crtn = buBsafeErrToCssm(brtn, "B_SetAlgorithmInfo");
532 goto abort;
533 }
534 }
535
536 /*
537 * OK, one way or another we have an algorithm object. Set up
538 * output buffer.
539 */
540 if(forEncrypt) {
541 outBufLen = inData->Length + blockSize;
542 }
543 else {
544 outBufLen = inData->Length;
545 }
546 outData->Length = 0;
547 outData->Data = NULL;
548 crtn = appSetupCssmData(outData, outBufLen);
549 if(crtn) {
550 goto abort;
551 }
552 if(forEncrypt) {
553 brtn = B_EncryptInit(alg,
554 (B_KEY_OBJ)key,
555 BSAFE_ALGORITHM_CHOOSER,
556 (A_SURRENDER_CTX *)NULL);
557 if(brtn) {
558 crtn = buBsafeErrToCssm(brtn, "B_EncryptInit");
559 goto abort;
560 }
561 brtn = B_EncryptUpdate(alg,
562 outData->Data,
563 &bytesMoved,
564 outBufLen,
565 inData->Data,
566 inData->Length,
567 buGetRng(), // randAlg
568 NULL); // surrender
569 if(brtn) {
570 crtn = buBsafeErrToCssm(brtn, "B_EncryptInit");
571 goto abort;
572 }
573 outData->Length = bytesMoved;
574 brtn = B_EncryptFinal(alg,
575 outData->Data + bytesMoved,
576 &bytesMoved,
577 outBufLen - outData->Length,
578 buGetRng(), // randAlg
579 NULL); // surrender
580 if(brtn) {
581 crtn = buBsafeErrToCssm(brtn, "B_EncryptFinal");
582 goto abort;
583 }
584 outData->Length += bytesMoved;
585 crtn = CSSM_OK;
586 }
587 else {
588 brtn = B_DecryptInit(alg,
589 (B_KEY_OBJ)key,
590 BSAFE_ALGORITHM_CHOOSER,
591 (A_SURRENDER_CTX *)NULL);
592 if(brtn) {
593 crtn = buBsafeErrToCssm(brtn, "B_DecryptInit");
594 goto abort;
595 }
596 brtn = B_DecryptUpdate(alg,
597 outData->Data,
598 &bytesMoved,
599 outBufLen,
600 inData->Data,
601 inData->Length,
602 NULL, // randAlg
603 NULL); // surrender
604 if(brtn) {
605 crtn = buBsafeErrToCssm(brtn, "B_DecryptUpdate");
606 goto abort;
607 }
608 outData->Length = bytesMoved;
609 brtn = B_DecryptFinal(alg,
610 outData->Data + bytesMoved,
611 &bytesMoved,
612 outBufLen - outData->Length,
613 NULL, // randAlg
614 NULL); // surrender
615 if(brtn) {
616 crtn = buBsafeErrToCssm(brtn, "B_DecryptFinal");
617 goto abort;
618 }
619 outData->Length += bytesMoved;
620 crtn = CSSM_OK;
621 }
622 abort:
623 B_DestroyAlgorithmObject(&alg);
624 #endif
625 return 0; //crtn;
626 }
627
628 #if 0
629 /* CSSM sig alg --> B_INFO_TYPE */
630 static CSSM_RETURN cssmSigAlgToInfoType(
631 CSSM_ALGORITHMS cssmAlg,
632 B_INFO_TYPE *infoType)
633 {
634 switch(cssmAlg) {
635 case CSSM_ALGID_SHA1WithRSA:
636 *infoType = AI_SHA1WithRSAEncryption;
637 break;
638 case CSSM_ALGID_MD5WithRSA:
639 *infoType = AI_MD5WithRSAEncryption;
640 break;
641 case CSSM_ALGID_SHA1WithDSA:
642 *infoType = AI_DSAWithSHA1;
643 break;
644 default:
645 printf("cssmSigAlgToInfoType: unknown algorithm\n");
646 return CSSMERR_CSSM_FUNCTION_NOT_IMPLEMENTED;
647 }
648 return CSSM_OK;
649 }
650 #endif
651
652 /*
653 * Sign/verify
654 */
655 CSSM_RETURN buSign(
656 BU_KEY key,
657 CSSM_ALGORITHMS sigAlg,
658 const CSSM_DATA *ptext,
659 uint32 keySizeInBits, // to set up sig
660 CSSM_DATA_PTR sig) // mallocd and RETURNED
661 {
662 #if 0 // NO MORE BSAFE
663 B_ALGORITHM_OBJ alg = NULL;
664 int brtn;
665 B_INFO_TYPE infoType;
666 CSSM_RETURN crtn;
667 unsigned sigBytes;
668
669 brtn = B_CreateAlgorithmObject(&alg);
670 if(brtn) {
671 return buBsafeErrToCssm(brtn, "B_CreateAlgorithmObject");
672 }
673 crtn = cssmSigAlgToInfoType(sigAlg, &infoType);
674 if(crtn) {
675 return crtn;
676 }
677 brtn = B_SetAlgorithmInfo(alg, infoType, NULL);
678 if(brtn) {
679 crtn = buBsafeErrToCssm(brtn, "B_SetAlgorithmInfo");
680 goto abort;
681 }
682 brtn = B_SignInit(alg, (B_KEY_OBJ)key, BSAFE_ALGORITHM_CHOOSER, NULL);
683 if(brtn) {
684 crtn = buBsafeErrToCssm(brtn, "B_SignInit");
685 goto abort;
686 }
687 brtn = B_SignUpdate(alg, ptext->Data, ptext->Length, NULL);
688 if(brtn) {
689 crtn = buBsafeErrToCssm(brtn, "B_SignUpdate");
690 goto abort;
691 }
692
693 /* prepare for sig, size of key */
694 sigBytes = (keySizeInBits + 7) / 8;
695 sig->Data = (uint8 *)CSSM_MALLOC(sigBytes);
696 sig->Length = sigBytes;
697
698 brtn = B_SignFinal(alg, sig->Data, &sigBytes, sigBytes, buGetRng(), NULL);
699 if(brtn) {
700 crtn = buBsafeErrToCssm(brtn, "B_SignFinal");
701 goto abort;
702 }
703 sig->Length = sigBytes;
704 crtn = CSSM_OK;
705 abort:
706 B_DestroyAlgorithmObject(&alg);
707 #endif
708 return 0;//;
709 }
710
711 CSSM_RETURN buVerify(
712 BU_KEY key,
713 CSSM_ALGORITHMS sigAlg,
714 const CSSM_DATA *ptext,
715 const CSSM_DATA *sig) // mallocd and RETURNED
716 {
717 #if 0 // NO MORE BSAFE
718 B_ALGORITHM_OBJ alg = NULL;
719 int brtn;
720 B_INFO_TYPE infoType;
721 CSSM_RETURN crtn;
722
723 brtn = B_CreateAlgorithmObject(&alg);
724 if(brtn) {
725 return buBsafeErrToCssm(brtn, "B_CreateAlgorithmObject");
726 }
727 crtn = cssmSigAlgToInfoType(sigAlg, &infoType);
728 if(crtn) {
729 return crtn;
730 }
731 brtn = B_SetAlgorithmInfo(alg, infoType, NULL);
732 if(brtn) {
733 crtn = buBsafeErrToCssm(brtn, "B_SetAlgorithmInfo");
734 goto abort;
735 }
736 brtn = B_VerifyInit(alg, (B_KEY_OBJ)key, BSAFE_ALGORITHM_CHOOSER, NULL);
737 if(brtn) {
738 crtn = buBsafeErrToCssm(brtn, "B_VerifyInit");
739 goto abort;
740 }
741 brtn = B_VerifyUpdate(alg, ptext->Data, ptext->Length, NULL);
742 if(brtn) {
743 crtn = buBsafeErrToCssm(brtn, "B_VerifyUpdate");
744 goto abort;
745 }
746 brtn = B_VerifyFinal(alg, sig->Data, sig->Length, buGetRng(), NULL);
747 if(brtn) {
748 crtn = buBsafeErrToCssm(brtn, "B_VerifyFinal");
749 goto abort;
750 }
751 crtn = CSSM_OK;
752 abort:
753 B_DestroyAlgorithmObject(&alg);
754 return crtn;
755 #endif
756 return 0;
757 }
758
759 /*
760 * generate MAC either one update (updateSizes == NULL) or
761 * specified set of update sizes.
762 */
763 #define MAX_MAC_SIZE 20
764
765 CSSM_RETURN buGenMac(
766 BU_KEY key, // any key, any size
767 CSSM_ALGORITHMS macAlg, // only CSSM_ALGID_SHA1HMAC for now
768 const CSSM_DATA *ptext,
769 unsigned *updateSizes, // NULL --> random updates
770 // else null-terminated list of sizes
771 CSSM_DATA_PTR mac) // mallocd and RETURNED
772 {
773 #if 0 // NO MORE BSAFE
774 B_ALGORITHM_OBJ alg = NULL;
775 int brtn;
776 CSSM_RETURN crtn;
777 B_DIGEST_SPECIFIER digestInfo;
778 B_INFO_TYPE infoType;
779 unsigned macBytes;
780
781 brtn = B_CreateAlgorithmObject(&alg);
782 if(brtn) {
783 return buBsafeErrToCssm(brtn, "B_CreateAlgorithmObject");
784 }
785 switch(macAlg) {
786 case CSSM_ALGID_SHA1HMAC:
787 case CSSM_ALGID_SHA1HMAC_LEGACY:
788 digestInfo.digestInfoType = AI_SHA1;
789 infoType = AI_HMAC;
790 break;
791 default:
792 printf("buGenMac: alg not supported\n");
793 return CSSMERR_CSSM_FUNCTION_NOT_IMPLEMENTED;
794 }
795 digestInfo.digestInfoParams = NULL;
796 brtn = B_SetAlgorithmInfo(alg, infoType, (POINTER)&digestInfo);
797 if(brtn) {
798 crtn = buBsafeErrToCssm(brtn, "B_SetAlgorithmInfo");
799 goto abort;
800 }
801 brtn = B_DigestInit(alg, (B_KEY_OBJ)key, BSAFE_ALGORITHM_CHOOSER, NULL);
802 if(brtn) {
803 crtn = buBsafeErrToCssm(brtn, "B_DigestInit");
804 goto abort;
805 }
806 if(updateSizes) {
807 uint8 *currData = ptext->Data;
808 while(*updateSizes) {
809 brtn = B_DigestUpdate(alg, currData, *updateSizes, NULL);
810 if(brtn) {
811 crtn = buBsafeErrToCssm(brtn, "B_DigestUpdate");
812 goto abort;
813 }
814 currData += *updateSizes;
815 updateSizes++;
816 }
817 }
818 else {
819 /* one-shot */
820 brtn = B_DigestUpdate(alg, ptext->Data, ptext->Length, NULL);
821 if(brtn) {
822 crtn = buBsafeErrToCssm(brtn, "B_DigestUpdate");
823 goto abort;
824 }
825 }
826 /* prepare for mac, magically gleaned max size */
827 macBytes = MAX_MAC_SIZE;
828 mac->Data = (uint8 *)CSSM_MALLOC(macBytes);
829 mac->Length = macBytes;
830
831 brtn = B_DigestFinal(alg, mac->Data, &macBytes, macBytes, NULL);
832 if(brtn) {
833 crtn = buBsafeErrToCssm(brtn, "B_DigestFinal");
834 goto abort;
835 }
836 mac->Length = macBytes;
837 crtn = CSSM_OK;
838 abort:
839 B_DestroyAlgorithmObject(&alg);
840 return crtn;
841 #endif
842 return 0;
843 }
844
845 /* generate digest */
846 #define MAX_DIGEST_SIZE 20
847
848 CSSM_RETURN buGenDigest(
849 CSSM_ALGORITHMS macAlg, // CSSM_ALGID_SHA1, etc. */
850 const CSSM_DATA *ptext,
851 CSSM_DATA_PTR digest) // mallocd and RETURNED
852 {
853 #if 0 // NO MORE BSAFE
854 B_ALGORITHM_OBJ alg = NULL;
855 int brtn;
856 CSSM_RETURN crtn;
857 B_INFO_TYPE infoType;
858 unsigned hashBytes;
859
860 brtn = B_CreateAlgorithmObject(&alg);
861 if(brtn) {
862 return buBsafeErrToCssm(brtn, "B_CreateAlgorithmObject");
863 }
864 switch(macAlg) {
865 case CSSM_ALGID_SHA1:
866 infoType = AI_SHA1;
867 break;
868 case CSSM_ALGID_MD5:
869 infoType = AI_MD5;
870 break;
871 case CSSM_ALGID_MD2:
872 infoType = AI_MD2;
873 break;
874 default:
875 printf("buGenDigest: alg not supported\n");
876 return CSSMERR_CSSM_FUNCTION_NOT_IMPLEMENTED;
877 }
878 brtn = B_SetAlgorithmInfo(alg, infoType, NULL);
879 if(brtn) {
880 crtn = buBsafeErrToCssm(brtn, "B_SetAlgorithmInfo");
881 goto abort;
882 }
883 brtn = B_DigestInit(alg, NULL, BSAFE_ALGORITHM_CHOOSER, NULL);
884 if(brtn) {
885 crtn = buBsafeErrToCssm(brtn, "B_DigestInit");
886 goto abort;
887 }
888 brtn = B_DigestUpdate(alg, ptext->Data, ptext->Length, NULL);
889 if(brtn) {
890 crtn = buBsafeErrToCssm(brtn, "B_DigestUpdate");
891 goto abort;
892 }
893
894 /* prepare for digest, magically gleaned max size */
895 hashBytes = MAX_DIGEST_SIZE;
896 digest->Data = (uint8 *)CSSM_MALLOC(hashBytes);
897 digest->Length = hashBytes;
898
899 brtn = B_DigestFinal(alg, digest->Data, &hashBytes, hashBytes, NULL);
900 if(brtn) {
901 crtn = buBsafeErrToCssm(brtn, "B_DigestFinal");
902 goto abort;
903 }
904 digest->Length = hashBytes;
905 crtn = CSSM_OK;
906 abort:
907 B_DestroyAlgorithmObject(&alg);
908 return crtn;
909 #else
910 return 0;
911 #endif
912 }
913
914 /*
915 * Convert between BSAFE and CDSA private keys
916 */
917 CSSM_RETURN buBsafePrivKeyToCdsa(
918 CSSM_ALGORITHMS keyAlg,
919 uint32 keySizeInBits,
920 BU_KEY bsafePrivKey,
921 CSSM_KEY_PTR cdsaPrivKey)
922 {
923 #if 0 // NO MORE BSAFE
924 B_INFO_TYPE infoType;
925 ITEM *keyBlob;
926 int brtn;
927 CSSM_KEYBLOB_FORMAT format;
928 CSSM_KEYHEADER_PTR hdr = &cdsaPrivKey->KeyHeader;
929
930 /* what kind of info? */
931 switch(keyAlg) {
932 case CSSM_ALGID_RSA:
933 infoType = KI_PKCS_RSAPrivateBER;
934 format = CSSM_KEYBLOB_RAW_FORMAT_PKCS8;
935 break;
936 case CSSM_ALGID_DSA:
937 infoType = KI_DSAPrivateBER;
938 format = CSSM_KEYBLOB_RAW_FORMAT_FIPS186;
939 break;
940 default:
941 printf("***buBsafePrivKeyToCdsa: bogus keyAlg\n");
942 return CSSMERR_CSSM_FUNCTION_NOT_IMPLEMENTED;
943 }
944
945 /* get the blob */
946 brtn = B_GetKeyInfo((POINTER *)&keyBlob,
947 (B_KEY_OBJ)bsafePrivKey,
948 infoType);
949 if(brtn) {
950 return buBsafeErrToCssm(brtn, "B_GetKeyInfo");
951 }
952
953 /* copy blob to CDSA key */
954 cdsaPrivKey->KeyData.Data = (uint8 *)CSSM_MALLOC(keyBlob->len);
955 cdsaPrivKey->KeyData.Length = keyBlob->len;
956 memmove(cdsaPrivKey->KeyData.Data, keyBlob->data, keyBlob->len);
957
958 /* set up CSSM key header */
959 memset(hdr, 0, sizeof(CSSM_KEYHEADER));
960 hdr->HeaderVersion = CSSM_KEYHEADER_VERSION;
961 hdr->BlobType = CSSM_KEYBLOB_RAW;
962 hdr->Format = format;
963 hdr->AlgorithmId = keyAlg;
964 hdr->KeyClass = CSSM_KEYCLASS_PRIVATE_KEY;
965 hdr->LogicalKeySizeInBits = keySizeInBits;
966 hdr->KeyAttr = CSSM_KEYATTR_EXTRACTABLE;
967 hdr->KeyUsage = CSSM_KEYUSE_ANY;
968 #endif
969 return CSSM_OK;
970 }
971
972 CSSM_RETURN buCdsaPrivKeyToBsafe(
973 CSSM_KEY_PTR cdsaPrivKey,
974 BU_KEY *bsafePrivKey)
975 {
976 #if 0 // NO MORE BSAFE
977 int brtn;
978 B_KEY_OBJ privKey = NULL;
979 ITEM keyBlob;
980 B_INFO_TYPE infoType;
981
982 /* what kind of info? */
983 switch(cdsaPrivKey->KeyHeader.AlgorithmId) {
984 case CSSM_ALGID_RSA:
985 infoType = KI_PKCS_RSAPrivateBER;
986 break;
987 case CSSM_ALGID_DSA:
988 infoType = KI_DSAPrivateBER;
989 break;
990 default:
991 printf("***buCdsaPrivKeyToCssm: bogus keyAlg\n");
992 return CSSMERR_CSSM_FUNCTION_NOT_IMPLEMENTED;
993 }
994
995 /* create caller's key, assign blob to it */
996 brtn = B_CreateKeyObject(&privKey);
997 if(brtn) {
998 return buBsafeErrToCssm(brtn, "B_CreateKeyObject");
999 }
1000 buCssmDataToItem(&cdsaPrivKey->KeyData, &keyBlob);
1001 brtn = B_SetKeyInfo(privKey, infoType, (POINTER)&keyBlob);
1002 if(brtn) {
1003 return buBsafeErrToCssm(brtn, "B_SetKeyInfo");
1004 }
1005 *bsafePrivKey = privKey;
1006 #endif
1007 return CSSM_OK;
1008 }
1009