2  * Copyright (c)1999-2004 Apple Computer, Inc. All rights reserved. 
   4  * @APPLE_LICENSE_HEADER_START@ 
   6  * The contents of this file constitute Original Code as defined in and 
   7  * are subject to the Apple Public Source License Version 1.1 (the 
   8  * "License").  You may not use this file except in compliance with the 
   9  * License.  Please obtain a copy of the License at 
  10  * http://www.apple.com/publicsource and read it before using this file. 
  12  * This Original Code and all software distributed under the License are 
  13  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  14  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  15  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 
  16  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the 
  17  * License for the specific language governing rights and limitations 
  20  * @APPLE_LICENSE_HEADER_END@ 
  23 #include <sys/param.h> 
  24 #include <sys/systm.h> 
  26 #include <sys/errno.h> 
  27 #include <sys/ioctl.h> 
  29 #include <sys/fcntl.h> 
  31 #include <miscfs/devfs/devfs.h> 
  32 #include <kern/lock.h> 
  34 #include <sys/malloc.h> 
  35 #include <sys/uio_internal.h> 
  37 #include <dev/random/randomdev.h> 
  38 #include <dev/random/YarrowCoreLib/include/yarrow.h> 
  39 #include <crypto/sha1.h> 
  41 #define RANDOM_MAJOR  -1 /* let the kernel pick the device number */ 
  43 d_ioctl_t       random_ioctl
; 
  46  * A struct describing which functions will get invoked for certain 
  49 static struct cdevsw random_cdevsw 
= 
  51         random_open
,            /* open */ 
  52         random_close
,           /* close */ 
  53         random_read
,            /* read */ 
  54         random_write
,           /* write */ 
  55         random_ioctl
,           /* ioctl */ 
  56         (stop_fcn_t 
*)nulldev
, /* stop */ 
  57         (reset_fcn_t 
*)nulldev
, /* reset */ 
  59         eno_select
,                     /* select */ 
  61         eno_strat
,                      /* strategy */ 
  67 /* Used to detect whether we've already been initialized */ 
  68 static int gRandomInstalled 
= 0; 
  69 static PrngRef gPrngRef
; 
  70 static int gRandomError 
= 1; 
  71 static mutex_t 
*gYarrowMutex 
= 0; 
  73 #define RESEED_TICKS 50 /* how long a reseed operation can take */ 
  76 enum {kBSizeInBits 
= 160}; // MUST be a multiple of 32!!! 
  77 enum {kBSizeInBytes 
= kBSizeInBits 
/ 8}; 
  78 typedef u_int32_t BlockWord
; 
  79 enum {kWordSizeInBits 
= 32}; 
  81 typedef BlockWord Block
[kBSize
]; 
  83 /* define prototypes to keep the compiler happy... */ 
  85 void add_blocks(Block a
, Block b
, BlockWord carry
); 
  86 void fips_initialize(void); 
  87 void random_block(Block b
, int addOptional
); 
  88 u_int32_t 
CalculateCRC(u_int8_t
* buffer
, size_t length
); 
  91  * Get 120 bits from yarrow 
  95  * add block b to block a 
  98 add_blocks(Block a
, Block b
, BlockWord carry
) 
 103                 u_int64_t c 
= (u_int64_t
)carry 
+ 
 106                 a
[i
] = c 
& ((1LL << kWordSizeInBits
) - 1); 
 107                 carry 
= c 
>> kWordSizeInBits
; 
 113 struct sha1_ctxt g_sha1_ctx
; 
 114 char zeros
[(512 - kBSizeInBits
) / 8]; 
 118 unsigned char g_SelfTestInitialized 
= 0; 
 119 u_int32_t gLastBlockChecksum
; 
 121 static const u_int32_t g_crc_table
[] = 
 123         0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, 
 124         0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 
 125         0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, 
 126         0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, 
 127         0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 
 128         0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, 
 129         0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, 
 130         0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 
 131         0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, 
 132         0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, 
 133         0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 
 134         0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, 
 135         0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, 
 136         0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 
 137         0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, 
 138         0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, 
 139         0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 
 140         0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, 
 141         0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, 
 142         0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 
 143         0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, 
 144         0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, 
 145         0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 
 146         0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, 
 147         0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, 
 148         0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 
 149         0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, 
 150         0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, 
 151         0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 
 152         0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, 
 153         0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, 
 154         0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D, 
 158  * Setup for fips compliance 
 162  * calculate a crc-32 checksum 
 164 u_int32_t 
CalculateCRC(u_int8_t
* buffer
, size_t length
) 
 169         for (i 
= 0; i 
< length
; ++i
) 
 171                 u_int32_t temp 
= (crc 
^ ((u_int32_t
) buffer
[i
])) & 0xFF; 
 172                 crc 
= (crc 
>> 8) ^ g_crc_table
[temp
]; 
 179  * get a random block of data per fips 186-2 
 182 random_block(Block b
, int addOptional
) 
 191                         prngOutput (gPrngRef
, (BYTE
*) &xSeed
, sizeof (xSeed
)); 
 193                         // add the seed to the previous value of g_xkey 
 194                         add_blocks (g_xkey
, xSeed
, 0); 
 198                 SHA1Update (&g_sha1_ctx
, (const u_int8_t 
*) &g_xkey
, sizeof (g_xkey
)); 
 200                 // add zeros to fill the internal SHA-1 buffer 
 201                 SHA1Update (&g_sha1_ctx
, (const u_int8_t 
*)zeros
, sizeof (zeros
)); 
 203                 // write the resulting block 
 204                 memmove(b
, g_sha1_ctx
.h
.b8
, sizeof (Block
)); 
 206                 // calculate the CRC-32 of the block 
 207                 u_int32_t new_crc 
= CalculateCRC(g_sha1_ctx
.h
.b8
, sizeof (Block
)); 
 209                 // make sure we don't repeat 
 210                 int cmp 
= new_crc 
== gLastBlockChecksum
; 
 211                 gLastBlockChecksum 
= new_crc
; 
 212                 if (!g_SelfTestInitialized
) 
 214                         g_SelfTestInitialized 
= 1; 
 224                 // fix up the next value of g_xkey 
 225                 add_blocks (g_xkey
, b
, 1); 
 226         } while (repeatCount 
< 2); 
 229          * If we got here, three sucessive checksums of the random number 
 230          * generator have been the same.  Since the odds of this happening are 
 231          * 1 in 18,446,744,073,709,551,616, (1 in 18 quintillion) one of the following has 
 232          * most likely happened: 
 234          * 1: There is a significant bug in this code. 
 235          * 2: There has been a massive system failure. 
 236          * 3: The universe has ceased to exist. 
 238          * There is no good way to recover from any of these cases. We 
 242          panic("FIPS random self-test failed."); 
 246  *Initialize ONLY the Yarrow generator. 
 249 PreliminarySetup(void) 
 251     prng_error_status perr
; 
 255     /* create a Yarrow object */ 
 256     perr 
= prngInitialize(&gPrngRef
); 
 258         printf ("Couldn't initialize Yarrow, /dev/random will not work.\n"); 
 262         /* clear the error flag, reads and write should then work */ 
 265     /* get a little non-deterministic data as an initial seed. */ 
 269          * So how much of the system clock is entropic? 
 270          * It's hard to say, but assume that at least the 
 271          * least significant byte of a 64 bit structure 
 272          * is entropic.  It's probably more, how can you figure 
 273          * the exact time the user turned the computer on, for example. 
 275     perr 
= prngInput(gPrngRef
, (BYTE
*) &tt
, sizeof (tt
), SYSTEM_SOURCE
, 8); 
 277         /* an error, complain */ 
 278         printf ("Couldn't seed Yarrow.\n"); 
 282     /* turn the data around */ 
 283     perr 
= prngOutput(gPrngRef
, (BYTE
*)buffer
, sizeof (buffer
)); 
 285     /* and scramble it some more */ 
 286     perr 
= prngForceReseed(gPrngRef
, RESEED_TICKS
); 
 288     /* make a mutex to control access */ 
 289     gYarrowMutex 
= mutex_alloc(0); 
 294 const Block kKnownAnswer 
= {0x92b404e5, 0x56588ced, 0x6c1acd4e, 0xbf053f68, 0x9f73a93}; 
 297 fips_initialize(void) 
 299         /* So that we can do the self test, set the seed to zero */ 
 300         memset(&g_xkey
, 0, sizeof(g_xkey
)); 
 302         /* initialize our SHA1 generator */ 
 303         SHA1Init (&g_sha1_ctx
); 
 305         /* other initializations */ 
 306         memset (zeros
, 0, sizeof (zeros
)); 
 308         random_block(g_random_data
, FALSE
); 
 310         // check here to see if we got the initial data we were expecting 
 312         for (i 
= 0; i 
< kBSize
; ++i
) 
 314                 if (kKnownAnswer
[i
] != g_random_data
[i
]) 
 316                         panic("FIPS random self test failed"); 
 320         // now do the random block again to make sure that userland doesn't get predictable data 
 321         random_block(g_random_data
, TRUE
); 
 325  * Called to initialize our device, 
 326  * and to register ourselves with devfs 
 333         if (gRandomInstalled
) 
 336         /* install us in the file system */ 
 337         gRandomInstalled 
= 1; 
 339         /* setup yarrow and the mutex */ 
 342         ret 
= cdevsw_add(RANDOM_MAJOR
, &random_cdevsw
); 
 344                 printf("random_init: failed to allocate a major number!\n"); 
 345                 gRandomInstalled 
= 0; 
 349         devfs_make_node(makedev (ret
, 0), DEVFS_CHAR
, 
 350                 UID_ROOT
, GID_WHEEL
, 0666, "random", 0); 
 354          * (which is exactly the same thing in our context) 
 356         devfs_make_node(makedev (ret
, 1), DEVFS_CHAR
, 
 357                 UID_ROOT
, GID_WHEEL
, 0666, "urandom", 0); 
 361 random_ioctl(   __unused dev_t dev
, u_long cmd
, __unused caddr_t data
,  
 362                                 __unused 
int flag
, __unused 
struct proc 
*p  
) 
 376  * Open the device.  Make sure init happened, and make sure the caller is 
 381 random_open(__unused dev_t dev
, int flags
, __unused 
int devtype
, __unused 
struct proc 
*p
) 
 383         if (gRandomError 
!= 0) { 
 384                 /* forget it, yarrow didn't come up */ 
 389          * if we are being opened for write, 
 390          * make sure that we have privledges do so 
 392         if (flags 
& FWRITE
) { 
 393                 if (securelevel 
>= 2) 
 396                 if ((securelevel 
>= 1) && proc_suser(p
)) 
 398 #endif  /* !__APPLE__ */ 
 410 random_close(__unused dev_t dev
, __unused 
int flags
, __unused 
int mode
, __unused 
struct proc 
*p
) 
 417  * Get entropic data from the Security Server, and use it to reseed the 
 421 random_write (__unused dev_t dev
, struct uio 
*uio
, __unused 
int ioflag
) 
 426     if (gRandomError 
!= 0) { 
 430     /* get control of the Yarrow instance, Yarrow is NOT thread safe */ 
 431     mutex_lock(gYarrowMutex
); 
 433     /* Security server is sending us entropy */ 
 435     while (uio_resid(uio
) > 0 && retCode 
== 0) { 
 436         /* get the user's data */ 
 437         // LP64todo - fix this!  uio_resid may be 64-bit value 
 438         int bytesToInput 
= min(uio_resid(uio
), sizeof (rdBuffer
)); 
 439         retCode 
= uiomove(rdBuffer
, bytesToInput
, uio
); 
 441             goto /*ugh*/ error_exit
; 
 443         /* put it in Yarrow */ 
 444         if (prngInput(gPrngRef
, (BYTE
*)rdBuffer
, 
 445                         bytesToInput
, SYSTEM_SOURCE
, 
 446                 bytesToInput 
* 8) != 0) { 
 453     if (prngForceReseed(gPrngRef
, RESEED_TICKS
) != 0) { 
 458     /* retCode should be 0 at this point */ 
 460 error_exit
: /* do this to make sure the mutex unlocks. */ 
 461     mutex_unlock(gYarrowMutex
); 
 466  * return data to the caller.  Results unpredictable. 
 468 int random_read(__unused dev_t dev
, struct uio 
*uio
, __unused 
int ioflag
) 
 472     if (gRandomError 
!= 0) 
 475    /* lock down the mutex */ 
 476     mutex_lock(gYarrowMutex
); 
 478         int bytes_remaining 
= uio_resid(uio
); 
 479     while (bytes_remaining 
> 0 && retCode 
== 0) { 
 480         /* get the user's data */ 
 481                 int bytes_to_read 
= 0; 
 483                 int bytes_available 
= kBSizeInBytes 
- g_bytes_used
; 
 484         if (bytes_available 
== 0) 
 486                         random_block(g_random_data
, TRUE
); 
 488                         bytes_available 
= kBSizeInBytes
; 
 491                 bytes_to_read 
= min (bytes_remaining
, bytes_available
); 
 493         retCode 
= uiomove(((u_int8_t
*)g_random_data
)+ g_bytes_used
, bytes_to_read
, uio
); 
 494         g_bytes_used 
+= bytes_to_read
; 
 499                 bytes_remaining 
= uio_resid(uio
); 
 505     mutex_unlock(gYarrowMutex
); 
 509 /* export good random numbers to the rest of the kernel */ 
 511 read_random(void* buffer
, u_int numbytes
) 
 513     if (gYarrowMutex 
== 0) { /* are we initialized? */ 
 517     mutex_lock(gYarrowMutex
); 
 521         int bytes_remaining 
= numbytes
; 
 522     while (bytes_remaining 
> 0) { 
 523         int bytes_to_read 
= min(bytes_remaining
, kBSizeInBytes 
- g_bytes_used
); 
 524         if (bytes_to_read 
== 0) 
 526                         random_block(g_random_data
, TRUE
); 
 528                         bytes_to_read 
= min(bytes_remaining
, kBSizeInBytes
); 
 531                 memmove (buffer
, ((u_int8_t
*)g_random_data
)+ bytes_read
, bytes_to_read
); 
 532                 g_bytes_used 
+= bytes_to_read
; 
 533                 bytes_read 
+= bytes_to_read
; 
 534                 bytes_remaining 
-= bytes_to_read
; 
 537     mutex_unlock(gYarrowMutex
); 
 541  * Return an unsigned long pseudo-random number. 
 547         read_random(&buf
, sizeof (buf
));