]> git.saurik.com Git - apple/security.git/blobdiff - SecurityTests/cspxutils/randTest/randTest.c
Security-57031.1.35.tar.gz
[apple/security.git] / SecurityTests / cspxutils / randTest / randTest.c
diff --git a/SecurityTests/cspxutils/randTest/randTest.c b/SecurityTests/cspxutils/randTest/randTest.c
new file mode 100644 (file)
index 0000000..5466d62
--- /dev/null
@@ -0,0 +1,219 @@
+/*
+ * Simple interactive CSP RNG exerciser. 
+ */
+#include <stdlib.h>
+#include <stdio.h>
+#include <time.h>
+#include <Security/cssm.h>
+#include <Security/cssmapple.h>
+#include "cspwrap.h"
+#include "common.h"
+
+#define RAND_ALG               CSSM_ALGID_APPLE_YARROW
+#define BUFSIZE                        32
+
+static void usage(char **argv)
+{
+       printf("usage: %s [options]\n", argv[0]);
+       printf("Options:\n");
+       printf("  D (CSP/DL; default = bare CSP)\n");
+       exit(1);
+}
+
+static void dumpBuf(uint8 *buf,
+       unsigned len)
+{
+       unsigned i;
+       
+       printf("   ");
+       for(i=0; i<len; i++) {
+               printf("%02X  ", buf[i]);
+               if((i % 8) == 7) {
+                       printf("\n   ");
+               }
+       }
+       printf("\n");
+}
+
+void doGenRand(
+       CSSM_CSP_HANDLE                 cspHand,
+       CSSM_CC_HANDLE                  ccHand,         // 0 ==> gen a new one
+                                                                               // else use this
+       CSSM_CRYPTO_DATA_PTR    seed,           // optional
+       unsigned                                len,
+       CSSM_BOOL                               weMalloc)
+{
+       CSSM_RETURN                             crtn;
+       CSSM_DATA                               data = {0, NULL};
+       
+       /* optional existing context */
+       if(ccHand == 0) {
+               crtn = CSSM_CSP_CreateRandomGenContext(
+                       cspHand,
+                       RAND_ALG,
+                       seed,
+                       len,
+                       &ccHand);
+               if(crtn) {
+                       printError("CSSM_CSP_CreateRandomGenContext", crtn);
+                       return;
+               }
+       }
+       
+       /* who mallocs the data? */
+       if(weMalloc) {
+               data.Data = (uint8 *)appMalloc(len, NULL);
+               if(data.Data == NULL) {
+                       printf("***malloc failure\n");
+                       return;
+               }
+               data.Length = len;
+       }
+       
+       /* go for it */
+       crtn = CSSM_GenerateRandom(ccHand, &data);
+       if(crtn) {
+               printError("CSSM_GenerateRandom", crtn);
+               return;
+       }
+       
+       dumpBuf(data.Data, data.Length);
+       appFree(data.Data, NULL);
+       return;
+}
+
+#define SEED_SIZE      32
+
+/*
+ * CryptoData callback for optional random seed.
+ */
+CSSM_RETURN seedCallback(
+       CSSM_DATA_PTR OutData, 
+       void *CallerCtx)
+{
+       int i, j;
+       static unsigned char    seed[SEED_SIZE];
+       
+       OutData->Length = SEED_SIZE;
+       OutData->Data = seed;
+       for(i=SEED_SIZE, j=0; i>0; i--, j++) {
+               seed[j] = i;
+       }
+       return CSSM_OK;
+}
+
+int main(int argc, char **argv)
+{
+       int                                             arg;
+       char                                    *argp;
+       CSSM_CSP_HANDLE                 cspHand;
+       CSSM_CC_HANDLE                  ccHand = 0;
+       CSSM_RETURN                             crtn;
+       CSSM_BOOL                               bareCsp = CSSM_TRUE;
+       char                                    resp = 'n';                     
+                                               // initial op = get random data
+       CSSM_BOOL                               weMalloc = CSSM_FALSE;
+       unsigned char                   seed[SEED_SIZE];
+       CSSM_CRYPTO_DATA                cseed;
+       int                                     i;
+       unsigned                                reqLen = 16;
+       CSSM_BOOL                               explicitSeed;
+       
+       for(arg=1; arg<argc; arg++) {
+               argp = argv[arg];
+           switch(argv[arg][0]) {
+                       case 'D':
+                               bareCsp = CSSM_FALSE;
+                               break;
+                       default:
+                               usage(argv);
+               }
+       }
+       cspHand = cspDlDbStartup(bareCsp, NULL);
+       if(cspHand == 0) {
+               exit(1);
+       }
+       
+       /* set up for explicit seed */
+       cseed.Param.Length = SEED_SIZE;
+       cseed.Param.Data = seed;
+       for(i=0; i<SEED_SIZE; i++) {
+               seed[i] = i;
+       }
+       cseed.Callback = NULL;
+       cseed.CallerCtx = NULL;
+       explicitSeed = CSSM_TRUE;
+       
+       while(1) {
+               printf(" g   Get random data w/seed\n");
+               printf(" n   Get random data w/o seed\n");
+               printf(" c   Get random data using current context\n");
+               printf(" m   we malloc (current: %s)\n",
+                       weMalloc ? "True" : "False");
+               printf(" M   CSP mallocs\n");
+               printf(" s   seed via explicit data (current: %d)\n", (int)explicitSeed);
+               printf(" S   seed via callback\n");
+               printf(" q   quit\n");
+               fpurge(stdin);
+               printf("\ncommand me: ");
+       nextChar:
+               resp = getchar();
+               if(resp == 'q') {
+                       break;
+               }
+               switch(resp) {
+                       case 'g':
+                               if(ccHand != 0) {
+                                       crtn = CSSM_DeleteContext(ccHand);
+                                       if(crtn) {
+                                               printError("CSSM_DeleteContext", crtn);
+                                       }
+                                       ccHand = 0;
+                               }
+                               doGenRand(cspHand, ccHand, &cseed, reqLen, weMalloc);
+                               break;
+                       case 'n':
+                               if(ccHand != 0) {
+                                       crtn = CSSM_DeleteContext(ccHand);
+                                       if(crtn) {
+                                               printError("CSSM_DeleteContext", crtn);
+                                       }
+                                       ccHand = 0;
+                               }
+                               doGenRand(cspHand, ccHand, NULL, reqLen, weMalloc);
+                               break;
+                       case 'c':
+                               doGenRand(cspHand, ccHand, NULL, reqLen, weMalloc);
+                               break;
+                       case 'm':
+                               weMalloc = CSSM_TRUE;
+                               break;
+                       case 'M':
+                               weMalloc = CSSM_FALSE;
+                               break;
+                       case 'l':
+                               printf("New length: ");
+                               scanf("%d", &reqLen);
+                               break;
+                       case 's':
+                               /* explicit seed - presence of callback is the determinant */
+                               cseed.Callback = NULL;
+                               explicitSeed = CSSM_TRUE;
+                               break;
+                       case 'S':
+                               /* seed by calllback */
+                               cseed.Callback = seedCallback;
+                               explicitSeed = CSSM_FALSE;
+                               break;
+                       case '\n':
+                               goto nextChar;
+                       default:
+                               printf("Huh?\n");
+               }
+       }
+       if((crtn = CSSM_ModuleDetach(cspHand))) {
+               printError("CSSM_ModuleDetach", crtn);
+               exit(1);
+       }
+       return 0;
+}