crypt-sha1.c revision 1.6
1/* $NetBSD: crypt-sha1.c,v 1.6 2013/06/24 04:21:20 riastradh Exp $ */ 2 3/* 4 * Copyright (c) 2004, Juniper Networks, Inc. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. Neither the name of the copyright holders nor the names of its 16 * contributors may be used to endorse or promote products derived 17 * from this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32#include <sys/cdefs.h> 33#if !defined(lint) 34__RCSID("$NetBSD: crypt-sha1.c,v 1.6 2013/06/24 04:21:20 riastradh Exp $"); 35#endif /* not lint */ 36 37#include <stdlib.h> 38#include <unistd.h> 39#include <stdio.h> 40#include <string.h> 41#include <time.h> 42 43#include <err.h> 44#include "crypt.h" 45 46/* 47 * The default iterations - should take >0s on a fast CPU 48 * but not be insane for a slow CPU. 49 */ 50#ifndef CRYPT_SHA1_ITERATIONS 51# define CRYPT_SHA1_ITERATIONS 24680 52#endif 53/* 54 * Support a reasonably? long salt. 55 */ 56#ifndef CRYPT_SHA1_SALT_LENGTH 57# define CRYPT_SHA1_SALT_LENGTH 64 58#endif 59 60/* 61 * This may be called from crypt_sha1 or gensalt. 62 * 63 * The value returned will be slightly less than <hint> which defaults 64 * to 24680. The goals are that the number of iterations should take 65 * non-zero amount of time on a fast cpu while not taking insanely 66 * long on a slow cpu. The current default will take about 5 seconds 67 * on a 100MHz sparc, and about 0.04 seconds on a 3GHz i386. 68 * The number is varied to frustrate those attempting to generate a 69 * dictionary of pre-computed hashes. 70 */ 71unsigned int 72__crypt_sha1_iterations (unsigned int hint) 73{ 74 static int once = 1; 75 76 /* 77 * We treat CRYPT_SHA1_ITERATIONS as a hint. 78 * Make it harder for someone to pre-compute hashes for a 79 * dictionary attack by not using the same iteration count for 80 * every entry. 81 */ 82 83 if (once) { 84 int pid = getpid(); 85 86 srandom(time(NULL) ^ (pid * pid)); 87 once = 0; 88 } 89 if (hint == 0) 90 hint = CRYPT_SHA1_ITERATIONS; 91 return hint - (random() % (hint / 4)); 92} 93 94/* 95 * UNIX password using hmac_sha1 96 * This is PBKDF1 from RFC 2898, but using hmac_sha1. 97 * 98 * The format of the encrypted password is: 99 * $<tag>$<iterations>$<salt>$<digest> 100 * 101 * where: 102 * <tag> is "sha1" 103 * <iterations> is an unsigned int identifying how many rounds 104 * have been applied to <digest>. The number 105 * should vary slightly for each password to make 106 * it harder to generate a dictionary of 107 * pre-computed hashes. See crypt_sha1_iterations. 108 * <salt> up to 64 bytes of random data, 8 bytes is 109 * currently considered more than enough. 110 * <digest> the hashed password. 111 * 112 * NOTE: 113 * To be FIPS 140 compliant, the password which is used as a hmac key, 114 * should be between 10 and 20 characters to provide at least 80bits 115 * strength, and avoid the need to hash it before using as the 116 * hmac key. 117 */ 118char * 119__crypt_sha1 (const char *pw, const char *salt) 120{ 121 static const char *magic = SHA1_MAGIC; 122 static unsigned char hmac_buf[SHA1_SIZE]; 123 static char passwd[(2 * sizeof(SHA1_MAGIC)) + 124 CRYPT_SHA1_SALT_LENGTH + SHA1_SIZE]; 125 const char *sp; 126 char *ep; 127 unsigned long ul; 128 int sl; 129 int pl; 130 int dl; 131 unsigned int iterations; 132 unsigned int i; 133 134 /* 135 * Salt format is 136 * $<tag>$<iterations>$salt[$] 137 * If it does not start with $ we use our default iterations. 138 */ 139 140 /* If it starts with the magic string, then skip that */ 141 if (!strncmp(salt, magic, strlen(magic))) { 142 salt += strlen(magic); 143 /* and get the iteration count */ 144 iterations = strtoul(salt, &ep, 10); 145 if (*ep != '$') 146 return NULL; /* invalid input */ 147 salt = ep + 1; /* skip over the '$' */ 148 } else { 149 iterations = __crypt_sha1_iterations(0); 150 } 151 152 /* It stops at the next '$', max CRYPT_SHA1_ITERATIONS chars */ 153 for (sp = salt; *sp && *sp != '$' && sp < (salt + CRYPT_SHA1_ITERATIONS); sp++) 154 continue; 155 156 /* Get the length of the actual salt */ 157 sl = sp - salt; 158 pl = strlen(pw); 159 160 /* 161 * Now get to work... 162 * Prime the pump with <salt><magic><iterations> 163 */ 164 dl = snprintf(passwd, sizeof (passwd), "%.*s%s%u", 165 sl, salt, magic, iterations); 166 /* 167 * Then hmac using <pw> as key, and repeat... 168 */ 169 __hmac_sha1(passwd, dl, pw, pl, hmac_buf); 170 for (i = 1; i < iterations; i++) { 171 __hmac_sha1(hmac_buf, SHA1_SIZE, pw, pl, hmac_buf); 172 } 173 /* Now output... */ 174 pl = snprintf(passwd, sizeof(passwd), "%s%u$%.*s$", 175 magic, iterations, sl, salt); 176 ep = passwd + pl; 177 178 /* Every 3 bytes of hash gives 24 bits which is 4 base64 chars */ 179 for (i = 0; i < SHA1_SIZE - 3; i += 3) { 180 ul = (hmac_buf[i+0] << 16) | 181 (hmac_buf[i+1] << 8) | 182 hmac_buf[i+2]; 183 __crypt_to64(ep, ul, 4); ep += 4; 184 } 185 /* Only 2 bytes left, so we pad with byte0 */ 186 ul = (hmac_buf[SHA1_SIZE - 2] << 16) | 187 (hmac_buf[SHA1_SIZE - 1] << 8) | 188 hmac_buf[0]; 189 __crypt_to64(ep, ul, 4); ep += 4; 190 *ep = '\0'; 191 192 /* Don't leave anything around in vm they could use. */ 193 __explicit_memset(hmac_buf, 0, sizeof hmac_buf); 194 195 return passwd; 196} 197