1 /* Copyright (c) 1998,2003-2005,2008 Apple Inc.
3 * wrapTest.c - wrap/unwrap exerciser.
7 * 4 May 2000 Doug Mitchell
9 * 6 Aug 1998 Doug Mitchell at Apple
17 #include <Security/cssm.h>
20 #include "cspdlTesting.h"
23 * Currently the CSP can use wrapping keys flagged exclusively for wrapping
24 * (CSSM_KEYUSE_{WRAP,UNWRAP} for the actual wrap sinceĆthe wrp/unwrap op is
25 * done with an encrypt/decrypt op. The WrapKey op doesn't even see the
26 * wrapping key - it's in the context we pass it. Thus for now wrap/unwrap
27 * keys have to be marked with CSSM_KEYUSE_ANY.
29 #define WRAP_USAGE_ANY 0
32 * When false, the CMS wrap algorithm can't deal with RSA encryption - we
33 * have to encrypt something twice with the same key. An impossibility with
34 * BSAFE-based RSA encryption because the output of the first encrypt is
35 * the size of the key modulus, and you can't encrypt something that big
37 * This is not a limitation with openssl-based RSA.
39 #define WRAP_WITH_RSA 1
42 * When false, can't wrap with RC4 because the RC4 context is stateful
43 * but doesn't get reinit'd for the second CMS encrypt.
45 #define WRAP_WITH_RC4 1
48 * Temporary hack to use CSSM_KEYBLOB_WRAPPED_FORMAT_{PKCS7,PKCS8}, which
49 * are no longer supported as of 7/28/00
51 #define PKCS7_FORMAT_ENABLE 1 // for wrapping symmetric keys
52 #define PKCS8_FORMAT_ENABLE 1 // for wrapping private keys
55 #define ENCR_LABEL "encrKey"
56 #define ENCR_LABEL_LEN (strlen(ENCR_LABEL))
57 #define WRAP_LABEL "wrapKey"
58 #define WRAP_LABEL_LEN (strlen(WRAP_LABEL))
60 #define MAX_PTEXT_SIZE 100
61 #define LOOP_PAUSE 100
62 #define MAX_DESC_DATA_SIZE 16
65 * Enumerate algorithms our way to allow loop interations.
67 typedef unsigned PrivAlg
;
80 #define ALG_MIN ALG_DES
81 #define ALG_MAX_WRAP ALG_AES
82 #define ALG_MAX_ENCR ALG_AES
84 static void usage(char **argv
)
86 printf("usage: %s [options]\n", argv
[0]);
87 printf(" Options:\n");
88 printf(" w=wrapAlg (d=DES, 3=3DES, f=FEEDEXP, r=RSA, A=ASC, 4=RC4, "
90 printf(" e=encrAlg (d=DES, 3=3DES, f=FEEDEXP, r=RSA, A=ASC, 4=RC4, "
92 printf(" l=loops (default=%d; 0=forever)\n", LOOPS_DEF
);
93 printf(" r (ref keys only)\n");
94 printf(" p(ause every loop)\n");
95 printf(" D (CSP/DL; default = bare CSP)\n");
96 printf(" v(erbose)\n");
97 printf(" k (quick; small keys)\n");
102 /* wrapped format to string */
103 static const char *formatString(CSSM_KEYBLOB_FORMAT format
)
105 static char noform
[100];
108 case CSSM_KEYBLOB_WRAPPED_FORMAT_NONE
:
109 return "NONE (default)";
110 case CSSM_KEYBLOB_WRAPPED_FORMAT_PKCS7
:
112 case CSSM_KEYBLOB_WRAPPED_FORMAT_PKCS8
:
114 case CSSM_KEYBLOB_WRAPPED_FORMAT_APPLE_CUSTOM
:
115 return "APPLE_CUSTOM";
117 sprintf(noform
, "***UNKNOWN (%u)***", (unsigned)format
);
122 static int vfyWrapHeader(
123 const CSSM_KEYHEADER
*srcHdr
,
124 const CSSM_KEYHEADER
*dstHdr
,
125 CSSM_KEYBLOB_TYPE expectBlob
,
130 if(dstHdr
->BlobType
!= expectBlob
) {
131 printf("***%s.BlobType error: expect %u got %u\n",
132 op
, (unsigned)expectBlob
, (unsigned)dstHdr
->BlobType
);
133 if(testError(quiet
)) {
137 if(srcHdr
->KeyClass
!= dstHdr
->KeyClass
) {
138 printf("***%s.KeyClass error: expect %u got %u\n",
139 op
, (unsigned)srcHdr
->KeyClass
, (unsigned)dstHdr
->KeyClass
);
140 if(testError(quiet
)) {
144 if(srcHdr
->AlgorithmId
!= dstHdr
->AlgorithmId
) {
145 printf("***%s.AlgorithmId error: expect %u got %u\n",
146 op
, (unsigned)srcHdr
->AlgorithmId
, (unsigned)dstHdr
->AlgorithmId
);
147 if(testError(quiet
)) {
151 if(srcHdr
->KeyUsage
!= dstHdr
->KeyUsage
) {
152 printf("***%s.KeyUsage error: expect 0x%x got 0x%x\n",
153 op
, (unsigned)srcHdr
->KeyUsage
, (unsigned)dstHdr
->KeyUsage
);
154 if(testError(quiet
)) {
159 /* GUIDs must match */
160 if(memcmp(&srcHdr
->CspId
, &dstHdr
->CspId
, sizeof(CSSM_GUID
))) {
161 printf("***%s.CspId mismatch\n", op
);
162 if(testError(quiet
)) {
168 /* CSPDL - GUIDs do NOT match - ref keys are in the CSPDL's domain;
169 * wrapped keys are in the bare CSP's domain. */
170 if(!memcmp(&srcHdr
->CspId
, &dstHdr
->CspId
, sizeof(CSSM_GUID
))) {
171 printf("***Unexpected %s.CspId compare\n", op
);
172 if(testError(quiet
)) {
180 #define UNWRAPPED_LABEL "unwrapped thing"
181 #define SHOW_WRAP_FORMAT 0
183 /* not all algs need this */
184 CSSM_DATA initVector
= {16, (uint8
*)"SomeReallyStrangeInitVect"};
186 static int doTest(CSSM_CSP_HANDLE cspHand
,
187 CSSM_KEY_PTR encrKey
,
188 CSSM_BOOL wrapEncrKey
, // wrap encrKey before using
189 CSSM_KEY_PTR decrKey
, // we wrap this one
190 CSSM_KEY_PTR wrappingKey
, // ...using this key
191 CSSM_KEY_PTR unwrappingKey
,
192 CSSM_ALGORITHMS wrapAlg
,
193 CSSM_ENCRYPT_MODE wrapMode
,
194 CSSM_KEYBLOB_FORMAT wrapFormat
, // NONE, PKCS7, PKCS8, APPLE_CUSTOM
195 CSSM_KEYBLOB_FORMAT expectFormat
, // PKCS7, PKCS8, APPLE_CUSTOM
196 CSSM_PADDING wrapPad
,
198 CSSM_ALGORITHMS encrAlg
,
199 CSSM_ENCRYPT_MODE encrMode
,
200 CSSM_PADDING encrPad
,
202 uint32 effectiveKeySizeInBits
, // for encr/decr - 0 means none specified
204 CSSM_DATA_PTR descData
,
210 CSSM_KEY wrappedDecrKey
;
211 CSSM_KEY unwrappedDecrKey
;
212 CSSM_KEY wrappedEncrKey
;
214 CSSM_KEY_PTR actualEncrKey
;
215 uint32 maxPtextSize
= MAX_PTEXT_SIZE
;
216 CSSM_DATA outDescData1
= {0, NULL
}; // for encr key
217 CSSM_DATA outDescData2
= {0, NULL
}; // for decr key, must match descData
218 CSSM_DATA nullInitVect
= {0, NULL
}; // for custom unwrap
219 CSSM_DATA_PTR wrapIvp
;
220 CSSM_DATA_PTR encrIvp
;
222 /* Hack to deal with RSA's max encrypt size */
225 if(encrAlg
== CSSM_ALGID_RSA
) {
226 uint32 keySizeBytes
= encrKey
->KeyHeader
.LogicalKeySizeInBits
/ 8;
227 maxPtextSize
= keySizeBytes
- 11;
228 if(maxPtextSize
> MAX_PTEXT_SIZE
) {
229 maxPtextSize
= MAX_PTEXT_SIZE
;
233 maxPtextSize
= MAX_PTEXT_SIZE
;
236 simpleGenData(ptext
, 1, maxPtextSize
);
239 * Optionaly wrap/unwrap encrKey. If encrKey is a ref key, do a
240 * NULL wrap. If encrKey is a raw key, do a NULL unwrap.
243 CSSM_KEYBLOB_TYPE expectBlob
;
245 if(encrKey
->KeyHeader
.BlobType
== CSSM_KEYBLOB_REFERENCE
) {
246 crtn
= cspWrapKey(cspHand
,
256 expectBlob
= CSSM_KEYBLOB_RAW
;
259 crtn
= cspUnwrapKey(cspHand
,
261 NULL
, // unwrappingKey
270 expectBlob
= CSSM_KEYBLOB_REFERENCE
;
273 return testError(quiet
);
275 if(vfyWrapHeader(&encrKey
->KeyHeader
,
276 &wrappedEncrKey
.KeyHeader
,
283 actualEncrKey
= &wrappedEncrKey
;
286 actualEncrKey
= encrKey
;
288 /* encrypt using actualEncrKey ==> ctext */
292 initVector
.Length
= encrIvSize
;
293 encrIvp
= &initVector
;
298 crtn
= cspEncrypt(cspHand
,
304 effectiveKeySizeInBits
,
309 CSSM_TRUE
); // mallocCtext
311 return testError(quiet
);
313 /* wrap decrKey using wrappingKey ==> wrappedDecrKey */
314 /* Note that APPLE_CUSTOM wrap alg REQUIRES an 8-byte IV */
315 if(expectFormat
== CSSM_KEYBLOB_WRAPPED_FORMAT_APPLE_CUSTOM
) {
316 initVector
.Length
= 8;
319 initVector
.Length
= wrapIvSize
;
321 crtn
= cspWrapKey(cspHand
,
332 return testError(quiet
);
334 if(wrapAlg
!= CSSM_ALGID_NONE
) {
335 if(wrappedDecrKey
.KeyHeader
.Format
!= expectFormat
) {
336 printf("***Wrap format mismatch expect %s got %s\n",
337 formatString(wrappedDecrKey
.KeyHeader
.Format
),
338 formatString(expectFormat
));
339 if(testError(quiet
)) {
345 if(vfyWrapHeader(&decrKey
->KeyHeader
,
346 &wrappedDecrKey
.KeyHeader
,
347 (wrapAlg
== CSSM_ALGID_NONE
) ? CSSM_KEYBLOB_RAW
: CSSM_KEYBLOB_WRAPPED
,
354 if(wrappedDecrKey
.KeyHeader
.Format
== CSSM_KEYBLOB_WRAPPED_FORMAT_APPLE_CUSTOM
) {
355 /* special case - no IV needed - test it */
356 wrapIvp
= &nullInitVect
;
359 wrapIvp
= &initVector
;
360 initVector
.Length
= wrapIvSize
;
363 /* unwrap wrappedDecrKey using unwrappingKey ==> unwrappedDecrKey; */
364 crtn
= cspUnwrapKey(cspHand
,
376 return testError(quiet
);
379 if(vfyWrapHeader(&wrappedDecrKey
.KeyHeader
,
380 &unwrappedDecrKey
.KeyHeader
,
381 CSSM_KEYBLOB_REFERENCE
,
388 /* compare descData to outDescData2 */
390 if(descData
->Length
!= outDescData2
.Length
) {
391 printf("descData length mismatch\n");
392 if(testError(quiet
)) {
396 if(memcmp(descData
->Data
, outDescData2
.Data
, outDescData2
.Length
)) {
397 printf("***descDatadata miscompare\n");
398 if(testError(quiet
)) {
404 /* decrypt ctext with unwrappedDecrKey ==> rptext; */
408 initVector
.Length
= encrIvSize
;
410 crtn
= cspDecrypt(cspHand
,
416 effectiveKeySizeInBits
,
423 return testError(quiet
);
425 /* compare ptext vs. rptext; */
426 if(ptext
->Length
!= rptext
.Length
) {
427 printf("ptext length mismatch\n");
428 return testError(quiet
);
430 if(memcmp(ptext
->Data
, rptext
.Data
, ptext
->Length
)) {
431 printf("***data miscompare\n");
432 return testError(quiet
);
435 cspFreeKey(cspHand
, &wrappedDecrKey
);
436 cspFreeKey(cspHand
, &unwrappedDecrKey
);
438 cspFreeKey(cspHand
, actualEncrKey
);
440 CSSM_FREE(ctext
.Data
);
441 CSSM_FREE(rptext
.Data
);
442 if(outDescData2
.Data
!= NULL
) {
443 CSSM_FREE(outDescData2
.Data
);
445 if(outDescData1
.Data
!= NULL
) {
446 CSSM_FREE(outDescData1
.Data
);
452 * values associated with a private algorithm (e.g., ALG_DES).
463 CSSM_ALGORITHMS encrAlg
;
464 CSSM_ENCRYPT_MODE encrMode
;
465 CSSM_PADDING encrPad
;
466 uint32 ivSize
; // in bytes; 0 means no IV
471 * Convert our private alg to CDSA keygen alg, encr alg, encr mode, pad
473 static void getAlgInfo(PrivAlg privAlg
, // e.g., ALG_DES
478 algInfo
->keyGenAlg
= CSSM_ALGID_DES
;
479 algInfo
->wtype
= WT_Symmetric
;
480 algInfo
->encrAlg
= CSSM_ALGID_DES
;
481 algInfo
->encrMode
= CSSM_ALGMODE_CBCPadIV8
;
482 algInfo
->encrPad
= CSSM_PADDING_PKCS5
;
484 algInfo
->algName
= "DES";
487 algInfo
->keyGenAlg
= CSSM_ALGID_3DES_3KEY
;
488 algInfo
->wtype
= WT_Symmetric
;
489 algInfo
->encrAlg
= CSSM_ALGID_3DES_3KEY_EDE
;
490 algInfo
->encrMode
= CSSM_ALGMODE_CBCPadIV8
;
491 algInfo
->encrPad
= CSSM_PADDING_PKCS5
;
493 algInfo
->algName
= "3DES";
496 algInfo
->keyGenAlg
= CSSM_ALGID_FEE
;
497 algInfo
->wtype
= WT_Asymmetric
;
498 algInfo
->encrAlg
= CSSM_ALGID_FEEDEXP
;
499 algInfo
->encrMode
= CSSM_ALGMODE_NONE
;
500 algInfo
->encrPad
= CSSM_PADDING_NONE
;
502 algInfo
->algName
= "FEEDEXP";
505 algInfo
->keyGenAlg
= CSSM_ALGID_RSA
;
506 algInfo
->wtype
= WT_Asymmetric
;
507 algInfo
->encrAlg
= CSSM_ALGID_RSA
;
508 algInfo
->encrMode
= CSSM_ALGMODE_NONE
;
509 algInfo
->encrPad
= CSSM_PADDING_PKCS1
;
511 algInfo
->algName
= "RSA";
514 algInfo
->keyGenAlg
= CSSM_ALGID_ASC
;
515 algInfo
->wtype
= WT_Symmetric
;
516 algInfo
->encrAlg
= CSSM_ALGID_ASC
;
517 algInfo
->encrMode
= CSSM_ALGMODE_NONE
;
518 algInfo
->encrPad
= CSSM_PADDING_NONE
;
520 algInfo
->algName
= "ASC";
523 algInfo
->keyGenAlg
= CSSM_ALGID_RC2
;
524 algInfo
->wtype
= WT_Symmetric
;
525 algInfo
->encrAlg
= CSSM_ALGID_RC2
;
526 algInfo
->encrMode
= CSSM_ALGMODE_CBCPadIV8
;
527 algInfo
->encrPad
= CSSM_PADDING_PKCS5
;
529 algInfo
->algName
= "RC2";
532 algInfo
->keyGenAlg
= CSSM_ALGID_RC4
;
533 algInfo
->wtype
= WT_Symmetric
;
534 algInfo
->encrAlg
= CSSM_ALGID_RC4
;
535 algInfo
->encrMode
= CSSM_ALGMODE_CBCPadIV8
;
536 algInfo
->encrPad
= CSSM_PADDING_PKCS5
;
538 algInfo
->algName
= "RC4";
541 algInfo
->keyGenAlg
= CSSM_ALGID_NONE
;
542 algInfo
->wtype
= WT_Null
;
543 algInfo
->encrAlg
= CSSM_ALGID_NONE
;
544 algInfo
->encrMode
= CSSM_ALGMODE_NONE
;
545 algInfo
->encrPad
= CSSM_PADDING_NONE
;
547 algInfo
->algName
= "Null";
550 algInfo
->keyGenAlg
= CSSM_ALGID_AES
;
551 algInfo
->wtype
= WT_Symmetric
;
552 algInfo
->encrAlg
= CSSM_ALGID_AES
;
553 algInfo
->encrMode
= CSSM_ALGMODE_CBCPadIV8
;
554 algInfo
->encrPad
= CSSM_PADDING_PKCS7
;
555 algInfo
->ivSize
= 16;
556 algInfo
->algName
= "AES";
559 printf("Bogus privAlg\n");
565 /* argv letter to private alg */
566 static PrivAlg
letterToAlg(char **argv
, char letter
)
569 case 'd': return ALG_DES
;
570 case '3': return ALG_3DES
;
571 case 'f': return ALG_FEEDEXP
;
572 case 'r': return ALG_RSA
;
573 case 'A': return ALG_ASC
;
574 case '4': return ALG_RC4
;
575 case 'a': return ALG_AES
;
583 * Null wrapping of symmetric keys now allowed
585 #define SYMM_NULL_WRAP_ENABLE 1
587 /* indices into algInfo[] */
591 int main(int argc
, char **argv
)
596 CSSM_CSP_HANDLE cspHand
;
599 uint32 encrKeySizeBits
; // well aligned
600 uint32 wrapKeySizeBits
;
601 uint32 effectiveKeySizeInBits
; // for encr, may be odd
603 uint32 maxRsaKeySize
= 1024;
604 uint32 maxFeeKeySize
= 192;
605 CSSM_KEYBLOB_FORMAT wrapFormat
; // NONE, PKCS7, PKCS8, APPLE_CUSTOM
606 CSSM_KEYBLOB_FORMAT expectFormat
; // PKCS7, PKCS8, APPLE_CUSTOM
607 CSSM_DATA descData
= {0, NULL
};
608 CSSM_DATA_PTR descDataP
;
611 * key pointers passed to doTest() - for symmetric algs, the pairs
612 * might point to the same key
614 CSSM_KEY_PTR encrKeyPtr
;
615 CSSM_KEY_PTR decrKeyPtr
;
616 CSSM_KEY_PTR wrapKeyPtr
;
617 CSSM_KEY_PTR unwrapKeyPtr
;
619 /* persistent asymmetric keys - symm keys are dynamically allocated */
621 CSSM_KEY privEncrKey
;
623 CSSM_KEY privWrapKey
;
625 /* we iterate these values thru all possible algs */
626 PrivAlg privEncrAlg
; // ALG_xxx
629 /* two AlgInfo which contain everything we need to know per alg */
633 CSSM_BOOL wrapEncrKey
= CSSM_FALSE
; // varies loop-to-loop
634 CSSM_BOOL encrKeyIsRef
= CSSM_TRUE
; // ditto
636 CSSM_BOOL genSeed
; // for FEE key gen
639 /* user-specified vars */
640 unsigned loops
= LOOPS_DEF
;
641 CSSM_BOOL pause
= CSSM_FALSE
;
642 CSSM_BOOL verbose
= CSSM_FALSE
;
643 PrivAlg minWrapAlg
= ALG_MIN
;
644 PrivAlg maxWrapAlg
= ALG_MAX_WRAP
;
645 PrivAlg minEncrAlg
= ALG_MIN
;
646 PrivAlg maxEncrAlg
= ALG_MAX_ENCR
;
647 CSSM_BOOL quick
= CSSM_FALSE
;
648 CSSM_BOOL quiet
= CSSM_FALSE
;
649 CSSM_BOOL bareCsp
= CSSM_TRUE
;
650 CSSM_BOOL refKeysOnly
= CSSM_FALSE
;
652 for(arg
=1; arg
<argc
; arg
++) {
657 minWrapAlg
= maxWrapAlg
= ALG_NULL
;
660 minWrapAlg
= maxWrapAlg
= letterToAlg(argv
, argp
[2]);
664 minEncrAlg
= maxEncrAlg
= letterToAlg(argv
, argp
[2]);
667 loops
= atoi(&argp
[2]);
676 bareCsp
= CSSM_FALSE
;
677 #if CSPDL_ALL_KEYS_ARE_REF
678 refKeysOnly
= CSSM_TRUE
;
682 refKeysOnly
= CSSM_TRUE
;
696 cspHand
= cspDlDbStartup(bareCsp
, NULL
);
700 wrapInfo
= &algInfo
[AI_WRAP
];
701 encrInfo
= &algInfo
[AI_ENCR
];
703 /* cook up ptext, descData */
704 ptext
.Data
= (uint8
*)CSSM_MALLOC(MAX_PTEXT_SIZE
);
705 descData
.Data
= (uint8
*)CSSM_MALLOC(MAX_DESC_DATA_SIZE
);
707 printf("Starting wrapTest; args: ");
708 for(i
=1; i
<argc
; i
++) {
709 printf("%s ", argv
[i
]);
713 for(loop
=0; loop
<loops
; loop
++) {
715 printf("...loop %d\n", loop
);
719 printf("Hit CR to proceed: ");
723 /* iterate thru all encryption algs */
724 for(privEncrAlg
=minEncrAlg
; privEncrAlg
<=maxEncrAlg
; privEncrAlg
++) {
725 /* handle disabled algs */
726 switch(privEncrAlg
) {
727 case ALG_NULL
: /* just skip this one, it's just for wrap */
733 /* generate key(s) to be wrapped */
734 getAlgInfo(privEncrAlg
, encrInfo
);
735 effectiveKeySizeInBits
= randKeySizeBits(encrInfo
->keyGenAlg
, OT_Encrypt
);
737 encrKeyIsRef
= (loop
& 2) ? CSSM_TRUE
: CSSM_FALSE
;
740 switch(encrInfo
->wtype
) {
742 /* round up to even byte */
743 encrKeySizeBits
= (effectiveKeySizeInBits
+ 7) & ~7;
744 if(encrKeySizeBits
== effectiveKeySizeInBits
) {
745 effectiveKeySizeInBits
= 0;
747 encrKeyPtr
= decrKeyPtr
= cspGenSymKey(cspHand
,
751 CSSM_KEYUSE_ENCRYPT
| CSSM_KEYUSE_DECRYPT
,
754 if(encrKeyPtr
== NULL
) {
758 #if SYMM_NULL_WRAP_ENABLE
759 /* wrapEncrKey every other loop */
761 wrapEncrKey
= (loop
& 1) ? CSSM_TRUE
: CSSM_FALSE
;
764 wrapEncrKey
= CSSM_FALSE
;
765 #endif /* SYMM_NULL_WRAP_ENABLE */
768 /* handle alg-specific cases */
769 genSeed
= CSSM_FALSE
;
770 switch(privEncrAlg
) {
772 if(effectiveKeySizeInBits
> maxRsaKeySize
) {
773 effectiveKeySizeInBits
= maxRsaKeySize
;
777 if(effectiveKeySizeInBits
> maxFeeKeySize
) {
778 effectiveKeySizeInBits
= maxFeeKeySize
;
787 encrKeySizeBits
= effectiveKeySizeInBits
;
788 effectiveKeySizeInBits
= 0; // i.e., not specified
789 crtn
= cspGenKeyPair(cspHand
,
795 encrKeyIsRef
, // pubIsRef
797 CSSM_KEYBLOB_RAW_FORMAT_NONE
,
799 CSSM_TRUE
, // privIsRef
801 CSSM_KEYBLOB_RAW_FORMAT_NONE
,
804 rtn
= testError(quiet
);
807 encrKeyPtr
= &pubEncrKey
;
808 decrKeyPtr
= &privEncrKey
;
809 /* wrapEncrKey every other loop */
811 wrapEncrKey
= (loop
& 1) ? CSSM_TRUE
: CSSM_FALSE
;
815 printf("***BRRZAP: can't do null encrypt\n");
819 printf(" ...encrAlg %s wrapEncrKey %d encrKeyIsRef %d size %u "
820 "bits effectSize %u\n",
821 encrInfo
->algName
, (int)wrapEncrKey
, (int)encrKeyIsRef
,
822 (unsigned)encrKeySizeBits
, (unsigned)effectiveKeySizeInBits
);
824 /* iterate thru all wrap algs */
825 for(privWrapAlg
=minWrapAlg
; privWrapAlg
<=maxWrapAlg
; privWrapAlg
++) {
826 /* handle disabled algs */
827 if((privWrapAlg
== ALG_AES
) && (privEncrAlg
== ALG_FEEDEXP
)) {
829 * Can't do it. FEED can't do PKCS8 because it doesn't
830 * support PKCS8 private key format, and AES can't
831 * do APPLE_CUSTOM because AES needs a 16-byte IV.
835 /* any other restrictions/ */
837 /* generate wrapping key(s) */
838 getAlgInfo(privWrapAlg
, wrapInfo
);
839 switch(wrapInfo
->wtype
) {
841 /* note we can't do odd-size wrapping keys */
842 wrapKeySizeBits
= randKeySizeBits(wrapInfo
->keyGenAlg
,
844 wrapKeySizeBits
&= ~7;
845 wrapKeyPtr
= unwrapKeyPtr
= cspGenSymKey(cspHand
,
849 WRAP_USAGE_ANY
? CSSM_KEYUSE_ANY
:
850 CSSM_KEYUSE_WRAP
| CSSM_KEYUSE_UNWRAP
,
853 if(wrapKeyPtr
== NULL
) {
859 wrapKeySizeBits
= randKeySizeBits(wrapInfo
->keyGenAlg
,
861 genSeed
= CSSM_FALSE
;
862 switch(privWrapAlg
) {
864 if(wrapKeySizeBits
> maxRsaKeySize
) {
865 wrapKeySizeBits
= maxRsaKeySize
;
869 if(wrapKeySizeBits
> maxFeeKeySize
) {
870 wrapKeySizeBits
= maxFeeKeySize
;
879 crtn
= cspGenKeyPair(cspHand
,
885 CSSM_TRUE
, // pubIsRef
886 WRAP_USAGE_ANY
? CSSM_KEYUSE_ANY
: CSSM_KEYUSE_WRAP
,
887 CSSM_KEYBLOB_RAW_FORMAT_NONE
,
889 CSSM_TRUE
, // privIsRef
890 WRAP_USAGE_ANY
? CSSM_KEYUSE_ANY
: CSSM_KEYUSE_UNWRAP
,
891 CSSM_KEYBLOB_RAW_FORMAT_NONE
,
894 rtn
= testError(quiet
);
897 wrapKeyPtr
= &pubWrapKey
;
898 unwrapKeyPtr
= &privWrapKey
;
901 #if !SYMM_NULL_WRAP_ENABLE
902 if(encrInfo
->wtype
== WT_Symmetric
) {
903 /* can't do null wrap of symmetric key */
913 /* special case for 3DES/3DES */
915 if((wrapKeyPtr
!= NULL
) &&
916 (wrapKeyPtr
->KeyHeader
.AlgorithmId
== CSSM_ALGID_3DES_3KEY
) &&
917 (decrKeyPtr
->KeyHeader
.AlgorithmId
== CSSM_ALGID_3DES_3KEY
)) {
918 isAppleCustom
= CSSM_TRUE
;
921 isAppleCustom
= CSSM_FALSE
;
925 /* cook up a wrapFormat - every other loop use default, others
926 * specify a reasonable one */
927 if(wrapInfo
->wtype
== WT_Null
) {
928 wrapFormat
= expectFormat
= CSSM_KEYBLOB_WRAPPED_FORMAT_NONE
;
930 else if((loop
& 1)) {
932 * FORMAT_NONE - default - figure out expected format;
933 * this has to track CSP behavior
935 wrapFormat
= CSSM_KEYBLOB_WRAPPED_FORMAT_NONE
;
936 switch(encrInfo
->wtype
) {
938 expectFormat
= CSSM_KEYBLOB_WRAPPED_FORMAT_PKCS7
;
941 if(privEncrAlg
== ALG_FEEDEXP
) {
942 expectFormat
= CSSM_KEYBLOB_WRAPPED_FORMAT_APPLE_CUSTOM
;
945 expectFormat
= CSSM_KEYBLOB_WRAPPED_FORMAT_PKCS8
;
949 /* NULL encr not done */
950 printf("**GAK! Internal error\n");
954 /* pick a good explicit one - this encapsulates the
955 * range of legal wrap formats per wrap/encrypt alg */
957 switch(encrInfo
->wtype
) {
959 if(privWrapAlg
== ALG_AES
) {
960 /* can't do APPLE_CUSTOM - 16 byte IV */
961 wrapFormat
= CSSM_KEYBLOB_WRAPPED_FORMAT_PKCS7
;
964 wrapFormat
= CSSM_KEYBLOB_WRAPPED_FORMAT_PKCS7
;
967 wrapFormat
= CSSM_KEYBLOB_WRAPPED_FORMAT_APPLE_CUSTOM
;
971 /* Can't wrap FEE key with AES no way, no how -
972 * this is detected at the top of the privWrapAlg
975 if(privEncrAlg
== ALG_FEEDEXP
) {
976 /* FEE doesn't do PKCS8 private key format */
977 wrapFormat
= CSSM_KEYBLOB_WRAPPED_FORMAT_APPLE_CUSTOM
;
980 wrapFormat
= CSSM_KEYBLOB_WRAPPED_FORMAT_PKCS8
;
982 else if(privWrapAlg
== ALG_AES
) {
983 /* AES can't do APPLE_CUSTOM - 16 byte IV */
984 wrapFormat
= CSSM_KEYBLOB_WRAPPED_FORMAT_PKCS8
;
987 wrapFormat
= CSSM_KEYBLOB_WRAPPED_FORMAT_APPLE_CUSTOM
;
991 /* NULL encr not done */
992 printf("***GAK! Internal error\n");
995 expectFormat
= wrapFormat
;
999 * If wrapping with apple custom - either by default or
1000 * explicitly - generate some descriptive data.
1002 if(expectFormat
== CSSM_KEYBLOB_WRAPPED_FORMAT_APPLE_CUSTOM
) {
1003 simpleGenData(&descData
, 1, MAX_DESC_DATA_SIZE
);
1004 descDataP
= &descData
;
1011 printf(" ...wrapAlg = %s size %u bits format %s expect %s\n",
1012 wrapInfo
->algName
, (unsigned)wrapKeySizeBits
, formatString(wrapFormat
),
1013 formatString(expectFormat
));
1015 /* OK, here we go! */
1032 effectiveKeySizeInBits
,
1040 /* end of wrap alg loop - free/delete wrap key(s) */
1041 switch(wrapInfo
->wtype
) {
1043 cspFreeKey(cspHand
, wrapKeyPtr
);
1044 /* mallocd by cspGenSymKey */
1045 CSSM_FREE(wrapKeyPtr
);
1048 cspFreeKey(cspHand
, wrapKeyPtr
);
1049 cspFreeKey(cspHand
, unwrapKeyPtr
);
1055 /* end of encr alg loop - free encr key(s) */
1056 cspFreeKey(cspHand
, encrKeyPtr
);
1057 if(encrInfo
->wtype
== WT_Symmetric
) {
1058 /* mallocd by cspGenSymKey */
1059 CSSM_FREE(decrKeyPtr
);
1062 cspFreeKey(cspHand
, decrKeyPtr
);
1067 cspShutdown(cspHand
, bareCsp
);
1070 printf("ModuleDetach/Unload complete; hit CR to exit: ");
1073 if((rtn
== 0) && !quiet
) {
1074 printf("%s test complete\n", argv
[0]);