Bill Cox | 2d0b441 | 2016-03-09 23:08:31 +0100 | [diff] [blame] | 1 | /* |
Pauli | 677963e | 2017-08-18 13:52:46 +1000 | [diff] [blame] | 2 | * Copyright 2016-2017 The OpenSSL Project Authors. All Rights Reserved. |
Bill Cox | 2d0b441 | 2016-03-09 23:08:31 +0100 | [diff] [blame] | 3 | * |
Rich Salz | b132225 | 2016-05-17 14:52:22 -0400 | [diff] [blame] | 4 | * Licensed under the OpenSSL license (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 |
Kurt Roeckx | 208527a | 2016-03-10 00:49:55 +0100 | [diff] [blame] | 7 | * https://www.openssl.org/source/license.html |
Bill Cox | 2d0b441 | 2016-03-09 23:08:31 +0100 | [diff] [blame] | 8 | */ |
| 9 | |
Kurt Roeckx | 208527a | 2016-03-10 00:49:55 +0100 | [diff] [blame] | 10 | /* |
| 11 | * Derived from the BLAKE2 reference implementation written by Samuel Neves. |
Rich Salz | b132225 | 2016-05-17 14:52:22 -0400 | [diff] [blame] | 12 | * Copyright 2012, Samuel Neves <sneves@dei.uc.pt> |
Kurt Roeckx | 208527a | 2016-03-10 00:49:55 +0100 | [diff] [blame] | 13 | * More information about the BLAKE2 hash function and its implementations |
| 14 | * can be found at https://blake2.net. |
| 15 | */ |
Bill Cox | 2d0b441 | 2016-03-09 23:08:31 +0100 | [diff] [blame] | 16 | |
Bill Cox | 2d0b441 | 2016-03-09 23:08:31 +0100 | [diff] [blame] | 17 | #include <string.h> |
| 18 | |
Kurt Roeckx | a574108 | 2016-03-11 01:06:51 +0100 | [diff] [blame] | 19 | static ossl_inline uint32_t load32(const uint8_t *src) |
Bill Cox | 2d0b441 | 2016-03-09 23:08:31 +0100 | [diff] [blame] | 20 | { |
Kurt Roeckx | 208527a | 2016-03-10 00:49:55 +0100 | [diff] [blame] | 21 | const union { |
| 22 | long one; |
| 23 | char little; |
| 24 | } is_endian = { 1 }; |
| 25 | |
| 26 | if (is_endian.little) { |
| 27 | uint32_t w; |
| 28 | memcpy(&w, src, sizeof(w)); |
| 29 | return w; |
| 30 | } else { |
Andy Polyakov | 1fab06a | 2016-03-13 22:19:53 +0100 | [diff] [blame] | 31 | uint32_t w = ((uint32_t)src[0]) |
| 32 | | ((uint32_t)src[1] << 8) |
| 33 | | ((uint32_t)src[2] << 16) |
| 34 | | ((uint32_t)src[3] << 24); |
Kurt Roeckx | 208527a | 2016-03-10 00:49:55 +0100 | [diff] [blame] | 35 | return w; |
| 36 | } |
Bill Cox | 2d0b441 | 2016-03-09 23:08:31 +0100 | [diff] [blame] | 37 | } |
| 38 | |
Kurt Roeckx | a574108 | 2016-03-11 01:06:51 +0100 | [diff] [blame] | 39 | static ossl_inline uint64_t load64(const uint8_t *src) |
Bill Cox | 2d0b441 | 2016-03-09 23:08:31 +0100 | [diff] [blame] | 40 | { |
Kurt Roeckx | 208527a | 2016-03-10 00:49:55 +0100 | [diff] [blame] | 41 | const union { |
| 42 | long one; |
| 43 | char little; |
| 44 | } is_endian = { 1 }; |
| 45 | |
| 46 | if (is_endian.little) { |
| 47 | uint64_t w; |
| 48 | memcpy(&w, src, sizeof(w)); |
| 49 | return w; |
| 50 | } else { |
Andy Polyakov | 1fab06a | 2016-03-13 22:19:53 +0100 | [diff] [blame] | 51 | uint64_t w = ((uint64_t)src[0]) |
| 52 | | ((uint64_t)src[1] << 8) |
| 53 | | ((uint64_t)src[2] << 16) |
| 54 | | ((uint64_t)src[3] << 24) |
| 55 | | ((uint64_t)src[4] << 32) |
| 56 | | ((uint64_t)src[5] << 40) |
| 57 | | ((uint64_t)src[6] << 48) |
| 58 | | ((uint64_t)src[7] << 56); |
Kurt Roeckx | 208527a | 2016-03-10 00:49:55 +0100 | [diff] [blame] | 59 | return w; |
| 60 | } |
Bill Cox | 2d0b441 | 2016-03-09 23:08:31 +0100 | [diff] [blame] | 61 | } |
| 62 | |
Kurt Roeckx | a574108 | 2016-03-11 01:06:51 +0100 | [diff] [blame] | 63 | static ossl_inline void store32(uint8_t *dst, uint32_t w) |
Bill Cox | 2d0b441 | 2016-03-09 23:08:31 +0100 | [diff] [blame] | 64 | { |
Kurt Roeckx | 208527a | 2016-03-10 00:49:55 +0100 | [diff] [blame] | 65 | const union { |
| 66 | long one; |
| 67 | char little; |
| 68 | } is_endian = { 1 }; |
| 69 | |
| 70 | if (is_endian.little) { |
| 71 | memcpy(dst, &w, sizeof(w)); |
| 72 | } else { |
| 73 | uint8_t *p = (uint8_t *)dst; |
| 74 | int i; |
| 75 | |
| 76 | for (i = 0; i < 4; i++) |
| 77 | p[i] = (uint8_t)(w >> (8 * i)); |
| 78 | } |
Bill Cox | 2d0b441 | 2016-03-09 23:08:31 +0100 | [diff] [blame] | 79 | } |
| 80 | |
Kurt Roeckx | a574108 | 2016-03-11 01:06:51 +0100 | [diff] [blame] | 81 | static ossl_inline void store64(uint8_t *dst, uint64_t w) |
Bill Cox | 2d0b441 | 2016-03-09 23:08:31 +0100 | [diff] [blame] | 82 | { |
Kurt Roeckx | 208527a | 2016-03-10 00:49:55 +0100 | [diff] [blame] | 83 | const union { |
| 84 | long one; |
| 85 | char little; |
| 86 | } is_endian = { 1 }; |
| 87 | |
| 88 | if (is_endian.little) { |
| 89 | memcpy(dst, &w, sizeof(w)); |
| 90 | } else { |
| 91 | uint8_t *p = (uint8_t *)dst; |
| 92 | int i; |
| 93 | |
| 94 | for (i = 0; i < 8; i++) |
| 95 | p[i] = (uint8_t)(w >> (8 * i)); |
| 96 | } |
Bill Cox | 2d0b441 | 2016-03-09 23:08:31 +0100 | [diff] [blame] | 97 | } |
| 98 | |
Kurt Roeckx | a574108 | 2016-03-11 01:06:51 +0100 | [diff] [blame] | 99 | static ossl_inline uint64_t load48(const uint8_t *src) |
Bill Cox | 2d0b441 | 2016-03-09 23:08:31 +0100 | [diff] [blame] | 100 | { |
Andy Polyakov | 1fab06a | 2016-03-13 22:19:53 +0100 | [diff] [blame] | 101 | uint64_t w = ((uint64_t)src[0]) |
| 102 | | ((uint64_t)src[1] << 8) |
| 103 | | ((uint64_t)src[2] << 16) |
| 104 | | ((uint64_t)src[3] << 24) |
| 105 | | ((uint64_t)src[4] << 32) |
| 106 | | ((uint64_t)src[5] << 40); |
Bill Cox | 2d0b441 | 2016-03-09 23:08:31 +0100 | [diff] [blame] | 107 | return w; |
| 108 | } |
| 109 | |
Kurt Roeckx | a574108 | 2016-03-11 01:06:51 +0100 | [diff] [blame] | 110 | static ossl_inline void store48(uint8_t *dst, uint64_t w) |
Bill Cox | 2d0b441 | 2016-03-09 23:08:31 +0100 | [diff] [blame] | 111 | { |
| 112 | uint8_t *p = (uint8_t *)dst; |
Andy Polyakov | 1fab06a | 2016-03-13 22:19:53 +0100 | [diff] [blame] | 113 | p[0] = (uint8_t)w; |
| 114 | p[1] = (uint8_t)(w>>8); |
| 115 | p[2] = (uint8_t)(w>>16); |
| 116 | p[3] = (uint8_t)(w>>24); |
| 117 | p[4] = (uint8_t)(w>>32); |
| 118 | p[5] = (uint8_t)(w>>40); |
Bill Cox | 2d0b441 | 2016-03-09 23:08:31 +0100 | [diff] [blame] | 119 | } |
| 120 | |
Kurt Roeckx | 53a5167 | 2016-03-11 01:19:43 +0100 | [diff] [blame] | 121 | static ossl_inline uint32_t rotr32(const uint32_t w, const unsigned int c) |
Bill Cox | 2d0b441 | 2016-03-09 23:08:31 +0100 | [diff] [blame] | 122 | { |
| 123 | return (w >> c) | (w << (32 - c)); |
| 124 | } |
| 125 | |
Kurt Roeckx | 53a5167 | 2016-03-11 01:19:43 +0100 | [diff] [blame] | 126 | static ossl_inline uint64_t rotr64(const uint64_t w, const unsigned int c) |
Bill Cox | 2d0b441 | 2016-03-09 23:08:31 +0100 | [diff] [blame] | 127 | { |
| 128 | return (w >> c) | (w << (64 - c)); |
| 129 | } |