1*4d92dbe9Sriastradh /* $NetBSD: crypt-sha1.c,v 1.11 2024/07/23 22:37:11 riastradh Exp $ */ 2d16ceb03Sdrochner 33a0c68edSsjg /* 43a0c68edSsjg * Copyright (c) 2004, Juniper Networks, Inc. 53a0c68edSsjg * All rights reserved. 63a0c68edSsjg * 73a0c68edSsjg * Redistribution and use in source and binary forms, with or without 83a0c68edSsjg * modification, are permitted provided that the following conditions 93a0c68edSsjg * are met: 103a0c68edSsjg * 1. Redistributions of source code must retain the above copyright 113a0c68edSsjg * notice, this list of conditions and the following disclaimer. 123a0c68edSsjg * 2. Redistributions in binary form must reproduce the above copyright 133a0c68edSsjg * notice, this list of conditions and the following disclaimer in the 143a0c68edSsjg * documentation and/or other materials provided with the distribution. 153a0c68edSsjg * 3. Neither the name of the copyright holders nor the names of its 163a0c68edSsjg * contributors may be used to endorse or promote products derived 173a0c68edSsjg * from this software without specific prior written permission. 183a0c68edSsjg * 193a0c68edSsjg * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 203a0c68edSsjg * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 213a0c68edSsjg * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 223a0c68edSsjg * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 233a0c68edSsjg * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 243a0c68edSsjg * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 253a0c68edSsjg * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 263a0c68edSsjg * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 273a0c68edSsjg * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 283a0c68edSsjg * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 293a0c68edSsjg * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 303a0c68edSsjg */ 313a0c68edSsjg 323a0c68edSsjg #include <sys/cdefs.h> 333a0c68edSsjg #if !defined(lint) 34*4d92dbe9Sriastradh __RCSID("$NetBSD: crypt-sha1.c,v 1.11 2024/07/23 22:37:11 riastradh Exp $"); 353a0c68edSsjg #endif /* not lint */ 363a0c68edSsjg 373a0c68edSsjg #include <stdlib.h> 383a0c68edSsjg #include <unistd.h> 393a0c68edSsjg #include <stdio.h> 403a0c68edSsjg #include <string.h> 413a0c68edSsjg #include <time.h> 423a0c68edSsjg 433a0c68edSsjg #include <err.h> 443a0c68edSsjg #include "crypt.h" 453a0c68edSsjg 463a0c68edSsjg /* 473a0c68edSsjg * The default iterations - should take >0s on a fast CPU 483a0c68edSsjg * but not be insane for a slow CPU. 493a0c68edSsjg */ 503a0c68edSsjg #ifndef CRYPT_SHA1_ITERATIONS 513a0c68edSsjg # define CRYPT_SHA1_ITERATIONS 24680 523a0c68edSsjg #endif 533a0c68edSsjg /* 543a0c68edSsjg * Support a reasonably? long salt. 553a0c68edSsjg */ 563a0c68edSsjg #ifndef CRYPT_SHA1_SALT_LENGTH 573a0c68edSsjg # define CRYPT_SHA1_SALT_LENGTH 64 583a0c68edSsjg #endif 593a0c68edSsjg 603a0c68edSsjg /* 613a0c68edSsjg * This may be called from crypt_sha1 or gensalt. 623a0c68edSsjg * 633a0c68edSsjg * The value returned will be slightly less than <hint> which defaults 643a0c68edSsjg * to 24680. The goals are that the number of iterations should take 653a0c68edSsjg * non-zero amount of time on a fast cpu while not taking insanely 663a0c68edSsjg * long on a slow cpu. The current default will take about 5 seconds 673a0c68edSsjg * on a 100MHz sparc, and about 0.04 seconds on a 3GHz i386. 683a0c68edSsjg * The number is varied to frustrate those attempting to generate a 693a0c68edSsjg * dictionary of pre-computed hashes. 703a0c68edSsjg */ 71f9151ba9Snia crypt_private unsigned int 723a0c68edSsjg __crypt_sha1_iterations (unsigned int hint) 733a0c68edSsjg { 743a0c68edSsjg /* 753a0c68edSsjg * We treat CRYPT_SHA1_ITERATIONS as a hint. 763a0c68edSsjg * Make it harder for someone to pre-compute hashes for a 773a0c68edSsjg * dictionary attack by not using the same iteration count for 783a0c68edSsjg * every entry. 793a0c68edSsjg */ 80129cb9a5Snia if (hint < 4) 813a0c68edSsjg hint = CRYPT_SHA1_ITERATIONS; 82129cb9a5Snia return hint - arc4random_uniform(hint / 4); 833a0c68edSsjg } 843a0c68edSsjg 853a0c68edSsjg /* 863a0c68edSsjg * UNIX password using hmac_sha1 873a0c68edSsjg * This is PBKDF1 from RFC 2898, but using hmac_sha1. 883a0c68edSsjg * 893a0c68edSsjg * The format of the encrypted password is: 903a0c68edSsjg * $<tag>$<iterations>$<salt>$<digest> 913a0c68edSsjg * 923a0c68edSsjg * where: 933a0c68edSsjg * <tag> is "sha1" 943a0c68edSsjg * <iterations> is an unsigned int identifying how many rounds 953a0c68edSsjg * have been applied to <digest>. The number 963a0c68edSsjg * should vary slightly for each password to make 973a0c68edSsjg * it harder to generate a dictionary of 983a0c68edSsjg * pre-computed hashes. See crypt_sha1_iterations. 993a0c68edSsjg * <salt> up to 64 bytes of random data, 8 bytes is 1003a0c68edSsjg * currently considered more than enough. 1013a0c68edSsjg * <digest> the hashed password. 1023a0c68edSsjg * 1033a0c68edSsjg * NOTE: 1043a0c68edSsjg * To be FIPS 140 compliant, the password which is used as a hmac key, 1053a0c68edSsjg * should be between 10 and 20 characters to provide at least 80bits 1063a0c68edSsjg * strength, and avoid the need to hash it before using as the 1073a0c68edSsjg * hmac key. 1083a0c68edSsjg */ 109f9151ba9Snia crypt_private char * 1103a0c68edSsjg __crypt_sha1 (const char *pw, const char *salt) 1113a0c68edSsjg { 112d16ceb03Sdrochner static const char *magic = SHA1_MAGIC; 1133a0c68edSsjg static unsigned char hmac_buf[SHA1_SIZE]; 1143a0c68edSsjg static char passwd[(2 * sizeof(SHA1_MAGIC)) + 1153a0c68edSsjg CRYPT_SHA1_SALT_LENGTH + SHA1_SIZE]; 116e7c5804cSdrochner const char *sp; 1173a0c68edSsjg char *ep; 1183a0c68edSsjg unsigned long ul; 1193a0c68edSsjg int sl; 1203a0c68edSsjg int pl; 1213a0c68edSsjg int dl; 1223a0c68edSsjg unsigned int iterations; 1233a0c68edSsjg unsigned int i; 12439ab77f3Sdholland /* XXX silence -Wpointer-sign (would be nice to fix this some other way) */ 12539ab77f3Sdholland const unsigned char *pwu = (const unsigned char *)pw; 1263a0c68edSsjg 1273a0c68edSsjg /* 1283a0c68edSsjg * Salt format is 1293a0c68edSsjg * $<tag>$<iterations>$salt[$] 1303a0c68edSsjg * If it does not start with $ we use our default iterations. 1313a0c68edSsjg */ 1323a0c68edSsjg 1333a0c68edSsjg /* If it starts with the magic string, then skip that */ 134e7c5804cSdrochner if (!strncmp(salt, magic, strlen(magic))) { 135e7c5804cSdrochner salt += strlen(magic); 1363a0c68edSsjg /* and get the iteration count */ 137e7c5804cSdrochner iterations = strtoul(salt, &ep, 10); 1383a0c68edSsjg if (*ep != '$') 1393a0c68edSsjg return NULL; /* invalid input */ 140e7c5804cSdrochner salt = ep + 1; /* skip over the '$' */ 1413a0c68edSsjg } else { 1423a0c68edSsjg iterations = __crypt_sha1_iterations(0); 1433a0c68edSsjg } 1443a0c68edSsjg 1453a0c68edSsjg /* It stops at the next '$', max CRYPT_SHA1_ITERATIONS chars */ 146e7c5804cSdrochner for (sp = salt; *sp && *sp != '$' && sp < (salt + CRYPT_SHA1_ITERATIONS); sp++) 1473a0c68edSsjg continue; 1483a0c68edSsjg 1493a0c68edSsjg /* Get the length of the actual salt */ 150e7c5804cSdrochner sl = sp - salt; 1513a0c68edSsjg pl = strlen(pw); 1523a0c68edSsjg 1533a0c68edSsjg /* 1543a0c68edSsjg * Now get to work... 1553a0c68edSsjg * Prime the pump with <salt><magic><iterations> 1563a0c68edSsjg */ 1573a0c68edSsjg dl = snprintf(passwd, sizeof (passwd), "%.*s%s%u", 158e7c5804cSdrochner sl, salt, magic, iterations); 1593a0c68edSsjg /* 1603a0c68edSsjg * Then hmac using <pw> as key, and repeat... 1613a0c68edSsjg */ 16239ab77f3Sdholland __hmac_sha1((unsigned char *)passwd, dl, pwu, pl, hmac_buf); 1633a0c68edSsjg for (i = 1; i < iterations; i++) { 16439ab77f3Sdholland __hmac_sha1(hmac_buf, SHA1_SIZE, pwu, pl, hmac_buf); 1653a0c68edSsjg } 1663a0c68edSsjg /* Now output... */ 1673a0c68edSsjg pl = snprintf(passwd, sizeof(passwd), "%s%u$%.*s$", 168e7c5804cSdrochner magic, iterations, sl, salt); 1693a0c68edSsjg ep = passwd + pl; 1703a0c68edSsjg 1713a0c68edSsjg /* Every 3 bytes of hash gives 24 bits which is 4 base64 chars */ 1723a0c68edSsjg for (i = 0; i < SHA1_SIZE - 3; i += 3) { 1733a0c68edSsjg ul = (hmac_buf[i+0] << 16) | 1743a0c68edSsjg (hmac_buf[i+1] << 8) | 1753a0c68edSsjg hmac_buf[i+2]; 1763a0c68edSsjg __crypt_to64(ep, ul, 4); ep += 4; 1773a0c68edSsjg } 1783a0c68edSsjg /* Only 2 bytes left, so we pad with byte0 */ 1793a0c68edSsjg ul = (hmac_buf[SHA1_SIZE - 2] << 16) | 1803a0c68edSsjg (hmac_buf[SHA1_SIZE - 1] << 8) | 1813a0c68edSsjg hmac_buf[0]; 1823a0c68edSsjg __crypt_to64(ep, ul, 4); ep += 4; 1833a0c68edSsjg *ep = '\0'; 1843a0c68edSsjg 1853a0c68edSsjg /* Don't leave anything around in vm they could use. */ 1861239c2bbSriastradh explicit_memset(hmac_buf, 0, sizeof hmac_buf); 1873a0c68edSsjg 1883a0c68edSsjg return passwd; 1893a0c68edSsjg } 190