diff options
| author | jsing <> | 2023-05-27 09:18:17 +0000 |
|---|---|---|
| committer | jsing <> | 2023-05-27 09:18:17 +0000 |
| commit | fce75c36c6fda1fa1488c600abe6490c27e90d75 (patch) | |
| tree | a08cff9b4e35549320f4459a98e3dfc282dbdb90 | |
| parent | 79242671d4fc62c0520403a6875e4c4254611365 (diff) | |
| download | openbsd-fce75c36c6fda1fa1488c600abe6490c27e90d75.tar.gz openbsd-fce75c36c6fda1fa1488c600abe6490c27e90d75.tar.bz2 openbsd-fce75c36c6fda1fa1488c600abe6490c27e90d75.zip | |
Clean up alignment handling for SHA-512.
This recommits r1.37 of sha512.c, however uses uint8_t * instead of void *
for the crypto_load_* functions and primarily uses const uint8_t * to track
input, only casting to const SHA_LONG64 * once we know that it is suitably
aligned. This prevents the compiler from implying alignment based on type.
Tested by tb@ and deraadt@ on platforms with gcc and strict alignment.
ok tb@
Diffstat (limited to '')
| -rw-r--r-- | src/lib/libcrypto/crypto_internal.h | 51 | ||||
| -rw-r--r-- | src/lib/libcrypto/sha/sha512.c | 125 |
2 files changed, 96 insertions, 80 deletions
diff --git a/src/lib/libcrypto/crypto_internal.h b/src/lib/libcrypto/crypto_internal.h index db3e99510b..4fe868e9a1 100644 --- a/src/lib/libcrypto/crypto_internal.h +++ b/src/lib/libcrypto/crypto_internal.h | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: crypto_internal.h,v 1.5 2023/05/19 00:54:27 deraadt Exp $ */ | 1 | /* $OpenBSD: crypto_internal.h,v 1.6 2023/05/27 09:18:17 jsing Exp $ */ |
| 2 | /* | 2 | /* |
| 3 | * Copyright (c) 2023 Joel Sing <jsing@openbsd.org> | 3 | * Copyright (c) 2023 Joel Sing <jsing@openbsd.org> |
| 4 | * | 4 | * |
| @@ -22,10 +22,30 @@ | |||
| 22 | #ifndef HEADER_CRYPTO_INTERNAL_H | 22 | #ifndef HEADER_CRYPTO_INTERNAL_H |
| 23 | #define HEADER_CRYPTO_INTERNAL_H | 23 | #define HEADER_CRYPTO_INTERNAL_H |
| 24 | 24 | ||
| 25 | #define CTASSERT(x) \ | ||
| 26 | extern char _ctassert[(x) ? 1 : -1] __attribute__((__unused__)) | ||
| 27 | |||
| 28 | /* | ||
| 29 | * crypto_load_be32toh() loads a 32 bit unsigned big endian value as a 32 bit | ||
| 30 | * unsigned host endian value, from the specified address in memory. The memory | ||
| 31 | * address may have any alignment. | ||
| 32 | */ | ||
| 33 | #ifndef HAVE_CRYPTO_LOAD_BE32TOH | ||
| 34 | static inline uint32_t | ||
| 35 | crypto_load_be32toh(const uint8_t *src) | ||
| 36 | { | ||
| 37 | uint32_t v; | ||
| 38 | |||
| 39 | memcpy(&v, src, sizeof(v)); | ||
| 40 | |||
| 41 | return be32toh(v); | ||
| 42 | } | ||
| 43 | #endif | ||
| 44 | |||
| 25 | /* | 45 | /* |
| 26 | * crypto_store_htobe32() stores a 32 bit unsigned host endian value | 46 | * crypto_store_htobe32() stores a 32 bit unsigned host endian value as a 32 bit |
| 27 | * as a 32 bit unsigned big endian value, at the specified location in | 47 | * unsigned big endian value, at the specified address in memory. The memory |
| 28 | * memory. The memory location may have any alignment. | 48 | * address may have any alignment. |
| 29 | */ | 49 | */ |
| 30 | #ifndef HAVE_CRYPTO_STORE_HTOBE32 | 50 | #ifndef HAVE_CRYPTO_STORE_HTOBE32 |
| 31 | static inline void | 51 | static inline void |
| @@ -37,9 +57,26 @@ crypto_store_htobe32(uint8_t *dst, uint32_t v) | |||
| 37 | #endif | 57 | #endif |
| 38 | 58 | ||
| 39 | /* | 59 | /* |
| 40 | * crypto_store_htobe64() stores a 64 bit unsigned host endian value | 60 | * crypto_load_be64toh() loads a 64 bit unsigned big endian value as a 64 bit |
| 41 | * as a 64 bit unsigned big endian value, at the specified location in | 61 | * unsigned host endian value, from the specified address in memory. The memory |
| 42 | * memory. The memory location may have any alignment. | 62 | * address may have any alignment. |
| 63 | */ | ||
| 64 | #ifndef HAVE_CRYPTO_LOAD_BE64TOH | ||
| 65 | static inline uint64_t | ||
| 66 | crypto_load_be64toh(const uint8_t *src) | ||
| 67 | { | ||
| 68 | uint64_t v; | ||
| 69 | |||
| 70 | memcpy(&v, src, sizeof(v)); | ||
| 71 | |||
| 72 | return be64toh(v); | ||
| 73 | } | ||
| 74 | #endif | ||
| 75 | |||
| 76 | /* | ||
| 77 | * crypto_store_htobe64() stores a 64 bit unsigned host endian value as a 64 bit | ||
| 78 | * unsigned big endian value, at the specified address in memory. The memory | ||
| 79 | * address may have any alignment. | ||
| 43 | */ | 80 | */ |
| 44 | #ifndef HAVE_CRYPTO_STORE_HTOBE64 | 81 | #ifndef HAVE_CRYPTO_STORE_HTOBE64 |
| 45 | static inline void | 82 | static inline void |
diff --git a/src/lib/libcrypto/sha/sha512.c b/src/lib/libcrypto/sha/sha512.c index 94e55a3d2a..0bc6039326 100644 --- a/src/lib/libcrypto/sha/sha512.c +++ b/src/lib/libcrypto/sha/sha512.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: sha512.c,v 1.38 2023/05/19 00:54:28 deraadt Exp $ */ | 1 | /* $OpenBSD: sha512.c,v 1.39 2023/05/27 09:18:17 jsing Exp $ */ |
| 2 | /* ==================================================================== | 2 | /* ==================================================================== |
| 3 | * Copyright (c) 1998-2011 The OpenSSL Project. All rights reserved. | 3 | * Copyright (c) 1998-2011 The OpenSSL Project. All rights reserved. |
| 4 | * | 4 | * |
| @@ -66,9 +66,8 @@ | |||
| 66 | 66 | ||
| 67 | #if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA512) | 67 | #if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA512) |
| 68 | 68 | ||
| 69 | #if !defined(__STRICT_ALIGNMENT) || defined(SHA512_ASM) | 69 | /* Ensure that SHA_LONG64 is 64 bits. */ |
| 70 | #define SHA512_BLOCK_CAN_MANAGE_UNALIGNED_DATA | 70 | CTASSERT(sizeof(SHA_LONG64) == sizeof(uint64_t)); |
| 71 | #endif | ||
| 72 | 71 | ||
| 73 | #ifdef SHA512_ASM | 72 | #ifdef SHA512_ASM |
| 74 | void sha512_block_data_order(SHA512_CTX *ctx, const void *in, size_t num); | 73 | void sha512_block_data_order(SHA512_CTX *ctx, const void *in, size_t num); |
| @@ -118,31 +117,6 @@ static const SHA_LONG64 K512[80] = { | |||
| 118 | U64(0x5fcb6fab3ad6faec), U64(0x6c44198c4a475817), | 117 | U64(0x5fcb6fab3ad6faec), U64(0x6c44198c4a475817), |
| 119 | }; | 118 | }; |
| 120 | 119 | ||
| 121 | #if defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) | ||
| 122 | # if defined(__x86_64) || defined(__x86_64__) | ||
| 123 | # define PULL64(x) ({ SHA_LONG64 ret=*((const SHA_LONG64 *)(&(x))); \ | ||
| 124 | asm ("bswapq %0" \ | ||
| 125 | : "=r"(ret) \ | ||
| 126 | : "0"(ret)); ret; }) | ||
| 127 | # elif (defined(__i386) || defined(__i386__)) | ||
| 128 | # define PULL64(x) ({ const unsigned int *p=(const unsigned int *)(&(x));\ | ||
| 129 | unsigned int hi=p[0],lo=p[1]; \ | ||
| 130 | asm ("bswapl %0; bswapl %1;" \ | ||
| 131 | : "=r"(lo),"=r"(hi) \ | ||
| 132 | : "0"(lo),"1"(hi)); \ | ||
| 133 | ((SHA_LONG64)hi)<<32|lo; }) | ||
| 134 | # endif | ||
| 135 | #endif | ||
| 136 | |||
| 137 | #ifndef PULL64 | ||
| 138 | #if BYTE_ORDER == BIG_ENDIAN | ||
| 139 | #define PULL64(x) (x) | ||
| 140 | #else | ||
| 141 | #define B(x, j) (((SHA_LONG64)(*(((const unsigned char *)(&x))+j)))<<((7-j)*8)) | ||
| 142 | #define PULL64(x) (B(x,0)|B(x,1)|B(x,2)|B(x,3)|B(x,4)|B(x,5)|B(x,6)|B(x,7)) | ||
| 143 | #endif | ||
| 144 | #endif | ||
| 145 | |||
| 146 | #define ROTR(x, s) crypto_ror_u64(x, s) | 120 | #define ROTR(x, s) crypto_ror_u64(x, s) |
| 147 | 121 | ||
| 148 | #define Sigma0(x) (ROTR((x),28) ^ ROTR((x),34) ^ ROTR((x),39)) | 122 | #define Sigma0(x) (ROTR((x),28) ^ ROTR((x),34) ^ ROTR((x),39)) |
| @@ -170,7 +144,8 @@ static const SHA_LONG64 K512[80] = { | |||
| 170 | static void | 144 | static void |
| 171 | sha512_block_data_order(SHA512_CTX *ctx, const void *_in, size_t num) | 145 | sha512_block_data_order(SHA512_CTX *ctx, const void *_in, size_t num) |
| 172 | { | 146 | { |
| 173 | const SHA_LONG64 *in = _in; | 147 | const uint8_t *in = _in; |
| 148 | const SHA_LONG64 *in64; | ||
| 174 | SHA_LONG64 a, b, c, d, e, f, g, h, s0, s1, T1, T2; | 149 | SHA_LONG64 a, b, c, d, e, f, g, h, s0, s1, T1, T2; |
| 175 | SHA_LONG64 X[16]; | 150 | SHA_LONG64 X[16]; |
| 176 | int i; | 151 | int i; |
| @@ -185,37 +160,61 @@ sha512_block_data_order(SHA512_CTX *ctx, const void *_in, size_t num) | |||
| 185 | g = ctx->h[6]; | 160 | g = ctx->h[6]; |
| 186 | h = ctx->h[7]; | 161 | h = ctx->h[7]; |
| 187 | 162 | ||
| 188 | X[0] = PULL64(in[0]); | 163 | if ((size_t)in % sizeof(SHA_LONG64) == 0) { |
| 164 | /* Input is 64 bit aligned. */ | ||
| 165 | in64 = (const SHA_LONG64 *)in; | ||
| 166 | X[0] = be64toh(in64[0]); | ||
| 167 | X[1] = be64toh(in64[1]); | ||
| 168 | X[2] = be64toh(in64[2]); | ||
| 169 | X[3] = be64toh(in64[3]); | ||
| 170 | X[4] = be64toh(in64[4]); | ||
| 171 | X[5] = be64toh(in64[5]); | ||
| 172 | X[6] = be64toh(in64[6]); | ||
| 173 | X[7] = be64toh(in64[7]); | ||
| 174 | X[8] = be64toh(in64[8]); | ||
| 175 | X[9] = be64toh(in64[9]); | ||
| 176 | X[10] = be64toh(in64[10]); | ||
| 177 | X[11] = be64toh(in64[11]); | ||
| 178 | X[12] = be64toh(in64[12]); | ||
| 179 | X[13] = be64toh(in64[13]); | ||
| 180 | X[14] = be64toh(in64[14]); | ||
| 181 | X[15] = be64toh(in64[15]); | ||
| 182 | } else { | ||
| 183 | /* Input is not 64 bit aligned. */ | ||
| 184 | X[0] = crypto_load_be64toh(&in[0 * 8]); | ||
| 185 | X[1] = crypto_load_be64toh(&in[1 * 8]); | ||
| 186 | X[2] = crypto_load_be64toh(&in[2 * 8]); | ||
| 187 | X[3] = crypto_load_be64toh(&in[3 * 8]); | ||
| 188 | X[4] = crypto_load_be64toh(&in[4 * 8]); | ||
| 189 | X[5] = crypto_load_be64toh(&in[5 * 8]); | ||
| 190 | X[6] = crypto_load_be64toh(&in[6 * 8]); | ||
| 191 | X[7] = crypto_load_be64toh(&in[7 * 8]); | ||
| 192 | X[8] = crypto_load_be64toh(&in[8 * 8]); | ||
| 193 | X[9] = crypto_load_be64toh(&in[9 * 8]); | ||
| 194 | X[10] = crypto_load_be64toh(&in[10 * 8]); | ||
| 195 | X[11] = crypto_load_be64toh(&in[11 * 8]); | ||
| 196 | X[12] = crypto_load_be64toh(&in[12 * 8]); | ||
| 197 | X[13] = crypto_load_be64toh(&in[13 * 8]); | ||
| 198 | X[14] = crypto_load_be64toh(&in[14 * 8]); | ||
| 199 | X[15] = crypto_load_be64toh(&in[15 * 8]); | ||
| 200 | } | ||
| 201 | in += SHA512_CBLOCK; | ||
| 202 | |||
| 189 | ROUND_00_15(0, a, b, c, d, e, f, g, h, X[0]); | 203 | ROUND_00_15(0, a, b, c, d, e, f, g, h, X[0]); |
| 190 | X[1] = PULL64(in[1]); | ||
| 191 | ROUND_00_15(1, h, a, b, c, d, e, f, g, X[1]); | 204 | ROUND_00_15(1, h, a, b, c, d, e, f, g, X[1]); |
| 192 | X[2] = PULL64(in[2]); | ||
| 193 | ROUND_00_15(2, g, h, a, b, c, d, e, f, X[2]); | 205 | ROUND_00_15(2, g, h, a, b, c, d, e, f, X[2]); |
| 194 | X[3] = PULL64(in[3]); | ||
| 195 | ROUND_00_15(3, f, g, h, a, b, c, d, e, X[3]); | 206 | ROUND_00_15(3, f, g, h, a, b, c, d, e, X[3]); |
| 196 | X[4] = PULL64(in[4]); | ||
| 197 | ROUND_00_15(4, e, f, g, h, a, b, c, d, X[4]); | 207 | ROUND_00_15(4, e, f, g, h, a, b, c, d, X[4]); |
| 198 | X[5] = PULL64(in[5]); | ||
| 199 | ROUND_00_15(5, d, e, f, g, h, a, b, c, X[5]); | 208 | ROUND_00_15(5, d, e, f, g, h, a, b, c, X[5]); |
| 200 | X[6] = PULL64(in[6]); | ||
| 201 | ROUND_00_15(6, c, d, e, f, g, h, a, b, X[6]); | 209 | ROUND_00_15(6, c, d, e, f, g, h, a, b, X[6]); |
| 202 | X[7] = PULL64(in[7]); | ||
| 203 | ROUND_00_15(7, b, c, d, e, f, g, h, a, X[7]); | 210 | ROUND_00_15(7, b, c, d, e, f, g, h, a, X[7]); |
| 204 | X[8] = PULL64(in[8]); | ||
| 205 | ROUND_00_15(8, a, b, c, d, e, f, g, h, X[8]); | 211 | ROUND_00_15(8, a, b, c, d, e, f, g, h, X[8]); |
| 206 | X[9] = PULL64(in[9]); | ||
| 207 | ROUND_00_15(9, h, a, b, c, d, e, f, g, X[9]); | 212 | ROUND_00_15(9, h, a, b, c, d, e, f, g, X[9]); |
| 208 | X[10] = PULL64(in[10]); | ||
| 209 | ROUND_00_15(10, g, h, a, b, c, d, e, f, X[10]); | 213 | ROUND_00_15(10, g, h, a, b, c, d, e, f, X[10]); |
| 210 | X[11] = PULL64(in[11]); | ||
| 211 | ROUND_00_15(11, f, g, h, a, b, c, d, e, X[11]); | 214 | ROUND_00_15(11, f, g, h, a, b, c, d, e, X[11]); |
| 212 | X[12] = PULL64(in[12]); | ||
| 213 | ROUND_00_15(12, e, f, g, h, a, b, c, d, X[12]); | 215 | ROUND_00_15(12, e, f, g, h, a, b, c, d, X[12]); |
| 214 | X[13] = PULL64(in[13]); | ||
| 215 | ROUND_00_15(13, d, e, f, g, h, a, b, c, X[13]); | 216 | ROUND_00_15(13, d, e, f, g, h, a, b, c, X[13]); |
| 216 | X[14] = PULL64(in[14]); | ||
| 217 | ROUND_00_15(14, c, d, e, f, g, h, a, b, X[14]); | 217 | ROUND_00_15(14, c, d, e, f, g, h, a, b, X[14]); |
| 218 | X[15] = PULL64(in[15]); | ||
| 219 | ROUND_00_15(15, b, c, d, e, f, g, h, a, X[15]); | 218 | ROUND_00_15(15, b, c, d, e, f, g, h, a, X[15]); |
| 220 | 219 | ||
| 221 | for (i = 16; i < 80; i += 16) { | 220 | for (i = 16; i < 80; i += 16) { |
| @@ -245,8 +244,6 @@ sha512_block_data_order(SHA512_CTX *ctx, const void *_in, size_t num) | |||
| 245 | ctx->h[5] += f; | 244 | ctx->h[5] += f; |
| 246 | ctx->h[6] += g; | 245 | ctx->h[6] += g; |
| 247 | ctx->h[7] += h; | 246 | ctx->h[7] += h; |
| 248 | |||
| 249 | in += SHA_LBLOCK; | ||
| 250 | } | 247 | } |
| 251 | } | 248 | } |
| 252 | 249 | ||
| @@ -323,21 +320,15 @@ SHA512_Init(SHA512_CTX *c) | |||
| 323 | void | 320 | void |
| 324 | SHA512_Transform(SHA512_CTX *c, const unsigned char *data) | 321 | SHA512_Transform(SHA512_CTX *c, const unsigned char *data) |
| 325 | { | 322 | { |
| 326 | #ifndef SHA512_BLOCK_CAN_MANAGE_UNALIGNED_DATA | ||
| 327 | if ((size_t)data % sizeof(c->u.d[0]) != 0) { | ||
| 328 | memcpy(c->u.p, data, sizeof(c->u.p)); | ||
| 329 | data = c->u.p; | ||
| 330 | } | ||
| 331 | #endif | ||
| 332 | sha512_block_data_order(c, data, 1); | 323 | sha512_block_data_order(c, data, 1); |
| 333 | } | 324 | } |
| 334 | 325 | ||
| 335 | int | 326 | int |
| 336 | SHA512_Update(SHA512_CTX *c, const void *_data, size_t len) | 327 | SHA512_Update(SHA512_CTX *c, const void *_data, size_t len) |
| 337 | { | 328 | { |
| 338 | SHA_LONG64 l; | 329 | const unsigned char *data = _data; |
| 339 | unsigned char *p = c->u.p; | 330 | unsigned char *p = c->u.p; |
| 340 | const unsigned char *data = (const unsigned char *)_data; | 331 | SHA_LONG64 l; |
| 341 | 332 | ||
| 342 | if (len == 0) | 333 | if (len == 0) |
| 343 | return 1; | 334 | return 1; |
| @@ -366,22 +357,10 @@ SHA512_Update(SHA512_CTX *c, const void *_data, size_t len) | |||
| 366 | } | 357 | } |
| 367 | 358 | ||
| 368 | if (len >= sizeof(c->u)) { | 359 | if (len >= sizeof(c->u)) { |
| 369 | #ifndef SHA512_BLOCK_CAN_MANAGE_UNALIGNED_DATA | 360 | sha512_block_data_order(c, data, len/sizeof(c->u)); |
| 370 | if ((size_t)data % sizeof(c->u.d[0]) != 0) { | 361 | data += len; |
| 371 | while (len >= sizeof(c->u)) { | 362 | len %= sizeof(c->u); |
| 372 | memcpy(p, data, sizeof(c->u)); | 363 | data -= len; |
| 373 | sha512_block_data_order(c, p, 1); | ||
| 374 | len -= sizeof(c->u); | ||
| 375 | data += sizeof(c->u); | ||
| 376 | } | ||
| 377 | } else | ||
| 378 | #endif | ||
| 379 | { | ||
| 380 | sha512_block_data_order(c, data, len/sizeof(c->u)); | ||
| 381 | data += len; | ||
| 382 | len %= sizeof(c->u); | ||
| 383 | data -= len; | ||
| 384 | } | ||
| 385 | } | 364 | } |
| 386 | 365 | ||
| 387 | if (len != 0) { | 366 | if (len != 0) { |
