The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/cddl/boot/zfs/sha256.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * CDDL HEADER START
    3  *
    4  * The contents of this file are subject to the terms of the
    5  * Common Development and Distribution License, Version 1.0 only
    6  * (the "License").  You may not use this file except in compliance
    7  * with the License.
    8  *
    9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   10  * or http://www.opensolaris.org/os/licensing.
   11  * See the License for the specific language governing permissions
   12  * and limitations under the License.
   13  *
   14  * When distributing Covered Code, include this CDDL HEADER in each
   15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
   16  * If applicable, add the following below this CDDL HEADER, with the
   17  * fields enclosed by brackets "[]" replaced with your own identifying
   18  * information: Portions Copyright [yyyy] [name of copyright owner]
   19  *
   20  * CDDL HEADER END
   21  */
   22 /*
   23  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
   24  * Use is subject to license terms.
   25  */
   26 /*
   27  * Copyright 2013 Saso Kiselkov.  All rights reserved.
   28  * Copyright 2015 Toomas Soome <tsoome@me.com>
   29  */
   30 
   31 /*
   32  * SHA-256 and SHA-512/256 hashes, as specified in FIPS 180-4, available at:
   33  * http://csrc.nist.gov/cryptval
   34  *
   35  * This is a very compact implementation of SHA-256 and SHA-512/256.
   36  * It is designed to be simple and portable, not to be fast.
   37  */
   38 
   39 /*
   40  * The literal definitions according to FIPS180-4 would be:
   41  *
   42  *      Ch(x, y, z)     (((x) & (y)) ^ ((~(x)) & (z)))
   43  *      Maj(x, y, z)    (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
   44  *
   45  * We use logical equivalents which require one less op.
   46  */
   47 #define Ch(x, y, z)     ((z) ^ ((x) & ((y) ^ (z))))
   48 #define Maj(x, y, z)    (((x) & (y)) ^ ((z) & ((x) ^ (y))))
   49 #define ROTR(x, n)      (((x) >> (n)) | ((x) << ((sizeof (x) * NBBY)-(n))))
   50 
   51 /* SHA-224/256 operations */
   52 #define BIGSIGMA0_256(x)        (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22))
   53 #define BIGSIGMA1_256(x)        (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25))
   54 #define SIGMA0_256(x)           (ROTR(x, 7) ^ ROTR(x, 18) ^ ((x) >> 3))
   55 #define SIGMA1_256(x)           (ROTR(x, 17) ^ ROTR(x, 19) ^ ((x) >> 10))
   56 
   57 /* SHA-384/512 operations */
   58 #define BIGSIGMA0_512(x)        (ROTR((x), 28) ^ ROTR((x), 34) ^ ROTR((x), 39))
   59 #define BIGSIGMA1_512(x)        (ROTR((x), 14) ^ ROTR((x), 18) ^ ROTR((x), 41))
   60 #define SIGMA0_512(x)           (ROTR((x), 1) ^ ROTR((x), 8) ^ ((x) >> 7))
   61 #define SIGMA1_512(x)           (ROTR((x), 19) ^ ROTR((x), 61) ^ ((x) >> 6))
   62 
   63 /* SHA-256 round constants */
   64 static const uint32_t SHA256_K[64] = {
   65         0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
   66         0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
   67         0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
   68         0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
   69         0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
   70         0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
   71         0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
   72         0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
   73         0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
   74         0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
   75         0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
   76         0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
   77         0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
   78         0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
   79         0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
   80         0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
   81 };
   82 
   83 /* SHA-512 round constants */
   84 static const uint64_t SHA512_K[80] = {
   85         0x428A2F98D728AE22ULL, 0x7137449123EF65CDULL,
   86         0xB5C0FBCFEC4D3B2FULL, 0xE9B5DBA58189DBBCULL,
   87         0x3956C25BF348B538ULL, 0x59F111F1B605D019ULL,
   88         0x923F82A4AF194F9BULL, 0xAB1C5ED5DA6D8118ULL,
   89         0xD807AA98A3030242ULL, 0x12835B0145706FBEULL,
   90         0x243185BE4EE4B28CULL, 0x550C7DC3D5FFB4E2ULL,
   91         0x72BE5D74F27B896FULL, 0x80DEB1FE3B1696B1ULL,
   92         0x9BDC06A725C71235ULL, 0xC19BF174CF692694ULL,
   93         0xE49B69C19EF14AD2ULL, 0xEFBE4786384F25E3ULL,
   94         0x0FC19DC68B8CD5B5ULL, 0x240CA1CC77AC9C65ULL,
   95         0x2DE92C6F592B0275ULL, 0x4A7484AA6EA6E483ULL,
   96         0x5CB0A9DCBD41FBD4ULL, 0x76F988DA831153B5ULL,
   97         0x983E5152EE66DFABULL, 0xA831C66D2DB43210ULL,
   98         0xB00327C898FB213FULL, 0xBF597FC7BEEF0EE4ULL,
   99         0xC6E00BF33DA88FC2ULL, 0xD5A79147930AA725ULL,
  100         0x06CA6351E003826FULL, 0x142929670A0E6E70ULL,
  101         0x27B70A8546D22FFCULL, 0x2E1B21385C26C926ULL,
  102         0x4D2C6DFC5AC42AEDULL, 0x53380D139D95B3DFULL,
  103         0x650A73548BAF63DEULL, 0x766A0ABB3C77B2A8ULL,
  104         0x81C2C92E47EDAEE6ULL, 0x92722C851482353BULL,
  105         0xA2BFE8A14CF10364ULL, 0xA81A664BBC423001ULL,
  106         0xC24B8B70D0F89791ULL, 0xC76C51A30654BE30ULL,
  107         0xD192E819D6EF5218ULL, 0xD69906245565A910ULL,
  108         0xF40E35855771202AULL, 0x106AA07032BBD1B8ULL,
  109         0x19A4C116B8D2D0C8ULL, 0x1E376C085141AB53ULL,
  110         0x2748774CDF8EEB99ULL, 0x34B0BCB5E19B48A8ULL,
  111         0x391C0CB3C5C95A63ULL, 0x4ED8AA4AE3418ACBULL,
  112         0x5B9CCA4F7763E373ULL, 0x682E6FF3D6B2B8A3ULL,
  113         0x748F82EE5DEFB2FCULL, 0x78A5636F43172F60ULL,
  114         0x84C87814A1F0AB72ULL, 0x8CC702081A6439ECULL,
  115         0x90BEFFFA23631E28ULL, 0xA4506CEBDE82BDE9ULL,
  116         0xBEF9A3F7B2C67915ULL, 0xC67178F2E372532BULL,
  117         0xCA273ECEEA26619CULL, 0xD186B8C721C0C207ULL,
  118         0xEADA7DD6CDE0EB1EULL, 0xF57D4F7FEE6ED178ULL,
  119         0x06F067AA72176FBAULL, 0x0A637DC5A2C898A6ULL,
  120         0x113F9804BEF90DAEULL, 0x1B710B35131C471BULL,
  121         0x28DB77F523047D84ULL, 0x32CAAB7B40C72493ULL,
  122         0x3C9EBE0A15C9BEBCULL, 0x431D67C49C100D4CULL,
  123         0x4CC5D4BECB3E42B6ULL, 0x597F299CFC657E2AULL,
  124         0x5FCB6FAB3AD6FAECULL, 0x6C44198C4A475817ULL
  125 };
  126 
  127 static void
  128 SHA256Transform(uint32_t *H, const uint8_t *cp)
  129 {
  130         uint32_t a, b, c, d, e, f, g, h, t, T1, T2, W[64];
  131 
  132         /* copy chunk into the first 16 words of the message schedule */
  133         for (t = 0; t < 16; t++, cp += sizeof (uint32_t))
  134                 W[t] = (cp[0] << 24) | (cp[1] << 16) | (cp[2] << 8) | cp[3];
  135 
  136         /* extend the first 16 words into the remaining 48 words */
  137         for (t = 16; t < 64; t++)
  138                 W[t] = SIGMA1_256(W[t - 2]) + W[t - 7] +
  139                     SIGMA0_256(W[t - 15]) + W[t - 16];
  140 
  141         /* init working variables to the current hash value */
  142         a = H[0]; b = H[1]; c = H[2]; d = H[3];
  143         e = H[4]; f = H[5]; g = H[6]; h = H[7];
  144 
  145         /* iterate the compression function for all rounds of the hash */
  146         for (t = 0; t < 64; t++) {
  147                 T1 = h + BIGSIGMA1_256(e) + Ch(e, f, g) + SHA256_K[t] + W[t];
  148                 T2 = BIGSIGMA0_256(a) + Maj(a, b, c);
  149                 h = g; g = f; f = e; e = d + T1;
  150                 d = c; c = b; b = a; a = T1 + T2;
  151         }
  152 
  153         /* add the compressed chunk to the current hash value */
  154         H[0] += a; H[1] += b; H[2] += c; H[3] += d;
  155         H[4] += e; H[5] += f; H[6] += g; H[7] += h;
  156 }
  157 
  158 static void
  159 SHA512Transform(uint64_t *H, const uint8_t *cp)
  160 {
  161         uint64_t a, b, c, d, e, f, g, h, t, T1, T2, W[80];
  162 
  163         /* copy chunk into the first 16 words of the message schedule */
  164         for (t = 0; t < 16; t++, cp += sizeof (uint64_t))
  165                 W[t] = ((uint64_t)cp[0] << 56) | ((uint64_t)cp[1] << 48) |
  166                     ((uint64_t)cp[2] << 40) | ((uint64_t)cp[3] << 32) |
  167                     ((uint64_t)cp[4] << 24) | ((uint64_t)cp[5] << 16) |
  168                     ((uint64_t)cp[6] << 8) | (uint64_t)cp[7];
  169 
  170         /* extend the first 16 words into the remaining 64 words */
  171         for (t = 16; t < 80; t++)
  172                 W[t] = SIGMA1_512(W[t - 2]) + W[t - 7] +
  173                     SIGMA0_512(W[t - 15]) + W[t - 16];
  174 
  175         /* init working variables to the current hash value */
  176         a = H[0]; b = H[1]; c = H[2]; d = H[3];
  177         e = H[4]; f = H[5]; g = H[6]; h = H[7];
  178 
  179         /* iterate the compression function for all rounds of the hash */
  180         for (t = 0; t < 80; t++) {
  181                 T1 = h + BIGSIGMA1_512(e) + Ch(e, f, g) + SHA512_K[t] + W[t];
  182                 T2 = BIGSIGMA0_512(a) + Maj(a, b, c);
  183                 h = g; g = f; f = e; e = d + T1;
  184                 d = c; c = b; b = a; a = T1 + T2;
  185         }
  186 
  187         /* add the compressed chunk to the current hash value */
  188         H[0] += a; H[1] += b; H[2] += c; H[3] += d;
  189         H[4] += e; H[5] += f; H[6] += g; H[7] += h;
  190 }
  191 
  192 /*
  193  * Implements the SHA-224 and SHA-256 hash algos - to select between them
  194  * pass the appropriate initial values of 'H' and truncate the last 32 bits
  195  * in case of SHA-224.
  196  */
  197 static void
  198 SHA256(uint32_t *H, const void *buf, uint64_t size, zio_cksum_t *zcp)
  199 {
  200         uint8_t pad[128];
  201         unsigned padsize = size & 63;
  202         unsigned i, k;
  203 
  204         /* process all blocks up to the last one */
  205         for (i = 0; i < size - padsize; i += 64)
  206                 SHA256Transform(H, (const uint8_t *)buf + i);
  207 
  208         /* process the last block and padding */
  209         for (k = 0; k < padsize; k++)
  210                 pad[k] = ((const uint8_t *)buf)[k + i];
  211 
  212         for (pad[padsize++] = 0x80; (padsize & 63) != 56; padsize++)
  213                 pad[padsize] = 0;
  214 
  215         for (i = 0; i < 8; i++)
  216                 pad[padsize++] = (size << 3) >> (56 - 8 * i);
  217 
  218         for (i = 0; i < padsize; i += 64)
  219                 SHA256Transform(H, pad + i);
  220 
  221         ZIO_SET_CHECKSUM(zcp,
  222             (uint64_t)H[0] << 32 | H[1],
  223             (uint64_t)H[2] << 32 | H[3],
  224             (uint64_t)H[4] << 32 | H[5],
  225             (uint64_t)H[6] << 32 | H[7]);
  226 }
  227 
  228 /*
  229  * encode 64bit data in big-endian format.
  230  */
  231 static void
  232 Encode64(uint8_t *output, uint64_t *input, size_t len)
  233 {
  234         size_t i, j;
  235         for (i = 0, j = 0; j < len; i++, j += 8) {
  236                 output[j]       = (input[i] >> 56) & 0xff;
  237                 output[j + 1]   = (input[i] >> 48) & 0xff;
  238                 output[j + 2]   = (input[i] >> 40) & 0xff;
  239                 output[j + 3]   = (input[i] >> 32) & 0xff;
  240                 output[j + 4]   = (input[i] >> 24) & 0xff;
  241                 output[j + 5]   = (input[i] >> 16) & 0xff;
  242                 output[j + 6]   = (input[i] >>  8) & 0xff;
  243                 output[j + 7]   = input[i] & 0xff;
  244         }
  245 }
  246 
  247 /*
  248  * Implements the SHA-384, SHA-512 and SHA-512/t hash algos - to select
  249  * between them pass the appropriate initial values for 'H'. The output
  250  * of this function is truncated to the first 256 bits that fit into 'zcp'.
  251  */
  252 static void
  253 SHA512(uint64_t *H, const void *buf, uint64_t size, zio_cksum_t *zcp)
  254 {
  255         uint64_t        c64[2];
  256         uint8_t         pad[256];
  257         unsigned        padsize = size & 127;
  258         unsigned        i, k;
  259 
  260         /* process all blocks up to the last one */
  261         for (i = 0; i < size - padsize; i += 128)
  262                 SHA512Transform(H, (const uint8_t *)buf + i);
  263 
  264         /* process the last block and padding */
  265         for (k = 0; k < padsize; k++)
  266                 pad[k] = ((const uint8_t *)buf)[k + i];
  267 
  268         if (padsize < 112) {
  269                 for (pad[padsize++] = 0x80; padsize < 112; padsize++)
  270                         pad[padsize] = 0;
  271         } else {
  272                 for (pad[padsize++] = 0x80; padsize < 240; padsize++)
  273                         pad[padsize] = 0;
  274         }
  275 
  276         c64[0] = 0;
  277         c64[1] = size << 3;
  278         Encode64(pad+padsize, c64, sizeof (c64));
  279         padsize += sizeof (c64);
  280 
  281         for (i = 0; i < padsize; i += 128)
  282                 SHA512Transform(H, pad + i);
  283 
  284         /* truncate the output to the first 256 bits which fit into 'zcp' */
  285         Encode64((uint8_t *)zcp, H, sizeof (uint64_t) * 4);
  286 }
  287 
  288 static void
  289 zio_checksum_SHA256(const void *buf, uint64_t size,
  290     const void *ctx_template __unused, zio_cksum_t *zcp)
  291 {
  292         /* SHA-256 as per FIPS 180-4. */
  293         uint32_t        H[] = {
  294                 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
  295                 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
  296         };
  297         SHA256(H, buf, size, zcp);
  298 }
  299 
  300 static void
  301 zio_checksum_SHA512_native(const void *buf, uint64_t size,
  302     const void *ctx_template __unused, zio_cksum_t *zcp)
  303 {
  304         /* SHA-512/256 as per FIPS 180-4. */
  305         uint64_t        H[] = {
  306                 0x22312194FC2BF72CULL, 0x9F555FA3C84C64C2ULL,
  307                 0x2393B86B6F53B151ULL, 0x963877195940EABDULL,
  308                 0x96283EE2A88EFFE3ULL, 0xBE5E1E2553863992ULL,
  309                 0x2B0199FC2C85B8AAULL, 0x0EB72DDC81C52CA2ULL
  310         };
  311         SHA512(H, buf, size, zcp);
  312 }
  313 
  314 static void
  315 zio_checksum_SHA512_byteswap(const void *buf, uint64_t size,
  316     const void *ctx_template, zio_cksum_t *zcp)
  317 {
  318         zio_cksum_t     tmp;
  319 
  320         zio_checksum_SHA512_native(buf, size, ctx_template, &tmp);
  321         zcp->zc_word[0] = BSWAP_64(tmp.zc_word[0]);
  322         zcp->zc_word[1] = BSWAP_64(tmp.zc_word[1]);
  323         zcp->zc_word[2] = BSWAP_64(tmp.zc_word[2]);
  324         zcp->zc_word[3] = BSWAP_64(tmp.zc_word[3]);
  325 }

Cache object: e924a1736fcf73003cd1dd6c5785bbe2


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.