Home | History | Annotate | Line # | Download | only in cp
      1 
      2 /*-
      3  * Copyright 2005,2007,2009 Colin Percival
      4  * All rights reserved.
      5  *
      6  * Redistribution and use in source and binary forms, with or without
      7  * modification, are permitted provided that the following conditions
      8  * are met:
      9  * 1. Redistributions of source code must retain the above copyright
     10  *    notice, this list of conditions and the following disclaimer.
     11  * 2. Redistributions in binary form must reproduce the above copyright
     12  *    notice, this list of conditions and the following disclaimer in the
     13  *    documentation and/or other materials provided with the distribution.
     14  *
     15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
     16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
     19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     25  * SUCH DAMAGE.
     26  *
     27  */
     28 
     29 #include <limits.h>
     30 #include <stdint.h>
     31 #include <stdlib.h>
     32 #include <string.h>
     33 
     34 #include <sys/types.h>
     35 
     36 #include "crypto_hash_sha512.h"
     37 #include "private/common.h"
     38 #include "utils.h"
     39 
     40 static void
     41 be64enc_vect(unsigned char *dst, const uint64_t *src, size_t len)
     42 {
     43     size_t i;
     44 
     45     for (i = 0; i < len / 8; i++) {
     46         STORE64_BE(dst + i * 8, src[i]);
     47     }
     48 }
     49 
     50 static void
     51 be64dec_vect(uint64_t *dst, const unsigned char *src, size_t len)
     52 {
     53     size_t i;
     54 
     55     for (i = 0; i < len / 8; i++) {
     56         dst[i] = LOAD64_BE(src + i * 8);
     57     }
     58 }
     59 
     60 static const uint64_t Krnd[80] = {
     61     0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL,
     62     0xe9b5dba58189dbbcULL, 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,
     63     0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, 0xd807aa98a3030242ULL,
     64     0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
     65     0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL,
     66     0xc19bf174cf692694ULL, 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL,
     67     0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, 0x2de92c6f592b0275ULL,
     68     0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
     69     0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL,
     70     0xbf597fc7beef0ee4ULL, 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL,
     71     0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, 0x27b70a8546d22ffcULL,
     72     0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
     73     0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL,
     74     0x92722c851482353bULL, 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL,
     75     0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, 0xd192e819d6ef5218ULL,
     76     0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
     77     0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL,
     78     0x34b0bcb5e19b48a8ULL, 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL,
     79     0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, 0x748f82ee5defb2fcULL,
     80     0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
     81     0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL,
     82     0xc67178f2e372532bULL, 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL,
     83     0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, 0x06f067aa72176fbaULL,
     84     0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
     85     0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL,
     86     0x431d67c49c100d4cULL, 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL,
     87     0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL
     88 };
     89 
     90 #define Ch(x, y, z) ((x & (y ^ z)) ^ z)
     91 #define Maj(x, y, z) ((x & (y | z)) | (y & z))
     92 #define SHR(x, n) (x >> n)
     93 #define ROTR(x, n) ROTR64(x, n)
     94 #define S0(x) (ROTR(x, 28) ^ ROTR(x, 34) ^ ROTR(x, 39))
     95 #define S1(x) (ROTR(x, 14) ^ ROTR(x, 18) ^ ROTR(x, 41))
     96 #define s0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7))
     97 #define s1(x) (ROTR(x, 19) ^ ROTR(x, 61) ^ SHR(x, 6))
     98 
     99 #define RND(a, b, c, d, e, f, g, h, k) \
    100     h += S1(e) + Ch(e, f, g) + k;      \
    101     d += h;                            \
    102     h += S0(a) + Maj(a, b, c);
    103 
    104 #define RNDr(S, W, i, ii)                                                   \
    105     RND(S[(80 - i) % 8], S[(81 - i) % 8], S[(82 - i) % 8], S[(83 - i) % 8], \
    106         S[(84 - i) % 8], S[(85 - i) % 8], S[(86 - i) % 8], S[(87 - i) % 8], \
    107         W[i + ii] + Krnd[i + ii])
    108 
    109 #define MSCH(W, ii, i) \
    110     W[i + ii + 16] =   \
    111         s1(W[i + ii + 14]) + W[i + ii + 9] + s0(W[i + ii + 1]) + W[i + ii]
    112 
    113 static void
    114 SHA512_Transform(uint64_t *state, const uint8_t block[128], uint64_t W[80],
    115                  uint64_t S[8])
    116 {
    117     int i;
    118 
    119     be64dec_vect(W, block, 128);
    120     memcpy(S, state, 64);
    121     for (i = 0; i < 80; i += 16) {
    122         RNDr(S, W, 0, i);
    123         RNDr(S, W, 1, i);
    124         RNDr(S, W, 2, i);
    125         RNDr(S, W, 3, i);
    126         RNDr(S, W, 4, i);
    127         RNDr(S, W, 5, i);
    128         RNDr(S, W, 6, i);
    129         RNDr(S, W, 7, i);
    130         RNDr(S, W, 8, i);
    131         RNDr(S, W, 9, i);
    132         RNDr(S, W, 10, i);
    133         RNDr(S, W, 11, i);
    134         RNDr(S, W, 12, i);
    135         RNDr(S, W, 13, i);
    136         RNDr(S, W, 14, i);
    137         RNDr(S, W, 15, i);
    138         if (i == 64) {
    139             break;
    140         }
    141         MSCH(W, 0, i);
    142         MSCH(W, 1, i);
    143         MSCH(W, 2, i);
    144         MSCH(W, 3, i);
    145         MSCH(W, 4, i);
    146         MSCH(W, 5, i);
    147         MSCH(W, 6, i);
    148         MSCH(W, 7, i);
    149         MSCH(W, 8, i);
    150         MSCH(W, 9, i);
    151         MSCH(W, 10, i);
    152         MSCH(W, 11, i);
    153         MSCH(W, 12, i);
    154         MSCH(W, 13, i);
    155         MSCH(W, 14, i);
    156         MSCH(W, 15, i);
    157     }
    158     for (i = 0; i < 8; i++) {
    159         state[i] += S[i];
    160     }
    161 }
    162 
    163 static const uint8_t PAD[128] = {
    164     0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    165     0,    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    166     0,    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    167     0,    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    168     0,    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    169     0,    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
    170 };
    171 
    172 static void
    173 SHA512_Pad(crypto_hash_sha512_state *state, uint64_t tmp64[80 + 8])
    174 {
    175     unsigned int r;
    176     unsigned int i;
    177 
    178     r = (unsigned int) ((state->count[1] >> 3) & 0x7f);
    179     if (r < 112) {
    180         for (i = 0; i < 112 - r; i++) {
    181             state->buf[r + i] = PAD[i];
    182         }
    183     } else {
    184         for (i = 0; i < 128 - r; i++) {
    185             state->buf[r + i] = PAD[i];
    186         }
    187         SHA512_Transform(state->state, state->buf, &tmp64[0], &tmp64[80]);
    188         memset(&state->buf[0], 0, 112);
    189     }
    190     be64enc_vect(&state->buf[112], state->count, 16);
    191     SHA512_Transform(state->state, state->buf, &tmp64[0], &tmp64[80]);
    192 }
    193 
    194 int
    195 crypto_hash_sha512_init(crypto_hash_sha512_state *state)
    196 {
    197     static const uint64_t sha512_initial_state[8] = {
    198         0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL, 0x3c6ef372fe94f82bULL,
    199         0xa54ff53a5f1d36f1ULL, 0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL,
    200         0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL
    201     };
    202 
    203     state->count[0] = state->count[1] = (uint64_t) 0U;
    204     memcpy(state->state, sha512_initial_state, sizeof sha512_initial_state);
    205 
    206     return 0;
    207 }
    208 
    209 int
    210 crypto_hash_sha512_update(crypto_hash_sha512_state *state,
    211                           const unsigned char *in, unsigned long long inlen)
    212 {
    213     uint64_t           tmp64[80 + 8];
    214     uint64_t           bitlen[2];
    215     unsigned long long i;
    216     unsigned long long r;
    217 
    218     if (inlen <= 0U) {
    219         return 0;
    220     }
    221     r = (unsigned long long) ((state->count[1] >> 3) & 0x7f);
    222 
    223     bitlen[1] = ((uint64_t) inlen) << 3;
    224     bitlen[0] = ((uint64_t) inlen) >> 61;
    225     /* LCOV_EXCL_START */
    226     if ((state->count[1] += bitlen[1]) < bitlen[1]) {
    227         state->count[0]++;
    228     }
    229     /* LCOV_EXCL_STOP */
    230     state->count[0] += bitlen[0];
    231     if (inlen < 128 - r) {
    232         for (i = 0; i < inlen; i++) {
    233             state->buf[r + i] = in[i];
    234         }
    235         return 0;
    236     }
    237     for (i = 0; i < 128 - r; i++) {
    238         state->buf[r + i] = in[i];
    239     }
    240     SHA512_Transform(state->state, state->buf, &tmp64[0], &tmp64[80]);
    241     in += 128 - r;
    242     inlen -= 128 - r;
    243 
    244     while (inlen >= 128) {
    245         SHA512_Transform(state->state, in, &tmp64[0], &tmp64[80]);
    246         in += 128;
    247         inlen -= 128;
    248     }
    249     inlen &= 127;
    250     for (i = 0; i < inlen; i++) {
    251         state->buf[i] = in[i];
    252     }
    253     sodium_memzero((void *) tmp64, sizeof tmp64);
    254 
    255     return 0;
    256 }
    257 
    258 int
    259 crypto_hash_sha512_final(crypto_hash_sha512_state *state, unsigned char *out)
    260 {
    261     uint64_t tmp64[80 + 8];
    262 
    263     SHA512_Pad(state, tmp64);
    264     be64enc_vect(out, state->state, 64);
    265     sodium_memzero((void *) tmp64, sizeof tmp64);
    266     sodium_memzero((void *) state, sizeof *state);
    267 
    268     return 0;
    269 }
    270 
    271 int
    272 crypto_hash_sha512(unsigned char *out, const unsigned char *in,
    273                    unsigned long long inlen)
    274 {
    275     crypto_hash_sha512_state state;
    276 
    277     crypto_hash_sha512_init(&state);
    278     crypto_hash_sha512_update(&state, in, inlen);
    279     crypto_hash_sha512_final(&state, out);
    280 
    281     return 0;
    282 }
    283