+++ /dev/null
-/* Copyright (c) 1998,2003-2005,2008 Apple Inc.
- *
- * wrapTest.c - wrap/unwrap exerciser.
- *
- * Revision History
- * ----------------
- * 4 May 2000 Doug Mitchell
- * Ported to X/CDSA2.
- * 6 Aug 1998 Doug Mitchell at Apple
- * Created.
- */
-
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <time.h>
-#include <Security/cssm.h>
-#include "cspwrap.h"
-#include "common.h"
-#include "cspdlTesting.h"
-
-/*
- * Currently the CSP can use wrapping keys flagged exclusively for wrapping
- * (CSSM_KEYUSE_{WRAP,UNWRAP} for the actual wrap sinceĆthe wrp/unwrap op is
- * done with an encrypt/decrypt op. The WrapKey op doesn't even see the
- * wrapping key - it's in the context we pass it. Thus for now wrap/unwrap
- * keys have to be marked with CSSM_KEYUSE_ANY.
- */
-#define WRAP_USAGE_ANY 0
-
-/*
- * When false, the CMS wrap algorithm can't deal with RSA encryption - we
- * have to encrypt something twice with the same key. An impossibility with
- * BSAFE-based RSA encryption because the output of the first encrypt is
- * the size of the key modulus, and you can't encrypt something that big
- * with that key.
- * This is not a limitation with openssl-based RSA.
- */
-#define WRAP_WITH_RSA 1
-
-/*
- * When false, can't wrap with RC4 because the RC4 context is stateful
- * but doesn't get reinit'd for the second CMS encrypt.
- */
-#define WRAP_WITH_RC4 1
-
-/*
- * Temporary hack to use CSSM_KEYBLOB_WRAPPED_FORMAT_{PKCS7,PKCS8}, which
- * are no longer supported as of 7/28/00
- */
-#define PKCS7_FORMAT_ENABLE 1 // for wrapping symmetric keys
-#define PKCS8_FORMAT_ENABLE 1 // for wrapping private keys
-
-
-#define ENCR_LABEL "encrKey"
-#define ENCR_LABEL_LEN (strlen(ENCR_LABEL))
-#define WRAP_LABEL "wrapKey"
-#define WRAP_LABEL_LEN (strlen(WRAP_LABEL))
-#define LOOPS_DEF 10
-#define MAX_PTEXT_SIZE 100
-#define LOOP_PAUSE 100
-#define MAX_DESC_DATA_SIZE 16
-
-/*
- * Enumerate algorithms our way to allow loop interations.
- */
-typedef unsigned PrivAlg;
-enum {
- ALG_DES = 1,
- ALG_3DES,
- ALG_RC2,
- ALG_RC4,
- ALG_RSA,
- ALG_NULL,
- ALG_FEEDEXP,
- ALG_ASC,
- ALG_AES
-};
-
-#define ALG_MIN ALG_DES
-#define ALG_MAX_WRAP ALG_AES
-#define ALG_MAX_ENCR ALG_AES
-
-static void usage(char **argv)
-{
- printf("usage: %s [options]\n", argv[0]);
- printf(" Options:\n");
- printf(" w=wrapAlg (d=DES, 3=3DES, f=FEEDEXP, r=RSA, A=ASC, 4=RC4, "
- "a=AES, n=null)\n");
- printf(" e=encrAlg (d=DES, 3=3DES, f=FEEDEXP, r=RSA, A=ASC, 4=RC4, "
- "a=AES)\n");
- printf(" l=loops (default=%d; 0=forever)\n", LOOPS_DEF);
- printf(" r (ref keys only)\n");
- printf(" p(ause every loop)\n");
- printf(" D (CSP/DL; default = bare CSP)\n");
- printf(" v(erbose)\n");
- printf(" k (quick; small keys)\n");
- printf(" h(elp)\n");
- exit(1);
-}
-
-/* wrapped format to string */
-static const char *formatString(CSSM_KEYBLOB_FORMAT format)
-{
- static char noform[100];
-
- switch(format) {
- case CSSM_KEYBLOB_WRAPPED_FORMAT_NONE:
- return "NONE (default)";
- case CSSM_KEYBLOB_WRAPPED_FORMAT_PKCS7:
- return "PKCS7";
- case CSSM_KEYBLOB_WRAPPED_FORMAT_PKCS8:
- return "PKCS8";
- case CSSM_KEYBLOB_WRAPPED_FORMAT_APPLE_CUSTOM:
- return "APPLE_CUSTOM";
- default:
- sprintf(noform, "***UNKNOWN (%u)***", (unsigned)format);
- return noform;
- }
-}
-
-static int vfyWrapHeader(
- const CSSM_KEYHEADER *srcHdr,
- const CSSM_KEYHEADER *dstHdr,
- CSSM_KEYBLOB_TYPE expectBlob,
- const char *op,
- CSSM_BOOL bareCsp,
- int quiet)
-{
- if(dstHdr->BlobType != expectBlob) {
- printf("***%s.BlobType error: expect %u got %u\n",
- op, (unsigned)expectBlob, (unsigned)dstHdr->BlobType);
- if(testError(quiet)) {
- return 1;
- }
- }
- if(srcHdr->KeyClass != dstHdr->KeyClass) {
- printf("***%s.KeyClass error: expect %u got %u\n",
- op, (unsigned)srcHdr->KeyClass, (unsigned)dstHdr->KeyClass);
- if(testError(quiet)) {
- return 1;
- }
- }
- if(srcHdr->AlgorithmId != dstHdr->AlgorithmId) {
- printf("***%s.AlgorithmId error: expect %u got %u\n",
- op, (unsigned)srcHdr->AlgorithmId, (unsigned)dstHdr->AlgorithmId);
- if(testError(quiet)) {
- return 1;
- }
- }
- if(srcHdr->KeyUsage != dstHdr->KeyUsage) {
- printf("***%s.KeyUsage error: expect 0x%x got 0x%x\n",
- op, (unsigned)srcHdr->KeyUsage, (unsigned)dstHdr->KeyUsage);
- if(testError(quiet)) {
- return 1;
- }
- }
- if(bareCsp) {
- /* GUIDs must match */
- if(memcmp(&srcHdr->CspId, &dstHdr->CspId, sizeof(CSSM_GUID))) {
- printf("***%s.CspId mismatch\n", op);
- if(testError(quiet)) {
- return 1;
- }
- }
- }
- else {
- /* CSPDL - GUIDs do NOT match - ref keys are in the CSPDL's domain;
- * wrapped keys are in the bare CSP's domain. */
- if(!memcmp(&srcHdr->CspId, &dstHdr->CspId, sizeof(CSSM_GUID))) {
- printf("***Unexpected %s.CspId compare\n", op);
- if(testError(quiet)) {
- return 1;
- }
- }
- }
- return 0;
-}
-
-#define UNWRAPPED_LABEL "unwrapped thing"
-#define SHOW_WRAP_FORMAT 0
-
-/* not all algs need this */
-CSSM_DATA initVector = {16, (uint8 *)"SomeReallyStrangeInitVect"};
-
-static int doTest(CSSM_CSP_HANDLE cspHand,
- CSSM_KEY_PTR encrKey,
- CSSM_BOOL wrapEncrKey, // wrap encrKey before using
- CSSM_KEY_PTR decrKey, // we wrap this one
- CSSM_KEY_PTR wrappingKey, // ...using this key
- CSSM_KEY_PTR unwrappingKey,
- CSSM_ALGORITHMS wrapAlg,
- CSSM_ENCRYPT_MODE wrapMode,
- CSSM_KEYBLOB_FORMAT wrapFormat, // NONE, PKCS7, PKCS8, APPLE_CUSTOM
- CSSM_KEYBLOB_FORMAT expectFormat, // PKCS7, PKCS8, APPLE_CUSTOM
- CSSM_PADDING wrapPad,
- uint32 wrapIvSize,
- CSSM_ALGORITHMS encrAlg,
- CSSM_ENCRYPT_MODE encrMode,
- CSSM_PADDING encrPad,
- uint32 encrIvSize,
- uint32 effectiveKeySizeInBits, // for encr/decr - 0 means none specified
- CSSM_DATA_PTR ptext,
- CSSM_DATA_PTR descData,
- CSSM_BOOL quiet,
- CSSM_BOOL bareCsp)
-{
- CSSM_DATA ctext;
- CSSM_DATA rptext;
- CSSM_KEY wrappedDecrKey;
- CSSM_KEY unwrappedDecrKey;
- CSSM_KEY wrappedEncrKey;
- CSSM_RETURN crtn;
- CSSM_KEY_PTR actualEncrKey;
- uint32 maxPtextSize = MAX_PTEXT_SIZE;
- CSSM_DATA outDescData1 = {0, NULL}; // for encr key
- CSSM_DATA outDescData2 = {0, NULL}; // for decr key, must match descData
- CSSM_DATA nullInitVect = {0, NULL}; // for custom unwrap
- CSSM_DATA_PTR wrapIvp;
- CSSM_DATA_PTR encrIvp;
-
- /* Hack to deal with RSA's max encrypt size */
- #if 0
- /* no more */
- if(encrAlg == CSSM_ALGID_RSA) {
- uint32 keySizeBytes = encrKey->KeyHeader.LogicalKeySizeInBits / 8;
- maxPtextSize = keySizeBytes - 11;
- if(maxPtextSize > MAX_PTEXT_SIZE) {
- maxPtextSize = MAX_PTEXT_SIZE;
- }
- }
- else {
- maxPtextSize = MAX_PTEXT_SIZE;
- }
- #endif
- simpleGenData(ptext, 1, maxPtextSize);
-
- /*
- * Optionaly wrap/unwrap encrKey. If encrKey is a ref key, do a
- * NULL wrap. If encrKey is a raw key, do a NULL unwrap.
- */
- if(wrapEncrKey) {
- CSSM_KEYBLOB_TYPE expectBlob;
-
- if(encrKey->KeyHeader.BlobType == CSSM_KEYBLOB_REFERENCE) {
- crtn = cspWrapKey(cspHand,
- encrKey,
- NULL, // wrappingKey
- CSSM_ALGID_NONE,
- CSSM_ALGMODE_NONE,
- wrapFormat,
- CSSM_PADDING_NONE,
- NULL, // iv
- descData,
- &wrappedEncrKey);
- expectBlob = CSSM_KEYBLOB_RAW;
- }
- else {
- crtn = cspUnwrapKey(cspHand,
- encrKey,
- NULL, // unwrappingKey
- CSSM_ALGID_NONE,
- CSSM_ALGMODE_NONE,
- CSSM_PADDING_NONE,
- NULL, // iv
- &wrappedEncrKey,
- &outDescData1,
- WRAP_LABEL,
- WRAP_LABEL_LEN);
- expectBlob = CSSM_KEYBLOB_REFERENCE;
- }
- if(crtn) {
- return testError(quiet);
- }
- if(vfyWrapHeader(&encrKey->KeyHeader,
- &wrappedEncrKey.KeyHeader,
- expectBlob,
- "wrappedEncrKey",
- bareCsp,
- quiet)) {
- return 1;
- }
- actualEncrKey = &wrappedEncrKey;
- }
- else {
- actualEncrKey = encrKey;
- }
- /* encrypt using actualEncrKey ==> ctext */
- ctext.Data = NULL;
- ctext.Length = 0;
- if(encrIvSize) {
- initVector.Length = encrIvSize;
- encrIvp = &initVector;
- }
- else {
- encrIvp = NULL;
- }
- crtn = cspEncrypt(cspHand,
- encrAlg,
- encrMode,
- encrPad,
- actualEncrKey,
- NULL, // no 2nd key
- effectiveKeySizeInBits,
- 0, // rounds
- encrIvp,
- ptext,
- &ctext,
- CSSM_TRUE); // mallocCtext
- if(crtn) {
- return testError(quiet);
- }
- /* wrap decrKey using wrappingKey ==> wrappedDecrKey */
- /* Note that APPLE_CUSTOM wrap alg REQUIRES an 8-byte IV */
- if(expectFormat == CSSM_KEYBLOB_WRAPPED_FORMAT_APPLE_CUSTOM) {
- initVector.Length = 8;
- }
- else {
- initVector.Length = wrapIvSize;
- }
- crtn = cspWrapKey(cspHand,
- decrKey,
- wrappingKey,
- wrapAlg,
- wrapMode,
- wrapFormat,
- wrapPad,
- &initVector,
- descData,
- &wrappedDecrKey);
- if(crtn) {
- return testError(quiet);
- }
- if(wrapAlg != CSSM_ALGID_NONE) {
- if(wrappedDecrKey.KeyHeader.Format != expectFormat) {
- printf("***Wrap format mismatch expect %s got %s\n",
- formatString(wrappedDecrKey.KeyHeader.Format),
- formatString(expectFormat));
- if(testError(quiet)) {
- return 1;
- }
- }
- }
-
- if(vfyWrapHeader(&decrKey->KeyHeader,
- &wrappedDecrKey.KeyHeader,
- (wrapAlg == CSSM_ALGID_NONE) ? CSSM_KEYBLOB_RAW : CSSM_KEYBLOB_WRAPPED,
- "wrappedDecrKey",
- bareCsp,
- quiet)) {
- return 1;
- }
-
- if(wrappedDecrKey.KeyHeader.Format == CSSM_KEYBLOB_WRAPPED_FORMAT_APPLE_CUSTOM) {
- /* special case - no IV needed - test it */
- wrapIvp = &nullInitVect;
- }
- else {
- wrapIvp = &initVector;
- initVector.Length = wrapIvSize;
- }
-
- /* unwrap wrappedDecrKey using unwrappingKey ==> unwrappedDecrKey; */
- crtn = cspUnwrapKey(cspHand,
- &wrappedDecrKey,
- unwrappingKey,
- wrapAlg,
- wrapMode,
- wrapPad,
- wrapIvp,
- &unwrappedDecrKey,
- &outDescData2,
- "unwrapped thing",
- 15);
- if(crtn) {
- return testError(quiet);
- }
-
- if(vfyWrapHeader(&wrappedDecrKey.KeyHeader,
- &unwrappedDecrKey.KeyHeader,
- CSSM_KEYBLOB_REFERENCE,
- "unwrappedDecrKey",
- bareCsp,
- quiet)) {
- return 1;
- }
-
- /* compare descData to outDescData2 */
- if(descData) {
- if(descData->Length != outDescData2.Length) {
- printf("descData length mismatch\n");
- if(testError(quiet)) {
- return 1;
- }
- }
- if(memcmp(descData->Data, outDescData2.Data, outDescData2.Length)) {
- printf("***descDatadata miscompare\n");
- if(testError(quiet)) {
- return 1;
- }
- }
- }
-
- /* decrypt ctext with unwrappedDecrKey ==> rptext; */
- rptext.Data = NULL;
- rptext.Length = 0;
- if(encrIvSize) {
- initVector.Length = encrIvSize;
- }
- crtn = cspDecrypt(cspHand,
- encrAlg,
- encrMode,
- encrPad,
- &unwrappedDecrKey,
- NULL, // no 2nd key
- effectiveKeySizeInBits,
- 0, // rounds
- &initVector,
- &ctext,
- &rptext,
- CSSM_TRUE);
- if(crtn) {
- return testError(quiet);
- }
- /* compare ptext vs. rptext; */
- if(ptext->Length != rptext.Length) {
- printf("ptext length mismatch\n");
- return testError(quiet);
- }
- if(memcmp(ptext->Data, rptext.Data, ptext->Length)) {
- printf("***data miscompare\n");
- return testError(quiet);
- }
- /* free resources */
- cspFreeKey(cspHand, &wrappedDecrKey);
- cspFreeKey(cspHand, &unwrappedDecrKey);
- if(wrapEncrKey) {
- cspFreeKey(cspHand, actualEncrKey);
- }
- CSSM_FREE(ctext.Data);
- CSSM_FREE(rptext.Data);
- if(outDescData2.Data != NULL) {
- CSSM_FREE(outDescData2.Data);
- }
- if(outDescData1.Data != NULL) {
- CSSM_FREE(outDescData1.Data);
- }
- return 0;
-}
-
-/*
- * values associated with a private algorithm (e.g., ALG_DES).
- */
-typedef enum {
- WT_Symmetric,
- WT_Asymmetric,
- WT_Null
-} wrapType;
-
-typedef struct {
- uint32 keyGenAlg;
- wrapType wtype;
- CSSM_ALGORITHMS encrAlg;
- CSSM_ENCRYPT_MODE encrMode;
- CSSM_PADDING encrPad;
- uint32 ivSize; // in bytes; 0 means no IV
- const char *algName;
-} AlgInfo;
-
-/*
- * Convert our private alg to CDSA keygen alg, encr alg, encr mode, pad
- */
-static void getAlgInfo(PrivAlg privAlg, // e.g., ALG_DES
- AlgInfo *algInfo)
-{
- switch(privAlg) {
- case ALG_DES:
- algInfo->keyGenAlg = CSSM_ALGID_DES;
- algInfo->wtype = WT_Symmetric;
- algInfo->encrAlg = CSSM_ALGID_DES;
- algInfo->encrMode = CSSM_ALGMODE_CBCPadIV8;
- algInfo->encrPad = CSSM_PADDING_PKCS5;
- algInfo->ivSize = 8;
- algInfo->algName = "DES";
- break;
- case ALG_3DES:
- algInfo->keyGenAlg = CSSM_ALGID_3DES_3KEY;
- algInfo->wtype = WT_Symmetric;
- algInfo->encrAlg = CSSM_ALGID_3DES_3KEY_EDE;
- algInfo->encrMode = CSSM_ALGMODE_CBCPadIV8;
- algInfo->encrPad = CSSM_PADDING_PKCS5;
- algInfo->ivSize = 8;
- algInfo->algName = "3DES";
- break;
- case ALG_FEEDEXP:
- algInfo->keyGenAlg = CSSM_ALGID_FEE;
- algInfo->wtype = WT_Asymmetric;
- algInfo->encrAlg = CSSM_ALGID_FEEDEXP;
- algInfo->encrMode = CSSM_ALGMODE_NONE;
- algInfo->encrPad = CSSM_PADDING_NONE;
- algInfo->ivSize = 0;
- algInfo->algName = "FEEDEXP";
- break;
- case ALG_RSA:
- algInfo->keyGenAlg = CSSM_ALGID_RSA;
- algInfo->wtype = WT_Asymmetric;
- algInfo->encrAlg = CSSM_ALGID_RSA;
- algInfo->encrMode = CSSM_ALGMODE_NONE;
- algInfo->encrPad = CSSM_PADDING_PKCS1;
- algInfo->ivSize = 0;
- algInfo->algName = "RSA";
- break;
- case ALG_ASC:
- algInfo->keyGenAlg = CSSM_ALGID_ASC;
- algInfo->wtype = WT_Symmetric;
- algInfo->encrAlg = CSSM_ALGID_ASC;
- algInfo->encrMode = CSSM_ALGMODE_NONE;
- algInfo->encrPad = CSSM_PADDING_NONE;
- algInfo->ivSize = 0;
- algInfo->algName = "ASC";
- break;
- case ALG_RC2:
- algInfo->keyGenAlg = CSSM_ALGID_RC2;
- algInfo->wtype = WT_Symmetric;
- algInfo->encrAlg = CSSM_ALGID_RC2;
- algInfo->encrMode = CSSM_ALGMODE_CBCPadIV8;
- algInfo->encrPad = CSSM_PADDING_PKCS5;
- algInfo->ivSize = 8;
- algInfo->algName = "RC2";
- break;
- case ALG_RC4:
- algInfo->keyGenAlg = CSSM_ALGID_RC4;
- algInfo->wtype = WT_Symmetric;
- algInfo->encrAlg = CSSM_ALGID_RC4;
- algInfo->encrMode = CSSM_ALGMODE_CBCPadIV8;
- algInfo->encrPad = CSSM_PADDING_PKCS5;
- algInfo->ivSize = 0;
- algInfo->algName = "RC4";
- break;
- case ALG_NULL:
- algInfo->keyGenAlg = CSSM_ALGID_NONE;
- algInfo->wtype = WT_Null;
- algInfo->encrAlg = CSSM_ALGID_NONE;
- algInfo->encrMode = CSSM_ALGMODE_NONE;
- algInfo->encrPad = CSSM_PADDING_NONE;
- algInfo->ivSize = 0;
- algInfo->algName = "Null";
- break;
- case ALG_AES:
- algInfo->keyGenAlg = CSSM_ALGID_AES;
- algInfo->wtype = WT_Symmetric;
- algInfo->encrAlg = CSSM_ALGID_AES;
- algInfo->encrMode = CSSM_ALGMODE_CBCPadIV8;
- algInfo->encrPad = CSSM_PADDING_PKCS7;
- algInfo->ivSize = 16;
- algInfo->algName = "AES";
- break;
- default:
- printf("Bogus privAlg\n");
- exit(1);
- }
- return;
-}
-
-/* argv letter to private alg */
-static PrivAlg letterToAlg(char **argv, char letter)
-{
- switch(letter) {
- case 'd': return ALG_DES;
- case '3': return ALG_3DES;
- case 'f': return ALG_FEEDEXP;
- case 'r': return ALG_RSA;
- case 'A': return ALG_ASC;
- case '4': return ALG_RC4;
- case 'a': return ALG_AES;
- default:
- usage(argv);
- return 0;
- }
-}
-
-/*
- * Null wrapping of symmetric keys now allowed
- */
-#define SYMM_NULL_WRAP_ENABLE 1
-
-/* indices into algInfo[] */
-#define AI_WRAP 0
-#define AI_ENCR 1
-
-int main(int argc, char **argv)
-{
- int arg;
- char *argp;
- unsigned loop;
- CSSM_CSP_HANDLE cspHand;
- CSSM_RETURN crtn;
- CSSM_DATA ptext;
- uint32 encrKeySizeBits; // well aligned
- uint32 wrapKeySizeBits;
- uint32 effectiveKeySizeInBits; // for encr, may be odd
- int rtn = 0;
- uint32 maxRsaKeySize = 1024;
- uint32 maxFeeKeySize = 192;
- CSSM_KEYBLOB_FORMAT wrapFormat; // NONE, PKCS7, PKCS8, APPLE_CUSTOM
- CSSM_KEYBLOB_FORMAT expectFormat; // PKCS7, PKCS8, APPLE_CUSTOM
- CSSM_DATA descData = {0, NULL};
- CSSM_DATA_PTR descDataP;
-
- /*
- * key pointers passed to doTest() - for symmetric algs, the pairs
- * might point to the same key
- */
- CSSM_KEY_PTR encrKeyPtr;
- CSSM_KEY_PTR decrKeyPtr;
- CSSM_KEY_PTR wrapKeyPtr;
- CSSM_KEY_PTR unwrapKeyPtr;
-
- /* persistent asymmetric keys - symm keys are dynamically allocated */
- CSSM_KEY pubEncrKey;
- CSSM_KEY privEncrKey;
- CSSM_KEY pubWrapKey;
- CSSM_KEY privWrapKey;
-
- /* we iterate these values thru all possible algs */
- PrivAlg privEncrAlg; // ALG_xxx
- PrivAlg privWrapAlg;
-
- /* two AlgInfo which contain everything we need to know per alg */
- AlgInfo algInfo[2];
- AlgInfo *encrInfo;
- AlgInfo *wrapInfo;
- CSSM_BOOL wrapEncrKey = CSSM_FALSE; // varies loop-to-loop
- CSSM_BOOL encrKeyIsRef = CSSM_TRUE; // ditto
-
- CSSM_BOOL genSeed; // for FEE key gen
- int i;
-
- /* user-specified vars */
- unsigned loops = LOOPS_DEF;
- CSSM_BOOL pause = CSSM_FALSE;
- CSSM_BOOL verbose = CSSM_FALSE;
- PrivAlg minWrapAlg = ALG_MIN;
- PrivAlg maxWrapAlg = ALG_MAX_WRAP;
- PrivAlg minEncrAlg = ALG_MIN;
- PrivAlg maxEncrAlg = ALG_MAX_ENCR;
- CSSM_BOOL quick = CSSM_FALSE;
- CSSM_BOOL quiet = CSSM_FALSE;
- CSSM_BOOL bareCsp = CSSM_TRUE;
- CSSM_BOOL refKeysOnly = CSSM_FALSE;
-
- for(arg=1; arg<argc; arg++) {
- argp = argv[arg];
- switch(argp[0]) {
- case 'w':
- if(argp[2] == 'n') {
- minWrapAlg = maxWrapAlg = ALG_NULL;
- }
- else {
- minWrapAlg = maxWrapAlg = letterToAlg(argv, argp[2]);
- }
- break;
- case 'e':
- minEncrAlg = maxEncrAlg = letterToAlg(argv, argp[2]);
- break;
- case 'l':
- loops = atoi(&argp[2]);
- break;
- case 'p':
- pause = CSSM_TRUE;
- break;
- case 'v':
- verbose = CSSM_TRUE;
- break;
- case 'D':
- bareCsp = CSSM_FALSE;
- #if CSPDL_ALL_KEYS_ARE_REF
- refKeysOnly = CSSM_TRUE;
- #endif
- break;
- case 'r':
- refKeysOnly = CSSM_TRUE;
- break;
- case 'q':
- quiet = CSSM_TRUE;
- break;
- case 'k':
- quick = CSSM_TRUE;
- maxRsaKeySize = 512;
- maxFeeKeySize = 127;
- break;
- default:
- usage(argv);
- }
- }
- cspHand = cspDlDbStartup(bareCsp, NULL);
- if(cspHand == 0) {
- exit(1);
- }
- wrapInfo = &algInfo[AI_WRAP];
- encrInfo = &algInfo[AI_ENCR];
-
- /* cook up ptext, descData */
- ptext.Data = (uint8 *)CSSM_MALLOC(MAX_PTEXT_SIZE);
- descData.Data = (uint8 *)CSSM_MALLOC(MAX_DESC_DATA_SIZE);
-
- printf("Starting wrapTest; args: ");
- for(i=1; i<argc; i++) {
- printf("%s ", argv[i]);
- }
- printf("\n");
-
- for(loop=0; loop<loops; loop++) {
- if(!quiet) {
- printf("...loop %d\n", loop);
- }
- if(pause) {
- fpurge(stdin);
- printf("Hit CR to proceed: ");
- getchar();
- }
-
- /* iterate thru all encryption algs */
- for(privEncrAlg=minEncrAlg; privEncrAlg<=maxEncrAlg; privEncrAlg++) {
- /* handle disabled algs */
- switch(privEncrAlg) {
- case ALG_NULL: /* just skip this one, it's just for wrap */
- continue;
- default:
- break;
- }
-
- /* generate key(s) to be wrapped */
- getAlgInfo(privEncrAlg, encrInfo);
- effectiveKeySizeInBits = randKeySizeBits(encrInfo->keyGenAlg, OT_Encrypt);
- if(!refKeysOnly) {
- encrKeyIsRef = (loop & 2) ? CSSM_TRUE : CSSM_FALSE;
- }
-
- switch(encrInfo->wtype) {
- case WT_Symmetric:
- /* round up to even byte */
- encrKeySizeBits = (effectiveKeySizeInBits + 7) & ~7;
- if(encrKeySizeBits == effectiveKeySizeInBits) {
- effectiveKeySizeInBits = 0;
- }
- encrKeyPtr = decrKeyPtr = cspGenSymKey(cspHand,
- encrInfo->keyGenAlg,
- ENCR_LABEL,
- ENCR_LABEL_LEN,
- CSSM_KEYUSE_ENCRYPT | CSSM_KEYUSE_DECRYPT,
- encrKeySizeBits,
- encrKeyIsRef);
- if(encrKeyPtr == NULL) {
- rtn = 1;
- goto testDone;
- }
- #if SYMM_NULL_WRAP_ENABLE
- /* wrapEncrKey every other loop */
- if(!refKeysOnly) {
- wrapEncrKey = (loop & 1) ? CSSM_TRUE : CSSM_FALSE;
- }
- #else
- wrapEncrKey = CSSM_FALSE;
- #endif /* SYMM_NULL_WRAP_ENABLE */
- break;
- case WT_Asymmetric:
- /* handle alg-specific cases */
- genSeed = CSSM_FALSE;
- switch(privEncrAlg) {
- case ALG_RSA:
- if(effectiveKeySizeInBits > maxRsaKeySize) {
- effectiveKeySizeInBits = maxRsaKeySize;
- }
- break;
- case ALG_FEEDEXP:
- if(effectiveKeySizeInBits > maxFeeKeySize) {
- effectiveKeySizeInBits = maxFeeKeySize;
- }
- if(loop & 4) {
- genSeed = CSSM_TRUE;
- }
- break;
- default:
- break;
- }
- encrKeySizeBits = effectiveKeySizeInBits;
- effectiveKeySizeInBits = 0; // i.e., not specified
- crtn = cspGenKeyPair(cspHand,
- encrInfo->keyGenAlg,
- ENCR_LABEL,
- ENCR_LABEL_LEN,
- encrKeySizeBits,
- &pubEncrKey,
- encrKeyIsRef, // pubIsRef
- CSSM_KEYUSE_ENCRYPT,
- CSSM_KEYBLOB_RAW_FORMAT_NONE,
- &privEncrKey,
- CSSM_TRUE, // privIsRef
- CSSM_KEYUSE_DECRYPT,
- CSSM_KEYBLOB_RAW_FORMAT_NONE,
- genSeed);
- if(crtn) {
- rtn = testError(quiet);
- goto testDone;
- }
- encrKeyPtr = &pubEncrKey;
- decrKeyPtr = &privEncrKey;
- /* wrapEncrKey every other loop */
- if(!refKeysOnly) {
- wrapEncrKey = (loop & 1) ? CSSM_TRUE : CSSM_FALSE;
- }
- break;
- case WT_Null:
- printf("***BRRZAP: can't do null encrypt\n");
- goto testDone;
- }
- if(verbose) {
- printf(" ...encrAlg %s wrapEncrKey %d encrKeyIsRef %d size %u "
- "bits effectSize %u\n",
- encrInfo->algName, (int)wrapEncrKey, (int)encrKeyIsRef,
- (unsigned)encrKeySizeBits, (unsigned)effectiveKeySizeInBits);
- }
- /* iterate thru all wrap algs */
- for(privWrapAlg=minWrapAlg; privWrapAlg<=maxWrapAlg; privWrapAlg++) {
- /* handle disabled algs */
- if((privWrapAlg == ALG_AES) && (privEncrAlg == ALG_FEEDEXP)) {
- /*
- * Can't do it. FEED can't do PKCS8 because it doesn't
- * support PKCS8 private key format, and AES can't
- * do APPLE_CUSTOM because AES needs a 16-byte IV.
- */
- continue;
- }
- /* any other restrictions/ */
-
- /* generate wrapping key(s) */
- getAlgInfo(privWrapAlg, wrapInfo);
- switch(wrapInfo->wtype) {
- case WT_Symmetric:
- /* note we can't do odd-size wrapping keys */
- wrapKeySizeBits = randKeySizeBits(wrapInfo->keyGenAlg,
- OT_KeyExch);
- wrapKeySizeBits &= ~7;
- wrapKeyPtr = unwrapKeyPtr = cspGenSymKey(cspHand,
- wrapInfo->keyGenAlg,
- WRAP_LABEL,
- WRAP_LABEL_LEN,
- WRAP_USAGE_ANY ? CSSM_KEYUSE_ANY :
- CSSM_KEYUSE_WRAP | CSSM_KEYUSE_UNWRAP,
- wrapKeySizeBits,
- CSSM_TRUE);
- if(wrapKeyPtr == NULL) {
- rtn = 1;
- goto testDone;
- }
- break;
- case WT_Asymmetric:
- wrapKeySizeBits = randKeySizeBits(wrapInfo->keyGenAlg,
- OT_KeyExch);
- genSeed = CSSM_FALSE;
- switch(privWrapAlg) {
- case ALG_RSA:
- if(wrapKeySizeBits > maxRsaKeySize) {
- wrapKeySizeBits = maxRsaKeySize;
- }
- break;
- case ALG_FEEDEXP:
- if(wrapKeySizeBits > maxFeeKeySize) {
- wrapKeySizeBits = maxFeeKeySize;
- }
- if(loop & 2) {
- genSeed = CSSM_TRUE;
- }
- break;
- default:
- break;
- }
- crtn = cspGenKeyPair(cspHand,
- wrapInfo->keyGenAlg,
- WRAP_LABEL,
- WRAP_LABEL_LEN,
- wrapKeySizeBits,
- &pubWrapKey,
- CSSM_TRUE, // pubIsRef
- WRAP_USAGE_ANY ? CSSM_KEYUSE_ANY : CSSM_KEYUSE_WRAP,
- CSSM_KEYBLOB_RAW_FORMAT_NONE,
- &privWrapKey,
- CSSM_TRUE, // privIsRef
- WRAP_USAGE_ANY ? CSSM_KEYUSE_ANY : CSSM_KEYUSE_UNWRAP,
- CSSM_KEYBLOB_RAW_FORMAT_NONE,
- genSeed);
- if(crtn) {
- rtn = testError(quiet);
- goto testDone;
- }
- wrapKeyPtr = &pubWrapKey;
- unwrapKeyPtr = &privWrapKey;
- break;
- case WT_Null:
- #if !SYMM_NULL_WRAP_ENABLE
- if(encrInfo->wtype == WT_Symmetric) {
- /* can't do null wrap of symmetric key */
- continue;
- }
- #endif
- wrapKeySizeBits = 0;
- wrapKeyPtr = NULL;
- unwrapKeyPtr = NULL;
- break;
- }
-
- /* special case for 3DES/3DES */
- #if 0
- if((wrapKeyPtr != NULL) &&
- (wrapKeyPtr->KeyHeader.AlgorithmId == CSSM_ALGID_3DES_3KEY) &&
- (decrKeyPtr->KeyHeader.AlgorithmId == CSSM_ALGID_3DES_3KEY)) {
- isAppleCustom = CSSM_TRUE;
- }
- else {
- isAppleCustom = CSSM_FALSE;
- }
- #endif
-
- /* cook up a wrapFormat - every other loop use default, others
- * specify a reasonable one */
- if(wrapInfo->wtype == WT_Null) {
- wrapFormat = expectFormat = CSSM_KEYBLOB_WRAPPED_FORMAT_NONE;
- }
- else if((loop & 1)) {
- /*
- * FORMAT_NONE - default - figure out expected format;
- * this has to track CSP behavior
- */
- wrapFormat = CSSM_KEYBLOB_WRAPPED_FORMAT_NONE;
- switch(encrInfo->wtype) {
- case WT_Symmetric:
- expectFormat = CSSM_KEYBLOB_WRAPPED_FORMAT_PKCS7;
- break;
- case WT_Asymmetric:
- if(privEncrAlg == ALG_FEEDEXP) {
- expectFormat = CSSM_KEYBLOB_WRAPPED_FORMAT_APPLE_CUSTOM;
- }
- else {
- expectFormat = CSSM_KEYBLOB_WRAPPED_FORMAT_PKCS8;
- }
- break;
- default:
- /* NULL encr not done */
- printf("**GAK! Internal error\n");
- }
- }
- else {
- /* pick a good explicit one - this encapsulates the
- * range of legal wrap formats per wrap/encrypt alg */
- int die = loop & 2;
- switch(encrInfo->wtype) {
- case WT_Symmetric:
- if(privWrapAlg == ALG_AES) {
- /* can't do APPLE_CUSTOM - 16 byte IV */
- wrapFormat = CSSM_KEYBLOB_WRAPPED_FORMAT_PKCS7;
- }
- else if(die) {
- wrapFormat = CSSM_KEYBLOB_WRAPPED_FORMAT_PKCS7;
- }
- else {
- wrapFormat = CSSM_KEYBLOB_WRAPPED_FORMAT_APPLE_CUSTOM;
- }
- break;
- case WT_Asymmetric:
- /* Can't wrap FEE key with AES no way, no how -
- * this is detected at the top of the privWrapAlg
- * loop
- */
- if(privEncrAlg == ALG_FEEDEXP) {
- /* FEE doesn't do PKCS8 private key format */
- wrapFormat = CSSM_KEYBLOB_WRAPPED_FORMAT_APPLE_CUSTOM;
- }
- else if(die) {
- wrapFormat = CSSM_KEYBLOB_WRAPPED_FORMAT_PKCS8;
- }
- else if(privWrapAlg == ALG_AES) {
- /* AES can't do APPLE_CUSTOM - 16 byte IV */
- wrapFormat = CSSM_KEYBLOB_WRAPPED_FORMAT_PKCS8;
- }
- else {
- wrapFormat = CSSM_KEYBLOB_WRAPPED_FORMAT_APPLE_CUSTOM;
- }
- break;
- default:
- /* NULL encr not done */
- printf("***GAK! Internal error\n");
- exit(1);
- }
- expectFormat = wrapFormat;
- }
-
- /*
- * If wrapping with apple custom - either by default or
- * explicitly - generate some descriptive data.
- */
- if(expectFormat == CSSM_KEYBLOB_WRAPPED_FORMAT_APPLE_CUSTOM) {
- simpleGenData(&descData, 1, MAX_DESC_DATA_SIZE);
- descDataP = &descData;
- }
- else {
- descDataP = NULL;
- }
-
- if(verbose) {
- printf(" ...wrapAlg = %s size %u bits format %s expect %s\n",
- wrapInfo->algName, (unsigned)wrapKeySizeBits, formatString(wrapFormat),
- formatString(expectFormat));
- }
- /* OK, here we go! */
- if(doTest(cspHand,
- encrKeyPtr,
- wrapEncrKey,
- decrKeyPtr,
- wrapKeyPtr,
- unwrapKeyPtr,
- wrapInfo->encrAlg,
- wrapInfo->encrMode,
- wrapFormat,
- expectFormat,
- wrapInfo->encrPad,
- wrapInfo->ivSize,
- encrInfo->encrAlg,
- encrInfo->encrMode,
- encrInfo->encrPad,
- encrInfo->ivSize,
- effectiveKeySizeInBits,
- &ptext,
- descDataP,
- quiet,
- bareCsp)) {
- rtn = 1;
- goto testDone;
- }
- /* end of wrap alg loop - free/delete wrap key(s) */
- switch(wrapInfo->wtype) {
- case WT_Symmetric:
- cspFreeKey(cspHand, wrapKeyPtr);
- /* mallocd by cspGenSymKey */
- CSSM_FREE(wrapKeyPtr);
- break;
- case WT_Asymmetric:
- cspFreeKey(cspHand, wrapKeyPtr);
- cspFreeKey(cspHand, unwrapKeyPtr);
- break;
- default:
- break;
- }
- } /* for wrapAlg */
- /* end of encr alg loop - free encr key(s) */
- cspFreeKey(cspHand, encrKeyPtr);
- if(encrInfo->wtype == WT_Symmetric) {
- /* mallocd by cspGenSymKey */
- CSSM_FREE(decrKeyPtr);
- }
- else {
- cspFreeKey(cspHand, decrKeyPtr);
- }
- }
- }
-testDone:
- cspShutdown(cspHand, bareCsp);
- if(pause) {
- fpurge(stdin);
- printf("ModuleDetach/Unload complete; hit CR to exit: ");
- getchar();
- }
- if((rtn == 0) && !quiet) {
- printf("%s test complete\n", argv[0]);
- }
- return rtn;
-}