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