| Absolute File Name: | /home/opencoverage/opencoverage/guest-scripts/openssl/src/crypto/siphash/siphash.c |
| Source code | Switch to Preprocessed file |
| Line | Source | Count | ||||||
|---|---|---|---|---|---|---|---|---|
| 1 | /* | - | ||||||
| 2 | * Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved. | - | ||||||
| 3 | * | - | ||||||
| 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 | - | ||||||
| 7 | * https://www.openssl.org/source/license.html | - | ||||||
| 8 | */ | - | ||||||
| 9 | - | |||||||
| 10 | /* Based on https://131002.net/siphash C reference implementation */ | - | ||||||
| 11 | /* | - | ||||||
| 12 | SipHash reference C implementation | - | ||||||
| 13 | - | |||||||
| 14 | Copyright (c) 2012-2016 Jean-Philippe Aumasson | - | ||||||
| 15 | Copyright (c) 2012-2014 Daniel J. Bernstein | - | ||||||
| 16 | - | |||||||
| 17 | To the extent possible under law, the author(s) have dedicated all copyright | - | ||||||
| 18 | and related and neighboring rights to this software to the public domain | - | ||||||
| 19 | worldwide. This software is distributed without any warranty. | - | ||||||
| 20 | - | |||||||
| 21 | You should have received a copy of the CC0 Public Domain Dedication along | - | ||||||
| 22 | with this software. If not, see | - | ||||||
| 23 | <http://creativecommons.org/publicdomain/zero/1.0/>. | - | ||||||
| 24 | */ | - | ||||||
| 25 | - | |||||||
| 26 | #include <stdlib.h> | - | ||||||
| 27 | #include <string.h> | - | ||||||
| 28 | #include <openssl/crypto.h> | - | ||||||
| 29 | - | |||||||
| 30 | #include "internal/siphash.h" | - | ||||||
| 31 | #include "siphash_local.h" | - | ||||||
| 32 | - | |||||||
| 33 | /* default: SipHash-2-4 */ | - | ||||||
| 34 | #define SIPHASH_C_ROUNDS 2 | - | ||||||
| 35 | #define SIPHASH_D_ROUNDS 4 | - | ||||||
| 36 | - | |||||||
| 37 | #define ROTL(x, b) (uint64_t)(((x) << (b)) | ((x) >> (64 - (b)))) | - | ||||||
| 38 | - | |||||||
| 39 | #define U32TO8_LE(p, v) \ | - | ||||||
| 40 | (p)[0] = (uint8_t)((v)); \ | - | ||||||
| 41 | (p)[1] = (uint8_t)((v) >> 8); \ | - | ||||||
| 42 | (p)[2] = (uint8_t)((v) >> 16); \ | - | ||||||
| 43 | (p)[3] = (uint8_t)((v) >> 24); | - | ||||||
| 44 | - | |||||||
| 45 | #define U64TO8_LE(p, v) \ | - | ||||||
| 46 | U32TO8_LE((p), (uint32_t)((v))); \ | - | ||||||
| 47 | U32TO8_LE((p) + 4, (uint32_t)((v) >> 32)); | - | ||||||
| 48 | - | |||||||
| 49 | #define U8TO64_LE(p) \ | - | ||||||
| 50 | (((uint64_t)((p)[0])) | ((uint64_t)((p)[1]) << 8) | \ | - | ||||||
| 51 | ((uint64_t)((p)[2]) << 16) | ((uint64_t)((p)[3]) << 24) | \ | - | ||||||
| 52 | ((uint64_t)((p)[4]) << 32) | ((uint64_t)((p)[5]) << 40) | \ | - | ||||||
| 53 | ((uint64_t)((p)[6]) << 48) | ((uint64_t)((p)[7]) << 56)) | - | ||||||
| 54 | - | |||||||
| 55 | #define SIPROUND \ | - | ||||||
| 56 | do { \ | - | ||||||
| 57 | v0 += v1; \ | - | ||||||
| 58 | v1 = ROTL(v1, 13); \ | - | ||||||
| 59 | v1 ^= v0; \ | - | ||||||
| 60 | v0 = ROTL(v0, 32); \ | - | ||||||
| 61 | v2 += v3; \ | - | ||||||
| 62 | v3 = ROTL(v3, 16); \ | - | ||||||
| 63 | v3 ^= v2; \ | - | ||||||
| 64 | v0 += v3; \ | - | ||||||
| 65 | v3 = ROTL(v3, 21); \ | - | ||||||
| 66 | v3 ^= v0; \ | - | ||||||
| 67 | v2 += v1; \ | - | ||||||
| 68 | v1 = ROTL(v1, 17); \ | - | ||||||
| 69 | v1 ^= v2; \ | - | ||||||
| 70 | v2 = ROTL(v2, 32); \ | - | ||||||
| 71 | } while (0) | - | ||||||
| 72 | - | |||||||
| 73 | size_t SipHash_ctx_size(void) | - | ||||||
| 74 | { | - | ||||||
| 75 | return sizeof(SIPHASH); never executed: return sizeof(SIPHASH); | 0 | ||||||
| 76 | } | - | ||||||
| 77 | - | |||||||
| 78 | size_t SipHash_hash_size(SIPHASH *ctx) | - | ||||||
| 79 | { | - | ||||||
| 80 | return ctx->hash_size; executed 52 times by 1 test: return ctx->hash_size;Executed by:
| 52 | ||||||
| 81 | } | - | ||||||
| 82 | - | |||||||
| 83 | static size_t siphash_adjust_hash_size(size_t hash_size) | - | ||||||
| 84 | { | - | ||||||
| 85 | if (hash_size == 0)
| 28-885 | ||||||
| 86 | hash_size = SIPHASH_MAX_DIGEST_SIZE; executed 28 times by 2 tests: hash_size = 16;Executed by:
| 28 | ||||||
| 87 | return hash_size; executed 913 times by 2 tests: return hash_size;Executed by:
| 913 | ||||||
| 88 | } | - | ||||||
| 89 | - | |||||||
| 90 | int SipHash_set_hash_size(SIPHASH *ctx, size_t hash_size) | - | ||||||
| 91 | { | - | ||||||
| 92 | hash_size = siphash_adjust_hash_size(hash_size); | - | ||||||
| 93 | if (hash_size != SIPHASH_MIN_DIGEST_SIZE
| 221-225 | ||||||
| 94 | && hash_size != SIPHASH_MAX_DIGEST_SIZE)
| 2-223 | ||||||
| 95 | return 0; executed 2 times by 2 tests: return 0;Executed by:
| 2 | ||||||
| 96 | - | |||||||
| 97 | ctx->hash_size = hash_size; | - | ||||||
| 98 | return 1; executed 444 times by 2 tests: return 1;Executed by:
| 444 | ||||||
| 99 | } | - | ||||||
| 100 | - | |||||||
| 101 | /* hash_size = crounds = drounds = 0 means SipHash24 with 16-byte output */ | - | ||||||
| 102 | int SipHash_Init(SIPHASH *ctx, const unsigned char *k, int crounds, int drounds) | - | ||||||
| 103 | { | - | ||||||
| 104 | uint64_t k0 = U8TO64_LE(k); | - | ||||||
| 105 | uint64_t k1 = U8TO64_LE(k + 8); | - | ||||||
| 106 | - | |||||||
| 107 | /* If the hash size wasn't set, i.e. is zero */ | - | ||||||
| 108 | ctx->hash_size = siphash_adjust_hash_size(ctx->hash_size); | - | ||||||
| 109 | - | |||||||
| 110 | if (drounds == 0)
| 0-467 | ||||||
| 111 | drounds = SIPHASH_D_ROUNDS; executed 467 times by 2 tests: drounds = 4;Executed by:
| 467 | ||||||
| 112 | if (crounds == 0)
| 0-467 | ||||||
| 113 | crounds = SIPHASH_C_ROUNDS; executed 467 times by 2 tests: crounds = 2;Executed by:
| 467 | ||||||
| 114 | - | |||||||
| 115 | ctx->crounds = crounds; | - | ||||||
| 116 | ctx->drounds = drounds; | - | ||||||
| 117 | - | |||||||
| 118 | ctx->len = 0; | - | ||||||
| 119 | ctx->total_inlen = 0; | - | ||||||
| 120 | - | |||||||
| 121 | ctx->v0 = 0x736f6d6570736575ULL ^ k0; | - | ||||||
| 122 | ctx->v1 = 0x646f72616e646f6dULL ^ k1; | - | ||||||
| 123 | ctx->v2 = 0x6c7967656e657261ULL ^ k0; | - | ||||||
| 124 | ctx->v3 = 0x7465646279746573ULL ^ k1; | - | ||||||
| 125 | - | |||||||
| 126 | if (ctx->hash_size == SIPHASH_MAX_DIGEST_SIZE)
| 220-247 | ||||||
| 127 | ctx->v1 ^= 0xee; executed 247 times by 2 tests: ctx->v1 ^= 0xee;Executed by:
| 247 | ||||||
| 128 | - | |||||||
| 129 | return 1; executed 467 times by 2 tests: return 1;Executed by:
| 467 | ||||||
| 130 | } | - | ||||||
| 131 | - | |||||||
| 132 | void SipHash_Update(SIPHASH *ctx, const unsigned char *in, size_t inlen) | - | ||||||
| 133 | { | - | ||||||
| 134 | uint64_t m; | - | ||||||
| 135 | const uint8_t *end; | - | ||||||
| 136 | int left; | - | ||||||
| 137 | int i; | - | ||||||
| 138 | uint64_t v0 = ctx->v0; | - | ||||||
| 139 | uint64_t v1 = ctx->v1; | - | ||||||
| 140 | uint64_t v2 = ctx->v2; | - | ||||||
| 141 | uint64_t v3 = ctx->v3; | - | ||||||
| 142 | - | |||||||
| 143 | ctx->total_inlen += inlen; | - | ||||||
| 144 | - | |||||||
| 145 | if (ctx->len) {
| 150-624 | ||||||
| 146 | /* deal with leavings */ | - | ||||||
| 147 | size_t available = SIPHASH_BLOCK_SIZE - ctx->len; | - | ||||||
| 148 | - | |||||||
| 149 | /* not enough to fill leavings */ | - | ||||||
| 150 | if (inlen < available) {
| 0-150 | ||||||
| 151 | memcpy(&ctx->leavings[ctx->len], in, inlen); | - | ||||||
| 152 | ctx->len += inlen; | - | ||||||
| 153 | return; never executed: return; | 0 | ||||||
| 154 | } | - | ||||||
| 155 | - | |||||||
| 156 | /* copy data into leavings and reduce input */ | - | ||||||
| 157 | memcpy(&ctx->leavings[ctx->len], in, available); | - | ||||||
| 158 | inlen -= available; | - | ||||||
| 159 | in += available; | - | ||||||
| 160 | - | |||||||
| 161 | /* process leavings */ | - | ||||||
| 162 | m = U8TO64_LE(ctx->leavings); | - | ||||||
| 163 | v3 ^= m; | - | ||||||
| 164 | for (i = 0; i < ctx->crounds; ++i)
| 150-300 | ||||||
| 165 | SIPROUND; executed 300 times by 1 test: end of blockExecuted by:
| 300 | ||||||
| 166 | v0 ^= m; | - | ||||||
| 167 | } executed 150 times by 1 test: end of blockExecuted by:
| 150 | ||||||
| 168 | left = inlen & (SIPHASH_BLOCK_SIZE-1); /* gets put into leavings */ | - | ||||||
| 169 | end = in + inlen - left; | - | ||||||
| 170 | - | |||||||
| 171 | for (; in != end; in += 8) {
| 774-2000 | ||||||
| 172 | m = U8TO64_LE(in); | - | ||||||
| 173 | v3 ^= m; | - | ||||||
| 174 | for (i = 0; i < ctx->crounds; ++i)
| 2000-4000 | ||||||
| 175 | SIPROUND; executed 4000 times by 2 tests: end of blockExecuted by:
| 4000 | ||||||
| 176 | v0 ^= m; | - | ||||||
| 177 | } executed 2000 times by 2 tests: end of blockExecuted by:
| 2000 | ||||||
| 178 | - | |||||||
| 179 | /* save leavings and other ctx */ | - | ||||||
| 180 | if (left)
| 210-564 | ||||||
| 181 | memcpy(ctx->leavings, end, left); executed 564 times by 2 tests: memcpy(ctx->leavings, end, left);Executed by:
| 564 | ||||||
| 182 | ctx->len = left; | - | ||||||
| 183 | - | |||||||
| 184 | ctx->v0 = v0; | - | ||||||
| 185 | ctx->v1 = v1; | - | ||||||
| 186 | ctx->v2 = v2; | - | ||||||
| 187 | ctx->v3 = v3; | - | ||||||
| 188 | } executed 774 times by 2 tests: end of blockExecuted by:
| 774 | ||||||
| 189 | - | |||||||
| 190 | int SipHash_Final(SIPHASH *ctx, unsigned char *out, size_t outlen) | - | ||||||
| 191 | { | - | ||||||
| 192 | /* finalize hash */ | - | ||||||
| 193 | int i; | - | ||||||
| 194 | uint64_t b = ctx->total_inlen << 56; | - | ||||||
| 195 | uint64_t v0 = ctx->v0; | - | ||||||
| 196 | uint64_t v1 = ctx->v1; | - | ||||||
| 197 | uint64_t v2 = ctx->v2; | - | ||||||
| 198 | uint64_t v3 = ctx->v3; | - | ||||||
| 199 | - | |||||||
| 200 | if (outlen != (size_t)ctx->hash_size)
| 3-467 | ||||||
| 201 | return 0; executed 3 times by 1 test: return 0;Executed by:
| 3 | ||||||
| 202 | - | |||||||
| 203 | switch (ctx->len) { | - | ||||||
| 204 | case 7: executed 64 times by 2 tests: case 7:Executed by:
| 64 | ||||||
| 205 | b |= ((uint64_t)ctx->leavings[6]) << 48; | - | ||||||
| 206 | /* fall thru */ | - | ||||||
| 207 | case 6: code before this statement executed 64 times by 2 tests: case 6:Executed by:
executed 58 times by 2 tests: case 6:Executed by:
| 58-64 | ||||||
| 208 | b |= ((uint64_t)ctx->leavings[5]) << 40; | - | ||||||
| 209 | /* fall thru */ | - | ||||||
| 210 | case 5: code before this statement executed 122 times by 2 tests: case 5:Executed by:
executed 58 times by 2 tests: case 5:Executed by:
| 58-122 | ||||||
| 211 | b |= ((uint64_t)ctx->leavings[4]) << 32; | - | ||||||
| 212 | /* fall thru */ | - | ||||||
| 213 | case 4: code before this statement executed 180 times by 2 tests: case 4:Executed by:
executed 58 times by 2 tests: case 4:Executed by:
| 58-180 | ||||||
| 214 | b |= ((uint64_t)ctx->leavings[3]) << 24; | - | ||||||
| 215 | /* fall thru */ | - | ||||||
| 216 | case 3: code before this statement executed 238 times by 2 tests: case 3:Executed by:
executed 58 times by 2 tests: case 3:Executed by:
| 58-238 | ||||||
| 217 | b |= ((uint64_t)ctx->leavings[2]) << 16; | - | ||||||
| 218 | /* fall thru */ | - | ||||||
| 219 | case 2: code before this statement executed 296 times by 2 tests: case 2:Executed by:
executed 58 times by 2 tests: case 2:Executed by:
| 58-296 | ||||||
| 220 | b |= ((uint64_t)ctx->leavings[1]) << 8; | - | ||||||
| 221 | /* fall thru */ | - | ||||||
| 222 | case 1: code before this statement executed 354 times by 2 tests: case 1:Executed by:
executed 60 times by 2 tests: case 1:Executed by:
| 60-354 | ||||||
| 223 | b |= ((uint64_t)ctx->leavings[0]); | - | ||||||
| 224 | case 0: code before this statement executed 414 times by 2 tests: case 0:Executed by:
executed 467 times by 2 tests: case 0:Executed by:
| 414-467 | ||||||
| 225 | break; executed 467 times by 2 tests: break;Executed by:
| 467 | ||||||
| 226 | } | - | ||||||
| 227 | - | |||||||
| 228 | v3 ^= b; | - | ||||||
| 229 | for (i = 0; i < ctx->crounds; ++i)
| 467-934 | ||||||
| 230 | SIPROUND; executed 934 times by 2 tests: end of blockExecuted by:
| 934 | ||||||
| 231 | v0 ^= b; | - | ||||||
| 232 | if (ctx->hash_size == SIPHASH_MAX_DIGEST_SIZE)
| 221-246 | ||||||
| 233 | v2 ^= 0xee; executed 246 times by 2 tests: v2 ^= 0xee;Executed by:
| 246 | ||||||
| 234 | else | - | ||||||
| 235 | v2 ^= 0xff; executed 221 times by 2 tests: v2 ^= 0xff;Executed by:
| 221 | ||||||
| 236 | for (i = 0; i < ctx->drounds; ++i)
| 467-1868 | ||||||
| 237 | SIPROUND; executed 1868 times by 2 tests: end of blockExecuted by:
| 1868 | ||||||
| 238 | b = v0 ^ v1 ^ v2 ^ v3; | - | ||||||
| 239 | U64TO8_LE(out, b); | - | ||||||
| 240 | if (ctx->hash_size == SIPHASH_MIN_DIGEST_SIZE)
| 221-246 | ||||||
| 241 | return 1; executed 221 times by 2 tests: return 1;Executed by:
| 221 | ||||||
| 242 | v1 ^= 0xdd; | - | ||||||
| 243 | for (i = 0; i < ctx->drounds; ++i)
| 246-984 | ||||||
| 244 | SIPROUND; executed 984 times by 2 tests: end of blockExecuted by:
| 984 | ||||||
| 245 | b = v0 ^ v1 ^ v2 ^ v3; | - | ||||||
| 246 | U64TO8_LE(out + 8, b); | - | ||||||
| 247 | return 1; executed 246 times by 2 tests: return 1;Executed by:
| 246 | ||||||
| 248 | } | - | ||||||
| Source code | Switch to Preprocessed file |