Home | History | Annotate | Line # | Download | only in digests
      1 /*
      2  * Copyright 2016-2020 The OpenSSL Project Authors. All Rights Reserved.
      3  *
      4  * Licensed under the Apache License 2.0 (the "License").  You may not use
      5  * this file except in compliance with the License.  You can obtain a copy
      6  * in the file LICENSE in the source distribution or at
      7  * https://www.openssl.org/source/license.html
      8  */
      9 
     10 /*
     11  * Derived from the BLAKE2 reference implementation written by Samuel Neves.
     12  * Copyright 2012, Samuel Neves <sneves (at) dei.uc.pt>
     13  * More information about the BLAKE2 hash function and its implementations
     14  * can be found at https://blake2.net.
     15  */
     16 
     17 #include <string.h>
     18 #include "internal/endian.h"
     19 
     20 static ossl_inline uint32_t load32(const uint8_t *src)
     21 {
     22     DECLARE_IS_ENDIAN;
     23 
     24     if (IS_LITTLE_ENDIAN) {
     25         uint32_t w;
     26         memcpy(&w, src, sizeof(w));
     27         return w;
     28     } else {
     29         uint32_t w = ((uint32_t)src[0])
     30             | ((uint32_t)src[1] << 8)
     31             | ((uint32_t)src[2] << 16)
     32             | ((uint32_t)src[3] << 24);
     33         return w;
     34     }
     35 }
     36 
     37 static ossl_inline uint64_t load64(const uint8_t *src)
     38 {
     39     DECLARE_IS_ENDIAN;
     40 
     41     if (IS_LITTLE_ENDIAN) {
     42         uint64_t w;
     43         memcpy(&w, src, sizeof(w));
     44         return w;
     45     } else {
     46         uint64_t w = ((uint64_t)src[0])
     47             | ((uint64_t)src[1] << 8)
     48             | ((uint64_t)src[2] << 16)
     49             | ((uint64_t)src[3] << 24)
     50             | ((uint64_t)src[4] << 32)
     51             | ((uint64_t)src[5] << 40)
     52             | ((uint64_t)src[6] << 48)
     53             | ((uint64_t)src[7] << 56);
     54         return w;
     55     }
     56 }
     57 
     58 static ossl_inline void store32(uint8_t *dst, uint32_t w)
     59 {
     60     DECLARE_IS_ENDIAN;
     61 
     62     if (IS_LITTLE_ENDIAN) {
     63         memcpy(dst, &w, sizeof(w));
     64     } else {
     65         uint8_t *p = (uint8_t *)dst;
     66         int i;
     67 
     68         for (i = 0; i < 4; i++)
     69             p[i] = (uint8_t)(w >> (8 * i));
     70     }
     71 }
     72 
     73 static ossl_inline void store64(uint8_t *dst, uint64_t w)
     74 {
     75     DECLARE_IS_ENDIAN;
     76 
     77     if (IS_LITTLE_ENDIAN) {
     78         memcpy(dst, &w, sizeof(w));
     79     } else {
     80         uint8_t *p = (uint8_t *)dst;
     81         int i;
     82 
     83         for (i = 0; i < 8; i++)
     84             p[i] = (uint8_t)(w >> (8 * i));
     85     }
     86 }
     87 
     88 static ossl_inline uint64_t load48(const uint8_t *src)
     89 {
     90     uint64_t w = ((uint64_t)src[0])
     91         | ((uint64_t)src[1] << 8)
     92         | ((uint64_t)src[2] << 16)
     93         | ((uint64_t)src[3] << 24)
     94         | ((uint64_t)src[4] << 32)
     95         | ((uint64_t)src[5] << 40);
     96     return w;
     97 }
     98 
     99 static ossl_inline void store48(uint8_t *dst, uint64_t w)
    100 {
    101     uint8_t *p = (uint8_t *)dst;
    102     p[0] = (uint8_t)w;
    103     p[1] = (uint8_t)(w >> 8);
    104     p[2] = (uint8_t)(w >> 16);
    105     p[3] = (uint8_t)(w >> 24);
    106     p[4] = (uint8_t)(w >> 32);
    107     p[5] = (uint8_t)(w >> 40);
    108 }
    109 
    110 static ossl_inline uint32_t rotr32(const uint32_t w, const unsigned int c)
    111 {
    112     return (w >> c) | (w << (32 - c));
    113 }
    114 
    115 static ossl_inline uint64_t rotr64(const uint64_t w, const unsigned int c)
    116 {
    117     return (w >> c) | (w << (64 - c));
    118 }
    119