xref: /netbsd-src/lib/libcrypt/crypt-sha1.c (revision 4d92dbe90eae91beded70db613c2e6a1fd6dd84a)
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