1/* 2 * Copyright (c) 2010 Apple Inc. All Rights Reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23 24/* 25 * randomTest 26 * CommonCrypto 27 */ 28#include "testmore.h" 29#include "capabilities.h" 30#include "testbyteBuffer.h" 31 32 33#if (CCRANDOM == 0) 34entryPoint(CommonRandom,"Random Number Generation") 35#else 36#include <CommonCrypto/CommonRandomSPI.h> 37#include <sys/resource.h> 38 39static const int kTestTestCount = 1000; 40static const int bufmax = kTestTestCount + 16; 41 42// Number of file which can be open by CCRegression application 43// This value need to be acceptable for all CCRegression since default value can only be restored by Super User. 44#define CCREGRESSION_MAX_FILE_OPEN_LIMIT 10 45 46int CommonRandom(int argc, char *const *argv) 47{ 48 int i; 49 uint8_t buf1[bufmax], buf2[bufmax], buf3[bufmax], buf4[bufmax], buf5[bufmax], buf6[bufmax], buf7[bufmax]; 50 CCRandomRef rngref; 51 52 plan_tests(kTestTestCount * 14 + 11); 53 54 55 struct ccrng_state *devRandom = NULL; 56 struct ccrng_state *drbg = NULL; 57 58 // ============================================ 59 // Negative testing first 60 // ============================================ 61 struct ccrng_system_state rng_array[CCREGRESSION_MAX_FILE_OPEN_LIMIT]; 62 int rng_array_valid_cnt=0; 63 int rng_status=0; 64 65 // Reduce number to CCREGRESSION_MAX_FILE_OPEN_LIMIT 66 // Only SU can increase this value so we just don't restore it to default. 67 const struct rlimit rlp= { CCREGRESSION_MAX_FILE_OPEN_LIMIT, CCREGRESSION_MAX_FILE_OPEN_LIMIT }; 68 is(setrlimit(RLIMIT_NOFILE, &rlp),0, "Set max number of open files"); 69 70 // Exhaust opening of /dev/random 71 for(i=0; ((i < CCREGRESSION_MAX_FILE_OPEN_LIMIT) && (rng_status>=0)); i++) { 72 rng_status=ccrng_system_init(&rng_array[i]); 73 rng_array_valid_cnt++; 74 } 75 cmp_ok(rng_array_valid_cnt,<,CCREGRESSION_MAX_FILE_OPEN_LIMIT, "/dev/random exhaustion"); 76 77 // Any random initialization will cause abort below. 78 // Since we can't recover, this can't be permanently in the test 79#if 0 80 isnt(CCRNGCreate(0, &rngref),kCCSuccess, "CCRNGCreate with /dev/random exhaustion"); 81 devRandom = ccDevRandomGetRngState(); 82 is(devRandom,NULL, "ccDevRandomGetRngState /dev/random exhaustion"); 83 drbg = ccDRBGGetRngState(); 84 is(drbg,NULL, "ccDRBGGetRngState /dev/random exhaustion"); 85 86 // Get random under exhausted /dev/random 87 isnt(CCRandomCopyBytes(kCCRandomDefault, buf1, 1),0, "Exhausted /dev/random failure"); 88 isnt(CCRandomCopyBytes(kCCRandomDevRandom, buf2, 1),0, "Exhausted /dev/random failure"); 89 isnt(CCRandomCopyBytes(rngref, buf3, 1),0, "Exhausted /dev/random failure"); 90 isnt(CCRandomCopyBytes(NULL, buf4, 1),0, "Exhausted /dev/random failure"); 91 isnt(CCRandomGenerateBytes(buf7, 1),0, "Exhausted /dev/random failure"); 92#endif 93 // Close to allow again the use of /dev/random 94 for(i=0; (i < rng_array_valid_cnt); i++) { 95 ccrng_system_done(&rng_array[i]); 96 } 97 98 // ============================================ 99 // Positive testing 100 // ============================================ 101 102 is(CCRNGCreate(0, &rngref),kCCSuccess, "CCRNGCreate success"); 103 devRandom = ccDevRandomGetRngState(); 104 isnt(devRandom,NULL, "Dev random first state ok"); 105 drbg = ccDRBGGetRngState(); 106 isnt(drbg,NULL, "DRBG first state ok"); 107 108 for(i=0; i < kTestTestCount; i++) { 109 size_t len = i+16; 110 is(CCRandomCopyBytes(kCCRandomDefault, buf1, len),0, "Random success"); 111 is(CCRandomCopyBytes(kCCRandomDevRandom, buf2, len),0, "Random success"); 112 is(CCRandomCopyBytes(rngref, buf3, len),0, "Random success"); 113 is(CCRandomCopyBytes(NULL, buf4, len),0, "Random success"); 114 is(ccrng_generate(devRandom, len, buf5),0, "Random success"); 115 is(ccrng_generate(drbg, len, buf6),0, "Random success"); 116 is(CCRandomGenerateBytes(buf7, len),0, "Random success"); 117 118 ok(memcmp(buf1, buf2, len), "Buffers aren't the same"); 119 ok(memcmp(buf3, buf4, len), "Buffers aren't the same"); 120 ok(memcmp(buf2, buf3, len), "Buffers aren't the same"); 121 ok(memcmp(buf5, buf6, len), "Buffers aren't the same"); 122 ok(memcmp(buf5, buf2, len), "Buffers aren't the same"); 123 ok(memcmp(buf6, buf1, len), "Buffers aren't the same"); 124 ok(memcmp(buf7, buf1, len), "Buffers aren't the same"); 125 } 126 127 128 // Bad inputs 129 is(CCRandomCopyBytes(kCCRandomDefault, buf1, 0),0, "Zero Length"); 130 is(CCRandomCopyBytes(kCCRandomDevRandom, buf2, 0),0, "Zero Length"); 131 is(CCRandomGenerateBytes(buf7, 0),0, "Zero Length"); 132 133 isnt(CCRandomCopyBytes(kCCRandomDefault, NULL, 1),0, "NULL pointer"); 134 isnt(CCRandomCopyBytes(kCCRandomDevRandom, NULL, 1),0, "NULL pointer"); 135 isnt(CCRandomGenerateBytes(NULL, 1),0, "NULL pointer"); 136 137 CCRNGRelease(rngref); 138 139 return 0; 140} 141#endif 142 143