133841545SHajimu UMEMOTO /* $KAME: sha1.c,v 1.5 2000/11/08 06:13:08 itojun Exp $ */
251369649SPedro F. Giffuni /*-
351369649SPedro F. Giffuni * SPDX-License-Identifier: BSD-3-Clause
451369649SPedro F. Giffuni *
56a800098SYoshinobu Inoue * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
66a800098SYoshinobu Inoue * All rights reserved.
76a800098SYoshinobu Inoue *
86a800098SYoshinobu Inoue * Redistribution and use in source and binary forms, with or without
96a800098SYoshinobu Inoue * modification, are permitted provided that the following conditions
106a800098SYoshinobu Inoue * are met:
116a800098SYoshinobu Inoue * 1. Redistributions of source code must retain the above copyright
126a800098SYoshinobu Inoue * notice, this list of conditions and the following disclaimer.
136a800098SYoshinobu Inoue * 2. Redistributions in binary form must reproduce the above copyright
146a800098SYoshinobu Inoue * notice, this list of conditions and the following disclaimer in the
156a800098SYoshinobu Inoue * documentation and/or other materials provided with the distribution.
166a800098SYoshinobu Inoue * 3. Neither the name of the project nor the names of its contributors
176a800098SYoshinobu Inoue * may be used to endorse or promote products derived from this software
186a800098SYoshinobu Inoue * without specific prior written permission.
196a800098SYoshinobu Inoue *
206a800098SYoshinobu Inoue * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
216a800098SYoshinobu Inoue * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
226a800098SYoshinobu Inoue * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
236a800098SYoshinobu Inoue * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
246a800098SYoshinobu Inoue * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
256a800098SYoshinobu Inoue * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
266a800098SYoshinobu Inoue * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
276a800098SYoshinobu Inoue * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
286a800098SYoshinobu Inoue * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
296a800098SYoshinobu Inoue * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
306a800098SYoshinobu Inoue * SUCH DAMAGE.
316a800098SYoshinobu Inoue */
32ad39da78SDavid E. O'Brien
336a800098SYoshinobu Inoue /*
346a800098SYoshinobu Inoue * FIPS pub 180-1: Secure Hash Algorithm (SHA-1)
356a800098SYoshinobu Inoue * based on: http://csrc.nist.gov/fips/fip180-1.txt
366a800098SYoshinobu Inoue * implemented by Jun-ichiro itojun Itoh <itojun@itojun.org>
376a800098SYoshinobu Inoue */
386a800098SYoshinobu Inoue
396a800098SYoshinobu Inoue #include <sys/types.h>
406a800098SYoshinobu Inoue #include <sys/cdefs.h>
416a800098SYoshinobu Inoue #include <sys/time.h>
426a800098SYoshinobu Inoue #include <sys/systm.h>
436a800098SYoshinobu Inoue
446a800098SYoshinobu Inoue #include <crypto/sha1.h>
456a800098SYoshinobu Inoue
466a800098SYoshinobu Inoue /* sanity check */
476a800098SYoshinobu Inoue #if BYTE_ORDER != BIG_ENDIAN
486a800098SYoshinobu Inoue # if BYTE_ORDER != LITTLE_ENDIAN
496a800098SYoshinobu Inoue # define unsupported 1
506a800098SYoshinobu Inoue # endif
516a800098SYoshinobu Inoue #endif
526a800098SYoshinobu Inoue
536a800098SYoshinobu Inoue #ifndef unsupported
546a800098SYoshinobu Inoue
556a800098SYoshinobu Inoue /* constant table */
56d3d79e96SJohn Baldwin static uint32_t _K[] = { 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6 };
576a800098SYoshinobu Inoue #define K(t) _K[(t) / 20]
586a800098SYoshinobu Inoue
596a800098SYoshinobu Inoue #define F0(b, c, d) (((b) & (c)) | ((~(b)) & (d)))
606a800098SYoshinobu Inoue #define F1(b, c, d) (((b) ^ (c)) ^ (d))
616a800098SYoshinobu Inoue #define F2(b, c, d) (((b) & (c)) | ((b) & (d)) | ((c) & (d)))
626a800098SYoshinobu Inoue #define F3(b, c, d) (((b) ^ (c)) ^ (d))
636a800098SYoshinobu Inoue
646a800098SYoshinobu Inoue #define S(n, x) (((x) << (n)) | ((x) >> (32 - n)))
656a800098SYoshinobu Inoue
666a800098SYoshinobu Inoue #define H(n) (ctxt->h.b32[(n)])
676a800098SYoshinobu Inoue #define COUNT (ctxt->count)
686a800098SYoshinobu Inoue #define BCOUNT (ctxt->c.b64[0] / 8)
696a800098SYoshinobu Inoue #define W(n) (ctxt->m.b32[(n)])
706a800098SYoshinobu Inoue
716a800098SYoshinobu Inoue #define PUTBYTE(x) { \
726a800098SYoshinobu Inoue ctxt->m.b8[(COUNT % 64)] = (x); \
736a800098SYoshinobu Inoue COUNT++; \
746a800098SYoshinobu Inoue COUNT %= 64; \
756a800098SYoshinobu Inoue ctxt->c.b64[0] += 8; \
766a800098SYoshinobu Inoue if (COUNT % 64 == 0) \
776a800098SYoshinobu Inoue sha1_step(ctxt); \
786a800098SYoshinobu Inoue }
796a800098SYoshinobu Inoue
806a800098SYoshinobu Inoue #define PUTPAD(x) { \
816a800098SYoshinobu Inoue ctxt->m.b8[(COUNT % 64)] = (x); \
826a800098SYoshinobu Inoue COUNT++; \
836a800098SYoshinobu Inoue COUNT %= 64; \
846a800098SYoshinobu Inoue if (COUNT % 64 == 0) \
856a800098SYoshinobu Inoue sha1_step(ctxt); \
866a800098SYoshinobu Inoue }
876a800098SYoshinobu Inoue
8814e10f99SAlfred Perlstein static void sha1_step(struct sha1_ctxt *);
896a800098SYoshinobu Inoue
906a800098SYoshinobu Inoue static void
sha1_step(struct sha1_ctxt * ctxt)91*9038e6a1SJohn Baldwin sha1_step(struct sha1_ctxt *ctxt)
926a800098SYoshinobu Inoue {
93d3d79e96SJohn Baldwin uint32_t a, b, c, d, e;
946a800098SYoshinobu Inoue size_t t, s;
95d3d79e96SJohn Baldwin uint32_t tmp;
966a800098SYoshinobu Inoue
976a800098SYoshinobu Inoue #if BYTE_ORDER == LITTLE_ENDIAN
986a800098SYoshinobu Inoue struct sha1_ctxt tctxt;
996a800098SYoshinobu Inoue bcopy(&ctxt->m.b8[0], &tctxt.m.b8[0], 64);
1006a800098SYoshinobu Inoue ctxt->m.b8[0] = tctxt.m.b8[3]; ctxt->m.b8[1] = tctxt.m.b8[2];
1016a800098SYoshinobu Inoue ctxt->m.b8[2] = tctxt.m.b8[1]; ctxt->m.b8[3] = tctxt.m.b8[0];
1026a800098SYoshinobu Inoue ctxt->m.b8[4] = tctxt.m.b8[7]; ctxt->m.b8[5] = tctxt.m.b8[6];
1036a800098SYoshinobu Inoue ctxt->m.b8[6] = tctxt.m.b8[5]; ctxt->m.b8[7] = tctxt.m.b8[4];
1046a800098SYoshinobu Inoue ctxt->m.b8[8] = tctxt.m.b8[11]; ctxt->m.b8[9] = tctxt.m.b8[10];
1056a800098SYoshinobu Inoue ctxt->m.b8[10] = tctxt.m.b8[9]; ctxt->m.b8[11] = tctxt.m.b8[8];
1066a800098SYoshinobu Inoue ctxt->m.b8[12] = tctxt.m.b8[15]; ctxt->m.b8[13] = tctxt.m.b8[14];
1076a800098SYoshinobu Inoue ctxt->m.b8[14] = tctxt.m.b8[13]; ctxt->m.b8[15] = tctxt.m.b8[12];
1086a800098SYoshinobu Inoue ctxt->m.b8[16] = tctxt.m.b8[19]; ctxt->m.b8[17] = tctxt.m.b8[18];
1096a800098SYoshinobu Inoue ctxt->m.b8[18] = tctxt.m.b8[17]; ctxt->m.b8[19] = tctxt.m.b8[16];
1106a800098SYoshinobu Inoue ctxt->m.b8[20] = tctxt.m.b8[23]; ctxt->m.b8[21] = tctxt.m.b8[22];
1116a800098SYoshinobu Inoue ctxt->m.b8[22] = tctxt.m.b8[21]; ctxt->m.b8[23] = tctxt.m.b8[20];
1126a800098SYoshinobu Inoue ctxt->m.b8[24] = tctxt.m.b8[27]; ctxt->m.b8[25] = tctxt.m.b8[26];
1136a800098SYoshinobu Inoue ctxt->m.b8[26] = tctxt.m.b8[25]; ctxt->m.b8[27] = tctxt.m.b8[24];
1146a800098SYoshinobu Inoue ctxt->m.b8[28] = tctxt.m.b8[31]; ctxt->m.b8[29] = tctxt.m.b8[30];
1156a800098SYoshinobu Inoue ctxt->m.b8[30] = tctxt.m.b8[29]; ctxt->m.b8[31] = tctxt.m.b8[28];
1166a800098SYoshinobu Inoue ctxt->m.b8[32] = tctxt.m.b8[35]; ctxt->m.b8[33] = tctxt.m.b8[34];
1176a800098SYoshinobu Inoue ctxt->m.b8[34] = tctxt.m.b8[33]; ctxt->m.b8[35] = tctxt.m.b8[32];
1186a800098SYoshinobu Inoue ctxt->m.b8[36] = tctxt.m.b8[39]; ctxt->m.b8[37] = tctxt.m.b8[38];
1196a800098SYoshinobu Inoue ctxt->m.b8[38] = tctxt.m.b8[37]; ctxt->m.b8[39] = tctxt.m.b8[36];
1206a800098SYoshinobu Inoue ctxt->m.b8[40] = tctxt.m.b8[43]; ctxt->m.b8[41] = tctxt.m.b8[42];
1216a800098SYoshinobu Inoue ctxt->m.b8[42] = tctxt.m.b8[41]; ctxt->m.b8[43] = tctxt.m.b8[40];
1226a800098SYoshinobu Inoue ctxt->m.b8[44] = tctxt.m.b8[47]; ctxt->m.b8[45] = tctxt.m.b8[46];
1236a800098SYoshinobu Inoue ctxt->m.b8[46] = tctxt.m.b8[45]; ctxt->m.b8[47] = tctxt.m.b8[44];
1246a800098SYoshinobu Inoue ctxt->m.b8[48] = tctxt.m.b8[51]; ctxt->m.b8[49] = tctxt.m.b8[50];
1256a800098SYoshinobu Inoue ctxt->m.b8[50] = tctxt.m.b8[49]; ctxt->m.b8[51] = tctxt.m.b8[48];
1266a800098SYoshinobu Inoue ctxt->m.b8[52] = tctxt.m.b8[55]; ctxt->m.b8[53] = tctxt.m.b8[54];
1276a800098SYoshinobu Inoue ctxt->m.b8[54] = tctxt.m.b8[53]; ctxt->m.b8[55] = tctxt.m.b8[52];
1286a800098SYoshinobu Inoue ctxt->m.b8[56] = tctxt.m.b8[59]; ctxt->m.b8[57] = tctxt.m.b8[58];
1296a800098SYoshinobu Inoue ctxt->m.b8[58] = tctxt.m.b8[57]; ctxt->m.b8[59] = tctxt.m.b8[56];
1306a800098SYoshinobu Inoue ctxt->m.b8[60] = tctxt.m.b8[63]; ctxt->m.b8[61] = tctxt.m.b8[62];
1316a800098SYoshinobu Inoue ctxt->m.b8[62] = tctxt.m.b8[61]; ctxt->m.b8[63] = tctxt.m.b8[60];
1326a800098SYoshinobu Inoue #endif
1336a800098SYoshinobu Inoue
1346a800098SYoshinobu Inoue a = H(0); b = H(1); c = H(2); d = H(3); e = H(4);
1356a800098SYoshinobu Inoue
1366a800098SYoshinobu Inoue for (t = 0; t < 20; t++) {
1376a800098SYoshinobu Inoue s = t & 0x0f;
1386a800098SYoshinobu Inoue if (t >= 16) {
1396a800098SYoshinobu Inoue W(s) = S(1, W((s+13) & 0x0f) ^ W((s+8) & 0x0f) ^ W((s+2) & 0x0f) ^ W(s));
1406a800098SYoshinobu Inoue }
1416a800098SYoshinobu Inoue tmp = S(5, a) + F0(b, c, d) + e + W(s) + K(t);
1426a800098SYoshinobu Inoue e = d; d = c; c = S(30, b); b = a; a = tmp;
1436a800098SYoshinobu Inoue }
1446a800098SYoshinobu Inoue for (t = 20; t < 40; t++) {
1456a800098SYoshinobu Inoue s = t & 0x0f;
1466a800098SYoshinobu Inoue W(s) = S(1, W((s+13) & 0x0f) ^ W((s+8) & 0x0f) ^ W((s+2) & 0x0f) ^ W(s));
1476a800098SYoshinobu Inoue tmp = S(5, a) + F1(b, c, d) + e + W(s) + K(t);
1486a800098SYoshinobu Inoue e = d; d = c; c = S(30, b); b = a; a = tmp;
1496a800098SYoshinobu Inoue }
1506a800098SYoshinobu Inoue for (t = 40; t < 60; t++) {
1516a800098SYoshinobu Inoue s = t & 0x0f;
1526a800098SYoshinobu Inoue W(s) = S(1, W((s+13) & 0x0f) ^ W((s+8) & 0x0f) ^ W((s+2) & 0x0f) ^ W(s));
1536a800098SYoshinobu Inoue tmp = S(5, a) + F2(b, c, d) + e + W(s) + K(t);
1546a800098SYoshinobu Inoue e = d; d = c; c = S(30, b); b = a; a = tmp;
1556a800098SYoshinobu Inoue }
1566a800098SYoshinobu Inoue for (t = 60; t < 80; t++) {
1576a800098SYoshinobu Inoue s = t & 0x0f;
1586a800098SYoshinobu Inoue W(s) = S(1, W((s+13) & 0x0f) ^ W((s+8) & 0x0f) ^ W((s+2) & 0x0f) ^ W(s));
1596a800098SYoshinobu Inoue tmp = S(5, a) + F3(b, c, d) + e + W(s) + K(t);
1606a800098SYoshinobu Inoue e = d; d = c; c = S(30, b); b = a; a = tmp;
1616a800098SYoshinobu Inoue }
1626a800098SYoshinobu Inoue
1636a800098SYoshinobu Inoue H(0) = H(0) + a;
1646a800098SYoshinobu Inoue H(1) = H(1) + b;
1656a800098SYoshinobu Inoue H(2) = H(2) + c;
1666a800098SYoshinobu Inoue H(3) = H(3) + d;
1676a800098SYoshinobu Inoue H(4) = H(4) + e;
1686a800098SYoshinobu Inoue
1696a800098SYoshinobu Inoue bzero(&ctxt->m.b8[0], 64);
1706a800098SYoshinobu Inoue }
1716a800098SYoshinobu Inoue
1726a800098SYoshinobu Inoue /*------------------------------------------------------------*/
1736a800098SYoshinobu Inoue
1746a800098SYoshinobu Inoue void
sha1_init(struct sha1_ctxt * ctxt)175*9038e6a1SJohn Baldwin sha1_init(struct sha1_ctxt *ctxt)
1766a800098SYoshinobu Inoue {
1776a800098SYoshinobu Inoue bzero(ctxt, sizeof(struct sha1_ctxt));
1786a800098SYoshinobu Inoue H(0) = 0x67452301;
1796a800098SYoshinobu Inoue H(1) = 0xefcdab89;
1806a800098SYoshinobu Inoue H(2) = 0x98badcfe;
1816a800098SYoshinobu Inoue H(3) = 0x10325476;
1826a800098SYoshinobu Inoue H(4) = 0xc3d2e1f0;
1836a800098SYoshinobu Inoue }
1846a800098SYoshinobu Inoue
1856a800098SYoshinobu Inoue void
sha1_pad(struct sha1_ctxt * ctxt)186*9038e6a1SJohn Baldwin sha1_pad(struct sha1_ctxt *ctxt)
1876a800098SYoshinobu Inoue {
1886a800098SYoshinobu Inoue size_t padlen; /*pad length in bytes*/
1896a800098SYoshinobu Inoue size_t padstart;
1906a800098SYoshinobu Inoue
1916a800098SYoshinobu Inoue PUTPAD(0x80);
1926a800098SYoshinobu Inoue
1936a800098SYoshinobu Inoue padstart = COUNT % 64;
1946a800098SYoshinobu Inoue padlen = 64 - padstart;
1956a800098SYoshinobu Inoue if (padlen < 8) {
1966a800098SYoshinobu Inoue bzero(&ctxt->m.b8[padstart], padlen);
1976a800098SYoshinobu Inoue COUNT += padlen;
1986a800098SYoshinobu Inoue COUNT %= 64;
1996a800098SYoshinobu Inoue sha1_step(ctxt);
2006a800098SYoshinobu Inoue padstart = COUNT % 64; /* should be 0 */
2016a800098SYoshinobu Inoue padlen = 64 - padstart; /* should be 64 */
2026a800098SYoshinobu Inoue }
2036a800098SYoshinobu Inoue bzero(&ctxt->m.b8[padstart], padlen - 8);
2046a800098SYoshinobu Inoue COUNT += (padlen - 8);
2056a800098SYoshinobu Inoue COUNT %= 64;
2066a800098SYoshinobu Inoue #if BYTE_ORDER == BIG_ENDIAN
2076a800098SYoshinobu Inoue PUTPAD(ctxt->c.b8[0]); PUTPAD(ctxt->c.b8[1]);
2086a800098SYoshinobu Inoue PUTPAD(ctxt->c.b8[2]); PUTPAD(ctxt->c.b8[3]);
2096a800098SYoshinobu Inoue PUTPAD(ctxt->c.b8[4]); PUTPAD(ctxt->c.b8[5]);
2106a800098SYoshinobu Inoue PUTPAD(ctxt->c.b8[6]); PUTPAD(ctxt->c.b8[7]);
2116a800098SYoshinobu Inoue #else
2126a800098SYoshinobu Inoue PUTPAD(ctxt->c.b8[7]); PUTPAD(ctxt->c.b8[6]);
2136a800098SYoshinobu Inoue PUTPAD(ctxt->c.b8[5]); PUTPAD(ctxt->c.b8[4]);
2146a800098SYoshinobu Inoue PUTPAD(ctxt->c.b8[3]); PUTPAD(ctxt->c.b8[2]);
2156a800098SYoshinobu Inoue PUTPAD(ctxt->c.b8[1]); PUTPAD(ctxt->c.b8[0]);
2166a800098SYoshinobu Inoue #endif
2176a800098SYoshinobu Inoue }
2186a800098SYoshinobu Inoue
2196a800098SYoshinobu Inoue void
sha1_loop(struct sha1_ctxt * ctxt,const uint8_t * input,size_t len)220*9038e6a1SJohn Baldwin sha1_loop(struct sha1_ctxt *ctxt, const uint8_t *input, size_t len)
2216a800098SYoshinobu Inoue {
2226a800098SYoshinobu Inoue size_t gaplen;
2236a800098SYoshinobu Inoue size_t gapstart;
2246a800098SYoshinobu Inoue size_t off;
2256a800098SYoshinobu Inoue size_t copysiz;
2266a800098SYoshinobu Inoue
2276a800098SYoshinobu Inoue off = 0;
2286a800098SYoshinobu Inoue
2296a800098SYoshinobu Inoue while (off < len) {
2306a800098SYoshinobu Inoue gapstart = COUNT % 64;
2316a800098SYoshinobu Inoue gaplen = 64 - gapstart;
2326a800098SYoshinobu Inoue
2336a800098SYoshinobu Inoue copysiz = (gaplen < len - off) ? gaplen : len - off;
2346a800098SYoshinobu Inoue bcopy(&input[off], &ctxt->m.b8[gapstart], copysiz);
2356a800098SYoshinobu Inoue COUNT += copysiz;
2366a800098SYoshinobu Inoue COUNT %= 64;
2376a800098SYoshinobu Inoue ctxt->c.b64[0] += copysiz * 8;
2386a800098SYoshinobu Inoue if (COUNT % 64 == 0)
2396a800098SYoshinobu Inoue sha1_step(ctxt);
2406a800098SYoshinobu Inoue off += copysiz;
2416a800098SYoshinobu Inoue }
2426a800098SYoshinobu Inoue }
2436a800098SYoshinobu Inoue
2446a800098SYoshinobu Inoue void
sha1_result(struct sha1_ctxt * ctxt,char digest0[static SHA1_RESULTLEN])245571ebf76SConrad Meyer sha1_result(struct sha1_ctxt *ctxt, char digest0[static SHA1_RESULTLEN])
2466a800098SYoshinobu Inoue {
247d3d79e96SJohn Baldwin uint8_t *digest;
2486a800098SYoshinobu Inoue
249d3d79e96SJohn Baldwin digest = (uint8_t *)digest0;
2506a800098SYoshinobu Inoue sha1_pad(ctxt);
2516a800098SYoshinobu Inoue #if BYTE_ORDER == BIG_ENDIAN
252571ebf76SConrad Meyer bcopy(&ctxt->h.b8[0], digest, SHA1_RESULTLEN);
2536a800098SYoshinobu Inoue #else
2546a800098SYoshinobu Inoue digest[0] = ctxt->h.b8[3]; digest[1] = ctxt->h.b8[2];
2556a800098SYoshinobu Inoue digest[2] = ctxt->h.b8[1]; digest[3] = ctxt->h.b8[0];
2566a800098SYoshinobu Inoue digest[4] = ctxt->h.b8[7]; digest[5] = ctxt->h.b8[6];
2576a800098SYoshinobu Inoue digest[6] = ctxt->h.b8[5]; digest[7] = ctxt->h.b8[4];
2586a800098SYoshinobu Inoue digest[8] = ctxt->h.b8[11]; digest[9] = ctxt->h.b8[10];
2596a800098SYoshinobu Inoue digest[10] = ctxt->h.b8[9]; digest[11] = ctxt->h.b8[8];
2606a800098SYoshinobu Inoue digest[12] = ctxt->h.b8[15]; digest[13] = ctxt->h.b8[14];
2616a800098SYoshinobu Inoue digest[14] = ctxt->h.b8[13]; digest[15] = ctxt->h.b8[12];
2626a800098SYoshinobu Inoue digest[16] = ctxt->h.b8[19]; digest[17] = ctxt->h.b8[18];
2636a800098SYoshinobu Inoue digest[18] = ctxt->h.b8[17]; digest[19] = ctxt->h.b8[16];
2646a800098SYoshinobu Inoue #endif
2656a800098SYoshinobu Inoue }
2666a800098SYoshinobu Inoue
2676a800098SYoshinobu Inoue #endif /*unsupported*/
268