forked from open-mpi/ompi
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add sha256 generation func to opal util toolbox
Looks like there may be at least one place in ompi where being able to compute a sha of a user supplied string plus internally generated data could be useful, so add function to do this to the opal util toolbox. Related to open-mpi#10895 This code is derived from a sha256 implementation at https://github.com/B-Con/crypto-algorithms.git Signed-off-by: Howard Pritchard <[email protected]>
- Loading branch information
Showing
6 changed files
with
305 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,170 @@ | ||
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */ | ||
/* | ||
* Copyright (c) 2022 Triad National Security, LLC. All rights | ||
* reserved. | ||
* | ||
* Additional copyrights may follow | ||
* | ||
* $HEADER$ | ||
*/ | ||
|
||
|
||
/********************************************************************* | ||
* Filename: sha256.c | ||
* Author: Brad Conte (brad AT bradconte.com) | ||
* Copyright: | ||
* Disclaimer: This code is presented "as is" without any guarantees. | ||
* Details: Implementation of the SHA-256 hashing algorithm. | ||
SHA-256 is one of the three algorithms in the SHA2 | ||
specification. The others, SHA-384 and SHA-512, are not | ||
offered in this implementation. | ||
Algorithm specification can be found here: | ||
* http://csrc.nist.gov/publications/fips/fips180-2/fips180-2withchangenotice.pdf | ||
This implementation uses little endian byte order. | ||
See https://github.com/B-Con/crypto-algorithms | ||
*********************************************************************/ | ||
|
||
/*************************** HEADER FILES ***************************/ | ||
#include <stdlib.h> | ||
#include <memory.h> | ||
#include "sha256.h" | ||
|
||
/****************************** MACROS ******************************/ | ||
#define ROTLEFT(a,b) (((a) << (b)) | ((a) >> (32-(b)))) | ||
#define ROTRIGHT(a,b) (((a) >> (b)) | ((a) << (32-(b)))) | ||
|
||
#define CH(x,y,z) (((x) & (y)) ^ (~(x) & (z))) | ||
#define MAJ(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) | ||
#define EP0(x) (ROTRIGHT(x,2) ^ ROTRIGHT(x,13) ^ ROTRIGHT(x,22)) | ||
#define EP1(x) (ROTRIGHT(x,6) ^ ROTRIGHT(x,11) ^ ROTRIGHT(x,25)) | ||
#define SIG0(x) (ROTRIGHT(x,7) ^ ROTRIGHT(x,18) ^ ((x) >> 3)) | ||
#define SIG1(x) (ROTRIGHT(x,17) ^ ROTRIGHT(x,19) ^ ((x) >> 10)) | ||
|
||
/**************************** VARIABLES *****************************/ | ||
static const WORD k[64] = { | ||
0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5,0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5, | ||
0xd807aa98,0x12835b01,0x243185be,0x550c7dc3,0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174, | ||
0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc,0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da, | ||
0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7,0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967, | ||
0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13,0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85, | ||
0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3,0xd192e819,0xd6990624,0xf40e3585,0x106aa070, | ||
0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5,0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3, | ||
0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208,0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2 | ||
}; | ||
|
||
/*********************** FUNCTION DEFINITIONS ***********************/ | ||
static void sha256_transform(opal_sha256_ctx *ctx, const BYTE data[]) | ||
{ | ||
WORD a, b, c, d, e, f, g, h, i, j, t1, t2, m[64]; | ||
|
||
for (i = 0, j = 0; i < 16; ++i, j += 4) | ||
m[i] = (data[j] << 24) | (data[j + 1] << 16) | (data[j + 2] << 8) | (data[j + 3]); | ||
for ( ; i < 64; ++i) | ||
m[i] = SIG1(m[i - 2]) + m[i - 7] + SIG0(m[i - 15]) + m[i - 16]; | ||
|
||
a = ctx->state[0]; | ||
b = ctx->state[1]; | ||
c = ctx->state[2]; | ||
d = ctx->state[3]; | ||
e = ctx->state[4]; | ||
f = ctx->state[5]; | ||
g = ctx->state[6]; | ||
h = ctx->state[7]; | ||
|
||
for (i = 0; i < 64; ++i) { | ||
t1 = h + EP1(e) + CH(e,f,g) + k[i] + m[i]; | ||
t2 = EP0(a) + MAJ(a,b,c); | ||
h = g; | ||
g = f; | ||
f = e; | ||
e = d + t1; | ||
d = c; | ||
c = b; | ||
b = a; | ||
a = t1 + t2; | ||
} | ||
|
||
ctx->state[0] += a; | ||
ctx->state[1] += b; | ||
ctx->state[2] += c; | ||
ctx->state[3] += d; | ||
ctx->state[4] += e; | ||
ctx->state[5] += f; | ||
ctx->state[6] += g; | ||
ctx->state[7] += h; | ||
} | ||
|
||
void opal_sha256_init(opal_sha256_ctx *ctx) | ||
{ | ||
ctx->datalen = 0; | ||
ctx->bitlen = 0; | ||
ctx->state[0] = 0x6a09e667; | ||
ctx->state[1] = 0xbb67ae85; | ||
ctx->state[2] = 0x3c6ef372; | ||
ctx->state[3] = 0xa54ff53a; | ||
ctx->state[4] = 0x510e527f; | ||
ctx->state[5] = 0x9b05688c; | ||
ctx->state[6] = 0x1f83d9ab; | ||
ctx->state[7] = 0x5be0cd19; | ||
} | ||
|
||
void opal_sha256_update(opal_sha256_ctx *ctx, const BYTE data[], size_t len) | ||
{ | ||
WORD i; | ||
|
||
for (i = 0; i < len; ++i) { | ||
ctx->data[ctx->datalen] = data[i]; | ||
ctx->datalen++; | ||
if (ctx->datalen == 64) { | ||
sha256_transform(ctx, ctx->data); | ||
ctx->bitlen += 512; | ||
ctx->datalen = 0; | ||
} | ||
} | ||
} | ||
|
||
void opal_sha256_final(opal_sha256_ctx *ctx, BYTE hash[]) | ||
{ | ||
WORD i; | ||
|
||
i = ctx->datalen; | ||
|
||
// Pad whatever data is left in the buffer. | ||
if (ctx->datalen < 56) { | ||
ctx->data[i++] = 0x80; | ||
while (i < 56) | ||
ctx->data[i++] = 0x00; | ||
} | ||
else { | ||
ctx->data[i++] = 0x80; | ||
while (i < 64) | ||
ctx->data[i++] = 0x00; | ||
sha256_transform(ctx, ctx->data); | ||
memset(ctx->data, 0, 56); | ||
} | ||
|
||
// Append to the padding the total message's length in bits and transform. | ||
ctx->bitlen += ctx->datalen * 8; | ||
ctx->data[63] = ctx->bitlen; | ||
ctx->data[62] = ctx->bitlen >> 8; | ||
ctx->data[61] = ctx->bitlen >> 16; | ||
ctx->data[60] = ctx->bitlen >> 24; | ||
ctx->data[59] = ctx->bitlen >> 32; | ||
ctx->data[58] = ctx->bitlen >> 40; | ||
ctx->data[57] = ctx->bitlen >> 48; | ||
ctx->data[56] = ctx->bitlen >> 56; | ||
sha256_transform(ctx, ctx->data); | ||
|
||
// Since this implementation uses little endian byte ordering and SHA uses big endian, | ||
// reverse all the bytes when copying the final state to the output hash. | ||
for (i = 0; i < 4; ++i) { | ||
hash[i] = (ctx->state[0] >> (24 - i * 8)) & 0x000000ff; | ||
hash[i + 4] = (ctx->state[1] >> (24 - i * 8)) & 0x000000ff; | ||
hash[i + 8] = (ctx->state[2] >> (24 - i * 8)) & 0x000000ff; | ||
hash[i + 12] = (ctx->state[3] >> (24 - i * 8)) & 0x000000ff; | ||
hash[i + 16] = (ctx->state[4] >> (24 - i * 8)) & 0x000000ff; | ||
hash[i + 20] = (ctx->state[5] >> (24 - i * 8)) & 0x000000ff; | ||
hash[i + 24] = (ctx->state[6] >> (24 - i * 8)) & 0x000000ff; | ||
hash[i + 28] = (ctx->state[7] >> (24 - i * 8)) & 0x000000ff; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */ | ||
/* | ||
* Copyright (c) 2022 Triad National Security, LLC. All rights | ||
* reserved. | ||
* | ||
* Additional copyrights may follow | ||
* | ||
* $HEADER$ | ||
*/ | ||
|
||
/********************************************************************* | ||
* Filename: sha256.h | ||
* Author: Brad Conte (brad AT bradconte.com) | ||
* Copyright: | ||
* Disclaimer: This code is presented "as is" without any guarantees. | ||
* Details: Defines the API for the corresponding SHA1 implementation. | ||
* Notes: see https://github.com/B-Con/crypto-algorithms | ||
*********************************************************************/ | ||
|
||
#ifndef OPAL_SHA256_H | ||
#define OPAL_SHA256_H | ||
|
||
/*************************** HEADER FILES ***************************/ | ||
#include <stddef.h> | ||
|
||
/****************************** MACROS ******************************/ | ||
#define OPAL_SHA256_BLOCK_SIZE 32 // SHA256 outputs a 32 byte digest | ||
|
||
/**************************** DATA TYPES ****************************/ | ||
typedef unsigned char BYTE; // 8-bit byte | ||
typedef unsigned int WORD; // 32-bit word, change to "long" for 16-bit machines | ||
|
||
typedef struct { | ||
BYTE data[64]; | ||
WORD datalen; | ||
unsigned long long bitlen; | ||
WORD state[8]; | ||
} opal_sha256_ctx; | ||
|
||
/*********************** FUNCTION DECLARATIONS **********************/ | ||
void opal_sha256_init(opal_sha256_ctx *ctx); | ||
void opal_sha256_update(opal_sha256_ctx *ctx, const BYTE data[], size_t len); | ||
void opal_sha256_final(opal_sha256_ctx *ctx, BYTE hash[]); | ||
|
||
#endif // OPAL_SHA256_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -39,7 +39,8 @@ AM_CPPFLAGS = -I$(top_srcdir)/test/support | |
check_PROGRAMS = \ | ||
opal_bit_ops \ | ||
opal_path_nfs \ | ||
bipartite_graph | ||
bipartite_graph \ | ||
opal_sha256 | ||
|
||
TESTS = \ | ||
$(check_PROGRAMS) | ||
|
@@ -128,6 +129,12 @@ bipartite_graph_LDADD = \ | |
$(top_builddir)/test/support/libsupport.a | ||
bipartite_graph_DEPENDENCIES = $(bipartite_graph_LDADD) | ||
|
||
opal_sha256_SOURCES = opal_sha256.c | ||
opal_sha256_LDADD = \ | ||
$(top_builddir)/opal/lib@[email protected] \ | ||
$(top_builddir)/test/support/libsupport.a | ||
opal_sha256_DEPENDENCIES = $(opal_sha256_LDADD) | ||
|
||
clean-local: | ||
rm -f test_session_dir_out test-file opal_path_nfs.out | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */ | ||
/* | ||
* Copyright (c) 2022 Triad National Security, LLC. All rights | ||
* reserved. | ||
* | ||
* Additional copyrights may follow | ||
* | ||
* $HEADER$ | ||
*/ | ||
|
||
/********************************************************************* | ||
* Filename: sha256.c | ||
* Author: Brad Conte (brad AT bradconte.com) | ||
* Copyright: | ||
* Disclaimer: This code is presented "as is" without any guarantees. | ||
* Details: Performs known-answer tests on the corresponding SHA1 | ||
implementation. These tests do not encompass the full | ||
range of available test vectors, however, if the tests | ||
pass it is very, very likely that the code is correct | ||
and was compiled properly. This code also serves as | ||
example usage of the functions. | ||
*********************************************************************/ | ||
|
||
/*************************** HEADER FILES ***************************/ | ||
#include <stdio.h> | ||
#include <memory.h> | ||
#include <string.h> | ||
#include "support.h" | ||
#include "opal/util/sha256.h" | ||
|
||
/*********************** FUNCTION DEFINITIONS ***********************/ | ||
static int sha256_test(void) | ||
{ | ||
BYTE text1[] = {"abc"}; | ||
BYTE text2[] = {"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"}; | ||
BYTE text3[] = {"aaaaaaaaaa"}; | ||
BYTE hash1[OPAL_SHA256_BLOCK_SIZE] = {0xba,0x78,0x16,0xbf,0x8f,0x01,0xcf,0xea,0x41,0x41,0x40,0xde,0x5d,0xae,0x22,0x23, | ||
0xb0,0x03,0x61,0xa3,0x96,0x17,0x7a,0x9c,0xb4,0x10,0xff,0x61,0xf2,0x00,0x15,0xad}; | ||
BYTE hash2[OPAL_SHA256_BLOCK_SIZE] = {0x24,0x8d,0x6a,0x61,0xd2,0x06,0x38,0xb8,0xe5,0xc0,0x26,0x93,0x0c,0x3e,0x60,0x39, | ||
0xa3,0x3c,0xe4,0x59,0x64,0xff,0x21,0x67,0xf6,0xec,0xed,0xd4,0x19,0xdb,0x06,0xc1}; | ||
BYTE hash3[OPAL_SHA256_BLOCK_SIZE] = {0xcd,0xc7,0x6e,0x5c,0x99,0x14,0xfb,0x92,0x81,0xa1,0xc7,0xe2,0x84,0xd7,0x3e,0x67, | ||
0xf1,0x80,0x9a,0x48,0xa4,0x97,0x20,0x0e,0x04,0x6d,0x39,0xcc,0xc7,0x11,0x2c,0xd0}; | ||
BYTE buf[OPAL_SHA256_BLOCK_SIZE]; | ||
opal_sha256_ctx ctx; | ||
int idx; | ||
int pass = 1; | ||
|
||
opal_sha256_init(&ctx); | ||
opal_sha256_update(&ctx, text1, strlen((const char *)text1)); | ||
opal_sha256_final(&ctx, buf); | ||
pass = pass && !memcmp(hash1, buf, OPAL_SHA256_BLOCK_SIZE); | ||
|
||
opal_sha256_init(&ctx); | ||
opal_sha256_update(&ctx, text2, strlen((const char *)text2)); | ||
opal_sha256_final(&ctx, buf); | ||
pass = pass && !memcmp(hash2, buf, OPAL_SHA256_BLOCK_SIZE); | ||
|
||
opal_sha256_init(&ctx); | ||
for (idx = 0; idx < 100000; ++idx) | ||
opal_sha256_update(&ctx, text3, strlen((const char *)text3)); | ||
opal_sha256_final(&ctx, buf); | ||
pass = pass && !memcmp(hash3, buf, OPAL_SHA256_BLOCK_SIZE); | ||
|
||
return pass; | ||
} | ||
|
||
int main(void) | ||
{ | ||
test_init("sha256 test"); | ||
|
||
if (sha256_test()) { | ||
test_success(); | ||
} else { | ||
test_failure("sh256 test failed"); | ||
} | ||
|
||
return test_finalize(); | ||
} |