1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #include <sys/types.h> 27 #include <rng/fips_random.h> 28 #include <sys/sha1.h> 29 30 /* 31 * Adds val1 and val2 and stores result into sum. The various input 32 * pointers can be exactly aliased. (They cannot be offset and 33 * overlapping, but no one would ever do that.) Values are big endian 34 * by words and native byte order within words. The return value's 35 * 2-bit is 0 if the result is zero, it's 1 bit is carry out. (This 36 * is reused code. The return code is not used by n2rng.) Thus, 37 * calling with both carryin and complement_val2 ones does a 38 * subtraction. A null sum pointer parameter is allowed. The 39 * subtraction features were required when this code was orginally 40 * written so it could do a mod q operation. 41 */ 42 static int 43 fips_add160(uint32_t *sum, uint32_t const *val1, uint32_t const *val2, 44 const unsigned carryin, const int complement_val2) 45 { 46 int i; 47 uint32_t partialsum; 48 uint32_t carry = (carryin > 0); 49 uint32_t non_zero = 0; 50 51 for (i = 4; i >= 0; --i) { 52 partialsum = val1[i] + (complement_val2 ? ~val2[i] : val2[i]) + 53 carry; 54 if (carry) { 55 carry = (partialsum <= val1[i]); 56 } else { 57 carry = (partialsum < val1[i]); 58 } 59 if (sum) { 60 sum[i] = partialsum; 61 } 62 non_zero |= partialsum; 63 } 64 65 return (((non_zero != 0) * 2) | carry); 66 } 67 68 #ifdef _LITTLE_ENDIAN 69 #define SWAP16(value) \ 70 ((((value) & 0xff) << 8) | ((value) >> 8)) 71 72 #define SWAP32(value) \ 73 (((uint32_t)SWAP16((uint16_t)((value) & 0xffff)) << 16) | \ 74 (uint32_t)SWAP16((uint16_t)((value) >> 16))) 75 76 static void 77 xvalconv(uint32_t *dest, uint32_t *src, int len) 78 { 79 int i; 80 81 for (i = 0; i < len; i++) { 82 dest [i] = SWAP32(src[i]); 83 } 84 } 85 #endif /* _LITTLE_ENDIAN */ 86 87 /* 88 * Computes a new random value, which is stored in x_j; updates 89 * XKEY. XSEED_j is additional input. In principle, we should 90 * protect XKEY, perhaps by putting it on a non-pagable page, but we 91 * aways clobber XKEY with fresh entropy just before we use it. And 92 * step 3d irreversibly updates it just after we use it. The only 93 * risk is that if an attacker captured the state while the entropy 94 * generator was broken, the attacker could predict future values. 95 * There are two cases: 1. The attack gets root access to a live 96 * system. But there is no defense against that. 2. The attacker 97 * gets access to a crash dump. But by then no values are being 98 * generated. 99 * 100 * Note that XSEEDj is overwritten with sensitive stuff, and must be 101 * zeroed by the caller. We use two separate symbols (XVAL and 102 * XSEEDj) to make each step match the notation in FIPS 186-2. 103 */ 104 void 105 fips_random_inner(uint32_t *key, uint32_t *x_j, 106 uint32_t *XSEED_j) 107 { 108 SHA1_CTX sha1_context; 109 /* Alias to preserve terminology from FIPS 186-2 */ 110 #define XVAL XSEED_j 111 /* 112 * K&R section A8.7: If the array has fixed size, the number 113 * of initializers may not exceed the number of members in the 114 * array; if there are fewer, the trailing members are 115 * initialized with 0. 116 */ 117 static const char zero[SHA1BLOCKBYTES - SHA1BYTES] = {0}; 118 119 /* 120 * Step 3b: XVAL = (XKEY + XSEED_sub_j) mod 2^b. The mod is 121 * implicit in the 160 bit representation. Note that XVAL and 122 * XSEED_j are actually the same location. 123 */ 124 (void) fips_add160(XVAL, key, XSEED_j, 0, 0); 125 /* 126 * Step 3c: x_sub_j = G(t, XVAL). 127 */ 128 SHA1Init(&sha1_context); 129 SHA1Update(&sha1_context, (unsigned char *)XVAL, SHA1BYTES); 130 /* 131 * Filling to 64 bytes is requried by FIPS 186-2 Appendix 3.3. 132 * It also triggers SHA1Transform (the steps a-e of the spec). 133 * 134 * zero is a const char[], but SHA1update does not declare its 135 * second parameter const, even though it does not modify it, 136 * so we cast to suppress a compiler warning. 137 */ 138 SHA1Update(&sha1_context, (unsigned char *)zero, 139 SHA1BLOCKBYTES - SHA1BYTES); 140 /* 141 * The code below directly accesses the state field of 142 * sha1_context, which is of type SHA1_CTX, defined in sha1.h. 143 */ 144 /* copy out to x_j */ 145 146 #ifdef _BIG_ENDIAN 147 { 148 int i; 149 for (i = 0; i < 5; i++) { 150 x_j[i] = sha1_context.state[i]; 151 } 152 } 153 #else 154 xvalconv(x_j, sha1_context.state, SHA1BYTES/4); 155 #endif 156 157 /* 158 * Step 3d: XKEY = (1 + XKEY + x_sub_j) mod 2^b. b=160. The 159 * mod 2^160 is implicit in the 160 bit representation. The 160 * one is added via the carry-in flag. 161 */ 162 (void) fips_add160(key, key, x_j, 1, 0); 163 #undef XVAL 164 } 165