Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Heapster bugfixes for sha512 example #1523

Merged
merged 11 commits into from
Nov 23, 2021
2 changes: 2 additions & 0 deletions heapster-saw/examples/_CoqProject
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,5 @@ clearbufs_gen.v
clearbufs_proofs.v
mbox_gen.v
mbox_proofs.v
#sha512_gen.v
#sha512_proofs.v
Binary file added heapster-saw/examples/sha512.bc
Binary file not shown.
288 changes: 288 additions & 0 deletions heapster-saw/examples/sha512.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,288 @@
#include <stdlib.h>
#include <stdint.h>
#include <string.h>

// First simplication of sha512_block_data_order

static inline uint64_t SIMPL1_CRYPTO_load_u64_be(const void *ptr) {
uint64_t ret;
memcpy(&ret, ptr, sizeof(ret));
return ret;
}

static const uint64_t SIMPL1_K512[80] = {
UINT64_C(0x428a2f98d728ae22), UINT64_C(0x7137449123ef65cd),
UINT64_C(0xb5c0fbcfec4d3b2f), UINT64_C(0xe9b5dba58189dbbc),
UINT64_C(0x3956c25bf348b538), UINT64_C(0x59f111f1b605d019),
UINT64_C(0x923f82a4af194f9b), UINT64_C(0xab1c5ed5da6d8118),
UINT64_C(0xd807aa98a3030242), UINT64_C(0x12835b0145706fbe),
UINT64_C(0x243185be4ee4b28c), UINT64_C(0x550c7dc3d5ffb4e2),
UINT64_C(0x72be5d74f27b896f), UINT64_C(0x80deb1fe3b1696b1),
UINT64_C(0x9bdc06a725c71235), UINT64_C(0xc19bf174cf692694),
UINT64_C(0xe49b69c19ef14ad2), UINT64_C(0xefbe4786384f25e3),
UINT64_C(0x0fc19dc68b8cd5b5), UINT64_C(0x240ca1cc77ac9c65),
UINT64_C(0x2de92c6f592b0275), UINT64_C(0x4a7484aa6ea6e483),
UINT64_C(0x5cb0a9dcbd41fbd4), UINT64_C(0x76f988da831153b5),
UINT64_C(0x983e5152ee66dfab), UINT64_C(0xa831c66d2db43210),
UINT64_C(0xb00327c898fb213f), UINT64_C(0xbf597fc7beef0ee4),
UINT64_C(0xc6e00bf33da88fc2), UINT64_C(0xd5a79147930aa725),
UINT64_C(0x06ca6351e003826f), UINT64_C(0x142929670a0e6e70),
UINT64_C(0x27b70a8546d22ffc), UINT64_C(0x2e1b21385c26c926),
UINT64_C(0x4d2c6dfc5ac42aed), UINT64_C(0x53380d139d95b3df),
UINT64_C(0x650a73548baf63de), UINT64_C(0x766a0abb3c77b2a8),
UINT64_C(0x81c2c92e47edaee6), UINT64_C(0x92722c851482353b),
UINT64_C(0xa2bfe8a14cf10364), UINT64_C(0xa81a664bbc423001),
UINT64_C(0xc24b8b70d0f89791), UINT64_C(0xc76c51a30654be30),
UINT64_C(0xd192e819d6ef5218), UINT64_C(0xd69906245565a910),
UINT64_C(0xf40e35855771202a), UINT64_C(0x106aa07032bbd1b8),
UINT64_C(0x19a4c116b8d2d0c8), UINT64_C(0x1e376c085141ab53),
UINT64_C(0x2748774cdf8eeb99), UINT64_C(0x34b0bcb5e19b48a8),
UINT64_C(0x391c0cb3c5c95a63), UINT64_C(0x4ed8aa4ae3418acb),
UINT64_C(0x5b9cca4f7763e373), UINT64_C(0x682e6ff3d6b2b8a3),
UINT64_C(0x748f82ee5defb2fc), UINT64_C(0x78a5636f43172f60),
UINT64_C(0x84c87814a1f0ab72), UINT64_C(0x8cc702081a6439ec),
UINT64_C(0x90befffa23631e28), UINT64_C(0xa4506cebde82bde9),
UINT64_C(0xbef9a3f7b2c67915), UINT64_C(0xc67178f2e372532b),
UINT64_C(0xca273eceea26619c), UINT64_C(0xd186b8c721c0c207),
UINT64_C(0xeada7dd6cde0eb1e), UINT64_C(0xf57d4f7fee6ed178),
UINT64_C(0x06f067aa72176fba), UINT64_C(0x0a637dc5a2c898a6),
UINT64_C(0x113f9804bef90dae), UINT64_C(0x1b710b35131c471b),
UINT64_C(0x28db77f523047d84), UINT64_C(0x32caab7b40c72493),
UINT64_C(0x3c9ebe0a15c9bebc), UINT64_C(0x431d67c49c100d4c),
UINT64_C(0x4cc5d4becb3e42b6), UINT64_C(0x597f299cfc657e2a),
UINT64_C(0x5fcb6fab3ad6faec), UINT64_C(0x6c44198c4a475817),
};

#define SIMPL1_ROUND_00_01(i, a, b) \
do { \
T1 += a + SIMPL1_K512[i]; \
a += T1; \
b += T1; \
} while (0)

#define SIMPL1_ROUND_02_10(i, j, a, b) \
do { \
SIMPL1_ROUND_00_01(i + j, a, b); \
} while (0)

void simpl1_return_state(uint64_t *state) {

}

uint64_t sha512_block_data_order_simpl1(uint64_t *state, const uint8_t *in, size_t num) {
uint64_t a, b, T1;
int i;

while (num--) {

a = state[0];
b = state[1];
simpl1_return_state(state);

T1 = SIMPL1_CRYPTO_load_u64_be(in);
SIMPL1_ROUND_00_01(0, a, b);
T1 = SIMPL1_CRYPTO_load_u64_be(in + 8);
SIMPL1_ROUND_00_01(1, a, b);

for (i = 2; i < 10; i += 2) {
SIMPL1_ROUND_02_10(i, 0, a, b);
SIMPL1_ROUND_02_10(i, 1, a, b);
}

state[0] += a;
state[1] += b;

in += 2 * 8;
}
return a;
}

// sha512_block_data_order

static inline void *OPENSSL_memcpy(void *dst, const void *src, size_t n) {
if (n == 0) {
return dst;
}

return memcpy(dst, src, n);
}

static inline uint32_t CRYPTO_bswap4(uint32_t x) {
x = (x >> 16) | (x << 16);
x = ((x & 0xff00ff00) >> 8) | ((x & 0x00ff00ff) << 8);
return x;
}

static inline uint64_t CRYPTO_bswap8(uint64_t x) {
return CRYPTO_bswap4(x >> 32) | (((uint64_t)CRYPTO_bswap4(x)) << 32);
}

static inline uint64_t CRYPTO_load_u64_be(const void *ptr) {
uint64_t ret;
OPENSSL_memcpy(&ret, ptr, sizeof(ret));
return CRYPTO_bswap8(ret);
}

static const uint64_t K512[80] = {
UINT64_C(0x428a2f98d728ae22), UINT64_C(0x7137449123ef65cd),
UINT64_C(0xb5c0fbcfec4d3b2f), UINT64_C(0xe9b5dba58189dbbc),
UINT64_C(0x3956c25bf348b538), UINT64_C(0x59f111f1b605d019),
UINT64_C(0x923f82a4af194f9b), UINT64_C(0xab1c5ed5da6d8118),
UINT64_C(0xd807aa98a3030242), UINT64_C(0x12835b0145706fbe),
UINT64_C(0x243185be4ee4b28c), UINT64_C(0x550c7dc3d5ffb4e2),
UINT64_C(0x72be5d74f27b896f), UINT64_C(0x80deb1fe3b1696b1),
UINT64_C(0x9bdc06a725c71235), UINT64_C(0xc19bf174cf692694),
UINT64_C(0xe49b69c19ef14ad2), UINT64_C(0xefbe4786384f25e3),
UINT64_C(0x0fc19dc68b8cd5b5), UINT64_C(0x240ca1cc77ac9c65),
UINT64_C(0x2de92c6f592b0275), UINT64_C(0x4a7484aa6ea6e483),
UINT64_C(0x5cb0a9dcbd41fbd4), UINT64_C(0x76f988da831153b5),
UINT64_C(0x983e5152ee66dfab), UINT64_C(0xa831c66d2db43210),
UINT64_C(0xb00327c898fb213f), UINT64_C(0xbf597fc7beef0ee4),
UINT64_C(0xc6e00bf33da88fc2), UINT64_C(0xd5a79147930aa725),
UINT64_C(0x06ca6351e003826f), UINT64_C(0x142929670a0e6e70),
UINT64_C(0x27b70a8546d22ffc), UINT64_C(0x2e1b21385c26c926),
UINT64_C(0x4d2c6dfc5ac42aed), UINT64_C(0x53380d139d95b3df),
UINT64_C(0x650a73548baf63de), UINT64_C(0x766a0abb3c77b2a8),
UINT64_C(0x81c2c92e47edaee6), UINT64_C(0x92722c851482353b),
UINT64_C(0xa2bfe8a14cf10364), UINT64_C(0xa81a664bbc423001),
UINT64_C(0xc24b8b70d0f89791), UINT64_C(0xc76c51a30654be30),
UINT64_C(0xd192e819d6ef5218), UINT64_C(0xd69906245565a910),
UINT64_C(0xf40e35855771202a), UINT64_C(0x106aa07032bbd1b8),
UINT64_C(0x19a4c116b8d2d0c8), UINT64_C(0x1e376c085141ab53),
UINT64_C(0x2748774cdf8eeb99), UINT64_C(0x34b0bcb5e19b48a8),
UINT64_C(0x391c0cb3c5c95a63), UINT64_C(0x4ed8aa4ae3418acb),
UINT64_C(0x5b9cca4f7763e373), UINT64_C(0x682e6ff3d6b2b8a3),
UINT64_C(0x748f82ee5defb2fc), UINT64_C(0x78a5636f43172f60),
UINT64_C(0x84c87814a1f0ab72), UINT64_C(0x8cc702081a6439ec),
UINT64_C(0x90befffa23631e28), UINT64_C(0xa4506cebde82bde9),
UINT64_C(0xbef9a3f7b2c67915), UINT64_C(0xc67178f2e372532b),
UINT64_C(0xca273eceea26619c), UINT64_C(0xd186b8c721c0c207),
UINT64_C(0xeada7dd6cde0eb1e), UINT64_C(0xf57d4f7fee6ed178),
UINT64_C(0x06f067aa72176fba), UINT64_C(0x0a637dc5a2c898a6),
UINT64_C(0x113f9804bef90dae), UINT64_C(0x1b710b35131c471b),
UINT64_C(0x28db77f523047d84), UINT64_C(0x32caab7b40c72493),
UINT64_C(0x3c9ebe0a15c9bebc), UINT64_C(0x431d67c49c100d4c),
UINT64_C(0x4cc5d4becb3e42b6), UINT64_C(0x597f299cfc657e2a),
UINT64_C(0x5fcb6fab3ad6faec), UINT64_C(0x6c44198c4a475817),
};

#ifndef ROTR
#define ROTR(x, s) (((x) >> s) | (x) << (64 - s))
#endif

#define Sigma0(x) (ROTR((x), 28) ^ ROTR((x), 34) ^ ROTR((x), 39))
#define Sigma1(x) (ROTR((x), 14) ^ ROTR((x), 18) ^ ROTR((x), 41))
#define sigma0(x) (ROTR((x), 1) ^ ROTR((x), 8) ^ ((x) >> 7))
#define sigma1(x) (ROTR((x), 19) ^ ROTR((x), 61) ^ ((x) >> 6))

#define Ch(x, y, z) (((x) & (y)) ^ ((~(x)) & (z)))
#define Maj(x, y, z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))

#define ROUND_00_15(i, a, b, c, d, e, f, g, h) \
do { \
T1 += h + Sigma1(e) + Ch(e, f, g) + K512[i]; \
h = Sigma0(a) + Maj(a, b, c); \
d += T1; \
h += T1; \
} while (0)

#define ROUND_16_80(i, j, a, b, c, d, e, f, g, h, X) \
do { \
s0 = X[(j + 1) & 0x0f]; \
s0 = sigma0(s0); \
s1 = X[(j + 14) & 0x0f]; \
s1 = sigma1(s1); \
T1 = X[(j) & 0x0f] += s0 + s1 + X[(j + 9) & 0x0f]; \
ROUND_00_15(i + j, a, b, c, d, e, f, g, h); \
} while (0)

void return_state(uint64_t *state) {

}

static void sha512_block_data_order(uint64_t *state, const uint8_t *in,
size_t num) {
uint64_t a, b, c, d, e, f, g, h, s0, s1, T1;
uint64_t X[16];
int i;

while (num--) {

a = state[0];
b = state[1];
c = state[2];
d = state[3];
e = state[4];
f = state[5];
g = state[6];
h = state[7];
return_state(state);

T1 = X[0] = CRYPTO_load_u64_be(in);
ROUND_00_15(0, a, b, c, d, e, f, g, h);
T1 = X[1] = CRYPTO_load_u64_be(in + 8);
ROUND_00_15(1, h, a, b, c, d, e, f, g);
T1 = X[2] = CRYPTO_load_u64_be(in + 2 * 8);
ROUND_00_15(2, g, h, a, b, c, d, e, f);
T1 = X[3] = CRYPTO_load_u64_be(in + 3 * 8);
ROUND_00_15(3, f, g, h, a, b, c, d, e);
T1 = X[4] = CRYPTO_load_u64_be(in + 4 * 8);
ROUND_00_15(4, e, f, g, h, a, b, c, d);
T1 = X[5] = CRYPTO_load_u64_be(in + 5 * 8);
ROUND_00_15(5, d, e, f, g, h, a, b, c);
T1 = X[6] = CRYPTO_load_u64_be(in + 6 * 8);
ROUND_00_15(6, c, d, e, f, g, h, a, b);
T1 = X[7] = CRYPTO_load_u64_be(in + 7 * 8);
ROUND_00_15(7, b, c, d, e, f, g, h, a);
T1 = X[8] = CRYPTO_load_u64_be(in + 8 * 8);
ROUND_00_15(8, a, b, c, d, e, f, g, h);
T1 = X[9] = CRYPTO_load_u64_be(in + 9 * 8);
ROUND_00_15(9, h, a, b, c, d, e, f, g);
T1 = X[10] = CRYPTO_load_u64_be(in + 10 * 8);
ROUND_00_15(10, g, h, a, b, c, d, e, f);
T1 = X[11] = CRYPTO_load_u64_be(in + 11 * 8);
ROUND_00_15(11, f, g, h, a, b, c, d, e);
T1 = X[12] = CRYPTO_load_u64_be(in + 12 * 8);
ROUND_00_15(12, e, f, g, h, a, b, c, d);
T1 = X[13] = CRYPTO_load_u64_be(in + 13 * 8);
ROUND_00_15(13, d, e, f, g, h, a, b, c);
T1 = X[14] = CRYPTO_load_u64_be(in + 14 * 8);
ROUND_00_15(14, c, d, e, f, g, h, a, b);
T1 = X[15] = CRYPTO_load_u64_be(in + 15 * 8);
ROUND_00_15(15, b, c, d, e, f, g, h, a);

for (i = 16; i < 80; i += 16) {
ROUND_16_80(i, 0, a, b, c, d, e, f, g, h, X);
ROUND_16_80(i, 1, h, a, b, c, d, e, f, g, X);
ROUND_16_80(i, 2, g, h, a, b, c, d, e, f, X);
ROUND_16_80(i, 3, f, g, h, a, b, c, d, e, X);
ROUND_16_80(i, 4, e, f, g, h, a, b, c, d, X);
ROUND_16_80(i, 5, d, e, f, g, h, a, b, c, X);
ROUND_16_80(i, 6, c, d, e, f, g, h, a, b, X);
ROUND_16_80(i, 7, b, c, d, e, f, g, h, a, X);
ROUND_16_80(i, 8, a, b, c, d, e, f, g, h, X);
ROUND_16_80(i, 9, h, a, b, c, d, e, f, g, X);
ROUND_16_80(i, 10, g, h, a, b, c, d, e, f, X);
ROUND_16_80(i, 11, f, g, h, a, b, c, d, e, X);
ROUND_16_80(i, 12, e, f, g, h, a, b, c, d, X);
ROUND_16_80(i, 13, d, e, f, g, h, a, b, c, X);
ROUND_16_80(i, 14, c, d, e, f, g, h, a, b, X);
ROUND_16_80(i, 15, b, c, d, e, f, g, h, a, X);
}

state[0] += a;
state[1] += b;
state[2] += c;
state[3] += d;
state[4] += e;
state[5] += f;
state[6] += g;
state[7] += h;

in += 16 * 8;
}
}

void dummy(uint64_t *state, const uint8_t *in, size_t num) {
sha512_block_data_order(state, in, num);
}
77 changes: 77 additions & 0 deletions heapster-saw/examples/sha512.saw
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
enable_experimental;
env <- heapster_init_env "SHA512" "sha512.bc";

heapster_set_debug_level env 1;

heapster_define_perm env "int64" " " "llvmptr 64" "exists x:bv 64.eq(llvmword(x))";
heapster_define_perm env "int32" " " "llvmptr 32" "exists x:bv 32.eq(llvmword(x))";
heapster_define_perm env "int8" " " "llvmptr 8" "exists x:bv 8.eq(llvmword(x))";

heapster_assume_fun env "llvm.memcpy.p0i8.p0i8.i64"
"(rw:rwmodality, l1:lifetime, l2:lifetime, sh:llvmshape 64, \
\ b:llvmblock 64, len:bv 64). \
\ arg0:[l1]memblock(W,0,len,sh), arg1:[l2]memblock(rw,0,len,eqsh(b)), \
\ arg2:eq(llvmword(len)) -o \
\ arg0:[l1]memblock(W,0,len,eqsh(b)), arg1:[l2]memblock(rw,0,len,eqsh(b))"
"\\ (X:sort 0) (len:Vec 64 Bool) (x:X) (_:#()) -> returnM (#() * #()) ((),())";

/*
heapster_typecheck_fun env "SIMPL1_CRYPTO_load_u64_be"
"(). arg0:ptr((R,0) |-> int64<>) -o \
\ arg0:ptr((R,0) |-> int64<>), ret:int64<>";

heapster_typecheck_fun env "simpl1_return_state"
"(). arg0:array(W,0,<2,*8,fieldsh(int64<>)) -o \
\ arg0:array(W,0,<2,*8,fieldsh(int64<>))";

heapster_typecheck_fun env "sha512_block_data_order_simpl1"
"(num:bv 64). arg0:array(W,0,<2,*8,fieldsh(int64<>)), \
\ arg1:array(R,0,<2*num,*8,fieldsh(int64<>)), \
\ arg2:eq(llvmword(num)) -o \
\ arg0:array(W,0,<2,*8,fieldsh(int64<>)), \
\ arg1:array(R,0,<2*num,*8,fieldsh(int64<>)), \
\ arg2:true, ret:true";
// arg0:array(W,0,<1,*8,fieldsh(int64<>))
*/

/*
// A copy of the permissions for memcpy
heapster_assume_fun env "OPENSSL_memcpy"
"(rw:rwmodality, l1:lifetime, l2:lifetime, sh:llvmshape 64, \
\ b:llvmblock 64, len:bv 64). \
\ arg0:[l1]memblock(W,0,len,sh), arg1:[l2]memblock(rw,0,len,eqsh(b)), \
\ arg2:eq(llvmword(len)) -o \
\ arg0:[l1]memblock(W,0,len,eqsh(b)), arg1:[l2]memblock(rw,0,len,eqsh(b))"
"\\ (X:sort 0) (len:Vec 64 Bool) (x:X) (_:#()) -> returnM (#() * #()) ((),())";

heapster_typecheck_fun env "CRYPTO_bswap4"
"(). arg0:int32<> -o arg0:int32<>, ret:int32<>";

heapster_typecheck_fun env "CRYPTO_bswap8"
"(). arg0:int64<> -o arg0:int64<>, ret:int64<>";

heapster_typecheck_fun env "CRYPTO_load_u64_be"
"(). arg0:ptr((R,0) |-> int64<>) -o \
\ arg0:ptr((R,0) |-> int64<>), ret:int64<>";
*/

heapster_assume_fun env "CRYPTO_load_u64_be"
"(). arg0:ptr((R,0) |-> int64<>) -o \
\ arg0:ptr((R,0) |-> int64<>), ret:int64<>"
"\\ (x:Vec 64 Bool) -> returnM (Vec 64 Bool * Vec 64 Bool) (x, x)";

heapster_typecheck_fun env "return_state"
"(). arg0:array(W,0,<8,*8,fieldsh(int64<>)) -o \
\ arg0:array(W,0,<8,*8,fieldsh(int64<>))";

heapster_set_translation_checks env false;
heapster_typecheck_fun env "sha512_block_data_order"
"(num:bv 64). arg0:array(W,0,<8,*8,fieldsh(int64<>)), \
\ arg1:array(R,0,<16*num,*8,fieldsh(int64<>)), \
\ arg2:eq(llvmword(num)) -o \
\ arg0:array(W,0,<8,*8,fieldsh(int64<>)), \
\ arg1:array(R,0,<16*num,*8,fieldsh(int64<>)), \
\ arg2:true, ret:true";


heapster_export_coq env "sha512_gen.v";
21 changes: 21 additions & 0 deletions heapster-saw/examples/sha512_proofs.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
From Coq Require Import Program.Basics.
From Coq Require Import Lists.List.
From Coq Require Import String.
From Coq Require Import Vectors.Vector.
From CryptolToCoq Require Import SAWCoreScaffolding.
From CryptolToCoq Require Import SAWCoreVectorsAsCoqVectors.
From CryptolToCoq Require Import SAWCoreBitvectors.

From CryptolToCoq Require Import SAWCorePrelude.
From CryptolToCoq Require Import CompMExtra.

Import SAWCorePrelude.

Require Import Examples.sha512_gen.
Import SHA512.

Lemma no_errors_sha512_block_data_order_simpl1 :
refinesFun sha512_block_data_order_simpl1 (fun _ _ _ => noErrorsSpec).
Proof.
unfold sha512_block_data_order_simpl1, sha512_block_data_order_simpl1__tuple_fun.
Set Printing Depth 1000.
Loading