From c474e656682e2762bde61ec7e2582a1b70ca6a36 Mon Sep 17 00:00:00 2001 From: Yan Peng Date: Fri, 14 Feb 2025 00:33:22 +0000 Subject: [PATCH 001/132] aes-xts experiments --- arm/Makefile | 5 +- arm/aes-xts/aes-xts-armv8.S | 654 ++++++++++++++++++++++++++++++++++++ 2 files changed, 658 insertions(+), 1 deletion(-) create mode 100644 arm/aes-xts/aes-xts-armv8.S diff --git a/arm/Makefile b/arm/Makefile index 822ee41cd..078794c38 100644 --- a/arm/Makefile +++ b/arm/Makefile @@ -403,7 +403,10 @@ UNOPT_OBJ = p256/unopt/bignum_montmul_p256_base.o \ fastmul/unopt/bignum_mul_8_16_base.o \ fastmul/unopt/bignum_sqr_8_16_base.o -OBJ = $(POINT_OBJ) $(BIGNUM_OBJ) +AES_XTS_OBJ = aes-xts/aes-xts-armv8.o + +# OBJ = $(POINT_OBJ) $(BIGNUM_OBJ) $(AES_XTS_OBJ) +OBJ = $(AES_XTS_OBJ) # Tutorial assembly files diff --git a/arm/aes-xts/aes-xts-armv8.S b/arm/aes-xts/aes-xts-armv8.S new file mode 100644 index 000000000..04ffb0bbe --- /dev/null +++ b/arm/aes-xts/aes-xts-armv8.S @@ -0,0 +1,654 @@ +#include "_internal_s2n_bignum.h" + +aes_hw_xts_encrypt: + // AARCH64_VALID_CALL_TARGET + cmp x2,#16 + // Original input data size bigger than 16, jump to big size processing. + b.ne .Lxts_enc_big_size + // Encrypt the iv with key2, as the first XEX iv. + ldr w6,[x4,#240] + ld1 {v0.16b},[x4],#16 + ld1 {v6.16b},[x5] + sub w6,w6,#2 + ld1 {v1.16b},[x4],#16 + +.Loop_enc_iv_enc: + aese v6.16b,v0.16b + aesmc v6.16b,v6.16b + ld1 {v0.4s},[x4],#16 + subs w6,w6,#2 + aese v6.16b,v1.16b + aesmc v6.16b,v6.16b + ld1 {v1.4s},[x4],#16 + b.gt .Loop_enc_iv_enc + + aese v6.16b,v0.16b + aesmc v6.16b,v6.16b + ld1 {v0.4s},[x4] + aese v6.16b,v1.16b + eor v6.16b,v6.16b,v0.16b + + ld1 {v0.16b},[x0] + eor v0.16b,v6.16b,v0.16b + + ldr w6,[x3,#240] + ld1 {v28.4s,v29.4s},[x3],#32 // load key schedule... + + aese v0.16b,v28.16b + aesmc v0.16b,v0.16b + ld1 {v16.4s,v17.4s},[x3],#32 // load key schedule... + aese v0.16b,v29.16b + aesmc v0.16b,v0.16b + subs w6,w6,#10 // if rounds==10, jump to aes-128-xts processing + b.eq .Lxts_128_enc +.Lxts_enc_round_loop: + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + ld1 {v16.4s},[x3],#16 // load key schedule... + aese v0.16b,v17.16b + aesmc v0.16b,v0.16b + ld1 {v17.4s},[x3],#16 // load key schedule... + subs w6,w6,#2 // bias + b.gt .Lxts_enc_round_loop +.Lxts_128_enc: + ld1 {v18.4s,v19.4s},[x3],#32 // load key schedule... + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + aese v0.16b,v17.16b + aesmc v0.16b,v0.16b + ld1 {v20.4s,v21.4s},[x3],#32 // load key schedule... + aese v0.16b,v18.16b + aesmc v0.16b,v0.16b + aese v0.16b,v19.16b + aesmc v0.16b,v0.16b + ld1 {v22.4s,v23.4s},[x3],#32 // load key schedule... + aese v0.16b,v20.16b + aesmc v0.16b,v0.16b + aese v0.16b,v21.16b + aesmc v0.16b,v0.16b + ld1 {v7.4s},[x3] + aese v0.16b,v22.16b + aesmc v0.16b,v0.16b + aese v0.16b,v23.16b + eor v0.16b,v0.16b,v7.16b + eor v0.16b,v0.16b,v6.16b + st1 {v0.16b},[x1] + b .Lxts_enc_final_abort + +.align 4 +.Lxts_enc_big_size: + // Encrypt input size > 16 bytes + stp x19,x20,[sp,#-64]! + stp x21,x22,[sp,#48] + stp d8,d9,[sp,#32] + stp d10,d11,[sp,#16] + + // tailcnt store the tail value of length%16. + and x21,x2,#0xf + and x2,x2,#-16 // len &= 0x1..110000, now divisible by 16 + subs x2,x2,#16 + mov x8,#16 + b.lo .Lxts_abort // if !(len > 16): error + csel x8,xzr,x8,eq // if (len == 16): step = 0 + + // Firstly, encrypt the iv with key2, as the first iv of XEX. + ldr w6,[x4,#240] + ld1 {v0.4s},[x4],#16 + ld1 {v6.16b},[x5] + sub w6,w6,#2 + ld1 {v1.4s},[x4],#16 + +.Loop_iv_enc: + aese v6.16b,v0.16b + aesmc v6.16b,v6.16b + ld1 {v0.4s},[x4],#16 + subs w6,w6,#2 + aese v6.16b,v1.16b + aesmc v6.16b,v6.16b + ld1 {v1.4s},[x4],#16 + b.gt .Loop_iv_enc + + aese v6.16b,v0.16b + aesmc v6.16b,v6.16b + ld1 {v0.4s},[x4] + aese v6.16b,v1.16b + eor v6.16b,v6.16b,v0.16b + + // The iv for second block + // x9- iv(low), x10 - iv(high) + // the five ivs stored into, v6.16b,v8.16b,v9.16b,v10.16b,v11.16b + fmov x9,d6 + fmov x10,v6.d[1] + mov w19,#0x87 + extr x22,x10,x10,#32 + extr x10,x10,x9,#63 + and w11,w19,w22,asr#31 + eor x9,x11,x9,lsl#1 + fmov d8,x9 + fmov v8.d[1],x10 + + ldr w5,[x3,#240] // next starting point + ld1 {v0.16b},[x0],x8 + + ld1 {v16.4s,v17.4s},[x3] // load key schedule... + sub w5,w5,#6 + add x7,x3,x5,lsl#4 // pointer to last 7 round keys + sub w5,w5,#2 + ld1 {v18.4s,v19.4s},[x7],#32 + ld1 {v20.4s,v21.4s},[x7],#32 + ld1 {v22.4s,v23.4s},[x7],#32 + ld1 {v7.4s},[x7] + + add x7,x3,#32 + mov w6,w5 + + // Encryption +.Lxts_enc: + ld1 {v24.16b},[x0],#16 + subs x2,x2,#32 // bias + add w6,w5,#2 + orr v3.16b,v0.16b,v0.16b + orr v1.16b,v0.16b,v0.16b + orr v28.16b,v0.16b,v0.16b + orr v27.16b,v24.16b,v24.16b + orr v29.16b,v24.16b,v24.16b + b.lo .Lxts_inner_enc_tail // when input size % 5 = 1 or 2 + // (with tail or not) + eor v0.16b,v0.16b,v6.16b // before encryption, xor with iv + eor v24.16b,v24.16b,v8.16b + + // The iv for third block + extr x22,x10,x10,#32 + extr x10,x10,x9,#63 + and w11,w19,w22,asr#31 + eor x9,x11,x9,lsl#1 + fmov d9,x9 + fmov v9.d[1],x10 + + + orr v1.16b,v24.16b,v24.16b + ld1 {v24.16b},[x0],#16 + orr v2.16b,v0.16b,v0.16b + orr v3.16b,v1.16b,v1.16b + eor v27.16b,v24.16b,v9.16b // the third block + eor v24.16b,v24.16b,v9.16b + cmp x2,#32 + b.lo .Lxts_outer_enc_tail + + // The iv for fourth block + extr x22,x10,x10,#32 + extr x10,x10,x9,#63 + and w11,w19,w22,asr#31 + eor x9,x11,x9,lsl#1 + fmov d10,x9 + fmov v10.d[1],x10 + + ld1 {v25.16b},[x0],#16 + // The iv for fifth block + extr x22,x10,x10,#32 + extr x10,x10,x9,#63 + and w11,w19,w22,asr#31 + eor x9,x11,x9,lsl#1 + fmov d11,x9 + fmov v11.d[1],x10 + + ld1 {v26.16b},[x0],#16 + eor v25.16b,v25.16b,v10.16b // the fourth block + eor v26.16b,v26.16b,v11.16b + sub x2,x2,#32 // bias + mov w6,w5 + b .Loop5x_xts_enc + +.align 4 +.Loop5x_xts_enc: + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + aese v1.16b,v16.16b + aesmc v1.16b,v1.16b + aese v24.16b,v16.16b + aesmc v24.16b,v24.16b + aese v25.16b,v16.16b + aesmc v25.16b,v25.16b + aese v26.16b,v16.16b + aesmc v26.16b,v26.16b + ld1 {v16.4s},[x7],#16 + subs w6,w6,#2 + aese v0.16b,v17.16b + aesmc v0.16b,v0.16b + aese v1.16b,v17.16b + aesmc v1.16b,v1.16b + aese v24.16b,v17.16b + aesmc v24.16b,v24.16b + aese v25.16b,v17.16b + aesmc v25.16b,v25.16b + aese v26.16b,v17.16b + aesmc v26.16b,v26.16b + ld1 {v17.4s},[x7],#16 + b.gt .Loop5x_xts_enc + + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + aese v1.16b,v16.16b + aesmc v1.16b,v1.16b + aese v24.16b,v16.16b + aesmc v24.16b,v24.16b + aese v25.16b,v16.16b + aesmc v25.16b,v25.16b + aese v26.16b,v16.16b + aesmc v26.16b,v26.16b + subs x2,x2,#0x50 // because .Lxts_enc_tail4x + + aese v0.16b,v17.16b + aesmc v0.16b,v0.16b + aese v1.16b,v17.16b + aesmc v1.16b,v1.16b + aese v24.16b,v17.16b + aesmc v24.16b,v24.16b + aese v25.16b,v17.16b + aesmc v25.16b,v25.16b + aese v26.16b,v17.16b + aesmc v26.16b,v26.16b + csel x6,xzr,x2,gt // borrow x6, w6, "gt" is not typo + mov x7,x3 + + aese v0.16b,v18.16b + aesmc v0.16b,v0.16b + aese v1.16b,v18.16b + aesmc v1.16b,v1.16b + aese v24.16b,v18.16b + aesmc v24.16b,v24.16b + aese v25.16b,v18.16b + aesmc v25.16b,v25.16b + aese v26.16b,v18.16b + aesmc v26.16b,v26.16b + add x0,x0,x6 // x0 is adjusted in such way that + // at exit from the loop v1.16b-v26.16b + // are loaded with last "words" + add x6,x2,#0x60 // because .Lxts_enc_tail4x + + aese v0.16b,v19.16b + aesmc v0.16b,v0.16b + aese v1.16b,v19.16b + aesmc v1.16b,v1.16b + aese v24.16b,v19.16b + aesmc v24.16b,v24.16b + aese v25.16b,v19.16b + aesmc v25.16b,v25.16b + aese v26.16b,v19.16b + aesmc v26.16b,v26.16b + + aese v0.16b,v20.16b + aesmc v0.16b,v0.16b + aese v1.16b,v20.16b + aesmc v1.16b,v1.16b + aese v24.16b,v20.16b + aesmc v24.16b,v24.16b + aese v25.16b,v20.16b + aesmc v25.16b,v25.16b + aese v26.16b,v20.16b + aesmc v26.16b,v26.16b + + aese v0.16b,v21.16b + aesmc v0.16b,v0.16b + aese v1.16b,v21.16b + aesmc v1.16b,v1.16b + aese v24.16b,v21.16b + aesmc v24.16b,v24.16b + aese v25.16b,v21.16b + aesmc v25.16b,v25.16b + aese v26.16b,v21.16b + aesmc v26.16b,v26.16b + + aese v0.16b,v22.16b + aesmc v0.16b,v0.16b + aese v1.16b,v22.16b + aesmc v1.16b,v1.16b + aese v24.16b,v22.16b + aesmc v24.16b,v24.16b + aese v25.16b,v22.16b + aesmc v25.16b,v25.16b + aese v26.16b,v22.16b + aesmc v26.16b,v26.16b + + eor v4.16b,v7.16b,v6.16b + aese v0.16b,v23.16b + // The iv for first block of one iteration + extr x22,x10,x10,#32 + extr x10,x10,x9,#63 + and w11,w19,w22,asr#31 + eor x9,x11,x9,lsl#1 + fmov d6,x9 + fmov v6.d[1],x10 + eor v5.16b,v7.16b,v8.16b + ld1 {v2.16b},[x0],#16 + aese v1.16b,v23.16b + // The iv for second block + extr x22,x10,x10,#32 + extr x10,x10,x9,#63 + and w11,w19,w22,asr#31 + eor x9,x11,x9,lsl#1 + fmov d8,x9 + fmov v8.d[1],x10 + eor v17.16b,v7.16b,v9.16b + ld1 {v3.16b},[x0],#16 + aese v24.16b,v23.16b + // The iv for third block + extr x22,x10,x10,#32 + extr x10,x10,x9,#63 + and w11,w19,w22,asr#31 + eor x9,x11,x9,lsl#1 + fmov d9,x9 + fmov v9.d[1],x10 + eor v30.16b,v7.16b,v10.16b + ld1 {v27.16b},[x0],#16 + aese v25.16b,v23.16b + // The iv for fourth block + extr x22,x10,x10,#32 + extr x10,x10,x9,#63 + and w11,w19,w22,asr#31 + eor x9,x11,x9,lsl#1 + fmov d10,x9 + fmov v10.d[1],x10 + eor v31.16b,v7.16b,v11.16b + ld1 {v28.16b},[x0],#16 + aese v26.16b,v23.16b + + // The iv for fifth block + extr x22,x10,x10,#32 + extr x10,x10,x9,#63 + and w11,w19,w22,asr #31 + eor x9,x11,x9,lsl #1 + fmov d11,x9 + fmov v11.d[1],x10 + + ld1 {v29.16b},[x0],#16 + cbz x6,.Lxts_enc_tail4x + ld1 {v16.4s},[x7],#16 // re-pre-load rndkey[0] + eor v4.16b,v4.16b,v0.16b + eor v0.16b,v2.16b,v6.16b + eor v5.16b,v5.16b,v1.16b + eor v1.16b,v3.16b,v8.16b + eor v17.16b,v17.16b,v24.16b + eor v24.16b,v27.16b,v9.16b + eor v30.16b,v30.16b,v25.16b + eor v25.16b,v28.16b,v10.16b + eor v31.16b,v31.16b,v26.16b + st1 {v4.16b},[x1],#16 + eor v26.16b,v29.16b,v11.16b + st1 {v5.16b},[x1],#16 + mov w6,w5 + st1 {v17.16b},[x1],#16 + ld1 {v17.4s},[x7],#16 // re-pre-load rndkey[1] + st1 {v30.16b},[x1],#16 + st1 {v31.16b},[x1],#16 + b.hs .Loop5x_xts_enc + + + // If left 4 blocks, borrow the five block's processing. + // This means if (x2 + 1 block) == 0, which is the case + // when input size % 5 = 4, continue processing and do + // another iteration in Loop5x_xts_enc which will exit from + // cbz x6,.Lxts_enc_tail4x. + // Otherwise, this is the end of the loop continue processing + // 0, 1, 2 or 3 blocks (with or without tail) starting at + // Loop5x_enc_after + cmn x2,#0x10 + b.ne .Loop5x_enc_after + orr v11.16b,v10.16b,v10.16b + orr v10.16b,v9.16b,v9.16b + orr v9.16b,v8.16b,v8.16b + orr v8.16b,v6.16b,v6.16b + fmov x9,d11 + fmov x10,v11.d[1] + eor v0.16b,v6.16b,v2.16b + eor v1.16b,v8.16b,v3.16b + eor v24.16b,v27.16b,v9.16b + eor v25.16b,v28.16b,v10.16b + eor v26.16b,v29.16b,v11.16b + b.eq .Loop5x_xts_enc + +.Loop5x_enc_after: + add x2,x2,#0x50 + cbz x2,.Lxts_enc_done // no blocks left + + add w6,w5,#2 + subs x2,x2,#0x30 + b.lo .Lxts_inner_enc_tail // 1 or 2 blocks left + // (with tail or not) + + eor v0.16b,v6.16b,v27.16b // 3 blocks left + eor v1.16b,v8.16b,v28.16b + eor v24.16b,v29.16b,v9.16b + b .Lxts_outer_enc_tail + +.align 4 +.Lxts_enc_tail4x: + add x0,x0,#16 + eor v5.16b,v1.16b,v5.16b + st1 {v5.16b},[x1],#16 + eor v17.16b,v24.16b,v17.16b + st1 {v17.16b},[x1],#16 + eor v30.16b,v25.16b,v30.16b + eor v31.16b,v26.16b,v31.16b + st1 {v30.16b,v31.16b},[x1],#32 + b .Lxts_enc_done +.align 4 +.Lxts_outer_enc_tail: + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + aese v1.16b,v16.16b + aesmc v1.16b,v1.16b + aese v24.16b,v16.16b + aesmc v24.16b,v24.16b + ld1 {v16.4s},[x7],#16 + subs w6,w6,#2 + aese v0.16b,v17.16b + aesmc v0.16b,v0.16b + aese v1.16b,v17.16b + aesmc v1.16b,v1.16b + aese v24.16b,v17.16b + aesmc v24.16b,v24.16b + ld1 {v17.4s},[x7],#16 + b.gt .Lxts_outer_enc_tail + + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + aese v1.16b,v16.16b + aesmc v1.16b,v1.16b + aese v24.16b,v16.16b + aesmc v24.16b,v24.16b + eor v4.16b,v6.16b,v7.16b + subs x2,x2,#0x30 + // The iv for first block + fmov x9,d9 + fmov x10,v9.d[1] + //mov w19,#0x87 + extr x22,x10,x10,#32 + extr x10,x10,x9,#63 + and w11,w19,w22,asr#31 + eor x9,x11,x9,lsl#1 + fmov d6,x9 + fmov v6.d[1],x10 + eor v5.16b,v8.16b,v7.16b + csel x6,x2,x6,lo // x6, w6, is zero at this point + aese v0.16b,v17.16b + aesmc v0.16b,v0.16b + aese v1.16b,v17.16b + aesmc v1.16b,v1.16b + aese v24.16b,v17.16b + aesmc v24.16b,v24.16b + eor v17.16b,v9.16b,v7.16b + + add x6,x6,#0x20 + add x0,x0,x6 + mov x7,x3 + + aese v0.16b,v20.16b + aesmc v0.16b,v0.16b + aese v1.16b,v20.16b + aesmc v1.16b,v1.16b + aese v24.16b,v20.16b + aesmc v24.16b,v24.16b + aese v0.16b,v21.16b + aesmc v0.16b,v0.16b + aese v1.16b,v21.16b + aesmc v1.16b,v1.16b + aese v24.16b,v21.16b + aesmc v24.16b,v24.16b + aese v0.16b,v22.16b + aesmc v0.16b,v0.16b + aese v1.16b,v22.16b + aesmc v1.16b,v1.16b + aese v24.16b,v22.16b + aesmc v24.16b,v24.16b + aese v0.16b,v23.16b + aese v1.16b,v23.16b + aese v24.16b,v23.16b + ld1 {v27.16b},[x0],#16 + add w6,w5,#2 + ld1 {v16.4s},[x7],#16 // re-pre-load rndkey[0] + eor v4.16b,v4.16b,v0.16b + eor v5.16b,v5.16b,v1.16b + eor v24.16b,v24.16b,v17.16b + ld1 {v17.4s},[x7],#16 // re-pre-load rndkey[1] + st1 {v4.16b},[x1],#16 + st1 {v5.16b},[x1],#16 + st1 {v24.16b},[x1],#16 + cmn x2,#0x30 + b.eq .Lxts_enc_done +.Lxts_encxor_one: + orr v28.16b,v3.16b,v3.16b + orr v29.16b,v27.16b,v27.16b + nop + +.Lxts_inner_enc_tail: + cmn x2,#0x10 + eor v1.16b,v28.16b,v6.16b + eor v24.16b,v29.16b,v8.16b + b.eq .Lxts_enc_tail_loop + eor v24.16b,v29.16b,v6.16b +.Lxts_enc_tail_loop: + aese v1.16b,v16.16b + aesmc v1.16b,v1.16b + aese v24.16b,v16.16b + aesmc v24.16b,v24.16b + ld1 {v16.4s},[x7],#16 + subs w6,w6,#2 + aese v1.16b,v17.16b + aesmc v1.16b,v1.16b + aese v24.16b,v17.16b + aesmc v24.16b,v24.16b + ld1 {v17.4s},[x7],#16 + b.gt .Lxts_enc_tail_loop + + aese v1.16b,v16.16b + aesmc v1.16b,v1.16b + aese v24.16b,v16.16b + aesmc v24.16b,v24.16b + aese v1.16b,v17.16b + aesmc v1.16b,v1.16b + aese v24.16b,v17.16b + aesmc v24.16b,v24.16b + aese v1.16b,v20.16b + aesmc v1.16b,v1.16b + aese v24.16b,v20.16b + aesmc v24.16b,v24.16b + cmn x2,#0x20 + aese v1.16b,v21.16b + aesmc v1.16b,v1.16b + aese v24.16b,v21.16b + aesmc v24.16b,v24.16b + eor v5.16b,v6.16b,v7.16b + aese v1.16b,v22.16b + aesmc v1.16b,v1.16b + aese v24.16b,v22.16b + aesmc v24.16b,v24.16b + eor v17.16b,v8.16b,v7.16b + aese v1.16b,v23.16b + aese v24.16b,v23.16b + b.eq .Lxts_enc_one + eor v5.16b,v5.16b,v1.16b + st1 {v5.16b},[x1],#16 + eor v17.16b,v17.16b,v24.16b + orr v6.16b,v8.16b,v8.16b + st1 {v17.16b},[x1],#16 + fmov x9,d8 + fmov x10,v8.d[1] + mov w19,#0x87 + extr x22,x10,x10,#32 + extr x10,x10,x9,#63 + and w11,w19,w22,asr #31 + eor x9,x11,x9,lsl #1 + fmov d6,x9 + fmov v6.d[1],x10 + b .Lxts_enc_done + +.Lxts_enc_one: + eor v5.16b,v5.16b,v24.16b + orr v6.16b,v6.16b,v6.16b + st1 {v5.16b},[x1],#16 + fmov x9,d6 + fmov x10,v6.d[1] + mov w19,#0x87 + extr x22,x10,x10,#32 + extr x10,x10,x9,#63 + and w11,w19,w22,asr #31 + eor x9,x11,x9,lsl #1 + fmov d6,x9 + fmov v6.d[1],x10 + b .Lxts_enc_done +.align 5 +.Lxts_enc_done: + // Process the tail block with cipher stealing. + tst x21,#0xf + b.eq .Lxts_abort + + mov x20,x0 + mov x13,x1 + sub x1,x1,#16 +.composite_enc_loop: + subs x21,x21,#1 + ldrb w15,[x1,x21] + ldrb w14,[x20,x21] + strb w15,[x13,x21] + strb w14,[x1,x21] + b.gt .composite_enc_loop +.Lxts_enc_load_done: + ld1 {v26.16b},[x1] + eor v26.16b,v26.16b,v6.16b + + // Encrypt the composite block to get the last second encrypted text block + ldr w6,[x3,#240] // load key schedule... + ld1 {v0.16b},[x3],#16 + sub w6,w6,#2 + ld1 {v1.16b},[x3],#16 // load key schedule... +.Loop_final_enc: + aese v26.16b,v0.16b + aesmc v26.16b,v26.16b + ld1 {v0.4s},[x3],#16 + subs w6,w6,#2 + aese v26.16b,v1.16b + aesmc v26.16b,v26.16b + ld1 {v1.4s},[x3],#16 + b.gt .Loop_final_enc + + aese v26.16b,v0.16b + aesmc v26.16b,v26.16b + ld1 {v0.4s},[x3] + aese v26.16b,v1.16b + eor v26.16b,v26.16b,v0.16b + eor v26.16b,v26.16b,v6.16b + st1 {v26.16b},[x1] + +.Lxts_abort: + ldp x21,x22,[sp,#48] + ldp d8,d9,[sp,#32] + ldp d10,d11,[sp,#16] + ldp x19,x20,[sp],#64 +.Lxts_enc_final_abort: + ret +.size aes_hw_xts_encrypt,.-aes_hw_xts_encrypt + +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif \ No newline at end of file From 00a95b33f2a3e54ae5722415db70322b36aca698 Mon Sep 17 00:00:00 2001 From: Yan Peng Date: Fri, 14 Feb 2025 01:00:34 +0000 Subject: [PATCH 002/132] More experiments --- arm/Makefile | 4 ++-- arm/aes-xts/aes-xts-armv8.S | 2 +- arm/proofs/aes-xts.ml | 8 ++++++++ 3 files changed, 11 insertions(+), 3 deletions(-) create mode 100644 arm/proofs/aes-xts.ml diff --git a/arm/Makefile b/arm/Makefile index 078794c38..950088fe5 100644 --- a/arm/Makefile +++ b/arm/Makefile @@ -421,9 +421,9 @@ TUTORIAL_OBJ = $(TUTORIAL_PROOFS:.ml=.o) tutorial/rel_loop2.o \ # x18 should not be used for Apple platforms. Check this using grep. %.o : %.S - cat $< | $(PREPROCESS) | $(SPLIT) | grep -v -E '^\s+\.(quad|hword)\s+(0x|-)?[0-9a-f]+$$' | $(ASSEMBLE) -o $@ - + cat $< | $(PREPROCESS) | $(SPLIT) | grep -v -E '^\s+.quad\s+0x[0-9a-f]+$$' | $(ASSEMBLE) -march=armv8-a+crypto -o $@ - $(OBJDUMP) $@ | ( ( ! grep --ignore-case -E 'w18|[^0]x18' ) || ( rm $@ ; exit 1 ) ) - cat $< | $(PREPROCESS) | $(SPLIT) | $(ASSEMBLE) -o $@ - + cat $< | $(PREPROCESS) | $(SPLIT) | $(ASSEMBLE) -march=armv8-a+crypto -o $@ - libs2nbignum.a: $(OBJ) ; ar -rc libs2nbignum.a $(OBJ) diff --git a/arm/aes-xts/aes-xts-armv8.S b/arm/aes-xts/aes-xts-armv8.S index 04ffb0bbe..fb0fd46b0 100644 --- a/arm/aes-xts/aes-xts-armv8.S +++ b/arm/aes-xts/aes-xts-armv8.S @@ -651,4 +651,4 @@ aes_hw_xts_encrypt: #if defined(__linux__) && defined(__ELF__) .section .note.GNU-stack,"",%progbits -#endif \ No newline at end of file +#endif diff --git a/arm/proofs/aes-xts.ml b/arm/proofs/aes-xts.ml new file mode 100644 index 000000000..8a245be7a --- /dev/null +++ b/arm/proofs/aes-xts.ml @@ -0,0 +1,8 @@ +(* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT-0 + *) + +needs "arm/proofs/base.ml";; + +print_literal_from_elf "arm/aes-xts/aes-xts-armv8.o";; From 19f9d1ce952fe598c87f2b1037abcba780bcfd40 Mon Sep 17 00:00:00 2001 From: Nevine Ebeid Date: Tue, 18 Mar 2025 10:28:32 -0400 Subject: [PATCH 003/132] Add Decrypt function- its instructions are all understood by the decoder. "Remove `.size` as not passing on MacOS with this build. --- arm/aes-xts/aes-xts-armv8.S | 684 +++++++++++++++++++++++++++++++++++- 1 file changed, 683 insertions(+), 1 deletion(-) diff --git a/arm/aes-xts/aes-xts-armv8.S b/arm/aes-xts/aes-xts-armv8.S index fb0fd46b0..ca34d8484 100644 --- a/arm/aes-xts/aes-xts-armv8.S +++ b/arm/aes-xts/aes-xts-armv8.S @@ -647,7 +647,689 @@ aes_hw_xts_encrypt: ldp x19,x20,[sp],#64 .Lxts_enc_final_abort: ret -.size aes_hw_xts_encrypt,.-aes_hw_xts_encrypt + +aes_hw_xts_decrypt: + cmp x2,#16 + // Original input data size bigger than 16, jump to big size processing. + b.ne Lxts_dec_big_size + // Encrypt the iv with key2, as the first XEX iv. + ldr w6,[x4,#240] + ld1 {v0.16b},[x4],#16 + ld1 {v6.16b},[x5] + sub w6,w6,#2 + ld1 {v1.16b},[x4],#16 + +Loop_dec_small_iv_enc: + aese v6.16b,v0.16b + aesmc v6.16b,v6.16b + ld1 {v0.4s},[x4],#16 + subs w6,w6,#2 + aese v6.16b,v1.16b + aesmc v6.16b,v6.16b + ld1 {v1.4s},[x4],#16 + b.gt Loop_dec_small_iv_enc + + aese v6.16b,v0.16b + aesmc v6.16b,v6.16b + ld1 {v0.4s},[x4] + aese v6.16b,v1.16b + eor v6.16b,v6.16b,v0.16b + + ld1 {v0.16b},[x0] + eor v0.16b,v6.16b,v0.16b + + ldr w6,[x3,#240] + ld1 {v28.4s,v29.4s},[x3],#32 // load key schedule... + + aesd v0.16b,v28.16b + aesimc v0.16b,v0.16b + ld1 {v16.4s,v17.4s},[x3],#32 // load key schedule... + aesd v0.16b,v29.16b + aesimc v0.16b,v0.16b + subs w6,w6,#10 // bias + b.eq Lxts_128_dec +Lxts_dec_round_loop: + aesd v0.16b,v16.16b + aesimc v0.16b,v0.16b + ld1 {v16.4s},[x3],#16 // load key schedule... + aesd v0.16b,v17.16b + aesimc v0.16b,v0.16b + ld1 {v17.4s},[x3],#16 // load key schedule... + subs w6,w6,#2 // bias + b.gt Lxts_dec_round_loop +Lxts_128_dec: + ld1 {v18.4s,v19.4s},[x3],#32 // load key schedule... + aesd v0.16b,v16.16b + aesimc v0.16b,v0.16b + aesd v0.16b,v17.16b + aesimc v0.16b,v0.16b + ld1 {v20.4s,v21.4s},[x3],#32 // load key schedule... + aesd v0.16b,v18.16b + aesimc v0.16b,v0.16b + aesd v0.16b,v19.16b + aesimc v0.16b,v0.16b + ld1 {v22.4s,v23.4s},[x3],#32 // load key schedule... + aesd v0.16b,v20.16b + aesimc v0.16b,v0.16b + aesd v0.16b,v21.16b + aesimc v0.16b,v0.16b + ld1 {v7.4s},[x3] + aesd v0.16b,v22.16b + aesimc v0.16b,v0.16b + aesd v0.16b,v23.16b + eor v0.16b,v0.16b,v7.16b + eor v0.16b,v6.16b,v0.16b + st1 {v0.16b},[x1] + b Lxts_dec_final_abort +Lxts_dec_big_size: + stp x19,x20,[sp,#-64]! + stp x21,x22,[sp,#48] + stp d8,d9,[sp,#32] + stp d10,d11,[sp,#16] + + and x21,x2,#0xf + and x2,x2,#-16 + subs x2,x2,#16 + mov x8,#16 + b.lo Lxts_dec_abort + + // Encrypt the iv with key2, as the first XEX iv + ldr w6,[x4,#240] + ld1 {v0.16b},[x4],#16 + ld1 {v6.16b},[x5] + sub w6,w6,#2 + ld1 {v1.16b},[x4],#16 + +Loop_dec_iv_enc: + aese v6.16b,v0.16b + aesmc v6.16b,v6.16b + ld1 {v0.4s},[x4],#16 + subs w6,w6,#2 + aese v6.16b,v1.16b + aesmc v6.16b,v6.16b + ld1 {v1.4s},[x4],#16 + b.gt Loop_dec_iv_enc + + aese v6.16b,v0.16b + aesmc v6.16b,v6.16b + ld1 {v0.4s},[x4] + aese v6.16b,v1.16b + eor v6.16b,v6.16b,v0.16b + + // The iv for second block + // x9- iv(low), x10 - iv(high) + // the five ivs stored into, v6.16b,v8.16b,v9.16b,v10.16b,v11.16b + fmov x9,d6 + fmov x10,v6.d[1] + mov w19,#0x87 + extr x22,x10,x10,#32 + extr x10,x10,x9,#63 + and w11,w19,w22,asr #31 + eor x9,x11,x9,lsl #1 + fmov d8,x9 + fmov v8.d[1],x10 + + ldr w5,[x3,#240] // load rounds number + + // The iv for third block + extr x22,x10,x10,#32 + extr x10,x10,x9,#63 + and w11,w19,w22,asr #31 + eor x9,x11,x9,lsl #1 + fmov d9,x9 + fmov v9.d[1],x10 + + ld1 {v16.4s,v17.4s},[x3] // load key schedule... + sub w5,w5,#6 + add x7,x3,x5,lsl#4 // pointer to last 7 round keys + sub w5,w5,#2 + ld1 {v18.4s,v19.4s},[x7],#32 // load key schedule... + ld1 {v20.4s,v21.4s},[x7],#32 + ld1 {v22.4s,v23.4s},[x7],#32 + ld1 {v7.4s},[x7] + + // The iv for fourth block + extr x22,x10,x10,#32 + extr x10,x10,x9,#63 + and w11,w19,w22,asr #31 + eor x9,x11,x9,lsl #1 + fmov d10,x9 + fmov v10.d[1],x10 + + add x7,x3,#32 + mov w6,w5 + b Lxts_dec + + // Decryption +.align 5 +Lxts_dec: + tst x21,#0xf + b.eq Lxts_dec_begin + subs x2,x2,#16 + csel x8,xzr,x8,eq + ld1 {v0.16b},[x0],#16 + b.lo Lxts_done + sub x0,x0,#16 +Lxts_dec_begin: + ld1 {v0.16b},[x0],x8 + subs x2,x2,#32 // bias + add w6,w5,#2 + orr v3.16b,v0.16b,v0.16b + orr v1.16b,v0.16b,v0.16b + orr v28.16b,v0.16b,v0.16b + ld1 {v24.16b},[x0],#16 + orr v27.16b,v24.16b,v24.16b + orr v29.16b,v24.16b,v24.16b + b.lo Lxts_inner_dec_tail + eor v0.16b,v0.16b,v6.16b // before decryt, xor with iv + eor v24.16b,v24.16b,v8.16b + + orr v1.16b,v24.16b,v24.16b + ld1 {v24.16b},[x0],#16 + orr v2.16b,v0.16b,v0.16b + orr v3.16b,v1.16b,v1.16b + eor v27.16b,v24.16b,v9.16b // third block xox with third iv + eor v24.16b,v24.16b,v9.16b + cmp x2,#32 + b.lo Lxts_outer_dec_tail + + ld1 {v25.16b},[x0],#16 + + // The iv for fifth block + extr x22,x10,x10,#32 + extr x10,x10,x9,#63 + and w11,w19,w22,asr #31 + eor x9,x11,x9,lsl #1 + fmov d11,x9 + fmov v11.d[1],x10 + + ld1 {v26.16b},[x0],#16 + eor v25.16b,v25.16b,v10.16b // the fourth block + eor v26.16b,v26.16b,v11.16b + sub x2,x2,#32 // bias + mov w6,w5 + b Loop5x_xts_dec + +.align 4 +Loop5x_xts_dec: + aesd v0.16b,v16.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v16.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v16.16b + aesimc v24.16b,v24.16b + aesd v25.16b,v16.16b + aesimc v25.16b,v25.16b + aesd v26.16b,v16.16b + aesimc v26.16b,v26.16b + ld1 {v16.4s},[x7],#16 // load key schedule... + subs w6,w6,#2 + aesd v0.16b,v17.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v17.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v17.16b + aesimc v24.16b,v24.16b + aesd v25.16b,v17.16b + aesimc v25.16b,v25.16b + aesd v26.16b,v17.16b + aesimc v26.16b,v26.16b + ld1 {v17.4s},[x7],#16 // load key schedule... + b.gt Loop5x_xts_dec + + aesd v0.16b,v16.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v16.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v16.16b + aesimc v24.16b,v24.16b + aesd v25.16b,v16.16b + aesimc v25.16b,v25.16b + aesd v26.16b,v16.16b + aesimc v26.16b,v26.16b + subs x2,x2,#0x50 // because Lxts_dec_tail4x + + aesd v0.16b,v17.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v17.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v17.16b + aesimc v24.16b,v24.16b + aesd v25.16b,v17.16b + aesimc v25.16b,v25.16b + aesd v26.16b,v17.16b + aesimc v26.16b,v26.16b + csel x6,xzr,x2,gt // borrow x6, w6, "gt" is not typo + mov x7,x3 + + aesd v0.16b,v18.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v18.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v18.16b + aesimc v24.16b,v24.16b + aesd v25.16b,v18.16b + aesimc v25.16b,v25.16b + aesd v26.16b,v18.16b + aesimc v26.16b,v26.16b + add x0,x0,x6 // x0 is adjusted in such way that + // at exit from the loop v1.16b-v26.16b + // are loaded with last "words" + add x6,x2,#0x60 // because Lxts_dec_tail4x + + aesd v0.16b,v19.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v19.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v19.16b + aesimc v24.16b,v24.16b + aesd v25.16b,v19.16b + aesimc v25.16b,v25.16b + aesd v26.16b,v19.16b + aesimc v26.16b,v26.16b + + aesd v0.16b,v20.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v20.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v20.16b + aesimc v24.16b,v24.16b + aesd v25.16b,v20.16b + aesimc v25.16b,v25.16b + aesd v26.16b,v20.16b + aesimc v26.16b,v26.16b + + aesd v0.16b,v21.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v21.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v21.16b + aesimc v24.16b,v24.16b + aesd v25.16b,v21.16b + aesimc v25.16b,v25.16b + aesd v26.16b,v21.16b + aesimc v26.16b,v26.16b + + aesd v0.16b,v22.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v22.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v22.16b + aesimc v24.16b,v24.16b + aesd v25.16b,v22.16b + aesimc v25.16b,v25.16b + aesd v26.16b,v22.16b + aesimc v26.16b,v26.16b + + eor v4.16b,v7.16b,v6.16b + aesd v0.16b,v23.16b + // The iv for first block of next iteration. + extr x22,x10,x10,#32 + extr x10,x10,x9,#63 + and w11,w19,w22,asr #31 + eor x9,x11,x9,lsl #1 + fmov d6,x9 + fmov v6.d[1],x10 + eor v5.16b,v7.16b,v8.16b + ld1 {v2.16b},[x0],#16 + aesd v1.16b,v23.16b + // The iv for second block + extr x22,x10,x10,#32 + extr x10,x10,x9,#63 + and w11,w19,w22,asr #31 + eor x9,x11,x9,lsl #1 + fmov d8,x9 + fmov v8.d[1],x10 + eor v17.16b,v7.16b,v9.16b + ld1 {v3.16b},[x0],#16 + aesd v24.16b,v23.16b + // The iv for third block + extr x22,x10,x10,#32 + extr x10,x10,x9,#63 + and w11,w19,w22,asr #31 + eor x9,x11,x9,lsl #1 + fmov d9,x9 + fmov v9.d[1],x10 + eor v30.16b,v7.16b,v10.16b + ld1 {v27.16b},[x0],#16 + aesd v25.16b,v23.16b + // The iv for fourth block + extr x22,x10,x10,#32 + extr x10,x10,x9,#63 + and w11,w19,w22,asr #31 + eor x9,x11,x9,lsl #1 + fmov d10,x9 + fmov v10.d[1],x10 + eor v31.16b,v7.16b,v11.16b + ld1 {v28.16b},[x0],#16 + aesd v26.16b,v23.16b + + // The iv for fifth block + extr x22,x10,x10,#32 + extr x10,x10,x9,#63 + and w11,w19,w22,asr #31 + eor x9,x11,x9,lsl #1 + fmov d11,x9 + fmov v11.d[1],x10 + + ld1 {v29.16b},[x0],#16 + cbz x6,Lxts_dec_tail4x + ld1 {v16.4s},[x7],#16 // re-pre-load rndkey[0] + eor v4.16b,v4.16b,v0.16b + eor v0.16b,v2.16b,v6.16b + eor v5.16b,v5.16b,v1.16b + eor v1.16b,v3.16b,v8.16b + eor v17.16b,v17.16b,v24.16b + eor v24.16b,v27.16b,v9.16b + eor v30.16b,v30.16b,v25.16b + eor v25.16b,v28.16b,v10.16b + eor v31.16b,v31.16b,v26.16b + st1 {v4.16b},[x1],#16 + eor v26.16b,v29.16b,v11.16b + st1 {v5.16b},[x1],#16 + mov w6,w5 + st1 {v17.16b},[x1],#16 + ld1 {v17.4s},[x7],#16 // re-pre-load rndkey[1] + st1 {v30.16b},[x1],#16 + st1 {v31.16b},[x1],#16 + b.hs Loop5x_xts_dec + + cmn x2,#0x10 + b.ne Loop5x_dec_after + // If x2(x2) equal to -0x10, the left blocks is 4. + // After specially processing, utilize the five blocks processing again. + // It will use the following IVs: v6.16b,v6.16b,v8.16b,v9.16b,v10.16b. + orr v11.16b,v10.16b,v10.16b + orr v10.16b,v9.16b,v9.16b + orr v9.16b,v8.16b,v8.16b + orr v8.16b,v6.16b,v6.16b + fmov x9,d11 + fmov x10,v11.d[1] + eor v0.16b,v6.16b,v2.16b + eor v1.16b,v8.16b,v3.16b + eor v24.16b,v27.16b,v9.16b + eor v25.16b,v28.16b,v10.16b + eor v26.16b,v29.16b,v11.16b + b.eq Loop5x_xts_dec + +Loop5x_dec_after: + add x2,x2,#0x50 + cbz x2,Lxts_done + + add w6,w5,#2 + subs x2,x2,#0x30 + b.lo Lxts_inner_dec_tail + + eor v0.16b,v6.16b,v27.16b + eor v1.16b,v8.16b,v28.16b + eor v24.16b,v29.16b,v9.16b + b Lxts_outer_dec_tail + +.align 4 +Lxts_dec_tail4x: + add x0,x0,#16 + tst x21,#0xf + eor v5.16b,v1.16b,v4.16b + st1 {v5.16b},[x1],#16 + eor v17.16b,v24.16b,v17.16b + st1 {v17.16b},[x1],#16 + eor v30.16b,v25.16b,v30.16b + eor v31.16b,v26.16b,v31.16b + st1 {v30.16b,v31.16b},[x1],#32 + + b.eq Lxts_dec_abort + ld1 {v0.4s},[x0],#16 + b Lxts_done +.align 4 +Lxts_outer_dec_tail: + aesd v0.16b,v16.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v16.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v16.16b + aesimc v24.16b,v24.16b + ld1 {v16.4s},[x7],#16 + subs w6,w6,#2 + aesd v0.16b,v17.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v17.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v17.16b + aesimc v24.16b,v24.16b + ld1 {v17.4s},[x7],#16 + b.gt Lxts_outer_dec_tail + + aesd v0.16b,v16.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v16.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v16.16b + aesimc v24.16b,v24.16b + eor v4.16b,v6.16b,v7.16b + subs x2,x2,#0x30 + // The iv for first block + fmov x9,d9 + fmov x10,v9.d[1] + mov w19,#0x87 + extr x22,x10,x10,#32 + extr x10,x10,x9,#63 + and w11,w19,w22,asr #31 + eor x9,x11,x9,lsl #1 + fmov d6,x9 + fmov v6.d[1],x10 + eor v5.16b,v8.16b,v7.16b + csel x6,x2,x6,lo // x6, w6, is zero at this point + aesd v0.16b,v17.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v17.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v17.16b + aesimc v24.16b,v24.16b + eor v17.16b,v9.16b,v7.16b + // The iv for second block + extr x22,x10,x10,#32 + extr x10,x10,x9,#63 + and w11,w19,w22,asr #31 + eor x9,x11,x9,lsl #1 + fmov d8,x9 + fmov v8.d[1],x10 + + add x6,x6,#0x20 + add x0,x0,x6 // x0 is adjusted to the last data + + mov x7,x3 + + // The iv for third block + extr x22,x10,x10,#32 + extr x10,x10,x9,#63 + and w11,w19,w22,asr #31 + eor x9,x11,x9,lsl #1 + fmov d9,x9 + fmov v9.d[1],x10 + + aesd v0.16b,v20.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v20.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v20.16b + aesimc v24.16b,v24.16b + aesd v0.16b,v21.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v21.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v21.16b + aesimc v24.16b,v24.16b + aesd v0.16b,v22.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v22.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v22.16b + aesimc v24.16b,v24.16b + ld1 {v27.16b},[x0],#16 + aesd v0.16b,v23.16b + aesd v1.16b,v23.16b + aesd v24.16b,v23.16b + ld1 {v16.4s},[x7],#16 // re-pre-load rndkey[0] + add w6,w5,#2 + eor v4.16b,v4.16b,v0.16b + eor v5.16b,v5.16b,v1.16b + eor v24.16b,v24.16b,v17.16b + ld1 {v17.4s},[x7],#16 // re-pre-load rndkey[1] + st1 {v4.16b},[x1],#16 + st1 {v5.16b},[x1],#16 + st1 {v24.16b},[x1],#16 + + cmn x2,#0x30 + add x2,x2,#0x30 + b.eq Lxts_done + sub x2,x2,#0x30 + orr v28.16b,v3.16b,v3.16b + orr v29.16b,v27.16b,v27.16b + nop + +Lxts_inner_dec_tail: + // x2 == -0x10 means two blocks left. + cmn x2,#0x10 + eor v1.16b,v28.16b,v6.16b + eor v24.16b,v29.16b,v8.16b + b.eq Lxts_dec_tail_loop + eor v24.16b,v29.16b,v6.16b +Lxts_dec_tail_loop: + aesd v1.16b,v16.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v16.16b + aesimc v24.16b,v24.16b + ld1 {v16.4s},[x7],#16 + subs w6,w6,#2 + aesd v1.16b,v17.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v17.16b + aesimc v24.16b,v24.16b + ld1 {v17.4s},[x7],#16 + b.gt Lxts_dec_tail_loop + + aesd v1.16b,v16.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v16.16b + aesimc v24.16b,v24.16b + aesd v1.16b,v17.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v17.16b + aesimc v24.16b,v24.16b + aesd v1.16b,v20.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v20.16b + aesimc v24.16b,v24.16b + cmn x2,#0x20 + aesd v1.16b,v21.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v21.16b + aesimc v24.16b,v24.16b + eor v5.16b,v6.16b,v7.16b + aesd v1.16b,v22.16b + aesimc v1.16b,v1.16b + aesd v24.16b,v22.16b + aesimc v24.16b,v24.16b + eor v17.16b,v8.16b,v7.16b + aesd v1.16b,v23.16b + aesd v24.16b,v23.16b + b.eq Lxts_dec_one + eor v5.16b,v5.16b,v1.16b + eor v17.16b,v17.16b,v24.16b + orr v6.16b,v9.16b,v9.16b + orr v8.16b,v10.16b,v10.16b + st1 {v5.16b},[x1],#16 + st1 {v17.16b},[x1],#16 + add x2,x2,#16 + b Lxts_done + +Lxts_dec_one: + eor v5.16b,v5.16b,v24.16b + orr v6.16b,v8.16b,v8.16b + orr v8.16b,v9.16b,v9.16b + st1 {v5.16b},[x1],#16 + add x2,x2,#32 + +Lxts_done: + tst x21,#0xf + b.eq Lxts_dec_abort + // Processing the last two blocks with cipher stealing. + mov x7,x3 + cbnz x2,Lxts_dec_1st_done + ld1 {v0.4s},[x0],#16 + + // Decrypt the last secod block to get the last plain text block +Lxts_dec_1st_done: + eor v26.16b,v0.16b,v8.16b + ldr w6,[x3,#240] + ld1 {v0.4s},[x3],#16 + sub w6,w6,#2 + ld1 {v1.4s},[x3],#16 +Loop_final_2nd_dec: + aesd v26.16b,v0.16b + aesimc v26.16b,v26.16b + ld1 {v0.4s},[x3],#16 // load key schedule... + subs w6,w6,#2 + aesd v26.16b,v1.16b + aesimc v26.16b,v26.16b + ld1 {v1.4s},[x3],#16 // load key schedule... + b.gt Loop_final_2nd_dec + + aesd v26.16b,v0.16b + aesimc v26.16b,v26.16b + ld1 {v0.4s},[x3] + aesd v26.16b,v1.16b + eor v26.16b,v26.16b,v0.16b + eor v26.16b,v26.16b,v8.16b + st1 {v26.16b},[x1] + + mov x20,x0 + add x13,x1,#16 + + // Composite the tailcnt "16 byte not aligned block" into the last second plain blocks + // to get the last encrypted block. +.composite_dec_loop: + subs x21,x21,#1 + ldrb w15,[x1,x21] + ldrb w14,[x20,x21] + strb w15,[x13,x21] + strb w14,[x1,x21] + b.gt .composite_dec_loop +Lxts_dec_load_done: + ld1 {v26.16b},[x1] + eor v26.16b,v26.16b,v6.16b + + // Decrypt the composite block to get the last second plain text block + ldr w6,[x7,#240] + ld1 {v0.16b},[x7],#16 + sub w6,w6,#2 + ld1 {v1.16b},[x7],#16 +Loop_final_dec: + aesd v26.16b,v0.16b + aesimc v26.16b,v26.16b + ld1 {v0.4s},[x7],#16 // load key schedule... + subs w6,w6,#2 + aesd v26.16b,v1.16b + aesimc v26.16b,v26.16b + ld1 {v1.4s},[x7],#16 // load key schedule... + b.gt Loop_final_dec + + aesd v26.16b,v0.16b + aesimc v26.16b,v26.16b + ld1 {v0.4s},[x7] + aesd v26.16b,v1.16b + eor v26.16b,v26.16b,v0.16b + eor v26.16b,v26.16b,v6.16b + st1 {v26.16b},[x1] + +Lxts_dec_abort: + ldp x21,x22,[sp,#48] + ldp d8,d9,[sp,#32] + ldp d10,d11,[sp,#16] + ldp x19,x20,[sp],#64 + +Lxts_dec_final_abort: + ret #if defined(__linux__) && defined(__ELF__) .section .note.GNU-stack,"",%progbits From 8579d6aecc3776c0fb3195dcd641927bc5270de3 Mon Sep 17 00:00:00 2001 From: Nevine Ebeid Date: Tue, 18 Mar 2025 10:41:21 -0400 Subject: [PATCH 004/132] The decrypt version is now from linux-aarch64. It's from AWS-LC's generated-src/linux-aarch64/crypto/fipsmodule/aesv8-armx.S It was previously taken from win-aarch64. --- arm/aes-xts/aes-xts-armv8.S | 117 ++++++++++++++++++------------------ 1 file changed, 60 insertions(+), 57 deletions(-) diff --git a/arm/aes-xts/aes-xts-armv8.S b/arm/aes-xts/aes-xts-armv8.S index ca34d8484..8c6587053 100644 --- a/arm/aes-xts/aes-xts-armv8.S +++ b/arm/aes-xts/aes-xts-armv8.S @@ -648,10 +648,13 @@ aes_hw_xts_encrypt: .Lxts_enc_final_abort: ret +# Decrypt is taken from +# https://github.com/aws/aws-lc/blob/804a11b6f965365156b0a8b6d958233e1372a2e2/generated-src/linux-aarch64/crypto/fipsmodule/aesv8-armx.S#L1475 + aes_hw_xts_decrypt: - cmp x2,#16 + cmp x2,#16 // Original input data size bigger than 16, jump to big size processing. - b.ne Lxts_dec_big_size + b.ne .Lxts_dec_big_size // Encrypt the iv with key2, as the first XEX iv. ldr w6,[x4,#240] ld1 {v0.16b},[x4],#16 @@ -659,7 +662,7 @@ aes_hw_xts_decrypt: sub w6,w6,#2 ld1 {v1.16b},[x4],#16 -Loop_dec_small_iv_enc: +.Loop_dec_small_iv_enc: aese v6.16b,v0.16b aesmc v6.16b,v6.16b ld1 {v0.4s},[x4],#16 @@ -667,7 +670,7 @@ Loop_dec_small_iv_enc: aese v6.16b,v1.16b aesmc v6.16b,v6.16b ld1 {v1.4s},[x4],#16 - b.gt Loop_dec_small_iv_enc + b.gt .Loop_dec_small_iv_enc aese v6.16b,v0.16b aesmc v6.16b,v6.16b @@ -687,8 +690,8 @@ Loop_dec_small_iv_enc: aesd v0.16b,v29.16b aesimc v0.16b,v0.16b subs w6,w6,#10 // bias - b.eq Lxts_128_dec -Lxts_dec_round_loop: + b.eq .Lxts_128_dec +.Lxts_dec_round_loop: aesd v0.16b,v16.16b aesimc v0.16b,v0.16b ld1 {v16.4s},[x3],#16 // load key schedule... @@ -696,8 +699,8 @@ Lxts_dec_round_loop: aesimc v0.16b,v0.16b ld1 {v17.4s},[x3],#16 // load key schedule... subs w6,w6,#2 // bias - b.gt Lxts_dec_round_loop -Lxts_128_dec: + b.gt .Lxts_dec_round_loop +.Lxts_128_dec: ld1 {v18.4s,v19.4s},[x3],#32 // load key schedule... aesd v0.16b,v16.16b aesimc v0.16b,v0.16b @@ -720,8 +723,8 @@ Lxts_128_dec: eor v0.16b,v0.16b,v7.16b eor v0.16b,v6.16b,v0.16b st1 {v0.16b},[x1] - b Lxts_dec_final_abort -Lxts_dec_big_size: + b .Lxts_dec_final_abort +.Lxts_dec_big_size: stp x19,x20,[sp,#-64]! stp x21,x22,[sp,#48] stp d8,d9,[sp,#32] @@ -731,7 +734,7 @@ Lxts_dec_big_size: and x2,x2,#-16 subs x2,x2,#16 mov x8,#16 - b.lo Lxts_dec_abort + b.lo .Lxts_dec_abort // Encrypt the iv with key2, as the first XEX iv ldr w6,[x4,#240] @@ -740,7 +743,7 @@ Lxts_dec_big_size: sub w6,w6,#2 ld1 {v1.16b},[x4],#16 -Loop_dec_iv_enc: +.Loop_dec_iv_enc: aese v6.16b,v0.16b aesmc v6.16b,v6.16b ld1 {v0.4s},[x4],#16 @@ -748,7 +751,7 @@ Loop_dec_iv_enc: aese v6.16b,v1.16b aesmc v6.16b,v6.16b ld1 {v1.4s},[x4],#16 - b.gt Loop_dec_iv_enc + b.gt .Loop_dec_iv_enc aese v6.16b,v0.16b aesmc v6.16b,v6.16b @@ -798,19 +801,19 @@ Loop_dec_iv_enc: add x7,x3,#32 mov w6,w5 - b Lxts_dec + b .Lxts_dec // Decryption .align 5 -Lxts_dec: +.Lxts_dec: tst x21,#0xf - b.eq Lxts_dec_begin + b.eq .Lxts_dec_begin subs x2,x2,#16 csel x8,xzr,x8,eq ld1 {v0.16b},[x0],#16 - b.lo Lxts_done + b.lo .Lxts_done sub x0,x0,#16 -Lxts_dec_begin: +.Lxts_dec_begin: ld1 {v0.16b},[x0],x8 subs x2,x2,#32 // bias add w6,w5,#2 @@ -820,7 +823,7 @@ Lxts_dec_begin: ld1 {v24.16b},[x0],#16 orr v27.16b,v24.16b,v24.16b orr v29.16b,v24.16b,v24.16b - b.lo Lxts_inner_dec_tail + b.lo .Lxts_inner_dec_tail eor v0.16b,v0.16b,v6.16b // before decryt, xor with iv eor v24.16b,v24.16b,v8.16b @@ -831,7 +834,7 @@ Lxts_dec_begin: eor v27.16b,v24.16b,v9.16b // third block xox with third iv eor v24.16b,v24.16b,v9.16b cmp x2,#32 - b.lo Lxts_outer_dec_tail + b.lo .Lxts_outer_dec_tail ld1 {v25.16b},[x0],#16 @@ -848,10 +851,10 @@ Lxts_dec_begin: eor v26.16b,v26.16b,v11.16b sub x2,x2,#32 // bias mov w6,w5 - b Loop5x_xts_dec + b .Loop5x_xts_dec .align 4 -Loop5x_xts_dec: +.Loop5x_xts_dec: aesd v0.16b,v16.16b aesimc v0.16b,v0.16b aesd v1.16b,v16.16b @@ -875,7 +878,7 @@ Loop5x_xts_dec: aesd v26.16b,v17.16b aesimc v26.16b,v26.16b ld1 {v17.4s},[x7],#16 // load key schedule... - b.gt Loop5x_xts_dec + b.gt .Loop5x_xts_dec aesd v0.16b,v16.16b aesimc v0.16b,v0.16b @@ -887,7 +890,7 @@ Loop5x_xts_dec: aesimc v25.16b,v25.16b aesd v26.16b,v16.16b aesimc v26.16b,v26.16b - subs x2,x2,#0x50 // because Lxts_dec_tail4x + subs x2,x2,#0x50 // because .Lxts_dec_tail4x aesd v0.16b,v17.16b aesimc v0.16b,v0.16b @@ -915,7 +918,7 @@ Loop5x_xts_dec: add x0,x0,x6 // x0 is adjusted in such way that // at exit from the loop v1.16b-v26.16b // are loaded with last "words" - add x6,x2,#0x60 // because Lxts_dec_tail4x + add x6,x2,#0x60 // because .Lxts_dec_tail4x aesd v0.16b,v19.16b aesimc v0.16b,v0.16b @@ -1013,7 +1016,7 @@ Loop5x_xts_dec: fmov v11.d[1],x10 ld1 {v29.16b},[x0],#16 - cbz x6,Lxts_dec_tail4x + cbz x6,.Lxts_dec_tail4x ld1 {v16.4s},[x7],#16 // re-pre-load rndkey[0] eor v4.16b,v4.16b,v0.16b eor v0.16b,v2.16b,v6.16b @@ -1032,10 +1035,10 @@ Loop5x_xts_dec: ld1 {v17.4s},[x7],#16 // re-pre-load rndkey[1] st1 {v30.16b},[x1],#16 st1 {v31.16b},[x1],#16 - b.hs Loop5x_xts_dec + b.hs .Loop5x_xts_dec cmn x2,#0x10 - b.ne Loop5x_dec_after + b.ne .Loop5x_dec_after // If x2(x2) equal to -0x10, the left blocks is 4. // After specially processing, utilize the five blocks processing again. // It will use the following IVs: v6.16b,v6.16b,v8.16b,v9.16b,v10.16b. @@ -1050,23 +1053,23 @@ Loop5x_xts_dec: eor v24.16b,v27.16b,v9.16b eor v25.16b,v28.16b,v10.16b eor v26.16b,v29.16b,v11.16b - b.eq Loop5x_xts_dec + b.eq .Loop5x_xts_dec -Loop5x_dec_after: +.Loop5x_dec_after: add x2,x2,#0x50 - cbz x2,Lxts_done + cbz x2,.Lxts_done add w6,w5,#2 subs x2,x2,#0x30 - b.lo Lxts_inner_dec_tail + b.lo .Lxts_inner_dec_tail eor v0.16b,v6.16b,v27.16b eor v1.16b,v8.16b,v28.16b eor v24.16b,v29.16b,v9.16b - b Lxts_outer_dec_tail + b .Lxts_outer_dec_tail .align 4 -Lxts_dec_tail4x: +.Lxts_dec_tail4x: add x0,x0,#16 tst x21,#0xf eor v5.16b,v1.16b,v4.16b @@ -1077,11 +1080,11 @@ Lxts_dec_tail4x: eor v31.16b,v26.16b,v31.16b st1 {v30.16b,v31.16b},[x1],#32 - b.eq Lxts_dec_abort + b.eq .Lxts_dec_abort ld1 {v0.4s},[x0],#16 - b Lxts_done + b .Lxts_done .align 4 -Lxts_outer_dec_tail: +.Lxts_outer_dec_tail: aesd v0.16b,v16.16b aesimc v0.16b,v0.16b aesd v1.16b,v16.16b @@ -1097,7 +1100,7 @@ Lxts_outer_dec_tail: aesd v24.16b,v17.16b aesimc v24.16b,v24.16b ld1 {v17.4s},[x7],#16 - b.gt Lxts_outer_dec_tail + b.gt .Lxts_outer_dec_tail aesd v0.16b,v16.16b aesimc v0.16b,v0.16b @@ -1181,20 +1184,20 @@ Lxts_outer_dec_tail: cmn x2,#0x30 add x2,x2,#0x30 - b.eq Lxts_done + b.eq .Lxts_done sub x2,x2,#0x30 orr v28.16b,v3.16b,v3.16b orr v29.16b,v27.16b,v27.16b nop -Lxts_inner_dec_tail: +.Lxts_inner_dec_tail: // x2 == -0x10 means two blocks left. cmn x2,#0x10 eor v1.16b,v28.16b,v6.16b eor v24.16b,v29.16b,v8.16b - b.eq Lxts_dec_tail_loop + b.eq .Lxts_dec_tail_loop eor v24.16b,v29.16b,v6.16b -Lxts_dec_tail_loop: +.Lxts_dec_tail_loop: aesd v1.16b,v16.16b aesimc v1.16b,v1.16b aesd v24.16b,v16.16b @@ -1206,7 +1209,7 @@ Lxts_dec_tail_loop: aesd v24.16b,v17.16b aesimc v24.16b,v24.16b ld1 {v17.4s},[x7],#16 - b.gt Lxts_dec_tail_loop + b.gt .Lxts_dec_tail_loop aesd v1.16b,v16.16b aesimc v1.16b,v1.16b @@ -1233,7 +1236,7 @@ Lxts_dec_tail_loop: eor v17.16b,v8.16b,v7.16b aesd v1.16b,v23.16b aesd v24.16b,v23.16b - b.eq Lxts_dec_one + b.eq .Lxts_dec_one eor v5.16b,v5.16b,v1.16b eor v17.16b,v17.16b,v24.16b orr v6.16b,v9.16b,v9.16b @@ -1241,31 +1244,31 @@ Lxts_dec_tail_loop: st1 {v5.16b},[x1],#16 st1 {v17.16b},[x1],#16 add x2,x2,#16 - b Lxts_done + b .Lxts_done -Lxts_dec_one: +.Lxts_dec_one: eor v5.16b,v5.16b,v24.16b orr v6.16b,v8.16b,v8.16b orr v8.16b,v9.16b,v9.16b st1 {v5.16b},[x1],#16 add x2,x2,#32 -Lxts_done: +.Lxts_done: tst x21,#0xf - b.eq Lxts_dec_abort + b.eq .Lxts_dec_abort // Processing the last two blocks with cipher stealing. mov x7,x3 - cbnz x2,Lxts_dec_1st_done + cbnz x2,.Lxts_dec_1st_done ld1 {v0.4s},[x0],#16 // Decrypt the last secod block to get the last plain text block -Lxts_dec_1st_done: +.Lxts_dec_1st_done: eor v26.16b,v0.16b,v8.16b ldr w6,[x3,#240] ld1 {v0.4s},[x3],#16 sub w6,w6,#2 ld1 {v1.4s},[x3],#16 -Loop_final_2nd_dec: +.Loop_final_2nd_dec: aesd v26.16b,v0.16b aesimc v26.16b,v26.16b ld1 {v0.4s},[x3],#16 // load key schedule... @@ -1273,7 +1276,7 @@ Loop_final_2nd_dec: aesd v26.16b,v1.16b aesimc v26.16b,v26.16b ld1 {v1.4s},[x3],#16 // load key schedule... - b.gt Loop_final_2nd_dec + b.gt .Loop_final_2nd_dec aesd v26.16b,v0.16b aesimc v26.16b,v26.16b @@ -1295,7 +1298,7 @@ Loop_final_2nd_dec: strb w15,[x13,x21] strb w14,[x1,x21] b.gt .composite_dec_loop -Lxts_dec_load_done: +.Lxts_dec_load_done: ld1 {v26.16b},[x1] eor v26.16b,v26.16b,v6.16b @@ -1304,7 +1307,7 @@ Lxts_dec_load_done: ld1 {v0.16b},[x7],#16 sub w6,w6,#2 ld1 {v1.16b},[x7],#16 -Loop_final_dec: +.Loop_final_dec: aesd v26.16b,v0.16b aesimc v26.16b,v26.16b ld1 {v0.4s},[x7],#16 // load key schedule... @@ -1312,7 +1315,7 @@ Loop_final_dec: aesd v26.16b,v1.16b aesimc v26.16b,v26.16b ld1 {v1.4s},[x7],#16 // load key schedule... - b.gt Loop_final_dec + b.gt .Loop_final_dec aesd v26.16b,v0.16b aesimc v26.16b,v26.16b @@ -1322,13 +1325,13 @@ Loop_final_dec: eor v26.16b,v26.16b,v6.16b st1 {v26.16b},[x1] -Lxts_dec_abort: +.Lxts_dec_abort: ldp x21,x22,[sp,#48] ldp d8,d9,[sp,#32] ldp d10,d11,[sp,#16] ldp x19,x20,[sp],#64 -Lxts_dec_final_abort: +.Lxts_dec_final_abort: ret #if defined(__linux__) && defined(__ELF__) From b246573513ccf1c5ab04a98c1c1e3b8dbc123470 Mon Sep 17 00:00:00 2001 From: Nevine Ebeid Date: Thu, 20 Mar 2025 17:21:50 -0400 Subject: [PATCH 005/132] enable stopping at first error. --- arm/proofs/{aes-xts.ml => aes-xts-armv8.ml} | 2 ++ 1 file changed, 2 insertions(+) rename arm/proofs/{aes-xts.ml => aes-xts-armv8.ml} (86%) diff --git a/arm/proofs/aes-xts.ml b/arm/proofs/aes-xts-armv8.ml similarity index 86% rename from arm/proofs/aes-xts.ml rename to arm/proofs/aes-xts-armv8.ml index 8a245be7a..4b4df2eb9 100644 --- a/arm/proofs/aes-xts.ml +++ b/arm/proofs/aes-xts-armv8.ml @@ -3,6 +3,8 @@ * SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT-0 *) +use_file_raise_failure := true;; + needs "arm/proofs/base.ml";; print_literal_from_elf "arm/aes-xts/aes-xts-armv8.o";; From e17e78857ef1ea4bf3c2de0934da69b5699fb2a8 Mon Sep 17 00:00:00 2001 From: Nevine Ebeid Date: Fri, 21 Mar 2025 11:41:20 -0400 Subject: [PATCH 006/132] Save decoded output to a text file. --- arm/aes-xts/aes-xts-armv8.txt | 1124 +++++++++++++++++++++++++++++++++ arm/proofs/aes-xts-armv8.ml | 5 +- 2 files changed, 1128 insertions(+), 1 deletion(-) create mode 100644 arm/aes-xts/aes-xts-armv8.txt diff --git a/arm/aes-xts/aes-xts-armv8.txt b/arm/aes-xts/aes-xts-armv8.txt new file mode 100644 index 000000000..16e1b3ad7 --- /dev/null +++ b/arm/aes-xts/aes-xts-armv8.txt @@ -0,0 +1,1124 @@ +[ + 0xf100405f; (* arm_CMP X2 (rvalue (word 16)) *) + 0x540007e1; (* arm_BNE (word 252) *) + 0xb940f086; (* arm_LDR W6 X4 (Immediate_Offset (word 240)) *) + 0x4cdf7080; (* arm_LDR Q0 X4 (Postimmediate_Offset (word 16)) *) + 0x4c4070a6; (* arm_LDR Q6 X5 No_Offset *) + 0x510008c6; (* arm_SUB W6 W6 (rvalue (word 2)) *) + 0x4cdf7081; (* arm_LDR Q1 X4 (Postimmediate_Offset (word 16)) *) + 0x4e284806; (* arm_AESE Q6 Q0 *) + 0x4e2868c6; (* arm_AESMC Q6 Q6 *) + 0x4cdf7880; (* arm_LDR Q0 X4 (Postimmediate_Offset (word 16)) *) + 0x710008c6; (* arm_SUBS W6 W6 (rvalue (word 2)) *) + 0x4e284826; (* arm_AESE Q6 Q1 *) + 0x4e2868c6; (* arm_AESMC Q6 Q6 *) + 0x4cdf7881; (* arm_LDR Q1 X4 (Postimmediate_Offset (word 16)) *) + 0x54ffff2c; (* arm_BGT (word 2097124) *) + 0x4e284806; (* arm_AESE Q6 Q0 *) + 0x4e2868c6; (* arm_AESMC Q6 Q6 *) + 0x4c407880; (* arm_LDR Q0 X4 No_Offset *) + 0x4e284826; (* arm_AESE Q6 Q1 *) + 0x6e201cc6; (* arm_EOR_VEC Q6 Q6 Q0 128 *) + 0x4c407000; (* arm_LDR Q0 X0 No_Offset *) + 0x6e201cc0; (* arm_EOR_VEC Q0 Q6 Q0 128 *) + 0xb940f066; (* arm_LDR W6 X3 (Immediate_Offset (word 240)) *) + 0x4cdfa87c; (* arm_ldstp_2q true (word 28) X3 (Postimmediate_Offset (word 32)) *) + 0x4e284b80; (* arm_AESE Q0 Q28 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4cdfa870; (* arm_ldstp_2q true (word 16) X3 (Postimmediate_Offset (word 32)) *) + 0x4e284ba0; (* arm_AESE Q0 Q29 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x710028c6; (* arm_SUBS W6 W6 (rvalue (word 10)) *) + 0x54000120; (* arm_BEQ (word 36) *) + 0x4e284a00; (* arm_AESE Q0 Q16 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4cdf7870; (* arm_LDR Q16 X3 (Postimmediate_Offset (word 16)) *) + 0x4e284a20; (* arm_AESE Q0 Q17 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4cdf7871; (* arm_LDR Q17 X3 (Postimmediate_Offset (word 16)) *) + 0x710008c6; (* arm_SUBS W6 W6 (rvalue (word 2)) *) + 0x54ffff2c; (* arm_BGT (word 2097124) *) + 0x4cdfa872; (* arm_ldstp_2q true (word 18) X3 (Postimmediate_Offset (word 32)) *) + 0x4e284a00; (* arm_AESE Q0 Q16 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e284a20; (* arm_AESE Q0 Q17 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4cdfa874; (* arm_ldstp_2q true (word 20) X3 (Postimmediate_Offset (word 32)) *) + 0x4e284a40; (* arm_AESE Q0 Q18 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e284a60; (* arm_AESE Q0 Q19 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4cdfa876; (* arm_ldstp_2q true (word 22) X3 (Postimmediate_Offset (word 32)) *) + 0x4e284a80; (* arm_AESE Q0 Q20 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e284aa0; (* arm_AESE Q0 Q21 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4c407867; (* arm_LDR Q7 X3 No_Offset *) + 0x4e284ac0; (* arm_AESE Q0 Q22 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e284ae0; (* arm_AESE Q0 Q23 *) + 0x6e271c00; (* arm_EOR_VEC Q0 Q0 Q7 128 *) + 0x6e261c00; (* arm_EOR_VEC Q0 Q0 Q6 128 *) + 0x4c007020; (* arm_STR Q0 X1 No_Offset *) + 0x140001e7; (* arm_B (word 1948) *) + 0xd503201f; (* arm_NOP *) + 0xd503201f; (* arm_NOP *) + 0xa9bc53f3; (* arm_STP X19 X20 SP (Preimmediate_Offset (iword (-- &64))) *) + 0xa9035bf5; (* arm_STP X21 X22 SP (Immediate_Offset (iword (&48))) *) + 0x6d0227e8; (* arm_STP D8 D9 SP (Immediate_Offset (iword (&32))) *) + 0x6d012fea; (* arm_STP D10 D11 SP (Immediate_Offset (iword (&16))) *) + 0x92400c55; (* arm_AND X21 X2 (rvalue (word 15)) *) + 0x927cec42; (* arm_AND X2 X2 (rvalue (word 18446744073709551600)) *) + 0xf1004042; (* arm_SUBS X2 X2 (rvalue (word 16)) *) + 0xd2800208; (* arm_MOV X8 (rvalue (word 16)) *) + 0x54003b03; (* arm_BCC (word 1888) *) + 0x9a8803e8; (* arm_CSEL X8 XZR X8 Condition_EQ *) + 0xb940f086; (* arm_LDR W6 X4 (Immediate_Offset (word 240)) *) + 0x4cdf7880; (* arm_LDR Q0 X4 (Postimmediate_Offset (word 16)) *) + 0x4c4070a6; (* arm_LDR Q6 X5 No_Offset *) + 0x510008c6; (* arm_SUB W6 W6 (rvalue (word 2)) *) + 0x4cdf7881; (* arm_LDR Q1 X4 (Postimmediate_Offset (word 16)) *) + 0x4e284806; (* arm_AESE Q6 Q0 *) + 0x4e2868c6; (* arm_AESMC Q6 Q6 *) + 0x4cdf7880; (* arm_LDR Q0 X4 (Postimmediate_Offset (word 16)) *) + 0x710008c6; (* arm_SUBS W6 W6 (rvalue (word 2)) *) + 0x4e284826; (* arm_AESE Q6 Q1 *) + 0x4e2868c6; (* arm_AESMC Q6 Q6 *) + 0x4cdf7881; (* arm_LDR Q1 X4 (Postimmediate_Offset (word 16)) *) + 0x54ffff2c; (* arm_BGT (word 2097124) *) + 0x4e284806; (* arm_AESE Q6 Q0 *) + 0x4e2868c6; (* arm_AESMC Q6 Q6 *) + 0x4c407880; (* arm_LDR Q0 X4 No_Offset *) + 0x4e284826; (* arm_AESE Q6 Q1 *) + 0x6e201cc6; (* arm_EOR_VEC Q6 Q6 Q0 128 *) + 0x9e6600c9; (* arm_FMOV_FtoI X9 Q6 0 *) + 0x9eae00ca; (* arm_FMOV_FtoI X10 Q6 1 *) + 0x528010f3; (* arm_MOV W19 (rvalue (word 135)) *) + 0x93ca8156; (* arm_ROR X22 X10 32 *) + 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) + 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 31) *) + 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 1) *) + 0x9e670128; (* arm_FMOV_ItoF Q8 X9 0 *) + 0x9eaf0148; (* arm_FMOV_ItoF Q8 X10 1 *) + 0xb940f065; (* arm_LDR W5 X3 (Immediate_Offset (word 240)) *) + 0x4cc87000; (* arm_LDR Q0 X0 (Register_Offset X8) *) + 0x4c40a870; (* arm_ldstp_2q true (word 16) X3 No_Offset *) + 0x510018a5; (* arm_SUB W5 W5 (rvalue (word 6)) *) + 0x8b051067; (* arm_ADD X7 X3 (Shiftedreg X5 LSL 4) *) + 0x510008a5; (* arm_SUB W5 W5 (rvalue (word 2)) *) + 0x4cdfa8f2; (* arm_ldstp_2q true (word 18) X7 (Postimmediate_Offset (word 32)) *) + 0x4cdfa8f4; (* arm_ldstp_2q true (word 20) X7 (Postimmediate_Offset (word 32)) *) + 0x4cdfa8f6; (* arm_ldstp_2q true (word 22) X7 (Postimmediate_Offset (word 32)) *) + 0x4c4078e7; (* arm_LDR Q7 X7 No_Offset *) + 0x91008067; (* arm_ADD X7 X3 (rvalue (word 32)) *) + 0x2a0503e6; (* arm_MOV W6 W5 *) + 0x4cdf7018; (* arm_LDR Q24 X0 (Postimmediate_Offset (word 16)) *) + 0xf1008042; (* arm_SUBS X2 X2 (rvalue (word 32)) *) + 0x110008a6; (* arm_ADD W6 W5 (rvalue (word 2)) *) + 0x4ea01c03; (* arm_MOV_VEC Q3 Q0 128 *) + 0x4ea01c01; (* arm_MOV_VEC Q1 Q0 128 *) + 0x4ea01c1c; (* arm_MOV_VEC Q28 Q0 128 *) + 0x4eb81f1b; (* arm_MOV_VEC Q27 Q24 128 *) + 0x4eb81f1d; (* arm_MOV_VEC Q29 Q24 128 *) + 0x540027e3; (* arm_BCC (word 1276) *) + 0x6e261c00; (* arm_EOR_VEC Q0 Q0 Q6 128 *) + 0x6e281f18; (* arm_EOR_VEC Q24 Q24 Q8 128 *) + 0x93ca8156; (* arm_ROR X22 X10 32 *) + 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) + 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 31) *) + 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 1) *) + 0x9e670129; (* arm_FMOV_ItoF Q9 X9 0 *) + 0x9eaf0149; (* arm_FMOV_ItoF Q9 X10 1 *) + 0x4eb81f01; (* arm_MOV_VEC Q1 Q24 128 *) + 0x4cdf7018; (* arm_LDR Q24 X0 (Postimmediate_Offset (word 16)) *) + 0x4ea01c02; (* arm_MOV_VEC Q2 Q0 128 *) + 0x4ea11c23; (* arm_MOV_VEC Q3 Q1 128 *) + 0x6e291f1b; (* arm_EOR_VEC Q27 Q24 Q9 128 *) + 0x6e291f18; (* arm_EOR_VEC Q24 Q24 Q9 128 *) + 0xf100805f; (* arm_CMP X2 (rvalue (word 32)) *) + 0x54001be3; (* arm_BCC (word 892) *) + 0x93ca8156; (* arm_ROR X22 X10 32 *) + 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) + 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 31) *) + 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 1) *) + 0x9e67012a; (* arm_FMOV_ItoF Q10 X9 0 *) + 0x9eaf014a; (* arm_FMOV_ItoF Q10 X10 1 *) + 0x4cdf7019; (* arm_LDR Q25 X0 (Postimmediate_Offset (word 16)) *) + 0x93ca8156; (* arm_ROR X22 X10 32 *) + 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) + 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 31) *) + 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 1) *) + 0x9e67012b; (* arm_FMOV_ItoF Q11 X9 0 *) + 0x9eaf014b; (* arm_FMOV_ItoF Q11 X10 1 *) + 0x4cdf701a; (* arm_LDR Q26 X0 (Postimmediate_Offset (word 16)) *) + 0x6e2a1f39; (* arm_EOR_VEC Q25 Q25 Q10 128 *) + 0x6e2b1f5a; (* arm_EOR_VEC Q26 Q26 Q11 128 *) + 0xd1008042; (* arm_SUB X2 X2 (rvalue (word 32)) *) + 0x2a0503e6; (* arm_MOV W6 W5 *) + 0x14000004; (* arm_B (word 16) *) + 0xd503201f; (* arm_NOP *) + 0xd503201f; (* arm_NOP *) + 0xd503201f; (* arm_NOP *) + 0x4e284a00; (* arm_AESE Q0 Q16 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e284a01; (* arm_AESE Q1 Q16 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e284a18; (* arm_AESE Q24 Q16 *) + 0x4e286b18; (* arm_AESMC Q24 Q24 *) + 0x4e284a19; (* arm_AESE Q25 Q16 *) + 0x4e286b39; (* arm_AESMC Q25 Q25 *) + 0x4e284a1a; (* arm_AESE Q26 Q16 *) + 0x4e286b5a; (* arm_AESMC Q26 Q26 *) + 0x4cdf78f0; (* arm_LDR Q16 X7 (Postimmediate_Offset (word 16)) *) + 0x710008c6; (* arm_SUBS W6 W6 (rvalue (word 2)) *) + 0x4e284a20; (* arm_AESE Q0 Q17 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e284a21; (* arm_AESE Q1 Q17 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e284a38; (* arm_AESE Q24 Q17 *) + 0x4e286b18; (* arm_AESMC Q24 Q24 *) + 0x4e284a39; (* arm_AESE Q25 Q17 *) + 0x4e286b39; (* arm_AESMC Q25 Q25 *) + 0x4e284a3a; (* arm_AESE Q26 Q17 *) + 0x4e286b5a; (* arm_AESMC Q26 Q26 *) + 0x4cdf78f1; (* arm_LDR Q17 X7 (Postimmediate_Offset (word 16)) *) + 0x54fffd2c; (* arm_BGT (word 2097060) *) + 0x4e284a00; (* arm_AESE Q0 Q16 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e284a01; (* arm_AESE Q1 Q16 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e284a18; (* arm_AESE Q24 Q16 *) + 0x4e286b18; (* arm_AESMC Q24 Q24 *) + 0x4e284a19; (* arm_AESE Q25 Q16 *) + 0x4e286b39; (* arm_AESMC Q25 Q25 *) + 0x4e284a1a; (* arm_AESE Q26 Q16 *) + 0x4e286b5a; (* arm_AESMC Q26 Q26 *) + 0xf1014042; (* arm_SUBS X2 X2 (rvalue (word 80)) *) + 0x4e284a20; (* arm_AESE Q0 Q17 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e284a21; (* arm_AESE Q1 Q17 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e284a38; (* arm_AESE Q24 Q17 *) + 0x4e286b18; (* arm_AESMC Q24 Q24 *) + 0x4e284a39; (* arm_AESE Q25 Q17 *) + 0x4e286b39; (* arm_AESMC Q25 Q25 *) + 0x4e284a3a; (* arm_AESE Q26 Q17 *) + 0x4e286b5a; (* arm_AESMC Q26 Q26 *) + 0x9a82c3e6; (* arm_CSEL X6 XZR X2 Condition_GT *) + 0xaa0303e7; (* arm_MOV X7 X3 *) + 0x4e284a40; (* arm_AESE Q0 Q18 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e284a41; (* arm_AESE Q1 Q18 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e284a58; (* arm_AESE Q24 Q18 *) + 0x4e286b18; (* arm_AESMC Q24 Q24 *) + 0x4e284a59; (* arm_AESE Q25 Q18 *) + 0x4e286b39; (* arm_AESMC Q25 Q25 *) + 0x4e284a5a; (* arm_AESE Q26 Q18 *) + 0x4e286b5a; (* arm_AESMC Q26 Q26 *) + 0x8b060000; (* arm_ADD X0 X0 X6 *) + 0x91018046; (* arm_ADD X6 X2 (rvalue (word 96)) *) + 0x4e284a60; (* arm_AESE Q0 Q19 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e284a61; (* arm_AESE Q1 Q19 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e284a78; (* arm_AESE Q24 Q19 *) + 0x4e286b18; (* arm_AESMC Q24 Q24 *) + 0x4e284a79; (* arm_AESE Q25 Q19 *) + 0x4e286b39; (* arm_AESMC Q25 Q25 *) + 0x4e284a7a; (* arm_AESE Q26 Q19 *) + 0x4e286b5a; (* arm_AESMC Q26 Q26 *) + 0x4e284a80; (* arm_AESE Q0 Q20 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e284a81; (* arm_AESE Q1 Q20 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e284a98; (* arm_AESE Q24 Q20 *) + 0x4e286b18; (* arm_AESMC Q24 Q24 *) + 0x4e284a99; (* arm_AESE Q25 Q20 *) + 0x4e286b39; (* arm_AESMC Q25 Q25 *) + 0x4e284a9a; (* arm_AESE Q26 Q20 *) + 0x4e286b5a; (* arm_AESMC Q26 Q26 *) + 0x4e284aa0; (* arm_AESE Q0 Q21 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e284aa1; (* arm_AESE Q1 Q21 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e284ab8; (* arm_AESE Q24 Q21 *) + 0x4e286b18; (* arm_AESMC Q24 Q24 *) + 0x4e284ab9; (* arm_AESE Q25 Q21 *) + 0x4e286b39; (* arm_AESMC Q25 Q25 *) + 0x4e284aba; (* arm_AESE Q26 Q21 *) + 0x4e286b5a; (* arm_AESMC Q26 Q26 *) + 0x4e284ac0; (* arm_AESE Q0 Q22 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e284ac1; (* arm_AESE Q1 Q22 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e284ad8; (* arm_AESE Q24 Q22 *) + 0x4e286b18; (* arm_AESMC Q24 Q24 *) + 0x4e284ad9; (* arm_AESE Q25 Q22 *) + 0x4e286b39; (* arm_AESMC Q25 Q25 *) + 0x4e284ada; (* arm_AESE Q26 Q22 *) + 0x4e286b5a; (* arm_AESMC Q26 Q26 *) + 0x6e261ce4; (* arm_EOR_VEC Q4 Q7 Q6 128 *) + 0x4e284ae0; (* arm_AESE Q0 Q23 *) + 0x93ca8156; (* arm_ROR X22 X10 32 *) + 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) + 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 31) *) + 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 1) *) + 0x9e670126; (* arm_FMOV_ItoF Q6 X9 0 *) + 0x9eaf0146; (* arm_FMOV_ItoF Q6 X10 1 *) + 0x6e281ce5; (* arm_EOR_VEC Q5 Q7 Q8 128 *) + 0x4cdf7002; (* arm_LDR Q2 X0 (Postimmediate_Offset (word 16)) *) + 0x4e284ae1; (* arm_AESE Q1 Q23 *) + 0x93ca8156; (* arm_ROR X22 X10 32 *) + 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) + 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 31) *) + 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 1) *) + 0x9e670128; (* arm_FMOV_ItoF Q8 X9 0 *) + 0x9eaf0148; (* arm_FMOV_ItoF Q8 X10 1 *) + 0x6e291cf1; (* arm_EOR_VEC Q17 Q7 Q9 128 *) + 0x4cdf7003; (* arm_LDR Q3 X0 (Postimmediate_Offset (word 16)) *) + 0x4e284af8; (* arm_AESE Q24 Q23 *) + 0x93ca8156; (* arm_ROR X22 X10 32 *) + 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) + 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 31) *) + 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 1) *) + 0x9e670129; (* arm_FMOV_ItoF Q9 X9 0 *) + 0x9eaf0149; (* arm_FMOV_ItoF Q9 X10 1 *) + 0x6e2a1cfe; (* arm_EOR_VEC Q30 Q7 Q10 128 *) + 0x4cdf701b; (* arm_LDR Q27 X0 (Postimmediate_Offset (word 16)) *) + 0x4e284af9; (* arm_AESE Q25 Q23 *) + 0x93ca8156; (* arm_ROR X22 X10 32 *) + 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) + 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 31) *) + 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 1) *) + 0x9e67012a; (* arm_FMOV_ItoF Q10 X9 0 *) + 0x9eaf014a; (* arm_FMOV_ItoF Q10 X10 1 *) + 0x6e2b1cff; (* arm_EOR_VEC Q31 Q7 Q11 128 *) + 0x4cdf701c; (* arm_LDR Q28 X0 (Postimmediate_Offset (word 16)) *) + 0x4e284afa; (* arm_AESE Q26 Q23 *) + 0x93ca8156; (* arm_ROR X22 X10 32 *) + 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) + 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 31) *) + 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 1) *) + 0x9e67012b; (* arm_FMOV_ItoF Q11 X9 0 *) + 0x9eaf014b; (* arm_FMOV_ItoF Q11 X10 1 *) + 0x4cdf701d; (* arm_LDR Q29 X0 (Postimmediate_Offset (word 16)) *) + 0xb4000586; (* arm_CBZ X6 (word 176) *) + 0x4cdf78f0; (* arm_LDR Q16 X7 (Postimmediate_Offset (word 16)) *) + 0x6e201c84; (* arm_EOR_VEC Q4 Q4 Q0 128 *) + 0x6e261c40; (* arm_EOR_VEC Q0 Q2 Q6 128 *) + 0x6e211ca5; (* arm_EOR_VEC Q5 Q5 Q1 128 *) + 0x6e281c61; (* arm_EOR_VEC Q1 Q3 Q8 128 *) + 0x6e381e31; (* arm_EOR_VEC Q17 Q17 Q24 128 *) + 0x6e291f78; (* arm_EOR_VEC Q24 Q27 Q9 128 *) + 0x6e391fde; (* arm_EOR_VEC Q30 Q30 Q25 128 *) + 0x6e2a1f99; (* arm_EOR_VEC Q25 Q28 Q10 128 *) + 0x6e3a1fff; (* arm_EOR_VEC Q31 Q31 Q26 128 *) + 0x4c9f7024; (* arm_STR Q4 X1 (Postimmediate_Offset (word 16)) *) + 0x6e2b1fba; (* arm_EOR_VEC Q26 Q29 Q11 128 *) + 0x4c9f7025; (* arm_STR Q5 X1 (Postimmediate_Offset (word 16)) *) + 0x2a0503e6; (* arm_MOV W6 W5 *) + 0x4c9f7031; (* arm_STR Q17 X1 (Postimmediate_Offset (word 16)) *) + 0x4cdf78f1; (* arm_LDR Q17 X7 (Postimmediate_Offset (word 16)) *) + 0x4c9f703e; (* arm_STR Q30 X1 (Postimmediate_Offset (word 16)) *) + 0x4c9f703f; (* arm_STR Q31 X1 (Postimmediate_Offset (word 16)) *) + 0x54ffeba2; (* arm_BCS (word 2096500) *) + 0xb100405f; (* arm_CMN X2 (rvalue (word 16)) *) + 0x540001a1; (* arm_BNE (word 52) *) + 0x4eaa1d4b; (* arm_MOV_VEC Q11 Q10 128 *) + 0x4ea91d2a; (* arm_MOV_VEC Q10 Q9 128 *) + 0x4ea81d09; (* arm_MOV_VEC Q9 Q8 128 *) + 0x4ea61cc8; (* arm_MOV_VEC Q8 Q6 128 *) + 0x9e660169; (* arm_FMOV_FtoI X9 Q11 0 *) + 0x9eae016a; (* arm_FMOV_FtoI X10 Q11 1 *) + 0x6e221cc0; (* arm_EOR_VEC Q0 Q6 Q2 128 *) + 0x6e231d01; (* arm_EOR_VEC Q1 Q8 Q3 128 *) + 0x6e291f78; (* arm_EOR_VEC Q24 Q27 Q9 128 *) + 0x6e2a1f99; (* arm_EOR_VEC Q25 Q28 Q10 128 *) + 0x6e2b1fba; (* arm_EOR_VEC Q26 Q29 Q11 128 *) + 0x54ffe9e0; (* arm_BEQ (word 2096444) *) + 0x91014042; (* arm_ADD X2 X2 (rvalue (word 80)) *) + 0xb40015a2; (* arm_CBZ X2 (word 692) *) + 0x110008a6; (* arm_ADD W6 W5 (rvalue (word 2)) *) + 0xf100c042; (* arm_SUBS X2 X2 (rvalue (word 48)) *) + 0x54000c43; (* arm_BCC (word 392) *) + 0x6e3b1cc0; (* arm_EOR_VEC Q0 Q6 Q27 128 *) + 0x6e3c1d01; (* arm_EOR_VEC Q1 Q8 Q28 128 *) + 0x6e291fb8; (* arm_EOR_VEC Q24 Q29 Q9 128 *) + 0x1400000e; (* arm_B (word 56) *) + 0xd503201f; (* arm_NOP *) + 0x91004000; (* arm_ADD X0 X0 (rvalue (word 16)) *) + 0x6e251c25; (* arm_EOR_VEC Q5 Q1 Q5 128 *) + 0x4c9f7025; (* arm_STR Q5 X1 (Postimmediate_Offset (word 16)) *) + 0x6e311f11; (* arm_EOR_VEC Q17 Q24 Q17 128 *) + 0x4c9f7031; (* arm_STR Q17 X1 (Postimmediate_Offset (word 16)) *) + 0x6e3e1f3e; (* arm_EOR_VEC Q30 Q25 Q30 128 *) + 0x6e3f1f5f; (* arm_EOR_VEC Q31 Q26 Q31 128 *) + 0x4c9fa03e; (* arm_ldstp_2q false (word 30) X1 (Postimmediate_Offset (word 32)) *) + 0x1400009c; (* arm_B (word 624) *) + 0xd503201f; (* arm_NOP *) + 0xd503201f; (* arm_NOP *) + 0xd503201f; (* arm_NOP *) + 0x4e284a00; (* arm_AESE Q0 Q16 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e284a01; (* arm_AESE Q1 Q16 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e284a18; (* arm_AESE Q24 Q16 *) + 0x4e286b18; (* arm_AESMC Q24 Q24 *) + 0x4cdf78f0; (* arm_LDR Q16 X7 (Postimmediate_Offset (word 16)) *) + 0x710008c6; (* arm_SUBS W6 W6 (rvalue (word 2)) *) + 0x4e284a20; (* arm_AESE Q0 Q17 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e284a21; (* arm_AESE Q1 Q17 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e284a38; (* arm_AESE Q24 Q17 *) + 0x4e286b18; (* arm_AESMC Q24 Q24 *) + 0x4cdf78f1; (* arm_LDR Q17 X7 (Postimmediate_Offset (word 16)) *) + 0x54fffe2c; (* arm_BGT (word 2097092) *) + 0x4e284a00; (* arm_AESE Q0 Q16 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e284a01; (* arm_AESE Q1 Q16 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e284a18; (* arm_AESE Q24 Q16 *) + 0x4e286b18; (* arm_AESMC Q24 Q24 *) + 0x6e271cc4; (* arm_EOR_VEC Q4 Q6 Q7 128 *) + 0xf100c042; (* arm_SUBS X2 X2 (rvalue (word 48)) *) + 0x9e660129; (* arm_FMOV_FtoI X9 Q9 0 *) + 0x9eae012a; (* arm_FMOV_FtoI X10 Q9 1 *) + 0x93ca8156; (* arm_ROR X22 X10 32 *) + 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) + 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 31) *) + 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 1) *) + 0x9e670126; (* arm_FMOV_ItoF Q6 X9 0 *) + 0x9eaf0146; (* arm_FMOV_ItoF Q6 X10 1 *) + 0x6e271d05; (* arm_EOR_VEC Q5 Q8 Q7 128 *) + 0x9a863046; (* arm_CSEL X6 X2 X6 Condition_CC *) + 0x4e284a20; (* arm_AESE Q0 Q17 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e284a21; (* arm_AESE Q1 Q17 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e284a38; (* arm_AESE Q24 Q17 *) + 0x4e286b18; (* arm_AESMC Q24 Q24 *) + 0x6e271d31; (* arm_EOR_VEC Q17 Q9 Q7 128 *) + 0x910080c6; (* arm_ADD X6 X6 (rvalue (word 32)) *) + 0x8b060000; (* arm_ADD X0 X0 X6 *) + 0xaa0303e7; (* arm_MOV X7 X3 *) + 0x4e284a80; (* arm_AESE Q0 Q20 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e284a81; (* arm_AESE Q1 Q20 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e284a98; (* arm_AESE Q24 Q20 *) + 0x4e286b18; (* arm_AESMC Q24 Q24 *) + 0x4e284aa0; (* arm_AESE Q0 Q21 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e284aa1; (* arm_AESE Q1 Q21 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e284ab8; (* arm_AESE Q24 Q21 *) + 0x4e286b18; (* arm_AESMC Q24 Q24 *) + 0x4e284ac0; (* arm_AESE Q0 Q22 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e284ac1; (* arm_AESE Q1 Q22 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e284ad8; (* arm_AESE Q24 Q22 *) + 0x4e286b18; (* arm_AESMC Q24 Q24 *) + 0x4e284ae0; (* arm_AESE Q0 Q23 *) + 0x4e284ae1; (* arm_AESE Q1 Q23 *) + 0x4e284af8; (* arm_AESE Q24 Q23 *) + 0x4cdf701b; (* arm_LDR Q27 X0 (Postimmediate_Offset (word 16)) *) + 0x110008a6; (* arm_ADD W6 W5 (rvalue (word 2)) *) + 0x4cdf78f0; (* arm_LDR Q16 X7 (Postimmediate_Offset (word 16)) *) + 0x6e201c84; (* arm_EOR_VEC Q4 Q4 Q0 128 *) + 0x6e211ca5; (* arm_EOR_VEC Q5 Q5 Q1 128 *) + 0x6e311f18; (* arm_EOR_VEC Q24 Q24 Q17 128 *) + 0x4cdf78f1; (* arm_LDR Q17 X7 (Postimmediate_Offset (word 16)) *) + 0x4c9f7024; (* arm_STR Q4 X1 (Postimmediate_Offset (word 16)) *) + 0x4c9f7025; (* arm_STR Q5 X1 (Postimmediate_Offset (word 16)) *) + 0x4c9f7038; (* arm_STR Q24 X1 (Postimmediate_Offset (word 16)) *) + 0xb100c05f; (* arm_CMN X2 (rvalue (word 48)) *) + 0x54000980; (* arm_BEQ (word 304) *) + 0x4ea31c7c; (* arm_MOV_VEC Q28 Q3 128 *) + 0x4ebb1f7d; (* arm_MOV_VEC Q29 Q27 128 *) + 0xd503201f; (* arm_NOP *) + 0xb100405f; (* arm_CMN X2 (rvalue (word 16)) *) + 0x6e261f81; (* arm_EOR_VEC Q1 Q28 Q6 128 *) + 0x6e281fb8; (* arm_EOR_VEC Q24 Q29 Q8 128 *) + 0x54000040; (* arm_BEQ (word 8) *) + 0x6e261fb8; (* arm_EOR_VEC Q24 Q29 Q6 128 *) + 0x4e284a01; (* arm_AESE Q1 Q16 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e284a18; (* arm_AESE Q24 Q16 *) + 0x4e286b18; (* arm_AESMC Q24 Q24 *) + 0x4cdf78f0; (* arm_LDR Q16 X7 (Postimmediate_Offset (word 16)) *) + 0x710008c6; (* arm_SUBS W6 W6 (rvalue (word 2)) *) + 0x4e284a21; (* arm_AESE Q1 Q17 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e284a38; (* arm_AESE Q24 Q17 *) + 0x4e286b18; (* arm_AESMC Q24 Q24 *) + 0x4cdf78f1; (* arm_LDR Q17 X7 (Postimmediate_Offset (word 16)) *) + 0x54fffeac; (* arm_BGT (word 2097108) *) + 0x4e284a01; (* arm_AESE Q1 Q16 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e284a18; (* arm_AESE Q24 Q16 *) + 0x4e286b18; (* arm_AESMC Q24 Q24 *) + 0x4e284a21; (* arm_AESE Q1 Q17 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e284a38; (* arm_AESE Q24 Q17 *) + 0x4e286b18; (* arm_AESMC Q24 Q24 *) + 0x4e284a81; (* arm_AESE Q1 Q20 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e284a98; (* arm_AESE Q24 Q20 *) + 0x4e286b18; (* arm_AESMC Q24 Q24 *) + 0xb100805f; (* arm_CMN X2 (rvalue (word 32)) *) + 0x4e284aa1; (* arm_AESE Q1 Q21 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e284ab8; (* arm_AESE Q24 Q21 *) + 0x4e286b18; (* arm_AESMC Q24 Q24 *) + 0x6e271cc5; (* arm_EOR_VEC Q5 Q6 Q7 128 *) + 0x4e284ac1; (* arm_AESE Q1 Q22 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e284ad8; (* arm_AESE Q24 Q22 *) + 0x4e286b18; (* arm_AESMC Q24 Q24 *) + 0x6e271d11; (* arm_EOR_VEC Q17 Q8 Q7 128 *) + 0x4e284ae1; (* arm_AESE Q1 Q23 *) + 0x4e284af8; (* arm_AESE Q24 Q23 *) + 0x54000200; (* arm_BEQ (word 64) *) + 0x6e211ca5; (* arm_EOR_VEC Q5 Q5 Q1 128 *) + 0x4c9f7025; (* arm_STR Q5 X1 (Postimmediate_Offset (word 16)) *) + 0x6e381e31; (* arm_EOR_VEC Q17 Q17 Q24 128 *) + 0x4ea81d06; (* arm_MOV_VEC Q6 Q8 128 *) + 0x4c9f7031; (* arm_STR Q17 X1 (Postimmediate_Offset (word 16)) *) + 0x9e660109; (* arm_FMOV_FtoI X9 Q8 0 *) + 0x9eae010a; (* arm_FMOV_FtoI X10 Q8 1 *) + 0x528010f3; (* arm_MOV W19 (rvalue (word 135)) *) + 0x93ca8156; (* arm_ROR X22 X10 32 *) + 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) + 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 31) *) + 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 1) *) + 0x9e670126; (* arm_FMOV_ItoF Q6 X9 0 *) + 0x9eaf0146; (* arm_FMOV_ItoF Q6 X10 1 *) + 0x1400000f; (* arm_B (word 60) *) + 0x6e381ca5; (* arm_EOR_VEC Q5 Q5 Q24 128 *) + 0x4ea61cc6; (* arm_MOV_VEC Q6 Q6 128 *) + 0x4c9f7025; (* arm_STR Q5 X1 (Postimmediate_Offset (word 16)) *) + 0x9e6600c9; (* arm_FMOV_FtoI X9 Q6 0 *) + 0x9eae00ca; (* arm_FMOV_FtoI X10 Q6 1 *) + 0x528010f3; (* arm_MOV W19 (rvalue (word 135)) *) + 0x93ca8156; (* arm_ROR X22 X10 32 *) + 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) + 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 31) *) + 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 1) *) + 0x9e670126; (* arm_FMOV_ItoF Q6 X9 0 *) + 0x9eaf0146; (* arm_FMOV_ItoF Q6 X10 1 *) + 0x14000002; (* arm_B (word 8) *) + 0xd503201f; (* arm_NOP *) + 0xf2400ebf; (* arm_TST X21 (rvalue (word 15)) *) + 0x540003e0; (* arm_BEQ (word 124) *) + 0xaa0003f4; (* arm_MOV X20 X0 *) + 0xaa0103ed; (* arm_MOV X13 X1 *) + 0xd1004021; (* arm_SUB X1 X1 (rvalue (word 16)) *) + 0xf10006b5; (* arm_SUBS X21 X21 (rvalue (word 1)) *) + 0x3875682f; (* arm_LDRB W15 X1 (Register_Offset X21) *) + 0x38756a8e; (* arm_LDRB W14 X20 (Register_Offset X21) *) + 0x383569af; (* arm_STRB W15 X13 (Register_Offset X21) *) + 0x3835682e; (* arm_STRB W14 X1 (Register_Offset X21) *) + 0x54ffff6c; (* arm_BGT (word 2097132) *) + 0x4c40703a; (* arm_LDR Q26 X1 No_Offset *) + 0x6e261f5a; (* arm_EOR_VEC Q26 Q26 Q6 128 *) + 0xb940f066; (* arm_LDR W6 X3 (Immediate_Offset (word 240)) *) + 0x4cdf7060; (* arm_LDR Q0 X3 (Postimmediate_Offset (word 16)) *) + 0x510008c6; (* arm_SUB W6 W6 (rvalue (word 2)) *) + 0x4cdf7061; (* arm_LDR Q1 X3 (Postimmediate_Offset (word 16)) *) + 0x4e28481a; (* arm_AESE Q26 Q0 *) + 0x4e286b5a; (* arm_AESMC Q26 Q26 *) + 0x4cdf7860; (* arm_LDR Q0 X3 (Postimmediate_Offset (word 16)) *) + 0x710008c6; (* arm_SUBS W6 W6 (rvalue (word 2)) *) + 0x4e28483a; (* arm_AESE Q26 Q1 *) + 0x4e286b5a; (* arm_AESMC Q26 Q26 *) + 0x4cdf7861; (* arm_LDR Q1 X3 (Postimmediate_Offset (word 16)) *) + 0x54ffff2c; (* arm_BGT (word 2097124) *) + 0x4e28481a; (* arm_AESE Q26 Q0 *) + 0x4e286b5a; (* arm_AESMC Q26 Q26 *) + 0x4c407860; (* arm_LDR Q0 X3 No_Offset *) + 0x4e28483a; (* arm_AESE Q26 Q1 *) + 0x6e201f5a; (* arm_EOR_VEC Q26 Q26 Q0 128 *) + 0x6e261f5a; (* arm_EOR_VEC Q26 Q26 Q6 128 *) + 0x4c00703a; (* arm_STR Q26 X1 No_Offset *) + 0xa9435bf5; (* arm_LDP X21 X22 SP (Immediate_Offset (iword (&48))) *) + 0x6d4227e8; (* arm_LDP D8 D9 SP (Immediate_Offset (iword (&32))) *) + 0x6d412fea; (* arm_LDP D10 D11 SP (Immediate_Offset (iword (&16))) *) + 0xa8c453f3; (* arm_LDP X19 X20 SP (Postimmediate_Offset (iword (&64))) *) + 0xd65f03c0; (* arm_RET X30 *) + 0xf100405f; (* arm_CMP X2 (rvalue (word 16)) *) + 0x540007a1; (* arm_BNE (word 244) *) + 0xb940f086; (* arm_LDR W6 X4 (Immediate_Offset (word 240)) *) + 0x4cdf7080; (* arm_LDR Q0 X4 (Postimmediate_Offset (word 16)) *) + 0x4c4070a6; (* arm_LDR Q6 X5 No_Offset *) + 0x510008c6; (* arm_SUB W6 W6 (rvalue (word 2)) *) + 0x4cdf7081; (* arm_LDR Q1 X4 (Postimmediate_Offset (word 16)) *) + 0x4e284806; (* arm_AESE Q6 Q0 *) + 0x4e2868c6; (* arm_AESMC Q6 Q6 *) + 0x4cdf7880; (* arm_LDR Q0 X4 (Postimmediate_Offset (word 16)) *) + 0x710008c6; (* arm_SUBS W6 W6 (rvalue (word 2)) *) + 0x4e284826; (* arm_AESE Q6 Q1 *) + 0x4e2868c6; (* arm_AESMC Q6 Q6 *) + 0x4cdf7881; (* arm_LDR Q1 X4 (Postimmediate_Offset (word 16)) *) + 0x54ffff2c; (* arm_BGT (word 2097124) *) + 0x4e284806; (* arm_AESE Q6 Q0 *) + 0x4e2868c6; (* arm_AESMC Q6 Q6 *) + 0x4c407880; (* arm_LDR Q0 X4 No_Offset *) + 0x4e284826; (* arm_AESE Q6 Q1 *) + 0x6e201cc6; (* arm_EOR_VEC Q6 Q6 Q0 128 *) + 0x4c407000; (* arm_LDR Q0 X0 No_Offset *) + 0x6e201cc0; (* arm_EOR_VEC Q0 Q6 Q0 128 *) + 0xb940f066; (* arm_LDR W6 X3 (Immediate_Offset (word 240)) *) + 0x4cdfa87c; (* arm_ldstp_2q true (word 28) X3 (Postimmediate_Offset (word 32)) *) + 0x4e285b80; (* arm_AESD Q0 Q28 *) + 0x4e287800; (* arm_AESIMC Q0 Q0 *) + 0x4cdfa870; (* arm_ldstp_2q true (word 16) X3 (Postimmediate_Offset (word 32)) *) + 0x4e285ba0; (* arm_AESD Q0 Q29 *) + 0x4e287800; (* arm_AESIMC Q0 Q0 *) + 0x710028c6; (* arm_SUBS W6 W6 (rvalue (word 10)) *) + 0x54000120; (* arm_BEQ (word 36) *) + 0x4e285a00; (* arm_AESD Q0 Q16 *) + 0x4e287800; (* arm_AESIMC Q0 Q0 *) + 0x4cdf7870; (* arm_LDR Q16 X3 (Postimmediate_Offset (word 16)) *) + 0x4e285a20; (* arm_AESD Q0 Q17 *) + 0x4e287800; (* arm_AESIMC Q0 Q0 *) + 0x4cdf7871; (* arm_LDR Q17 X3 (Postimmediate_Offset (word 16)) *) + 0x710008c6; (* arm_SUBS W6 W6 (rvalue (word 2)) *) + 0x54ffff2c; (* arm_BGT (word 2097124) *) + 0x4cdfa872; (* arm_ldstp_2q true (word 18) X3 (Postimmediate_Offset (word 32)) *) + 0x4e285a00; (* arm_AESD Q0 Q16 *) + 0x4e287800; (* arm_AESIMC Q0 Q0 *) + 0x4e285a20; (* arm_AESD Q0 Q17 *) + 0x4e287800; (* arm_AESIMC Q0 Q0 *) + 0x4cdfa874; (* arm_ldstp_2q true (word 20) X3 (Postimmediate_Offset (word 32)) *) + 0x4e285a40; (* arm_AESD Q0 Q18 *) + 0x4e287800; (* arm_AESIMC Q0 Q0 *) + 0x4e285a60; (* arm_AESD Q0 Q19 *) + 0x4e287800; (* arm_AESIMC Q0 Q0 *) + 0x4cdfa876; (* arm_ldstp_2q true (word 22) X3 (Postimmediate_Offset (word 32)) *) + 0x4e285a80; (* arm_AESD Q0 Q20 *) + 0x4e287800; (* arm_AESIMC Q0 Q0 *) + 0x4e285aa0; (* arm_AESD Q0 Q21 *) + 0x4e287800; (* arm_AESIMC Q0 Q0 *) + 0x4c407867; (* arm_LDR Q7 X3 No_Offset *) + 0x4e285ac0; (* arm_AESD Q0 Q22 *) + 0x4e287800; (* arm_AESIMC Q0 Q0 *) + 0x4e285ae0; (* arm_AESD Q0 Q23 *) + 0x6e271c00; (* arm_EOR_VEC Q0 Q0 Q7 128 *) + 0x6e201cc0; (* arm_EOR_VEC Q0 Q6 Q0 128 *) + 0x4c007020; (* arm_STR Q0 X1 No_Offset *) + 0x140001ff; (* arm_B (word 2044) *) + 0xa9bc53f3; (* arm_STP X19 X20 SP (Preimmediate_Offset (iword (-- &64))) *) + 0xa9035bf5; (* arm_STP X21 X22 SP (Immediate_Offset (iword (&48))) *) + 0x6d0227e8; (* arm_STP D8 D9 SP (Immediate_Offset (iword (&32))) *) + 0x6d012fea; (* arm_STP D10 D11 SP (Immediate_Offset (iword (&16))) *) + 0x92400c55; (* arm_AND X21 X2 (rvalue (word 15)) *) + 0x927cec42; (* arm_AND X2 X2 (rvalue (word 18446744073709551600)) *) + 0xf1004042; (* arm_SUBS X2 X2 (rvalue (word 16)) *) + 0xd2800208; (* arm_MOV X8 (rvalue (word 16)) *) + 0x54003e43; (* arm_BCC (word 1992) *) + 0xb940f086; (* arm_LDR W6 X4 (Immediate_Offset (word 240)) *) + 0x4cdf7080; (* arm_LDR Q0 X4 (Postimmediate_Offset (word 16)) *) + 0x4c4070a6; (* arm_LDR Q6 X5 No_Offset *) + 0x510008c6; (* arm_SUB W6 W6 (rvalue (word 2)) *) + 0x4cdf7081; (* arm_LDR Q1 X4 (Postimmediate_Offset (word 16)) *) + 0x4e284806; (* arm_AESE Q6 Q0 *) + 0x4e2868c6; (* arm_AESMC Q6 Q6 *) + 0x4cdf7880; (* arm_LDR Q0 X4 (Postimmediate_Offset (word 16)) *) + 0x710008c6; (* arm_SUBS W6 W6 (rvalue (word 2)) *) + 0x4e284826; (* arm_AESE Q6 Q1 *) + 0x4e2868c6; (* arm_AESMC Q6 Q6 *) + 0x4cdf7881; (* arm_LDR Q1 X4 (Postimmediate_Offset (word 16)) *) + 0x54ffff2c; (* arm_BGT (word 2097124) *) + 0x4e284806; (* arm_AESE Q6 Q0 *) + 0x4e2868c6; (* arm_AESMC Q6 Q6 *) + 0x4c407880; (* arm_LDR Q0 X4 No_Offset *) + 0x4e284826; (* arm_AESE Q6 Q1 *) + 0x6e201cc6; (* arm_EOR_VEC Q6 Q6 Q0 128 *) + 0x9e6600c9; (* arm_FMOV_FtoI X9 Q6 0 *) + 0x9eae00ca; (* arm_FMOV_FtoI X10 Q6 1 *) + 0x528010f3; (* arm_MOV W19 (rvalue (word 135)) *) + 0x93ca8156; (* arm_ROR X22 X10 32 *) + 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) + 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 31) *) + 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 1) *) + 0x9e670128; (* arm_FMOV_ItoF Q8 X9 0 *) + 0x9eaf0148; (* arm_FMOV_ItoF Q8 X10 1 *) + 0xb940f065; (* arm_LDR W5 X3 (Immediate_Offset (word 240)) *) + 0x93ca8156; (* arm_ROR X22 X10 32 *) + 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) + 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 31) *) + 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 1) *) + 0x9e670129; (* arm_FMOV_ItoF Q9 X9 0 *) + 0x9eaf0149; (* arm_FMOV_ItoF Q9 X10 1 *) + 0x4c40a870; (* arm_ldstp_2q true (word 16) X3 No_Offset *) + 0x510018a5; (* arm_SUB W5 W5 (rvalue (word 6)) *) + 0x8b051067; (* arm_ADD X7 X3 (Shiftedreg X5 LSL 4) *) + 0x510008a5; (* arm_SUB W5 W5 (rvalue (word 2)) *) + 0x4cdfa8f2; (* arm_ldstp_2q true (word 18) X7 (Postimmediate_Offset (word 32)) *) + 0x4cdfa8f4; (* arm_ldstp_2q true (word 20) X7 (Postimmediate_Offset (word 32)) *) + 0x4cdfa8f6; (* arm_ldstp_2q true (word 22) X7 (Postimmediate_Offset (word 32)) *) + 0x4c4078e7; (* arm_LDR Q7 X7 No_Offset *) + 0x93ca8156; (* arm_ROR X22 X10 32 *) + 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) + 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 31) *) + 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 1) *) + 0x9e67012a; (* arm_FMOV_ItoF Q10 X9 0 *) + 0x9eaf014a; (* arm_FMOV_ItoF Q10 X10 1 *) + 0x91008067; (* arm_ADD X7 X3 (rvalue (word 32)) *) + 0x2a0503e6; (* arm_MOV W6 W5 *) + 0x14000002; (* arm_B (word 8) *) + 0xd503201f; (* arm_NOP *) + 0xf2400ebf; (* arm_TST X21 (rvalue (word 15)) *) + 0x540000c0; (* arm_BEQ (word 24) *) + 0xf1004042; (* arm_SUBS X2 X2 (rvalue (word 16)) *) + 0x9a8803e8; (* arm_CSEL X8 XZR X8 Condition_EQ *) + 0x4cdf7000; (* arm_LDR Q0 X0 (Postimmediate_Offset (word 16)) *) + 0x54003043; (* arm_BCC (word 1544) *) + 0xd1004000; (* arm_SUB X0 X0 (rvalue (word 16)) *) + 0x4cc87000; (* arm_LDR Q0 X0 (Register_Offset X8) *) + 0xf1008042; (* arm_SUBS X2 X2 (rvalue (word 32)) *) + 0x110008a6; (* arm_ADD W6 W5 (rvalue (word 2)) *) + 0x4ea01c03; (* arm_MOV_VEC Q3 Q0 128 *) + 0x4ea01c01; (* arm_MOV_VEC Q1 Q0 128 *) + 0x4ea01c1c; (* arm_MOV_VEC Q28 Q0 128 *) + 0x4cdf7018; (* arm_LDR Q24 X0 (Postimmediate_Offset (word 16)) *) + 0x4eb81f1b; (* arm_MOV_VEC Q27 Q24 128 *) + 0x4eb81f1d; (* arm_MOV_VEC Q29 Q24 128 *) + 0x540027e3; (* arm_BCC (word 1276) *) + 0x6e261c00; (* arm_EOR_VEC Q0 Q0 Q6 128 *) + 0x6e281f18; (* arm_EOR_VEC Q24 Q24 Q8 128 *) + 0x4eb81f01; (* arm_MOV_VEC Q1 Q24 128 *) + 0x4cdf7018; (* arm_LDR Q24 X0 (Postimmediate_Offset (word 16)) *) + 0x4ea01c02; (* arm_MOV_VEC Q2 Q0 128 *) + 0x4ea11c23; (* arm_MOV_VEC Q3 Q1 128 *) + 0x6e291f1b; (* arm_EOR_VEC Q27 Q24 Q9 128 *) + 0x6e291f18; (* arm_EOR_VEC Q24 Q24 Q9 128 *) + 0xf100805f; (* arm_CMP X2 (rvalue (word 32)) *) + 0x54001ac3; (* arm_BCC (word 856) *) + 0x4cdf7019; (* arm_LDR Q25 X0 (Postimmediate_Offset (word 16)) *) + 0x93ca8156; (* arm_ROR X22 X10 32 *) + 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) + 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 31) *) + 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 1) *) + 0x9e67012b; (* arm_FMOV_ItoF Q11 X9 0 *) + 0x9eaf014b; (* arm_FMOV_ItoF Q11 X10 1 *) + 0x4cdf701a; (* arm_LDR Q26 X0 (Postimmediate_Offset (word 16)) *) + 0x6e2a1f39; (* arm_EOR_VEC Q25 Q25 Q10 128 *) + 0x6e2b1f5a; (* arm_EOR_VEC Q26 Q26 Q11 128 *) + 0xd1008042; (* arm_SUB X2 X2 (rvalue (word 32)) *) + 0x2a0503e6; (* arm_MOV W6 W5 *) + 0x14000001; (* arm_B (word 4) *) + 0x4e285a00; (* arm_AESD Q0 Q16 *) + 0x4e287800; (* arm_AESIMC Q0 Q0 *) + 0x4e285a01; (* arm_AESD Q1 Q16 *) + 0x4e287821; (* arm_AESIMC Q1 Q1 *) + 0x4e285a18; (* arm_AESD Q24 Q16 *) + 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x4e285a19; (* arm_AESD Q25 Q16 *) + 0x4e287b39; (* arm_AESIMC Q25 Q25 *) + 0x4e285a1a; (* arm_AESD Q26 Q16 *) + 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) + 0x4cdf78f0; (* arm_LDR Q16 X7 (Postimmediate_Offset (word 16)) *) + 0x710008c6; (* arm_SUBS W6 W6 (rvalue (word 2)) *) + 0x4e285a20; (* arm_AESD Q0 Q17 *) + 0x4e287800; (* arm_AESIMC Q0 Q0 *) + 0x4e285a21; (* arm_AESD Q1 Q17 *) + 0x4e287821; (* arm_AESIMC Q1 Q1 *) + 0x4e285a38; (* arm_AESD Q24 Q17 *) + 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x4e285a39; (* arm_AESD Q25 Q17 *) + 0x4e287b39; (* arm_AESIMC Q25 Q25 *) + 0x4e285a3a; (* arm_AESD Q26 Q17 *) + 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) + 0x4cdf78f1; (* arm_LDR Q17 X7 (Postimmediate_Offset (word 16)) *) + 0x54fffd2c; (* arm_BGT (word 2097060) *) + 0x4e285a00; (* arm_AESD Q0 Q16 *) + 0x4e287800; (* arm_AESIMC Q0 Q0 *) + 0x4e285a01; (* arm_AESD Q1 Q16 *) + 0x4e287821; (* arm_AESIMC Q1 Q1 *) + 0x4e285a18; (* arm_AESD Q24 Q16 *) + 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x4e285a19; (* arm_AESD Q25 Q16 *) + 0x4e287b39; (* arm_AESIMC Q25 Q25 *) + 0x4e285a1a; (* arm_AESD Q26 Q16 *) + 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) + 0xf1014042; (* arm_SUBS X2 X2 (rvalue (word 80)) *) + 0x4e285a20; (* arm_AESD Q0 Q17 *) + 0x4e287800; (* arm_AESIMC Q0 Q0 *) + 0x4e285a21; (* arm_AESD Q1 Q17 *) + 0x4e287821; (* arm_AESIMC Q1 Q1 *) + 0x4e285a38; (* arm_AESD Q24 Q17 *) + 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x4e285a39; (* arm_AESD Q25 Q17 *) + 0x4e287b39; (* arm_AESIMC Q25 Q25 *) + 0x4e285a3a; (* arm_AESD Q26 Q17 *) + 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) + 0x9a82c3e6; (* arm_CSEL X6 XZR X2 Condition_GT *) + 0xaa0303e7; (* arm_MOV X7 X3 *) + 0x4e285a40; (* arm_AESD Q0 Q18 *) + 0x4e287800; (* arm_AESIMC Q0 Q0 *) + 0x4e285a41; (* arm_AESD Q1 Q18 *) + 0x4e287821; (* arm_AESIMC Q1 Q1 *) + 0x4e285a58; (* arm_AESD Q24 Q18 *) + 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x4e285a59; (* arm_AESD Q25 Q18 *) + 0x4e287b39; (* arm_AESIMC Q25 Q25 *) + 0x4e285a5a; (* arm_AESD Q26 Q18 *) + 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) + 0x8b060000; (* arm_ADD X0 X0 X6 *) + 0x91018046; (* arm_ADD X6 X2 (rvalue (word 96)) *) + 0x4e285a60; (* arm_AESD Q0 Q19 *) + 0x4e287800; (* arm_AESIMC Q0 Q0 *) + 0x4e285a61; (* arm_AESD Q1 Q19 *) + 0x4e287821; (* arm_AESIMC Q1 Q1 *) + 0x4e285a78; (* arm_AESD Q24 Q19 *) + 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x4e285a79; (* arm_AESD Q25 Q19 *) + 0x4e287b39; (* arm_AESIMC Q25 Q25 *) + 0x4e285a7a; (* arm_AESD Q26 Q19 *) + 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) + 0x4e285a80; (* arm_AESD Q0 Q20 *) + 0x4e287800; (* arm_AESIMC Q0 Q0 *) + 0x4e285a81; (* arm_AESD Q1 Q20 *) + 0x4e287821; (* arm_AESIMC Q1 Q1 *) + 0x4e285a98; (* arm_AESD Q24 Q20 *) + 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x4e285a99; (* arm_AESD Q25 Q20 *) + 0x4e287b39; (* arm_AESIMC Q25 Q25 *) + 0x4e285a9a; (* arm_AESD Q26 Q20 *) + 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) + 0x4e285aa0; (* arm_AESD Q0 Q21 *) + 0x4e287800; (* arm_AESIMC Q0 Q0 *) + 0x4e285aa1; (* arm_AESD Q1 Q21 *) + 0x4e287821; (* arm_AESIMC Q1 Q1 *) + 0x4e285ab8; (* arm_AESD Q24 Q21 *) + 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x4e285ab9; (* arm_AESD Q25 Q21 *) + 0x4e287b39; (* arm_AESIMC Q25 Q25 *) + 0x4e285aba; (* arm_AESD Q26 Q21 *) + 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) + 0x4e285ac0; (* arm_AESD Q0 Q22 *) + 0x4e287800; (* arm_AESIMC Q0 Q0 *) + 0x4e285ac1; (* arm_AESD Q1 Q22 *) + 0x4e287821; (* arm_AESIMC Q1 Q1 *) + 0x4e285ad8; (* arm_AESD Q24 Q22 *) + 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x4e285ad9; (* arm_AESD Q25 Q22 *) + 0x4e287b39; (* arm_AESIMC Q25 Q25 *) + 0x4e285ada; (* arm_AESD Q26 Q22 *) + 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) + 0x6e261ce4; (* arm_EOR_VEC Q4 Q7 Q6 128 *) + 0x4e285ae0; (* arm_AESD Q0 Q23 *) + 0x93ca8156; (* arm_ROR X22 X10 32 *) + 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) + 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 31) *) + 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 1) *) + 0x9e670126; (* arm_FMOV_ItoF Q6 X9 0 *) + 0x9eaf0146; (* arm_FMOV_ItoF Q6 X10 1 *) + 0x6e281ce5; (* arm_EOR_VEC Q5 Q7 Q8 128 *) + 0x4cdf7002; (* arm_LDR Q2 X0 (Postimmediate_Offset (word 16)) *) + 0x4e285ae1; (* arm_AESD Q1 Q23 *) + 0x93ca8156; (* arm_ROR X22 X10 32 *) + 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) + 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 31) *) + 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 1) *) + 0x9e670128; (* arm_FMOV_ItoF Q8 X9 0 *) + 0x9eaf0148; (* arm_FMOV_ItoF Q8 X10 1 *) + 0x6e291cf1; (* arm_EOR_VEC Q17 Q7 Q9 128 *) + 0x4cdf7003; (* arm_LDR Q3 X0 (Postimmediate_Offset (word 16)) *) + 0x4e285af8; (* arm_AESD Q24 Q23 *) + 0x93ca8156; (* arm_ROR X22 X10 32 *) + 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) + 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 31) *) + 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 1) *) + 0x9e670129; (* arm_FMOV_ItoF Q9 X9 0 *) + 0x9eaf0149; (* arm_FMOV_ItoF Q9 X10 1 *) + 0x6e2a1cfe; (* arm_EOR_VEC Q30 Q7 Q10 128 *) + 0x4cdf701b; (* arm_LDR Q27 X0 (Postimmediate_Offset (word 16)) *) + 0x4e285af9; (* arm_AESD Q25 Q23 *) + 0x93ca8156; (* arm_ROR X22 X10 32 *) + 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) + 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 31) *) + 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 1) *) + 0x9e67012a; (* arm_FMOV_ItoF Q10 X9 0 *) + 0x9eaf014a; (* arm_FMOV_ItoF Q10 X10 1 *) + 0x6e2b1cff; (* arm_EOR_VEC Q31 Q7 Q11 128 *) + 0x4cdf701c; (* arm_LDR Q28 X0 (Postimmediate_Offset (word 16)) *) + 0x4e285afa; (* arm_AESD Q26 Q23 *) + 0x93ca8156; (* arm_ROR X22 X10 32 *) + 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) + 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 31) *) + 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 1) *) + 0x9e67012b; (* arm_FMOV_ItoF Q11 X9 0 *) + 0x9eaf014b; (* arm_FMOV_ItoF Q11 X10 1 *) + 0x4cdf701d; (* arm_LDR Q29 X0 (Postimmediate_Offset (word 16)) *) + 0xb4000586; (* arm_CBZ X6 (word 176) *) + 0x4cdf78f0; (* arm_LDR Q16 X7 (Postimmediate_Offset (word 16)) *) + 0x6e201c84; (* arm_EOR_VEC Q4 Q4 Q0 128 *) + 0x6e261c40; (* arm_EOR_VEC Q0 Q2 Q6 128 *) + 0x6e211ca5; (* arm_EOR_VEC Q5 Q5 Q1 128 *) + 0x6e281c61; (* arm_EOR_VEC Q1 Q3 Q8 128 *) + 0x6e381e31; (* arm_EOR_VEC Q17 Q17 Q24 128 *) + 0x6e291f78; (* arm_EOR_VEC Q24 Q27 Q9 128 *) + 0x6e391fde; (* arm_EOR_VEC Q30 Q30 Q25 128 *) + 0x6e2a1f99; (* arm_EOR_VEC Q25 Q28 Q10 128 *) + 0x6e3a1fff; (* arm_EOR_VEC Q31 Q31 Q26 128 *) + 0x4c9f7024; (* arm_STR Q4 X1 (Postimmediate_Offset (word 16)) *) + 0x6e2b1fba; (* arm_EOR_VEC Q26 Q29 Q11 128 *) + 0x4c9f7025; (* arm_STR Q5 X1 (Postimmediate_Offset (word 16)) *) + 0x2a0503e6; (* arm_MOV W6 W5 *) + 0x4c9f7031; (* arm_STR Q17 X1 (Postimmediate_Offset (word 16)) *) + 0x4cdf78f1; (* arm_LDR Q17 X7 (Postimmediate_Offset (word 16)) *) + 0x4c9f703e; (* arm_STR Q30 X1 (Postimmediate_Offset (word 16)) *) + 0x4c9f703f; (* arm_STR Q31 X1 (Postimmediate_Offset (word 16)) *) + 0x54ffeba2; (* arm_BCS (word 2096500) *) + 0xb100405f; (* arm_CMN X2 (rvalue (word 16)) *) + 0x540001a1; (* arm_BNE (word 52) *) + 0x4eaa1d4b; (* arm_MOV_VEC Q11 Q10 128 *) + 0x4ea91d2a; (* arm_MOV_VEC Q10 Q9 128 *) + 0x4ea81d09; (* arm_MOV_VEC Q9 Q8 128 *) + 0x4ea61cc8; (* arm_MOV_VEC Q8 Q6 128 *) + 0x9e660169; (* arm_FMOV_FtoI X9 Q11 0 *) + 0x9eae016a; (* arm_FMOV_FtoI X10 Q11 1 *) + 0x6e221cc0; (* arm_EOR_VEC Q0 Q6 Q2 128 *) + 0x6e231d01; (* arm_EOR_VEC Q1 Q8 Q3 128 *) + 0x6e291f78; (* arm_EOR_VEC Q24 Q27 Q9 128 *) + 0x6e2a1f99; (* arm_EOR_VEC Q25 Q28 Q10 128 *) + 0x6e2b1fba; (* arm_EOR_VEC Q26 Q29 Q11 128 *) + 0x54ffe9e0; (* arm_BEQ (word 2096444) *) + 0x91014042; (* arm_ADD X2 X2 (rvalue (word 80)) *) + 0xb4001582; (* arm_CBZ X2 (word 688) *) + 0x110008a6; (* arm_ADD W6 W5 (rvalue (word 2)) *) + 0xf100c042; (* arm_SUBS X2 X2 (rvalue (word 48)) *) + 0x54000e23; (* arm_BCC (word 452) *) + 0x6e3b1cc0; (* arm_EOR_VEC Q0 Q6 Q27 128 *) + 0x6e3c1d01; (* arm_EOR_VEC Q1 Q8 Q28 128 *) + 0x6e291fb8; (* arm_EOR_VEC Q24 Q29 Q9 128 *) + 0x1400000e; (* arm_B (word 56) *) + 0xd503201f; (* arm_NOP *) + 0x91004000; (* arm_ADD X0 X0 (rvalue (word 16)) *) + 0xf2400ebf; (* arm_TST X21 (rvalue (word 15)) *) + 0x6e241c25; (* arm_EOR_VEC Q5 Q1 Q4 128 *) + 0x4c9f7025; (* arm_STR Q5 X1 (Postimmediate_Offset (word 16)) *) + 0x6e311f11; (* arm_EOR_VEC Q17 Q24 Q17 128 *) + 0x4c9f7031; (* arm_STR Q17 X1 (Postimmediate_Offset (word 16)) *) + 0x6e3e1f3e; (* arm_EOR_VEC Q30 Q25 Q30 128 *) + 0x6e3f1f5f; (* arm_EOR_VEC Q31 Q26 Q31 128 *) + 0x4c9fa03e; (* arm_ldstp_2q false (word 30) X1 (Postimmediate_Offset (word 32)) *) + 0x54001a00; (* arm_BEQ (word 832) *) + 0x4cdf7800; (* arm_LDR Q0 X0 (Postimmediate_Offset (word 16)) *) + 0x14000098; (* arm_B (word 608) *) + 0x4e285a00; (* arm_AESD Q0 Q16 *) + 0x4e287800; (* arm_AESIMC Q0 Q0 *) + 0x4e285a01; (* arm_AESD Q1 Q16 *) + 0x4e287821; (* arm_AESIMC Q1 Q1 *) + 0x4e285a18; (* arm_AESD Q24 Q16 *) + 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x4cdf78f0; (* arm_LDR Q16 X7 (Postimmediate_Offset (word 16)) *) + 0x710008c6; (* arm_SUBS W6 W6 (rvalue (word 2)) *) + 0x4e285a20; (* arm_AESD Q0 Q17 *) + 0x4e287800; (* arm_AESIMC Q0 Q0 *) + 0x4e285a21; (* arm_AESD Q1 Q17 *) + 0x4e287821; (* arm_AESIMC Q1 Q1 *) + 0x4e285a38; (* arm_AESD Q24 Q17 *) + 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x4cdf78f1; (* arm_LDR Q17 X7 (Postimmediate_Offset (word 16)) *) + 0x54fffe2c; (* arm_BGT (word 2097092) *) + 0x4e285a00; (* arm_AESD Q0 Q16 *) + 0x4e287800; (* arm_AESIMC Q0 Q0 *) + 0x4e285a01; (* arm_AESD Q1 Q16 *) + 0x4e287821; (* arm_AESIMC Q1 Q1 *) + 0x4e285a18; (* arm_AESD Q24 Q16 *) + 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x6e271cc4; (* arm_EOR_VEC Q4 Q6 Q7 128 *) + 0xf100c042; (* arm_SUBS X2 X2 (rvalue (word 48)) *) + 0x9e660129; (* arm_FMOV_FtoI X9 Q9 0 *) + 0x9eae012a; (* arm_FMOV_FtoI X10 Q9 1 *) + 0x528010f3; (* arm_MOV W19 (rvalue (word 135)) *) + 0x93ca8156; (* arm_ROR X22 X10 32 *) + 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) + 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 31) *) + 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 1) *) + 0x9e670126; (* arm_FMOV_ItoF Q6 X9 0 *) + 0x9eaf0146; (* arm_FMOV_ItoF Q6 X10 1 *) + 0x6e271d05; (* arm_EOR_VEC Q5 Q8 Q7 128 *) + 0x9a863046; (* arm_CSEL X6 X2 X6 Condition_CC *) + 0x4e285a20; (* arm_AESD Q0 Q17 *) + 0x4e287800; (* arm_AESIMC Q0 Q0 *) + 0x4e285a21; (* arm_AESD Q1 Q17 *) + 0x4e287821; (* arm_AESIMC Q1 Q1 *) + 0x4e285a38; (* arm_AESD Q24 Q17 *) + 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x6e271d31; (* arm_EOR_VEC Q17 Q9 Q7 128 *) + 0x93ca8156; (* arm_ROR X22 X10 32 *) + 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) + 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 31) *) + 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 1) *) + 0x9e670128; (* arm_FMOV_ItoF Q8 X9 0 *) + 0x9eaf0148; (* arm_FMOV_ItoF Q8 X10 1 *) + 0x910080c6; (* arm_ADD X6 X6 (rvalue (word 32)) *) + 0x8b060000; (* arm_ADD X0 X0 X6 *) + 0xaa0303e7; (* arm_MOV X7 X3 *) + 0x93ca8156; (* arm_ROR X22 X10 32 *) + 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) + 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 31) *) + 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 1) *) + 0x9e670129; (* arm_FMOV_ItoF Q9 X9 0 *) + 0x9eaf0149; (* arm_FMOV_ItoF Q9 X10 1 *) + 0x4e285a80; (* arm_AESD Q0 Q20 *) + 0x4e287800; (* arm_AESIMC Q0 Q0 *) + 0x4e285a81; (* arm_AESD Q1 Q20 *) + 0x4e287821; (* arm_AESIMC Q1 Q1 *) + 0x4e285a98; (* arm_AESD Q24 Q20 *) + 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x4e285aa0; (* arm_AESD Q0 Q21 *) + 0x4e287800; (* arm_AESIMC Q0 Q0 *) + 0x4e285aa1; (* arm_AESD Q1 Q21 *) + 0x4e287821; (* arm_AESIMC Q1 Q1 *) + 0x4e285ab8; (* arm_AESD Q24 Q21 *) + 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x4e285ac0; (* arm_AESD Q0 Q22 *) + 0x4e287800; (* arm_AESIMC Q0 Q0 *) + 0x4e285ac1; (* arm_AESD Q1 Q22 *) + 0x4e287821; (* arm_AESIMC Q1 Q1 *) + 0x4e285ad8; (* arm_AESD Q24 Q22 *) + 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x4cdf701b; (* arm_LDR Q27 X0 (Postimmediate_Offset (word 16)) *) + 0x4e285ae0; (* arm_AESD Q0 Q23 *) + 0x4e285ae1; (* arm_AESD Q1 Q23 *) + 0x4e285af8; (* arm_AESD Q24 Q23 *) + 0x4cdf78f0; (* arm_LDR Q16 X7 (Postimmediate_Offset (word 16)) *) + 0x110008a6; (* arm_ADD W6 W5 (rvalue (word 2)) *) + 0x6e201c84; (* arm_EOR_VEC Q4 Q4 Q0 128 *) + 0x6e211ca5; (* arm_EOR_VEC Q5 Q5 Q1 128 *) + 0x6e311f18; (* arm_EOR_VEC Q24 Q24 Q17 128 *) + 0x4cdf78f1; (* arm_LDR Q17 X7 (Postimmediate_Offset (word 16)) *) + 0x4c9f7024; (* arm_STR Q4 X1 (Postimmediate_Offset (word 16)) *) + 0x4c9f7025; (* arm_STR Q5 X1 (Postimmediate_Offset (word 16)) *) + 0x4c9f7038; (* arm_STR Q24 X1 (Postimmediate_Offset (word 16)) *) + 0xb100c05f; (* arm_CMN X2 (rvalue (word 48)) *) + 0x9100c042; (* arm_ADD X2 X2 (rvalue (word 48)) *) + 0x540007a0; (* arm_BEQ (word 244) *) + 0xd100c042; (* arm_SUB X2 X2 (rvalue (word 48)) *) + 0x4ea31c7c; (* arm_MOV_VEC Q28 Q3 128 *) + 0x4ebb1f7d; (* arm_MOV_VEC Q29 Q27 128 *) + 0xd503201f; (* arm_NOP *) + 0xb100405f; (* arm_CMN X2 (rvalue (word 16)) *) + 0x6e261f81; (* arm_EOR_VEC Q1 Q28 Q6 128 *) + 0x6e281fb8; (* arm_EOR_VEC Q24 Q29 Q8 128 *) + 0x54000040; (* arm_BEQ (word 8) *) + 0x6e261fb8; (* arm_EOR_VEC Q24 Q29 Q6 128 *) + 0x4e285a01; (* arm_AESD Q1 Q16 *) + 0x4e287821; (* arm_AESIMC Q1 Q1 *) + 0x4e285a18; (* arm_AESD Q24 Q16 *) + 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x4cdf78f0; (* arm_LDR Q16 X7 (Postimmediate_Offset (word 16)) *) + 0x710008c6; (* arm_SUBS W6 W6 (rvalue (word 2)) *) + 0x4e285a21; (* arm_AESD Q1 Q17 *) + 0x4e287821; (* arm_AESIMC Q1 Q1 *) + 0x4e285a38; (* arm_AESD Q24 Q17 *) + 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x4cdf78f1; (* arm_LDR Q17 X7 (Postimmediate_Offset (word 16)) *) + 0x54fffeac; (* arm_BGT (word 2097108) *) + 0x4e285a01; (* arm_AESD Q1 Q16 *) + 0x4e287821; (* arm_AESIMC Q1 Q1 *) + 0x4e285a18; (* arm_AESD Q24 Q16 *) + 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x4e285a21; (* arm_AESD Q1 Q17 *) + 0x4e287821; (* arm_AESIMC Q1 Q1 *) + 0x4e285a38; (* arm_AESD Q24 Q17 *) + 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x4e285a81; (* arm_AESD Q1 Q20 *) + 0x4e287821; (* arm_AESIMC Q1 Q1 *) + 0x4e285a98; (* arm_AESD Q24 Q20 *) + 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0xb100805f; (* arm_CMN X2 (rvalue (word 32)) *) + 0x4e285aa1; (* arm_AESD Q1 Q21 *) + 0x4e287821; (* arm_AESIMC Q1 Q1 *) + 0x4e285ab8; (* arm_AESD Q24 Q21 *) + 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x6e271cc5; (* arm_EOR_VEC Q5 Q6 Q7 128 *) + 0x4e285ac1; (* arm_AESD Q1 Q22 *) + 0x4e287821; (* arm_AESIMC Q1 Q1 *) + 0x4e285ad8; (* arm_AESD Q24 Q22 *) + 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x6e271d11; (* arm_EOR_VEC Q17 Q8 Q7 128 *) + 0x4e285ae1; (* arm_AESD Q1 Q23 *) + 0x4e285af8; (* arm_AESD Q24 Q23 *) + 0x54000120; (* arm_BEQ (word 36) *) + 0x6e211ca5; (* arm_EOR_VEC Q5 Q5 Q1 128 *) + 0x6e381e31; (* arm_EOR_VEC Q17 Q17 Q24 128 *) + 0x4ea91d26; (* arm_MOV_VEC Q6 Q9 128 *) + 0x4eaa1d48; (* arm_MOV_VEC Q8 Q10 128 *) + 0x4c9f7025; (* arm_STR Q5 X1 (Postimmediate_Offset (word 16)) *) + 0x4c9f7031; (* arm_STR Q17 X1 (Postimmediate_Offset (word 16)) *) + 0x91004042; (* arm_ADD X2 X2 (rvalue (word 16)) *) + 0x14000006; (* arm_B (word 24) *) + 0x6e381ca5; (* arm_EOR_VEC Q5 Q5 Q24 128 *) + 0x4ea81d06; (* arm_MOV_VEC Q6 Q8 128 *) + 0x4ea91d28; (* arm_MOV_VEC Q8 Q9 128 *) + 0x4c9f7025; (* arm_STR Q5 X1 (Postimmediate_Offset (word 16)) *) + 0x91008042; (* arm_ADD X2 X2 (rvalue (word 32)) *) + 0xf2400ebf; (* arm_TST X21 (rvalue (word 15)) *) + 0x540006a0; (* arm_BEQ (word 212) *) + 0xaa0303e7; (* arm_MOV X7 X3 *) + 0xb5000042; (* arm_CBNZ X2 (word 8) *) + 0x4cdf7800; (* arm_LDR Q0 X0 (Postimmediate_Offset (word 16)) *) + 0x6e281c1a; (* arm_EOR_VEC Q26 Q0 Q8 128 *) + 0xb940f066; (* arm_LDR W6 X3 (Immediate_Offset (word 240)) *) + 0x4cdf7860; (* arm_LDR Q0 X3 (Postimmediate_Offset (word 16)) *) + 0x510008c6; (* arm_SUB W6 W6 (rvalue (word 2)) *) + 0x4cdf7861; (* arm_LDR Q1 X3 (Postimmediate_Offset (word 16)) *) + 0x4e28581a; (* arm_AESD Q26 Q0 *) + 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) + 0x4cdf7860; (* arm_LDR Q0 X3 (Postimmediate_Offset (word 16)) *) + 0x710008c6; (* arm_SUBS W6 W6 (rvalue (word 2)) *) + 0x4e28583a; (* arm_AESD Q26 Q1 *) + 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) + 0x4cdf7861; (* arm_LDR Q1 X3 (Postimmediate_Offset (word 16)) *) + 0x54ffff2c; (* arm_BGT (word 2097124) *) + 0x4e28581a; (* arm_AESD Q26 Q0 *) + 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) + 0x4c407860; (* arm_LDR Q0 X3 No_Offset *) + 0x4e28583a; (* arm_AESD Q26 Q1 *) + 0x6e201f5a; (* arm_EOR_VEC Q26 Q26 Q0 128 *) + 0x6e281f5a; (* arm_EOR_VEC Q26 Q26 Q8 128 *) + 0x4c00703a; (* arm_STR Q26 X1 No_Offset *) + 0xaa0003f4; (* arm_MOV X20 X0 *) + 0x9100402d; (* arm_ADD X13 X1 (rvalue (word 16)) *) + 0xf10006b5; (* arm_SUBS X21 X21 (rvalue (word 1)) *) + 0x3875682f; (* arm_LDRB W15 X1 (Register_Offset X21) *) + 0x38756a8e; (* arm_LDRB W14 X20 (Register_Offset X21) *) + 0x383569af; (* arm_STRB W15 X13 (Register_Offset X21) *) + 0x3835682e; (* arm_STRB W14 X1 (Register_Offset X21) *) + 0x54ffff6c; (* arm_BGT (word 2097132) *) + 0x4c40703a; (* arm_LDR Q26 X1 No_Offset *) + 0x6e261f5a; (* arm_EOR_VEC Q26 Q26 Q6 128 *) + 0xb940f0e6; (* arm_LDR W6 X7 (Immediate_Offset (word 240)) *) + 0x4cdf70e0; (* arm_LDR Q0 X7 (Postimmediate_Offset (word 16)) *) + 0x510008c6; (* arm_SUB W6 W6 (rvalue (word 2)) *) + 0x4cdf70e1; (* arm_LDR Q1 X7 (Postimmediate_Offset (word 16)) *) + 0x4e28581a; (* arm_AESD Q26 Q0 *) + 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) + 0x4cdf78e0; (* arm_LDR Q0 X7 (Postimmediate_Offset (word 16)) *) + 0x710008c6; (* arm_SUBS W6 W6 (rvalue (word 2)) *) + 0x4e28583a; (* arm_AESD Q26 Q1 *) + 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) + 0x4cdf78e1; (* arm_LDR Q1 X7 (Postimmediate_Offset (word 16)) *) + 0x54ffff2c; (* arm_BGT (word 2097124) *) + 0x4e28581a; (* arm_AESD Q26 Q0 *) + 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) + 0x4c4078e0; (* arm_LDR Q0 X7 No_Offset *) + 0x4e28583a; (* arm_AESD Q26 Q1 *) + 0x6e201f5a; (* arm_EOR_VEC Q26 Q26 Q0 128 *) + 0x6e261f5a; (* arm_EOR_VEC Q26 Q26 Q6 128 *) + 0x4c00703a; (* arm_STR Q26 X1 No_Offset *) + 0xa9435bf5; (* arm_LDP X21 X22 SP (Immediate_Offset (iword (&48))) *) + 0x6d4227e8; (* arm_LDP D8 D9 SP (Immediate_Offset (iword (&32))) *) + 0x6d412fea; (* arm_LDP D10 D11 SP (Immediate_Offset (iword (&16))) *) + 0xa8c453f3; (* arm_LDP X19 X20 SP (Postimmediate_Offset (iword (&64))) *) + 0xd65f03c0 (* arm_RET X30 *) +];; diff --git a/arm/proofs/aes-xts-armv8.ml b/arm/proofs/aes-xts-armv8.ml index 4b4df2eb9..1a181bbbd 100644 --- a/arm/proofs/aes-xts-armv8.ml +++ b/arm/proofs/aes-xts-armv8.ml @@ -7,4 +7,7 @@ use_file_raise_failure := true;; needs "arm/proofs/base.ml";; -print_literal_from_elf "arm/aes-xts/aes-xts-armv8.o";; +(* print_literal_from_elf "arm/aes-xts/aes-xts-armv8.o";; *) +save_literal_from_elf "arm/aes-xts/aes-xts-armv8.txt" "arm/aes-xts/aes-xts-armv8.o";; + +(* let aes_xts_armv8 = define_assert_from_elf "aes_xts_armv8" "arm/aes-xts/aes-xts-armv8.o" ..*) From 239721369e45db680694f7ae6dd774fcb54a5cc1 Mon Sep 17 00:00:00 2001 From: Nevine Ebeid Date: Tue, 25 Mar 2025 11:34:49 -0400 Subject: [PATCH 007/132] Update decoded output after adding post-index register offset to the decoder. --- arm/aes-xts/aes-xts-armv8.txt | 4 ++-- arm/proofs/aes-xts-armv8.ml | 9 +++++++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/arm/aes-xts/aes-xts-armv8.txt b/arm/aes-xts/aes-xts-armv8.txt index 16e1b3ad7..191dcb8fb 100644 --- a/arm/aes-xts/aes-xts-armv8.txt +++ b/arm/aes-xts/aes-xts-armv8.txt @@ -101,7 +101,7 @@ 0x9e670128; (* arm_FMOV_ItoF Q8 X9 0 *) 0x9eaf0148; (* arm_FMOV_ItoF Q8 X10 1 *) 0xb940f065; (* arm_LDR W5 X3 (Immediate_Offset (word 240)) *) - 0x4cc87000; (* arm_LDR Q0 X0 (Register_Offset X8) *) + 0x4cc87000; (* arm_LDR Q0 X0 (Postreg_Offset X8) *) 0x4c40a870; (* arm_ldstp_2q true (word 16) X3 No_Offset *) 0x510018a5; (* arm_SUB W5 W5 (rvalue (word 6)) *) 0x8b051067; (* arm_ADD X7 X3 (Shiftedreg X5 LSL 4) *) @@ -678,7 +678,7 @@ 0x4cdf7000; (* arm_LDR Q0 X0 (Postimmediate_Offset (word 16)) *) 0x54003043; (* arm_BCC (word 1544) *) 0xd1004000; (* arm_SUB X0 X0 (rvalue (word 16)) *) - 0x4cc87000; (* arm_LDR Q0 X0 (Register_Offset X8) *) + 0x4cc87000; (* arm_LDR Q0 X0 (Postreg_Offset X8) *) 0xf1008042; (* arm_SUBS X2 X2 (rvalue (word 32)) *) 0x110008a6; (* arm_ADD W6 W5 (rvalue (word 2)) *) 0x4ea01c03; (* arm_MOV_VEC Q3 Q0 128 *) diff --git a/arm/proofs/aes-xts-armv8.ml b/arm/proofs/aes-xts-armv8.ml index 1a181bbbd..cbba0da7d 100644 --- a/arm/proofs/aes-xts-armv8.ml +++ b/arm/proofs/aes-xts-armv8.ml @@ -11,3 +11,12 @@ needs "arm/proofs/base.ml";; save_literal_from_elf "arm/aes-xts/aes-xts-armv8.txt" "arm/aes-xts/aes-xts-armv8.o";; (* let aes_xts_armv8 = define_assert_from_elf "aes_xts_armv8" "arm/aes-xts/aes-xts-armv8.o" ..*) + +(* Missing instructions that were added in PR#211 +4c4070a6 10: 4c4070a6 ld1.16b { v6 }, [x5] +4cdfa87c 5c: 4cdfa87c ld1.4s { v28, v29 }, [x3], #32 +d503201f f8: d503201f nop +4cc87000 198: 4cc87000 ld1.16b { v0 }, [x0], x8 +4c40a870 19c: 4c40a870 ld1.4s { v16, v17 }, [x3] +3875682f 818: 3875682f ldrb w15, [x1, x21] +*) \ No newline at end of file From cc7f0a2d0c12564bdaac55b8b1e29ac38d9ca0e0 Mon Sep 17 00:00:00 2001 From: Nevine Ebeid Date: Fri, 4 Apr 2025 10:47:24 -0400 Subject: [PATCH 008/132] New decoded output after shuffling around some instructions. In some places, only comments are different after the decoder was updated. --- arm/aes-xts/aes-xts-armv8.S | 864 ++++++++++++++++++++++++++++++---- arm/aes-xts/aes-xts-armv8.txt | 132 +++--- 2 files changed, 844 insertions(+), 152 deletions(-) diff --git a/arm/aes-xts/aes-xts-armv8.S b/arm/aes-xts/aes-xts-armv8.S index 8c6587053..25701e691 100644 --- a/arm/aes-xts/aes-xts-armv8.S +++ b/arm/aes-xts/aes-xts-armv8.S @@ -1,10 +1,12 @@ #include "_internal_s2n_bignum.h" -aes_hw_xts_encrypt: - // AARCH64_VALID_CALL_TARGET +# The following xts encrypt is from MacBook M3 build folder +# after moving around some instructions +_aes_hw_xts_encrypt: + # AARCH64_VALID_CALL_TARGET cmp x2,#16 // Original input data size bigger than 16, jump to big size processing. - b.ne .Lxts_enc_big_size + b.ne Lxts_enc_big_size // Encrypt the iv with key2, as the first XEX iv. ldr w6,[x4,#240] ld1 {v0.16b},[x4],#16 @@ -12,7 +14,7 @@ aes_hw_xts_encrypt: sub w6,w6,#2 ld1 {v1.16b},[x4],#16 -.Loop_enc_iv_enc: +Loop_enc_iv_enc: aese v6.16b,v0.16b aesmc v6.16b,v6.16b ld1 {v0.4s},[x4],#16 @@ -20,7 +22,7 @@ aes_hw_xts_encrypt: aese v6.16b,v1.16b aesmc v6.16b,v6.16b ld1 {v1.4s},[x4],#16 - b.gt .Loop_enc_iv_enc + b.gt Loop_enc_iv_enc aese v6.16b,v0.16b aesmc v6.16b,v6.16b @@ -39,9 +41,9 @@ aes_hw_xts_encrypt: ld1 {v16.4s,v17.4s},[x3],#32 // load key schedule... aese v0.16b,v29.16b aesmc v0.16b,v0.16b - subs w6,w6,#10 // if rounds==10, jump to aes-128-xts processing - b.eq .Lxts_128_enc -.Lxts_enc_round_loop: + subs w6,w6,#10 //// if rounds==10, jump to aes-128-xts processing +// b.eq .Lxts_128_enc +Lxts_enc_round_loop: aese v0.16b,v16.16b aesmc v0.16b,v0.16b ld1 {v16.4s},[x3],#16 // load key schedule... @@ -49,8 +51,8 @@ aes_hw_xts_encrypt: aesmc v0.16b,v0.16b ld1 {v17.4s},[x3],#16 // load key schedule... subs w6,w6,#2 // bias - b.gt .Lxts_enc_round_loop -.Lxts_128_enc: + b.gt Lxts_enc_round_loop +//.Lxts_128_enc: ld1 {v18.4s,v19.4s},[x3],#32 // load key schedule... aese v0.16b,v16.16b aesmc v0.16b,v0.16b @@ -73,10 +75,10 @@ aes_hw_xts_encrypt: eor v0.16b,v0.16b,v7.16b eor v0.16b,v0.16b,v6.16b st1 {v0.16b},[x1] - b .Lxts_enc_final_abort + b Lxts_enc_final_abort .align 4 -.Lxts_enc_big_size: +Lxts_enc_big_size: // Encrypt input size > 16 bytes stp x19,x20,[sp,#-64]! stp x21,x22,[sp,#48] @@ -88,7 +90,7 @@ aes_hw_xts_encrypt: and x2,x2,#-16 // len &= 0x1..110000, now divisible by 16 subs x2,x2,#16 mov x8,#16 - b.lo .Lxts_abort // if !(len > 16): error + b.lo Lxts_abort // if !(len > 16): error csel x8,xzr,x8,eq // if (len == 16): step = 0 // Firstly, encrypt the iv with key2, as the first iv of XEX. @@ -98,7 +100,7 @@ aes_hw_xts_encrypt: sub w6,w6,#2 ld1 {v1.4s},[x4],#16 -.Loop_iv_enc: +Loop_iv_enc: aese v6.16b,v0.16b aesmc v6.16b,v6.16b ld1 {v0.4s},[x4],#16 @@ -106,7 +108,7 @@ aes_hw_xts_encrypt: aese v6.16b,v1.16b aesmc v6.16b,v6.16b ld1 {v1.4s},[x4],#16 - b.gt .Loop_iv_enc + b.gt Loop_iv_enc aese v6.16b,v0.16b aesmc v6.16b,v6.16b @@ -133,17 +135,17 @@ aes_hw_xts_encrypt: ld1 {v16.4s,v17.4s},[x3] // load key schedule... sub w5,w5,#6 add x7,x3,x5,lsl#4 // pointer to last 7 round keys - sub w5,w5,#2 ld1 {v18.4s,v19.4s},[x7],#32 ld1 {v20.4s,v21.4s},[x7],#32 ld1 {v22.4s,v23.4s},[x7],#32 ld1 {v7.4s},[x7] + sub w5,w5,#2 add x7,x3,#32 mov w6,w5 // Encryption -.Lxts_enc: +Lxts_enc: ld1 {v24.16b},[x0],#16 subs x2,x2,#32 // bias add w6,w5,#2 @@ -152,7 +154,7 @@ aes_hw_xts_encrypt: orr v28.16b,v0.16b,v0.16b orr v27.16b,v24.16b,v24.16b orr v29.16b,v24.16b,v24.16b - b.lo .Lxts_inner_enc_tail // when input size % 5 = 1 or 2 + b.lo Lxts_inner_enc_tail // when input size % 5 = 1 or 2 // (with tail or not) eor v0.16b,v0.16b,v6.16b // before encryption, xor with iv eor v24.16b,v24.16b,v8.16b @@ -173,7 +175,7 @@ aes_hw_xts_encrypt: eor v27.16b,v24.16b,v9.16b // the third block eor v24.16b,v24.16b,v9.16b cmp x2,#32 - b.lo .Lxts_outer_enc_tail + b.lo Lxts_outer_enc_tail // The iv for fourth block extr x22,x10,x10,#32 @@ -197,10 +199,10 @@ aes_hw_xts_encrypt: eor v26.16b,v26.16b,v11.16b sub x2,x2,#32 // bias mov w6,w5 - b .Loop5x_xts_enc + // b .Loop5x_xts_enc .align 4 -.Loop5x_xts_enc: +Loop5x_xts_enc: aese v0.16b,v16.16b aesmc v0.16b,v0.16b aese v1.16b,v16.16b @@ -224,7 +226,7 @@ aes_hw_xts_encrypt: aese v26.16b,v17.16b aesmc v26.16b,v26.16b ld1 {v17.4s},[x7],#16 - b.gt .Loop5x_xts_enc + b.gt Loop5x_xts_enc aese v0.16b,v16.16b aesmc v0.16b,v0.16b @@ -236,7 +238,7 @@ aes_hw_xts_encrypt: aesmc v25.16b,v25.16b aese v26.16b,v16.16b aesmc v26.16b,v26.16b - subs x2,x2,#0x50 // because .Lxts_enc_tail4x + subs x2,x2,#0x50 // because Lxts_enc_tail4x aese v0.16b,v17.16b aesmc v0.16b,v0.16b @@ -264,7 +266,7 @@ aes_hw_xts_encrypt: add x0,x0,x6 // x0 is adjusted in such way that // at exit from the loop v1.16b-v26.16b // are loaded with last "words" - add x6,x2,#0x60 // because .Lxts_enc_tail4x + add x6,x2,#0x60 // because Lxts_enc_tail4x aese v0.16b,v19.16b aesmc v0.16b,v0.16b @@ -310,8 +312,14 @@ aes_hw_xts_encrypt: aese v26.16b,v22.16b aesmc v26.16b,v26.16b - eor v4.16b,v7.16b,v6.16b aese v0.16b,v23.16b + aese v1.16b,v23.16b + aese v24.16b,v23.16b + aese v25.16b,v23.16b + aese v26.16b,v23.16b + + eor v4.16b,v7.16b,v6.16b + // aese v0.16b,v23.16b // The iv for first block of one iteration extr x22,x10,x10,#32 extr x10,x10,x9,#63 @@ -321,7 +329,7 @@ aes_hw_xts_encrypt: fmov v6.d[1],x10 eor v5.16b,v7.16b,v8.16b ld1 {v2.16b},[x0],#16 - aese v1.16b,v23.16b + // aese v1.16b,v23.16b // The iv for second block extr x22,x10,x10,#32 extr x10,x10,x9,#63 @@ -331,7 +339,7 @@ aes_hw_xts_encrypt: fmov v8.d[1],x10 eor v17.16b,v7.16b,v9.16b ld1 {v3.16b},[x0],#16 - aese v24.16b,v23.16b + // aese v24.16b,v23.16b // The iv for third block extr x22,x10,x10,#32 extr x10,x10,x9,#63 @@ -341,7 +349,7 @@ aes_hw_xts_encrypt: fmov v9.d[1],x10 eor v30.16b,v7.16b,v10.16b ld1 {v27.16b},[x0],#16 - aese v25.16b,v23.16b + // aese v25.16b,v23.16b // The iv for fourth block extr x22,x10,x10,#32 extr x10,x10,x9,#63 @@ -351,7 +359,7 @@ aes_hw_xts_encrypt: fmov v10.d[1],x10 eor v31.16b,v7.16b,v11.16b ld1 {v28.16b},[x0],#16 - aese v26.16b,v23.16b + // aese v26.16b,v23.16b // The iv for fifth block extr x22,x10,x10,#32 @@ -362,8 +370,8 @@ aes_hw_xts_encrypt: fmov v11.d[1],x10 ld1 {v29.16b},[x0],#16 - cbz x6,.Lxts_enc_tail4x - ld1 {v16.4s},[x7],#16 // re-pre-load rndkey[0] + cbz x6,Lxts_enc_tail4x +// vld1 {v16.4s},[x7],#16 // re-pre-load rndkey[0] eor v4.16b,v4.16b,v0.16b eor v0.16b,v2.16b,v6.16b eor v5.16b,v5.16b,v1.16b @@ -373,15 +381,19 @@ aes_hw_xts_encrypt: eor v30.16b,v30.16b,v25.16b eor v25.16b,v28.16b,v10.16b eor v31.16b,v31.16b,v26.16b - st1 {v4.16b},[x1],#16 + //vst1 {v4.16b},[x1],#16 eor v26.16b,v29.16b,v11.16b - st1 {v5.16b},[x1],#16 + //vst1 {v5.16b},[x1],#16 mov w6,w5 + st1 {v4.16b,v5.16b},[x1],#32 st1 {v17.16b},[x1],#16 +// vld1 {v17.4s},[x7],#16 // re-pre-load rndkey[1] +// vst1 {v30.16b},[x1],#16 +// vst1 {v31.16b},[x1],#16 + st1 {v30.16b,v31.16b},[x1],#32 + ld1 {v16.4s},[x7],#16 // re-pre-load rndkey[0] ld1 {v17.4s},[x7],#16 // re-pre-load rndkey[1] - st1 {v30.16b},[x1],#16 - st1 {v31.16b},[x1],#16 - b.hs .Loop5x_xts_enc + b.hs Loop5x_xts_enc // If left 4 blocks, borrow the five block's processing. @@ -393,7 +405,7 @@ aes_hw_xts_encrypt: // 0, 1, 2 or 3 blocks (with or without tail) starting at // Loop5x_enc_after cmn x2,#0x10 - b.ne .Loop5x_enc_after + b.ne Loop5x_enc_after orr v11.16b,v10.16b,v10.16b orr v10.16b,v9.16b,v9.16b orr v9.16b,v8.16b,v8.16b @@ -405,24 +417,24 @@ aes_hw_xts_encrypt: eor v24.16b,v27.16b,v9.16b eor v25.16b,v28.16b,v10.16b eor v26.16b,v29.16b,v11.16b - b.eq .Loop5x_xts_enc + b.eq Loop5x_xts_enc -.Loop5x_enc_after: +Loop5x_enc_after: add x2,x2,#0x50 - cbz x2,.Lxts_enc_done // no blocks left + cbz x2,Lxts_enc_done // no blocks left add w6,w5,#2 subs x2,x2,#0x30 - b.lo .Lxts_inner_enc_tail // 1 or 2 blocks left + b.lo Lxts_inner_enc_tail // 1 or 2 blocks left // (with tail or not) eor v0.16b,v6.16b,v27.16b // 3 blocks left eor v1.16b,v8.16b,v28.16b eor v24.16b,v29.16b,v9.16b - b .Lxts_outer_enc_tail + b Lxts_outer_enc_tail .align 4 -.Lxts_enc_tail4x: +Lxts_enc_tail4x: add x0,x0,#16 eor v5.16b,v1.16b,v5.16b st1 {v5.16b},[x1],#16 @@ -431,9 +443,9 @@ aes_hw_xts_encrypt: eor v30.16b,v25.16b,v30.16b eor v31.16b,v26.16b,v31.16b st1 {v30.16b,v31.16b},[x1],#32 - b .Lxts_enc_done + b Lxts_enc_done .align 4 -.Lxts_outer_enc_tail: +Lxts_outer_enc_tail: aese v0.16b,v16.16b aesmc v0.16b,v0.16b aese v1.16b,v16.16b @@ -449,7 +461,7 @@ aes_hw_xts_encrypt: aese v24.16b,v17.16b aesmc v24.16b,v24.16b ld1 {v17.4s},[x7],#16 - b.gt .Lxts_outer_enc_tail + b.gt Lxts_outer_enc_tail aese v0.16b,v16.16b aesmc v0.16b,v0.16b @@ -458,31 +470,12 @@ aes_hw_xts_encrypt: aese v24.16b,v16.16b aesmc v24.16b,v24.16b eor v4.16b,v6.16b,v7.16b - subs x2,x2,#0x30 - // The iv for first block - fmov x9,d9 - fmov x10,v9.d[1] - //mov w19,#0x87 - extr x22,x10,x10,#32 - extr x10,x10,x9,#63 - and w11,w19,w22,asr#31 - eor x9,x11,x9,lsl#1 - fmov d6,x9 - fmov v6.d[1],x10 - eor v5.16b,v8.16b,v7.16b - csel x6,x2,x6,lo // x6, w6, is zero at this point aese v0.16b,v17.16b aesmc v0.16b,v0.16b aese v1.16b,v17.16b aesmc v1.16b,v1.16b aese v24.16b,v17.16b aesmc v24.16b,v24.16b - eor v17.16b,v9.16b,v7.16b - - add x6,x6,#0x20 - add x0,x0,x6 - mov x7,x3 - aese v0.16b,v20.16b aesmc v0.16b,v0.16b aese v1.16b,v20.16b @@ -504,30 +497,80 @@ aes_hw_xts_encrypt: aese v0.16b,v23.16b aese v1.16b,v23.16b aese v24.16b,v23.16b + + eor v17.16b,v9.16b,v7.16b + subs x2,x2,#0x30 + // The iv for first block + fmov x9,d9 + fmov x10,v9.d[1] + //mov w19,#0x87 + extr x22,x10,x10,#32 + extr x10,x10,x9,#63 + and w11,w19,w22,asr#31 + eor x9,x11,x9,lsl#1 + fmov d6,x9 + fmov v6.d[1],x10 + eor v5.16b,v8.16b,v7.16b + csel x6,x2,x6,lo // x6, w6, is zero at this point +// aese v0.16b,v17.16b +// aesmc v0.16b,v0.16b +// aese v1.16b,v17.16b +// aesmc v1.16b,v1.16b +// aese v24.16b,v17.16b +// aesmc v24.16b,v24.16b +// veor v17.16b,v9.16b,v7.16b + + add x6,x6,#0x20 + add x0,x0,x6 + mov x7,x3 + +// aese v0.16b,v20.16b +// aesmc v0.16b,v0.16b +// aese v1.16b,v20.16b +// aesmc v1.16b,v1.16b +// aese v24.16b,v20.16b +// aesmc v24.16b,v24.16b +// aese v0.16b,v21.16b +// aesmc v0.16b,v0.16b +// aese v1.16b,v21.16b +// aesmc v1.16b,v1.16b +// aese v24.16b,v21.16b +// aesmc v24.16b,v24.16b +// aese v0.16b,v22.16b +// aesmc v0.16b,v0.16b +// aese v1.16b,v22.16b +// aesmc v1.16b,v1.16b +// aese v24.16b,v22.16b +// aesmc v24.16b,v24.16b +// aese v0.16b,v23.16b +// aese v1.16b,v23.16b +// aese v24.16b,v23.16b ld1 {v27.16b},[x0],#16 add w6,w5,#2 - ld1 {v16.4s},[x7],#16 // re-pre-load rndkey[0] +// vld1 {v16.4s},[x7],#16 // re-pre-load rndkey[0] eor v4.16b,v4.16b,v0.16b eor v5.16b,v5.16b,v1.16b eor v24.16b,v24.16b,v17.16b - ld1 {v17.4s},[x7],#16 // re-pre-load rndkey[1] - st1 {v4.16b},[x1],#16 - st1 {v5.16b},[x1],#16 +// vld1 {v17.4s},[x7],#16 // re-pre-load rndkey[1] + ld1 {v16.4s,v17.4s},[x7],#32 +// vst1 {v4.16b},[x1],#16 +// vst1 {v5.16b},[x1],#16 + st1 {v4.16b,v5.16b},[x1],#32 st1 {v24.16b},[x1],#16 cmn x2,#0x30 - b.eq .Lxts_enc_done -.Lxts_encxor_one: + b.eq Lxts_enc_done +Lxts_encxor_one: orr v28.16b,v3.16b,v3.16b orr v29.16b,v27.16b,v27.16b nop -.Lxts_inner_enc_tail: +Lxts_inner_enc_tail: cmn x2,#0x10 eor v1.16b,v28.16b,v6.16b eor v24.16b,v29.16b,v8.16b - b.eq .Lxts_enc_tail_loop + b.eq Lxts_enc_tail_loop eor v24.16b,v29.16b,v6.16b -.Lxts_enc_tail_loop: +Lxts_enc_tail_loop: aese v1.16b,v16.16b aesmc v1.16b,v1.16b aese v24.16b,v16.16b @@ -539,7 +582,7 @@ aes_hw_xts_encrypt: aese v24.16b,v17.16b aesmc v24.16b,v24.16b ld1 {v17.4s},[x7],#16 - b.gt .Lxts_enc_tail_loop + b.gt Lxts_enc_tail_loop aese v1.16b,v16.16b aesmc v1.16b,v1.16b @@ -566,7 +609,7 @@ aes_hw_xts_encrypt: eor v17.16b,v8.16b,v7.16b aese v1.16b,v23.16b aese v24.16b,v23.16b - b.eq .Lxts_enc_one + b.eq Lxts_enc_one eor v5.16b,v5.16b,v1.16b st1 {v5.16b},[x1],#16 eor v17.16b,v17.16b,v24.16b @@ -581,9 +624,9 @@ aes_hw_xts_encrypt: eor x9,x11,x9,lsl #1 fmov d6,x9 fmov v6.d[1],x10 - b .Lxts_enc_done + b Lxts_enc_done -.Lxts_enc_one: +Lxts_enc_one: eor v5.16b,v5.16b,v24.16b orr v6.16b,v6.16b,v6.16b st1 {v5.16b},[x1],#16 @@ -596,12 +639,12 @@ aes_hw_xts_encrypt: eor x9,x11,x9,lsl #1 fmov d6,x9 fmov v6.d[1],x10 - b .Lxts_enc_done + b Lxts_enc_done .align 5 -.Lxts_enc_done: +Lxts_enc_done: // Process the tail block with cipher stealing. tst x21,#0xf - b.eq .Lxts_abort + b.eq Lxts_abort mov x20,x0 mov x13,x1 @@ -613,7 +656,7 @@ aes_hw_xts_encrypt: strb w15,[x13,x21] strb w14,[x1,x21] b.gt .composite_enc_loop -.Lxts_enc_load_done: +Lxts_enc_load_done: ld1 {v26.16b},[x1] eor v26.16b,v26.16b,v6.16b @@ -622,7 +665,7 @@ aes_hw_xts_encrypt: ld1 {v0.16b},[x3],#16 sub w6,w6,#2 ld1 {v1.16b},[x3],#16 // load key schedule... -.Loop_final_enc: +Loop_final_enc: aese v26.16b,v0.16b aesmc v26.16b,v26.16b ld1 {v0.4s},[x3],#16 @@ -630,7 +673,7 @@ aes_hw_xts_encrypt: aese v26.16b,v1.16b aesmc v26.16b,v26.16b ld1 {v1.4s},[x3],#16 - b.gt .Loop_final_enc + b.gt Loop_final_enc aese v26.16b,v0.16b aesmc v26.16b,v26.16b @@ -640,14 +683,663 @@ aes_hw_xts_encrypt: eor v26.16b,v26.16b,v6.16b st1 {v26.16b},[x1] -.Lxts_abort: +Lxts_abort: ldp x21,x22,[sp,#48] ldp d8,d9,[sp,#32] ldp d10,d11,[sp,#16] ldp x19,x20,[sp],#64 -.Lxts_enc_final_abort: +Lxts_enc_final_abort: ret +## aes_hw_xts_encrypt: +## // AARCH64_VALID_CALL_TARGET +## cmp x2,#16 +## // Original input data size bigger than 16, jump to big size processing. +## b.ne .Lxts_enc_big_size +## // Encrypt the iv with key2, as the first XEX iv. +## ldr w6,[x4,#240] +## ld1 {v0.16b},[x4],#16 +## ld1 {v6.16b},[x5] +## sub w6,w6,#2 +## ld1 {v1.16b},[x4],#16 +## +## .Loop_enc_iv_enc: +## aese v6.16b,v0.16b +## aesmc v6.16b,v6.16b +## ld1 {v0.4s},[x4],#16 +## subs w6,w6,#2 +## aese v6.16b,v1.16b +## aesmc v6.16b,v6.16b +## ld1 {v1.4s},[x4],#16 +## b.gt .Loop_enc_iv_enc +## +## aese v6.16b,v0.16b +## aesmc v6.16b,v6.16b +## ld1 {v0.4s},[x4] +## aese v6.16b,v1.16b +## eor v6.16b,v6.16b,v0.16b +## +## ld1 {v0.16b},[x0] +## eor v0.16b,v6.16b,v0.16b +## +## ldr w6,[x3,#240] +## ld1 {v28.4s,v29.4s},[x3],#32 // load key schedule... +## +## aese v0.16b,v28.16b +## aesmc v0.16b,v0.16b +## ld1 {v16.4s,v17.4s},[x3],#32 // load key schedule... +## aese v0.16b,v29.16b +## aesmc v0.16b,v0.16b +## subs w6,w6,#10 // if rounds==10, jump to aes-128-xts processing +## b.eq .Lxts_128_enc +## .Lxts_enc_round_loop: +## aese v0.16b,v16.16b +## aesmc v0.16b,v0.16b +## ld1 {v16.4s},[x3],#16 // load key schedule... +## aese v0.16b,v17.16b +## aesmc v0.16b,v0.16b +## ld1 {v17.4s},[x3],#16 // load key schedule... +## subs w6,w6,#2 // bias +## b.gt .Lxts_enc_round_loop +## .Lxts_128_enc: +## ld1 {v18.4s,v19.4s},[x3],#32 // load key schedule... +## aese v0.16b,v16.16b +## aesmc v0.16b,v0.16b +## aese v0.16b,v17.16b +## aesmc v0.16b,v0.16b +## ld1 {v20.4s,v21.4s},[x3],#32 // load key schedule... +## aese v0.16b,v18.16b +## aesmc v0.16b,v0.16b +## aese v0.16b,v19.16b +## aesmc v0.16b,v0.16b +## ld1 {v22.4s,v23.4s},[x3],#32 // load key schedule... +## aese v0.16b,v20.16b +## aesmc v0.16b,v0.16b +## aese v0.16b,v21.16b +## aesmc v0.16b,v0.16b +## ld1 {v7.4s},[x3] +## aese v0.16b,v22.16b +## aesmc v0.16b,v0.16b +## aese v0.16b,v23.16b +## eor v0.16b,v0.16b,v7.16b +## eor v0.16b,v0.16b,v6.16b +## st1 {v0.16b},[x1] +## b .Lxts_enc_final_abort +## +## .align 4 +## .Lxts_enc_big_size: +## // Encrypt input size > 16 bytes +## stp x19,x20,[sp,#-64]! +## stp x21,x22,[sp,#48] +## stp d8,d9,[sp,#32] +## stp d10,d11,[sp,#16] +## +## // tailcnt store the tail value of length%16. +## and x21,x2,#0xf +## and x2,x2,#-16 // len &= 0x1..110000, now divisible by 16 +## subs x2,x2,#16 +## mov x8,#16 +## b.lo .Lxts_abort // if !(len > 16): error +## csel x8,xzr,x8,eq // if (len == 16): step = 0 +## +## // Firstly, encrypt the iv with key2, as the first iv of XEX. +## ldr w6,[x4,#240] +## ld1 {v0.4s},[x4],#16 +## ld1 {v6.16b},[x5] +## sub w6,w6,#2 +## ld1 {v1.4s},[x4],#16 +## +## .Loop_iv_enc: +## aese v6.16b,v0.16b +## aesmc v6.16b,v6.16b +## ld1 {v0.4s},[x4],#16 +## subs w6,w6,#2 +## aese v6.16b,v1.16b +## aesmc v6.16b,v6.16b +## ld1 {v1.4s},[x4],#16 +## b.gt .Loop_iv_enc +## +## aese v6.16b,v0.16b +## aesmc v6.16b,v6.16b +## ld1 {v0.4s},[x4] +## aese v6.16b,v1.16b +## eor v6.16b,v6.16b,v0.16b +## +## // The iv for second block +## // x9- iv(low), x10 - iv(high) +## // the five ivs stored into, v6.16b,v8.16b,v9.16b,v10.16b,v11.16b +## fmov x9,d6 +## fmov x10,v6.d[1] +## mov w19,#0x87 +## extr x22,x10,x10,#32 +## extr x10,x10,x9,#63 +## and w11,w19,w22,asr#31 +## eor x9,x11,x9,lsl#1 +## fmov d8,x9 +## fmov v8.d[1],x10 +## +## ldr w5,[x3,#240] // next starting point +## ld1 {v0.16b},[x0],x8 +## +## ld1 {v16.4s,v17.4s},[x3] // load key schedule... +## sub w5,w5,#6 +## add x7,x3,x5,lsl#4 // pointer to last 7 round keys +## sub w5,w5,#2 +## ld1 {v18.4s,v19.4s},[x7],#32 +## ld1 {v20.4s,v21.4s},[x7],#32 +## ld1 {v22.4s,v23.4s},[x7],#32 +## ld1 {v7.4s},[x7] +## +## add x7,x3,#32 +## mov w6,w5 +## +## // Encryption +## .Lxts_enc: +## ld1 {v24.16b},[x0],#16 +## subs x2,x2,#32 // bias +## add w6,w5,#2 +## orr v3.16b,v0.16b,v0.16b +## orr v1.16b,v0.16b,v0.16b +## orr v28.16b,v0.16b,v0.16b +## orr v27.16b,v24.16b,v24.16b +## orr v29.16b,v24.16b,v24.16b +## b.lo .Lxts_inner_enc_tail // when input size % 5 = 1 or 2 +## // (with tail or not) +## eor v0.16b,v0.16b,v6.16b // before encryption, xor with iv +## eor v24.16b,v24.16b,v8.16b +## +## // The iv for third block +## extr x22,x10,x10,#32 +## extr x10,x10,x9,#63 +## and w11,w19,w22,asr#31 +## eor x9,x11,x9,lsl#1 +## fmov d9,x9 +## fmov v9.d[1],x10 +## +## +## orr v1.16b,v24.16b,v24.16b +## ld1 {v24.16b},[x0],#16 +## orr v2.16b,v0.16b,v0.16b +## orr v3.16b,v1.16b,v1.16b +## eor v27.16b,v24.16b,v9.16b // the third block +## eor v24.16b,v24.16b,v9.16b +## cmp x2,#32 +## b.lo .Lxts_outer_enc_tail +## +## // The iv for fourth block +## extr x22,x10,x10,#32 +## extr x10,x10,x9,#63 +## and w11,w19,w22,asr#31 +## eor x9,x11,x9,lsl#1 +## fmov d10,x9 +## fmov v10.d[1],x10 +## +## ld1 {v25.16b},[x0],#16 +## // The iv for fifth block +## extr x22,x10,x10,#32 +## extr x10,x10,x9,#63 +## and w11,w19,w22,asr#31 +## eor x9,x11,x9,lsl#1 +## fmov d11,x9 +## fmov v11.d[1],x10 +## +## ld1 {v26.16b},[x0],#16 +## eor v25.16b,v25.16b,v10.16b // the fourth block +## eor v26.16b,v26.16b,v11.16b +## sub x2,x2,#32 // bias +## mov w6,w5 +## b .Loop5x_xts_enc +## +## .align 4 +## .Loop5x_xts_enc: +## aese v0.16b,v16.16b +## aesmc v0.16b,v0.16b +## aese v1.16b,v16.16b +## aesmc v1.16b,v1.16b +## aese v24.16b,v16.16b +## aesmc v24.16b,v24.16b +## aese v25.16b,v16.16b +## aesmc v25.16b,v25.16b +## aese v26.16b,v16.16b +## aesmc v26.16b,v26.16b +## ld1 {v16.4s},[x7],#16 +## subs w6,w6,#2 +## aese v0.16b,v17.16b +## aesmc v0.16b,v0.16b +## aese v1.16b,v17.16b +## aesmc v1.16b,v1.16b +## aese v24.16b,v17.16b +## aesmc v24.16b,v24.16b +## aese v25.16b,v17.16b +## aesmc v25.16b,v25.16b +## aese v26.16b,v17.16b +## aesmc v26.16b,v26.16b +## ld1 {v17.4s},[x7],#16 +## b.gt .Loop5x_xts_enc +## +## aese v0.16b,v16.16b +## aesmc v0.16b,v0.16b +## aese v1.16b,v16.16b +## aesmc v1.16b,v1.16b +## aese v24.16b,v16.16b +## aesmc v24.16b,v24.16b +## aese v25.16b,v16.16b +## aesmc v25.16b,v25.16b +## aese v26.16b,v16.16b +## aesmc v26.16b,v26.16b +## subs x2,x2,#0x50 // because .Lxts_enc_tail4x +## +## aese v0.16b,v17.16b +## aesmc v0.16b,v0.16b +## aese v1.16b,v17.16b +## aesmc v1.16b,v1.16b +## aese v24.16b,v17.16b +## aesmc v24.16b,v24.16b +## aese v25.16b,v17.16b +## aesmc v25.16b,v25.16b +## aese v26.16b,v17.16b +## aesmc v26.16b,v26.16b +## csel x6,xzr,x2,gt // borrow x6, w6, "gt" is not typo +## mov x7,x3 +## +## aese v0.16b,v18.16b +## aesmc v0.16b,v0.16b +## aese v1.16b,v18.16b +## aesmc v1.16b,v1.16b +## aese v24.16b,v18.16b +## aesmc v24.16b,v24.16b +## aese v25.16b,v18.16b +## aesmc v25.16b,v25.16b +## aese v26.16b,v18.16b +## aesmc v26.16b,v26.16b +## add x0,x0,x6 // x0 is adjusted in such way that +## // at exit from the loop v1.16b-v26.16b +## // are loaded with last "words" +## add x6,x2,#0x60 // because .Lxts_enc_tail4x +## +## aese v0.16b,v19.16b +## aesmc v0.16b,v0.16b +## aese v1.16b,v19.16b +## aesmc v1.16b,v1.16b +## aese v24.16b,v19.16b +## aesmc v24.16b,v24.16b +## aese v25.16b,v19.16b +## aesmc v25.16b,v25.16b +## aese v26.16b,v19.16b +## aesmc v26.16b,v26.16b +## +## aese v0.16b,v20.16b +## aesmc v0.16b,v0.16b +## aese v1.16b,v20.16b +## aesmc v1.16b,v1.16b +## aese v24.16b,v20.16b +## aesmc v24.16b,v24.16b +## aese v25.16b,v20.16b +## aesmc v25.16b,v25.16b +## aese v26.16b,v20.16b +## aesmc v26.16b,v26.16b +## +## aese v0.16b,v21.16b +## aesmc v0.16b,v0.16b +## aese v1.16b,v21.16b +## aesmc v1.16b,v1.16b +## aese v24.16b,v21.16b +## aesmc v24.16b,v24.16b +## aese v25.16b,v21.16b +## aesmc v25.16b,v25.16b +## aese v26.16b,v21.16b +## aesmc v26.16b,v26.16b +## +## aese v0.16b,v22.16b +## aesmc v0.16b,v0.16b +## aese v1.16b,v22.16b +## aesmc v1.16b,v1.16b +## aese v24.16b,v22.16b +## aesmc v24.16b,v24.16b +## aese v25.16b,v22.16b +## aesmc v25.16b,v25.16b +## aese v26.16b,v22.16b +## aesmc v26.16b,v26.16b +## +## eor v4.16b,v7.16b,v6.16b +## aese v0.16b,v23.16b +## // The iv for first block of one iteration +## extr x22,x10,x10,#32 +## extr x10,x10,x9,#63 +## and w11,w19,w22,asr#31 +## eor x9,x11,x9,lsl#1 +## fmov d6,x9 +## fmov v6.d[1],x10 +## eor v5.16b,v7.16b,v8.16b +## ld1 {v2.16b},[x0],#16 +## aese v1.16b,v23.16b +## // The iv for second block +## extr x22,x10,x10,#32 +## extr x10,x10,x9,#63 +## and w11,w19,w22,asr#31 +## eor x9,x11,x9,lsl#1 +## fmov d8,x9 +## fmov v8.d[1],x10 +## eor v17.16b,v7.16b,v9.16b +## ld1 {v3.16b},[x0],#16 +## aese v24.16b,v23.16b +## // The iv for third block +## extr x22,x10,x10,#32 +## extr x10,x10,x9,#63 +## and w11,w19,w22,asr#31 +## eor x9,x11,x9,lsl#1 +## fmov d9,x9 +## fmov v9.d[1],x10 +## eor v30.16b,v7.16b,v10.16b +## ld1 {v27.16b},[x0],#16 +## aese v25.16b,v23.16b +## // The iv for fourth block +## extr x22,x10,x10,#32 +## extr x10,x10,x9,#63 +## and w11,w19,w22,asr#31 +## eor x9,x11,x9,lsl#1 +## fmov d10,x9 +## fmov v10.d[1],x10 +## eor v31.16b,v7.16b,v11.16b +## ld1 {v28.16b},[x0],#16 +## aese v26.16b,v23.16b +## +## // The iv for fifth block +## extr x22,x10,x10,#32 +## extr x10,x10,x9,#63 +## and w11,w19,w22,asr #31 +## eor x9,x11,x9,lsl #1 +## fmov d11,x9 +## fmov v11.d[1],x10 +## +## ld1 {v29.16b},[x0],#16 +## cbz x6,.Lxts_enc_tail4x +## ld1 {v16.4s},[x7],#16 // re-pre-load rndkey[0] +## eor v4.16b,v4.16b,v0.16b +## eor v0.16b,v2.16b,v6.16b +## eor v5.16b,v5.16b,v1.16b +## eor v1.16b,v3.16b,v8.16b +## eor v17.16b,v17.16b,v24.16b +## eor v24.16b,v27.16b,v9.16b +## eor v30.16b,v30.16b,v25.16b +## eor v25.16b,v28.16b,v10.16b +## eor v31.16b,v31.16b,v26.16b +## st1 {v4.16b},[x1],#16 +## eor v26.16b,v29.16b,v11.16b +## st1 {v5.16b},[x1],#16 +## mov w6,w5 +## st1 {v17.16b},[x1],#16 +## ld1 {v17.4s},[x7],#16 // re-pre-load rndkey[1] +## st1 {v30.16b},[x1],#16 +## st1 {v31.16b},[x1],#16 +## b.hs .Loop5x_xts_enc +## +## +## // If left 4 blocks, borrow the five block's processing. +## // This means if (x2 + 1 block) == 0, which is the case +## // when input size % 5 = 4, continue processing and do +## // another iteration in Loop5x_xts_enc which will exit from +## // cbz x6,.Lxts_enc_tail4x. +## // Otherwise, this is the end of the loop continue processing +## // 0, 1, 2 or 3 blocks (with or without tail) starting at +## // Loop5x_enc_after +## cmn x2,#0x10 +## b.ne .Loop5x_enc_after +## orr v11.16b,v10.16b,v10.16b +## orr v10.16b,v9.16b,v9.16b +## orr v9.16b,v8.16b,v8.16b +## orr v8.16b,v6.16b,v6.16b +## fmov x9,d11 +## fmov x10,v11.d[1] +## eor v0.16b,v6.16b,v2.16b +## eor v1.16b,v8.16b,v3.16b +## eor v24.16b,v27.16b,v9.16b +## eor v25.16b,v28.16b,v10.16b +## eor v26.16b,v29.16b,v11.16b +## b.eq .Loop5x_xts_enc +## +## .Loop5x_enc_after: +## add x2,x2,#0x50 +## cbz x2,.Lxts_enc_done // no blocks left +## +## add w6,w5,#2 +## subs x2,x2,#0x30 +## b.lo .Lxts_inner_enc_tail // 1 or 2 blocks left +## // (with tail or not) +## +## eor v0.16b,v6.16b,v27.16b // 3 blocks left +## eor v1.16b,v8.16b,v28.16b +## eor v24.16b,v29.16b,v9.16b +## b .Lxts_outer_enc_tail +## +## .align 4 +## .Lxts_enc_tail4x: +## add x0,x0,#16 +## eor v5.16b,v1.16b,v5.16b +## st1 {v5.16b},[x1],#16 +## eor v17.16b,v24.16b,v17.16b +## st1 {v17.16b},[x1],#16 +## eor v30.16b,v25.16b,v30.16b +## eor v31.16b,v26.16b,v31.16b +## st1 {v30.16b,v31.16b},[x1],#32 +## b .Lxts_enc_done +## .align 4 +## .Lxts_outer_enc_tail: +## aese v0.16b,v16.16b +## aesmc v0.16b,v0.16b +## aese v1.16b,v16.16b +## aesmc v1.16b,v1.16b +## aese v24.16b,v16.16b +## aesmc v24.16b,v24.16b +## ld1 {v16.4s},[x7],#16 +## subs w6,w6,#2 +## aese v0.16b,v17.16b +## aesmc v0.16b,v0.16b +## aese v1.16b,v17.16b +## aesmc v1.16b,v1.16b +## aese v24.16b,v17.16b +## aesmc v24.16b,v24.16b +## ld1 {v17.4s},[x7],#16 +## b.gt .Lxts_outer_enc_tail +## +## aese v0.16b,v16.16b +## aesmc v0.16b,v0.16b +## aese v1.16b,v16.16b +## aesmc v1.16b,v1.16b +## aese v24.16b,v16.16b +## aesmc v24.16b,v24.16b +## eor v4.16b,v6.16b,v7.16b +## subs x2,x2,#0x30 +## // The iv for first block +## fmov x9,d9 +## fmov x10,v9.d[1] +## //mov w19,#0x87 +## extr x22,x10,x10,#32 +## extr x10,x10,x9,#63 +## and w11,w19,w22,asr#31 +## eor x9,x11,x9,lsl#1 +## fmov d6,x9 +## fmov v6.d[1],x10 +## eor v5.16b,v8.16b,v7.16b +## csel x6,x2,x6,lo // x6, w6, is zero at this point +## aese v0.16b,v17.16b +## aesmc v0.16b,v0.16b +## aese v1.16b,v17.16b +## aesmc v1.16b,v1.16b +## aese v24.16b,v17.16b +## aesmc v24.16b,v24.16b +## eor v17.16b,v9.16b,v7.16b +## +## add x6,x6,#0x20 +## add x0,x0,x6 +## mov x7,x3 +## +## aese v0.16b,v20.16b +## aesmc v0.16b,v0.16b +## aese v1.16b,v20.16b +## aesmc v1.16b,v1.16b +## aese v24.16b,v20.16b +## aesmc v24.16b,v24.16b +## aese v0.16b,v21.16b +## aesmc v0.16b,v0.16b +## aese v1.16b,v21.16b +## aesmc v1.16b,v1.16b +## aese v24.16b,v21.16b +## aesmc v24.16b,v24.16b +## aese v0.16b,v22.16b +## aesmc v0.16b,v0.16b +## aese v1.16b,v22.16b +## aesmc v1.16b,v1.16b +## aese v24.16b,v22.16b +## aesmc v24.16b,v24.16b +## aese v0.16b,v23.16b +## aese v1.16b,v23.16b +## aese v24.16b,v23.16b +## ld1 {v27.16b},[x0],#16 +## add w6,w5,#2 +## ld1 {v16.4s},[x7],#16 // re-pre-load rndkey[0] +## eor v4.16b,v4.16b,v0.16b +## eor v5.16b,v5.16b,v1.16b +## eor v24.16b,v24.16b,v17.16b +## ld1 {v17.4s},[x7],#16 // re-pre-load rndkey[1] +## st1 {v4.16b},[x1],#16 +## st1 {v5.16b},[x1],#16 +## st1 {v24.16b},[x1],#16 +## cmn x2,#0x30 +## b.eq .Lxts_enc_done +## .Lxts_encxor_one: +## orr v28.16b,v3.16b,v3.16b +## orr v29.16b,v27.16b,v27.16b +## nop +## +## .Lxts_inner_enc_tail: +## cmn x2,#0x10 +## eor v1.16b,v28.16b,v6.16b +## eor v24.16b,v29.16b,v8.16b +## b.eq .Lxts_enc_tail_loop +## eor v24.16b,v29.16b,v6.16b +## .Lxts_enc_tail_loop: +## aese v1.16b,v16.16b +## aesmc v1.16b,v1.16b +## aese v24.16b,v16.16b +## aesmc v24.16b,v24.16b +## ld1 {v16.4s},[x7],#16 +## subs w6,w6,#2 +## aese v1.16b,v17.16b +## aesmc v1.16b,v1.16b +## aese v24.16b,v17.16b +## aesmc v24.16b,v24.16b +## ld1 {v17.4s},[x7],#16 +## b.gt .Lxts_enc_tail_loop +## +## aese v1.16b,v16.16b +## aesmc v1.16b,v1.16b +## aese v24.16b,v16.16b +## aesmc v24.16b,v24.16b +## aese v1.16b,v17.16b +## aesmc v1.16b,v1.16b +## aese v24.16b,v17.16b +## aesmc v24.16b,v24.16b +## aese v1.16b,v20.16b +## aesmc v1.16b,v1.16b +## aese v24.16b,v20.16b +## aesmc v24.16b,v24.16b +## cmn x2,#0x20 +## aese v1.16b,v21.16b +## aesmc v1.16b,v1.16b +## aese v24.16b,v21.16b +## aesmc v24.16b,v24.16b +## eor v5.16b,v6.16b,v7.16b +## aese v1.16b,v22.16b +## aesmc v1.16b,v1.16b +## aese v24.16b,v22.16b +## aesmc v24.16b,v24.16b +## eor v17.16b,v8.16b,v7.16b +## aese v1.16b,v23.16b +## aese v24.16b,v23.16b +## b.eq .Lxts_enc_one +## eor v5.16b,v5.16b,v1.16b +## st1 {v5.16b},[x1],#16 +## eor v17.16b,v17.16b,v24.16b +## orr v6.16b,v8.16b,v8.16b +## st1 {v17.16b},[x1],#16 +## fmov x9,d8 +## fmov x10,v8.d[1] +## mov w19,#0x87 +## extr x22,x10,x10,#32 +## extr x10,x10,x9,#63 +## and w11,w19,w22,asr #31 +## eor x9,x11,x9,lsl #1 +## fmov d6,x9 +## fmov v6.d[1],x10 +## b .Lxts_enc_done +## +## .Lxts_enc_one: +## eor v5.16b,v5.16b,v24.16b +## orr v6.16b,v6.16b,v6.16b +## st1 {v5.16b},[x1],#16 +## fmov x9,d6 +## fmov x10,v6.d[1] +## mov w19,#0x87 +## extr x22,x10,x10,#32 +## extr x10,x10,x9,#63 +## and w11,w19,w22,asr #31 +## eor x9,x11,x9,lsl #1 +## fmov d6,x9 +## fmov v6.d[1],x10 +## b .Lxts_enc_done +## .align 5 +## .Lxts_enc_done: +## // Process the tail block with cipher stealing. +## tst x21,#0xf +## b.eq .Lxts_abort +## +## mov x20,x0 +## mov x13,x1 +## sub x1,x1,#16 +## .composite_enc_loop: +## subs x21,x21,#1 +## ldrb w15,[x1,x21] +## ldrb w14,[x20,x21] +## strb w15,[x13,x21] +## strb w14,[x1,x21] +## b.gt .composite_enc_loop +## .Lxts_enc_load_done: +## ld1 {v26.16b},[x1] +## eor v26.16b,v26.16b,v6.16b +## +## // Encrypt the composite block to get the last second encrypted text block +## ldr w6,[x3,#240] // load key schedule... +## ld1 {v0.16b},[x3],#16 +## sub w6,w6,#2 +## ld1 {v1.16b},[x3],#16 // load key schedule... +## .Loop_final_enc: +## aese v26.16b,v0.16b +## aesmc v26.16b,v26.16b +## ld1 {v0.4s},[x3],#16 +## subs w6,w6,#2 +## aese v26.16b,v1.16b +## aesmc v26.16b,v26.16b +## ld1 {v1.4s},[x3],#16 +## b.gt .Loop_final_enc +## +## aese v26.16b,v0.16b +## aesmc v26.16b,v26.16b +## ld1 {v0.4s},[x3] +## aese v26.16b,v1.16b +## eor v26.16b,v26.16b,v0.16b +## eor v26.16b,v26.16b,v6.16b +## st1 {v26.16b},[x1] +## +## .Lxts_abort: +## ldp x21,x22,[sp,#48] +## ldp d8,d9,[sp,#32] +## ldp d10,d11,[sp,#16] +## ldp x19,x20,[sp],#64 +## .Lxts_enc_final_abort: +## ret +## + # Decrypt is taken from # https://github.com/aws/aws-lc/blob/804a11b6f965365156b0a8b6d958233e1372a2e2/generated-src/linux-aarch64/crypto/fipsmodule/aesv8-armx.S#L1475 diff --git a/arm/aes-xts/aes-xts-armv8.txt b/arm/aes-xts/aes-xts-armv8.txt index 191dcb8fb..78438bffb 100644 --- a/arm/aes-xts/aes-xts-armv8.txt +++ b/arm/aes-xts/aes-xts-armv8.txt @@ -22,14 +22,13 @@ 0x4c407000; (* arm_LDR Q0 X0 No_Offset *) 0x6e201cc0; (* arm_EOR_VEC Q0 Q6 Q0 128 *) 0xb940f066; (* arm_LDR W6 X3 (Immediate_Offset (word 240)) *) - 0x4cdfa87c; (* arm_ldstp_2q true (word 28) X3 (Postimmediate_Offset (word 32)) *) + 0x4cdfa87c; (* arm_LDP Q28 Q29 X3 (Postimmediate_Offset (word 32)) *) 0x4e284b80; (* arm_AESE Q0 Q28 *) 0x4e286800; (* arm_AESMC Q0 Q0 *) - 0x4cdfa870; (* arm_ldstp_2q true (word 16) X3 (Postimmediate_Offset (word 32)) *) + 0x4cdfa870; (* arm_LDP Q16 Q17 X3 (Postimmediate_Offset (word 32)) *) 0x4e284ba0; (* arm_AESE Q0 Q29 *) 0x4e286800; (* arm_AESMC Q0 Q0 *) 0x710028c6; (* arm_SUBS W6 W6 (rvalue (word 10)) *) - 0x54000120; (* arm_BEQ (word 36) *) 0x4e284a00; (* arm_AESE Q0 Q16 *) 0x4e286800; (* arm_AESMC Q0 Q0 *) 0x4cdf7870; (* arm_LDR Q16 X3 (Postimmediate_Offset (word 16)) *) @@ -38,17 +37,17 @@ 0x4cdf7871; (* arm_LDR Q17 X3 (Postimmediate_Offset (word 16)) *) 0x710008c6; (* arm_SUBS W6 W6 (rvalue (word 2)) *) 0x54ffff2c; (* arm_BGT (word 2097124) *) - 0x4cdfa872; (* arm_ldstp_2q true (word 18) X3 (Postimmediate_Offset (word 32)) *) + 0x4cdfa872; (* arm_LDP Q18 Q19 X3 (Postimmediate_Offset (word 32)) *) 0x4e284a00; (* arm_AESE Q0 Q16 *) 0x4e286800; (* arm_AESMC Q0 Q0 *) 0x4e284a20; (* arm_AESE Q0 Q17 *) 0x4e286800; (* arm_AESMC Q0 Q0 *) - 0x4cdfa874; (* arm_ldstp_2q true (word 20) X3 (Postimmediate_Offset (word 32)) *) + 0x4cdfa874; (* arm_LDP Q20 Q21 X3 (Postimmediate_Offset (word 32)) *) 0x4e284a40; (* arm_AESE Q0 Q18 *) 0x4e286800; (* arm_AESMC Q0 Q0 *) 0x4e284a60; (* arm_AESE Q0 Q19 *) 0x4e286800; (* arm_AESMC Q0 Q0 *) - 0x4cdfa876; (* arm_ldstp_2q true (word 22) X3 (Postimmediate_Offset (word 32)) *) + 0x4cdfa876; (* arm_LDP Q22 Q23 X3 (Postimmediate_Offset (word 32)) *) 0x4e284a80; (* arm_AESE Q0 Q20 *) 0x4e286800; (* arm_AESMC Q0 Q0 *) 0x4e284aa0; (* arm_AESE Q0 Q21 *) @@ -60,7 +59,8 @@ 0x6e271c00; (* arm_EOR_VEC Q0 Q0 Q7 128 *) 0x6e261c00; (* arm_EOR_VEC Q0 Q0 Q6 128 *) 0x4c007020; (* arm_STR Q0 X1 No_Offset *) - 0x140001e7; (* arm_B (word 1948) *) + 0x140001e8; (* arm_B (word 1952) *) + 0xd503201f; (* arm_NOP *) 0xd503201f; (* arm_NOP *) 0xd503201f; (* arm_NOP *) 0xa9bc53f3; (* arm_STP X19 X20 SP (Preimmediate_Offset (iword (-- &64))) *) @@ -102,14 +102,14 @@ 0x9eaf0148; (* arm_FMOV_ItoF Q8 X10 1 *) 0xb940f065; (* arm_LDR W5 X3 (Immediate_Offset (word 240)) *) 0x4cc87000; (* arm_LDR Q0 X0 (Postreg_Offset X8) *) - 0x4c40a870; (* arm_ldstp_2q true (word 16) X3 No_Offset *) + 0x4c40a870; (* arm_LDP Q16 Q17 X3 No_Offset *) 0x510018a5; (* arm_SUB W5 W5 (rvalue (word 6)) *) 0x8b051067; (* arm_ADD X7 X3 (Shiftedreg X5 LSL 4) *) - 0x510008a5; (* arm_SUB W5 W5 (rvalue (word 2)) *) - 0x4cdfa8f2; (* arm_ldstp_2q true (word 18) X7 (Postimmediate_Offset (word 32)) *) - 0x4cdfa8f4; (* arm_ldstp_2q true (word 20) X7 (Postimmediate_Offset (word 32)) *) - 0x4cdfa8f6; (* arm_ldstp_2q true (word 22) X7 (Postimmediate_Offset (word 32)) *) + 0x4cdfa8f2; (* arm_LDP Q18 Q19 X7 (Postimmediate_Offset (word 32)) *) + 0x4cdfa8f4; (* arm_LDP Q20 Q21 X7 (Postimmediate_Offset (word 32)) *) + 0x4cdfa8f6; (* arm_LDP Q22 Q23 X7 (Postimmediate_Offset (word 32)) *) 0x4c4078e7; (* arm_LDR Q7 X7 No_Offset *) + 0x510008a5; (* arm_SUB W5 W5 (rvalue (word 2)) *) 0x91008067; (* arm_ADD X7 X3 (rvalue (word 32)) *) 0x2a0503e6; (* arm_MOV W6 W5 *) 0x4cdf7018; (* arm_LDR Q24 X0 (Postimmediate_Offset (word 16)) *) @@ -120,7 +120,7 @@ 0x4ea01c1c; (* arm_MOV_VEC Q28 Q0 128 *) 0x4eb81f1b; (* arm_MOV_VEC Q27 Q24 128 *) 0x4eb81f1d; (* arm_MOV_VEC Q29 Q24 128 *) - 0x540027e3; (* arm_BCC (word 1276) *) + 0x54002723; (* arm_BCC (word 1252) *) 0x6e261c00; (* arm_EOR_VEC Q0 Q0 Q6 128 *) 0x6e281f18; (* arm_EOR_VEC Q24 Q24 Q8 128 *) 0x93ca8156; (* arm_ROR X22 X10 32 *) @@ -136,7 +136,7 @@ 0x6e291f1b; (* arm_EOR_VEC Q27 Q24 Q9 128 *) 0x6e291f18; (* arm_EOR_VEC Q24 Q24 Q9 128 *) 0xf100805f; (* arm_CMP X2 (rvalue (word 32)) *) - 0x54001be3; (* arm_BCC (word 892) *) + 0x54001b63; (* arm_BCC (word 876) *) 0x93ca8156; (* arm_ROR X22 X10 32 *) 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 31) *) @@ -155,10 +155,6 @@ 0x6e2b1f5a; (* arm_EOR_VEC Q26 Q26 Q11 128 *) 0xd1008042; (* arm_SUB X2 X2 (rvalue (word 32)) *) 0x2a0503e6; (* arm_MOV W6 W5 *) - 0x14000004; (* arm_B (word 16) *) - 0xd503201f; (* arm_NOP *) - 0xd503201f; (* arm_NOP *) - 0xd503201f; (* arm_NOP *) 0x4e284a00; (* arm_AESE Q0 Q16 *) 0x4e286800; (* arm_AESMC Q0 Q0 *) 0x4e284a01; (* arm_AESE Q1 Q16 *) @@ -258,8 +254,12 @@ 0x4e286b39; (* arm_AESMC Q25 Q25 *) 0x4e284ada; (* arm_AESE Q26 Q22 *) 0x4e286b5a; (* arm_AESMC Q26 Q26 *) - 0x6e261ce4; (* arm_EOR_VEC Q4 Q7 Q6 128 *) 0x4e284ae0; (* arm_AESE Q0 Q23 *) + 0x4e284ae1; (* arm_AESE Q1 Q23 *) + 0x4e284af8; (* arm_AESE Q24 Q23 *) + 0x4e284af9; (* arm_AESE Q25 Q23 *) + 0x4e284afa; (* arm_AESE Q26 Q23 *) + 0x6e261ce4; (* arm_EOR_VEC Q4 Q7 Q6 128 *) 0x93ca8156; (* arm_ROR X22 X10 32 *) 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 31) *) @@ -268,7 +268,6 @@ 0x9eaf0146; (* arm_FMOV_ItoF Q6 X10 1 *) 0x6e281ce5; (* arm_EOR_VEC Q5 Q7 Q8 128 *) 0x4cdf7002; (* arm_LDR Q2 X0 (Postimmediate_Offset (word 16)) *) - 0x4e284ae1; (* arm_AESE Q1 Q23 *) 0x93ca8156; (* arm_ROR X22 X10 32 *) 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 31) *) @@ -277,7 +276,6 @@ 0x9eaf0148; (* arm_FMOV_ItoF Q8 X10 1 *) 0x6e291cf1; (* arm_EOR_VEC Q17 Q7 Q9 128 *) 0x4cdf7003; (* arm_LDR Q3 X0 (Postimmediate_Offset (word 16)) *) - 0x4e284af8; (* arm_AESE Q24 Q23 *) 0x93ca8156; (* arm_ROR X22 X10 32 *) 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 31) *) @@ -286,7 +284,6 @@ 0x9eaf0149; (* arm_FMOV_ItoF Q9 X10 1 *) 0x6e2a1cfe; (* arm_EOR_VEC Q30 Q7 Q10 128 *) 0x4cdf701b; (* arm_LDR Q27 X0 (Postimmediate_Offset (word 16)) *) - 0x4e284af9; (* arm_AESE Q25 Q23 *) 0x93ca8156; (* arm_ROR X22 X10 32 *) 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 31) *) @@ -295,7 +292,6 @@ 0x9eaf014a; (* arm_FMOV_ItoF Q10 X10 1 *) 0x6e2b1cff; (* arm_EOR_VEC Q31 Q7 Q11 128 *) 0x4cdf701c; (* arm_LDR Q28 X0 (Postimmediate_Offset (word 16)) *) - 0x4e284afa; (* arm_AESE Q26 Q23 *) 0x93ca8156; (* arm_ROR X22 X10 32 *) 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 31) *) @@ -304,7 +300,6 @@ 0x9eaf014b; (* arm_FMOV_ItoF Q11 X10 1 *) 0x4cdf701d; (* arm_LDR Q29 X0 (Postimmediate_Offset (word 16)) *) 0xb4000586; (* arm_CBZ X6 (word 176) *) - 0x4cdf78f0; (* arm_LDR Q16 X7 (Postimmediate_Offset (word 16)) *) 0x6e201c84; (* arm_EOR_VEC Q4 Q4 Q0 128 *) 0x6e261c40; (* arm_EOR_VEC Q0 Q2 Q6 128 *) 0x6e211ca5; (* arm_EOR_VEC Q5 Q5 Q1 128 *) @@ -314,15 +309,14 @@ 0x6e391fde; (* arm_EOR_VEC Q30 Q30 Q25 128 *) 0x6e2a1f99; (* arm_EOR_VEC Q25 Q28 Q10 128 *) 0x6e3a1fff; (* arm_EOR_VEC Q31 Q31 Q26 128 *) - 0x4c9f7024; (* arm_STR Q4 X1 (Postimmediate_Offset (word 16)) *) 0x6e2b1fba; (* arm_EOR_VEC Q26 Q29 Q11 128 *) - 0x4c9f7025; (* arm_STR Q5 X1 (Postimmediate_Offset (word 16)) *) 0x2a0503e6; (* arm_MOV W6 W5 *) + 0x4c9fa024; (* arm_STP Q4 Q5 X1 (Postimmediate_Offset (word 32)) *) 0x4c9f7031; (* arm_STR Q17 X1 (Postimmediate_Offset (word 16)) *) + 0x4c9fa03e; (* arm_STP Q30 Q31 X1 (Postimmediate_Offset (word 32)) *) + 0x4cdf78f0; (* arm_LDR Q16 X7 (Postimmediate_Offset (word 16)) *) 0x4cdf78f1; (* arm_LDR Q17 X7 (Postimmediate_Offset (word 16)) *) - 0x4c9f703e; (* arm_STR Q30 X1 (Postimmediate_Offset (word 16)) *) - 0x4c9f703f; (* arm_STR Q31 X1 (Postimmediate_Offset (word 16)) *) - 0x54ffeba2; (* arm_BCS (word 2096500) *) + 0x54ffebe2; (* arm_BCS (word 2096508) *) 0xb100405f; (* arm_CMN X2 (rvalue (word 16)) *) 0x540001a1; (* arm_BNE (word 52) *) 0x4eaa1d4b; (* arm_MOV_VEC Q11 Q10 128 *) @@ -336,16 +330,18 @@ 0x6e291f78; (* arm_EOR_VEC Q24 Q27 Q9 128 *) 0x6e2a1f99; (* arm_EOR_VEC Q25 Q28 Q10 128 *) 0x6e2b1fba; (* arm_EOR_VEC Q26 Q29 Q11 128 *) - 0x54ffe9e0; (* arm_BEQ (word 2096444) *) + 0x54ffea20; (* arm_BEQ (word 2096452) *) 0x91014042; (* arm_ADD X2 X2 (rvalue (word 80)) *) - 0xb40015a2; (* arm_CBZ X2 (word 692) *) + 0xb4001662; (* arm_CBZ X2 (word 716) *) 0x110008a6; (* arm_ADD W6 W5 (rvalue (word 2)) *) 0xf100c042; (* arm_SUBS X2 X2 (rvalue (word 48)) *) 0x54000c43; (* arm_BCC (word 392) *) 0x6e3b1cc0; (* arm_EOR_VEC Q0 Q6 Q27 128 *) 0x6e3c1d01; (* arm_EOR_VEC Q1 Q8 Q28 128 *) 0x6e291fb8; (* arm_EOR_VEC Q24 Q29 Q9 128 *) - 0x1400000e; (* arm_B (word 56) *) + 0x14000010; (* arm_B (word 64) *) + 0xd503201f; (* arm_NOP *) + 0xd503201f; (* arm_NOP *) 0xd503201f; (* arm_NOP *) 0x91004000; (* arm_ADD X0 X0 (rvalue (word 16)) *) 0x6e251c25; (* arm_EOR_VEC Q5 Q1 Q5 128 *) @@ -354,8 +350,8 @@ 0x4c9f7031; (* arm_STR Q17 X1 (Postimmediate_Offset (word 16)) *) 0x6e3e1f3e; (* arm_EOR_VEC Q30 Q25 Q30 128 *) 0x6e3f1f5f; (* arm_EOR_VEC Q31 Q26 Q31 128 *) - 0x4c9fa03e; (* arm_ldstp_2q false (word 30) X1 (Postimmediate_Offset (word 32)) *) - 0x1400009c; (* arm_B (word 624) *) + 0x4c9fa03e; (* arm_STP Q30 Q31 X1 (Postimmediate_Offset (word 32)) *) + 0x140000a0; (* arm_B (word 640) *) 0xd503201f; (* arm_NOP *) 0xd503201f; (* arm_NOP *) 0xd503201f; (* arm_NOP *) @@ -382,27 +378,12 @@ 0x4e284a18; (* arm_AESE Q24 Q16 *) 0x4e286b18; (* arm_AESMC Q24 Q24 *) 0x6e271cc4; (* arm_EOR_VEC Q4 Q6 Q7 128 *) - 0xf100c042; (* arm_SUBS X2 X2 (rvalue (word 48)) *) - 0x9e660129; (* arm_FMOV_FtoI X9 Q9 0 *) - 0x9eae012a; (* arm_FMOV_FtoI X10 Q9 1 *) - 0x93ca8156; (* arm_ROR X22 X10 32 *) - 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) - 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 31) *) - 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 1) *) - 0x9e670126; (* arm_FMOV_ItoF Q6 X9 0 *) - 0x9eaf0146; (* arm_FMOV_ItoF Q6 X10 1 *) - 0x6e271d05; (* arm_EOR_VEC Q5 Q8 Q7 128 *) - 0x9a863046; (* arm_CSEL X6 X2 X6 Condition_CC *) 0x4e284a20; (* arm_AESE Q0 Q17 *) 0x4e286800; (* arm_AESMC Q0 Q0 *) 0x4e284a21; (* arm_AESE Q1 Q17 *) 0x4e286821; (* arm_AESMC Q1 Q1 *) 0x4e284a38; (* arm_AESE Q24 Q17 *) 0x4e286b18; (* arm_AESMC Q24 Q24 *) - 0x6e271d31; (* arm_EOR_VEC Q17 Q9 Q7 128 *) - 0x910080c6; (* arm_ADD X6 X6 (rvalue (word 32)) *) - 0x8b060000; (* arm_ADD X0 X0 X6 *) - 0xaa0303e7; (* arm_MOV X7 X3 *) 0x4e284a80; (* arm_AESE Q0 Q20 *) 0x4e286800; (* arm_AESMC Q0 Q0 *) 0x4e284a81; (* arm_AESE Q1 Q20 *) @@ -424,18 +405,31 @@ 0x4e284ae0; (* arm_AESE Q0 Q23 *) 0x4e284ae1; (* arm_AESE Q1 Q23 *) 0x4e284af8; (* arm_AESE Q24 Q23 *) + 0x6e271d31; (* arm_EOR_VEC Q17 Q9 Q7 128 *) + 0xf100c042; (* arm_SUBS X2 X2 (rvalue (word 48)) *) + 0x9e660129; (* arm_FMOV_FtoI X9 Q9 0 *) + 0x9eae012a; (* arm_FMOV_FtoI X10 Q9 1 *) + 0x93ca8156; (* arm_ROR X22 X10 32 *) + 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) + 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 31) *) + 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 1) *) + 0x9e670126; (* arm_FMOV_ItoF Q6 X9 0 *) + 0x9eaf0146; (* arm_FMOV_ItoF Q6 X10 1 *) + 0x6e271d05; (* arm_EOR_VEC Q5 Q8 Q7 128 *) + 0x9a863046; (* arm_CSEL X6 X2 X6 Condition_CC *) + 0x910080c6; (* arm_ADD X6 X6 (rvalue (word 32)) *) + 0x8b060000; (* arm_ADD X0 X0 X6 *) + 0xaa0303e7; (* arm_MOV X7 X3 *) 0x4cdf701b; (* arm_LDR Q27 X0 (Postimmediate_Offset (word 16)) *) 0x110008a6; (* arm_ADD W6 W5 (rvalue (word 2)) *) - 0x4cdf78f0; (* arm_LDR Q16 X7 (Postimmediate_Offset (word 16)) *) 0x6e201c84; (* arm_EOR_VEC Q4 Q4 Q0 128 *) 0x6e211ca5; (* arm_EOR_VEC Q5 Q5 Q1 128 *) 0x6e311f18; (* arm_EOR_VEC Q24 Q24 Q17 128 *) - 0x4cdf78f1; (* arm_LDR Q17 X7 (Postimmediate_Offset (word 16)) *) - 0x4c9f7024; (* arm_STR Q4 X1 (Postimmediate_Offset (word 16)) *) - 0x4c9f7025; (* arm_STR Q5 X1 (Postimmediate_Offset (word 16)) *) + 0x4cdfa8f0; (* arm_LDP Q16 Q17 X7 (Postimmediate_Offset (word 32)) *) + 0x4c9fa024; (* arm_STP Q4 Q5 X1 (Postimmediate_Offset (word 32)) *) 0x4c9f7038; (* arm_STR Q24 X1 (Postimmediate_Offset (word 16)) *) 0xb100c05f; (* arm_CMN X2 (rvalue (word 48)) *) - 0x54000980; (* arm_BEQ (word 304) *) + 0x54000a40; (* arm_BEQ (word 328) *) 0x4ea31c7c; (* arm_MOV_VEC Q28 Q3 128 *) 0x4ebb1f7d; (* arm_MOV_VEC Q29 Q27 128 *) 0xd503201f; (* arm_NOP *) @@ -496,7 +490,7 @@ 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 1) *) 0x9e670126; (* arm_FMOV_ItoF Q6 X9 0 *) 0x9eaf0146; (* arm_FMOV_ItoF Q6 X10 1 *) - 0x1400000f; (* arm_B (word 60) *) + 0x14000015; (* arm_B (word 84) *) 0x6e381ca5; (* arm_EOR_VEC Q5 Q5 Q24 128 *) 0x4ea61cc6; (* arm_MOV_VEC Q6 Q6 128 *) 0x4c9f7025; (* arm_STR Q5 X1 (Postimmediate_Offset (word 16)) *) @@ -509,7 +503,13 @@ 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 1) *) 0x9e670126; (* arm_FMOV_ItoF Q6 X9 0 *) 0x9eaf0146; (* arm_FMOV_ItoF Q6 X10 1 *) - 0x14000002; (* arm_B (word 8) *) + 0x14000008; (* arm_B (word 32) *) + 0xd503201f; (* arm_NOP *) + 0xd503201f; (* arm_NOP *) + 0xd503201f; (* arm_NOP *) + 0xd503201f; (* arm_NOP *) + 0xd503201f; (* arm_NOP *) + 0xd503201f; (* arm_NOP *) 0xd503201f; (* arm_NOP *) 0xf2400ebf; (* arm_TST X21 (rvalue (word 15)) *) 0x540003e0; (* arm_BEQ (word 124) *) @@ -571,10 +571,10 @@ 0x4c407000; (* arm_LDR Q0 X0 No_Offset *) 0x6e201cc0; (* arm_EOR_VEC Q0 Q6 Q0 128 *) 0xb940f066; (* arm_LDR W6 X3 (Immediate_Offset (word 240)) *) - 0x4cdfa87c; (* arm_ldstp_2q true (word 28) X3 (Postimmediate_Offset (word 32)) *) + 0x4cdfa87c; (* arm_LDP Q28 Q29 X3 (Postimmediate_Offset (word 32)) *) 0x4e285b80; (* arm_AESD Q0 Q28 *) 0x4e287800; (* arm_AESIMC Q0 Q0 *) - 0x4cdfa870; (* arm_ldstp_2q true (word 16) X3 (Postimmediate_Offset (word 32)) *) + 0x4cdfa870; (* arm_LDP Q16 Q17 X3 (Postimmediate_Offset (word 32)) *) 0x4e285ba0; (* arm_AESD Q0 Q29 *) 0x4e287800; (* arm_AESIMC Q0 Q0 *) 0x710028c6; (* arm_SUBS W6 W6 (rvalue (word 10)) *) @@ -587,17 +587,17 @@ 0x4cdf7871; (* arm_LDR Q17 X3 (Postimmediate_Offset (word 16)) *) 0x710008c6; (* arm_SUBS W6 W6 (rvalue (word 2)) *) 0x54ffff2c; (* arm_BGT (word 2097124) *) - 0x4cdfa872; (* arm_ldstp_2q true (word 18) X3 (Postimmediate_Offset (word 32)) *) + 0x4cdfa872; (* arm_LDP Q18 Q19 X3 (Postimmediate_Offset (word 32)) *) 0x4e285a00; (* arm_AESD Q0 Q16 *) 0x4e287800; (* arm_AESIMC Q0 Q0 *) 0x4e285a20; (* arm_AESD Q0 Q17 *) 0x4e287800; (* arm_AESIMC Q0 Q0 *) - 0x4cdfa874; (* arm_ldstp_2q true (word 20) X3 (Postimmediate_Offset (word 32)) *) + 0x4cdfa874; (* arm_LDP Q20 Q21 X3 (Postimmediate_Offset (word 32)) *) 0x4e285a40; (* arm_AESD Q0 Q18 *) 0x4e287800; (* arm_AESIMC Q0 Q0 *) 0x4e285a60; (* arm_AESD Q0 Q19 *) 0x4e287800; (* arm_AESIMC Q0 Q0 *) - 0x4cdfa876; (* arm_ldstp_2q true (word 22) X3 (Postimmediate_Offset (word 32)) *) + 0x4cdfa876; (* arm_LDP Q22 Q23 X3 (Postimmediate_Offset (word 32)) *) 0x4e285a80; (* arm_AESD Q0 Q20 *) 0x4e287800; (* arm_AESIMC Q0 Q0 *) 0x4e285aa0; (* arm_AESD Q0 Q21 *) @@ -653,13 +653,13 @@ 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 1) *) 0x9e670129; (* arm_FMOV_ItoF Q9 X9 0 *) 0x9eaf0149; (* arm_FMOV_ItoF Q9 X10 1 *) - 0x4c40a870; (* arm_ldstp_2q true (word 16) X3 No_Offset *) + 0x4c40a870; (* arm_LDP Q16 Q17 X3 No_Offset *) 0x510018a5; (* arm_SUB W5 W5 (rvalue (word 6)) *) 0x8b051067; (* arm_ADD X7 X3 (Shiftedreg X5 LSL 4) *) 0x510008a5; (* arm_SUB W5 W5 (rvalue (word 2)) *) - 0x4cdfa8f2; (* arm_ldstp_2q true (word 18) X7 (Postimmediate_Offset (word 32)) *) - 0x4cdfa8f4; (* arm_ldstp_2q true (word 20) X7 (Postimmediate_Offset (word 32)) *) - 0x4cdfa8f6; (* arm_ldstp_2q true (word 22) X7 (Postimmediate_Offset (word 32)) *) + 0x4cdfa8f2; (* arm_LDP Q18 Q19 X7 (Postimmediate_Offset (word 32)) *) + 0x4cdfa8f4; (* arm_LDP Q20 Q21 X7 (Postimmediate_Offset (word 32)) *) + 0x4cdfa8f6; (* arm_LDP Q22 Q23 X7 (Postimmediate_Offset (word 32)) *) 0x4c4078e7; (* arm_LDR Q7 X7 No_Offset *) 0x93ca8156; (* arm_ROR X22 X10 32 *) 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) @@ -907,7 +907,7 @@ 0x4c9f7031; (* arm_STR Q17 X1 (Postimmediate_Offset (word 16)) *) 0x6e3e1f3e; (* arm_EOR_VEC Q30 Q25 Q30 128 *) 0x6e3f1f5f; (* arm_EOR_VEC Q31 Q26 Q31 128 *) - 0x4c9fa03e; (* arm_ldstp_2q false (word 30) X1 (Postimmediate_Offset (word 32)) *) + 0x4c9fa03e; (* arm_STP Q30 Q31 X1 (Postimmediate_Offset (word 32)) *) 0x54001a00; (* arm_BEQ (word 832) *) 0x4cdf7800; (* arm_LDR Q0 X0 (Postimmediate_Offset (word 16)) *) 0x14000098; (* arm_B (word 608) *) From 9eb985e16ba131adf1cc807c573c873552b7423f Mon Sep 17 00:00:00 2001 From: Yan Peng Date: Fri, 30 May 2025 22:42:36 +0000 Subject: [PATCH 009/132] Start proof for AES256 encrypt --- arm/aes-xts/Makefile | 30 ++++++++++++++++ arm/aes-xts/aes256_encrypt.S | 34 ++++++++++++++++++ arm/proofs/aes_encrypt.ml | 65 ++++++++++++++++++++++++++++++++++ arm/proofs/aes_encrypt_spec.ml | 41 +++++++++++++++++++++ 4 files changed, 170 insertions(+) create mode 100644 arm/aes-xts/Makefile create mode 100644 arm/aes-xts/aes256_encrypt.S create mode 100644 arm/proofs/aes_encrypt.ml create mode 100644 arm/proofs/aes_encrypt_spec.ml diff --git a/arm/aes-xts/Makefile b/arm/aes-xts/Makefile new file mode 100644 index 000000000..235542c76 --- /dev/null +++ b/arm/aes-xts/Makefile @@ -0,0 +1,30 @@ +############################################################################# +# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +# SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT-0 +############################################################################# + +# If actually on an ARM8 machine, just use the GNU assembler (as). Otherwise +# use a cross-assembling version so that the code can still be assembled +# and the proofs checked against the object files (though you won't be able +# to run code without additional emulation infrastructure). The aarch64 +# cross-assembling version can be installed manually by something like: +# +# sudo apt-get install binutils-aarch64-linux-gnu + +UNAME_RESULT=$(shell uname -p) + +ifeq ($(UNAME_RESULT),aarch64) +GAS=as +else +GAS=aarch64-linux-gnu-as +endif + +# List of object files + +OBJ = aes256_encrypt.o + +%.o : %.S ; $(CC) -E -I../../include $< | $(GAS) -o $@ - + +default: $(OBJ); + +clean:; rm -f *.o *.correct diff --git a/arm/aes-xts/aes256_encrypt.S b/arm/aes-xts/aes256_encrypt.S new file mode 100644 index 000000000..b32b1498e --- /dev/null +++ b/arm/aes-xts/aes256_encrypt.S @@ -0,0 +1,34 @@ +// x2: key schedule +// x1: input +// x0: output +#include "_internal_s2n_bignum.h" + + S2N_BN_SYM_VISIBILITY_DIRECTIVE(aes_encrypt) + S2N_BN_SYM_PRIVACY_DIRECTIVE(aes_encrypt) + .text + .balign 4 + .arch armv8-a+crypto + +aes_encrypt: + ldr w6,[x2,#240] + ld1 {v0.16b},[x2],#16 + ld1 {v6.16b},[x1] + sub w6,w6,#2 + ld1 {v1.16b},[x2],#16 + +Loop_enc_iv_enc: + aese v6.16b,v0.16b + aesmc v6.16b,v6.16b + ld1 {v0.4s},[x2],#16 + subs w6,w6,#2 + aese v6.16b,v1.16b + aesmc v6.16b,v6.16b + ld1 {v1.4s},[x2],#16 + b.gt Loop_enc_iv_enc + + aese v6.16b,v0.16b + aesmc v6.16b,v6.16b + ld1 {v0.4s},[x4] + aese v6.16b,v1.16b + eor v6.16b,v6.16b,v0.16b + st1 {v6.4s},[x0] diff --git a/arm/proofs/aes_encrypt.ml b/arm/proofs/aes_encrypt.ml new file mode 100644 index 000000000..e055835ed --- /dev/null +++ b/arm/proofs/aes_encrypt.ml @@ -0,0 +1,65 @@ +needs "arm/proofs/base.ml";; +needs "arm/proofs/aes_encrypt_spec.ml";; + +print_literal_from_elf "arm/aes-xts/aes256_encrypt.o";; + +let aes256_encrypt_mc = define_assert_from_elf "aes256_encrypt_mc" "arm/aes-xts/aes256_encrypt.o" +[ + 0xb940f046; (* arm_LDR W6 X2 (Immediate_Offset (word 240)) *) + 0x4cdf7040; (* arm_LDR Q0 X2 (Postimmediate_Offset (word 16)) *) + 0x4c407026; (* arm_LDR Q6 X1 No_Offset *) + 0x510008c6; (* arm_SUB W6 W6 (rvalue (word 2)) *) + 0x4cdf7041; (* arm_LDR Q1 X2 (Postimmediate_Offset (word 16)) *) + 0x4e284806; (* arm_AESE Q6 Q0 *) + 0x4e2868c6; (* arm_AESMC Q6 Q6 *) + 0x4cdf7840; (* arm_LDR Q0 X2 (Postimmediate_Offset (word 16)) *) + 0x710008c6; (* arm_SUBS W6 W6 (rvalue (word 2)) *) + 0x4e284826; (* arm_AESE Q6 Q1 *) + 0x4e2868c6; (* arm_AESMC Q6 Q6 *) + 0x4cdf7841; (* arm_LDR Q1 X2 (Postimmediate_Offset (word 16)) *) + 0x54ffff2c; (* arm_BGT (word 2097124) *) + 0x4e284806; (* arm_AESE Q6 Q0 *) + 0x4e2868c6; (* arm_AESMC Q6 Q6 *) + 0x4c407880; (* arm_LDR Q0 X4 No_Offset *) + 0x4e284826; (* arm_AESE Q6 Q1 *) + 0x6e201cc6; (* arm_EOR_VEC Q6 Q6 Q0 128 *) + 0x4c007806 (* arm_STR Q6 X0 No_Offset *) +];; + +let AES256_ENCRYPT_EXEC = ARM_MK_EXEC_RULE aes256_encrypt_mc;; + +(* TODO: Could this be better? read(memory :> bytes(key, 240) = all_k) *) +let AES256_ENCRYPT_CORRECT = prove( + `!out in key ib k0 k1 k2 k3 k4 k5 k6 k7 k8 k9 k10 k11 k12 k13 k14 pc. + nonoverlapping (word pc,LENGTH aes256_encrypt_mc) (out,16) + ==> ensures arm + // precondition + (\s. aligned_bytes_loaded s (word pc) aes256_encrypt_mc /\ + read PC s = word pc /\ + C_ARGUMENTS [out; in; key] s /\ + read(memory :> bytes(in, 16)) s = ib /\ + read(memory :> bytes(word_add key (word 240), 4)) = word 13 /\ + read(memory :> bytes(key, 16)) = k0 /\ + read(memory :> bytes((word_add key (word 16)), 16)) = k1 /\ + read(memory :> bytes((word_add key (word 32)), 16)) = k2 /\ + read(memory :> bytes((word_add key (word 48)), 16)) = k3 /\ + read(memory :> bytes((word_add key (word 64)), 16)) = k4 /\ + read(memory :> bytes((word_add key (word 80)), 16)) = k5 /\ + read(memory :> bytes((word_add key (word 96)), 16)) = k6 /\ + read(memory :> bytes((word_add key (word 112)), 16)) = k7 /\ + read(memory :> bytes((word_add key (word 128)), 16)) = k8 /\ + read(memory :> bytes((word_add key (word 144)), 16)) = k9 /\ + read(memory :> bytes((word_add key (word 160)), 16)) = k10 /\ + read(memory :> bytes((word_add key (word 176)), 16)) = k11 /\ + read(memory :> bytes((word_add key (word 192)), 16)) = k12 /\ + read(memory :> bytes((word_add key (word 208)), 16)) = k13 /\ + read(memory :> bytes((word_add key (word 224)), 16)) = k14) + // postcondition + // TODO: Nevine will figure out the post condition for output + // hint: use the aes256_encrypt from aes_encrypt_spec + (\s. read PC s = word (pc + LENGTH aes256_encrypt_mc) /\ + ) + // MAYCHANGE + ()`, + CHEAT_TAC +) \ No newline at end of file diff --git a/arm/proofs/aes_encrypt_spec.ml b/arm/proofs/aes_encrypt_spec.ml new file mode 100644 index 000000000..698201f52 --- /dev/null +++ b/arm/proofs/aes_encrypt_spec.ml @@ -0,0 +1,41 @@ +needs "common/aes.ml";; + +(* +Cipher(byte in[4*Nb], byte out[4*Nb], word w[Nb*(Nr+1)]) + +begin + +byte state[4,Nb] +state = in + +AddRoundKey(state, w[0, Nb-1]) // See Sec. 5.1.4 + +for round = 1 step 1 to Nr–1 + +SubBytes(state) // See Sec. 5.1.1 + +ShiftRows(state) // See Sec. 5.1.2 + +MixColumns(state) // See Sec. 5.1.3 + +AddRoundKey(state, w[round*Nb, (round+1)*Nb-1]) + +end for + +SubBytes(state) + +ShiftRows(state) + +AddRoundKey(state, w[Nr*Nb, (Nr+1)*Nb-1]) + +out = state + +end +*) +(* TODO: Nevine will finish writing this spec *) +let aes256_encrypt = new_definition + `aes256_encrypt (block:int128) (key_schedule:int128 list) = + let res1 = word_xor block (EL 0 key_schedule) in + let res2 = aes_sub_bytes joined_GF2 res1 in + word_xor res2 (EL 14 key_schedule) + `;; From 36397116c82d683df664755b24ece871d71bdcef Mon Sep 17 00:00:00 2001 From: Nevine Ebeid Date: Tue, 17 Jun 2025 15:30:58 -0400 Subject: [PATCH 010/132] Continuing the AES specification. --- arm/proofs/aes_encrypt_spec.ml | 251 ++++++++++++++++++++++++++++++++- x86/proofs/aes.ml | 4 +- 2 files changed, 252 insertions(+), 3 deletions(-) diff --git a/arm/proofs/aes_encrypt_spec.ml b/arm/proofs/aes_encrypt_spec.ml index 698201f52..509e5daf9 100644 --- a/arm/proofs/aes_encrypt_spec.ml +++ b/arm/proofs/aes_encrypt_spec.ml @@ -1,3 +1,4 @@ +use_file_raise_failure := true;; needs "common/aes.ml";; (* @@ -33,9 +34,255 @@ out = state end *) (* TODO: Nevine will finish writing this spec *) +(* Note: In the spec, SubBytes precedes ShiftRows, but the instruction + definition of aese in arm/proofs/aes.ml has them interchanged. + This is possible but requires a modified lookup table, joined_GF2, + from the specs. + We will follow the same pattern below as the instruction definition + TODO: prove the equivalence with the spec later.*) + +let aes256_encrypt_round = new_definition + `aes256_encrypt_round (block:int128) (round_key:int128) = + let res2 = aes_shift_rows block in + let res3 = aes_sub_bytes joined_GF2 res2 in + let res1 = aes_mix_columns res3 in + word_xor res1 round_key + `;; + +let aes256_encrypt = new_definition + `aes256_encrypt (block:int128) (key_schedule:int128 list) = + let res0 = word_xor block (EL 0 key_schedule) in + let res1 = aes256_encrypt_round res0 (EL 1 key_schedule) in + let res2 = aes256_encrypt_round res1 (EL 2 key_schedule) in + let res3 = aes256_encrypt_round res2 (EL 3 key_schedule) in + let res4 = aes256_encrypt_round res3 (EL 4 key_schedule) in + let res5 = aes256_encrypt_round res4 (EL 5 key_schedule) in + let res6 = aes256_encrypt_round res5 (EL 6 key_schedule) in + let res7 = aes256_encrypt_round res6 (EL 7 key_schedule) in + let res8 = aes256_encrypt_round res7 (EL 8 key_schedule) in + let res9 = aes256_encrypt_round res8 (EL 9 key_schedule) in + let res10 = aes256_encrypt_round res9 (EL 10 key_schedule) in + let res11 = aes256_encrypt_round res10 (EL 11 key_schedule) in + let res12 = aes256_encrypt_round res11 (EL 12 key_schedule) in + let res13 = aes256_encrypt_round res12 (EL 13 key_schedule) in + let res14 = aes_shift_rows res13 in + let res15 = aes_sub_bytes joined_GF2 res14 in + word_xor res15 (EL 14 key_schedule) + `;; + +let PRINT_TERM_CONV t = Format.printf "%a\n" pp_print_qterm t; ALL_CONV t;; + +let AESENC_ROUND_HELPER_CONV = + PRINT_TERM_CONV THENC + REWRITE_CONV [aes256_encrypt_round] THENC + PRINT_TERM_CONV THENC + AES_SHIFT_ROWS_CONV THENC + PRINT_TERM_CONV THENC + AES_SUB_BYTES_CONV THENC + AES_MIX_COLUMNS_CONV THENC + DEPTH_CONV (WORD_RED_CONV ORELSEC NUM_RED_CONV);; + +let AESENC_REDUCE_CONV tm = + match tm with + Comb(Comb(Const("aes256_encrypt_round",_), + Comb(Const("word",_),state)), + Comb(Const("word",_),roundkey)) + when is_numeral state && is_numeral roundkey -> AESENC_ROUND_HELPER_CONV tm + | _ -> failwith "AESENC_REDUCE_CONV: inapplicable";; + +prove(`aes256_encrypt_round (word 0x7b5b54657374566563746f725d53475d) + (word 0x48692853686179295b477565726f6e5d) = + word 0xa8311c2f9fdba3c58b104b58ded7e595`, + CONV_TAC(LAND_CONV AESENC_REDUCE_CONV) THEN REFL_TAC);; + +(* +https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/AES_Core256.pdf +has the same test vector as +https://www.intel.com/content/dam/doc/white-paper/advanced-encryption-standard-new-instructions-set-paper.pdf: +AES256_TEST_KEY[] = +603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4 +AES_TEST_VECTOR[] = +6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710 +ECB256_EXPECTED[] = +f3eed1bdb5d2a03c064b5a7e3db181f8591ccb10d410ed26dc5ba74a31362870b6ed21b99ca6f4f9f153e7b1beafed1d23304b7a39f9f3ff067d8d8f9e24ecc7 +*) + +let ROUND_KEYS = new_definition `ROUND_KEYS:int128 list = + [ word 0x603DEB1015CA71BE2B73AEF0857D7781 + ; word 0x1F352C073B6108D72D9810A30914DFF4 + ; word 0x9BA354118E6925AFA51A8B5F2067FCDE + ; word 0xA8B09C1A93D194CDBE49846EB75D5B9A + ; word 0xD59AECB85BF3C917FEE94248DE8EBE96 + ; word 0xB5A9328A2678A647983122292F6C79B3 + ; word 0x812C81ADDADF48BA24360AF2FAB8B464 + ; word 0x98C5BFC9BEBD198E268C3BA709E04214 + ; word 0x68007BACB2DF331696E939E46C518D80 + ; word 0xC814E20476A9FB8A5025C02D59C58239 + ; word 0xDE1369676CCC5A71FA2563959674EE15 + ; word 0x5886CA5D2E2F31D77E0AF1FA27CF73C3 + ; word 0x749C47AB18501DDAE2757E4F7401905A + ; word 0xCAFAAAE3E4D59B349ADF6ACEBD10190D + ; word 0xFE4890D1E6188D0B046DF344706C631E + ]`;; + +let EL_15_128_CLAUSES = + let pat = `EL n [x0;x1;x2;x3;x4;x5;x6;x7;x8;x9;x10;x11;x12;x13;x14]:128 word` in + map (fun n -> EL_CONV(subst [mk_small_numeral n,`n:num`] pat)) (0--14);; + +REWRITE_CONV [ROUND_KEYS] + `let res0 = + word_xor (word 143233380420387077518460912116591433514) (EL 0 ROUND_KEYS) in + let res1 = aes256_encrypt_round res0 (EL 1 ROUND_KEYS) in + let res2 = aes256_encrypt_round res1 (EL 2 ROUND_KEYS) in + let res3 = aes256_encrypt_round res2 (EL 3 ROUND_KEYS) in + let res4 = aes256_encrypt_round res3 (EL 4 ROUND_KEYS) in + let res5 = aes256_encrypt_round res4 (EL 5 ROUND_KEYS) in + let res6 = aes256_encrypt_round res5 (EL 6 ROUND_KEYS) in + let res7 = aes256_encrypt_round res6 (EL 7 ROUND_KEYS) in + let res8 = aes256_encrypt_round res7 (EL 8 ROUND_KEYS) in + let res9 = aes256_encrypt_round res8 (EL 9 ROUND_KEYS) in + let res10 = aes256_encrypt_round res9 (EL 10 ROUND_KEYS) in + let res11 = aes256_encrypt_round res10 (EL 11 ROUND_KEYS) in + let res12 = aes256_encrypt_round res11 (EL 12 ROUND_KEYS) in + let res13 = aes256_encrypt_round res12 (EL 13 ROUND_KEYS) in + let res14 = aes_shift_rows res13 in + let res15 = aes_sub_bytes joined_GF2 res14 in + word_xor res15 (EL 14 ROUND_KEYS)`;; + +let AESENC_HELPER_CONV = + PRINT_TERM_CONV THENC + REWR_CONV aes256_encrypt THENC + PRINT_TERM_CONV THENC + REWRITE_CONV [ROUND_KEYS] THENC + PRINT_TERM_CONV THENC + REWRITE_CONV EL_15_128_CLAUSES THENC + PRINT_TERM_CONV THENC + (*REPEATC let_CONV THENC*) + PRINT_TERM_CONV THENC + DEPTH_CONV (WORD_RED_CONV ORELSEC NUM_RED_CONV) THENC + ONCE_DEPTH_CONV AESENC_ROUND_HELPER_CONV + ;; + +(* +let AESENC_HELPER_CONV = + PRINT_TERM_CONV THENC + REWR_CONV aes256_encrypt THENC + PRINT_TERM_CONV THENC + REWRITE_CONV [ROUND_KEYS] THENC + PRINT_TERM_CONV THENC + REWRITE_CONV EL_15_128_CLAUSES THENC + PRINT_TERM_CONV THENC + REPEATC let_CONV THENC + PRINT_TERM_CONV THENC + DEPTH_CONV (WORD_RED_CONV ORELSEC NUM_RED_CONV) THENC + ;; +evaluates to +` +word_xor +(aes_sub_bytes joined_GF2 +(aes_shift_rows +(aes256_encrypt_round + (aes256_encrypt_round + (aes256_encrypt_round + (aes256_encrypt_round + (aes256_encrypt_round + (aes256_encrypt_round + (aes256_encrypt_round + (aes256_encrypt_round + (aes256_encrypt_round + (aes256_encrypt_round + (aes256_encrypt_round + (aes256_encrypt_round + (aes256_encrypt_round + (word_xor (word 143233380420387077518460912116591433514) + (word 127927385344373932012120245488993531777)) + (word 41482152601831359329908363118012325876)) + (word 206878388847962593259677505409113390302)) + (word 224227313700546055987490685253953870746)) + (word 283929978073507663308377981111166221974)) + (word 241468790472035055121896954896908581299)) + (word 171701502723078332096379282178375726180)) + (word 203069427764564296087722130005204943380)) + (word 138242219980614615854290912811605396864)) + (word 265954029272361673955751890726720733753)) + (word 295189406551744036947605646357814373909)) + (word 117671935837368680518160876205111210947)) + (word 155001899427603818862311956147060445274)) +(word 269805595428433041131718239175312414989)))) +(word 338000693600063263164096359463337616158)` +*) + +let tmp = AESENC_HELPER_CONV + `aes256_encrypt + (word 0x6bc1bee22e409f96e93d7e117393172a) + ROUND_KEYS`;; +(* +let AESENC_REDUCE_CONV tm = + match tm with + Comb(Comb(Const("aes256_encrypt",_), + Comb(Const("word",_),state)), + Comb(Const("word",_),roundkey)) + when is_numeral state && is_numeral roundkey -> AESENC_HELPER_CONV tm + | _ -> failwith "AESENC_REDUCE_CONV: inapplicable";; +*) +(* let aes256_encrypt = new_definition `aes256_encrypt (block:int128) (key_schedule:int128 list) = let res1 = word_xor block (EL 0 key_schedule) in - let res2 = aes_sub_bytes joined_GF2 res1 in - word_xor res2 (EL 14 key_schedule) + let res2 = aes_shift_rows res1 in + let res3 = aes_sub_bytes joined_GF2 res2 in + let res4 = aes_mix_columns res3 in + let res5 = word_xor res4 (EL 1 key_schedule) in + let res6 = aes_shift_rows res5 in + let res7 = aes_sub_bytes joined_GF2 res6 in + let res8 = aes_mix_columns res7 in + let res9 = word_xor res8 (EL 2 key_schedule) in + let res10 = aes_shift_rows res9 in + let res11 = aes_sub_bytes joined_GF2 res10 in + let res12 = aes_mix_columns res11 in + let res13 = word_xor res12 (EL 3 key_schedule) in + let res14 = aes_shift_rows res13 in + let res15 = aes_sub_bytes joined_GF2 res14 in + let res16 = aes_mix_columns res15 in + let res17 = word_xor res16 (EL 4 key_schedule) in + let res18 = aes_shift_rows res17 in + let res19 = aes_sub_bytes joined_GF2 res18 in + let res20 = aes_mix_columns res19 in + let res21 = word_xor res20 (EL 5 key_schedule) in + let res22 = aes_shift_rows res21 in + let res23 = aes_sub_bytes joined_GF2 res22 in + let res24 = aes_mix_columns res23 in + let res25 = word_xor res24 (EL 6 key_schedule) in + let res26 = aes_shift_rows res25 in + let res27 = aes_sub_bytes joined_GF2 res26 in + let res28 = aes_mix_columns res27 in + let res29 = word_xor res28 (EL 7 key_schedule) in + let res30 = aes_shift_rows res29 in + let res31 = aes_sub_bytes joined_GF2 res30 in + let res32 = aes_mix_columns res31 in + let res33 = word_xor res32 (EL 8 key_schedule) in + let res34 = aes_shift_rows res33 in + let res35 = aes_sub_bytes joined_GF2 res34 in + let res36 = aes_mix_columns res35 in + let res37 = word_xor res36 (EL 9 key_schedule) in + let res38 = aes_shift_rows res37 in + let res39 = aes_sub_bytes joined_GF2 res38 in + let res40 = aes_mix_columns res39 in + let res41 = word_xor res40 (EL 10 key_schedule) in + let res42 = aes_shift_rows res41 in + let res43 = aes_sub_bytes joined_GF2 res42 in + let res44 = aes_mix_columns res43 in + let res45 = word_xor res44 (EL 11 key_schedule) in + let res46 = aes_shift_rows res45 in + let res47 = aes_sub_bytes joined_GF2 res46 in + let res48 = aes_mix_columns res47 in + let res49 = word_xor res48 (EL 12 key_schedule) in + let res50 = aes_shift_rows res49 in + let res51 = aes_sub_bytes joined_GF2 res50 in + let res52 = aes_mix_columns res51 in + let res53 = word_xor res52 (EL 13 key_schedule) in + let res54 = aes_shift_rows res53 in + let res55 = aes_sub_bytes joined_GF2 res54 in + word_xor res55 (EL 14 key_schedule) `;; +*) diff --git a/x86/proofs/aes.ml b/x86/proofs/aes.ml index 9c3fc94d3..5af731137 100644 --- a/x86/proofs/aes.ml +++ b/x86/proofs/aes.ml @@ -127,7 +127,9 @@ let AESKEYGENASSIST_REDUCE_CONV tm = (** TESTS **) (************************************************) (* From White Paper: - Intel Advanced Encryption Standard (AES) New Instructions Set *) + Intel Advanced Encryption Standard (AES) New Instructions Set + https://www.intel.com/content/dam/doc/white-paper/advanced-encryption-standard-new-instructions-set-paper.pdf + Fig 11. AESENC Example to Fig 14 AESDECLAST Example *) prove(`aesenc (word 0x7b5b54657374566563746f725d53475d) (word 0x48692853686179295b477565726f6e5d) = From 9b134b2ff2e561fd2ab6005037ce4b2306725665 Mon Sep 17 00:00:00 2001 From: Nevine Ebeid Date: Thu, 19 Jun 2025 14:00:02 -0400 Subject: [PATCH 011/132] The spec test vector succeeds after converting the inputs to little endian representation. --- arm/proofs/aes_encrypt_spec.ml | 223 ++++++++++++--------------------- 1 file changed, 78 insertions(+), 145 deletions(-) diff --git a/arm/proofs/aes_encrypt_spec.ml b/arm/proofs/aes_encrypt_spec.ml index 509e5daf9..320320762 100644 --- a/arm/proofs/aes_encrypt_spec.ml +++ b/arm/proofs/aes_encrypt_spec.ml @@ -1,6 +1,11 @@ use_file_raise_failure := true;; needs "common/aes.ml";; +let pp_print_num fmt tm = + let n = dest_numeral tm in + pp_print_string fmt (string_of_num_hex n) in +install_user_printer("pp_print_num",pp_print_num);; + (* Cipher(byte in[4*Nb], byte out[4*Nb], word w[Nb*(Nr+1)]) @@ -73,13 +78,15 @@ let aes256_encrypt = new_definition let PRINT_TERM_CONV t = Format.printf "%a\n" pp_print_qterm t; ALL_CONV t;; let AESENC_ROUND_HELPER_CONV = - PRINT_TERM_CONV THENC + PRINT_TERM_CONV THENC REWRITE_CONV [aes256_encrypt_round] THENC - PRINT_TERM_CONV THENC + (*PRINT_TERM_CONV THENC*) AES_SHIFT_ROWS_CONV THENC - PRINT_TERM_CONV THENC + (*PRINT_TERM_CONV THENC*) AES_SUB_BYTES_CONV THENC + PRINT_TERM_CONV THENC AES_MIX_COLUMNS_CONV THENC + PRINT_TERM_CONV THENC DEPTH_CONV (WORD_RED_CONV ORELSEC NUM_RED_CONV);; let AESENC_REDUCE_CONV tm = @@ -95,43 +102,69 @@ prove(`aes256_encrypt_round (word 0x7b5b54657374566563746f725d53475d) word 0xa8311c2f9fdba3c58b104b58ded7e595`, CONV_TAC(LAND_CONV AESENC_REDUCE_CONV) THEN REFL_TAC);; +prove(`aes256_encrypt_round (word 0xAB60EEF6E1D04EC228EE8A3BF255FC0B) + (word 0xF4DF1409A310982DD708613B072C351F) = + word 0x416EAD9670A2C6D71CFE3FCCB03F10D9`, + CONV_TAC(LAND_CONV AESENC_REDUCE_CONV) THEN REFL_TAC);; + (* https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/AES_Core256.pdf has the same test vector as -https://www.intel.com/content/dam/doc/white-paper/advanced-encryption-standard-new-instructions-set-paper.pdf: +https://www.intel.com/content/dam/doc/white-paper/advanced-encryption-standard-new-instructions-set-paper.pdf +The vector values appear in the code in reverse byte order to be little endian. + AES256_TEST_KEY[] = -603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4 +603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4 AES_TEST_VECTOR[] = -6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710 +6BC1BEE22E409F96E93D7E117393172A ECB256_EXPECTED[] = -f3eed1bdb5d2a03c064b5a7e3db181f8591ccb10d410ed26dc5ba74a31362870b6ed21b99ca6f4f9f153e7b1beafed1d23304b7a39f9f3ff067d8d8f9e24ecc7 +F3EED1BDB5D2A03C064B5A7E3DB181F8 + +Round keys in big endian generated from the key via a python code +Round 0: 603DEB1015CA71BE2B73AEF0857D7781 +Round 1: 1F352C073B6108D72D9810A30914DFF4 +Round 2: 9BA354118E6925AFA51A8B5F2067FCDE +Round 3: A8B09C1A93D194CDBE49846EB75D5B9A +Round 4: D59AECB85BF3C917FEE94248DE8EBE96 +Round 5: B5A9328A2678A647983122292F6C79B3 +Round 6: 812C81ADDADF48BA24360AF2FAB8B464 +Round 7: 98C5BFC9BEBD198E268C3BA709E04214 +Round 8: 68007BACB2DF331696E939E46C518D80 +Round 9: C814E20476A9FB8A5025C02D59C58239 +Round 10: DE1369676CCC5A71FA2563959674EE15 +Round 11: 5886CA5D2E2F31D77E0AF1FA27CF73C3 +Round 12: 749C47AB18501DDAE2757E4F7401905A +Round 13: CAFAAAE3E4D59B349ADF6ACEBD10190D +Round 14: FE4890D1E6188D0B046DF344706C631E *) +(* These are the ound keys with the bytes reversed to become little endian *) let ROUND_KEYS = new_definition `ROUND_KEYS:int128 list = - [ word 0x603DEB1015CA71BE2B73AEF0857D7781 - ; word 0x1F352C073B6108D72D9810A30914DFF4 - ; word 0x9BA354118E6925AFA51A8B5F2067FCDE - ; word 0xA8B09C1A93D194CDBE49846EB75D5B9A - ; word 0xD59AECB85BF3C917FEE94248DE8EBE96 - ; word 0xB5A9328A2678A647983122292F6C79B3 - ; word 0x812C81ADDADF48BA24360AF2FAB8B464 - ; word 0x98C5BFC9BEBD198E268C3BA709E04214 - ; word 0x68007BACB2DF331696E939E46C518D80 - ; word 0xC814E20476A9FB8A5025C02D59C58239 - ; word 0xDE1369676CCC5A71FA2563959674EE15 - ; word 0x5886CA5D2E2F31D77E0AF1FA27CF73C3 - ; word 0x749C47AB18501DDAE2757E4F7401905A - ; word 0xCAFAAAE3E4D59B349ADF6ACEBD10190D - ; word 0xFE4890D1E6188D0B046DF344706C631E + [ word 0x81777D85F0AE732BBE71CA1510EB3D60 + ; word 0xF4DF1409A310982DD708613B072C351F + ; word 0xDEFC67205F8B1AA5AF25698E1154A39B + ; word 0x9A5B5DB76E8449BECD94D1931A9CB0A8 + ; word 0x96BE8EDE4842E9FE17C9F35BB8EC9AD5 + ; word 0xB3796C2F2922319847A678268A32A9B5 + ; word 0x64B4B8FAF20A3624BA48DFDAAD812C81 + ; word 0x1442E009A73B8C268E19BDBEC9BFC598 + ; word 0x808D516CE439E9961633DFB2AC7B0068 + ; word 0x3982C5592DC025508AFBA97604E214C8 + ; word 0x15EE7496956325FA715ACC6C676913DE + ; word 0xC373CF27FAF10A7ED7312F2E5DCA8658 + ; word 0x5A9001744F7E75E2DA1D5018AB479C74 + ; word 0x0D1910BDCE6ADF9A349BD5E4E3AAFACA + ; word 0x1E636C7044F36D040B8D18E6D19048FE ]`;; + let EL_15_128_CLAUSES = let pat = `EL n [x0;x1;x2;x3;x4;x5;x6;x7;x8;x9;x10;x11;x12;x13;x14]:128 word` in map (fun n -> EL_CONV(subst [mk_small_numeral n,`n:num`] pat)) (0--14);; REWRITE_CONV [ROUND_KEYS] `let res0 = - word_xor (word 143233380420387077518460912116591433514) (EL 0 ROUND_KEYS) in + word_xor (word 143233380420387077518460912116591433514) (EL 0 ROUND_KEYS) in let res1 = aes256_encrypt_round res0 (EL 1 ROUND_KEYS) in let res2 = aes256_encrypt_round res1 (EL 2 ROUND_KEYS) in let res3 = aes256_encrypt_round res2 (EL 3 ROUND_KEYS) in @@ -152,137 +185,37 @@ REWRITE_CONV [ROUND_KEYS] let AESENC_HELPER_CONV = PRINT_TERM_CONV THENC REWR_CONV aes256_encrypt THENC - PRINT_TERM_CONV THENC +(* PRINT_TERM_CONV THENC *) REWRITE_CONV [ROUND_KEYS] THENC - PRINT_TERM_CONV THENC - REWRITE_CONV EL_15_128_CLAUSES THENC - PRINT_TERM_CONV THENC - (*REPEATC let_CONV THENC*) - PRINT_TERM_CONV THENC - DEPTH_CONV (WORD_RED_CONV ORELSEC NUM_RED_CONV) THENC - ONCE_DEPTH_CONV AESENC_ROUND_HELPER_CONV - ;; - -(* -let AESENC_HELPER_CONV = - PRINT_TERM_CONV THENC - REWR_CONV aes256_encrypt THENC - PRINT_TERM_CONV THENC - REWRITE_CONV [ROUND_KEYS] THENC - PRINT_TERM_CONV THENC +(* PRINT_TERM_CONV THENC *) REWRITE_CONV EL_15_128_CLAUSES THENC - PRINT_TERM_CONV THENC +(* PRINT_TERM_CONV THENC *) REPEATC let_CONV THENC - PRINT_TERM_CONV THENC DEPTH_CONV (WORD_RED_CONV ORELSEC NUM_RED_CONV) THENC + DEPTH_CONV AESENC_REDUCE_CONV THENC + AES_SHIFT_ROWS_CONV THENC + AES_SUB_BYTES_CONV THENC + PRINT_TERM_CONV THENC + DEPTH_CONV (WORD_RED_CONV ORELSEC NUM_RED_CONV) ;; -evaluates to -` -word_xor -(aes_sub_bytes joined_GF2 -(aes_shift_rows -(aes256_encrypt_round - (aes256_encrypt_round - (aes256_encrypt_round - (aes256_encrypt_round - (aes256_encrypt_round - (aes256_encrypt_round - (aes256_encrypt_round - (aes256_encrypt_round - (aes256_encrypt_round - (aes256_encrypt_round - (aes256_encrypt_round - (aes256_encrypt_round - (aes256_encrypt_round - (word_xor (word 143233380420387077518460912116591433514) - (word 127927385344373932012120245488993531777)) - (word 41482152601831359329908363118012325876)) - (word 206878388847962593259677505409113390302)) - (word 224227313700546055987490685253953870746)) - (word 283929978073507663308377981111166221974)) - (word 241468790472035055121896954896908581299)) - (word 171701502723078332096379282178375726180)) - (word 203069427764564296087722130005204943380)) - (word 138242219980614615854290912811605396864)) - (word 265954029272361673955751890726720733753)) - (word 295189406551744036947605646357814373909)) - (word 117671935837368680518160876205111210947)) - (word 155001899427603818862311956147060445274)) -(word 269805595428433041131718239175312414989)))) -(word 338000693600063263164096359463337616158)` -*) +(* +(* This proof works and takes about half a minute on an M3 *) let tmp = AESENC_HELPER_CONV `aes256_encrypt - (word 0x6bc1bee22e409f96e93d7e117393172a) + (word 0x2A179373117E3DE9969F402EE2BEC16B) ROUND_KEYS`;; -(* -let AESENC_REDUCE_CONV tm = - match tm with - Comb(Comb(Const("aes256_encrypt",_), - Comb(Const("word",_),state)), - Comb(Const("word",_),roundkey)) - when is_numeral state && is_numeral roundkey -> AESENC_HELPER_CONV tm - | _ -> failwith "AESENC_REDUCE_CONV: inapplicable";; + +prove(list_mk_comb (`(=):((128)word->(128)word->bool)`, + [rand (concl tmp);`(word 0xf881b13d7e5a4b063ca0d2b5bdd1eef3):(128)word`]), + REFL_TAC);; *) + (* -let aes256_encrypt = new_definition - `aes256_encrypt (block:int128) (key_schedule:int128 list) = - let res1 = word_xor block (EL 0 key_schedule) in - let res2 = aes_shift_rows res1 in - let res3 = aes_sub_bytes joined_GF2 res2 in - let res4 = aes_mix_columns res3 in - let res5 = word_xor res4 (EL 1 key_schedule) in - let res6 = aes_shift_rows res5 in - let res7 = aes_sub_bytes joined_GF2 res6 in - let res8 = aes_mix_columns res7 in - let res9 = word_xor res8 (EL 2 key_schedule) in - let res10 = aes_shift_rows res9 in - let res11 = aes_sub_bytes joined_GF2 res10 in - let res12 = aes_mix_columns res11 in - let res13 = word_xor res12 (EL 3 key_schedule) in - let res14 = aes_shift_rows res13 in - let res15 = aes_sub_bytes joined_GF2 res14 in - let res16 = aes_mix_columns res15 in - let res17 = word_xor res16 (EL 4 key_schedule) in - let res18 = aes_shift_rows res17 in - let res19 = aes_sub_bytes joined_GF2 res18 in - let res20 = aes_mix_columns res19 in - let res21 = word_xor res20 (EL 5 key_schedule) in - let res22 = aes_shift_rows res21 in - let res23 = aes_sub_bytes joined_GF2 res22 in - let res24 = aes_mix_columns res23 in - let res25 = word_xor res24 (EL 6 key_schedule) in - let res26 = aes_shift_rows res25 in - let res27 = aes_sub_bytes joined_GF2 res26 in - let res28 = aes_mix_columns res27 in - let res29 = word_xor res28 (EL 7 key_schedule) in - let res30 = aes_shift_rows res29 in - let res31 = aes_sub_bytes joined_GF2 res30 in - let res32 = aes_mix_columns res31 in - let res33 = word_xor res32 (EL 8 key_schedule) in - let res34 = aes_shift_rows res33 in - let res35 = aes_sub_bytes joined_GF2 res34 in - let res36 = aes_mix_columns res35 in - let res37 = word_xor res36 (EL 9 key_schedule) in - let res38 = aes_shift_rows res37 in - let res39 = aes_sub_bytes joined_GF2 res38 in - let res40 = aes_mix_columns res39 in - let res41 = word_xor res40 (EL 10 key_schedule) in - let res42 = aes_shift_rows res41 in - let res43 = aes_sub_bytes joined_GF2 res42 in - let res44 = aes_mix_columns res43 in - let res45 = word_xor res44 (EL 11 key_schedule) in - let res46 = aes_shift_rows res45 in - let res47 = aes_sub_bytes joined_GF2 res46 in - let res48 = aes_mix_columns res47 in - let res49 = word_xor res48 (EL 12 key_schedule) in - let res50 = aes_shift_rows res49 in - let res51 = aes_sub_bytes joined_GF2 res50 in - let res52 = aes_mix_columns res51 in - let res53 = word_xor res52 (EL 13 key_schedule) in - let res54 = aes_shift_rows res53 in - let res55 = aes_sub_bytes joined_GF2 res54 in - word_xor res55 (EL 14 key_schedule) - `;; +(* This other form of the proof works as well in half a minute *) +time prove (`aes256_encrypt + (word 0x2A179373117E3DE9969F402EE2BEC16B) + ROUND_KEYS = word 0xF881B13D7E5A4B063CA0D2B5BDD1EEF3`, + CONV_TAC(LAND_CONV AESENC_HELPER_CONV) THEN REFL_TAC);; *) + From 69dab0b1a341abb3f3a13a7a19293099a8fcc8a9 Mon Sep 17 00:00:00 2001 From: Nevine Ebeid Date: Tue, 24 Jun 2025 14:59:34 -0400 Subject: [PATCH 012/132] Post conditions and MAYCHANGE for an AES block encryption proof. --- arm/aes-xts/Makefile | 11 ++++++-- arm/aes-xts/aes256_encrypt.S | 2 +- arm/proofs/aes_encrypt.ml | 54 +++++++++++++++++++----------------- 3 files changed, 39 insertions(+), 28 deletions(-) diff --git a/arm/aes-xts/Makefile b/arm/aes-xts/Makefile index 235542c76..993cc6ec4 100644 --- a/arm/aes-xts/Makefile +++ b/arm/aes-xts/Makefile @@ -11,13 +11,20 @@ # # sudo apt-get install binutils-aarch64-linux-gnu -UNAME_RESULT=$(shell uname -p) +#UNAME_RESULT=$(shell uname -p) +OSTYPE_RESULT=$(shell uname -s) +ARCHTYPE_RESULT=$(shell uname -m) -ifeq ($(UNAME_RESULT),aarch64) +ifeq ($(ARCHTYPE_RESULT),aarch64) GAS=as else +ifeq ($(OSTYPE_RESULT),Darwin) +GAS=as -arch arm64 +OBJDUMP=otool -tvV +else GAS=aarch64-linux-gnu-as endif +endif # List of object files diff --git a/arm/aes-xts/aes256_encrypt.S b/arm/aes-xts/aes256_encrypt.S index b32b1498e..775da2f60 100644 --- a/arm/aes-xts/aes256_encrypt.S +++ b/arm/aes-xts/aes256_encrypt.S @@ -28,7 +28,7 @@ Loop_enc_iv_enc: aese v6.16b,v0.16b aesmc v6.16b,v6.16b - ld1 {v0.4s},[x4] + ld1 {v0.4s},[x2] aese v6.16b,v1.16b eor v6.16b,v6.16b,v0.16b st1 {v6.4s},[x0] diff --git a/arm/proofs/aes_encrypt.ml b/arm/proofs/aes_encrypt.ml index e055835ed..0736296a7 100644 --- a/arm/proofs/aes_encrypt.ml +++ b/arm/proofs/aes_encrypt.ml @@ -20,7 +20,7 @@ let aes256_encrypt_mc = define_assert_from_elf "aes256_encrypt_mc" "arm/aes-xts/ 0x54ffff2c; (* arm_BGT (word 2097124) *) 0x4e284806; (* arm_AESE Q6 Q0 *) 0x4e2868c6; (* arm_AESMC Q6 Q6 *) - 0x4c407880; (* arm_LDR Q0 X4 No_Offset *) + 0x4c407840; (* arm_LDR Q0 X2 No_Offset *) 0x4e284826; (* arm_AESE Q6 Q1 *) 0x6e201cc6; (* arm_EOR_VEC Q6 Q6 Q0 128 *) 0x4c007806 (* arm_STR Q6 X0 No_Offset *) @@ -29,37 +29,41 @@ let aes256_encrypt_mc = define_assert_from_elf "aes256_encrypt_mc" "arm/aes-xts/ let AES256_ENCRYPT_EXEC = ARM_MK_EXEC_RULE aes256_encrypt_mc;; (* TODO: Could this be better? read(memory :> bytes(key, 240) = all_k) *) + let AES256_ENCRYPT_CORRECT = prove( - `!out in key ib k0 k1 k2 k3 k4 k5 k6 k7 k8 k9 k10 k11 k12 k13 k14 pc. - nonoverlapping (word pc,LENGTH aes256_encrypt_mc) (out,16) + `!ciphertext plaintext key ib k0 k1 k2 k3 k4 k5 k6 k7 k8 k9 k10 k11 k12 k13 k14 pc. + nonoverlapping (word pc,LENGTH aes256_encrypt_mc) (ciphertext,16) ==> ensures arm // precondition (\s. aligned_bytes_loaded s (word pc) aes256_encrypt_mc /\ read PC s = word pc /\ - C_ARGUMENTS [out; in; key] s /\ - read(memory :> bytes(in, 16)) s = ib /\ - read(memory :> bytes(word_add key (word 240), 4)) = word 13 /\ - read(memory :> bytes(key, 16)) = k0 /\ - read(memory :> bytes((word_add key (word 16)), 16)) = k1 /\ - read(memory :> bytes((word_add key (word 32)), 16)) = k2 /\ - read(memory :> bytes((word_add key (word 48)), 16)) = k3 /\ - read(memory :> bytes((word_add key (word 64)), 16)) = k4 /\ - read(memory :> bytes((word_add key (word 80)), 16)) = k5 /\ - read(memory :> bytes((word_add key (word 96)), 16)) = k6 /\ - read(memory :> bytes((word_add key (word 112)), 16)) = k7 /\ - read(memory :> bytes((word_add key (word 128)), 16)) = k8 /\ - read(memory :> bytes((word_add key (word 144)), 16)) = k9 /\ - read(memory :> bytes((word_add key (word 160)), 16)) = k10 /\ - read(memory :> bytes((word_add key (word 176)), 16)) = k11 /\ - read(memory :> bytes((word_add key (word 192)), 16)) = k12 /\ - read(memory :> bytes((word_add key (word 208)), 16)) = k13 /\ - read(memory :> bytes((word_add key (word 224)), 16)) = k14) + C_ARGUMENTS [ciphertext; plaintext; key] s /\ + read(memory :> bytes(plaintext, 16)) s = ib /\ + read(memory :> bytes(word_add key (word 240), 4)) s = 14 /\ + read(memory :> bytes128 key) s = k0 /\ + read(memory :> bytes128 (word_add key (word 16))) s = k1 /\ + read(memory :> bytes128 (word_add key (word 32))) s = k2 /\ + read(memory :> bytes128 (word_add key (word 48))) s = k3 /\ + read(memory :> bytes128 (word_add key (word 64))) s = k4 /\ + read(memory :> bytes128 (word_add key (word 80))) s = k5 /\ + read(memory :> bytes128 (word_add key (word 96))) s = k6 /\ + read(memory :> bytes128 (word_add key (word 112))) s = k7 /\ + read(memory :> bytes128 (word_add key (word 128))) s = k8 /\ + read(memory :> bytes128 (word_add key (word 144))) s = k9 /\ + read(memory :> bytes128 (word_add key (word 160))) s = k10 /\ + read(memory :> bytes128 (word_add key (word 176))) s = k11 /\ + read(memory :> bytes128 (word_add key (word 192))) s = k12 /\ + read(memory :> bytes128 (word_add key (word 208))) s = k13 /\ + read(memory :> bytes128 (word_add key (word 224))) s = k14 + ) // postcondition // TODO: Nevine will figure out the post condition for output // hint: use the aes256_encrypt from aes_encrypt_spec (\s. read PC s = word (pc + LENGTH aes256_encrypt_mc) /\ - ) - // MAYCHANGE - ()`, + read(memory :> bytes128 ciphertext) s = + aes256_encrypt (word ib) + [k0; k1; k2; k3; k4; k5; k6; k7; k8; k9; k10; k11; k12; k13; k14] + ) + (MAYCHANGE [PC;X2],, MAYCHANGE [Q0;Q1;Q6],, MAYCHANGE [W6])`, CHEAT_TAC -) \ No newline at end of file +);; From 4bd82d11550e30c0e01e75001b5df90f10c94601 Mon Sep 17 00:00:00 2001 From: Nevine Ebeid Date: Wed, 25 Jun 2025 19:34:07 -0400 Subject: [PATCH 013/132] Proof of AES encryption of one block. --- arm/proofs/aes_encrypt.ml | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/arm/proofs/aes_encrypt.ml b/arm/proofs/aes_encrypt.ml index 0736296a7..25c278ab8 100644 --- a/arm/proofs/aes_encrypt.ml +++ b/arm/proofs/aes_encrypt.ml @@ -38,8 +38,8 @@ let AES256_ENCRYPT_CORRECT = prove( (\s. aligned_bytes_loaded s (word pc) aes256_encrypt_mc /\ read PC s = word pc /\ C_ARGUMENTS [ciphertext; plaintext; key] s /\ - read(memory :> bytes(plaintext, 16)) s = ib /\ - read(memory :> bytes(word_add key (word 240), 4)) s = 14 /\ + read(memory :> bytes128 plaintext) s = ib /\ + read(memory :> bytes32 (word_add key (word 240))) s = word 14 /\ read(memory :> bytes128 key) s = k0 /\ read(memory :> bytes128 (word_add key (word 16))) s = k1 /\ read(memory :> bytes128 (word_add key (word 32))) s = k2 /\ @@ -61,9 +61,31 @@ let AES256_ENCRYPT_CORRECT = prove( // hint: use the aes256_encrypt from aes_encrypt_spec (\s. read PC s = word (pc + LENGTH aes256_encrypt_mc) /\ read(memory :> bytes128 ciphertext) s = - aes256_encrypt (word ib) + aes256_encrypt ib [k0; k1; k2; k3; k4; k5; k6; k7; k8; k9; k10; k11; k12; k13; k14] ) - (MAYCHANGE [PC;X2],, MAYCHANGE [Q0;Q1;Q6],, MAYCHANGE [W6])`, - CHEAT_TAC + (MAYCHANGE [PC;X2;X6],, MAYCHANGE [Q0;Q1;Q6],, MAYCHANGE [events],, + MAYCHANGE SOME_FLAGS,, MAYCHANGE [memory :> bytes128 ciphertext])`, + REWRITE_TAC[NONOVERLAPPING_CLAUSES; C_ARGUMENTS; SOME_FLAGS] THEN + REWRITE_TAC [(REWRITE_CONV [aes256_encrypt_mc] THENC LENGTH_CONV) `LENGTH aes256_encrypt_mc`] THEN + REPEAT STRIP_TAC THEN + ENSURES_INIT_TAC "s0" THEN + ARM_STEPS_TAC AES256_ENCRYPT_EXEC (1--5) THEN + (* 1 loop iteration is 8 steps *) + ARM_STEPS_TAC AES256_ENCRYPT_EXEC (6--13) THEN + (* 5 more iterations = 8*5 = 40 steps *) + ARM_STEPS_TAC AES256_ENCRYPT_EXEC (14--53) THEN + (* 6 final steps *) + ARM_STEPS_TAC AES256_ENCRYPT_EXEC (54--58) THEN + ARM_STEPS_TAC AES256_ENCRYPT_EXEC (59--59) THEN + ENSURES_FINAL_STATE_TAC THEN + ASM_REWRITE_TAC[] THEN + REWRITE_TAC [aes256_encrypt] THEN + REWRITE_TAC EL_15_128_CLAUSES THEN + REWRITE_TAC [aes256_encrypt_round; aese; aesmc] + CONV_TAC (TOP_DEPTH_CONV let_CONV) THEN + BITBLAST_TAC + (* Alternatively, use the XOR symmetry + GEN_REWRITE_TAC LAND_CONV [WORD_XOR_SYM] THEN + REFL_TAC *) );; From a1c9c3c5dbf1ee4ab95e0bd2c52c07ca35deba1f Mon Sep 17 00:00:00 2001 From: Yan Peng Date: Mon, 23 Jun 2025 22:49:56 +0000 Subject: [PATCH 014/132] Add aes-xts decrypt programs --- arm/aes-xts/Makefile | 4 +- arm/aes-xts/aes256_decrypt.S | 0 arm/aes-xts/aes_xts_decrypt_armv8.S | 702 +++++++++++++++++++++++++++ arm/proofs/aes_decrypt.ml | 13 + arm/proofs/aes_xts_decrypt.ml | 724 ++++++++++++++++++++++++++++ 5 files changed, 1442 insertions(+), 1 deletion(-) create mode 100644 arm/aes-xts/aes256_decrypt.S create mode 100644 arm/aes-xts/aes_xts_decrypt_armv8.S create mode 100644 arm/proofs/aes_decrypt.ml create mode 100644 arm/proofs/aes_xts_decrypt.ml diff --git a/arm/aes-xts/Makefile b/arm/aes-xts/Makefile index 993cc6ec4..4d41cd311 100644 --- a/arm/aes-xts/Makefile +++ b/arm/aes-xts/Makefile @@ -28,7 +28,9 @@ endif # List of object files -OBJ = aes256_encrypt.o +OBJ = aes256_encrypt.o \ + aes256_decrypt.o \ + aes_xts_decrypt_armv8.o %.o : %.S ; $(CC) -E -I../../include $< | $(GAS) -o $@ - diff --git a/arm/aes-xts/aes256_decrypt.S b/arm/aes-xts/aes256_decrypt.S new file mode 100644 index 000000000..e69de29bb diff --git a/arm/aes-xts/aes_xts_decrypt_armv8.S b/arm/aes-xts/aes_xts_decrypt_armv8.S new file mode 100644 index 000000000..492f6df83 --- /dev/null +++ b/arm/aes-xts/aes_xts_decrypt_armv8.S @@ -0,0 +1,702 @@ +############################################################################# +# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +# SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT-0 +# TODO: figure out copyright +############################################################################# + +#include "_internal_s2n_bignum.h" + + S2N_BN_SYM_VISIBILITY_DIRECTIVE(aes_hw_xts_decrypt) + S2N_BN_SYM_PRIVACY_DIRECTIVE(aes_hw_xts_decrypt) + .text + .balign 4 + .arch armv8-a+crypto + +#define STACK_BASE_VREGS 0 +#define STACK_SIZE_VREGS (4*16) + +.macro save_vregs + stp d8,d9,[sp,#(STACK_BASE_VREGS + 16*0)] + stp d10,d11,[sp,#(STACK_BASE_VREGS + 16*1)] +.endm + +.macro save_regs + stp x19,x20,[sp,#(STACK_BASE_VREGS + 16*2)] + stp x21,x22,[sp,#(STACK_BASE_VREGS + 16*3)] +.endm + +.macro restore_vregs + ldp d8,d9,[sp,#(STACK_BASE_VREGS + 16*0)] + ldp d10,d11,[sp,#(STACK_BASE_VREGS + 16*1)] +.endm + +.macro restore_regs + ldp x19,x20,[sp,#(STACK_BASE_VREGS + 16*2)] + ldp x21,x22,[sp,#(STACK_BASE_VREGS + 16*3)] +.endm + +// A single AES round +// Prevent SLOTHY from unfolding because uArchs tend to fuse AESMC+AESE +.macro aesr data, key // @slothy:no-unfold + aese \data, \key + aesmc \data, \data +.endm + +// A single AESD round +// Prevent SLOTHY from unfolding because uArchs tend to fuse AESIMC+AESD +.macro aesdr data, key // @slothy:no-unfold + aesd \data, \key + aesimc \data, \data +.endm + +.macro tweak lo, hi + extr x22, x10, x10, #32 + extr x10, x10, x9, #63 + and w11, w19, w22, asr#31 + eor x9, x11, x9, lsl#1 + fmov \lo, x9 + fmov \hi, x10 +.endm + +S2N_BN_SYMBOL(aes_hw_xts_decrypt): + // AARCH64_VALID_CALL_TARGET + sub sp, sp, #STACK_SIZE_VREGS + save_vregs + save_regs + + cmp x2,#16 + // Original input data size bigger than 16, jump to big size processing. + b.lt Lxts_dec_abort + +.align 5 +Lxts_dec_big_size: // decrypt input size >= 16 bytes + and x21, x2, #0xf // store the tail value of length%16 + and x2, x2, #-16 // len &= 0x1..110000, now divisible by 16 + subs x2, x2, #16 + + // Firstly, encrypt the iv with key2, as the first iv of XEX. + ldr w6, [x4,#240] + ld1 {v0.4s}, [x4], #16 + ld1 {v6.16b}, [x5] + sub w6, w6, #2 + ld1 {v1.4s}, [x4], #16 + +Loop_iv_enc: + aesr v6.16b, v0.16b + ld1 {v0.4s}, [x4], #16 + subs w6, w6, #2 + aesr v6.16b, v1.16b + ld1 {v1.4s}, [x4], #16 + b.gt Loop_iv_enc + + aesr v6.16b, v0.16b + ld1 {v0.4s}, [x4] + aese v6.16b, v1.16b + eor v6.16b, v6.16b, v0.16b + + // The iv for second block + // x9- iv(low), x10 - iv(high) + // the five ivs stored into, v6.16b,v8.16b,v9.16b,v10.16b,v11.16b + fmov x9, d6 + fmov x10, v6.d[1] + mov w19, #0x87 + tweak d8, v8.d[1] + + mov x7, x3 + ld1 {v16.4s,v17.4s},[x7], #32 // load key schedule + ld1 {v12.4s,v13.4s},[x7], #32 + ld1 {v14.4s,v15.4s},[x7], #32 + ld1 {v4.4s,v5.4s}, [x7], #32 + ld1 {v18.4s,v19.4s},[x7], #32 + ld1 {v20.4s,v21.4s},[x7], #32 + ld1 {v22.4s,v23.4s},[x7], #32 + ld1 {v7.4s}, [x7] + // add x7, x3, #32 + +// decryption +Lxts_dec: + tst x21,#0xf + b.eq Lxts_dec_begin + subs x2,x2,#16 + cmp x2, #0 + b.lt Lxts_dec_done // There is one block and a tail, go directy to cipher-stealing + +Lxts_dec_begin: + ld1 {v0.16b}, [x0], #16 // the first block + cmp x2, #16 + orr v29.16b,v0.16b,v0.16b + b.lo Lxts_dec_tail1x // when input = 1 with another block and a tail + + ld1 {v1.16b},[x0],#16 // the second block + subs x2,x2,#32 // bias + orr v28.16b,v0.16b,v0.16b + orr v29.16b,v1.16b,v1.16b + b.lo Lxts_dec_tail2x // when input size = 2 with another block and a tail + + // The iv for third block + tweak d9,v9.d[1] + + orr v27.16b,v0.16b,v0.16b + orr v28.16b,v1.16b,v1.16b + ld1 {v24.16b},[x0],#16 // the third block + orr v29.16b,v24.16b,v24.16b + cmp x2,#16 + b.lo Lxts_dec_tail3x // when input size = 3 with another block and a tail + + // The iv for fourth block + tweak d10,v10.d[1] + + orr v3.16b,v0.16b,v0.16b + orr v27.16b,v1.16b,v1.16b + orr v28.16b,v24.16b,v24.16b + ld1 {v25.16b},[x0],#16 // the fourth block + orr v29.16b,v25.16b,v25.16b + subs x2,x2,#32 + b.lo Lxts_dec_tail4x // when input size = 4 with another block and a tail + + // The iv for fifth block + tweak d11,v11.d[1] + + ld1 {v26.16b},[x0],#16 // the fifth block + eor v0.16b,v0.16b,v6.16b // before decryption, xor with iv + eor v1.16b,v1.16b,v8.16b + eor v24.16b,v24.16b,v9.16b + eor v25.16b,v25.16b,v10.16b + eor v26.16b,v26.16b,v11.16b + +.align 4 +Loop5x_xts_dec: + aesdr v0.16b, v16.16b + aesdr v1.16b, v16.16b + aesdr v24.16b, v16.16b + aesdr v25.16b, v16.16b + aesdr v26.16b, v16.16b + subs x12,x2,#0x50 // because Lxts_dec_tail4x + + aesdr v0.16b, v17.16b + aesdr v1.16b, v17.16b + aesdr v24.16b, v17.16b + aesdr v25.16b, v17.16b + aesdr v26.16b, v17.16b + csel x6,xzr,x12,gt // borrow x6, w6, "gt" is not typo + + aesdr v0.16b, v12.16b + aesdr v1.16b, v12.16b + aesdr v24.16b, v12.16b + aesdr v25.16b, v12.16b + aesdr v26.16b, v12.16b + + aesdr v0.16b, v13.16b + aesdr v1.16b, v13.16b + aesdr v24.16b, v13.16b + aesdr v25.16b, v13.16b + aesdr v26.16b, v13.16b + + aesdr v0.16b, v14.16b + aesdr v1.16b, v14.16b + aesdr v24.16b, v14.16b + aesdr v25.16b, v14.16b + aesdr v26.16b, v14.16b + + aesdr v0.16b, v15.16b + aesdr v1.16b, v15.16b + aesdr v24.16b, v15.16b + aesdr v25.16b, v15.16b + aesdr v26.16b, v15.16b + + aesdr v0.16b, v4.16b + aesdr v1.16b, v4.16b + aesdr v24.16b, v4.16b + aesdr v25.16b, v4.16b + aesdr v26.16b, v4.16b + + aesdr v0.16b, v5.16b + aesdr v1.16b, v5.16b + aesdr v24.16b, v5.16b + aesdr v25.16b, v5.16b + aesdr v26.16b, v5.16b + + aesdr v0.16b, v18.16b + aesdr v1.16b, v18.16b + aesdr v24.16b, v18.16b + aesdr v25.16b, v18.16b + aesdr v26.16b, v18.16b + add x0,x0,x6 // x0 is adjusted in such way that + // at exit from the loop v1.16b-v26.16b + // are loaded with last "words" + + aesdr v0.16b, v19.16b + aesdr v1.16b, v19.16b + aesdr v24.16b, v19.16b + aesdr v25.16b, v19.16b + aesdr v26.16b, v19.16b + + aesdr v0.16b, v20.16b + aesdr v1.16b, v20.16b + aesdr v24.16b, v20.16b + aesdr v25.16b, v20.16b + aesdr v26.16b, v20.16b + + aesdr v0.16b, v21.16b + aesdr v1.16b, v21.16b + aesdr v24.16b, v21.16b + aesdr v25.16b, v21.16b + aesdr v26.16b, v21.16b + + aesdr v0.16b, v22.16b + aesdr v1.16b, v22.16b + aesdr v24.16b, v22.16b + aesdr v25.16b, v22.16b + aesdr v26.16b, v22.16b + + aesd v0.16b,v23.16b + aesd v1.16b,v23.16b + aesd v24.16b,v23.16b + aesd v25.16b,v23.16b + aesd v26.16b,v23.16b + + eor v0.16b,v0.16b,v7.16b + eor v0.16b,v0.16b,v6.16b + // The iv for first block of one iteration + tweak d6,v6.d[1] + eor v1.16b,v1.16b,v7.16b + eor v1.16b,v1.16b,v8.16b + ldp q2, q3, [x0], #0x50 + + // The iv for second block + tweak d8,v8.d[1] + eor v24.16b,v24.16b,v7.16b + eor v24.16b,v24.16b,v9.16b + + // The iv for third block + tweak d9,v9.d[1] + eor v25.16b,v25.16b,v7.16b + eor v25.16b,v25.16b,v10.16b + ldr q27, [x0, #-0x30] + + // The iv for fourth block + tweak d10,v10.d[1] + eor v26.16b,v26.16b,v7.16b + eor v26.16b,v26.16b,v11.16b + ldp q28, q29,[x0, #-0x20] + + // The iv for fifth block + tweak d11,v11.d[1] + + stp q0, q1, [x1], #0x50 + stp q24, q25, [x1, #-0x30] + str q26, [x1, #-0x10] + eor v0.16b,v2.16b,v6.16b + eor v1.16b,v3.16b,v8.16b + eor v24.16b,v27.16b,v9.16b + eor v25.16b,v28.16b,v10.16b + eor v26.16b,v29.16b,v11.16b + + subs x2,x2,#0x50 + b.hs Loop5x_xts_dec + +Loop5x_dec_after: + cmn x2,#0x10 + b.eq Lxts_dec_tail4x // 4 blocks left + 1block and a tail + + add x2,x2,#0x50 + cbz x2,Lxts_dec_done // no blocks left + 1block and a tail + + subs x2,x2,#0x20 + b.lo Lxts_dec_tail1x // 1 block left + 1block and a tail + + subs x2,x2,#0x10 + b.lo Lxts_dec_tail2x // 2 blocks left + 1block and a tail + + b Lxts_dec_tail3x // 3 blocks left + 1block and a tail + +.align 4 +Lxts_dec_tail4x: + eor v1.16b,v6.16b,v3.16b + eor v24.16b,v27.16b,v8.16b + eor v25.16b,v28.16b,v9.16b + eor v26.16b,v29.16b,v10.16b + + aesdr v1.16b, v16.16b + aesdr v24.16b, v16.16b + aesdr v25.16b, v16.16b + aesdr v26.16b, v16.16b + + aesdr v1.16b, v17.16b + aesdr v24.16b, v17.16b + aesdr v25.16b, v17.16b + aesdr v26.16b, v17.16b + + aesdr v1.16b, v12.16b + aesdr v24.16b, v12.16b + aesdr v25.16b, v12.16b + aesdr v26.16b, v12.16b + + aesdr v1.16b, v13.16b + aesdr v24.16b, v13.16b + aesdr v25.16b, v13.16b + aesdr v26.16b, v13.16b + + aesdr v1.16b, v14.16b + aesdr v24.16b, v14.16b + aesdr v25.16b, v14.16b + aesdr v26.16b, v14.16b + + aesdr v1.16b, v15.16b + aesdr v24.16b, v15.16b + aesdr v25.16b, v15.16b + aesdr v26.16b, v15.16b + + aesdr v1.16b, v4.16b + aesdr v24.16b, v4.16b + aesdr v25.16b, v4.16b + aesdr v26.16b, v4.16b + + aesdr v1.16b, v5.16b + aesdr v24.16b, v5.16b + aesdr v25.16b, v5.16b + aesdr v26.16b, v5.16b + + aesdr v1.16b, v18.16b + aesdr v24.16b, v18.16b + aesdr v25.16b, v18.16b + aesdr v26.16b, v18.16b + + aesdr v1.16b, v19.16b + aesdr v24.16b, v19.16b + aesdr v25.16b, v19.16b + aesdr v26.16b, v19.16b + + aesdr v1.16b, v20.16b + aesdr v24.16b, v20.16b + aesdr v25.16b, v20.16b + aesdr v26.16b, v20.16b + + aesdr v1.16b, v21.16b + aesdr v24.16b, v21.16b + aesdr v25.16b, v21.16b + aesdr v26.16b, v21.16b + + aesdr v1.16b, v22.16b + aesdr v24.16b, v22.16b + aesdr v25.16b, v22.16b + aesdr v26.16b, v22.16b + + aesd v1.16b,v23.16b + aesd v24.16b,v23.16b + aesd v25.16b,v23.16b + aesd v26.16b,v23.16b + + eor v1.16b,v1.16b,v7.16b + eor v1.16b,v1.16b,v6.16b + + eor v24.16b,v24.16b,v7.16b + eor v24.16b,v24.16b,v8.16b + + eor v25.16b,v25.16b,v7.16b + eor v25.16b,v25.16b,v9.16b + + eor v26.16b,v26.16b,v7.16b + eor v26.16b,v26.16b,v10.16b + // The iv for tail + fmov x9,d10 + fmov x10,v10.d[1] + tweak d6,v6.d[1] + + st1 {v1.16b},[x1],#16 + st1 {v24.16b,v25.16b},[x1],#32 + st1 {v26.16b},[x1],#16 + b Lxts_dec_done + +.align 4 +Lxts_dec_tail3x: + eor v0.16b,v6.16b,v27.16b // 3 blocks left + eor v1.16b,v8.16b,v28.16b + eor v24.16b,v29.16b,v9.16b + + // First round with v16 + aesdr v0.16b, v16.16b + aesdr v1.16b, v16.16b + aesdr v24.16b, v16.16b + + // Second round with v17 + aesdr v0.16b, v17.16b + aesdr v1.16b, v17.16b + aesdr v24.16b, v17.16b + + // Third round with v12 + aesdr v0.16b, v12.16b + aesdr v1.16b, v12.16b + aesdr v24.16b, v12.16b + + // Fourth round with v13 + aesdr v0.16b, v13.16b + aesdr v1.16b, v13.16b + aesdr v24.16b, v13.16b + + // Fifth round with v14 + aesdr v0.16b, v14.16b + aesdr v1.16b, v14.16b + aesdr v24.16b, v14.16b + + // Sixth round with v15 + aesdr v0.16b, v15.16b + aesdr v1.16b, v15.16b + aesdr v24.16b, v15.16b + + // Seventh round with v4 + aesdr v0.16b, v4.16b + aesdr v1.16b, v4.16b + aesdr v24.16b, v4.16b + + // Eighth round with v5 + aesdr v0.16b, v5.16b + aesdr v1.16b, v5.16b + aesdr v24.16b, v5.16b + + // 9th round with v18 + aesdr v0.16b, v18.16b + aesdr v1.16b, v18.16b + aesdr v24.16b, v18.16b + + // 10th round with v19 + aesdr v0.16b, v19.16b + aesdr v1.16b, v19.16b + aesdr v24.16b, v19.16b + + aesdr v0.16b, v20.16b + aesdr v1.16b, v20.16b + aesdr v24.16b, v20.16b + + aesdr v0.16b, v21.16b + aesdr v1.16b, v21.16b + aesdr v24.16b, v21.16b + + aesdr v0.16b, v22.16b + aesdr v1.16b, v22.16b + aesdr v24.16b, v22.16b + + aesd v0.16b,v23.16b + aesd v1.16b,v23.16b + aesd v24.16b,v23.16b + + eor v0.16b,v0.16b,v7.16b + eor v0.16b,v0.16b,v6.16b + eor v1.16b,v1.16b,v7.16b + eor v1.16b,v1.16b,v8.16b + eor v24.16b,v24.16b,v7.16b + eor v24.16b,v24.16b,v9.16b + + // The iv for tail + fmov x9,d9 + fmov x10,v9.d[1] + tweak d6,v6.d[1] + + st1 {v0.16b,v1.16b},[x1],#32 + st1 {v24.16b},[x1],#16 + b Lxts_dec_done // done processing three blocks + +Lxts_dec_tail2x: + eor v1.16b,v28.16b,v6.16b + eor v24.16b,v29.16b,v8.16b + + // First round with v16 + aesdr v1.16b, v16.16b + aesdr v24.16b, v16.16b + + // Second round with v17 + aesdr v1.16b, v17.16b + aesdr v24.16b, v17.16b + + // Third round with v12 + aesdr v1.16b, v12.16b + aesdr v24.16b, v12.16b + + // Fourth round with v13 + aesdr v1.16b, v13.16b + aesdr v24.16b, v13.16b + + // Fifth round with v14 + aesdr v1.16b, v14.16b + aesdr v24.16b, v14.16b + + // Sixth round with v15 + aesdr v1.16b, v15.16b + aesdr v24.16b, v15.16b + + // Seventh round with v4 + aesdr v1.16b, v4.16b + aesdr v24.16b, v4.16b + + // Eighth round with v5 + aesdr v1.16b, v5.16b + aesdr v24.16b, v5.16b + + // 9th round with v18 + aesdr v1.16b, v18.16b + aesdr v24.16b, v18.16b + + // 10th round with v19 + aesdr v1.16b, v19.16b + aesdr v24.16b, v19.16b + + aesdr v1.16b, v20.16b + aesdr v24.16b, v20.16b + + aesdr v1.16b, v21.16b + aesdr v24.16b, v21.16b + + aesdr v1.16b, v22.16b + aesdr v24.16b, v22.16b + aesd v1.16b,v23.16b + aesd v24.16b,v23.16b + + eor v1.16b,v1.16b,v7.16b + eor v1.16b,v1.16b,v6.16b + st1 {v1.16b},[x1],#16 + eor v24.16b,v24.16b,v7.16b + eor v24.16b,v24.16b,v8.16b + st1 {v24.16b},[x1],#16 + + // The iv for tail + fmov x9,d8 + fmov x10,v8.d[1] + tweak d6,v6.d[1] + b Lxts_dec_done + +Lxts_dec_tail1x: + eor v24.16b,v29.16b,v6.16b + + // First round with v16 + aesdr v24.16b, v16.16b + + // Second round with v17 + aesdr v24.16b, v17.16b + + // Third round with v12 + aesdr v24.16b, v12.16b + + // Fourth round with v13 + aesdr v24.16b, v13.16b + + // Fifth round with v14 + aesdr v24.16b, v14.16b + + // Sixth round with v15 + aesdr v24.16b, v15.16b + + // Seventh round with v4 + aesdr v24.16b, v4.16b + + // Eighth round with v5 + aesdr v24.16b, v5.16b + + // 9th round with v18 + aesdr v24.16b, v18.16b + + // 10th round with v19 + aesdr v24.16b, v19.16b + + aesdr v24.16b, v20.16b + aesdr v24.16b, v21.16b + aesdr v24.16b, v22.16b + aesd v24.16b,v23.16b + + eor v24.16b,v24.16b,v7.16b + eor v24.16b,v24.16b,v6.16b + st1 {v24.16b},[x1],#16 + // tweak for tail + fmov x9,d6 + fmov x10,v6.d[1] + tweak d6,v6.d[1] + b Lxts_dec_done + +Lxts_dec_done: + tst x21,#0xf + b.eq Lxts_dec_abort + // Processing the last 1 block and a tail with cipher stealing. + // At this point, we know there is 1 block+tail + // We need two tweaks, one is already calculated and stored in v6 + // We use it to calculate v8 + mov x7,x3 + + fmov x9,d6 + fmov x10,v6.d[1] + tweak d8,v8.d[1] + + ld1 {v0.4s},[x0],#16 + +// Decrypt the second to last block +.Lxts_dec_1st_done: + eor v26.16b,v0.16b,v8.16b + ldr w6,[x3,#240] + ld1 {v0.4s},[x3],#16 + sub w6,w6,#2 + ld1 {v1.4s},[x3],#16 +.Loop_final_2nd_dec: + aesd v26.16b,v0.16b + aesimc v26.16b,v26.16b + ld1 {v0.4s},[x3],#16 // load key schedule... + subs w6,w6,#2 + aesd v26.16b,v1.16b + aesimc v26.16b,v26.16b + ld1 {v1.4s},[x3],#16 // load key schedule... + b.gt .Loop_final_2nd_dec + + aesd v26.16b,v0.16b + aesimc v26.16b,v26.16b + ld1 {v0.4s},[x3] + aesd v26.16b,v1.16b + eor v26.16b,v26.16b,v0.16b + eor v26.16b,v26.16b,v8.16b + st1 {v26.16b},[x1] + + mov x20,x0 + add x13,x1,#16 + + // Composite the tailcnt "16 byte not aligned block" into the last second plain blocks + // to get the last encrypted block. +.composite_dec_loop: + subs x21,x21,#1 + ldrb w15,[x1,x21] + ldrb w14,[x20,x21] + strb w15,[x13,x21] + strb w14,[x1,x21] + b.gt .composite_dec_loop +.Lxts_dec_load_done: + ld1 {v26.16b},[x1] + eor v26.16b,v26.16b,v6.16b + + // Decrypt the composite block to get the last second plain text block + ldr w6,[x7,#240] + ld1 {v0.16b},[x7],#16 + sub w6,w6,#2 + ld1 {v1.16b},[x7],#16 +.Loop_final_dec: + aesd v26.16b,v0.16b + aesimc v26.16b,v26.16b + ld1 {v0.4s},[x7],#16 // load key schedule... + subs w6,w6,#2 + aesd v26.16b,v1.16b + aesimc v26.16b,v26.16b + ld1 {v1.4s},[x7],#16 // load key schedule... + b.gt .Loop_final_dec + + aesd v26.16b,v0.16b + aesimc v26.16b,v26.16b + ld1 {v0.4s},[x7] + aesd v26.16b,v1.16b + eor v26.16b,v26.16b,v0.16b + eor v26.16b,v26.16b,v6.16b + st1 {v26.16b},[x1] + +Lxts_dec_abort: + restore_vregs + restore_regs + add sp, sp, #STACK_SIZE_VREGS + ret + +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits +#endif diff --git a/arm/proofs/aes_decrypt.ml b/arm/proofs/aes_decrypt.ml new file mode 100644 index 000000000..51a7b1d83 --- /dev/null +++ b/arm/proofs/aes_decrypt.ml @@ -0,0 +1,13 @@ +(* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT-0 + *) + +use_file_raise_failure := true;; + +needs "arm/proofs/base.ml";; + +save_literal_from_elf "arm/aes-xts/aes256_decrypt.txt" "arm/aes-xts/aes256_decrypt.o";; + +let aes256_decrypt_mc = define_assert_from_elf "aes256_decrypt" "arm/aes-xts/aes256_decrypt.o" +[];; \ No newline at end of file diff --git a/arm/proofs/aes_xts_decrypt.ml b/arm/proofs/aes_xts_decrypt.ml new file mode 100644 index 000000000..7b862b1d3 --- /dev/null +++ b/arm/proofs/aes_xts_decrypt.ml @@ -0,0 +1,724 @@ +(* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT-0 + *) + +use_file_raise_failure := true;; + +needs "arm/proofs/base.ml";; + +(* print_literal_from_elf "arm/aes-xts/aes_xts_decrypt_armv8.o";; *) +let aes_xts_decrypt_mc = define_assert_from_elf "aes_hw_xts_decrypt" "arm/aes-xts/aes_xts_decrypt_armv8.o" +[ + 0xd10103ff; (* arm_SUB SP SP (rvalue (word 64)) *) + 0x6d0027e8; (* arm_STP D8 D9 SP (Immediate_Offset (iword (&0))) *) + 0x6d012fea; (* arm_STP D10 D11 SP (Immediate_Offset (iword (&16))) *) + 0xa90253f3; (* arm_STP X19 X20 SP (Immediate_Offset (iword (&32))) *) + 0xa9035bf5; (* arm_STP X21 X22 SP (Immediate_Offset (iword (&48))) *) + 0xf100405f; (* arm_CMP X2 (rvalue (word 16)) *) + 0x5400576b; (* arm_BLT (word 2796) *) + 0xd503201f; (* arm_NOP *) + 0x92400c55; (* arm_AND X21 X2 (rvalue (word 15)) *) + 0x927cec42; (* arm_AND X2 X2 (rvalue (word 18446744073709551600)) *) + 0xf1004042; (* arm_SUBS X2 X2 (rvalue (word 16)) *) + 0xb940f086; (* arm_LDR W6 X4 (Immediate_Offset (word 240)) *) + 0x4cdf7880; (* arm_LDR Q0 X4 (Postimmediate_Offset (word 16)) *) + 0x4c4070a6; (* arm_LDR Q6 X5 No_Offset *) + 0x510008c6; (* arm_SUB W6 W6 (rvalue (word 2)) *) + 0x4cdf7881; (* arm_LDR Q1 X4 (Postimmediate_Offset (word 16)) *) + 0x4e284806; (* arm_AESE Q6 Q0 *) + 0x4e2868c6; (* arm_AESMC Q6 Q6 *) + 0x4cdf7880; (* arm_LDR Q0 X4 (Postimmediate_Offset (word 16)) *) + 0x710008c6; (* arm_SUBS W6 W6 (rvalue (word 2)) *) + 0x4e284826; (* arm_AESE Q6 Q1 *) + 0x4e2868c6; (* arm_AESMC Q6 Q6 *) + 0x4cdf7881; (* arm_LDR Q1 X4 (Postimmediate_Offset (word 16)) *) + 0x54ffff2c; (* arm_BGT (word 2097124) *) + 0x4e284806; (* arm_AESE Q6 Q0 *) + 0x4e2868c6; (* arm_AESMC Q6 Q6 *) + 0x4c407880; (* arm_LDR Q0 X4 No_Offset *) + 0x4e284826; (* arm_AESE Q6 Q1 *) + 0x6e201cc6; (* arm_EOR_VEC Q6 Q6 Q0 128 *) + 0x9e6600c9; (* arm_FMOV_FtoI X9 Q6 0 64 *) + 0x9eae00ca; (* arm_FMOV_FtoI X10 Q6 1 64 *) + 0x528010f3; (* arm_MOV W19 (rvalue (word 135)) *) + 0x93ca8156; (* arm_ROR X22 X10 32 *) + 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) + 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 31) *) + 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 1) *) + 0x9e670128; (* arm_FMOV_ItoF Q8 X9 0 *) + 0x9eaf0148; (* arm_FMOV_ItoF Q8 X10 1 *) + 0xaa0303e7; (* arm_MOV X7 X3 *) + 0x4cdfa8f0; (* arm_LDP Q16 Q17 X7 (Postimmediate_Offset (word 32)) *) + 0x4cdfa8ec; (* arm_LDP Q12 Q13 X7 (Postimmediate_Offset (word 32)) *) + 0x4cdfa8ee; (* arm_LDP Q14 Q15 X7 (Postimmediate_Offset (word 32)) *) + 0x4cdfa8e4; (* arm_LDP Q4 Q5 X7 (Postimmediate_Offset (word 32)) *) + 0x4cdfa8f2; (* arm_LDP Q18 Q19 X7 (Postimmediate_Offset (word 32)) *) + 0x4cdfa8f4; (* arm_LDP Q20 Q21 X7 (Postimmediate_Offset (word 32)) *) + 0x4cdfa8f6; (* arm_LDP Q22 Q23 X7 (Postimmediate_Offset (word 32)) *) + 0x4c4078e7; (* arm_LDR Q7 X7 No_Offset *) + 0xf2400ebf; (* arm_TST X21 (rvalue (word 15)) *) + 0x54000080; (* arm_BEQ (word 16) *) + 0xf1004042; (* arm_SUBS X2 X2 (rvalue (word 16)) *) + 0xf100005f; (* arm_CMP X2 (rvalue (word 0)) *) + 0x54004a2b; (* arm_BLT (word 2372) *) + 0x4cdf7000; (* arm_LDR Q0 X0 (Postimmediate_Offset (word 16)) *) + 0xf100405f; (* arm_CMP X2 (rvalue (word 16)) *) + 0x4ea01c1d; (* arm_MOV_VEC Q29 Q0 128 *) + 0x540044a3; (* arm_BCC (word 2196) *) + 0x4cdf7001; (* arm_LDR Q1 X0 (Postimmediate_Offset (word 16)) *) + 0xf1008042; (* arm_SUBS X2 X2 (rvalue (word 32)) *) + 0x4ea01c1c; (* arm_MOV_VEC Q28 Q0 128 *) + 0x4ea11c3d; (* arm_MOV_VEC Q29 Q1 128 *) + 0x54003b23; (* arm_BCC (word 1892) *) + 0x93ca8156; (* arm_ROR X22 X10 32 *) + 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) + 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 31) *) + 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 1) *) + 0x9e670129; (* arm_FMOV_ItoF Q9 X9 0 *) + 0x9eaf0149; (* arm_FMOV_ItoF Q9 X10 1 *) + 0x4ea01c1b; (* arm_MOV_VEC Q27 Q0 128 *) + 0x4ea11c3c; (* arm_MOV_VEC Q28 Q1 128 *) + 0x4cdf7018; (* arm_LDR Q24 X0 (Postimmediate_Offset (word 16)) *) + 0x4eb81f1d; (* arm_MOV_VEC Q29 Q24 128 *) + 0xf100405f; (* arm_CMP X2 (rvalue (word 16)) *) + 0x54002d03; (* arm_BCC (word 1440) *) + 0x93ca8156; (* arm_ROR X22 X10 32 *) + 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) + 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 31) *) + 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 1) *) + 0x9e67012a; (* arm_FMOV_ItoF Q10 X9 0 *) + 0x9eaf014a; (* arm_FMOV_ItoF Q10 X10 1 *) + 0x4ea01c03; (* arm_MOV_VEC Q3 Q0 128 *) + 0x4ea11c3b; (* arm_MOV_VEC Q27 Q1 128 *) + 0x4eb81f1c; (* arm_MOV_VEC Q28 Q24 128 *) + 0x4cdf7019; (* arm_LDR Q25 X0 (Postimmediate_Offset (word 16)) *) + 0x4eb91f3d; (* arm_MOV_VEC Q29 Q25 128 *) + 0xf1008042; (* arm_SUBS X2 X2 (rvalue (word 32)) *) + 0x54001ae3; (* arm_BCC (word 860) *) + 0x93ca8156; (* arm_ROR X22 X10 32 *) + 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) + 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 31) *) + 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 1) *) + 0x9e67012b; (* arm_FMOV_ItoF Q11 X9 0 *) + 0x9eaf014b; (* arm_FMOV_ItoF Q11 X10 1 *) + 0x4cdf701a; (* arm_LDR Q26 X0 (Postimmediate_Offset (word 16)) *) + 0x6e261c00; (* arm_EOR_VEC Q0 Q0 Q6 128 *) + 0x6e281c21; (* arm_EOR_VEC Q1 Q1 Q8 128 *) + 0x6e291f18; (* arm_EOR_VEC Q24 Q24 Q9 128 *) + 0x6e2a1f39; (* arm_EOR_VEC Q25 Q25 Q10 128 *) + 0x6e2b1f5a; (* arm_EOR_VEC Q26 Q26 Q11 128 *) + 0xd503201f; (* arm_NOP *) + 0xd503201f; (* arm_NOP *) + 0x4e285a00; (* arm_AESD Q0 Q16 *) + 0x4e287800; (* arm_AESIMC Q0 Q0 *) + 0x4e285a01; (* arm_AESD Q1 Q16 *) + 0x4e287821; (* arm_AESIMC Q1 Q1 *) + 0x4e285a18; (* arm_AESD Q24 Q16 *) + 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x4e285a19; (* arm_AESD Q25 Q16 *) + 0x4e287b39; (* arm_AESIMC Q25 Q25 *) + 0x4e285a1a; (* arm_AESD Q26 Q16 *) + 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) + 0xf101404c; (* arm_SUBS X12 X2 (rvalue (word 80)) *) + 0x4e285a20; (* arm_AESD Q0 Q17 *) + 0x4e287800; (* arm_AESIMC Q0 Q0 *) + 0x4e285a21; (* arm_AESD Q1 Q17 *) + 0x4e287821; (* arm_AESIMC Q1 Q1 *) + 0x4e285a38; (* arm_AESD Q24 Q17 *) + 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x4e285a39; (* arm_AESD Q25 Q17 *) + 0x4e287b39; (* arm_AESIMC Q25 Q25 *) + 0x4e285a3a; (* arm_AESD Q26 Q17 *) + 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) + 0x9a8cc3e6; (* arm_CSEL X6 XZR X12 Condition_GT *) + 0x4e285980; (* arm_AESD Q0 Q12 *) + 0x4e287800; (* arm_AESIMC Q0 Q0 *) + 0x4e285981; (* arm_AESD Q1 Q12 *) + 0x4e287821; (* arm_AESIMC Q1 Q1 *) + 0x4e285998; (* arm_AESD Q24 Q12 *) + 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x4e285999; (* arm_AESD Q25 Q12 *) + 0x4e287b39; (* arm_AESIMC Q25 Q25 *) + 0x4e28599a; (* arm_AESD Q26 Q12 *) + 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) + 0x4e2859a0; (* arm_AESD Q0 Q13 *) + 0x4e287800; (* arm_AESIMC Q0 Q0 *) + 0x4e2859a1; (* arm_AESD Q1 Q13 *) + 0x4e287821; (* arm_AESIMC Q1 Q1 *) + 0x4e2859b8; (* arm_AESD Q24 Q13 *) + 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x4e2859b9; (* arm_AESD Q25 Q13 *) + 0x4e287b39; (* arm_AESIMC Q25 Q25 *) + 0x4e2859ba; (* arm_AESD Q26 Q13 *) + 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) + 0x4e2859c0; (* arm_AESD Q0 Q14 *) + 0x4e287800; (* arm_AESIMC Q0 Q0 *) + 0x4e2859c1; (* arm_AESD Q1 Q14 *) + 0x4e287821; (* arm_AESIMC Q1 Q1 *) + 0x4e2859d8; (* arm_AESD Q24 Q14 *) + 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x4e2859d9; (* arm_AESD Q25 Q14 *) + 0x4e287b39; (* arm_AESIMC Q25 Q25 *) + 0x4e2859da; (* arm_AESD Q26 Q14 *) + 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) + 0x4e2859e0; (* arm_AESD Q0 Q15 *) + 0x4e287800; (* arm_AESIMC Q0 Q0 *) + 0x4e2859e1; (* arm_AESD Q1 Q15 *) + 0x4e287821; (* arm_AESIMC Q1 Q1 *) + 0x4e2859f8; (* arm_AESD Q24 Q15 *) + 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x4e2859f9; (* arm_AESD Q25 Q15 *) + 0x4e287b39; (* arm_AESIMC Q25 Q25 *) + 0x4e2859fa; (* arm_AESD Q26 Q15 *) + 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) + 0x4e285880; (* arm_AESD Q0 Q4 *) + 0x4e287800; (* arm_AESIMC Q0 Q0 *) + 0x4e285881; (* arm_AESD Q1 Q4 *) + 0x4e287821; (* arm_AESIMC Q1 Q1 *) + 0x4e285898; (* arm_AESD Q24 Q4 *) + 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x4e285899; (* arm_AESD Q25 Q4 *) + 0x4e287b39; (* arm_AESIMC Q25 Q25 *) + 0x4e28589a; (* arm_AESD Q26 Q4 *) + 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) + 0x4e2858a0; (* arm_AESD Q0 Q5 *) + 0x4e287800; (* arm_AESIMC Q0 Q0 *) + 0x4e2858a1; (* arm_AESD Q1 Q5 *) + 0x4e287821; (* arm_AESIMC Q1 Q1 *) + 0x4e2858b8; (* arm_AESD Q24 Q5 *) + 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x4e2858b9; (* arm_AESD Q25 Q5 *) + 0x4e287b39; (* arm_AESIMC Q25 Q25 *) + 0x4e2858ba; (* arm_AESD Q26 Q5 *) + 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) + 0x4e285a40; (* arm_AESD Q0 Q18 *) + 0x4e287800; (* arm_AESIMC Q0 Q0 *) + 0x4e285a41; (* arm_AESD Q1 Q18 *) + 0x4e287821; (* arm_AESIMC Q1 Q1 *) + 0x4e285a58; (* arm_AESD Q24 Q18 *) + 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x4e285a59; (* arm_AESD Q25 Q18 *) + 0x4e287b39; (* arm_AESIMC Q25 Q25 *) + 0x4e285a5a; (* arm_AESD Q26 Q18 *) + 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) + 0x8b060000; (* arm_ADD X0 X0 X6 *) + 0x4e285a60; (* arm_AESD Q0 Q19 *) + 0x4e287800; (* arm_AESIMC Q0 Q0 *) + 0x4e285a61; (* arm_AESD Q1 Q19 *) + 0x4e287821; (* arm_AESIMC Q1 Q1 *) + 0x4e285a78; (* arm_AESD Q24 Q19 *) + 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x4e285a79; (* arm_AESD Q25 Q19 *) + 0x4e287b39; (* arm_AESIMC Q25 Q25 *) + 0x4e285a7a; (* arm_AESD Q26 Q19 *) + 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) + 0x4e285a80; (* arm_AESD Q0 Q20 *) + 0x4e287800; (* arm_AESIMC Q0 Q0 *) + 0x4e285a81; (* arm_AESD Q1 Q20 *) + 0x4e287821; (* arm_AESIMC Q1 Q1 *) + 0x4e285a98; (* arm_AESD Q24 Q20 *) + 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x4e285a99; (* arm_AESD Q25 Q20 *) + 0x4e287b39; (* arm_AESIMC Q25 Q25 *) + 0x4e285a9a; (* arm_AESD Q26 Q20 *) + 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) + 0x4e285aa0; (* arm_AESD Q0 Q21 *) + 0x4e287800; (* arm_AESIMC Q0 Q0 *) + 0x4e285aa1; (* arm_AESD Q1 Q21 *) + 0x4e287821; (* arm_AESIMC Q1 Q1 *) + 0x4e285ab8; (* arm_AESD Q24 Q21 *) + 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x4e285ab9; (* arm_AESD Q25 Q21 *) + 0x4e287b39; (* arm_AESIMC Q25 Q25 *) + 0x4e285aba; (* arm_AESD Q26 Q21 *) + 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) + 0x4e285ac0; (* arm_AESD Q0 Q22 *) + 0x4e287800; (* arm_AESIMC Q0 Q0 *) + 0x4e285ac1; (* arm_AESD Q1 Q22 *) + 0x4e287821; (* arm_AESIMC Q1 Q1 *) + 0x4e285ad8; (* arm_AESD Q24 Q22 *) + 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x4e285ad9; (* arm_AESD Q25 Q22 *) + 0x4e287b39; (* arm_AESIMC Q25 Q25 *) + 0x4e285ada; (* arm_AESD Q26 Q22 *) + 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) + 0x4e285ae0; (* arm_AESD Q0 Q23 *) + 0x4e285ae1; (* arm_AESD Q1 Q23 *) + 0x4e285af8; (* arm_AESD Q24 Q23 *) + 0x4e285af9; (* arm_AESD Q25 Q23 *) + 0x4e285afa; (* arm_AESD Q26 Q23 *) + 0x6e271c00; (* arm_EOR_VEC Q0 Q0 Q7 128 *) + 0x6e261c00; (* arm_EOR_VEC Q0 Q0 Q6 128 *) + 0x93ca8156; (* arm_ROR X22 X10 32 *) + 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) + 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 31) *) + 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 1) *) + 0x9e670126; (* arm_FMOV_ItoF Q6 X9 0 *) + 0x9eaf0146; (* arm_FMOV_ItoF Q6 X10 1 *) + 0x6e271c21; (* arm_EOR_VEC Q1 Q1 Q7 128 *) + 0x6e281c21; (* arm_EOR_VEC Q1 Q1 Q8 128 *) + 0xacc28c02; (* arm_LDP Q2 Q3 X0 (Postimmediate_Offset (iword (&80))) *) + 0x93ca8156; (* arm_ROR X22 X10 32 *) + 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) + 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 31) *) + 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 1) *) + 0x9e670128; (* arm_FMOV_ItoF Q8 X9 0 *) + 0x9eaf0148; (* arm_FMOV_ItoF Q8 X10 1 *) + 0x6e271f18; (* arm_EOR_VEC Q24 Q24 Q7 128 *) + 0x6e291f18; (* arm_EOR_VEC Q24 Q24 Q9 128 *) + 0x93ca8156; (* arm_ROR X22 X10 32 *) + 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) + 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 31) *) + 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 1) *) + 0x9e670129; (* arm_FMOV_ItoF Q9 X9 0 *) + 0x9eaf0149; (* arm_FMOV_ItoF Q9 X10 1 *) + 0x6e271f39; (* arm_EOR_VEC Q25 Q25 Q7 128 *) + 0x6e2a1f39; (* arm_EOR_VEC Q25 Q25 Q10 128 *) + 0x3cdd001b; (* arm_LDR Q27 X0 (Immediate_Offset (word 18446744073709551568)) *) + 0x93ca8156; (* arm_ROR X22 X10 32 *) + 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) + 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 31) *) + 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 1) *) + 0x9e67012a; (* arm_FMOV_ItoF Q10 X9 0 *) + 0x9eaf014a; (* arm_FMOV_ItoF Q10 X10 1 *) + 0x6e271f5a; (* arm_EOR_VEC Q26 Q26 Q7 128 *) + 0x6e2b1f5a; (* arm_EOR_VEC Q26 Q26 Q11 128 *) + 0xad7f741c; (* arm_LDP Q28 Q29 X0 (Immediate_Offset (iword (-- &32))) *) + 0x93ca8156; (* arm_ROR X22 X10 32 *) + 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) + 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 31) *) + 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 1) *) + 0x9e67012b; (* arm_FMOV_ItoF Q11 X9 0 *) + 0x9eaf014b; (* arm_FMOV_ItoF Q11 X10 1 *) + 0xac828420; (* arm_STP Q0 Q1 X1 (Postimmediate_Offset (iword (&80))) *) + 0xad3ee438; (* arm_STP Q24 Q25 X1 (Immediate_Offset (iword (-- &48))) *) + 0x3c9f003a; (* arm_STR Q26 X1 (Immediate_Offset (word 18446744073709551600)) *) + 0x6e261c40; (* arm_EOR_VEC Q0 Q2 Q6 128 *) + 0x6e281c61; (* arm_EOR_VEC Q1 Q3 Q8 128 *) + 0x6e291f78; (* arm_EOR_VEC Q24 Q27 Q9 128 *) + 0x6e2a1f99; (* arm_EOR_VEC Q25 Q28 Q10 128 *) + 0x6e2b1fba; (* arm_EOR_VEC Q26 Q29 Q11 128 *) + 0xf1014042; (* arm_SUBS X2 X2 (rvalue (word 80)) *) + 0x54ffe842; (* arm_BCS (word 2096392) *) + 0xb100405f; (* arm_CMN X2 (rvalue (word 16)) *) + 0x54000100; (* arm_BEQ (word 32) *) + 0x91014042; (* arm_ADD X2 X2 (rvalue (word 80)) *) + 0xb4002bc2; (* arm_CBZ X2 (word 1400) *) + 0xf1008042; (* arm_SUBS X2 X2 (rvalue (word 32)) *) + 0x54002683; (* arm_BCC (word 1232) *) + 0xf1004042; (* arm_SUBS X2 X2 (rvalue (word 16)) *) + 0x54001d63; (* arm_BCC (word 940) *) + 0x14000085; (* arm_B (word 532) *) + 0x6e231cc1; (* arm_EOR_VEC Q1 Q6 Q3 128 *) + 0x6e281f78; (* arm_EOR_VEC Q24 Q27 Q8 128 *) + 0x6e291f99; (* arm_EOR_VEC Q25 Q28 Q9 128 *) + 0x6e2a1fba; (* arm_EOR_VEC Q26 Q29 Q10 128 *) + 0x4e285a01; (* arm_AESD Q1 Q16 *) + 0x4e287821; (* arm_AESIMC Q1 Q1 *) + 0x4e285a18; (* arm_AESD Q24 Q16 *) + 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x4e285a19; (* arm_AESD Q25 Q16 *) + 0x4e287b39; (* arm_AESIMC Q25 Q25 *) + 0x4e285a1a; (* arm_AESD Q26 Q16 *) + 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) + 0x4e285a21; (* arm_AESD Q1 Q17 *) + 0x4e287821; (* arm_AESIMC Q1 Q1 *) + 0x4e285a38; (* arm_AESD Q24 Q17 *) + 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x4e285a39; (* arm_AESD Q25 Q17 *) + 0x4e287b39; (* arm_AESIMC Q25 Q25 *) + 0x4e285a3a; (* arm_AESD Q26 Q17 *) + 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) + 0x4e285981; (* arm_AESD Q1 Q12 *) + 0x4e287821; (* arm_AESIMC Q1 Q1 *) + 0x4e285998; (* arm_AESD Q24 Q12 *) + 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x4e285999; (* arm_AESD Q25 Q12 *) + 0x4e287b39; (* arm_AESIMC Q25 Q25 *) + 0x4e28599a; (* arm_AESD Q26 Q12 *) + 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) + 0x4e2859a1; (* arm_AESD Q1 Q13 *) + 0x4e287821; (* arm_AESIMC Q1 Q1 *) + 0x4e2859b8; (* arm_AESD Q24 Q13 *) + 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x4e2859b9; (* arm_AESD Q25 Q13 *) + 0x4e287b39; (* arm_AESIMC Q25 Q25 *) + 0x4e2859ba; (* arm_AESD Q26 Q13 *) + 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) + 0x4e2859c1; (* arm_AESD Q1 Q14 *) + 0x4e287821; (* arm_AESIMC Q1 Q1 *) + 0x4e2859d8; (* arm_AESD Q24 Q14 *) + 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x4e2859d9; (* arm_AESD Q25 Q14 *) + 0x4e287b39; (* arm_AESIMC Q25 Q25 *) + 0x4e2859da; (* arm_AESD Q26 Q14 *) + 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) + 0x4e2859e1; (* arm_AESD Q1 Q15 *) + 0x4e287821; (* arm_AESIMC Q1 Q1 *) + 0x4e2859f8; (* arm_AESD Q24 Q15 *) + 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x4e2859f9; (* arm_AESD Q25 Q15 *) + 0x4e287b39; (* arm_AESIMC Q25 Q25 *) + 0x4e2859fa; (* arm_AESD Q26 Q15 *) + 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) + 0x4e285881; (* arm_AESD Q1 Q4 *) + 0x4e287821; (* arm_AESIMC Q1 Q1 *) + 0x4e285898; (* arm_AESD Q24 Q4 *) + 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x4e285899; (* arm_AESD Q25 Q4 *) + 0x4e287b39; (* arm_AESIMC Q25 Q25 *) + 0x4e28589a; (* arm_AESD Q26 Q4 *) + 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) + 0x4e2858a1; (* arm_AESD Q1 Q5 *) + 0x4e287821; (* arm_AESIMC Q1 Q1 *) + 0x4e2858b8; (* arm_AESD Q24 Q5 *) + 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x4e2858b9; (* arm_AESD Q25 Q5 *) + 0x4e287b39; (* arm_AESIMC Q25 Q25 *) + 0x4e2858ba; (* arm_AESD Q26 Q5 *) + 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) + 0x4e285a41; (* arm_AESD Q1 Q18 *) + 0x4e287821; (* arm_AESIMC Q1 Q1 *) + 0x4e285a58; (* arm_AESD Q24 Q18 *) + 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x4e285a59; (* arm_AESD Q25 Q18 *) + 0x4e287b39; (* arm_AESIMC Q25 Q25 *) + 0x4e285a5a; (* arm_AESD Q26 Q18 *) + 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) + 0x4e285a61; (* arm_AESD Q1 Q19 *) + 0x4e287821; (* arm_AESIMC Q1 Q1 *) + 0x4e285a78; (* arm_AESD Q24 Q19 *) + 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x4e285a79; (* arm_AESD Q25 Q19 *) + 0x4e287b39; (* arm_AESIMC Q25 Q25 *) + 0x4e285a7a; (* arm_AESD Q26 Q19 *) + 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) + 0x4e285a81; (* arm_AESD Q1 Q20 *) + 0x4e287821; (* arm_AESIMC Q1 Q1 *) + 0x4e285a98; (* arm_AESD Q24 Q20 *) + 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x4e285a99; (* arm_AESD Q25 Q20 *) + 0x4e287b39; (* arm_AESIMC Q25 Q25 *) + 0x4e285a9a; (* arm_AESD Q26 Q20 *) + 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) + 0x4e285aa1; (* arm_AESD Q1 Q21 *) + 0x4e287821; (* arm_AESIMC Q1 Q1 *) + 0x4e285ab8; (* arm_AESD Q24 Q21 *) + 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x4e285ab9; (* arm_AESD Q25 Q21 *) + 0x4e287b39; (* arm_AESIMC Q25 Q25 *) + 0x4e285aba; (* arm_AESD Q26 Q21 *) + 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) + 0x4e285ac1; (* arm_AESD Q1 Q22 *) + 0x4e287821; (* arm_AESIMC Q1 Q1 *) + 0x4e285ad8; (* arm_AESD Q24 Q22 *) + 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x4e285ad9; (* arm_AESD Q25 Q22 *) + 0x4e287b39; (* arm_AESIMC Q25 Q25 *) + 0x4e285ada; (* arm_AESD Q26 Q22 *) + 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) + 0x4e285ae1; (* arm_AESD Q1 Q23 *) + 0x4e285af8; (* arm_AESD Q24 Q23 *) + 0x4e285af9; (* arm_AESD Q25 Q23 *) + 0x4e285afa; (* arm_AESD Q26 Q23 *) + 0x6e271c21; (* arm_EOR_VEC Q1 Q1 Q7 128 *) + 0x6e261c21; (* arm_EOR_VEC Q1 Q1 Q6 128 *) + 0x6e271f18; (* arm_EOR_VEC Q24 Q24 Q7 128 *) + 0x6e281f18; (* arm_EOR_VEC Q24 Q24 Q8 128 *) + 0x6e271f39; (* arm_EOR_VEC Q25 Q25 Q7 128 *) + 0x6e291f39; (* arm_EOR_VEC Q25 Q25 Q9 128 *) + 0x6e271f5a; (* arm_EOR_VEC Q26 Q26 Q7 128 *) + 0x6e2a1f5a; (* arm_EOR_VEC Q26 Q26 Q10 128 *) + 0x9e660149; (* arm_FMOV_FtoI X9 Q10 0 64 *) + 0x9eae014a; (* arm_FMOV_FtoI X10 Q10 1 64 *) + 0x93ca8156; (* arm_ROR X22 X10 32 *) + 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) + 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 31) *) + 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 1) *) + 0x9e670126; (* arm_FMOV_ItoF Q6 X9 0 *) + 0x9eaf0146; (* arm_FMOV_ItoF Q6 X10 1 *) + 0x4c9f7021; (* arm_STR Q1 X1 (Postimmediate_Offset (word 16)) *) + 0x4c9fa038; (* arm_STP Q24 Q25 X1 (Postimmediate_Offset (word 32)) *) + 0x4c9f703a; (* arm_STR Q26 X1 (Postimmediate_Offset (word 16)) *) + 0x140000d5; (* arm_B (word 852) *) + 0x6e3b1cc0; (* arm_EOR_VEC Q0 Q6 Q27 128 *) + 0x6e3c1d01; (* arm_EOR_VEC Q1 Q8 Q28 128 *) + 0x6e291fb8; (* arm_EOR_VEC Q24 Q29 Q9 128 *) + 0x4e285a00; (* arm_AESD Q0 Q16 *) + 0x4e287800; (* arm_AESIMC Q0 Q0 *) + 0x4e285a01; (* arm_AESD Q1 Q16 *) + 0x4e287821; (* arm_AESIMC Q1 Q1 *) + 0x4e285a18; (* arm_AESD Q24 Q16 *) + 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x4e285a20; (* arm_AESD Q0 Q17 *) + 0x4e287800; (* arm_AESIMC Q0 Q0 *) + 0x4e285a21; (* arm_AESD Q1 Q17 *) + 0x4e287821; (* arm_AESIMC Q1 Q1 *) + 0x4e285a38; (* arm_AESD Q24 Q17 *) + 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x4e285980; (* arm_AESD Q0 Q12 *) + 0x4e287800; (* arm_AESIMC Q0 Q0 *) + 0x4e285981; (* arm_AESD Q1 Q12 *) + 0x4e287821; (* arm_AESIMC Q1 Q1 *) + 0x4e285998; (* arm_AESD Q24 Q12 *) + 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x4e2859a0; (* arm_AESD Q0 Q13 *) + 0x4e287800; (* arm_AESIMC Q0 Q0 *) + 0x4e2859a1; (* arm_AESD Q1 Q13 *) + 0x4e287821; (* arm_AESIMC Q1 Q1 *) + 0x4e2859b8; (* arm_AESD Q24 Q13 *) + 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x4e2859c0; (* arm_AESD Q0 Q14 *) + 0x4e287800; (* arm_AESIMC Q0 Q0 *) + 0x4e2859c1; (* arm_AESD Q1 Q14 *) + 0x4e287821; (* arm_AESIMC Q1 Q1 *) + 0x4e2859d8; (* arm_AESD Q24 Q14 *) + 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x4e2859e0; (* arm_AESD Q0 Q15 *) + 0x4e287800; (* arm_AESIMC Q0 Q0 *) + 0x4e2859e1; (* arm_AESD Q1 Q15 *) + 0x4e287821; (* arm_AESIMC Q1 Q1 *) + 0x4e2859f8; (* arm_AESD Q24 Q15 *) + 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x4e285880; (* arm_AESD Q0 Q4 *) + 0x4e287800; (* arm_AESIMC Q0 Q0 *) + 0x4e285881; (* arm_AESD Q1 Q4 *) + 0x4e287821; (* arm_AESIMC Q1 Q1 *) + 0x4e285898; (* arm_AESD Q24 Q4 *) + 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x4e2858a0; (* arm_AESD Q0 Q5 *) + 0x4e287800; (* arm_AESIMC Q0 Q0 *) + 0x4e2858a1; (* arm_AESD Q1 Q5 *) + 0x4e287821; (* arm_AESIMC Q1 Q1 *) + 0x4e2858b8; (* arm_AESD Q24 Q5 *) + 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x4e285a40; (* arm_AESD Q0 Q18 *) + 0x4e287800; (* arm_AESIMC Q0 Q0 *) + 0x4e285a41; (* arm_AESD Q1 Q18 *) + 0x4e287821; (* arm_AESIMC Q1 Q1 *) + 0x4e285a58; (* arm_AESD Q24 Q18 *) + 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x4e285a60; (* arm_AESD Q0 Q19 *) + 0x4e287800; (* arm_AESIMC Q0 Q0 *) + 0x4e285a61; (* arm_AESD Q1 Q19 *) + 0x4e287821; (* arm_AESIMC Q1 Q1 *) + 0x4e285a78; (* arm_AESD Q24 Q19 *) + 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x4e285a80; (* arm_AESD Q0 Q20 *) + 0x4e287800; (* arm_AESIMC Q0 Q0 *) + 0x4e285a81; (* arm_AESD Q1 Q20 *) + 0x4e287821; (* arm_AESIMC Q1 Q1 *) + 0x4e285a98; (* arm_AESD Q24 Q20 *) + 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x4e285aa0; (* arm_AESD Q0 Q21 *) + 0x4e287800; (* arm_AESIMC Q0 Q0 *) + 0x4e285aa1; (* arm_AESD Q1 Q21 *) + 0x4e287821; (* arm_AESIMC Q1 Q1 *) + 0x4e285ab8; (* arm_AESD Q24 Q21 *) + 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x4e285ac0; (* arm_AESD Q0 Q22 *) + 0x4e287800; (* arm_AESIMC Q0 Q0 *) + 0x4e285ac1; (* arm_AESD Q1 Q22 *) + 0x4e287821; (* arm_AESIMC Q1 Q1 *) + 0x4e285ad8; (* arm_AESD Q24 Q22 *) + 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x4e285ae0; (* arm_AESD Q0 Q23 *) + 0x4e285ae1; (* arm_AESD Q1 Q23 *) + 0x4e285af8; (* arm_AESD Q24 Q23 *) + 0x6e271c00; (* arm_EOR_VEC Q0 Q0 Q7 128 *) + 0x6e261c00; (* arm_EOR_VEC Q0 Q0 Q6 128 *) + 0x6e271c21; (* arm_EOR_VEC Q1 Q1 Q7 128 *) + 0x6e281c21; (* arm_EOR_VEC Q1 Q1 Q8 128 *) + 0x6e271f18; (* arm_EOR_VEC Q24 Q24 Q7 128 *) + 0x6e291f18; (* arm_EOR_VEC Q24 Q24 Q9 128 *) + 0x9e660129; (* arm_FMOV_FtoI X9 Q9 0 64 *) + 0x9eae012a; (* arm_FMOV_FtoI X10 Q9 1 64 *) + 0x93ca8156; (* arm_ROR X22 X10 32 *) + 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) + 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 31) *) + 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 1) *) + 0x9e670126; (* arm_FMOV_ItoF Q6 X9 0 *) + 0x9eaf0146; (* arm_FMOV_ItoF Q6 X10 1 *) + 0x4c9fa020; (* arm_STP Q0 Q1 X1 (Postimmediate_Offset (word 32)) *) + 0x4c9f7038; (* arm_STR Q24 X1 (Postimmediate_Offset (word 16)) *) + 0x14000070; (* arm_B (word 448) *) + 0x6e261f81; (* arm_EOR_VEC Q1 Q28 Q6 128 *) + 0x6e281fb8; (* arm_EOR_VEC Q24 Q29 Q8 128 *) + 0x4e285a01; (* arm_AESD Q1 Q16 *) + 0x4e287821; (* arm_AESIMC Q1 Q1 *) + 0x4e285a18; (* arm_AESD Q24 Q16 *) + 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x4e285a21; (* arm_AESD Q1 Q17 *) + 0x4e287821; (* arm_AESIMC Q1 Q1 *) + 0x4e285a38; (* arm_AESD Q24 Q17 *) + 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x4e285981; (* arm_AESD Q1 Q12 *) + 0x4e287821; (* arm_AESIMC Q1 Q1 *) + 0x4e285998; (* arm_AESD Q24 Q12 *) + 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x4e2859a1; (* arm_AESD Q1 Q13 *) + 0x4e287821; (* arm_AESIMC Q1 Q1 *) + 0x4e2859b8; (* arm_AESD Q24 Q13 *) + 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x4e2859c1; (* arm_AESD Q1 Q14 *) + 0x4e287821; (* arm_AESIMC Q1 Q1 *) + 0x4e2859d8; (* arm_AESD Q24 Q14 *) + 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x4e2859e1; (* arm_AESD Q1 Q15 *) + 0x4e287821; (* arm_AESIMC Q1 Q1 *) + 0x4e2859f8; (* arm_AESD Q24 Q15 *) + 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x4e285881; (* arm_AESD Q1 Q4 *) + 0x4e287821; (* arm_AESIMC Q1 Q1 *) + 0x4e285898; (* arm_AESD Q24 Q4 *) + 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x4e2858a1; (* arm_AESD Q1 Q5 *) + 0x4e287821; (* arm_AESIMC Q1 Q1 *) + 0x4e2858b8; (* arm_AESD Q24 Q5 *) + 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x4e285a41; (* arm_AESD Q1 Q18 *) + 0x4e287821; (* arm_AESIMC Q1 Q1 *) + 0x4e285a58; (* arm_AESD Q24 Q18 *) + 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x4e285a61; (* arm_AESD Q1 Q19 *) + 0x4e287821; (* arm_AESIMC Q1 Q1 *) + 0x4e285a78; (* arm_AESD Q24 Q19 *) + 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x4e285a81; (* arm_AESD Q1 Q20 *) + 0x4e287821; (* arm_AESIMC Q1 Q1 *) + 0x4e285a98; (* arm_AESD Q24 Q20 *) + 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x4e285aa1; (* arm_AESD Q1 Q21 *) + 0x4e287821; (* arm_AESIMC Q1 Q1 *) + 0x4e285ab8; (* arm_AESD Q24 Q21 *) + 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x4e285ac1; (* arm_AESD Q1 Q22 *) + 0x4e287821; (* arm_AESIMC Q1 Q1 *) + 0x4e285ad8; (* arm_AESD Q24 Q22 *) + 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x4e285ae1; (* arm_AESD Q1 Q23 *) + 0x4e285af8; (* arm_AESD Q24 Q23 *) + 0x6e271c21; (* arm_EOR_VEC Q1 Q1 Q7 128 *) + 0x6e261c21; (* arm_EOR_VEC Q1 Q1 Q6 128 *) + 0x4c9f7021; (* arm_STR Q1 X1 (Postimmediate_Offset (word 16)) *) + 0x6e271f18; (* arm_EOR_VEC Q24 Q24 Q7 128 *) + 0x6e281f18; (* arm_EOR_VEC Q24 Q24 Q8 128 *) + 0x4c9f7038; (* arm_STR Q24 X1 (Postimmediate_Offset (word 16)) *) + 0x9e660109; (* arm_FMOV_FtoI X9 Q8 0 64 *) + 0x9eae010a; (* arm_FMOV_FtoI X10 Q8 1 64 *) + 0x93ca8156; (* arm_ROR X22 X10 32 *) + 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) + 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 31) *) + 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 1) *) + 0x9e670126; (* arm_FMOV_ItoF Q6 X9 0 *) + 0x9eaf0146; (* arm_FMOV_ItoF Q6 X10 1 *) + 0x14000029; (* arm_B (word 164) *) + 0x6e261fb8; (* arm_EOR_VEC Q24 Q29 Q6 128 *) + 0x4e285a18; (* arm_AESD Q24 Q16 *) + 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x4e285a38; (* arm_AESD Q24 Q17 *) + 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x4e285998; (* arm_AESD Q24 Q12 *) + 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x4e2859b8; (* arm_AESD Q24 Q13 *) + 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x4e2859d8; (* arm_AESD Q24 Q14 *) + 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x4e2859f8; (* arm_AESD Q24 Q15 *) + 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x4e285898; (* arm_AESD Q24 Q4 *) + 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x4e2858b8; (* arm_AESD Q24 Q5 *) + 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x4e285a58; (* arm_AESD Q24 Q18 *) + 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x4e285a78; (* arm_AESD Q24 Q19 *) + 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x4e285a98; (* arm_AESD Q24 Q20 *) + 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x4e285ab8; (* arm_AESD Q24 Q21 *) + 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x4e285ad8; (* arm_AESD Q24 Q22 *) + 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x4e285af8; (* arm_AESD Q24 Q23 *) + 0x6e271f18; (* arm_EOR_VEC Q24 Q24 Q7 128 *) + 0x6e261f18; (* arm_EOR_VEC Q24 Q24 Q6 128 *) + 0x4c9f7038; (* arm_STR Q24 X1 (Postimmediate_Offset (word 16)) *) + 0x9e6600c9; (* arm_FMOV_FtoI X9 Q6 0 64 *) + 0x9eae00ca; (* arm_FMOV_FtoI X10 Q6 1 64 *) + 0x93ca8156; (* arm_ROR X22 X10 32 *) + 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) + 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 31) *) + 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 1) *) + 0x9e670126; (* arm_FMOV_ItoF Q6 X9 0 *) + 0x9eaf0146; (* arm_FMOV_ItoF Q6 X10 1 *) + 0x14000001; (* arm_B (word 4) *) + 0xf2400ebf; (* arm_TST X21 (rvalue (word 15)) *) + 0x54000780; (* arm_BEQ (word 240) *) + 0xaa0303e7; (* arm_MOV X7 X3 *) + 0x9e6600c9; (* arm_FMOV_FtoI X9 Q6 0 64 *) + 0x9eae00ca; (* arm_FMOV_FtoI X10 Q6 1 64 *) + 0x93ca8156; (* arm_ROR X22 X10 32 *) + 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) + 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 31) *) + 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 1) *) + 0x9e670128; (* arm_FMOV_ItoF Q8 X9 0 *) + 0x9eaf0148; (* arm_FMOV_ItoF Q8 X10 1 *) + 0x4cdf7800; (* arm_LDR Q0 X0 (Postimmediate_Offset (word 16)) *) + 0x6e281c1a; (* arm_EOR_VEC Q26 Q0 Q8 128 *) + 0xb940f066; (* arm_LDR W6 X3 (Immediate_Offset (word 240)) *) + 0x4cdf7860; (* arm_LDR Q0 X3 (Postimmediate_Offset (word 16)) *) + 0x510008c6; (* arm_SUB W6 W6 (rvalue (word 2)) *) + 0x4cdf7861; (* arm_LDR Q1 X3 (Postimmediate_Offset (word 16)) *) + 0x4e28581a; (* arm_AESD Q26 Q0 *) + 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) + 0x4cdf7860; (* arm_LDR Q0 X3 (Postimmediate_Offset (word 16)) *) + 0x710008c6; (* arm_SUBS W6 W6 (rvalue (word 2)) *) + 0x4e28583a; (* arm_AESD Q26 Q1 *) + 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) + 0x4cdf7861; (* arm_LDR Q1 X3 (Postimmediate_Offset (word 16)) *) + 0x54ffff2c; (* arm_BGT (word 2097124) *) + 0x4e28581a; (* arm_AESD Q26 Q0 *) + 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) + 0x4c407860; (* arm_LDR Q0 X3 No_Offset *) + 0x4e28583a; (* arm_AESD Q26 Q1 *) + 0x6e201f5a; (* arm_EOR_VEC Q26 Q26 Q0 128 *) + 0x6e281f5a; (* arm_EOR_VEC Q26 Q26 Q8 128 *) + 0x4c00703a; (* arm_STR Q26 X1 No_Offset *) + 0xaa0003f4; (* arm_MOV X20 X0 *) + 0x9100402d; (* arm_ADD X13 X1 (rvalue (word 16)) *) + 0xf10006b5; (* arm_SUBS X21 X21 (rvalue (word 1)) *) + 0x3875682f; (* arm_LDRB W15 X1 (Register_Offset X21) *) + 0x38756a8e; (* arm_LDRB W14 X20 (Register_Offset X21) *) + 0x383569af; (* arm_STRB W15 X13 (Register_Offset X21) *) + 0x3835682e; (* arm_STRB W14 X1 (Register_Offset X21) *) + 0x54ffff6c; (* arm_BGT (word 2097132) *) + 0x4c40703a; (* arm_LDR Q26 X1 No_Offset *) + 0x6e261f5a; (* arm_EOR_VEC Q26 Q26 Q6 128 *) + 0xb940f0e6; (* arm_LDR W6 X7 (Immediate_Offset (word 240)) *) + 0x4cdf70e0; (* arm_LDR Q0 X7 (Postimmediate_Offset (word 16)) *) + 0x510008c6; (* arm_SUB W6 W6 (rvalue (word 2)) *) + 0x4cdf70e1; (* arm_LDR Q1 X7 (Postimmediate_Offset (word 16)) *) + 0x4e28581a; (* arm_AESD Q26 Q0 *) + 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) + 0x4cdf78e0; (* arm_LDR Q0 X7 (Postimmediate_Offset (word 16)) *) + 0x710008c6; (* arm_SUBS W6 W6 (rvalue (word 2)) *) + 0x4e28583a; (* arm_AESD Q26 Q1 *) + 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) + 0x4cdf78e1; (* arm_LDR Q1 X7 (Postimmediate_Offset (word 16)) *) + 0x54ffff2c; (* arm_BGT (word 2097124) *) + 0x4e28581a; (* arm_AESD Q26 Q0 *) + 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) + 0x4c4078e0; (* arm_LDR Q0 X7 No_Offset *) + 0x4e28583a; (* arm_AESD Q26 Q1 *) + 0x6e201f5a; (* arm_EOR_VEC Q26 Q26 Q0 128 *) + 0x6e261f5a; (* arm_EOR_VEC Q26 Q26 Q6 128 *) + 0x4c00703a; (* arm_STR Q26 X1 No_Offset *) + 0x6d4027e8; (* arm_LDP D8 D9 SP (Immediate_Offset (iword (&0))) *) + 0x6d412fea; (* arm_LDP D10 D11 SP (Immediate_Offset (iword (&16))) *) + 0xa94253f3; (* arm_LDP X19 X20 SP (Immediate_Offset (iword (&32))) *) + 0xa9435bf5; (* arm_LDP X21 X22 SP (Immediate_Offset (iword (&48))) *) + 0x910103ff; (* arm_ADD SP SP (rvalue (word 64)) *) + 0xd65f03c0 (* arm_RET X30 *) +];; \ No newline at end of file From c5585352caa1747282e0b53a7da0d37fec57332f Mon Sep 17 00:00:00 2001 From: Yan Peng Date: Tue, 24 Jun 2025 22:23:24 +0000 Subject: [PATCH 015/132] Add aes program and spec --- arm/aes-xts/aes256_decrypt.S | 34 ++++++++ arm/proofs/aes_decrypt.ml | 62 ++++++++++++++- arm/proofs/aes_decrypt_spec.ml | 139 +++++++++++++++++++++++++++++++++ 3 files changed, 233 insertions(+), 2 deletions(-) create mode 100644 arm/proofs/aes_decrypt_spec.ml diff --git a/arm/aes-xts/aes256_decrypt.S b/arm/aes-xts/aes256_decrypt.S index e69de29bb..a78061c6a 100644 --- a/arm/aes-xts/aes256_decrypt.S +++ b/arm/aes-xts/aes256_decrypt.S @@ -0,0 +1,34 @@ +// x2: key schedule +// x1: input +// x0: output +#include "_internal_s2n_bignum.h" + + S2N_BN_SYM_VISIBILITY_DIRECTIVE(aes_decrypt) + S2N_BN_SYM_PRIVACY_DIRECTIVE(aes_decrypt) + .text + .balign 4 + .arch armv8-a+crypto + +aes_decrypt: + ldr w6,[x2,#240] + ld1 {v0.16b},[x2],#16 + ld1 {v6.16b},[x1] + sub w6,w6,#2 + ld1 {v1.16b},[x2],#16 + +Loop_dec: + aesd v6.16b,v0.16b + aesimc v6.16b,v6.16b + ld1 {v0.4s},[x2],#16 + subs w6,w6,#2 + aesd v6.16b,v1.16b + aesimc v6.16b,v6.16b + ld1 {v1.4s},[x2],#16 + b.gt Loop_dec + + aesd v6.16b,v0.16b + aesimc v6.16b,v6.16b + ld1 {v0.4s},[x4] + aesd v6.16b,v1.16b + eor v6.16b,v6.16b,v0.16b + st1 {v6.4s},[x0] diff --git a/arm/proofs/aes_decrypt.ml b/arm/proofs/aes_decrypt.ml index 51a7b1d83..dada4eacc 100644 --- a/arm/proofs/aes_decrypt.ml +++ b/arm/proofs/aes_decrypt.ml @@ -7,7 +7,65 @@ use_file_raise_failure := true;; needs "arm/proofs/base.ml";; -save_literal_from_elf "arm/aes-xts/aes256_decrypt.txt" "arm/aes-xts/aes256_decrypt.o";; +print_literal_from_elf "arm/aes-xts/aes256_decrypt.o";; let aes256_decrypt_mc = define_assert_from_elf "aes256_decrypt" "arm/aes-xts/aes256_decrypt.o" -[];; \ No newline at end of file +[ + 0xb940f046; (* arm_LDR W6 X2 (Immediate_Offset (word 240)) *) + 0x4cdf7040; (* arm_LDR Q0 X2 (Postimmediate_Offset (word 16)) *) + 0x4c407026; (* arm_LDR Q6 X1 No_Offset *) + 0x510008c6; (* arm_SUB W6 W6 (rvalue (word 2)) *) + 0x4cdf7041; (* arm_LDR Q1 X2 (Postimmediate_Offset (word 16)) *) + 0x4e285806; (* arm_AESD Q6 Q0 *) + 0x4e2878c6; (* arm_AESIMC Q6 Q6 *) + 0x4cdf7840; (* arm_LDR Q0 X2 (Postimmediate_Offset (word 16)) *) + 0x710008c6; (* arm_SUBS W6 W6 (rvalue (word 2)) *) + 0x4e285826; (* arm_AESD Q6 Q1 *) + 0x4e2878c6; (* arm_AESIMC Q6 Q6 *) + 0x4cdf7841; (* arm_LDR Q1 X2 (Postimmediate_Offset (word 16)) *) + 0x54ffff2c; (* arm_BGT (word 2097124) *) + 0x4e285806; (* arm_AESD Q6 Q0 *) + 0x4e2878c6; (* arm_AESIMC Q6 Q6 *) + 0x4c407880; (* arm_LDR Q0 X4 No_Offset *) + 0x4e285826; (* arm_AESD Q6 Q1 *) + 0x6e201cc6; (* arm_EOR_VEC Q6 Q6 Q0 128 *) + 0x4c007806 (* arm_STR Q6 X0 No_Offset *) +];; + +let AES256_DECRYPT_EXEC = ARM_MK_EXEC_RULE aes256_decrypt_mc;; + +(* TODO: Could this be better? read(memory :> bytes(key, 240) = all_k) *) +let AES256_DECRYPT_CORRECT = prove( + `!out in key ib k0 k1 k2 k3 k4 k5 k6 k7 k8 k9 k10 k11 k12 k13 k14 pc. + nonoverlapping (word pc,LENGTH aes256_decrypt_mc) (out,16) + ==> ensures arm + // precondition + (\s. aligned_bytes_loaded s (word pc) aes256_encrypt_mc /\ + read PC s = word pc /\ + C_ARGUMENTS [out; in; key] s /\ + read(memory :> bytes(in, 16)) s = ib /\ + read(memory :> bytes(word_add key (word 240), 4)) = word 13 /\ + read(memory :> bytes(key, 16)) = k0 /\ + read(memory :> bytes((word_add key (word 16)), 16)) = k1 /\ + read(memory :> bytes((word_add key (word 32)), 16)) = k2 /\ + read(memory :> bytes((word_add key (word 48)), 16)) = k3 /\ + read(memory :> bytes((word_add key (word 64)), 16)) = k4 /\ + read(memory :> bytes((word_add key (word 80)), 16)) = k5 /\ + read(memory :> bytes((word_add key (word 96)), 16)) = k6 /\ + read(memory :> bytes((word_add key (word 112)), 16)) = k7 /\ + read(memory :> bytes((word_add key (word 128)), 16)) = k8 /\ + read(memory :> bytes((word_add key (word 144)), 16)) = k9 /\ + read(memory :> bytes((word_add key (word 160)), 16)) = k10 /\ + read(memory :> bytes((word_add key (word 176)), 16)) = k11 /\ + read(memory :> bytes((word_add key (word 192)), 16)) = k12 /\ + read(memory :> bytes((word_add key (word 208)), 16)) = k13 /\ + read(memory :> bytes((word_add key (word 224)), 16)) = k14) + // postcondition + // TODO: Nevine will figure out the post condition for output + // hint: use the aes256_encrypt from aes_encrypt_spec + (\s. read PC s = word (pc + LENGTH aes256_encrypt_mc) /\ + ) + // MAYCHANGE + ()`, + CHEAT_TAC +) \ No newline at end of file diff --git a/arm/proofs/aes_decrypt_spec.ml b/arm/proofs/aes_decrypt_spec.ml new file mode 100644 index 000000000..f0517cbe2 --- /dev/null +++ b/arm/proofs/aes_decrypt_spec.ml @@ -0,0 +1,139 @@ +use_file_raise_failure := true;; +needs "common/aes.ml";; + +let pp_print_num fmt tm = + let n = dest_numeral tm in + pp_print_string fmt (string_of_num_hex n) in +install_user_printer("pp_print_num",pp_print_num);; + +(* +NIST: https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.197-upd1.pdf + +procedure EQINVCIPHER(in, Nr, dw) +2: state ← in +3: state ← ADDROUNDKEY(state,dw[4 ∗Nr..4 ∗Nr +3]) +4: for round from Nr −1 downto 1 do +5: state ← INVSUBBYTES(state) +6: state ← INVSHIFTROWS(state) +7: state ← INVMIXCOLUMNS(state) +8: state ← ADDROUNDKEY(state,dw[4 ∗ round..4 ∗ round +3]) +9: end for +10: state ← INVSUBBYTES(state) +11: state ← INVSHIFTROWS(state) +12: state ← ADDROUNDKEY(state,dw[0..3]) +13: return state +14: end procedure +*) + +let aes256_decrypt_round = new_definition + `aes256_decrypt_round (block:int128) (round_key:int128) = + let res2 = aes_inv_shift_rows block in + let res3 = aes_sub_bytes joined_GF2_inv res2 in + let res1 = aes_inv_mix_columns res3 in + word_xor res1 round_key + `;; + +let aes256_decrypt = new_definition + `aes256_decrypt (block:int128) (key_schedule:int128 list) = + let res0 = word_xor block (EL 0 key_schedule) in + let res1 = aes256_decrypt_round res0 (EL 1 key_schedule) in + let res2 = aes256_decrypt_round res1 (EL 2 key_schedule) in + let res3 = aes256_decrypt_round res2 (EL 3 key_schedule) in + let res4 = aes256_decrypt_round res3 (EL 4 key_schedule) in + let res5 = aes256_decrypt_round res4 (EL 5 key_schedule) in + let res6 = aes256_decrypt_round res5 (EL 6 key_schedule) in + let res7 = aes256_decrypt_round res6 (EL 7 key_schedule) in + let res8 = aes256_decrypt_round res7 (EL 8 key_schedule) in + let res9 = aes256_decrypt_round res8 (EL 9 key_schedule) in + let res10 = aes256_decrypt_round res9 (EL 10 key_schedule) in + let res11 = aes256_decrypt_round res10 (EL 11 key_schedule) in + let res12 = aes256_decrypt_round res11 (EL 12 key_schedule) in + let res13 = aes256_decrypt_round res12 (EL 13 key_schedule) in + let res14 = aes_inv_shift_rows res13 in + let res15 = aes_sub_bytes joined_GF2_inv res14 in + word_xor res15 (EL 14 key_schedule) + `;; + +let AESDEC_ROUND_HELPER_CONV = + REWRITE_CONV [aes256_decrypt_round] THENC + AES_INV_SHIFT_ROWS_CONV THENC + AES_SUB_BYTES_CONV THENC + AES_INV_MIX_COLUMNS_CONV THENC + DEPTH_CONV (WORD_RED_CONV ORELSEC NUM_RED_CONV);; + +let AESDEC_REDUCE_CONV tm = + match tm with + Comb(Comb(Const("aes256_decrypt_round",_), + Comb(Const("word",_),state)), + Comb(Const("word",_),roundkey)) + when is_numeral state && is_numeral roundkey -> AESDEC_ROUND_HELPER_CONV tm + | _ -> failwith "AESDEC_REDUCE_CONV: inapplicable";; + +(* +Test case from AWS-LC + +Round keys: +0x36DE686D3CC21A37E97909BFCC79FC24 +0x6E0158255FE2E9FC2FAACEBFFFD1F134 +0x84E680DC46B771750A354C38EB48165E +0x31E3B1D970482743D07B3F8B8005A3C8 +0xC251F1A94C823D4DE17D5A66138E70B5 +0x41AB969AA03318C8507E9C43A37BDA74 +0x8ED3CCE4ADFF672BF2F32AD31597A63C +0xE1988E52F04D848BF3054637F3C45FF8 +0x232CABCF5F0C4DF8E7648CEF9A4069DE +0x11D50AD90348C2BC00C119CF1658D5AE +0x7C20E637B868C1177D24E531BD68C615 +0x129DC8650389DB731699CC610F85D77F +0xC4482720C54C2426C04C2324C940282A +0x1114131615101712191C1B1E1D181F1A +0x0F0E0D0C0B0A09080706050403020100 + +ciphertext: +0x8960494b9049fceabf456751cab7a28e + +plaintext: +0xffeeddccbbaa99887766554433221100 +*) + +(* These are the round keys with the bytes reversed to become little endian *) +let DEC_ROUND_KEYS = new_definition `DEC_ROUND_KEYS:int128 list = + [ word 0x36DE686D3CC21A37E97909BFCC79FC24 + ; word 0x6E0158255FE2E9FC2FAACEBFFFD1F134 + ; word 0x84E680DC46B771750A354C38EB48165E + ; word 0x31E3B1D970482743D07B3F8B8005A3C8 + ; word 0xC251F1A94C823D4DE17D5A66138E70B5 + ; word 0x41AB969AA03318C8507E9C43A37BDA74 + ; word 0x8ED3CCE4ADFF672BF2F32AD31597A63C + ; word 0xE1988E52F04D848BF3054637F3C45FF8 + ; word 0x232CABCF5F0C4DF8E7648CEF9A4069DE + ; word 0x11D50AD90348C2BC00C119CF1658D5AE + ; word 0x7C20E637B868C1177D24E531BD68C615 + ; word 0x129DC8650389DB731699CC610F85D77F + ; word 0xC4482720C54C2426C04C2324C940282A + ; word 0x1114131615101712191C1B1E1D181F1A + ; word 0x0F0E0D0C0B0A09080706050403020100 + ]`;; + +let EL_15_128_CLAUSES = + let pat = `EL n [x0;x1;x2;x3;x4;x5;x6;x7;x8;x9;x10;x11;x12;x13;x14]:128 word` in + map (fun n -> EL_CONV(subst [mk_small_numeral n,`n:num`] pat)) (0--14);; + +let AESDEC_HELPER_CONV = + REWR_CONV aes256_decrypt THENC + REWRITE_CONV [DEC_ROUND_KEYS] THENC + REWRITE_CONV EL_15_128_CLAUSES THENC + REPEATC let_CONV THENC + DEPTH_CONV (WORD_RED_CONV ORELSEC NUM_RED_CONV) THENC + DEPTH_CONV AESDEC_REDUCE_CONV THENC + AES_INV_SHIFT_ROWS_CONV THENC + AES_SUB_BYTES_CONV THENC + DEPTH_CONV (WORD_RED_CONV ORELSEC NUM_RED_CONV) + ;; + +(* +time prove (`aes256_decrypt + (word 0x8960494b9049fceabf456751cab7a28e) + DEC_ROUND_KEYS = word 0xffeeddccbbaa99887766554433221100`, + CONV_TAC(LAND_CONV AESDEC_HELPER_CONV) THEN REFL_TAC);; +*) \ No newline at end of file From 1e8932b1765bbbc6ede5812ffa66a03124f78b1f Mon Sep 17 00:00:00 2001 From: Yan Peng Date: Tue, 24 Jun 2025 23:35:45 +0000 Subject: [PATCH 016/132] Symbolic simulation and fixed a bug in code --- arm/aes-xts/aes256_decrypt.S | 2 +- arm/proofs/aes_decrypt.ml | 89 +++++++++++++++++++++--------------- 2 files changed, 52 insertions(+), 39 deletions(-) diff --git a/arm/aes-xts/aes256_decrypt.S b/arm/aes-xts/aes256_decrypt.S index a78061c6a..a2cac8c5c 100644 --- a/arm/aes-xts/aes256_decrypt.S +++ b/arm/aes-xts/aes256_decrypt.S @@ -28,7 +28,7 @@ Loop_dec: aesd v6.16b,v0.16b aesimc v6.16b,v6.16b - ld1 {v0.4s},[x4] + ld1 {v0.4s},[x2] aesd v6.16b,v1.16b eor v6.16b,v6.16b,v0.16b st1 {v6.4s},[x0] diff --git a/arm/proofs/aes_decrypt.ml b/arm/proofs/aes_decrypt.ml index dada4eacc..075c3494e 100644 --- a/arm/proofs/aes_decrypt.ml +++ b/arm/proofs/aes_decrypt.ml @@ -4,31 +4,33 @@ *) use_file_raise_failure := true;; +arm_print_log := true;; needs "arm/proofs/base.ml";; +loadt "arm/proofs/aes_decrypt_spec.ml";; print_literal_from_elf "arm/aes-xts/aes256_decrypt.o";; -let aes256_decrypt_mc = define_assert_from_elf "aes256_decrypt" "arm/aes-xts/aes256_decrypt.o" +let aes256_decrypt_mc = define_assert_from_elf "aes256_decrypt_mc" "arm/aes-xts/aes256_decrypt.o" [ - 0xb940f046; (* arm_LDR W6 X2 (Immediate_Offset (word 240)) *) - 0x4cdf7040; (* arm_LDR Q0 X2 (Postimmediate_Offset (word 16)) *) + 0xb940f046; (* arm_LDR W6 X2 (Immediate_Offset (word 0xf0)) *) + 0x4cdf7040; (* arm_LDR Q0 X2 (Postimmediate_Offset (word 0x10)) *) 0x4c407026; (* arm_LDR Q6 X1 No_Offset *) - 0x510008c6; (* arm_SUB W6 W6 (rvalue (word 2)) *) - 0x4cdf7041; (* arm_LDR Q1 X2 (Postimmediate_Offset (word 16)) *) + 0x510008c6; (* arm_SUB W6 W6 (rvalue (word 0x2)) *) + 0x4cdf7041; (* arm_LDR Q1 X2 (Postimmediate_Offset (word 0x10)) *) 0x4e285806; (* arm_AESD Q6 Q0 *) 0x4e2878c6; (* arm_AESIMC Q6 Q6 *) - 0x4cdf7840; (* arm_LDR Q0 X2 (Postimmediate_Offset (word 16)) *) - 0x710008c6; (* arm_SUBS W6 W6 (rvalue (word 2)) *) + 0x4cdf7840; (* arm_LDR Q0 X2 (Postimmediate_Offset (word 0x10)) *) + 0x710008c6; (* arm_SUBS W6 W6 (rvalue (word 0x2)) *) 0x4e285826; (* arm_AESD Q6 Q1 *) 0x4e2878c6; (* arm_AESIMC Q6 Q6 *) - 0x4cdf7841; (* arm_LDR Q1 X2 (Postimmediate_Offset (word 16)) *) - 0x54ffff2c; (* arm_BGT (word 2097124) *) + 0x4cdf7841; (* arm_LDR Q1 X2 (Postimmediate_Offset (word 0x10)) *) + 0x54ffff2c; (* arm_BGT (word 0x1fffe4) *) 0x4e285806; (* arm_AESD Q6 Q0 *) 0x4e2878c6; (* arm_AESIMC Q6 Q6 *) - 0x4c407880; (* arm_LDR Q0 X4 No_Offset *) + 0x4c407840; (* arm_LDR Q0 X2 No_Offset *) 0x4e285826; (* arm_AESD Q6 Q1 *) - 0x6e201cc6; (* arm_EOR_VEC Q6 Q6 Q0 128 *) + 0x6e201cc6; (* arm_EOR_VEC Q6 Q6 Q0 0x80 *) 0x4c007806 (* arm_STR Q6 X0 No_Offset *) ];; @@ -36,36 +38,47 @@ let AES256_DECRYPT_EXEC = ARM_MK_EXEC_RULE aes256_decrypt_mc;; (* TODO: Could this be better? read(memory :> bytes(key, 240) = all_k) *) let AES256_DECRYPT_CORRECT = prove( - `!out in key ib k0 k1 k2 k3 k4 k5 k6 k7 k8 k9 k10 k11 k12 k13 k14 pc. - nonoverlapping (word pc,LENGTH aes256_decrypt_mc) (out,16) + `!plaintext ciphertext key ib k0 k1 k2 k3 k4 k5 k6 k7 k8 k9 k10 k11 k12 k13 k14 pc. + nonoverlapping (word pc,LENGTH aes256_decrypt_mc) (plaintext,16) ==> ensures arm // precondition - (\s. aligned_bytes_loaded s (word pc) aes256_encrypt_mc /\ + (\s. aligned_bytes_loaded s (word pc) aes256_decrypt_mc /\ read PC s = word pc /\ - C_ARGUMENTS [out; in; key] s /\ - read(memory :> bytes(in, 16)) s = ib /\ - read(memory :> bytes(word_add key (word 240), 4)) = word 13 /\ - read(memory :> bytes(key, 16)) = k0 /\ - read(memory :> bytes((word_add key (word 16)), 16)) = k1 /\ - read(memory :> bytes((word_add key (word 32)), 16)) = k2 /\ - read(memory :> bytes((word_add key (word 48)), 16)) = k3 /\ - read(memory :> bytes((word_add key (word 64)), 16)) = k4 /\ - read(memory :> bytes((word_add key (word 80)), 16)) = k5 /\ - read(memory :> bytes((word_add key (word 96)), 16)) = k6 /\ - read(memory :> bytes((word_add key (word 112)), 16)) = k7 /\ - read(memory :> bytes((word_add key (word 128)), 16)) = k8 /\ - read(memory :> bytes((word_add key (word 144)), 16)) = k9 /\ - read(memory :> bytes((word_add key (word 160)), 16)) = k10 /\ - read(memory :> bytes((word_add key (word 176)), 16)) = k11 /\ - read(memory :> bytes((word_add key (word 192)), 16)) = k12 /\ - read(memory :> bytes((word_add key (word 208)), 16)) = k13 /\ - read(memory :> bytes((word_add key (word 224)), 16)) = k14) + C_ARGUMENTS [plaintext; ciphertext; key] s /\ + read(memory :> bytes128 ciphertext) s = ib /\ + read(memory :> bytes32 (word_add key (word 240))) s = word 14 /\ + read(memory :> bytes128 key) s = k0 /\ + read(memory :> bytes128 (word_add key (word 16))) s = k1 /\ + read(memory :> bytes128 (word_add key (word 32))) s = k2 /\ + read(memory :> bytes128 (word_add key (word 48))) s = k3 /\ + read(memory :> bytes128 (word_add key (word 64))) s = k4 /\ + read(memory :> bytes128 (word_add key (word 80))) s = k5 /\ + read(memory :> bytes128 (word_add key (word 96))) s = k6 /\ + read(memory :> bytes128 (word_add key (word 112))) s = k7 /\ + read(memory :> bytes128 (word_add key (word 128))) s = k8 /\ + read(memory :> bytes128 (word_add key (word 144))) s = k9 /\ + read(memory :> bytes128 (word_add key (word 160))) s = k10 /\ + read(memory :> bytes128 (word_add key (word 176))) s = k11 /\ + read(memory :> bytes128 (word_add key (word 192))) s = k12 /\ + read(memory :> bytes128 (word_add key (word 208))) s = k13 /\ + read(memory :> bytes128 (word_add key (word 224))) s = k14) // postcondition - // TODO: Nevine will figure out the post condition for output - // hint: use the aes256_encrypt from aes_encrypt_spec - (\s. read PC s = word (pc + LENGTH aes256_encrypt_mc) /\ - ) + (\s. read PC s = word (pc + LENGTH aes256_decrypt_mc) /\ + read (memory :> bytes128 plaintext) s = + aes256_decrypt ib [k0; k1; k2; k3; k4; k5; k6; k7; k8; k9; k10; k11; k12; k13; k14] + ) // MAYCHANGE - ()`, + (MAYCHANGE [PC])`, + MAP_EVERY X_GEN_TAC + [`plaintext:int64`; `ciphertext:int64`; `key:int64`; + `ib:int128`; `k0:int128`; `k1:int128`; `k2:int128`; + `k3:int128`; `k4:int128`; `k5:int128`; `k6:int128`; + `k7:int128`; `k8:int128`; `k9:int128`; `k10:int128`; + `k11:int128`; `k12:int128`; `k13:int128`; `k14:int128`; `pc:num`] THEN + REWRITE_TAC[C_ARGUMENTS; SOME_FLAGS;NONOVERLAPPING_CLAUSES] THEN + REWRITE_TAC [(REWRITE_CONV [aes256_decrypt_mc] THENC LENGTH_CONV) `LENGTH aes256_decrypt_mc`] THEN + DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN + ENSURES_INIT_TAC "s0" THEN + ARM_ACCSTEPS_TAC AES256_DECRYPT_EXEC [] (1--59) THEN CHEAT_TAC -) \ No newline at end of file +);; \ No newline at end of file From 8649a9c3ffcdffbd15134f2e062031e01e6d959b Mon Sep 17 00:00:00 2001 From: Yan Peng Date: Tue, 24 Jun 2025 23:55:27 +0000 Subject: [PATCH 017/132] Finish the proof for aes-xts-decrypt --- arm/proofs/aes_decrypt.ml | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/arm/proofs/aes_decrypt.ml b/arm/proofs/aes_decrypt.ml index 075c3494e..8da310298 100644 --- a/arm/proofs/aes_decrypt.ml +++ b/arm/proofs/aes_decrypt.ml @@ -64,21 +64,34 @@ let AES256_DECRYPT_CORRECT = prove( read(memory :> bytes128 (word_add key (word 224))) s = k14) // postcondition (\s. read PC s = word (pc + LENGTH aes256_decrypt_mc) /\ - read (memory :> bytes128 plaintext) s = + read (memory :> bytes128 plaintext) s = aes256_decrypt ib [k0; k1; k2; k3; k4; k5; k6; k7; k8; k9; k10; k11; k12; k13; k14] ) // MAYCHANGE - (MAYCHANGE [PC])`, + (MAYCHANGE [PC;X6;X2] ,, MAYCHANGE [Q0; Q1; Q6],, + MAYCHANGE [memory :> bytes128 plaintext],, + MAYCHANGE SOME_FLAGS,, MAYCHANGE [events])`, MAP_EVERY X_GEN_TAC - [`plaintext:int64`; `ciphertext:int64`; `key:int64`; - `ib:int128`; `k0:int128`; `k1:int128`; `k2:int128`; - `k3:int128`; `k4:int128`; `k5:int128`; `k6:int128`; - `k7:int128`; `k8:int128`; `k9:int128`; `k10:int128`; + [`plaintext:int64`; `ciphertext:int64`; `key:int64`; + `ib:int128`; `k0:int128`; `k1:int128`; `k2:int128`; + `k3:int128`; `k4:int128`; `k5:int128`; `k6:int128`; + `k7:int128`; `k8:int128`; `k9:int128`; `k10:int128`; `k11:int128`; `k12:int128`; `k13:int128`; `k14:int128`; `pc:num`] THEN REWRITE_TAC[C_ARGUMENTS; SOME_FLAGS;NONOVERLAPPING_CLAUSES] THEN REWRITE_TAC [(REWRITE_CONV [aes256_decrypt_mc] THENC LENGTH_CONV) `LENGTH aes256_decrypt_mc`] THEN DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN ENSURES_INIT_TAC "s0" THEN ARM_ACCSTEPS_TAC AES256_DECRYPT_EXEC [] (1--59) THEN - CHEAT_TAC -);; \ No newline at end of file + ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN + + CONJ_TAC THENL + [ REWRITE_TAC [aes256_decrypt] THEN + REWRITE_TAC EL_15_128_CLAUSES THEN + REWRITE_TAC [aes256_decrypt_round] THEN + CONV_TAC(TOP_DEPTH_CONV let_CONV) THEN + (*do sth about let*) + REWRITE_TAC [aesd;aesimc] THEN + GEN_REWRITE_TAC LAND_CONV [WORD_XOR_SYM] THEN + REFL_TAC + ] +);; From 5b951ab40049bd0259c17ab71bd01bc37059ad5d Mon Sep 17 00:00:00 2001 From: Yan Peng Date: Fri, 27 Jun 2025 19:00:56 +0000 Subject: [PATCH 018/132] Fix a bug --- arm/proofs/aes_decrypt.ml | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/arm/proofs/aes_decrypt.ml b/arm/proofs/aes_decrypt.ml index 8da310298..4d96fb2ea 100644 --- a/arm/proofs/aes_decrypt.ml +++ b/arm/proofs/aes_decrypt.ml @@ -84,14 +84,11 @@ let AES256_DECRYPT_CORRECT = prove( ARM_ACCSTEPS_TAC AES256_DECRYPT_EXEC [] (1--59) THEN ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN - CONJ_TAC THENL - [ REWRITE_TAC [aes256_decrypt] THEN - REWRITE_TAC EL_15_128_CLAUSES THEN - REWRITE_TAC [aes256_decrypt_round] THEN - CONV_TAC(TOP_DEPTH_CONV let_CONV) THEN - (*do sth about let*) - REWRITE_TAC [aesd;aesimc] THEN - GEN_REWRITE_TAC LAND_CONV [WORD_XOR_SYM] THEN - REFL_TAC - ] + REWRITE_TAC [aes256_decrypt] THEN + REWRITE_TAC EL_15_128_CLAUSES THEN + REWRITE_TAC [aes256_decrypt_round] THEN + CONV_TAC(TOP_DEPTH_CONV let_CONV) THEN + REWRITE_TAC [aesd;aesimc] THEN + GEN_REWRITE_TAC LAND_CONV [WORD_XOR_SYM] THEN + REFL_TAC );; From 684f3f7c95c2bbf9fbdde57b7aaad2cc7b324c91 Mon Sep 17 00:00:00 2001 From: Yan Peng Date: Wed, 25 Jun 2025 01:14:53 +0000 Subject: [PATCH 019/132] Set up for aes-xts one block proof --- arm/aes-xts/aes_xts_decrypt_armv8.S | 10 +++++ arm/proofs/aes_xts_decrypt.ml | 57 ++++++++++++++++++++++++++++- arm/proofs/aes_xts_decrypt_spec.ml | 21 +++++++++++ 3 files changed, 86 insertions(+), 2 deletions(-) create mode 100644 arm/proofs/aes_xts_decrypt_spec.ml diff --git a/arm/aes-xts/aes_xts_decrypt_armv8.S b/arm/aes-xts/aes_xts_decrypt_armv8.S index 492f6df83..274c4ceba 100644 --- a/arm/aes-xts/aes_xts_decrypt_armv8.S +++ b/arm/aes-xts/aes_xts_decrypt_armv8.S @@ -4,6 +4,16 @@ # TODO: figure out copyright ############################################################################# +// ---------------------------------------------------------------------------- +// AES_XTS_DECRYPT (256-bit) +// +// void aes_hw_xts_decrypt(const uint8_t *in, uint8_t *out, size_t length, +// const AES_KEY *key1, const AES_KEY *key2, +// const uint8_t iv[16]); +// +// Standard ARM ABI: X0 = in, X1 = out, X2 = length, X3 = key1, X4 = key2, X5 = iv, returns X1 +// ---------------------------------------------------------------------------- + #include "_internal_s2n_bignum.h" S2N_BN_SYM_VISIBILITY_DIRECTIVE(aes_hw_xts_decrypt) diff --git a/arm/proofs/aes_xts_decrypt.ml b/arm/proofs/aes_xts_decrypt.ml index 7b862b1d3..38d1c650a 100644 --- a/arm/proofs/aes_xts_decrypt.ml +++ b/arm/proofs/aes_xts_decrypt.ml @@ -8,7 +8,7 @@ use_file_raise_failure := true;; needs "arm/proofs/base.ml";; (* print_literal_from_elf "arm/aes-xts/aes_xts_decrypt_armv8.o";; *) -let aes_xts_decrypt_mc = define_assert_from_elf "aes_hw_xts_decrypt" "arm/aes-xts/aes_xts_decrypt_armv8.o" +let aes_xts_decrypt_mc = define_assert_from_elf "aes_hw_xts_decrypt_mc" "arm/aes-xts/aes_xts_decrypt_armv8.o" [ 0xd10103ff; (* arm_SUB SP SP (rvalue (word 64)) *) 0x6d0027e8; (* arm_STP D8 D9 SP (Immediate_Offset (iword (&0))) *) @@ -721,4 +721,57 @@ let aes_xts_decrypt_mc = define_assert_from_elf "aes_hw_xts_decrypt" "arm/aes-xt 0xa9435bf5; (* arm_LDP X21 X22 SP (Immediate_Offset (iword (&48))) *) 0x910103ff; (* arm_ADD SP SP (rvalue (word 64)) *) 0xd65f03c0 (* arm_RET X30 *) -];; \ No newline at end of file +];; + +let AES_XTS_DECRYPT_EXEC = ARM_MK_EXEC_RULE aes_xts_decrypt_mc;; + +let AES_XTS_DECRYPT_CORRECT = prove( + `!ct_ptr pt_ptr len key0_ptr key1_ptr iv_ptr ib iv + k00 k01 k02 k03 k04 k05 k06 k07 k08 k09 k0a k0b k0c k0d k0e + k10 k11 k12 k13 k14 k15 k16 k17 k18 k19 k1a k1b k1c k1d k1e + pc. + nonoverlapping (word pc, LENGTH aes_xts_decrypt_mc) (pt_ptr, val len) + ==> ensures arm + (\s. aligned_bytes_loaded s (word pc) aes_xts_decrypt_mc /\ + read PC s = word pc /\ + C_ARGUMENTS [ct_ptr; pt_ptr; len; key0_ptr; key1_ptr; iv_ptr] s /\ + read(memory :> bytes128 ct_ptr) s = ib /\ + read(memory :> bytes128 iv_ptr) s = iv /\ + read(memory :> bytes128 key0_ptr) s = k00 /\ + read(memory :> bytes128 (word_add key0_ptr (word 16))) s = k01 /\ + read(memory :> bytes128 (word_add key0_ptr (word 32))) s = k02 /\ + read(memory :> bytes128 (word_add key0_ptr (word 48))) s = k03 /\ + read(memory :> bytes128 (word_add key0_ptr (word 64))) s = k04 /\ + read(memory :> bytes128 (word_add key0_ptr (word 80))) s = k05 /\ + read(memory :> bytes128 (word_add key0_ptr (word 96))) s = k06 /\ + read(memory :> bytes128 (word_add key0_ptr (word 112))) s = k07 /\ + read(memory :> bytes128 (word_add key0_ptr (word 128))) s = k08 /\ + read(memory :> bytes128 (word_add key0_ptr (word 144))) s = k09 /\ + read(memory :> bytes128 (word_add key0_ptr (word 160))) s = k0a /\ + read(memory :> bytes128 (word_add key0_ptr (word 176))) s = k0b /\ + read(memory :> bytes128 (word_add key0_ptr (word 192))) s = k0c /\ + read(memory :> bytes128 (word_add key0_ptr (word 208))) s = k0d /\ + read(memory :> bytes128 (word_add key0_ptr (word 224))) s = k0e /\ + read(memory :> bytes32 (word_add key0_ptr (word 240))) s = word 14 /\ + read(memory :> bytes128 key1_ptr) s = k10 /\ + read(memory :> bytes128 (word_add key1_ptr (word 16))) s = k11 /\ + read(memory :> bytes128 (word_add key1_ptr (word 32))) s = k12 /\ + read(memory :> bytes128 (word_add key1_ptr (word 48))) s = k13 /\ + read(memory :> bytes128 (word_add key1_ptr (word 64))) s = k14 /\ + read(memory :> bytes128 (word_add key1_ptr (word 80))) s = k15 /\ + read(memory :> bytes128 (word_add key1_ptr (word 96))) s = k16 /\ + read(memory :> bytes128 (word_add key1_ptr (word 112))) s = k17 /\ + read(memory :> bytes128 (word_add key1_ptr (word 128))) s = k18 /\ + read(memory :> bytes128 (word_add key1_ptr (word 144))) s = k19 /\ + read(memory :> bytes128 (word_add key1_ptr (word 160))) s = k1a /\ + read(memory :> bytes128 (word_add key1_ptr (word 176))) s = k1b /\ + read(memory :> bytes128 (word_add key1_ptr (word 192))) s = k1c /\ + read(memory :> bytes128 (word_add key1_ptr (word 208))) s = k1d /\ + read(memory :> bytes128 (word_add key1_ptr (word 224))) s = k1e /\ + read(memory :> bytes32 (word_add key1_ptr (word 240))) s = word 14 + ) + (\s. read PC s = word (pc + LENGTH aes_xts_decrypt_mc)) + (MAYCHANGE SOME_FLAGS,, MAYCHANGE [memory :> bytes128 pt_ptr]) + `, + CHEAT_TAC +);; \ No newline at end of file diff --git a/arm/proofs/aes_xts_decrypt_spec.ml b/arm/proofs/aes_xts_decrypt_spec.ml new file mode 100644 index 000000000..fde82dfdd --- /dev/null +++ b/arm/proofs/aes_xts_decrypt_spec.ml @@ -0,0 +1,21 @@ +use_file_raise_failure := true;; +needs "common/aes.ml";; +loadt "arm/proofs/aes_encrypt_spec.ml";; +loadt "arm/proofs/aes_decrypt_spec.ml";; + +let pp_print_num fmt tm = + let n = dest_numeral tm in + pp_print_string fmt (string_of_num_hex n) in +install_user_printer("pp_print_num",pp_print_num);; + +(* +https://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=8637988 + +*) + +let xts_init_tweak = new_definition + `xts_init_tweak (iv:int128) (key_schedule:int128 list) = + aes256_encrypt iv key_schedule`;; + +let aes256_xts_decrypt_round = new_definition + ``;; From 3dde45961e11274bdaa56dd49e4b91bde4750f2e Mon Sep 17 00:00:00 2001 From: Yan Peng Date: Tue, 1 Jul 2025 06:00:59 +0000 Subject: [PATCH 020/132] Define spec for one block xts and define conversion --- arm/aes-xts/aes_xts_decrypt_armv8.S | 1 - arm/proofs/aes_decrypt_spec.ml | 12 +-- arm/proofs/aes_encrypt_spec.ml | 70 +++------------- arm/proofs/aes_xts_decrypt_spec.ml | 121 +++++++++++++++++++++++++++- 4 files changed, 135 insertions(+), 69 deletions(-) diff --git a/arm/aes-xts/aes_xts_decrypt_armv8.S b/arm/aes-xts/aes_xts_decrypt_armv8.S index 274c4ceba..4450dd6a7 100644 --- a/arm/aes-xts/aes_xts_decrypt_armv8.S +++ b/arm/aes-xts/aes_xts_decrypt_armv8.S @@ -121,7 +121,6 @@ Loop_iv_enc: ld1 {v20.4s,v21.4s},[x7], #32 ld1 {v22.4s,v23.4s},[x7], #32 ld1 {v7.4s}, [x7] - // add x7, x3, #32 // decryption Lxts_dec: diff --git a/arm/proofs/aes_decrypt_spec.ml b/arm/proofs/aes_decrypt_spec.ml index f0517cbe2..a8d862eed 100644 --- a/arm/proofs/aes_decrypt_spec.ml +++ b/arm/proofs/aes_decrypt_spec.ml @@ -61,13 +61,13 @@ let AESDEC_ROUND_HELPER_CONV = AES_INV_MIX_COLUMNS_CONV THENC DEPTH_CONV (WORD_RED_CONV ORELSEC NUM_RED_CONV);; -let AESDEC_REDUCE_CONV tm = +let AESDEC_ROUND_REDUCE_CONV tm = match tm with Comb(Comb(Const("aes256_decrypt_round",_), Comb(Const("word",_),state)), Comb(Const("word",_),roundkey)) when is_numeral state && is_numeral roundkey -> AESDEC_ROUND_HELPER_CONV tm - | _ -> failwith "AESDEC_REDUCE_CONV: inapplicable";; + | _ -> failwith "AESDEC_ROUND_REDUCE_CONV: inapplicable";; (* Test case from AWS-LC @@ -119,13 +119,13 @@ let EL_15_128_CLAUSES = let pat = `EL n [x0;x1;x2;x3;x4;x5;x6;x7;x8;x9;x10;x11;x12;x13;x14]:128 word` in map (fun n -> EL_CONV(subst [mk_small_numeral n,`n:num`] pat)) (0--14);; -let AESDEC_HELPER_CONV = +let AESDEC_HELPER_CONV KEYS = REWR_CONV aes256_decrypt THENC - REWRITE_CONV [DEC_ROUND_KEYS] THENC + REWRITE_CONV [KEYS] THENC REWRITE_CONV EL_15_128_CLAUSES THENC REPEATC let_CONV THENC DEPTH_CONV (WORD_RED_CONV ORELSEC NUM_RED_CONV) THENC - DEPTH_CONV AESDEC_REDUCE_CONV THENC + DEPTH_CONV AESDEC_ROUND_REDUCE_CONV THENC AES_INV_SHIFT_ROWS_CONV THENC AES_SUB_BYTES_CONV THENC DEPTH_CONV (WORD_RED_CONV ORELSEC NUM_RED_CONV) @@ -135,5 +135,5 @@ let AESDEC_HELPER_CONV = time prove (`aes256_decrypt (word 0x8960494b9049fceabf456751cab7a28e) DEC_ROUND_KEYS = word 0xffeeddccbbaa99887766554433221100`, - CONV_TAC(LAND_CONV AESDEC_HELPER_CONV) THEN REFL_TAC);; + CONV_TAC(LAND_CONV (AESDEC_HELPER_CONV DEC_ROUND_KEYS)) THEN REFL_TAC);; *) \ No newline at end of file diff --git a/arm/proofs/aes_encrypt_spec.ml b/arm/proofs/aes_encrypt_spec.ml index 320320762..62f320809 100644 --- a/arm/proofs/aes_encrypt_spec.ml +++ b/arm/proofs/aes_encrypt_spec.ml @@ -19,19 +19,14 @@ AddRoundKey(state, w[0, Nb-1]) // See Sec. 5.1.4 for round = 1 step 1 to Nr–1 SubBytes(state) // See Sec. 5.1.1 - ShiftRows(state) // See Sec. 5.1.2 - MixColumns(state) // See Sec. 5.1.3 - AddRoundKey(state, w[round*Nb, (round+1)*Nb-1]) end for SubBytes(state) - ShiftRows(state) - AddRoundKey(state, w[Nr*Nb, (Nr+1)*Nb-1]) out = state @@ -75,37 +70,30 @@ let aes256_encrypt = new_definition word_xor res15 (EL 14 key_schedule) `;; -let PRINT_TERM_CONV t = Format.printf "%a\n" pp_print_qterm t; ALL_CONV t;; - let AESENC_ROUND_HELPER_CONV = - PRINT_TERM_CONV THENC REWRITE_CONV [aes256_encrypt_round] THENC - (*PRINT_TERM_CONV THENC*) AES_SHIFT_ROWS_CONV THENC - (*PRINT_TERM_CONV THENC*) AES_SUB_BYTES_CONV THENC - PRINT_TERM_CONV THENC AES_MIX_COLUMNS_CONV THENC - PRINT_TERM_CONV THENC DEPTH_CONV (WORD_RED_CONV ORELSEC NUM_RED_CONV);; -let AESENC_REDUCE_CONV tm = +let AESENC_ROUND_REDUCE_CONV tm = match tm with Comb(Comb(Const("aes256_encrypt_round",_), Comb(Const("word",_),state)), Comb(Const("word",_),roundkey)) when is_numeral state && is_numeral roundkey -> AESENC_ROUND_HELPER_CONV tm - | _ -> failwith "AESENC_REDUCE_CONV: inapplicable";; + | _ -> failwith "AESENC_ROUND_REDUCE_CONV: inapplicable";; prove(`aes256_encrypt_round (word 0x7b5b54657374566563746f725d53475d) (word 0x48692853686179295b477565726f6e5d) = word 0xa8311c2f9fdba3c58b104b58ded7e595`, - CONV_TAC(LAND_CONV AESENC_REDUCE_CONV) THEN REFL_TAC);; + CONV_TAC(LAND_CONV AESENC_ROUND_REDUCE_CONV) THEN REFL_TAC);; prove(`aes256_encrypt_round (word 0xAB60EEF6E1D04EC228EE8A3BF255FC0B) (word 0xF4DF1409A310982DD708613B072C351F) = word 0x416EAD9670A2C6D71CFE3FCCB03F10D9`, - CONV_TAC(LAND_CONV AESENC_REDUCE_CONV) THEN REFL_TAC);; + CONV_TAC(LAND_CONV AESENC_ROUND_REDUCE_CONV) THEN REFL_TAC);; (* https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/AES_Core256.pdf @@ -162,60 +150,20 @@ let EL_15_128_CLAUSES = let pat = `EL n [x0;x1;x2;x3;x4;x5;x6;x7;x8;x9;x10;x11;x12;x13;x14]:128 word` in map (fun n -> EL_CONV(subst [mk_small_numeral n,`n:num`] pat)) (0--14);; -REWRITE_CONV [ROUND_KEYS] - `let res0 = - word_xor (word 143233380420387077518460912116591433514) (EL 0 ROUND_KEYS) in - let res1 = aes256_encrypt_round res0 (EL 1 ROUND_KEYS) in - let res2 = aes256_encrypt_round res1 (EL 2 ROUND_KEYS) in - let res3 = aes256_encrypt_round res2 (EL 3 ROUND_KEYS) in - let res4 = aes256_encrypt_round res3 (EL 4 ROUND_KEYS) in - let res5 = aes256_encrypt_round res4 (EL 5 ROUND_KEYS) in - let res6 = aes256_encrypt_round res5 (EL 6 ROUND_KEYS) in - let res7 = aes256_encrypt_round res6 (EL 7 ROUND_KEYS) in - let res8 = aes256_encrypt_round res7 (EL 8 ROUND_KEYS) in - let res9 = aes256_encrypt_round res8 (EL 9 ROUND_KEYS) in - let res10 = aes256_encrypt_round res9 (EL 10 ROUND_KEYS) in - let res11 = aes256_encrypt_round res10 (EL 11 ROUND_KEYS) in - let res12 = aes256_encrypt_round res11 (EL 12 ROUND_KEYS) in - let res13 = aes256_encrypt_round res12 (EL 13 ROUND_KEYS) in - let res14 = aes_shift_rows res13 in - let res15 = aes_sub_bytes joined_GF2 res14 in - word_xor res15 (EL 14 ROUND_KEYS)`;; - -let AESENC_HELPER_CONV = - PRINT_TERM_CONV THENC - REWR_CONV aes256_encrypt THENC -(* PRINT_TERM_CONV THENC *) - REWRITE_CONV [ROUND_KEYS] THENC -(* PRINT_TERM_CONV THENC *) +let AESENC_HELPER_CONV KEYS = + REWRITE_CONV [aes256_encrypt] THENC + REWRITE_CONV [KEYS] THENC REWRITE_CONV EL_15_128_CLAUSES THENC -(* PRINT_TERM_CONV THENC *) REPEATC let_CONV THENC DEPTH_CONV (WORD_RED_CONV ORELSEC NUM_RED_CONV) THENC - DEPTH_CONV AESENC_REDUCE_CONV THENC + DEPTH_CONV AESENC_ROUND_REDUCE_CONV THENC AES_SHIFT_ROWS_CONV THENC AES_SUB_BYTES_CONV THENC - PRINT_TERM_CONV THENC - DEPTH_CONV (WORD_RED_CONV ORELSEC NUM_RED_CONV) - ;; - -(* -(* This proof works and takes about half a minute on an M3 *) -let tmp = AESENC_HELPER_CONV - `aes256_encrypt - (word 0x2A179373117E3DE9969F402EE2BEC16B) - ROUND_KEYS`;; - -prove(list_mk_comb (`(=):((128)word->(128)word->bool)`, - [rand (concl tmp);`(word 0xf881b13d7e5a4b063ca0d2b5bdd1eef3):(128)word`]), - REFL_TAC);; -*) + DEPTH_CONV (WORD_RED_CONV ORELSEC NUM_RED_CONV);; (* -(* This other form of the proof works as well in half a minute *) time prove (`aes256_encrypt (word 0x2A179373117E3DE9969F402EE2BEC16B) ROUND_KEYS = word 0xF881B13D7E5A4B063CA0D2B5BDD1EEF3`, CONV_TAC(LAND_CONV AESENC_HELPER_CONV) THEN REFL_TAC);; *) - diff --git a/arm/proofs/aes_xts_decrypt_spec.ml b/arm/proofs/aes_xts_decrypt_spec.ml index fde82dfdd..a83cfdb30 100644 --- a/arm/proofs/aes_xts_decrypt_spec.ml +++ b/arm/proofs/aes_xts_decrypt_spec.ml @@ -9,8 +9,17 @@ let pp_print_num fmt tm = install_user_printer("pp_print_num",pp_print_num);; (* +IEEE Standard for Cryptographic Protection of +Data on Block-Oriented Storage Devices https://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=8637988 +Section 5.4.1 + +a) T ← AES-enc(Key2, i) ⊗ αj +b) CC ← C ⊕ T +c) PP ← AES-dec(Key1, CC) +d) P ← PP ⊕ T + *) let xts_init_tweak = new_definition @@ -18,4 +27,114 @@ let xts_init_tweak = new_definition aes256_encrypt iv key_schedule`;; let aes256_xts_decrypt_round = new_definition - ``;; + `aes256_xts_decrypt_round (C:int128) (tk:int128) (key_schedule:int128 list) = + let CC = word_xor C tk in + let PP = aes256_decrypt CC key_schedule in + word_xor PP tk`;; + +let aes256_xts_decrypt_1block = new_definition + `aes256_xts_decrypt_1block + (C:int128) (iv:int128) (key1:int128 list) (key2:int128 list) = + let tk = xts_init_tweak iv key2 in + aes256_xts_decrypt_round C tk key1`;; + + +(* Test vector: +key1: +c70a951e84370d1836bdd387607e94e5 +7ead95d6f74bf6b3103340cce21b473d +298c296cdf3241d53d0757ddbebda060 +89e66365e778b67ff22807f1cdc91c8f +f6be68b9e235160883baf7bd2340b902 +6e9ed51a1550b18e3fe11b7e185c513e +148b7eb1618fe1b5a0fa4ebf336ae76e +7bce64942ab1aaf027bd4a40982968cd +75049f04c175af0a9390a9d1d91a6526 +517fce640d0ce0b0bf94228de7e3085d +b471300e52e506db4a8accf7a81afe26 +5c732ed4b298c23d58772ad0be94ce31 +e69436d5186fca2ce29032d11463c620 +eeebece9eaefe8ede6e3e4e1e2e7e0e5 +f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff + +key2: +b0b1b2b3b4b5b6b7b8b9babbbcbdbebf +a0a1a2a3a4a5a6a7a8a9aaabacadaeaf +0ae0323bba5180880ee4363fb65d8c84 +67e123e2c740814163e527e6cb4c8d4d +908df02c9a6dc217203c429f2ed874a0 +685584790fb4a79bc8f426daab11013c +b241f85f22cc0873b8a1ca64989d88fb +338745cb5bd2c1b2546666299c9240f3 +af72a5d51d335d8a3fff55f9875e9f9d +d9e1a4a0ea66e16bb1b420d9e5d246f0 +ead5ca6245a76fb75894323d676b67c4 +e0e257483903f3e8d365128362d1325a +c26c685728b9a2356d1ecd82358affbf +4d05c122ade7966a94e4658247817701 +21a29367e3cefb30cb775905a6699487 + +iv: 0000000000000000000000123456789a + +out: 88c87a8644e587dc7e3057edf2a80cc3 + +in: 0f0e0d0c0b0a09080706050403020100 + *) + + let KEY1 = new_definition `KEY1:int128 list = + [ word 0xc70a951e84370d1836bdd387607e94e5 + ; word 0x7ead95d6f74bf6b3103340cce21b473d + ; word 0x298c296cdf3241d53d0757ddbebda060 + ; word 0x89e66365e778b67ff22807f1cdc91c8f + ; word 0xf6be68b9e235160883baf7bd2340b902 + ; word 0x6e9ed51a1550b18e3fe11b7e185c513e + ; word 0x148b7eb1618fe1b5a0fa4ebf336ae76e + ; word 0x7bce64942ab1aaf027bd4a40982968cd + ; word 0x75049f04c175af0a9390a9d1d91a6526 + ; word 0x517fce640d0ce0b0bf94228de7e3085d + ; word 0xb471300e52e506db4a8accf7a81afe26 + ; word 0x5c732ed4b298c23d58772ad0be94ce31 + ; word 0xe69436d5186fca2ce29032d11463c620 + ; word 0xeeebece9eaefe8ede6e3e4e1e2e7e0e5 + ; word 0xf0f1f2f3f4f5f6f7f8f9fafbfcfdfeff + ]`;; + +let KEY2 = new_definition `KEY2:int128 list = + [ word 0xb0b1b2b3b4b5b6b7b8b9babbbcbdbebf + ; word 0xa0a1a2a3a4a5a6a7a8a9aaabacadaeaf + ; word 0x0ae0323bba5180880ee4363fb65d8c84 + ; word 0x67e123e2c740814163e527e6cb4c8d4d + ; word 0x908df02c9a6dc217203c429f2ed874a0 + ; word 0x685584790fb4a79bc8f426daab11013c + ; word 0xb241f85f22cc0873b8a1ca64989d88fb + ; word 0x338745cb5bd2c1b2546666299c9240f3 + ; word 0xaf72a5d51d335d8a3fff55f9875e9f9d + ; word 0xd9e1a4a0ea66e16bb1b420d9e5d246f0 + ; word 0xead5ca6245a76fb75894323d676b67c4 + ; word 0xe0e257483903f3e8d365128362d1325a + ; word 0xc26c685728b9a2356d1ecd82358affbf + ; word 0x4d05c122ade7966a94e4658247817701 + ; word 0x21a29367e3cefb30cb775905a6699487 + ]`;; + +let XTSDEC_1BLOCK_HELPER_CONV = + REWR_CONV aes256_xts_decrypt_1block THENC + REWRITE_CONV [xts_init_tweak] THENC + SUBLET_CONV (AESENC_HELPER_CONV KEY2) THENC + let_CONV THENC + REWRITE_CONV [aes256_xts_decrypt_round] THENC + SUBLET_CONV (DEPTH_CONV (WORD_RED_CONV ORELSEC NUM_RED_CONV)) THENC + PRINT_TERM_CONV THENC + let_CONV THENC + SUBLET_CONV (AESDEC_HELPER_CONV KEY1) THENC + let_CONV THENC + DEPTH_CONV (WORD_RED_CONV ORELSEC NUM_RED_CONV) + ;; + +(*162 seconds +time prove (`aes256_xts_decrypt_1block + (word 0x88c87a8644e587dc7e3057edf2a80cc3) + (word 0x0000000000000000000000123456789a) + KEY1 KEY2 = word 0x0f0e0d0c0b0a09080706050403020100`, + CONV_TAC(LAND_CONV XTSDEC_1BLOCK_HELPER_CONV) THEN REFL_TAC);; +*) From aadaeae27d930c1f4a430baba12aad4a77b66f70 Mon Sep 17 00:00:00 2001 From: Yan Peng Date: Tue, 1 Jul 2025 22:50:07 +0000 Subject: [PATCH 021/132] Add proof for one block xts --- arm/proofs/aes_xts_decrypt.ml | 144 ++++++++++++++++++++++++---------- 1 file changed, 103 insertions(+), 41 deletions(-) diff --git a/arm/proofs/aes_xts_decrypt.ml b/arm/proofs/aes_xts_decrypt.ml index 38d1c650a..ec20d8139 100644 --- a/arm/proofs/aes_xts_decrypt.ml +++ b/arm/proofs/aes_xts_decrypt.ml @@ -4,11 +4,13 @@ *) use_file_raise_failure := true;; +arm_print_log := true;; needs "arm/proofs/base.ml";; +loadt "arm/proofs/aes_xts_decrypt_spec.ml";; (* print_literal_from_elf "arm/aes-xts/aes_xts_decrypt_armv8.o";; *) -let aes_xts_decrypt_mc = define_assert_from_elf "aes_hw_xts_decrypt_mc" "arm/aes-xts/aes_xts_decrypt_armv8.o" +let aes_xts_decrypt_mc = define_assert_from_elf "aes_xts_decrypt_mc" "arm/aes-xts/aes_xts_decrypt_armv8.o" [ 0xd10103ff; (* arm_SUB SP SP (rvalue (word 64)) *) 0x6d0027e8; (* arm_STP D8 D9 SP (Immediate_Offset (iword (&0))) *) @@ -725,53 +727,113 @@ let aes_xts_decrypt_mc = define_assert_from_elf "aes_hw_xts_decrypt_mc" "arm/aes let AES_XTS_DECRYPT_EXEC = ARM_MK_EXEC_RULE aes_xts_decrypt_mc;; +(** Definitions **) + +let set_key_schedule = new_definition + `set_key_schedule (s:armstate) (key_ptr:int64) (k0:int128) + (k1:int128) (k2:int128) (k3:int128) (k4:int128) (k5:int128) + (k6:int128) (k7:int128) (k8:int128) (k9:int128) (ka:int128) + (kb:int128) (kc:int128) (kd:int128) (ke:int128) : bool = + (read(memory :> bytes128 key_ptr) s = k0 /\ + read(memory :> bytes128 (word_add key_ptr (word 16))) s = k1 /\ + read(memory :> bytes128 (word_add key_ptr (word 32))) s = k2 /\ + read(memory :> bytes128 (word_add key_ptr (word 48))) s = k3 /\ + read(memory :> bytes128 (word_add key_ptr (word 64))) s = k4 /\ + read(memory :> bytes128 (word_add key_ptr (word 80))) s = k5 /\ + read(memory :> bytes128 (word_add key_ptr (word 96))) s = k6 /\ + read(memory :> bytes128 (word_add key_ptr (word 112))) s = k7 /\ + read(memory :> bytes128 (word_add key_ptr (word 128))) s = k8 /\ + read(memory :> bytes128 (word_add key_ptr (word 144))) s = k9 /\ + read(memory :> bytes128 (word_add key_ptr (word 160))) s = ka /\ + read(memory :> bytes128 (word_add key_ptr (word 176))) s = kb /\ + read(memory :> bytes128 (word_add key_ptr (word 192))) s = kc /\ + read(memory :> bytes128 (word_add key_ptr (word 208))) s = kd /\ + read(memory :> bytes128 (word_add key_ptr (word 224))) s = ke /\ + read(memory :> bytes32 (word_add key_ptr (word 240))) s = word 14)`;; + +(** Tactics **) + +let AESENC_TAC = + REWRITE_TAC [aes256_encrypt] THEN + REWRITE_TAC EL_15_128_CLAUSES THEN + REWRITE_TAC [aes256_encrypt_round] THEN + CONV_TAC(TOP_DEPTH_CONV let_CONV) THEN + REWRITE_TAC [aese;aesmc] THEN + GEN_REWRITE_TAC LAND_CONV [WORD_XOR_SYM] THEN + REFL_TAC;; + +let AESDEC_TAC = + REWRITE_TAC [aes256_decrypt] THEN + REWRITE_TAC EL_15_128_CLAUSES THEN + CONV_TAC(TOP_DEPTH_CONV let_CONV) THEN + REWRITE_TAC [aes256_decrypt_round] THEN + CONV_TAC(TOP_DEPTH_CONV let_CONV) THEN + REWRITE_TAC [aesd;aesimc] THEN + (* NOTE: BITBLAST_TAC couldn't handle this goal *) + GEN_REWRITE_TAC LAND_CONV [WORD_XOR_SYM] THEN + AP_THM_TAC THEN AP_TERM_TAC THEN + GEN_REWRITE_TAC LAND_CONV [WORD_XOR_SYM] THEN + AP_THM_TAC THEN AP_TERM_TAC THEN AP_TERM_TAC THEN AP_TERM_TAC THEN + REPLICATE_TAC 13 (AP_THM_TAC THEN (REPLICATE_TAC 4 AP_TERM_TAC)) THEN + AP_THM_TAC THEN AP_TERM_TAC THEN + GEN_REWRITE_TAC LAND_CONV [WORD_XOR_SYM] THEN REFL_TAC;; + +(** Proof **) + let AES_XTS_DECRYPT_CORRECT = prove( - `!ct_ptr pt_ptr len key0_ptr key1_ptr iv_ptr ib iv + `!ct_ptr pt_ptr key0_ptr key1_ptr iv_ptr ib iv k00 k01 k02 k03 k04 k05 k06 k07 k08 k09 k0a k0b k0c k0d k0e k10 k11 k12 k13 k14 k15 k16 k17 k18 k19 k1a k1b k1c k1d k1e pc. - nonoverlapping (word pc, LENGTH aes_xts_decrypt_mc) (pt_ptr, val len) + nonoverlapping (word pc, LENGTH aes_xts_decrypt_mc) (pt_ptr, 16) ==> ensures arm (\s. aligned_bytes_loaded s (word pc) aes_xts_decrypt_mc /\ - read PC s = word pc /\ - C_ARGUMENTS [ct_ptr; pt_ptr; len; key0_ptr; key1_ptr; iv_ptr] s /\ + read PC s = word (pc + 20) /\ + C_ARGUMENTS [ct_ptr; pt_ptr; word 16; key0_ptr; key1_ptr; iv_ptr] s /\ read(memory :> bytes128 ct_ptr) s = ib /\ read(memory :> bytes128 iv_ptr) s = iv /\ - read(memory :> bytes128 key0_ptr) s = k00 /\ - read(memory :> bytes128 (word_add key0_ptr (word 16))) s = k01 /\ - read(memory :> bytes128 (word_add key0_ptr (word 32))) s = k02 /\ - read(memory :> bytes128 (word_add key0_ptr (word 48))) s = k03 /\ - read(memory :> bytes128 (word_add key0_ptr (word 64))) s = k04 /\ - read(memory :> bytes128 (word_add key0_ptr (word 80))) s = k05 /\ - read(memory :> bytes128 (word_add key0_ptr (word 96))) s = k06 /\ - read(memory :> bytes128 (word_add key0_ptr (word 112))) s = k07 /\ - read(memory :> bytes128 (word_add key0_ptr (word 128))) s = k08 /\ - read(memory :> bytes128 (word_add key0_ptr (word 144))) s = k09 /\ - read(memory :> bytes128 (word_add key0_ptr (word 160))) s = k0a /\ - read(memory :> bytes128 (word_add key0_ptr (word 176))) s = k0b /\ - read(memory :> bytes128 (word_add key0_ptr (word 192))) s = k0c /\ - read(memory :> bytes128 (word_add key0_ptr (word 208))) s = k0d /\ - read(memory :> bytes128 (word_add key0_ptr (word 224))) s = k0e /\ - read(memory :> bytes32 (word_add key0_ptr (word 240))) s = word 14 /\ - read(memory :> bytes128 key1_ptr) s = k10 /\ - read(memory :> bytes128 (word_add key1_ptr (word 16))) s = k11 /\ - read(memory :> bytes128 (word_add key1_ptr (word 32))) s = k12 /\ - read(memory :> bytes128 (word_add key1_ptr (word 48))) s = k13 /\ - read(memory :> bytes128 (word_add key1_ptr (word 64))) s = k14 /\ - read(memory :> bytes128 (word_add key1_ptr (word 80))) s = k15 /\ - read(memory :> bytes128 (word_add key1_ptr (word 96))) s = k16 /\ - read(memory :> bytes128 (word_add key1_ptr (word 112))) s = k17 /\ - read(memory :> bytes128 (word_add key1_ptr (word 128))) s = k18 /\ - read(memory :> bytes128 (word_add key1_ptr (word 144))) s = k19 /\ - read(memory :> bytes128 (word_add key1_ptr (word 160))) s = k1a /\ - read(memory :> bytes128 (word_add key1_ptr (word 176))) s = k1b /\ - read(memory :> bytes128 (word_add key1_ptr (word 192))) s = k1c /\ - read(memory :> bytes128 (word_add key1_ptr (word 208))) s = k1d /\ - read(memory :> bytes128 (word_add key1_ptr (word 224))) s = k1e /\ - read(memory :> bytes32 (word_add key1_ptr (word 240))) s = word 14 + set_key_schedule s key0_ptr k00 k01 k02 k03 k04 k05 k06 k07 k08 k09 k0a k0b k0c k0d k0e /\ + set_key_schedule s key1_ptr k10 k11 k12 k13 k14 k15 k16 k17 k18 k19 k1a k1b k1c k1d k1e) + (\s. read PC s = word (pc + 0xb04) /\ + read(memory :> bytes128 pt_ptr) s = + aes256_xts_decrypt_1block ib iv + [k00; k01; k02; k03; k04; k05; k06; k07; k08; k09; k0a; k0b; k0c; k0d; k0e] + [k10; k11; k12; k13; k14; k15; k16; k17; k18; k19; k1a; k1b; k1c; k1d; k1e] ) - (\s. read PC s = word (pc + LENGTH aes_xts_decrypt_mc)) - (MAYCHANGE SOME_FLAGS,, MAYCHANGE [memory :> bytes128 pt_ptr]) + (MAYCHANGE [PC] ,, MAYCHANGE [events] ,, + MAYCHANGE [X21;X2;X6;X4;X9;X10;X19;X22;X11;X7;X0;X1] ,, + MAYCHANGE [Q6;Q1;Q0;Q8;Q16;Q17;Q12;Q13;Q14;Q15;Q4;Q5;Q18;Q19;Q20;Q21;Q22;Q23;Q7;Q29;Q24] ,, + MAYCHANGE SOME_FLAGS,, MAYCHANGE [memory :> bytes128 pt_ptr]) `, - CHEAT_TAC -);; \ No newline at end of file + REWRITE_TAC [(REWRITE_CONV [aes_xts_decrypt_mc] THENC LENGTH_CONV) `LENGTH aes_xts_decrypt_mc`] THEN + REWRITE_TAC[set_key_schedule; C_ARGUMENTS; SOME_FLAGS; NONOVERLAPPING_CLAUSES] THEN + REPEAT STRIP_TAC THEN + + (* Start symbolic simulation*) + ENSURES_INIT_TAC "s0" THEN + (* Simulate until the first tweak and verify the first tweak equiv the spec *) + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (1--64) THEN + FIRST_X_ASSUM(MP_TAC o SPEC + `(aes256_encrypt iv [k10; k11; k12; k13; k14; k15; k16; k17; k18; k19; k1a; k1b; k1c; k1d; k1e]):int128` + o MATCH_MP (MESON[] `read Q6 s = a ==> !a'. a = a' ==> read Q6 s = a'`)) THEN + ANTS_TAC THENL [ASM_REWRITE_TAC[] THEN AESENC_TAC; DISCH_TAC] THEN + + (* Simulating until finish decrypting one block *) + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (65--118) THEN + FIRST_X_ASSUM(MP_TAC o + SPEC `(aes256_xts_decrypt_1block ib iv + [k00; k01; k02; k03; k04; k05; k06; k07; k08; k09; k0a; k0b; k0c; k0d; k0e] + [k10; k11; k12; k13; k14; k15; k16; k17; k18; k19; k1a; k1b; k1c; k1d; k1e]):int128` + o MATCH_MP (MESON[] `read Q24 s = a ==> !a'. a = a' ==> read Q24 s = a'`)) THEN + ANTS_TAC THENL [ + REWRITE_TAC [aes256_xts_decrypt_1block] THEN + REWRITE_TAC [xts_init_tweak] THEN + CONV_TAC(TOP_DEPTH_CONV let_CONV) THEN + REWRITE_TAC [aes256_xts_decrypt_round] THEN + CONV_TAC(TOP_DEPTH_CONV let_CONV) THEN + AESDEC_TAC; DISCH_TAC] THEN + + (* Simulate to the end *) + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (119--130) THEN + ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC [] +);; From 0379411bd4daf0f8bd2a399fe666fc694a574c6b Mon Sep 17 00:00:00 2001 From: Yan Peng Date: Tue, 22 Jul 2025 22:21:59 +0000 Subject: [PATCH 022/132] Update one block proof to use more clean version --- arm/aes-xts/aes_xts_decrypt_armv8.S | 186 ++++---- arm/proofs/aes_xts_decrypt.ml | 689 ++++++++++++++-------------- 2 files changed, 424 insertions(+), 451 deletions(-) diff --git a/arm/aes-xts/aes_xts_decrypt_armv8.S b/arm/aes-xts/aes_xts_decrypt_armv8.S index 4450dd6a7..1ea2e1e63 100644 --- a/arm/aes-xts/aes_xts_decrypt_armv8.S +++ b/arm/aes-xts/aes_xts_decrypt_armv8.S @@ -131,63 +131,50 @@ Lxts_dec: b.lt Lxts_dec_done // There is one block and a tail, go directy to cipher-stealing Lxts_dec_begin: - ld1 {v0.16b}, [x0], #16 // the first block cmp x2, #16 - orr v29.16b,v0.16b,v0.16b b.lo Lxts_dec_tail1x // when input = 1 with another block and a tail - ld1 {v1.16b},[x0],#16 // the second block subs x2,x2,#32 // bias - orr v28.16b,v0.16b,v0.16b - orr v29.16b,v1.16b,v1.16b b.lo Lxts_dec_tail2x // when input size = 2 with another block and a tail // The iv for third block tweak d9,v9.d[1] - orr v27.16b,v0.16b,v0.16b - orr v28.16b,v1.16b,v1.16b - ld1 {v24.16b},[x0],#16 // the third block - orr v29.16b,v24.16b,v24.16b cmp x2,#16 b.lo Lxts_dec_tail3x // when input size = 3 with another block and a tail // The iv for fourth block tweak d10,v10.d[1] - orr v3.16b,v0.16b,v0.16b - orr v27.16b,v1.16b,v1.16b - orr v28.16b,v24.16b,v24.16b - ld1 {v25.16b},[x0],#16 // the fourth block - orr v29.16b,v25.16b,v25.16b subs x2,x2,#32 b.lo Lxts_dec_tail4x // when input size = 4 with another block and a tail // The iv for fifth block tweak d11,v11.d[1] - ld1 {v26.16b},[x0],#16 // the fifth block - eor v0.16b,v0.16b,v6.16b // before decryption, xor with iv +.align 4 +Loop5x_xts_dec: + ldp q0, q1, [x0], #0x50 + ldp q24, q25, [x0, #-0x30] + ldr q26, [x0, #-0x10] + + eor v0.16b,v0.16b,v6.16b eor v1.16b,v1.16b,v8.16b eor v24.16b,v24.16b,v9.16b eor v25.16b,v25.16b,v10.16b eor v26.16b,v26.16b,v11.16b -.align 4 -Loop5x_xts_dec: aesdr v0.16b, v16.16b aesdr v1.16b, v16.16b aesdr v24.16b, v16.16b aesdr v25.16b, v16.16b aesdr v26.16b, v16.16b - subs x12,x2,#0x50 // because Lxts_dec_tail4x aesdr v0.16b, v17.16b aesdr v1.16b, v17.16b aesdr v24.16b, v17.16b aesdr v25.16b, v17.16b aesdr v26.16b, v17.16b - csel x6,xzr,x12,gt // borrow x6, w6, "gt" is not typo aesdr v0.16b, v12.16b aesdr v1.16b, v12.16b @@ -230,9 +217,6 @@ Loop5x_xts_dec: aesdr v24.16b, v18.16b aesdr v25.16b, v18.16b aesdr v26.16b, v18.16b - add x0,x0,x6 // x0 is adjusted in such way that - // at exit from the loop v1.16b-v26.16b - // are loaded with last "words" aesdr v0.16b, v19.16b aesdr v1.16b, v19.16b @@ -270,7 +254,6 @@ Loop5x_xts_dec: tweak d6,v6.d[1] eor v1.16b,v1.16b,v7.16b eor v1.16b,v1.16b,v8.16b - ldp q2, q3, [x0], #0x50 // The iv for second block tweak d8,v8.d[1] @@ -281,13 +264,11 @@ Loop5x_xts_dec: tweak d9,v9.d[1] eor v25.16b,v25.16b,v7.16b eor v25.16b,v25.16b,v10.16b - ldr q27, [x0, #-0x30] // The iv for fourth block tweak d10,v10.d[1] eor v26.16b,v26.16b,v7.16b eor v26.16b,v26.16b,v11.16b - ldp q28, q29,[x0, #-0x20] // The iv for fifth block tweak d11,v11.d[1] @@ -295,13 +276,8 @@ Loop5x_xts_dec: stp q0, q1, [x1], #0x50 stp q24, q25, [x1, #-0x30] str q26, [x1, #-0x10] - eor v0.16b,v2.16b,v6.16b - eor v1.16b,v3.16b,v8.16b - eor v24.16b,v27.16b,v9.16b - eor v25.16b,v28.16b,v10.16b - eor v26.16b,v29.16b,v11.16b - subs x2,x2,#0x50 + subs x2,x2,#0x50 // @slothy:core b.hs Loop5x_xts_dec Loop5x_dec_after: @@ -321,107 +297,113 @@ Loop5x_dec_after: .align 4 Lxts_dec_tail4x: - eor v1.16b,v6.16b,v3.16b - eor v24.16b,v27.16b,v8.16b - eor v25.16b,v28.16b,v9.16b - eor v26.16b,v29.16b,v10.16b + ld1 {v0.16b,v1.16b}, [x0],#32 // the first and second blocks + ld1 {v24.16b,v25.16b}, [x0],#32 // the third and fourth blocks + + eor v0.16b,v0.16b,v6.16b + eor v1.16b,v1.16b,v8.16b + eor v24.16b,v24.16b,v9.16b + eor v25.16b,v25.16b,v10.16b + aesdr v0.16b, v16.16b aesdr v1.16b, v16.16b aesdr v24.16b, v16.16b aesdr v25.16b, v16.16b - aesdr v26.16b, v16.16b + aesdr v0.16b, v17.16b aesdr v1.16b, v17.16b aesdr v24.16b, v17.16b aesdr v25.16b, v17.16b - aesdr v26.16b, v17.16b + aesdr v0.16b, v12.16b aesdr v1.16b, v12.16b aesdr v24.16b, v12.16b aesdr v25.16b, v12.16b - aesdr v26.16b, v12.16b + aesdr v0.16b, v13.16b aesdr v1.16b, v13.16b aesdr v24.16b, v13.16b aesdr v25.16b, v13.16b - aesdr v26.16b, v13.16b + aesdr v0.16b, v14.16b aesdr v1.16b, v14.16b aesdr v24.16b, v14.16b aesdr v25.16b, v14.16b - aesdr v26.16b, v14.16b + aesdr v0.16b, v15.16b aesdr v1.16b, v15.16b aesdr v24.16b, v15.16b aesdr v25.16b, v15.16b - aesdr v26.16b, v15.16b + aesdr v0.16b, v4.16b aesdr v1.16b, v4.16b aesdr v24.16b, v4.16b aesdr v25.16b, v4.16b - aesdr v26.16b, v4.16b + aesdr v0.16b, v5.16b aesdr v1.16b, v5.16b aesdr v24.16b, v5.16b aesdr v25.16b, v5.16b - aesdr v26.16b, v5.16b + aesdr v0.16b, v18.16b aesdr v1.16b, v18.16b aesdr v24.16b, v18.16b aesdr v25.16b, v18.16b - aesdr v26.16b, v18.16b + aesdr v0.16b, v19.16b aesdr v1.16b, v19.16b aesdr v24.16b, v19.16b aesdr v25.16b, v19.16b - aesdr v26.16b, v19.16b + aesdr v0.16b, v20.16b aesdr v1.16b, v20.16b aesdr v24.16b, v20.16b aesdr v25.16b, v20.16b - aesdr v26.16b, v20.16b + aesdr v0.16b, v21.16b aesdr v1.16b, v21.16b aesdr v24.16b, v21.16b aesdr v25.16b, v21.16b - aesdr v26.16b, v21.16b + aesdr v0.16b, v22.16b aesdr v1.16b, v22.16b aesdr v24.16b, v22.16b aesdr v25.16b, v22.16b - aesdr v26.16b, v22.16b + aesd v0.16b,v23.16b aesd v1.16b,v23.16b aesd v24.16b,v23.16b aesd v25.16b,v23.16b - aesd v26.16b,v23.16b + + eor v0.16b,v0.16b,v7.16b + eor v0.16b,v0.16b,v6.16b eor v1.16b,v1.16b,v7.16b - eor v1.16b,v1.16b,v6.16b + eor v1.16b,v1.16b,v8.16b eor v24.16b,v24.16b,v7.16b - eor v24.16b,v24.16b,v8.16b + eor v24.16b,v24.16b,v9.16b eor v25.16b,v25.16b,v7.16b - eor v25.16b,v25.16b,v9.16b - - eor v26.16b,v26.16b,v7.16b - eor v26.16b,v26.16b,v10.16b + eor v25.16b,v25.16b,v10.16b // The iv for tail fmov x9,d10 fmov x10,v10.d[1] tweak d6,v6.d[1] - st1 {v1.16b},[x1],#16 + st1 {v0.16b,v1.16b},[x1],#32 st1 {v24.16b,v25.16b},[x1],#32 - st1 {v26.16b},[x1],#16 + b Lxts_dec_done .align 4 Lxts_dec_tail3x: - eor v0.16b,v6.16b,v27.16b // 3 blocks left - eor v1.16b,v8.16b,v28.16b - eor v24.16b,v29.16b,v9.16b + ld1 {v0.16b,v1.16b}, [x0],#32 + ld1 {v24.16b}, [x0],#16 + + eor v0.16b,v0.16b,v6.16b + eor v1.16b,v1.16b,v8.16b + eor v24.16b,v24.16b,v9.16b // First round with v16 aesdr v0.16b, v16.16b @@ -506,66 +488,68 @@ Lxts_dec_tail3x: b Lxts_dec_done // done processing three blocks Lxts_dec_tail2x: - eor v1.16b,v28.16b,v6.16b - eor v24.16b,v29.16b,v8.16b + ld1 {v0.16b,v1.16b},[x0],#32 // the first block + + eor v0.16b,v0.16b,v6.16b + eor v1.16b,v1.16b,v8.16b // First round with v16 + aesdr v0.16b, v16.16b aesdr v1.16b, v16.16b - aesdr v24.16b, v16.16b // Second round with v17 + aesdr v0.16b, v17.16b aesdr v1.16b, v17.16b - aesdr v24.16b, v17.16b // Third round with v12 + aesdr v0.16b, v12.16b aesdr v1.16b, v12.16b - aesdr v24.16b, v12.16b // Fourth round with v13 + aesdr v0.16b, v13.16b aesdr v1.16b, v13.16b - aesdr v24.16b, v13.16b // Fifth round with v14 + aesdr v0.16b, v14.16b aesdr v1.16b, v14.16b - aesdr v24.16b, v14.16b // Sixth round with v15 + aesdr v0.16b, v15.16b aesdr v1.16b, v15.16b - aesdr v24.16b, v15.16b // Seventh round with v4 + aesdr v0.16b, v4.16b aesdr v1.16b, v4.16b - aesdr v24.16b, v4.16b // Eighth round with v5 + aesdr v0.16b, v5.16b aesdr v1.16b, v5.16b - aesdr v24.16b, v5.16b // 9th round with v18 + aesdr v0.16b, v18.16b aesdr v1.16b, v18.16b - aesdr v24.16b, v18.16b // 10th round with v19 + aesdr v0.16b, v19.16b aesdr v1.16b, v19.16b - aesdr v24.16b, v19.16b + aesdr v0.16b, v20.16b aesdr v1.16b, v20.16b - aesdr v24.16b, v20.16b + aesdr v0.16b, v21.16b aesdr v1.16b, v21.16b - aesdr v24.16b, v21.16b + aesdr v0.16b, v22.16b aesdr v1.16b, v22.16b - aesdr v24.16b, v22.16b + aesd v0.16b,v23.16b aesd v1.16b,v23.16b - aesd v24.16b,v23.16b + eor v0.16b,v0.16b,v7.16b + eor v0.16b,v0.16b,v6.16b eor v1.16b,v1.16b,v7.16b - eor v1.16b,v1.16b,v6.16b - st1 {v1.16b},[x1],#16 - eor v24.16b,v24.16b,v7.16b - eor v24.16b,v24.16b,v8.16b - st1 {v24.16b},[x1],#16 + eor v1.16b,v1.16b,v8.16b + + st1 {v0.16b,v1.16b},[x1],#32 // The iv for tail fmov x9,d8 @@ -574,46 +558,48 @@ Lxts_dec_tail2x: b Lxts_dec_done Lxts_dec_tail1x: - eor v24.16b,v29.16b,v6.16b + ld1 {v0.16b}, [x0],#16 // the first block + + eor v0.16b,v0.16b,v6.16b // First round with v16 - aesdr v24.16b, v16.16b + aesdr v0.16b, v16.16b // Second round with v17 - aesdr v24.16b, v17.16b + aesdr v0.16b, v17.16b // Third round with v12 - aesdr v24.16b, v12.16b + aesdr v0.16b, v12.16b // Fourth round with v13 - aesdr v24.16b, v13.16b + aesdr v0.16b, v13.16b // Fifth round with v14 - aesdr v24.16b, v14.16b + aesdr v0.16b, v14.16b // Sixth round with v15 - aesdr v24.16b, v15.16b + aesdr v0.16b, v15.16b // Seventh round with v4 - aesdr v24.16b, v4.16b + aesdr v0.16b, v4.16b // Eighth round with v5 - aesdr v24.16b, v5.16b + aesdr v0.16b, v5.16b // 9th round with v18 - aesdr v24.16b, v18.16b + aesdr v0.16b, v18.16b // 10th round with v19 - aesdr v24.16b, v19.16b + aesdr v0.16b, v19.16b - aesdr v24.16b, v20.16b - aesdr v24.16b, v21.16b - aesdr v24.16b, v22.16b - aesd v24.16b,v23.16b + aesdr v0.16b, v20.16b + aesdr v0.16b, v21.16b + aesdr v0.16b, v22.16b + aesd v0.16b,v23.16b - eor v24.16b,v24.16b,v7.16b - eor v24.16b,v24.16b,v6.16b - st1 {v24.16b},[x1],#16 + eor v0.16b,v0.16b,v7.16b + eor v0.16b,v0.16b,v6.16b + st1 {v0.16b},[x1],#16 // tweak for tail fmov x9,d6 fmov x10,v6.d[1] diff --git a/arm/proofs/aes_xts_decrypt.ml b/arm/proofs/aes_xts_decrypt.ml index ec20d8139..4c3da89bb 100644 --- a/arm/proofs/aes_xts_decrypt.ml +++ b/arm/proofs/aes_xts_decrypt.ml @@ -12,106 +12,94 @@ loadt "arm/proofs/aes_xts_decrypt_spec.ml";; (* print_literal_from_elf "arm/aes-xts/aes_xts_decrypt_armv8.o";; *) let aes_xts_decrypt_mc = define_assert_from_elf "aes_xts_decrypt_mc" "arm/aes-xts/aes_xts_decrypt_armv8.o" [ - 0xd10103ff; (* arm_SUB SP SP (rvalue (word 64)) *) - 0x6d0027e8; (* arm_STP D8 D9 SP (Immediate_Offset (iword (&0))) *) - 0x6d012fea; (* arm_STP D10 D11 SP (Immediate_Offset (iword (&16))) *) - 0xa90253f3; (* arm_STP X19 X20 SP (Immediate_Offset (iword (&32))) *) - 0xa9035bf5; (* arm_STP X21 X22 SP (Immediate_Offset (iword (&48))) *) - 0xf100405f; (* arm_CMP X2 (rvalue (word 16)) *) - 0x5400576b; (* arm_BLT (word 2796) *) + 0xd10103ff; (* arm_SUB SP SP (rvalue (word 0x40)) *) + 0x6d0027e8; (* arm_STP D8 D9 SP (Immediate_Offset (iword (&0x0))) *) + 0x6d012fea; (* arm_STP D10 D11 SP (Immediate_Offset (iword (&0x10))) *) + 0xa90253f3; (* arm_STP X19 X20 SP (Immediate_Offset (iword (&0x20))) *) + 0xa9035bf5; (* arm_STP X21 X22 SP (Immediate_Offset (iword (&0x30))) *) + 0xf100405f; (* arm_CMP X2 (rvalue (word 0x10)) *) + 0x540055cb; (* arm_BLT (word 0xab8) *) 0xd503201f; (* arm_NOP *) - 0x92400c55; (* arm_AND X21 X2 (rvalue (word 15)) *) - 0x927cec42; (* arm_AND X2 X2 (rvalue (word 18446744073709551600)) *) - 0xf1004042; (* arm_SUBS X2 X2 (rvalue (word 16)) *) - 0xb940f086; (* arm_LDR W6 X4 (Immediate_Offset (word 240)) *) - 0x4cdf7880; (* arm_LDR Q0 X4 (Postimmediate_Offset (word 16)) *) + 0x92400c55; (* arm_AND X21 X2 (rvalue (word 0xf)) *) + 0x927cec42; (* arm_AND X2 X2 (rvalue (word 0xfffffffffffffff0)) *) + 0xf1004042; (* arm_SUBS X2 X2 (rvalue (word 0x10)) *) + 0xb940f086; (* arm_LDR W6 X4 (Immediate_Offset (word 0xf0)) *) + 0x4cdf7880; (* arm_LDR Q0 X4 (Postimmediate_Offset (word 0x10)) *) 0x4c4070a6; (* arm_LDR Q6 X5 No_Offset *) - 0x510008c6; (* arm_SUB W6 W6 (rvalue (word 2)) *) - 0x4cdf7881; (* arm_LDR Q1 X4 (Postimmediate_Offset (word 16)) *) + 0x510008c6; (* arm_SUB W6 W6 (rvalue (word 0x2)) *) + 0x4cdf7881; (* arm_LDR Q1 X4 (Postimmediate_Offset (word 0x10)) *) 0x4e284806; (* arm_AESE Q6 Q0 *) 0x4e2868c6; (* arm_AESMC Q6 Q6 *) - 0x4cdf7880; (* arm_LDR Q0 X4 (Postimmediate_Offset (word 16)) *) - 0x710008c6; (* arm_SUBS W6 W6 (rvalue (word 2)) *) + 0x4cdf7880; (* arm_LDR Q0 X4 (Postimmediate_Offset (word 0x10)) *) + 0x710008c6; (* arm_SUBS W6 W6 (rvalue (word 0x2)) *) 0x4e284826; (* arm_AESE Q6 Q1 *) 0x4e2868c6; (* arm_AESMC Q6 Q6 *) - 0x4cdf7881; (* arm_LDR Q1 X4 (Postimmediate_Offset (word 16)) *) - 0x54ffff2c; (* arm_BGT (word 2097124) *) + 0x4cdf7881; (* arm_LDR Q1 X4 (Postimmediate_Offset (word 0x10)) *) + 0x54ffff2c; (* arm_BGT (word 0x1fffe4) *) 0x4e284806; (* arm_AESE Q6 Q0 *) 0x4e2868c6; (* arm_AESMC Q6 Q6 *) 0x4c407880; (* arm_LDR Q0 X4 No_Offset *) 0x4e284826; (* arm_AESE Q6 Q1 *) - 0x6e201cc6; (* arm_EOR_VEC Q6 Q6 Q0 128 *) - 0x9e6600c9; (* arm_FMOV_FtoI X9 Q6 0 64 *) - 0x9eae00ca; (* arm_FMOV_FtoI X10 Q6 1 64 *) - 0x528010f3; (* arm_MOV W19 (rvalue (word 135)) *) - 0x93ca8156; (* arm_ROR X22 X10 32 *) - 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) - 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 31) *) - 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 1) *) - 0x9e670128; (* arm_FMOV_ItoF Q8 X9 0 *) - 0x9eaf0148; (* arm_FMOV_ItoF Q8 X10 1 *) + 0x6e201cc6; (* arm_EOR_VEC Q6 Q6 Q0 0x80 *) + 0x9e6600c9; (* arm_FMOV_FtoI X9 Q6 0x0 0x40 *) + 0x9eae00ca; (* arm_FMOV_FtoI X10 Q6 0x1 0x40 *) + 0x528010f3; (* arm_MOV W19 (rvalue (word 0x87)) *) + 0x93ca8156; (* arm_ROR X22 X10 0x20 *) + 0x93c9fd4a; (* arm_EXTR X10 X10 X9 0x3f *) + 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 0x1f) *) + 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 0x1) *) + 0x9e670128; (* arm_FMOV_ItoF Q8 X9 0x0 *) + 0x9eaf0148; (* arm_FMOV_ItoF Q8 X10 0x1 *) 0xaa0303e7; (* arm_MOV X7 X3 *) - 0x4cdfa8f0; (* arm_LDP Q16 Q17 X7 (Postimmediate_Offset (word 32)) *) - 0x4cdfa8ec; (* arm_LDP Q12 Q13 X7 (Postimmediate_Offset (word 32)) *) - 0x4cdfa8ee; (* arm_LDP Q14 Q15 X7 (Postimmediate_Offset (word 32)) *) - 0x4cdfa8e4; (* arm_LDP Q4 Q5 X7 (Postimmediate_Offset (word 32)) *) - 0x4cdfa8f2; (* arm_LDP Q18 Q19 X7 (Postimmediate_Offset (word 32)) *) - 0x4cdfa8f4; (* arm_LDP Q20 Q21 X7 (Postimmediate_Offset (word 32)) *) - 0x4cdfa8f6; (* arm_LDP Q22 Q23 X7 (Postimmediate_Offset (word 32)) *) + 0x4cdfa8f0; (* arm_LDP Q16 Q17 X7 (Postimmediate_Offset (word 0x20)) *) + 0x4cdfa8ec; (* arm_LDP Q12 Q13 X7 (Postimmediate_Offset (word 0x20)) *) + 0x4cdfa8ee; (* arm_LDP Q14 Q15 X7 (Postimmediate_Offset (word 0x20)) *) + 0x4cdfa8e4; (* arm_LDP Q4 Q5 X7 (Postimmediate_Offset (word 0x20)) *) + 0x4cdfa8f2; (* arm_LDP Q18 Q19 X7 (Postimmediate_Offset (word 0x20)) *) + 0x4cdfa8f4; (* arm_LDP Q20 Q21 X7 (Postimmediate_Offset (word 0x20)) *) + 0x4cdfa8f6; (* arm_LDP Q22 Q23 X7 (Postimmediate_Offset (word 0x20)) *) 0x4c4078e7; (* arm_LDR Q7 X7 No_Offset *) - 0xf2400ebf; (* arm_TST X21 (rvalue (word 15)) *) - 0x54000080; (* arm_BEQ (word 16) *) - 0xf1004042; (* arm_SUBS X2 X2 (rvalue (word 16)) *) - 0xf100005f; (* arm_CMP X2 (rvalue (word 0)) *) - 0x54004a2b; (* arm_BLT (word 2372) *) - 0x4cdf7000; (* arm_LDR Q0 X0 (Postimmediate_Offset (word 16)) *) - 0xf100405f; (* arm_CMP X2 (rvalue (word 16)) *) - 0x4ea01c1d; (* arm_MOV_VEC Q29 Q0 128 *) - 0x540044a3; (* arm_BCC (word 2196) *) - 0x4cdf7001; (* arm_LDR Q1 X0 (Postimmediate_Offset (word 16)) *) - 0xf1008042; (* arm_SUBS X2 X2 (rvalue (word 32)) *) - 0x4ea01c1c; (* arm_MOV_VEC Q28 Q0 128 *) - 0x4ea11c3d; (* arm_MOV_VEC Q29 Q1 128 *) - 0x54003b23; (* arm_BCC (word 1892) *) - 0x93ca8156; (* arm_ROR X22 X10 32 *) - 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) - 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 31) *) - 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 1) *) - 0x9e670129; (* arm_FMOV_ItoF Q9 X9 0 *) - 0x9eaf0149; (* arm_FMOV_ItoF Q9 X10 1 *) - 0x4ea01c1b; (* arm_MOV_VEC Q27 Q0 128 *) - 0x4ea11c3c; (* arm_MOV_VEC Q28 Q1 128 *) - 0x4cdf7018; (* arm_LDR Q24 X0 (Postimmediate_Offset (word 16)) *) - 0x4eb81f1d; (* arm_MOV_VEC Q29 Q24 128 *) - 0xf100405f; (* arm_CMP X2 (rvalue (word 16)) *) - 0x54002d03; (* arm_BCC (word 1440) *) - 0x93ca8156; (* arm_ROR X22 X10 32 *) - 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) - 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 31) *) - 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 1) *) - 0x9e67012a; (* arm_FMOV_ItoF Q10 X9 0 *) - 0x9eaf014a; (* arm_FMOV_ItoF Q10 X10 1 *) - 0x4ea01c03; (* arm_MOV_VEC Q3 Q0 128 *) - 0x4ea11c3b; (* arm_MOV_VEC Q27 Q1 128 *) - 0x4eb81f1c; (* arm_MOV_VEC Q28 Q24 128 *) - 0x4cdf7019; (* arm_LDR Q25 X0 (Postimmediate_Offset (word 16)) *) - 0x4eb91f3d; (* arm_MOV_VEC Q29 Q25 128 *) - 0xf1008042; (* arm_SUBS X2 X2 (rvalue (word 32)) *) - 0x54001ae3; (* arm_BCC (word 860) *) - 0x93ca8156; (* arm_ROR X22 X10 32 *) - 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) - 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 31) *) - 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 1) *) - 0x9e67012b; (* arm_FMOV_ItoF Q11 X9 0 *) - 0x9eaf014b; (* arm_FMOV_ItoF Q11 X10 1 *) - 0x4cdf701a; (* arm_LDR Q26 X0 (Postimmediate_Offset (word 16)) *) - 0x6e261c00; (* arm_EOR_VEC Q0 Q0 Q6 128 *) - 0x6e281c21; (* arm_EOR_VEC Q1 Q1 Q8 128 *) - 0x6e291f18; (* arm_EOR_VEC Q24 Q24 Q9 128 *) - 0x6e2a1f39; (* arm_EOR_VEC Q25 Q25 Q10 128 *) - 0x6e2b1f5a; (* arm_EOR_VEC Q26 Q26 Q11 128 *) + 0xf2400ebf; (* arm_TST X21 (rvalue (word 0xf)) *) + 0x54000080; (* arm_BEQ (word 0x10) *) + 0xf1004042; (* arm_SUBS X2 X2 (rvalue (word 0x10)) *) + 0xf100005f; (* arm_CMP X2 (rvalue (word 0x0)) *) + 0x5400488b; (* arm_BLT (word 0x910) *) + 0xf100405f; (* arm_CMP X2 (rvalue (word 0x10)) *) + 0x54004323; (* arm_BCC (word 0x864) *) + 0xf1008042; (* arm_SUBS X2 X2 (rvalue (word 0x20)) *) + 0x54003a03; (* arm_BCC (word 0x740) *) + 0x93ca8156; (* arm_ROR X22 X10 0x20 *) + 0x93c9fd4a; (* arm_EXTR X10 X10 X9 0x3f *) + 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 0x1f) *) + 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 0x1) *) + 0x9e670129; (* arm_FMOV_ItoF Q9 X9 0x0 *) + 0x9eaf0149; (* arm_FMOV_ItoF Q9 X10 0x1 *) + 0xf100405f; (* arm_CMP X2 (rvalue (word 0x10)) *) + 0x54002c23; (* arm_BCC (word 0x584) *) + 0x93ca8156; (* arm_ROR X22 X10 0x20 *) + 0x93c9fd4a; (* arm_EXTR X10 X10 X9 0x3f *) + 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 0x1f) *) + 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 0x1) *) + 0x9e67012a; (* arm_FMOV_ItoF Q10 X9 0x0 *) + 0x9eaf014a; (* arm_FMOV_ItoF Q10 X10 0x1 *) + 0xf1008042; (* arm_SUBS X2 X2 (rvalue (word 0x20)) *) + 0x54001a23; (* arm_BCC (word 0x344) *) + 0x93ca8156; (* arm_ROR X22 X10 0x20 *) + 0x93c9fd4a; (* arm_EXTR X10 X10 X9 0x3f *) + 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 0x1f) *) + 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 0x1) *) + 0x9e67012b; (* arm_FMOV_ItoF Q11 X9 0x0 *) + 0x9eaf014b; (* arm_FMOV_ItoF Q11 X10 0x1 *) 0xd503201f; (* arm_NOP *) 0xd503201f; (* arm_NOP *) + 0xacc28400; (* arm_LDP Q0 Q1 X0 (Postimmediate_Offset (iword (&0x50))) *) + 0xad7ee418; (* arm_LDP Q24 Q25 X0 (Immediate_Offset (iword (-- &0x30))) *) + 0x3cdf001a; (* arm_LDR Q26 X0 (Immediate_Offset (word 0xfffffffffffffff0)) *) + 0x6e261c00; (* arm_EOR_VEC Q0 Q0 Q6 0x80 *) + 0x6e281c21; (* arm_EOR_VEC Q1 Q1 Q8 0x80 *) + 0x6e291f18; (* arm_EOR_VEC Q24 Q24 Q9 0x80 *) + 0x6e2a1f39; (* arm_EOR_VEC Q25 Q25 Q10 0x80 *) + 0x6e2b1f5a; (* arm_EOR_VEC Q26 Q26 Q11 0x80 *) 0x4e285a00; (* arm_AESD Q0 Q16 *) 0x4e287800; (* arm_AESIMC Q0 Q0 *) 0x4e285a01; (* arm_AESD Q1 Q16 *) @@ -122,7 +110,6 @@ let aes_xts_decrypt_mc = define_assert_from_elf "aes_xts_decrypt_mc" "arm/aes-xt 0x4e287b39; (* arm_AESIMC Q25 Q25 *) 0x4e285a1a; (* arm_AESD Q26 Q16 *) 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) - 0xf101404c; (* arm_SUBS X12 X2 (rvalue (word 80)) *) 0x4e285a20; (* arm_AESD Q0 Q17 *) 0x4e287800; (* arm_AESIMC Q0 Q0 *) 0x4e285a21; (* arm_AESD Q1 Q17 *) @@ -133,7 +120,6 @@ let aes_xts_decrypt_mc = define_assert_from_elf "aes_xts_decrypt_mc" "arm/aes-xt 0x4e287b39; (* arm_AESIMC Q25 Q25 *) 0x4e285a3a; (* arm_AESD Q26 Q17 *) 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) - 0x9a8cc3e6; (* arm_CSEL X6 XZR X12 Condition_GT *) 0x4e285980; (* arm_AESD Q0 Q12 *) 0x4e287800; (* arm_AESIMC Q0 Q0 *) 0x4e285981; (* arm_AESD Q1 Q12 *) @@ -204,7 +190,6 @@ let aes_xts_decrypt_mc = define_assert_from_elf "aes_xts_decrypt_mc" "arm/aes-xt 0x4e287b39; (* arm_AESIMC Q25 Q25 *) 0x4e285a5a; (* arm_AESD Q26 Q18 *) 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) - 0x8b060000; (* arm_ADD X0 X0 X6 *) 0x4e285a60; (* arm_AESD Q0 Q19 *) 0x4e287800; (* arm_AESIMC Q0 Q0 *) 0x4e285a61; (* arm_AESD Q1 Q19 *) @@ -250,203 +235,204 @@ let aes_xts_decrypt_mc = define_assert_from_elf "aes_xts_decrypt_mc" "arm/aes-xt 0x4e285af8; (* arm_AESD Q24 Q23 *) 0x4e285af9; (* arm_AESD Q25 Q23 *) 0x4e285afa; (* arm_AESD Q26 Q23 *) - 0x6e271c00; (* arm_EOR_VEC Q0 Q0 Q7 128 *) - 0x6e261c00; (* arm_EOR_VEC Q0 Q0 Q6 128 *) - 0x93ca8156; (* arm_ROR X22 X10 32 *) - 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) - 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 31) *) - 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 1) *) - 0x9e670126; (* arm_FMOV_ItoF Q6 X9 0 *) - 0x9eaf0146; (* arm_FMOV_ItoF Q6 X10 1 *) - 0x6e271c21; (* arm_EOR_VEC Q1 Q1 Q7 128 *) - 0x6e281c21; (* arm_EOR_VEC Q1 Q1 Q8 128 *) - 0xacc28c02; (* arm_LDP Q2 Q3 X0 (Postimmediate_Offset (iword (&80))) *) - 0x93ca8156; (* arm_ROR X22 X10 32 *) - 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) - 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 31) *) - 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 1) *) - 0x9e670128; (* arm_FMOV_ItoF Q8 X9 0 *) - 0x9eaf0148; (* arm_FMOV_ItoF Q8 X10 1 *) - 0x6e271f18; (* arm_EOR_VEC Q24 Q24 Q7 128 *) - 0x6e291f18; (* arm_EOR_VEC Q24 Q24 Q9 128 *) - 0x93ca8156; (* arm_ROR X22 X10 32 *) - 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) - 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 31) *) - 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 1) *) - 0x9e670129; (* arm_FMOV_ItoF Q9 X9 0 *) - 0x9eaf0149; (* arm_FMOV_ItoF Q9 X10 1 *) - 0x6e271f39; (* arm_EOR_VEC Q25 Q25 Q7 128 *) - 0x6e2a1f39; (* arm_EOR_VEC Q25 Q25 Q10 128 *) - 0x3cdd001b; (* arm_LDR Q27 X0 (Immediate_Offset (word 18446744073709551568)) *) - 0x93ca8156; (* arm_ROR X22 X10 32 *) - 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) - 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 31) *) - 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 1) *) - 0x9e67012a; (* arm_FMOV_ItoF Q10 X9 0 *) - 0x9eaf014a; (* arm_FMOV_ItoF Q10 X10 1 *) - 0x6e271f5a; (* arm_EOR_VEC Q26 Q26 Q7 128 *) - 0x6e2b1f5a; (* arm_EOR_VEC Q26 Q26 Q11 128 *) - 0xad7f741c; (* arm_LDP Q28 Q29 X0 (Immediate_Offset (iword (-- &32))) *) - 0x93ca8156; (* arm_ROR X22 X10 32 *) - 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) - 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 31) *) - 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 1) *) - 0x9e67012b; (* arm_FMOV_ItoF Q11 X9 0 *) - 0x9eaf014b; (* arm_FMOV_ItoF Q11 X10 1 *) - 0xac828420; (* arm_STP Q0 Q1 X1 (Postimmediate_Offset (iword (&80))) *) - 0xad3ee438; (* arm_STP Q24 Q25 X1 (Immediate_Offset (iword (-- &48))) *) - 0x3c9f003a; (* arm_STR Q26 X1 (Immediate_Offset (word 18446744073709551600)) *) - 0x6e261c40; (* arm_EOR_VEC Q0 Q2 Q6 128 *) - 0x6e281c61; (* arm_EOR_VEC Q1 Q3 Q8 128 *) - 0x6e291f78; (* arm_EOR_VEC Q24 Q27 Q9 128 *) - 0x6e2a1f99; (* arm_EOR_VEC Q25 Q28 Q10 128 *) - 0x6e2b1fba; (* arm_EOR_VEC Q26 Q29 Q11 128 *) - 0xf1014042; (* arm_SUBS X2 X2 (rvalue (word 80)) *) - 0x54ffe842; (* arm_BCS (word 2096392) *) - 0xb100405f; (* arm_CMN X2 (rvalue (word 16)) *) - 0x54000100; (* arm_BEQ (word 32) *) - 0x91014042; (* arm_ADD X2 X2 (rvalue (word 80)) *) - 0xb4002bc2; (* arm_CBZ X2 (word 1400) *) - 0xf1008042; (* arm_SUBS X2 X2 (rvalue (word 32)) *) - 0x54002683; (* arm_BCC (word 1232) *) - 0xf1004042; (* arm_SUBS X2 X2 (rvalue (word 16)) *) - 0x54001d63; (* arm_BCC (word 940) *) - 0x14000085; (* arm_B (word 532) *) - 0x6e231cc1; (* arm_EOR_VEC Q1 Q6 Q3 128 *) - 0x6e281f78; (* arm_EOR_VEC Q24 Q27 Q8 128 *) - 0x6e291f99; (* arm_EOR_VEC Q25 Q28 Q9 128 *) - 0x6e2a1fba; (* arm_EOR_VEC Q26 Q29 Q10 128 *) + 0x6e271c00; (* arm_EOR_VEC Q0 Q0 Q7 0x80 *) + 0x6e261c00; (* arm_EOR_VEC Q0 Q0 Q6 0x80 *) + 0x93ca8156; (* arm_ROR X22 X10 0x20 *) + 0x93c9fd4a; (* arm_EXTR X10 X10 X9 0x3f *) + 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 0x1f) *) + 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 0x1) *) + 0x9e670126; (* arm_FMOV_ItoF Q6 X9 0x0 *) + 0x9eaf0146; (* arm_FMOV_ItoF Q6 X10 0x1 *) + 0x6e271c21; (* arm_EOR_VEC Q1 Q1 Q7 0x80 *) + 0x6e281c21; (* arm_EOR_VEC Q1 Q1 Q8 0x80 *) + 0x93ca8156; (* arm_ROR X22 X10 0x20 *) + 0x93c9fd4a; (* arm_EXTR X10 X10 X9 0x3f *) + 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 0x1f) *) + 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 0x1) *) + 0x9e670128; (* arm_FMOV_ItoF Q8 X9 0x0 *) + 0x9eaf0148; (* arm_FMOV_ItoF Q8 X10 0x1 *) + 0x6e271f18; (* arm_EOR_VEC Q24 Q24 Q7 0x80 *) + 0x6e291f18; (* arm_EOR_VEC Q24 Q24 Q9 0x80 *) + 0x93ca8156; (* arm_ROR X22 X10 0x20 *) + 0x93c9fd4a; (* arm_EXTR X10 X10 X9 0x3f *) + 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 0x1f) *) + 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 0x1) *) + 0x9e670129; (* arm_FMOV_ItoF Q9 X9 0x0 *) + 0x9eaf0149; (* arm_FMOV_ItoF Q9 X10 0x1 *) + 0x6e271f39; (* arm_EOR_VEC Q25 Q25 Q7 0x80 *) + 0x6e2a1f39; (* arm_EOR_VEC Q25 Q25 Q10 0x80 *) + 0x93ca8156; (* arm_ROR X22 X10 0x20 *) + 0x93c9fd4a; (* arm_EXTR X10 X10 X9 0x3f *) + 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 0x1f) *) + 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 0x1) *) + 0x9e67012a; (* arm_FMOV_ItoF Q10 X9 0x0 *) + 0x9eaf014a; (* arm_FMOV_ItoF Q10 X10 0x1 *) + 0x6e271f5a; (* arm_EOR_VEC Q26 Q26 Q7 0x80 *) + 0x6e2b1f5a; (* arm_EOR_VEC Q26 Q26 Q11 0x80 *) + 0x93ca8156; (* arm_ROR X22 X10 0x20 *) + 0x93c9fd4a; (* arm_EXTR X10 X10 X9 0x3f *) + 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 0x1f) *) + 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 0x1) *) + 0x9e67012b; (* arm_FMOV_ItoF Q11 X9 0x0 *) + 0x9eaf014b; (* arm_FMOV_ItoF Q11 X10 0x1 *) + 0xac828420; (* arm_STP Q0 Q1 X1 (Postimmediate_Offset (iword (&0x50))) *) + 0xad3ee438; (* arm_STP Q24 Q25 X1 (Immediate_Offset (iword (-- &0x30))) *) + 0x3c9f003a; (* arm_STR Q26 X1 (Immediate_Offset (word 0xfffffffffffffff0)) *) + 0xf1014042; (* arm_SUBS X2 X2 (rvalue (word 0x50)) *) + 0x54ffe8a2; (* arm_BCS (word 0x1ffd14) *) + 0xb100405f; (* arm_CMN X2 (rvalue (word 0x10)) *) + 0x54000160; (* arm_BEQ (word 0x2c) *) + 0x91014042; (* arm_ADD X2 X2 (rvalue (word 0x50)) *) + 0xb4002d02; (* arm_CBZ X2 (word 0x5a0) *) + 0xf1008042; (* arm_SUBS X2 X2 (rvalue (word 0x20)) *) + 0x540027a3; (* arm_BCC (word 0x4f4) *) + 0xf1004042; (* arm_SUBS X2 X2 (rvalue (word 0x10)) *) + 0x54001e83; (* arm_BCC (word 0x3d0) *) + 0x1400008c; (* arm_B (word 0x230) *) + 0xd503201f; (* arm_NOP *) + 0xd503201f; (* arm_NOP *) + 0xd503201f; (* arm_NOP *) + 0x4cdfa000; (* arm_LDP Q0 Q1 X0 (Postimmediate_Offset (word 0x20)) *) + 0x4cdfa018; (* arm_LDP Q24 Q25 X0 (Postimmediate_Offset (word 0x20)) *) + 0x6e261c00; (* arm_EOR_VEC Q0 Q0 Q6 0x80 *) + 0x6e281c21; (* arm_EOR_VEC Q1 Q1 Q8 0x80 *) + 0x6e291f18; (* arm_EOR_VEC Q24 Q24 Q9 0x80 *) + 0x6e2a1f39; (* arm_EOR_VEC Q25 Q25 Q10 0x80 *) + 0x4e285a00; (* arm_AESD Q0 Q16 *) + 0x4e287800; (* arm_AESIMC Q0 Q0 *) 0x4e285a01; (* arm_AESD Q1 Q16 *) 0x4e287821; (* arm_AESIMC Q1 Q1 *) 0x4e285a18; (* arm_AESD Q24 Q16 *) 0x4e287b18; (* arm_AESIMC Q24 Q24 *) 0x4e285a19; (* arm_AESD Q25 Q16 *) 0x4e287b39; (* arm_AESIMC Q25 Q25 *) - 0x4e285a1a; (* arm_AESD Q26 Q16 *) - 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) + 0x4e285a20; (* arm_AESD Q0 Q17 *) + 0x4e287800; (* arm_AESIMC Q0 Q0 *) 0x4e285a21; (* arm_AESD Q1 Q17 *) 0x4e287821; (* arm_AESIMC Q1 Q1 *) 0x4e285a38; (* arm_AESD Q24 Q17 *) 0x4e287b18; (* arm_AESIMC Q24 Q24 *) 0x4e285a39; (* arm_AESD Q25 Q17 *) 0x4e287b39; (* arm_AESIMC Q25 Q25 *) - 0x4e285a3a; (* arm_AESD Q26 Q17 *) - 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) + 0x4e285980; (* arm_AESD Q0 Q12 *) + 0x4e287800; (* arm_AESIMC Q0 Q0 *) 0x4e285981; (* arm_AESD Q1 Q12 *) 0x4e287821; (* arm_AESIMC Q1 Q1 *) 0x4e285998; (* arm_AESD Q24 Q12 *) 0x4e287b18; (* arm_AESIMC Q24 Q24 *) 0x4e285999; (* arm_AESD Q25 Q12 *) 0x4e287b39; (* arm_AESIMC Q25 Q25 *) - 0x4e28599a; (* arm_AESD Q26 Q12 *) - 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) + 0x4e2859a0; (* arm_AESD Q0 Q13 *) + 0x4e287800; (* arm_AESIMC Q0 Q0 *) 0x4e2859a1; (* arm_AESD Q1 Q13 *) 0x4e287821; (* arm_AESIMC Q1 Q1 *) 0x4e2859b8; (* arm_AESD Q24 Q13 *) 0x4e287b18; (* arm_AESIMC Q24 Q24 *) 0x4e2859b9; (* arm_AESD Q25 Q13 *) 0x4e287b39; (* arm_AESIMC Q25 Q25 *) - 0x4e2859ba; (* arm_AESD Q26 Q13 *) - 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) + 0x4e2859c0; (* arm_AESD Q0 Q14 *) + 0x4e287800; (* arm_AESIMC Q0 Q0 *) 0x4e2859c1; (* arm_AESD Q1 Q14 *) 0x4e287821; (* arm_AESIMC Q1 Q1 *) 0x4e2859d8; (* arm_AESD Q24 Q14 *) 0x4e287b18; (* arm_AESIMC Q24 Q24 *) 0x4e2859d9; (* arm_AESD Q25 Q14 *) 0x4e287b39; (* arm_AESIMC Q25 Q25 *) - 0x4e2859da; (* arm_AESD Q26 Q14 *) - 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) + 0x4e2859e0; (* arm_AESD Q0 Q15 *) + 0x4e287800; (* arm_AESIMC Q0 Q0 *) 0x4e2859e1; (* arm_AESD Q1 Q15 *) 0x4e287821; (* arm_AESIMC Q1 Q1 *) 0x4e2859f8; (* arm_AESD Q24 Q15 *) 0x4e287b18; (* arm_AESIMC Q24 Q24 *) 0x4e2859f9; (* arm_AESD Q25 Q15 *) 0x4e287b39; (* arm_AESIMC Q25 Q25 *) - 0x4e2859fa; (* arm_AESD Q26 Q15 *) - 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) + 0x4e285880; (* arm_AESD Q0 Q4 *) + 0x4e287800; (* arm_AESIMC Q0 Q0 *) 0x4e285881; (* arm_AESD Q1 Q4 *) 0x4e287821; (* arm_AESIMC Q1 Q1 *) 0x4e285898; (* arm_AESD Q24 Q4 *) 0x4e287b18; (* arm_AESIMC Q24 Q24 *) 0x4e285899; (* arm_AESD Q25 Q4 *) 0x4e287b39; (* arm_AESIMC Q25 Q25 *) - 0x4e28589a; (* arm_AESD Q26 Q4 *) - 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) + 0x4e2858a0; (* arm_AESD Q0 Q5 *) + 0x4e287800; (* arm_AESIMC Q0 Q0 *) 0x4e2858a1; (* arm_AESD Q1 Q5 *) 0x4e287821; (* arm_AESIMC Q1 Q1 *) 0x4e2858b8; (* arm_AESD Q24 Q5 *) 0x4e287b18; (* arm_AESIMC Q24 Q24 *) 0x4e2858b9; (* arm_AESD Q25 Q5 *) 0x4e287b39; (* arm_AESIMC Q25 Q25 *) - 0x4e2858ba; (* arm_AESD Q26 Q5 *) - 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) + 0x4e285a40; (* arm_AESD Q0 Q18 *) + 0x4e287800; (* arm_AESIMC Q0 Q0 *) 0x4e285a41; (* arm_AESD Q1 Q18 *) 0x4e287821; (* arm_AESIMC Q1 Q1 *) 0x4e285a58; (* arm_AESD Q24 Q18 *) 0x4e287b18; (* arm_AESIMC Q24 Q24 *) 0x4e285a59; (* arm_AESD Q25 Q18 *) 0x4e287b39; (* arm_AESIMC Q25 Q25 *) - 0x4e285a5a; (* arm_AESD Q26 Q18 *) - 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) + 0x4e285a60; (* arm_AESD Q0 Q19 *) + 0x4e287800; (* arm_AESIMC Q0 Q0 *) 0x4e285a61; (* arm_AESD Q1 Q19 *) 0x4e287821; (* arm_AESIMC Q1 Q1 *) 0x4e285a78; (* arm_AESD Q24 Q19 *) 0x4e287b18; (* arm_AESIMC Q24 Q24 *) 0x4e285a79; (* arm_AESD Q25 Q19 *) 0x4e287b39; (* arm_AESIMC Q25 Q25 *) - 0x4e285a7a; (* arm_AESD Q26 Q19 *) - 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) + 0x4e285a80; (* arm_AESD Q0 Q20 *) + 0x4e287800; (* arm_AESIMC Q0 Q0 *) 0x4e285a81; (* arm_AESD Q1 Q20 *) 0x4e287821; (* arm_AESIMC Q1 Q1 *) 0x4e285a98; (* arm_AESD Q24 Q20 *) 0x4e287b18; (* arm_AESIMC Q24 Q24 *) 0x4e285a99; (* arm_AESD Q25 Q20 *) 0x4e287b39; (* arm_AESIMC Q25 Q25 *) - 0x4e285a9a; (* arm_AESD Q26 Q20 *) - 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) + 0x4e285aa0; (* arm_AESD Q0 Q21 *) + 0x4e287800; (* arm_AESIMC Q0 Q0 *) 0x4e285aa1; (* arm_AESD Q1 Q21 *) 0x4e287821; (* arm_AESIMC Q1 Q1 *) 0x4e285ab8; (* arm_AESD Q24 Q21 *) 0x4e287b18; (* arm_AESIMC Q24 Q24 *) 0x4e285ab9; (* arm_AESD Q25 Q21 *) 0x4e287b39; (* arm_AESIMC Q25 Q25 *) - 0x4e285aba; (* arm_AESD Q26 Q21 *) - 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) + 0x4e285ac0; (* arm_AESD Q0 Q22 *) + 0x4e287800; (* arm_AESIMC Q0 Q0 *) 0x4e285ac1; (* arm_AESD Q1 Q22 *) 0x4e287821; (* arm_AESIMC Q1 Q1 *) 0x4e285ad8; (* arm_AESD Q24 Q22 *) 0x4e287b18; (* arm_AESIMC Q24 Q24 *) 0x4e285ad9; (* arm_AESD Q25 Q22 *) 0x4e287b39; (* arm_AESIMC Q25 Q25 *) - 0x4e285ada; (* arm_AESD Q26 Q22 *) - 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) + 0x4e285ae0; (* arm_AESD Q0 Q23 *) 0x4e285ae1; (* arm_AESD Q1 Q23 *) 0x4e285af8; (* arm_AESD Q24 Q23 *) 0x4e285af9; (* arm_AESD Q25 Q23 *) - 0x4e285afa; (* arm_AESD Q26 Q23 *) - 0x6e271c21; (* arm_EOR_VEC Q1 Q1 Q7 128 *) - 0x6e261c21; (* arm_EOR_VEC Q1 Q1 Q6 128 *) - 0x6e271f18; (* arm_EOR_VEC Q24 Q24 Q7 128 *) - 0x6e281f18; (* arm_EOR_VEC Q24 Q24 Q8 128 *) - 0x6e271f39; (* arm_EOR_VEC Q25 Q25 Q7 128 *) - 0x6e291f39; (* arm_EOR_VEC Q25 Q25 Q9 128 *) - 0x6e271f5a; (* arm_EOR_VEC Q26 Q26 Q7 128 *) - 0x6e2a1f5a; (* arm_EOR_VEC Q26 Q26 Q10 128 *) - 0x9e660149; (* arm_FMOV_FtoI X9 Q10 0 64 *) - 0x9eae014a; (* arm_FMOV_FtoI X10 Q10 1 64 *) - 0x93ca8156; (* arm_ROR X22 X10 32 *) - 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) - 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 31) *) - 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 1) *) - 0x9e670126; (* arm_FMOV_ItoF Q6 X9 0 *) - 0x9eaf0146; (* arm_FMOV_ItoF Q6 X10 1 *) - 0x4c9f7021; (* arm_STR Q1 X1 (Postimmediate_Offset (word 16)) *) - 0x4c9fa038; (* arm_STP Q24 Q25 X1 (Postimmediate_Offset (word 32)) *) - 0x4c9f703a; (* arm_STR Q26 X1 (Postimmediate_Offset (word 16)) *) - 0x140000d5; (* arm_B (word 852) *) - 0x6e3b1cc0; (* arm_EOR_VEC Q0 Q6 Q27 128 *) - 0x6e3c1d01; (* arm_EOR_VEC Q1 Q8 Q28 128 *) - 0x6e291fb8; (* arm_EOR_VEC Q24 Q29 Q9 128 *) + 0x6e271c00; (* arm_EOR_VEC Q0 Q0 Q7 0x80 *) + 0x6e261c00; (* arm_EOR_VEC Q0 Q0 Q6 0x80 *) + 0x6e271c21; (* arm_EOR_VEC Q1 Q1 Q7 0x80 *) + 0x6e281c21; (* arm_EOR_VEC Q1 Q1 Q8 0x80 *) + 0x6e271f18; (* arm_EOR_VEC Q24 Q24 Q7 0x80 *) + 0x6e291f18; (* arm_EOR_VEC Q24 Q24 Q9 0x80 *) + 0x6e271f39; (* arm_EOR_VEC Q25 Q25 Q7 0x80 *) + 0x6e2a1f39; (* arm_EOR_VEC Q25 Q25 Q10 0x80 *) + 0x9e660149; (* arm_FMOV_FtoI X9 Q10 0x0 0x40 *) + 0x9eae014a; (* arm_FMOV_FtoI X10 Q10 0x1 0x40 *) + 0x93ca8156; (* arm_ROR X22 X10 0x20 *) + 0x93c9fd4a; (* arm_EXTR X10 X10 X9 0x3f *) + 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 0x1f) *) + 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 0x1) *) + 0x9e670126; (* arm_FMOV_ItoF Q6 X9 0x0 *) + 0x9eaf0146; (* arm_FMOV_ItoF Q6 X10 0x1 *) + 0x4c9fa020; (* arm_STP Q0 Q1 X1 (Postimmediate_Offset (word 0x20)) *) + 0x4c9fa038; (* arm_STP Q24 Q25 X1 (Postimmediate_Offset (word 0x20)) *) + 0x140000db; (* arm_B (word 0x36c) *) + 0xd503201f; (* arm_NOP *) + 0xd503201f; (* arm_NOP *) + 0xd503201f; (* arm_NOP *) + 0x4cdfa000; (* arm_LDP Q0 Q1 X0 (Postimmediate_Offset (word 0x20)) *) + 0x4cdf7018; (* arm_LDR Q24 X0 (Postimmediate_Offset (word 0x10)) *) + 0x6e261c00; (* arm_EOR_VEC Q0 Q0 Q6 0x80 *) + 0x6e281c21; (* arm_EOR_VEC Q1 Q1 Q8 0x80 *) + 0x6e291f18; (* arm_EOR_VEC Q24 Q24 Q9 0x80 *) 0x4e285a00; (* arm_AESD Q0 Q16 *) 0x4e287800; (* arm_AESIMC Q0 Q0 *) 0x4e285a01; (* arm_AESD Q1 Q16 *) @@ -528,200 +514,201 @@ let aes_xts_decrypt_mc = define_assert_from_elf "aes_xts_decrypt_mc" "arm/aes-xt 0x4e285ae0; (* arm_AESD Q0 Q23 *) 0x4e285ae1; (* arm_AESD Q1 Q23 *) 0x4e285af8; (* arm_AESD Q24 Q23 *) - 0x6e271c00; (* arm_EOR_VEC Q0 Q0 Q7 128 *) - 0x6e261c00; (* arm_EOR_VEC Q0 Q0 Q6 128 *) - 0x6e271c21; (* arm_EOR_VEC Q1 Q1 Q7 128 *) - 0x6e281c21; (* arm_EOR_VEC Q1 Q1 Q8 128 *) - 0x6e271f18; (* arm_EOR_VEC Q24 Q24 Q7 128 *) - 0x6e291f18; (* arm_EOR_VEC Q24 Q24 Q9 128 *) - 0x9e660129; (* arm_FMOV_FtoI X9 Q9 0 64 *) - 0x9eae012a; (* arm_FMOV_FtoI X10 Q9 1 64 *) - 0x93ca8156; (* arm_ROR X22 X10 32 *) - 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) - 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 31) *) - 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 1) *) - 0x9e670126; (* arm_FMOV_ItoF Q6 X9 0 *) - 0x9eaf0146; (* arm_FMOV_ItoF Q6 X10 1 *) - 0x4c9fa020; (* arm_STP Q0 Q1 X1 (Postimmediate_Offset (word 32)) *) - 0x4c9f7038; (* arm_STR Q24 X1 (Postimmediate_Offset (word 16)) *) - 0x14000070; (* arm_B (word 448) *) - 0x6e261f81; (* arm_EOR_VEC Q1 Q28 Q6 128 *) - 0x6e281fb8; (* arm_EOR_VEC Q24 Q29 Q8 128 *) + 0x6e271c00; (* arm_EOR_VEC Q0 Q0 Q7 0x80 *) + 0x6e261c00; (* arm_EOR_VEC Q0 Q0 Q6 0x80 *) + 0x6e271c21; (* arm_EOR_VEC Q1 Q1 Q7 0x80 *) + 0x6e281c21; (* arm_EOR_VEC Q1 Q1 Q8 0x80 *) + 0x6e271f18; (* arm_EOR_VEC Q24 Q24 Q7 0x80 *) + 0x6e291f18; (* arm_EOR_VEC Q24 Q24 Q9 0x80 *) + 0x9e660129; (* arm_FMOV_FtoI X9 Q9 0x0 0x40 *) + 0x9eae012a; (* arm_FMOV_FtoI X10 Q9 0x1 0x40 *) + 0x93ca8156; (* arm_ROR X22 X10 0x20 *) + 0x93c9fd4a; (* arm_EXTR X10 X10 X9 0x3f *) + 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 0x1f) *) + 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 0x1) *) + 0x9e670126; (* arm_FMOV_ItoF Q6 X9 0x0 *) + 0x9eaf0146; (* arm_FMOV_ItoF Q6 X10 0x1 *) + 0x4c9fa020; (* arm_STP Q0 Q1 X1 (Postimmediate_Offset (word 0x20)) *) + 0x4c9f7038; (* arm_STR Q24 X1 (Postimmediate_Offset (word 0x10)) *) + 0x14000071; (* arm_B (word 0x1c4) *) + 0x4cdfa000; (* arm_LDP Q0 Q1 X0 (Postimmediate_Offset (word 0x20)) *) + 0x6e261c00; (* arm_EOR_VEC Q0 Q0 Q6 0x80 *) + 0x6e281c21; (* arm_EOR_VEC Q1 Q1 Q8 0x80 *) + 0x4e285a00; (* arm_AESD Q0 Q16 *) + 0x4e287800; (* arm_AESIMC Q0 Q0 *) 0x4e285a01; (* arm_AESD Q1 Q16 *) 0x4e287821; (* arm_AESIMC Q1 Q1 *) - 0x4e285a18; (* arm_AESD Q24 Q16 *) - 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x4e285a20; (* arm_AESD Q0 Q17 *) + 0x4e287800; (* arm_AESIMC Q0 Q0 *) 0x4e285a21; (* arm_AESD Q1 Q17 *) 0x4e287821; (* arm_AESIMC Q1 Q1 *) - 0x4e285a38; (* arm_AESD Q24 Q17 *) - 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x4e285980; (* arm_AESD Q0 Q12 *) + 0x4e287800; (* arm_AESIMC Q0 Q0 *) 0x4e285981; (* arm_AESD Q1 Q12 *) 0x4e287821; (* arm_AESIMC Q1 Q1 *) - 0x4e285998; (* arm_AESD Q24 Q12 *) - 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x4e2859a0; (* arm_AESD Q0 Q13 *) + 0x4e287800; (* arm_AESIMC Q0 Q0 *) 0x4e2859a1; (* arm_AESD Q1 Q13 *) 0x4e287821; (* arm_AESIMC Q1 Q1 *) - 0x4e2859b8; (* arm_AESD Q24 Q13 *) - 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x4e2859c0; (* arm_AESD Q0 Q14 *) + 0x4e287800; (* arm_AESIMC Q0 Q0 *) 0x4e2859c1; (* arm_AESD Q1 Q14 *) 0x4e287821; (* arm_AESIMC Q1 Q1 *) - 0x4e2859d8; (* arm_AESD Q24 Q14 *) - 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x4e2859e0; (* arm_AESD Q0 Q15 *) + 0x4e287800; (* arm_AESIMC Q0 Q0 *) 0x4e2859e1; (* arm_AESD Q1 Q15 *) 0x4e287821; (* arm_AESIMC Q1 Q1 *) - 0x4e2859f8; (* arm_AESD Q24 Q15 *) - 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x4e285880; (* arm_AESD Q0 Q4 *) + 0x4e287800; (* arm_AESIMC Q0 Q0 *) 0x4e285881; (* arm_AESD Q1 Q4 *) 0x4e287821; (* arm_AESIMC Q1 Q1 *) - 0x4e285898; (* arm_AESD Q24 Q4 *) - 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x4e2858a0; (* arm_AESD Q0 Q5 *) + 0x4e287800; (* arm_AESIMC Q0 Q0 *) 0x4e2858a1; (* arm_AESD Q1 Q5 *) 0x4e287821; (* arm_AESIMC Q1 Q1 *) - 0x4e2858b8; (* arm_AESD Q24 Q5 *) - 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x4e285a40; (* arm_AESD Q0 Q18 *) + 0x4e287800; (* arm_AESIMC Q0 Q0 *) 0x4e285a41; (* arm_AESD Q1 Q18 *) 0x4e287821; (* arm_AESIMC Q1 Q1 *) - 0x4e285a58; (* arm_AESD Q24 Q18 *) - 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x4e285a60; (* arm_AESD Q0 Q19 *) + 0x4e287800; (* arm_AESIMC Q0 Q0 *) 0x4e285a61; (* arm_AESD Q1 Q19 *) 0x4e287821; (* arm_AESIMC Q1 Q1 *) - 0x4e285a78; (* arm_AESD Q24 Q19 *) - 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x4e285a80; (* arm_AESD Q0 Q20 *) + 0x4e287800; (* arm_AESIMC Q0 Q0 *) 0x4e285a81; (* arm_AESD Q1 Q20 *) 0x4e287821; (* arm_AESIMC Q1 Q1 *) - 0x4e285a98; (* arm_AESD Q24 Q20 *) - 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x4e285aa0; (* arm_AESD Q0 Q21 *) + 0x4e287800; (* arm_AESIMC Q0 Q0 *) 0x4e285aa1; (* arm_AESD Q1 Q21 *) 0x4e287821; (* arm_AESIMC Q1 Q1 *) - 0x4e285ab8; (* arm_AESD Q24 Q21 *) - 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x4e285ac0; (* arm_AESD Q0 Q22 *) + 0x4e287800; (* arm_AESIMC Q0 Q0 *) 0x4e285ac1; (* arm_AESD Q1 Q22 *) 0x4e287821; (* arm_AESIMC Q1 Q1 *) - 0x4e285ad8; (* arm_AESD Q24 Q22 *) - 0x4e287b18; (* arm_AESIMC Q24 Q24 *) + 0x4e285ae0; (* arm_AESD Q0 Q23 *) 0x4e285ae1; (* arm_AESD Q1 Q23 *) - 0x4e285af8; (* arm_AESD Q24 Q23 *) - 0x6e271c21; (* arm_EOR_VEC Q1 Q1 Q7 128 *) - 0x6e261c21; (* arm_EOR_VEC Q1 Q1 Q6 128 *) - 0x4c9f7021; (* arm_STR Q1 X1 (Postimmediate_Offset (word 16)) *) - 0x6e271f18; (* arm_EOR_VEC Q24 Q24 Q7 128 *) - 0x6e281f18; (* arm_EOR_VEC Q24 Q24 Q8 128 *) - 0x4c9f7038; (* arm_STR Q24 X1 (Postimmediate_Offset (word 16)) *) - 0x9e660109; (* arm_FMOV_FtoI X9 Q8 0 64 *) - 0x9eae010a; (* arm_FMOV_FtoI X10 Q8 1 64 *) - 0x93ca8156; (* arm_ROR X22 X10 32 *) - 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) - 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 31) *) - 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 1) *) - 0x9e670126; (* arm_FMOV_ItoF Q6 X9 0 *) - 0x9eaf0146; (* arm_FMOV_ItoF Q6 X10 1 *) - 0x14000029; (* arm_B (word 164) *) - 0x6e261fb8; (* arm_EOR_VEC Q24 Q29 Q6 128 *) - 0x4e285a18; (* arm_AESD Q24 Q16 *) - 0x4e287b18; (* arm_AESIMC Q24 Q24 *) - 0x4e285a38; (* arm_AESD Q24 Q17 *) - 0x4e287b18; (* arm_AESIMC Q24 Q24 *) - 0x4e285998; (* arm_AESD Q24 Q12 *) - 0x4e287b18; (* arm_AESIMC Q24 Q24 *) - 0x4e2859b8; (* arm_AESD Q24 Q13 *) - 0x4e287b18; (* arm_AESIMC Q24 Q24 *) - 0x4e2859d8; (* arm_AESD Q24 Q14 *) - 0x4e287b18; (* arm_AESIMC Q24 Q24 *) - 0x4e2859f8; (* arm_AESD Q24 Q15 *) - 0x4e287b18; (* arm_AESIMC Q24 Q24 *) - 0x4e285898; (* arm_AESD Q24 Q4 *) - 0x4e287b18; (* arm_AESIMC Q24 Q24 *) - 0x4e2858b8; (* arm_AESD Q24 Q5 *) - 0x4e287b18; (* arm_AESIMC Q24 Q24 *) - 0x4e285a58; (* arm_AESD Q24 Q18 *) - 0x4e287b18; (* arm_AESIMC Q24 Q24 *) - 0x4e285a78; (* arm_AESD Q24 Q19 *) - 0x4e287b18; (* arm_AESIMC Q24 Q24 *) - 0x4e285a98; (* arm_AESD Q24 Q20 *) - 0x4e287b18; (* arm_AESIMC Q24 Q24 *) - 0x4e285ab8; (* arm_AESD Q24 Q21 *) - 0x4e287b18; (* arm_AESIMC Q24 Q24 *) - 0x4e285ad8; (* arm_AESD Q24 Q22 *) - 0x4e287b18; (* arm_AESIMC Q24 Q24 *) - 0x4e285af8; (* arm_AESD Q24 Q23 *) - 0x6e271f18; (* arm_EOR_VEC Q24 Q24 Q7 128 *) - 0x6e261f18; (* arm_EOR_VEC Q24 Q24 Q6 128 *) - 0x4c9f7038; (* arm_STR Q24 X1 (Postimmediate_Offset (word 16)) *) - 0x9e6600c9; (* arm_FMOV_FtoI X9 Q6 0 64 *) - 0x9eae00ca; (* arm_FMOV_FtoI X10 Q6 1 64 *) - 0x93ca8156; (* arm_ROR X22 X10 32 *) - 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) - 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 31) *) - 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 1) *) - 0x9e670126; (* arm_FMOV_ItoF Q6 X9 0 *) - 0x9eaf0146; (* arm_FMOV_ItoF Q6 X10 1 *) - 0x14000001; (* arm_B (word 4) *) - 0xf2400ebf; (* arm_TST X21 (rvalue (word 15)) *) - 0x54000780; (* arm_BEQ (word 240) *) + 0x6e271c00; (* arm_EOR_VEC Q0 Q0 Q7 0x80 *) + 0x6e261c00; (* arm_EOR_VEC Q0 Q0 Q6 0x80 *) + 0x6e271c21; (* arm_EOR_VEC Q1 Q1 Q7 0x80 *) + 0x6e281c21; (* arm_EOR_VEC Q1 Q1 Q8 0x80 *) + 0x4c9fa020; (* arm_STP Q0 Q1 X1 (Postimmediate_Offset (word 0x20)) *) + 0x9e660109; (* arm_FMOV_FtoI X9 Q8 0x0 0x40 *) + 0x9eae010a; (* arm_FMOV_FtoI X10 Q8 0x1 0x40 *) + 0x93ca8156; (* arm_ROR X22 X10 0x20 *) + 0x93c9fd4a; (* arm_EXTR X10 X10 X9 0x3f *) + 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 0x1f) *) + 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 0x1) *) + 0x9e670126; (* arm_FMOV_ItoF Q6 X9 0x0 *) + 0x9eaf0146; (* arm_FMOV_ItoF Q6 X10 0x1 *) + 0x1400002a; (* arm_B (word 0xa8) *) + 0x4cdf7000; (* arm_LDR Q0 X0 (Postimmediate_Offset (word 0x10)) *) + 0x6e261c00; (* arm_EOR_VEC Q0 Q0 Q6 0x80 *) + 0x4e285a00; (* arm_AESD Q0 Q16 *) + 0x4e287800; (* arm_AESIMC Q0 Q0 *) + 0x4e285a20; (* arm_AESD Q0 Q17 *) + 0x4e287800; (* arm_AESIMC Q0 Q0 *) + 0x4e285980; (* arm_AESD Q0 Q12 *) + 0x4e287800; (* arm_AESIMC Q0 Q0 *) + 0x4e2859a0; (* arm_AESD Q0 Q13 *) + 0x4e287800; (* arm_AESIMC Q0 Q0 *) + 0x4e2859c0; (* arm_AESD Q0 Q14 *) + 0x4e287800; (* arm_AESIMC Q0 Q0 *) + 0x4e2859e0; (* arm_AESD Q0 Q15 *) + 0x4e287800; (* arm_AESIMC Q0 Q0 *) + 0x4e285880; (* arm_AESD Q0 Q4 *) + 0x4e287800; (* arm_AESIMC Q0 Q0 *) + 0x4e2858a0; (* arm_AESD Q0 Q5 *) + 0x4e287800; (* arm_AESIMC Q0 Q0 *) + 0x4e285a40; (* arm_AESD Q0 Q18 *) + 0x4e287800; (* arm_AESIMC Q0 Q0 *) + 0x4e285a60; (* arm_AESD Q0 Q19 *) + 0x4e287800; (* arm_AESIMC Q0 Q0 *) + 0x4e285a80; (* arm_AESD Q0 Q20 *) + 0x4e287800; (* arm_AESIMC Q0 Q0 *) + 0x4e285aa0; (* arm_AESD Q0 Q21 *) + 0x4e287800; (* arm_AESIMC Q0 Q0 *) + 0x4e285ac0; (* arm_AESD Q0 Q22 *) + 0x4e287800; (* arm_AESIMC Q0 Q0 *) + 0x4e285ae0; (* arm_AESD Q0 Q23 *) + 0x6e271c00; (* arm_EOR_VEC Q0 Q0 Q7 0x80 *) + 0x6e261c00; (* arm_EOR_VEC Q0 Q0 Q6 0x80 *) + 0x4c9f7020; (* arm_STR Q0 X1 (Postimmediate_Offset (word 0x10)) *) + 0x9e6600c9; (* arm_FMOV_FtoI X9 Q6 0x0 0x40 *) + 0x9eae00ca; (* arm_FMOV_FtoI X10 Q6 0x1 0x40 *) + 0x93ca8156; (* arm_ROR X22 X10 0x20 *) + 0x93c9fd4a; (* arm_EXTR X10 X10 X9 0x3f *) + 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 0x1f) *) + 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 0x1) *) + 0x9e670126; (* arm_FMOV_ItoF Q6 X9 0x0 *) + 0x9eaf0146; (* arm_FMOV_ItoF Q6 X10 0x1 *) + 0x14000001; (* arm_B (word 0x4) *) + 0xf2400ebf; (* arm_TST X21 (rvalue (word 0xf)) *) + 0x54000780; (* arm_BEQ (word 0xf0) *) 0xaa0303e7; (* arm_MOV X7 X3 *) - 0x9e6600c9; (* arm_FMOV_FtoI X9 Q6 0 64 *) - 0x9eae00ca; (* arm_FMOV_FtoI X10 Q6 1 64 *) - 0x93ca8156; (* arm_ROR X22 X10 32 *) - 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) - 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 31) *) - 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 1) *) - 0x9e670128; (* arm_FMOV_ItoF Q8 X9 0 *) - 0x9eaf0148; (* arm_FMOV_ItoF Q8 X10 1 *) - 0x4cdf7800; (* arm_LDR Q0 X0 (Postimmediate_Offset (word 16)) *) - 0x6e281c1a; (* arm_EOR_VEC Q26 Q0 Q8 128 *) - 0xb940f066; (* arm_LDR W6 X3 (Immediate_Offset (word 240)) *) - 0x4cdf7860; (* arm_LDR Q0 X3 (Postimmediate_Offset (word 16)) *) - 0x510008c6; (* arm_SUB W6 W6 (rvalue (word 2)) *) - 0x4cdf7861; (* arm_LDR Q1 X3 (Postimmediate_Offset (word 16)) *) + 0x9e6600c9; (* arm_FMOV_FtoI X9 Q6 0x0 0x40 *) + 0x9eae00ca; (* arm_FMOV_FtoI X10 Q6 0x1 0x40 *) + 0x93ca8156; (* arm_ROR X22 X10 0x20 *) + 0x93c9fd4a; (* arm_EXTR X10 X10 X9 0x3f *) + 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 0x1f) *) + 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 0x1) *) + 0x9e670128; (* arm_FMOV_ItoF Q8 X9 0x0 *) + 0x9eaf0148; (* arm_FMOV_ItoF Q8 X10 0x1 *) + 0x4cdf7800; (* arm_LDR Q0 X0 (Postimmediate_Offset (word 0x10)) *) + 0x6e281c1a; (* arm_EOR_VEC Q26 Q0 Q8 0x80 *) + 0xb940f066; (* arm_LDR W6 X3 (Immediate_Offset (word 0xf0)) *) + 0x4cdf7860; (* arm_LDR Q0 X3 (Postimmediate_Offset (word 0x10)) *) + 0x510008c6; (* arm_SUB W6 W6 (rvalue (word 0x2)) *) + 0x4cdf7861; (* arm_LDR Q1 X3 (Postimmediate_Offset (word 0x10)) *) 0x4e28581a; (* arm_AESD Q26 Q0 *) 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) - 0x4cdf7860; (* arm_LDR Q0 X3 (Postimmediate_Offset (word 16)) *) - 0x710008c6; (* arm_SUBS W6 W6 (rvalue (word 2)) *) + 0x4cdf7860; (* arm_LDR Q0 X3 (Postimmediate_Offset (word 0x10)) *) + 0x710008c6; (* arm_SUBS W6 W6 (rvalue (word 0x2)) *) 0x4e28583a; (* arm_AESD Q26 Q1 *) 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) - 0x4cdf7861; (* arm_LDR Q1 X3 (Postimmediate_Offset (word 16)) *) - 0x54ffff2c; (* arm_BGT (word 2097124) *) + 0x4cdf7861; (* arm_LDR Q1 X3 (Postimmediate_Offset (word 0x10)) *) + 0x54ffff2c; (* arm_BGT (word 0x1fffe4) *) 0x4e28581a; (* arm_AESD Q26 Q0 *) 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) 0x4c407860; (* arm_LDR Q0 X3 No_Offset *) 0x4e28583a; (* arm_AESD Q26 Q1 *) - 0x6e201f5a; (* arm_EOR_VEC Q26 Q26 Q0 128 *) - 0x6e281f5a; (* arm_EOR_VEC Q26 Q26 Q8 128 *) + 0x6e201f5a; (* arm_EOR_VEC Q26 Q26 Q0 0x80 *) + 0x6e281f5a; (* arm_EOR_VEC Q26 Q26 Q8 0x80 *) 0x4c00703a; (* arm_STR Q26 X1 No_Offset *) 0xaa0003f4; (* arm_MOV X20 X0 *) - 0x9100402d; (* arm_ADD X13 X1 (rvalue (word 16)) *) - 0xf10006b5; (* arm_SUBS X21 X21 (rvalue (word 1)) *) + 0x9100402d; (* arm_ADD X13 X1 (rvalue (word 0x10)) *) + 0xf10006b5; (* arm_SUBS X21 X21 (rvalue (word 0x1)) *) 0x3875682f; (* arm_LDRB W15 X1 (Register_Offset X21) *) 0x38756a8e; (* arm_LDRB W14 X20 (Register_Offset X21) *) 0x383569af; (* arm_STRB W15 X13 (Register_Offset X21) *) 0x3835682e; (* arm_STRB W14 X1 (Register_Offset X21) *) - 0x54ffff6c; (* arm_BGT (word 2097132) *) + 0x54ffff6c; (* arm_BGT (word 0x1fffec) *) 0x4c40703a; (* arm_LDR Q26 X1 No_Offset *) - 0x6e261f5a; (* arm_EOR_VEC Q26 Q26 Q6 128 *) - 0xb940f0e6; (* arm_LDR W6 X7 (Immediate_Offset (word 240)) *) - 0x4cdf70e0; (* arm_LDR Q0 X7 (Postimmediate_Offset (word 16)) *) - 0x510008c6; (* arm_SUB W6 W6 (rvalue (word 2)) *) - 0x4cdf70e1; (* arm_LDR Q1 X7 (Postimmediate_Offset (word 16)) *) + 0x6e261f5a; (* arm_EOR_VEC Q26 Q26 Q6 0x80 *) + 0xb940f0e6; (* arm_LDR W6 X7 (Immediate_Offset (word 0xf0)) *) + 0x4cdf70e0; (* arm_LDR Q0 X7 (Postimmediate_Offset (word 0x10)) *) + 0x510008c6; (* arm_SUB W6 W6 (rvalue (word 0x2)) *) + 0x4cdf70e1; (* arm_LDR Q1 X7 (Postimmediate_Offset (word 0x10)) *) 0x4e28581a; (* arm_AESD Q26 Q0 *) 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) - 0x4cdf78e0; (* arm_LDR Q0 X7 (Postimmediate_Offset (word 16)) *) - 0x710008c6; (* arm_SUBS W6 W6 (rvalue (word 2)) *) + 0x4cdf78e0; (* arm_LDR Q0 X7 (Postimmediate_Offset (word 0x10)) *) + 0x710008c6; (* arm_SUBS W6 W6 (rvalue (word 0x2)) *) 0x4e28583a; (* arm_AESD Q26 Q1 *) 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) - 0x4cdf78e1; (* arm_LDR Q1 X7 (Postimmediate_Offset (word 16)) *) - 0x54ffff2c; (* arm_BGT (word 2097124) *) + 0x4cdf78e1; (* arm_LDR Q1 X7 (Postimmediate_Offset (word 0x10)) *) + 0x54ffff2c; (* arm_BGT (word 0x1fffe4) *) 0x4e28581a; (* arm_AESD Q26 Q0 *) 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) 0x4c4078e0; (* arm_LDR Q0 X7 No_Offset *) 0x4e28583a; (* arm_AESD Q26 Q1 *) - 0x6e201f5a; (* arm_EOR_VEC Q26 Q26 Q0 128 *) - 0x6e261f5a; (* arm_EOR_VEC Q26 Q26 Q6 128 *) + 0x6e201f5a; (* arm_EOR_VEC Q26 Q26 Q0 0x80 *) + 0x6e261f5a; (* arm_EOR_VEC Q26 Q26 Q6 0x80 *) 0x4c00703a; (* arm_STR Q26 X1 No_Offset *) - 0x6d4027e8; (* arm_LDP D8 D9 SP (Immediate_Offset (iword (&0))) *) - 0x6d412fea; (* arm_LDP D10 D11 SP (Immediate_Offset (iword (&16))) *) - 0xa94253f3; (* arm_LDP X19 X20 SP (Immediate_Offset (iword (&32))) *) - 0xa9435bf5; (* arm_LDP X21 X22 SP (Immediate_Offset (iword (&48))) *) - 0x910103ff; (* arm_ADD SP SP (rvalue (word 64)) *) + 0x6d4027e8; (* arm_LDP D8 D9 SP (Immediate_Offset (iword (&0x0))) *) + 0x6d412fea; (* arm_LDP D10 D11 SP (Immediate_Offset (iword (&0x10))) *) + 0xa94253f3; (* arm_LDP X19 X20 SP (Immediate_Offset (iword (&0x20))) *) + 0xa9435bf5; (* arm_LDP X21 X22 SP (Immediate_Offset (iword (&0x30))) *) + 0x910103ff; (* arm_ADD SP SP (rvalue (word 0x40)) *) 0xd65f03c0 (* arm_RET X30 *) ];; @@ -794,7 +781,7 @@ let AES_XTS_DECRYPT_CORRECT = prove( read(memory :> bytes128 iv_ptr) s = iv /\ set_key_schedule s key0_ptr k00 k01 k02 k03 k04 k05 k06 k07 k08 k09 k0a k0b k0c k0d k0e /\ set_key_schedule s key1_ptr k10 k11 k12 k13 k14 k15 k16 k17 k18 k19 k1a k1b k1c k1d k1e) - (\s. read PC s = word (pc + 0xb04) /\ + (\s. read PC s = word (pc + 0xad0) /\ read(memory :> bytes128 pt_ptr) s = aes256_xts_decrypt_1block ib iv [k00; k01; k02; k03; k04; k05; k06; k07; k08; k09; k0a; k0b; k0c; k0d; k0e] @@ -819,12 +806,12 @@ let AES_XTS_DECRYPT_CORRECT = prove( ANTS_TAC THENL [ASM_REWRITE_TAC[] THEN AESENC_TAC; DISCH_TAC] THEN (* Simulating until finish decrypting one block *) - ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (65--118) THEN + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (65--117) THEN FIRST_X_ASSUM(MP_TAC o SPEC `(aes256_xts_decrypt_1block ib iv [k00; k01; k02; k03; k04; k05; k06; k07; k08; k09; k0a; k0b; k0c; k0d; k0e] [k10; k11; k12; k13; k14; k15; k16; k17; k18; k19; k1a; k1b; k1c; k1d; k1e]):int128` - o MATCH_MP (MESON[] `read Q24 s = a ==> !a'. a = a' ==> read Q24 s = a'`)) THEN + o MATCH_MP (MESON[] `read Q0 s = a ==> !a'. a = a' ==> read Q0 s = a'`)) THEN ANTS_TAC THENL [ REWRITE_TAC [aes256_xts_decrypt_1block] THEN REWRITE_TAC [xts_init_tweak] THEN @@ -834,6 +821,6 @@ let AES_XTS_DECRYPT_CORRECT = prove( AESDEC_TAC; DISCH_TAC] THEN (* Simulate to the end *) - ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (119--130) THEN + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (118--129) THEN ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC [] );; From 70a24e0a9cfdb6b0641f530bf70bc349506fe5fe Mon Sep 17 00:00:00 2001 From: Yan Peng Date: Tue, 22 Jul 2025 23:40:11 +0000 Subject: [PATCH 023/132] WIP: define XTS full specification --- arm/proofs/aes_xts_decrypt_spec.ml | 144 +++++++++++++++++++++++++++++ 1 file changed, 144 insertions(+) diff --git a/arm/proofs/aes_xts_decrypt_spec.ml b/arm/proofs/aes_xts_decrypt_spec.ml index a83cfdb30..592822462 100644 --- a/arm/proofs/aes_xts_decrypt_spec.ml +++ b/arm/proofs/aes_xts_decrypt_spec.ml @@ -138,3 +138,147 @@ time prove (`aes256_xts_decrypt_1block KEY1 KEY2 = word 0x0f0e0d0c0b0a09080706050403020100`, CONV_TAC(LAND_CONV XTSDEC_1BLOCK_HELPER_CONV) THEN REFL_TAC);; *) + +(*******************************************) +(* AES-XTS decryption full *) +(* Note: the implementation sequences the calculation of the tweak + for each block, however, the specification will calculate the tweak + from the very beginning for each block. We write the specification + in the sequenced version for proof simplicity. +*) + +(* Helper functions derived from Amanda's code: + https://github.com/amanda-zx/s2n-bignum/blob/sha512/arm/sha512/sha512_specs.ml#L360 +*) +let bytes_to_int128 = define + `bytes_to_int128 (bs : byte list) : int128 = + word_join + (word_join + (word_join (word_join (EL 7 bs) (EL 6 bs) : int16) (word_join (EL 5 bs) (EL 4 bs) : int16) : int32) + (word_join (word_join (EL 3 bs) (EL 2 bs) : int16) (word_join (EL 1 bs) (EL 8 bs) : int16) : int32) : int64) + (word_join + (word_join (word_join (EL 7 bs) (EL 6 bs) : int16) (word_join (EL 5 bs) (EL 4 bs) : int16) : int32) + (word_join (word_join (EL 3 bs) (EL 2 bs) : int16) (word_join (EL 1 bs) (EL 0 bs) : int16) : int32) : int64)`;; + +let int128_to_bytes = define + `int128_to_bytes (w : int128) : byte list = + [word_subword w (0, 1); + word_subword w (1, 1); + word_subword w (2, 1); + word_subword w (3, 1); + word_subword w (4, 1); + word_subword w (5, 1); + word_subword w (6, 1); + word_subword w (7, 1); + word_subword w (8, 1); + word_subword w (9, 1); + word_subword w (10, 1); + word_subword w (11, 1); + word_subword w (12, 1); + word_subword w (13, 1); + word_subword w (14, 1); + word_subword w (15, 1)]`;; + +(* Multiplication by the primitive element \alpha in GF(2^128) *) +let GF_128_mult_by_primitive = new_definition + `GF_128_mult_by_primitive + (tweak:(128)word) = + let shifted = word_shl tweak 1 in + let mask = word_ishr tweak 127 in + word_xor (word_and mask (word 0x87)) shifted`;; + +let FST3 = define + `FST3 (x:a#b#c) = FST x`;; +let SND3 = define + `SND3 (x:a#b#c) = FST (SND x)`;; +let THD3 = define + `THD3 (x:a#b#c) = SND (SND x)`;; + +let eth = prove_general_recursive_function_exists + `?aes256_xts_decrypt_rec. + ! (i:num) (m:num) (C:byte list) (iv:int128) (key1:int128 list) (key2:int128 list). + aes256_xts_decrypt_rec i m C iv key1 key2 : (byte list)#int128#num = + if m < i then ([], iv, i) + else + let current_block = bytes_to_int128 (SUB_LIST (i * 16, 16) C) in + let curr = int128_to_bytes (aes256_xts_decrypt_round current_block iv key1) in + let iv = GF_128_mult_by_primitive iv in + let res = aes256_xts_decrypt_rec (i + 1) m C iv key1 key2 in + (APPEND curr (FST3 res), SND3 res, THD3 res)`;; + +let wfth = prove(hd(hyp eth), + EXISTS_TAC `MEASURE (\(i:num,m:num,C:byte list,iv:int128,key1:int128 list,key2:int128 list). (m + 1) - i)` THEN + REWRITE_TAC[WF_MEASURE; MEASURE] THEN ARITH_TAC);; + +let exists_lemma = PROVE_HYP wfth eth;; + +(* Note: results are stored in LSByte to MSByte *) +let aes256_xts_decrypt_rec = new_specification ["aes256_xts_decrypt_rec"] exists_lemma;; + +(* Note: last block is padded to make it suitable for int128_to_bytes *) +let cipher_stealing = new_definition + `cipher_stealing (block:int128) (tail:int128) (tail_len:num) (iv:int128) : int128#int128 = + let iv_last = GF_128_mult_by_primitive iv in + let PP = aes256_xts_decrypt_round block iv_last key1 in + let Pm = word_subword PP (0, tail_len) in + let CP = word_subword PP (tail_len, 16 - tail_len) in + let CC = word_join (word_subword tail (0,tail_len)) CP in + let Pm1 = aes256_xts_decrypt_round CC iv key1 in + (Pm1, (word_zx Pm))`;; + +(* Depending on the tail, either do one block decryption or do cipher stealing *) +let aes256_xts_decrypt_tail = new_definition + `aes256_xts_decrypt_tail (i:num) (m:num) (tail:num) + (C:byte list) (iv:int128) (key1:int128 list) (key2:int128 list) : byte list = + if tail = 0 then + let Cm1 = bytes_to_int128 (SUB_LIST (i * 16, 16) C) in + int128_to_bytes (aes256_xts_decrypt_round Cm1 iv key1) + else + let Cm1 = bytes_to_int128 (SUB_LIST (i * 16, 16) C) in + let padded_tail = APPEND (SUB_LIST ((i + 1) * 16, tail) C) (REPLICATE (16 - tail) (word 0)) in + let Ctail = bytes_to_int128 padded_tail in + + let res_cs = cipher_stealing Cm1 Ctail tail iv in + let Pm1 = int128_to_bytes (FST res_cs) in + let Ptail = SUB_LIST (0, tail) (int128_to_bytes (SND res_cs)) in + APPEND Pm1 Ptail`;; + +(* The main decryption function *) +(* Note: the specification does not handle the case of len < 16, which is + handled in the implementation. *) + +(* AES256-XTS assumes there is at least one block in input *) +(* + C: Input ciphertext represented as a byte list + len: Length of C + iv: Initialization vector (tweak) as an int128 + key1: Key schedule for AES-256 decryption + key2: Key schedule for AES-256 encryption for the tweak + P_error: Error output plaintext in case of invalid input length + + return: Output plaintext as a byte list + + When input len < 16, the function returns P_error, + which will be the initial value stored in output address. +*) +(* TODO: Challenge lemma: proving that the output is of same length as input *) +(* TODO: Double check if NIST spec talks about the error case len < 16 *) +(* TODO: Double check the pseudo code in the spec for tweak caculation in ANEX c *) +let aes256_xts_decrypt = new_definition + `aes256_xts_decrypt + (C:byte list) (len:num) (iv:int128) (key1:int128 list) (key2:int128 list) (P_error:byte list) : byte list = + if len < 16 then + P_error + else + let tail = len MOD 16 in + let m = (len - tail) DIV 16 in + let i = 0 in + + let iv = xts_init_tweak iv key2 in + if m < 2 then + aes256_xts_decrypt_tail i m tail C iv key1 key2 + else + let res = aes256_xts_decrypt_rec 0 (m - 2) C iv key1 key2 in + let Ptail = aes256_xts_decrypt_tail (THD3 res) m tail C (SND3 res) key1 key2 in + APPEND (FST3 res) Ptail`;; + `;; From 31fccb6c655d2253f2301574d9c5d068e7ed97d1 Mon Sep 17 00:00:00 2001 From: Yan Peng Date: Fri, 25 Jul 2025 05:14:51 -0700 Subject: [PATCH 024/132] Experiment with conversions --- arm/proofs/aes_xts_decrypt_spec.ml | 45 +++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/arm/proofs/aes_xts_decrypt_spec.ml b/arm/proofs/aes_xts_decrypt_spec.ml index 592822462..66af05c6e 100644 --- a/arm/proofs/aes_xts_decrypt_spec.ml +++ b/arm/proofs/aes_xts_decrypt_spec.ml @@ -139,6 +139,21 @@ time prove (`aes256_xts_decrypt_1block CONV_TAC(LAND_CONV XTSDEC_1BLOCK_HELPER_CONV) THEN REFL_TAC);; *) +(* Compute not working, takes longer time than hand written conv *) +needs "Library/words.ml";; +let rw = Compute.bool_compset();; +word_compute_add_convs rw;; +num_compute_add_convs rw;; +Compute.add_thms [aes256_xts_decrypt_1block;aes256_xts_decrypt_round;xts_init_tweak; + aes256_encrypt;KEY1;KEY2;EL_CONS;LET_END_DEF;aes256_decrypt;aes_sub_bytes;aes_inv_shift_rows; + aes256_decrypt_round] rw;; +let my_conv = Compute.WEAK_CBV_CONV rw;; + +my_conv `aes256_xts_decrypt_1block + (word 0x88c87a8644e587dc7e3057edf2a80cc3) + (word 0x0000000000000000000000123456789a) + KEY1 KEY2`;; + (*******************************************) (* AES-XTS decryption full *) (* Note: the implementation sequences the calculation of the tweak @@ -281,4 +296,32 @@ let aes256_xts_decrypt = new_definition let res = aes256_xts_decrypt_rec 0 (m - 2) C iv key1 key2 in let Ptail = aes256_xts_decrypt_tail (THD3 res) m tail C (SND3 res) key1 key2 in APPEND (FST3 res) Ptail`;; - `;; + +(*******************************************) +(* Conversions *) + +let ciphertext = new_definition + `[word 0xc3; word 0x0c; word 0xa8; word 0xf2 + ; word 0xed; word 0x57; word 0x30; word 0x7e + ; word 0xdc; word 0x87; word 0xe5; word 0x44 + ; word 0x86; word 0x7a; word 0xc8; word 0x88] : byte list`;; +let iv = new_definition + `(word 0x0000000000000000000000123456789a) : int128`;; +let P_error = new_definition + `[ word 0; word 0; word 0; word 0 + ; word 0; word 0; word 0; word 0 + ; word 0; word 0; word 0; word 0 + ; word 0; word 0; word 0; word 0] : byte list`;; +let plaintext = new_definition + `[word 0x0f; word 0x0e; word 0x0d; word 0x0c + ; word 0x0b; word 0x0a; word 0x09; word 0x08 + ; word 0x07; word 0x06; word 0x05; word 0x04 + ; word 0x03; word 0x02; word 0x01; word 0x00] : byte list`;; + +let rw = Compute.bool_compset();; +word_compute_add_convs rw;; +num_compute_add_convs rw;; +Compute.add_thms [aes256_xts_decrypt;KEY1;KEY2;ciphertext;iv;P_error;plaintext] rw;; +let my_conv = Compute.WEAK_CBV_CONV rw;; + +my_conv `aes256_xts_decrypt C 16 iv KEY1 KEY2 P_error`;; \ No newline at end of file From 424ddb529cf1f145794db88bdd898808e647d1bb Mon Sep 17 00:00:00 2001 From: Yan Peng Date: Tue, 19 Aug 2025 13:06:57 -0700 Subject: [PATCH 025/132] Fix type issue in cipher stealing --- arm/proofs/aes_xts_decrypt_spec.ml | 33 ++++++++++++++---------------- 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/arm/proofs/aes_xts_decrypt_spec.ml b/arm/proofs/aes_xts_decrypt_spec.ml index 66af05c6e..430082f4e 100644 --- a/arm/proofs/aes_xts_decrypt_spec.ml +++ b/arm/proofs/aes_xts_decrypt_spec.ml @@ -81,7 +81,7 @@ out: 88c87a8644e587dc7e3057edf2a80cc3 in: 0f0e0d0c0b0a09080706050403020100 *) - let KEY1 = new_definition `KEY1:int128 list = +let KEY1 = new_definition `KEY1:int128 list = [ word 0xc70a951e84370d1836bdd387607e94e5 ; word 0x7ead95d6f74bf6b3103340cce21b473d ; word 0x298c296cdf3241d53d0757ddbebda060 @@ -230,33 +230,30 @@ let exists_lemma = PROVE_HYP wfth eth;; (* Note: results are stored in LSByte to MSByte *) let aes256_xts_decrypt_rec = new_specification ["aes256_xts_decrypt_rec"] exists_lemma;; -(* Note: last block is padded to make it suitable for int128_to_bytes *) let cipher_stealing = new_definition - `cipher_stealing (block:int128) (tail:int128) (tail_len:num) (iv:int128) : int128#int128 = + `cipher_stealing (block:byte list) (tail:byte list) (tail_len:num) (iv:int128) (key1:int128 list): (byte list)#(byte list) = let iv_last = GF_128_mult_by_primitive iv in - let PP = aes256_xts_decrypt_round block iv_last key1 in - let Pm = word_subword PP (0, tail_len) in - let CP = word_subword PP (tail_len, 16 - tail_len) in - let CC = word_join (word_subword tail (0,tail_len)) CP in - let Pm1 = aes256_xts_decrypt_round CC iv key1 in - (Pm1, (word_zx Pm))`;; + let PP = int128_to_bytes (aes256_xts_decrypt_round (bytes_to_int128 block) iv_last key1) in + let len = tail_len * 8 in + let Pm = SUB_LIST (0, tail_len) PP in + let CP = SUB_LIST (tail_len, 16 - tail_len) PP in + let CC = bytes_to_int128 (APPEND tail CP) in + let Pm1 = int128_to_bytes (aes256_xts_decrypt_round CC iv key1) in + (Pm1, Pm)`;; (* Depending on the tail, either do one block decryption or do cipher stealing *) let aes256_xts_decrypt_tail = new_definition - `aes256_xts_decrypt_tail (i:num) (m:num) (tail:num) + `aes256_xts_decrypt_tail (i:num) (m:num) (tail_len:num) (C:byte list) (iv:int128) (key1:int128 list) (key2:int128 list) : byte list = - if tail = 0 then + if tail_len = 0 then let Cm1 = bytes_to_int128 (SUB_LIST (i * 16, 16) C) in int128_to_bytes (aes256_xts_decrypt_round Cm1 iv key1) else - let Cm1 = bytes_to_int128 (SUB_LIST (i * 16, 16) C) in - let padded_tail = APPEND (SUB_LIST ((i + 1) * 16, tail) C) (REPLICATE (16 - tail) (word 0)) in - let Ctail = bytes_to_int128 padded_tail in + let Cm1 = SUB_LIST (i * 16, 16) C in + let Ctail = SUB_LIST ((i + 1) * 16, tail_len) C in - let res_cs = cipher_stealing Cm1 Ctail tail iv in - let Pm1 = int128_to_bytes (FST res_cs) in - let Ptail = SUB_LIST (0, tail) (int128_to_bytes (SND res_cs)) in - APPEND Pm1 Ptail`;; + let res_cs = cipher_stealing Cm1 Ctail tail_len iv key1 in + APPEND (FST res_cs) (SND res_cs)`;; (* The main decryption function *) (* Note: the specification does not handle the case of len < 16, which is From d981037dbd53c32577fd6390e3d67fbc585a0fbc Mon Sep 17 00:00:00 2001 From: Yan Peng Date: Wed, 20 Aug 2025 11:54:30 -0700 Subject: [PATCH 026/132] Write conversions and add tests --- arm/proofs/aes_decrypt_spec.ml | 5 +- arm/proofs/aes_encrypt_spec.ml | 5 +- arm/proofs/aes_xts_decrypt_spec.ml | 446 +++++++++++++++++++++-------- 3 files changed, 329 insertions(+), 127 deletions(-) diff --git a/arm/proofs/aes_decrypt_spec.ml b/arm/proofs/aes_decrypt_spec.ml index a8d862eed..b3a4f6b87 100644 --- a/arm/proofs/aes_decrypt_spec.ml +++ b/arm/proofs/aes_decrypt_spec.ml @@ -119,9 +119,8 @@ let EL_15_128_CLAUSES = let pat = `EL n [x0;x1;x2;x3;x4;x5;x6;x7;x8;x9;x10;x11;x12;x13;x14]:128 word` in map (fun n -> EL_CONV(subst [mk_small_numeral n,`n:num`] pat)) (0--14);; -let AESDEC_HELPER_CONV KEYS = +let AESDEC_HELPER_CONV = REWR_CONV aes256_decrypt THENC - REWRITE_CONV [KEYS] THENC REWRITE_CONV EL_15_128_CLAUSES THENC REPEATC let_CONV THENC DEPTH_CONV (WORD_RED_CONV ORELSEC NUM_RED_CONV) THENC @@ -135,5 +134,5 @@ let AESDEC_HELPER_CONV KEYS = time prove (`aes256_decrypt (word 0x8960494b9049fceabf456751cab7a28e) DEC_ROUND_KEYS = word 0xffeeddccbbaa99887766554433221100`, - CONV_TAC(LAND_CONV (AESDEC_HELPER_CONV DEC_ROUND_KEYS)) THEN REFL_TAC);; + CONV_TAC(LAND_CONV (REWRITE_CONV [DEC_ROUND_KEYS] THENC AESDEC_HELPER_CONV)) THEN REFL_TAC);; *) \ No newline at end of file diff --git a/arm/proofs/aes_encrypt_spec.ml b/arm/proofs/aes_encrypt_spec.ml index 62f320809..f1a74c4ad 100644 --- a/arm/proofs/aes_encrypt_spec.ml +++ b/arm/proofs/aes_encrypt_spec.ml @@ -150,9 +150,8 @@ let EL_15_128_CLAUSES = let pat = `EL n [x0;x1;x2;x3;x4;x5;x6;x7;x8;x9;x10;x11;x12;x13;x14]:128 word` in map (fun n -> EL_CONV(subst [mk_small_numeral n,`n:num`] pat)) (0--14);; -let AESENC_HELPER_CONV KEYS = +let AESENC_HELPER_CONV = REWRITE_CONV [aes256_encrypt] THENC - REWRITE_CONV [KEYS] THENC REWRITE_CONV EL_15_128_CLAUSES THENC REPEATC let_CONV THENC DEPTH_CONV (WORD_RED_CONV ORELSEC NUM_RED_CONV) THENC @@ -165,5 +164,5 @@ let AESENC_HELPER_CONV KEYS = time prove (`aes256_encrypt (word 0x2A179373117E3DE9969F402EE2BEC16B) ROUND_KEYS = word 0xF881B13D7E5A4B063CA0D2B5BDD1EEF3`, - CONV_TAC(LAND_CONV AESENC_HELPER_CONV) THEN REFL_TAC);; + CONV_TAC(LAND_CONV (REWRITE_CONV [ROUND_KEYS] THENC AESENC_HELPER_CONV)) THEN REFL_TAC);; *) diff --git a/arm/proofs/aes_xts_decrypt_spec.ml b/arm/proofs/aes_xts_decrypt_spec.ml index 430082f4e..d2cd6775e 100644 --- a/arm/proofs/aes_xts_decrypt_spec.ml +++ b/arm/proofs/aes_xts_decrypt_spec.ml @@ -8,37 +8,6 @@ let pp_print_num fmt tm = pp_print_string fmt (string_of_num_hex n) in install_user_printer("pp_print_num",pp_print_num);; -(* -IEEE Standard for Cryptographic Protection of -Data on Block-Oriented Storage Devices -https://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=8637988 - -Section 5.4.1 - -a) T ← AES-enc(Key2, i) ⊗ αj -b) CC ← C ⊕ T -c) PP ← AES-dec(Key1, CC) -d) P ← PP ⊕ T - -*) - -let xts_init_tweak = new_definition - `xts_init_tweak (iv:int128) (key_schedule:int128 list) = - aes256_encrypt iv key_schedule`;; - -let aes256_xts_decrypt_round = new_definition - `aes256_xts_decrypt_round (C:int128) (tk:int128) (key_schedule:int128 list) = - let CC = word_xor C tk in - let PP = aes256_decrypt CC key_schedule in - word_xor PP tk`;; - -let aes256_xts_decrypt_1block = new_definition - `aes256_xts_decrypt_1block - (C:int128) (iv:int128) (key1:int128 list) (key2:int128 list) = - let tk = xts_init_tweak iv key2 in - aes256_xts_decrypt_round C tk key1`;; - - (* Test vector: key1: c70a951e84370d1836bdd387607e94e5 @@ -74,12 +43,40 @@ c26c685728b9a2356d1ecd82358affbf 4d05c122ade7966a94e4658247817701 21a29367e3cefb30cb775905a6699487 +1 block iv: 0000000000000000000000123456789a - out: 88c87a8644e587dc7e3057edf2a80cc3 - in: 0f0e0d0c0b0a09080706050403020100 - *) + +1 block + 6 bytes +iv: 0000000000000000000000123456789a +out: 57edf2a80cc389a4b92cde579f93da9ae5cc8b18e875 +in: 1514131211100f0e0d0c0b0a0908070605040302010 + +3 blocks + 3 bytes +iv: 0000000000000000000000123456789a +out: 41c2e1e4a22c106ace4c926e3725aa6877a4be5b7b62cb514595696240d72889208c3488c87a8644e587dc7e3057edf2a80cc3 +in: 3231302f2e2d2c2b2a292827262524232221201f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100 + +*) + +let ciphertext = new_definition + `ciphertext = [word 0xc3; word 0x0c; word 0xa8; word 0xf2 + ; word 0xed; word 0x57; word 0x30; word 0x7e + ; word 0xdc; word 0x87; word 0xe5; word 0x44 + ; word 0x86; word 0x7a; word 0xc8; word 0x88] : byte list`;; +let iv_tweak = new_definition + `iv_tweak = (word 0x0000000000000000000000123456789a) : int128`;; +let perror = new_definition + `perorr = [ word 0; word 0; word 0; word 0 + ; word 0; word 0; word 0; word 0 + ; word 0; word 0; word 0; word 0 + ; word 0; word 0; word 0; word 0] : byte list`;; +let plaintext = new_definition + `plaintext = [word 0x0f; word 0x0e; word 0x0d; word 0x0c + ; word 0x0b; word 0x0a; word 0x09; word 0x08 + ; word 0x07; word 0x06; word 0x05; word 0x04 + ; word 0x03; word 0x02; word 0x01; word 0x00] : byte list`;; let KEY1 = new_definition `KEY1:int128 list = [ word 0xc70a951e84370d1836bdd387607e94e5 @@ -117,19 +114,57 @@ let KEY2 = new_definition `KEY2:int128 list = ; word 0x21a29367e3cefb30cb775905a6699487 ]`;; +(* +IEEE Standard for Cryptographic Protection of +Data on Block-Oriented Storage Devices +https://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=8637988 + +Section 5.4.1 + +a) T ← AES-enc(Key2, i) ⊗ αj +b) CC ← C ⊕ T +c) PP ← AES-dec(Key1, CC) +d) P ← PP ⊕ T + +*) + +let xts_init_tweak = new_definition + `xts_init_tweak (iv:int128) (key_schedule:int128 list) = + aes256_encrypt iv key_schedule`;; + +let XTS_INIT_TWEAK_CONV = + REWR_CONV xts_init_tweak THENC AESENC_HELPER_CONV;; + +(REWRITE_CONV [iv_tweak;KEY2] THENC XTS_INIT_TWEAK_CONV) `xts_init_tweak iv_tweak KEY2`;; + +let aes256_xts_decrypt_round = new_definition + `aes256_xts_decrypt_round (C:int128) (tk:int128) (key_schedule:int128 list) = + let CC = word_xor C tk in + let PP = aes256_decrypt CC key_schedule in + word_xor PP tk`;; + +let AES256_XTS_DECRYPT_ROUND_CONV = + REWRITE_CONV [aes256_xts_decrypt_round] THENC + SUBLET_CONV WORD_RED_CONV THENC + let_CONV THENC + SUBLET_CONV AESDEC_HELPER_CONV THENC + let_CONV THENC WORD_RED_CONV;; + +(* (REWRITE_CONV [iv_tweak; KEY2] THENC AES256_XTS_DECRYPT_ROUND_CONV) + `aes256_xts_decrypt_round iv_tweak iv_tweak KEY2`;; *) + +let aes256_xts_decrypt_1block = new_definition + `aes256_xts_decrypt_1block + (C:int128) (iv:int128) (key1:int128 list) (key2:int128 list) = + let tk = xts_init_tweak iv key2 in + aes256_xts_decrypt_round C tk key1`;; + let XTSDEC_1BLOCK_HELPER_CONV = REWR_CONV aes256_xts_decrypt_1block THENC REWRITE_CONV [xts_init_tweak] THENC - SUBLET_CONV (AESENC_HELPER_CONV KEY2) THENC - let_CONV THENC - REWRITE_CONV [aes256_xts_decrypt_round] THENC - SUBLET_CONV (DEPTH_CONV (WORD_RED_CONV ORELSEC NUM_RED_CONV)) THENC - PRINT_TERM_CONV THENC - let_CONV THENC - SUBLET_CONV (AESDEC_HELPER_CONV KEY1) THENC + SUBLET_CONV AESENC_HELPER_CONV THENC let_CONV THENC - DEPTH_CONV (WORD_RED_CONV ORELSEC NUM_RED_CONV) - ;; + AES256_XTS_DECRYPT_ROUND_CONV;; (*162 seconds time prove (`aes256_xts_decrypt_1block @@ -139,21 +174,6 @@ time prove (`aes256_xts_decrypt_1block CONV_TAC(LAND_CONV XTSDEC_1BLOCK_HELPER_CONV) THEN REFL_TAC);; *) -(* Compute not working, takes longer time than hand written conv *) -needs "Library/words.ml";; -let rw = Compute.bool_compset();; -word_compute_add_convs rw;; -num_compute_add_convs rw;; -Compute.add_thms [aes256_xts_decrypt_1block;aes256_xts_decrypt_round;xts_init_tweak; - aes256_encrypt;KEY1;KEY2;EL_CONS;LET_END_DEF;aes256_decrypt;aes_sub_bytes;aes_inv_shift_rows; - aes256_decrypt_round] rw;; -let my_conv = Compute.WEAK_CBV_CONV rw;; - -my_conv `aes256_xts_decrypt_1block - (word 0x88c87a8644e587dc7e3057edf2a80cc3) - (word 0x0000000000000000000000123456789a) - KEY1 KEY2`;; - (*******************************************) (* AES-XTS decryption full *) (* Note: the implementation sequences the calculation of the tweak @@ -169,30 +189,52 @@ let bytes_to_int128 = define `bytes_to_int128 (bs : byte list) : int128 = word_join (word_join - (word_join (word_join (EL 7 bs) (EL 6 bs) : int16) (word_join (EL 5 bs) (EL 4 bs) : int16) : int32) - (word_join (word_join (EL 3 bs) (EL 2 bs) : int16) (word_join (EL 1 bs) (EL 8 bs) : int16) : int32) : int64) + (word_join (word_join (EL 15 bs) (EL 14 bs) : int16) (word_join (EL 13 bs) (EL 12 bs) : int16) : int32) + (word_join (word_join (EL 11 bs) (EL 10 bs) : int16) (word_join (EL 9 bs) (EL 8 bs) : int16) : int32) : int64) (word_join (word_join (word_join (EL 7 bs) (EL 6 bs) : int16) (word_join (EL 5 bs) (EL 4 bs) : int16) : int32) (word_join (word_join (EL 3 bs) (EL 2 bs) : int16) (word_join (EL 1 bs) (EL 0 bs) : int16) : int32) : int64)`;; +let EL_16_8_CLAUSES = + let pat = `EL n [x0;x1;x2;x3;x4;x5;x6;x7;x8;x9;x10;x11;x12;x13;x14;x15]:byte` in + map (fun n -> EL_CONV(subst [mk_small_numeral n,`n:num`] pat)) (0--15);; + +let BYTES_TO_INT128_CONV = + REWRITE_CONV [bytes_to_int128] THENC + REWRITE_CONV EL_16_8_CLAUSES THENC + DEPTH_CONV WORD_RED_CONV;; + +BYTES_TO_INT128_CONV `bytes_to_int128 + [word 0x0f; word 0x0e; word 0x0d; word 0x0c + ; word 0x0b; word 0x0a; word 0x09; word 0x08 + ; word 0x07; word 0x06; word 0x05; word 0x04 + ; word 0x03; word 0x02; word 0x01; word 0x00]`;; + let int128_to_bytes = define `int128_to_bytes (w : int128) : byte list = - [word_subword w (0, 1); - word_subword w (1, 1); - word_subword w (2, 1); - word_subword w (3, 1); - word_subword w (4, 1); - word_subword w (5, 1); - word_subword w (6, 1); - word_subword w (7, 1); - word_subword w (8, 1); - word_subword w (9, 1); - word_subword w (10, 1); - word_subword w (11, 1); - word_subword w (12, 1); - word_subword w (13, 1); - word_subword w (14, 1); - word_subword w (15, 1)]`;; + [word_subword w (0, 8); + word_subword w (8, 8); + word_subword w (16, 8); + word_subword w (24, 8); + word_subword w (32, 8); + word_subword w (40, 8); + word_subword w (48, 8); + word_subword w (56, 8); + word_subword w (64, 8); + word_subword w (72, 8); + word_subword w (80, 8); + word_subword w (88, 8); + word_subword w (96, 8); + word_subword w (104, 8); + word_subword w (112, 8); + word_subword w (120, 8)]`;; + +let INT128_TO_BYTES_CONV = + REWRITE_CONV [int128_to_bytes] THENC + DEPTH_CONV WORD_RED_CONV;; + +INT128_TO_BYTES_CONV `int128_to_bytes (word 0x0102030405060708090a0b0c0d0e0f)`;; + (* Multiplication by the primitive element \alpha in GF(2^128) *) let GF_128_mult_by_primitive = new_definition @@ -202,27 +244,31 @@ let GF_128_mult_by_primitive = new_definition let mask = word_ishr tweak 127 in word_xor (word_and mask (word 0x87)) shifted`;; -let FST3 = define - `FST3 (x:a#b#c) = FST x`;; -let SND3 = define - `SND3 (x:a#b#c) = FST (SND x)`;; -let THD3 = define - `THD3 (x:a#b#c) = SND (SND x)`;; +let GF_128_MULT_BY_PRIMITIVE_CONV = + REWRITE_CONV [GF_128_mult_by_primitive] THENC + REPEATC let_CONV THENC + DEPTH_CONV WORD_RED_CONV;; + +GF_128_MULT_BY_PRIMITIVE_CONV `GF_128_mult_by_primitive (word 0xffffffffffffffffffffffffffffffff)`;; + +let FST3 = define `FST3 (x:a#b#c) = FST x`;; +let SND3 = define `SND3 (x:a#b#c) = FST (SND x)`;; +let THD3 = define `THD3 (x:a#b#c) = SND (SND x)`;; let eth = prove_general_recursive_function_exists `?aes256_xts_decrypt_rec. - ! (i:num) (m:num) (C:byte list) (iv:int128) (key1:int128 list) (key2:int128 list). - aes256_xts_decrypt_rec i m C iv key1 key2 : (byte list)#int128#num = + ! (i:num) (m:num) (C:byte list) (iv:int128) (key1:int128 list). + aes256_xts_decrypt_rec i m C iv key1 : (byte list)#int128#num = if m < i then ([], iv, i) else let current_block = bytes_to_int128 (SUB_LIST (i * 16, 16) C) in let curr = int128_to_bytes (aes256_xts_decrypt_round current_block iv key1) in let iv = GF_128_mult_by_primitive iv in - let res = aes256_xts_decrypt_rec (i + 1) m C iv key1 key2 in + let res = aes256_xts_decrypt_rec (i + 1) m C iv key1 in (APPEND curr (FST3 res), SND3 res, THD3 res)`;; let wfth = prove(hd(hyp eth), - EXISTS_TAC `MEASURE (\(i:num,m:num,C:byte list,iv:int128,key1:int128 list,key2:int128 list). (m + 1) - i)` THEN + EXISTS_TAC `MEASURE (\(i:num,m:num,C:byte list,iv:int128,key1:int128 list). (m + 1) - i)` THEN REWRITE_TAC[WF_MEASURE; MEASURE] THEN ARITH_TAC);; let exists_lemma = PROVE_HYP wfth eth;; @@ -230,21 +276,68 @@ let exists_lemma = PROVE_HYP wfth eth;; (* Note: results are stored in LSByte to MSByte *) let aes256_xts_decrypt_rec = new_specification ["aes256_xts_decrypt_rec"] exists_lemma;; +let rec AES256_XTS_DECRYPT_REC_CONV tm = + let BASE_CONV = + REWR_CONV aes256_xts_decrypt_rec THENC + DEPTH_CONV NUM_RED_CONV in + let INDUCT_CONV = + REWR_CONV aes256_xts_decrypt_rec THENC + DEPTH_CONV NUM_RED_CONV THENC + ONCE_DEPTH_CONV SUB_LIST_CONV THENC + ONCE_DEPTH_CONV BYTES_TO_INT128_CONV THENC let_CONV THENC + SUBLET_CONV (RAND_CONV AES256_XTS_DECRYPT_ROUND_CONV) THENC + SUBLET_CONV INT128_TO_BYTES_CONV THENC let_CONV THENC + SUBLET_CONV GF_128_MULT_BY_PRIMITIVE_CONV THENC let_CONV THENC + SUBLET_CONV AES256_XTS_DECRYPT_REC_CONV THENC let_CONV THENC + REWRITE_CONV [FST3;SND3;THD3;APPEND] in + match tm with + | Comb + (Comb + (Comb + (Comb + (Comb (Const ("aes256_xts_decrypt_rec", _), i), m), + _), + _), + _) -> + if dest_numeral m failwith "AES256_XTS_DECRYPT_REC_CONV: inapplicable";; + +(REWRITE_CONV [iv_tweak;KEY1;KEY2;ciphertext] THENC AES256_XTS_DECRYPT_REC_CONV) + `aes256_xts_decrypt_rec 0 0 ciphertext iv_tweak KEY1`;; + let cipher_stealing = new_definition - `cipher_stealing (block:byte list) (tail:byte list) (tail_len:num) (iv:int128) (key1:int128 list): (byte list)#(byte list) = + `cipher_stealing (block:byte list) (tail:byte list) (tail_len:num) + (iv:int128) (key1:int128 list): (byte list)#(byte list) = let iv_last = GF_128_mult_by_primitive iv in let PP = int128_to_bytes (aes256_xts_decrypt_round (bytes_to_int128 block) iv_last key1) in - let len = tail_len * 8 in let Pm = SUB_LIST (0, tail_len) PP in let CP = SUB_LIST (tail_len, 16 - tail_len) PP in let CC = bytes_to_int128 (APPEND tail CP) in let Pm1 = int128_to_bytes (aes256_xts_decrypt_round CC iv key1) in (Pm1, Pm)`;; +let CIPHER_STEALING_CONV = + REWRITE_CONV [cipher_stealing] THENC + SUBLET_CONV GF_128_MULT_BY_PRIMITIVE_CONV THENC let_CONV THENC + SUBLET_CONV (ONCE_DEPTH_CONV BYTES_TO_INT128_CONV) THENC + SUBLET_CONV (RAND_CONV AES256_XTS_DECRYPT_ROUND_CONV) THENC + SUBLET_CONV INT128_TO_BYTES_CONV THENC let_CONV THENC + SUBLET_CONV SUB_LIST_CONV THENC let_CONV THENC + SUBLET_CONV (DEPTH_CONV NUM_RED_CONV) THENC (* For evaluating 16 - tail_len *) + SUBLET_CONV SUB_LIST_CONV THENC let_CONV THENC + SUBLET_CONV (ONCE_DEPTH_CONV (REWRITE_CONV [APPEND])) THENC + SUBLET_CONV BYTES_TO_INT128_CONV THENC let_CONV THENC + SUBLET_CONV (RAND_CONV AES256_XTS_DECRYPT_ROUND_CONV) THENC + SUBLET_CONV INT128_TO_BYTES_CONV THENC let_CONV;; + +(REWRITE_CONV [ciphertext;iv_tweak;KEY1] THENC CIPHER_STEALING_CONV) + `cipher_stealing ciphertext [(word 0x0)] 1 iv_tweak KEY1`;; + (* Depending on the tail, either do one block decryption or do cipher stealing *) let aes256_xts_decrypt_tail = new_definition - `aes256_xts_decrypt_tail (i:num) (m:num) (tail_len:num) - (C:byte list) (iv:int128) (key1:int128 list) (key2:int128 list) : byte list = + `aes256_xts_decrypt_tail (i:num) (tail_len:num) (C:byte list) (iv:int128) (key1:int128 list) : byte list = if tail_len = 0 then let Cm1 = bytes_to_int128 (SUB_LIST (i * 16, 16) C) in int128_to_bytes (aes256_xts_decrypt_round Cm1 iv key1) @@ -255,6 +348,47 @@ let aes256_xts_decrypt_tail = new_definition let res_cs = cipher_stealing Cm1 Ctail tail_len iv key1 in APPEND (FST res_cs) (SND res_cs)`;; +let AES256_XTS_DECRYPT_TAIL_CONV tm = + let ONE_BLOCK_CONV = + REWR_CONV aes256_xts_decrypt_tail THENC + DEPTH_CONV NUM_RED_CONV THENC + SUBLET_CONV (RAND_CONV SUB_LIST_CONV) THENC + SUBLET_CONV BYTES_TO_INT128_CONV THENC let_CONV THENC + RAND_CONV AES256_XTS_DECRYPT_ROUND_CONV THENC + INT128_TO_BYTES_CONV in + let ONE_BLOCK_AND_TAIL_CONV = + REWR_CONV aes256_xts_decrypt_tail THENC + DEPTH_CONV NUM_RED_CONV THENC + SUBLET_CONV SUB_LIST_CONV THENC let_CONV THENC + SUBLET_CONV SUB_LIST_CONV THENC let_CONV THENC + SUBLET_CONV CIPHER_STEALING_CONV THENC let_CONV THENC + REWRITE_CONV [FST;SND] THENC REWRITE_CONV [APPEND] in + match tm with + | Comb + (Comb + (Comb + (Comb + (Comb + (Const ("aes256_xts_decrypt_tail", _), _), tail_len), + _), + _), + _) -> + if dest_numeral tail_len =/ num 0 + then ONE_BLOCK_CONV tm + else ONE_BLOCK_AND_TAIL_CONV tm + | _ -> failwith "AES256_XTS_DECRYPT_TAIL_CONV: inapplicable";; + +(REWRITE_CONV [ciphertext;iv_tweak;KEY1;KEY2] THENC AES256_XTS_DECRYPT_TAIL_CONV) + `aes256_xts_decrypt_tail 0 0 ciphertext iv_tweak KEY1`;; + +(REWRITE_CONV [iv_tweak;KEY1;KEY2] THENC AES256_XTS_DECRYPT_TAIL_CONV) +`aes256_xts_decrypt_tail 0 1 + [word 0xc3; word 0x0c; word 0xa8; word 0xf2 + ; word 0xed; word 0x57; word 0x30; word 0x7e + ; word 0xdc; word 0x87; word 0xe5; word 0x44 + ; word 0x86; word 0x7a; word 0xc8; word 0x88; word 0x00] + iv_tweak KEY1`;; + (* The main decryption function *) (* Note: the specification does not handle the case of len < 16, which is handled in the implementation. *) @@ -266,21 +400,21 @@ let aes256_xts_decrypt_tail = new_definition iv: Initialization vector (tweak) as an int128 key1: Key schedule for AES-256 decryption key2: Key schedule for AES-256 encryption for the tweak - P_error: Error output plaintext in case of invalid input length + perror: Error output plaintext in case of invalid input length return: Output plaintext as a byte list - When input len < 16, the function returns P_error, + When input len < 16, the function returns perror, which will be the initial value stored in output address. *) (* TODO: Challenge lemma: proving that the output is of same length as input *) -(* TODO: Double check if NIST spec talks about the error case len < 16 *) +(* TODO: Double check if IEEE and NIST spec talks about the error case len < 16 *) (* TODO: Double check the pseudo code in the spec for tweak caculation in ANEX c *) let aes256_xts_decrypt = new_definition `aes256_xts_decrypt - (C:byte list) (len:num) (iv:int128) (key1:int128 list) (key2:int128 list) (P_error:byte list) : byte list = + (C:byte list) (len:num) (iv:int128) (key1:int128 list) (key2:int128 list) (perror:byte list) : byte list = if len < 16 then - P_error + perror else let tail = len MOD 16 in let m = (len - tail) DIV 16 in @@ -288,37 +422,107 @@ let aes256_xts_decrypt = new_definition let iv = xts_init_tweak iv key2 in if m < 2 then - aes256_xts_decrypt_tail i m tail C iv key1 key2 + aes256_xts_decrypt_tail i tail C iv key1 else - let res = aes256_xts_decrypt_rec 0 (m - 2) C iv key1 key2 in - let Ptail = aes256_xts_decrypt_tail (THD3 res) m tail C (SND3 res) key1 key2 in + let res = aes256_xts_decrypt_rec 0 (m - 2) C iv key1 in + let Ptail = aes256_xts_decrypt_tail (THD3 res) tail C (SND3 res) key1 in APPEND (FST3 res) Ptail`;; +let AES256_XTS_DECRYPT_CONV tm = + let ERROR_CONV = + REWR_CONV aes256_xts_decrypt THENC + DEPTH_CONV NUM_RED_CONV in + let MORE_THAN_2_CONV = + REWRITE_CONV [FST3;SND3;THD3] THENC + SUBLET_CONV AES256_XTS_DECRYPT_REC_CONV THENC let_CONV THENC + SUBLET_CONV AES256_XTS_DECRYPT_TAIL_CONV THENC let_CONV THENC + REWRITE_CONV [APPEND] in + let BODY_CONV = + REWR_CONV aes256_xts_decrypt THENC + DEPTH_CONV NUM_RED_CONV THENC let_CONV THENC + DEPTH_CONV NUM_RED_CONV THENC let_CONV THENC let_CONV THENC + SUBLET_CONV XTS_INIT_TWEAK_CONV THENC let_CONV THENC + DEPTH_CONV NUM_RED_CONV THENC + (AES256_XTS_DECRYPT_TAIL_CONV ORELSEC MORE_THAN_2_CONV) in + match tm with + | Comb + (Comb + (Comb + (Comb + (Comb + (Comb + (Const ("aes256_xts_decrypt", _), _), len), + _), + _), + _), + _) -> + if dest_numeral len failwith "AES256_XTS_DECRYPT_CONV: inapplicable";; + + +(* TODO: figure out why perror isn't expanded out ??*) +(REWRITE_CONV [perror] THENC AES256_XTS_DECRYPT_CONV) + `aes256_xts_decrypt ciphertext 5 iv_tweak KEY1 KEY2 perror`;; + +(REWRITE_CONV [ciphertext;iv_tweak;KEY1;KEY2;perror] THENC AES256_XTS_DECRYPT_CONV) + `aes256_xts_decrypt ciphertext 16 iv_tweak KEY1 KEY2 perror`;; + +(* 165 seconds *) +time (REWRITE_CONV [iv_tweak;KEY1;KEY2;perror] THENC AES256_XTS_DECRYPT_CONV) + `aes256_xts_decrypt [word 0xc3; word 0x0c; word 0xa8; word 0xf2 + ; word 0xed; word 0x57; word 0x30; word 0x7e + ; word 0xdc; word 0x87; word 0xe5; word 0x44 + ; word 0x86; word 0x7a; word 0xc8; word 0x88 + ; word 0xc3; word 0x0c; word 0xa8; word 0xf2 + ; word 0xed; word 0x57; word 0x30; word 0x7e + ; word 0xdc; word 0x87; word 0xe5; word 0x44 + ; word 0x86; word 0x7a; word 0xc8; word 0x88 + ; word 0x00] + 33 iv_tweak KEY1 KEY2 perror`;; + (*******************************************) (* Conversions *) -let ciphertext = new_definition - `[word 0xc3; word 0x0c; word 0xa8; word 0xf2 - ; word 0xed; word 0x57; word 0x30; word 0x7e - ; word 0xdc; word 0x87; word 0xe5; word 0x44 - ; word 0x86; word 0x7a; word 0xc8; word 0x88] : byte list`;; -let iv = new_definition - `(word 0x0000000000000000000000123456789a) : int128`;; -let P_error = new_definition - `[ word 0; word 0; word 0; word 0 - ; word 0; word 0; word 0; word 0 - ; word 0; word 0; word 0; word 0 - ; word 0; word 0; word 0; word 0] : byte list`;; -let plaintext = new_definition - `[word 0x0f; word 0x0e; word 0x0d; word 0x0c - ; word 0x0b; word 0x0a; word 0x09; word 0x08 - ; word 0x07; word 0x06; word 0x05; word 0x04 - ; word 0x03; word 0x02; word 0x01; word 0x00] : byte list`;; +(*******************************************) +(* Tests *) -let rw = Compute.bool_compset();; -word_compute_add_convs rw;; -num_compute_add_convs rw;; -Compute.add_thms [aes256_xts_decrypt;KEY1;KEY2;ciphertext;iv;P_error;plaintext] rw;; -let my_conv = Compute.WEAK_CBV_CONV rw;; +(* 1 block : 81 second *) +time (REWRITE_CONV [iv_tweak;KEY1;KEY2;perror] THENC AES256_XTS_DECRYPT_CONV) + `aes256_xts_decrypt + [ word 0xc3; word 0x0c; word 0xa8; word 0xf2; + word 0xed; word 0x57; word 0x30; word 0x7e; + word 0xdc; word 0x87; word 0xe5; word 0x44; + word 0x86; word 0x7a; word 0xc8; word 0x88 ] + 16 iv_tweak KEY1 KEY2 perror`;; + +(* 1 block + 6 bytes : 121 seconds *) +time (REWRITE_CONV [iv_tweak;KEY1;KEY2;perror] THENC AES256_XTS_DECRYPT_CONV) + `aes256_xts_decrypt + [ word 0x75; word 0xe8; word 0x18; word 0x8b; + word 0xcc; word 0xe5; word 0x9a; word 0xda; + word 0x93; word 0x9f; word 0x57; word 0xde; + word 0x2c; word 0xb9; word 0xa4; word 0x89;eiifcbfhciurugujvrcfbnrlukjdrebhuklngddvufnf -my_conv `aes256_xts_decrypt C 16 iv KEY1 KEY2 P_error`;; \ No newline at end of file + word 0xc3; word 0x0c; word 0xa8; word 0xf2; + word 0xed; word 0x57 ] + 22 iv_tweak KEY1 KEY2 perror`;; + +(* 3 blocks + 3 bytes : 206 seconds *) +time (REWRITE_CONV [iv_tweak;KEY1;KEY2;perror] THENC AES256_XTS_DECRYPT_CONV) + `aes256_xts_decrypt + [ word 0xc3; word 0x0c; word 0xa8; word 0xf2; + word 0xed; word 0x57; word 0x30; word 0x7e; + word 0xdc; word 0x87; word 0xe5; word 0x44; + word 0x86; word 0x7a; word 0xc8; word 0x88; + word 0x34; word 0x8c; word 0x20; word 0x89; + word 0x28; word 0xd7; word 0x40; word 0x62; + word 0x69; word 0x95; word 0x45; word 0x51; + word 0xcb; word 0x62; word 0x7b; word 0x5b; + word 0xbe; word 0xa4; word 0x77; word 0x68; + word 0xaa; word 0x25; word 0x37; word 0x6e; + word 0x92; word 0x4c; word 0xce; word 0x6a; + word 0x10; word 0x2c; word 0xa2; word 0xe4; + word 0xe1; word 0xc2; word 0x41 ] + 51 iv_tweak KEY1 KEY2 perror`;; From ebb74f2f719a9799beaf0b82582c86a33fc69f15 Mon Sep 17 00:00:00 2001 From: Yan Peng Date: Thu, 21 Aug 2025 15:23:46 -0700 Subject: [PATCH 027/132] The ultimate clean up --- arm/proofs/aes_xts_decrypt_spec.ml | 494 +++++++++++++++-------------- 1 file changed, 260 insertions(+), 234 deletions(-) diff --git a/arm/proofs/aes_xts_decrypt_spec.ml b/arm/proofs/aes_xts_decrypt_spec.ml index d2cd6775e..036a39276 100644 --- a/arm/proofs/aes_xts_decrypt_spec.ml +++ b/arm/proofs/aes_xts_decrypt_spec.ml @@ -8,7 +8,179 @@ let pp_print_num fmt tm = pp_print_string fmt (string_of_num_hex n) in install_user_printer("pp_print_num",pp_print_num);; -(* Test vector: +(*******************************************) +(* Specification *) + +(* +IEEE Standard for Cryptographic Protection of +Data on Block-Oriented Storage Devices +https://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=8637988 + +Section 5.4.1 + +a) T ← AES-enc(Key2, i) ⊗ αj +b) CC ← C ⊕ T +c) PP ← AES-dec(Key1, CC) +d) P ← PP ⊕ T + +*) + +let xts_init_tweak = new_definition + `xts_init_tweak (iv:int128) (key_schedule:int128 list) = + aes256_encrypt iv key_schedule`;; + +let aes256_xts_decrypt_round = new_definition + `aes256_xts_decrypt_round (C:int128) (tk:int128) (key_schedule:int128 list) = + let CC = word_xor C tk in + let PP = aes256_decrypt CC key_schedule in + word_xor PP tk`;; + +let aes256_xts_decrypt_1block = new_definition + `aes256_xts_decrypt_1block + (C:int128) (iv:int128) (key1:int128 list) (key2:int128 list) = + let tk = xts_init_tweak iv key2 in + aes256_xts_decrypt_round C tk key1`;; + +(*******************************************) +(* AES-XTS decryption full *) +(* Note: the implementation sequences the calculation of the tweak + for each block, however, the specification will calculate the tweak + from the very beginning for each block. We write the specification + in the sequenced version for proof simplicity. +*) + +(* Helper functions derived from Amanda's code: + https://github.com/amanda-zx/s2n-bignum/blob/sha512/arm/sha512/sha512_specs.ml#L360 +*) +let bytes_to_int128 = define + `bytes_to_int128 (bs : byte list) : int128 = + word_join + (word_join + (word_join (word_join (EL 15 bs) (EL 14 bs) : int16) (word_join (EL 13 bs) (EL 12 bs) : int16) : int32) + (word_join (word_join (EL 11 bs) (EL 10 bs) : int16) (word_join (EL 9 bs) (EL 8 bs) : int16) : int32) : int64) + (word_join + (word_join (word_join (EL 7 bs) (EL 6 bs) : int16) (word_join (EL 5 bs) (EL 4 bs) : int16) : int32) + (word_join (word_join (EL 3 bs) (EL 2 bs) : int16) (word_join (EL 1 bs) (EL 0 bs) : int16) : int32) : int64)`;; + +let int128_to_bytes = define + `int128_to_bytes (w : int128) : byte list = + [word_subword w (0, 8); + word_subword w (8, 8); + word_subword w (16, 8); + word_subword w (24, 8); + word_subword w (32, 8); + word_subword w (40, 8); + word_subword w (48, 8); + word_subword w (56, 8); + word_subword w (64, 8); + word_subword w (72, 8); + word_subword w (80, 8); + word_subword w (88, 8); + word_subword w (96, 8); + word_subword w (104, 8); + word_subword w (112, 8); + word_subword w (120, 8)]`;; + +(* Multiplication by the primitive element \alpha in GF(2^128) *) +let GF_128_mult_by_primitive = new_definition + `GF_128_mult_by_primitive + (tweak:(128)word) = + let shifted = word_shl tweak 1 in + let mask = word_ishr tweak 127 in + word_xor (word_and mask (word 0x87)) shifted`;; + +let FST3 = define `FST3 (x:a#b#c) = FST x`;; +let SND3 = define `SND3 (x:a#b#c) = FST (SND x)`;; +let THD3 = define `THD3 (x:a#b#c) = SND (SND x)`;; + +let eth = prove_general_recursive_function_exists + `?aes256_xts_decrypt_rec. + ! (i:num) (m:num) (C:byte list) (iv:int128) (key1:int128 list). + aes256_xts_decrypt_rec i m C iv key1 : (byte list)#int128#num = + if m < i then ([], iv, i) + else + let current_block = bytes_to_int128 (SUB_LIST (i * 16, 16) C) in + let curr = int128_to_bytes (aes256_xts_decrypt_round current_block iv key1) in + let iv = GF_128_mult_by_primitive iv in + let res = aes256_xts_decrypt_rec (i + 1) m C iv key1 in + (APPEND curr (FST3 res), SND3 res, THD3 res)`;; + +let wfth = prove(hd(hyp eth), + EXISTS_TAC `MEASURE (\(i:num,m:num,C:byte list,iv:int128,key1:int128 list). (m + 1) - i)` THEN + REWRITE_TAC[WF_MEASURE; MEASURE] THEN ARITH_TAC);; + +let exists_lemma = PROVE_HYP wfth eth;; + +(* Note: results are stored in LSByte to MSByte *) +let aes256_xts_decrypt_rec = new_specification ["aes256_xts_decrypt_rec"] exists_lemma;; + +let cipher_stealing = new_definition + `cipher_stealing (block:byte list) (tail:byte list) (tail_len:num) + (iv:int128) (key1:int128 list): (byte list)#(byte list) = + let iv_last = GF_128_mult_by_primitive iv in + let PP = int128_to_bytes (aes256_xts_decrypt_round (bytes_to_int128 block) iv_last key1) in + let Pm = SUB_LIST (0, tail_len) PP in + let CP = SUB_LIST (tail_len, 16 - tail_len) PP in + let CC = bytes_to_int128 (APPEND tail CP) in + let Pm1 = int128_to_bytes (aes256_xts_decrypt_round CC iv key1) in + (Pm1, Pm)`;; + +(* Depending on the tail, either do one block decryption or do cipher stealing *) +let aes256_xts_decrypt_tail = new_definition + `aes256_xts_decrypt_tail (i:num) (tail_len:num) (C:byte list) (iv:int128) (key1:int128 list) : byte list = + if tail_len = 0 then + let Cm1 = bytes_to_int128 (SUB_LIST (i * 16, 16) C) in + int128_to_bytes (aes256_xts_decrypt_round Cm1 iv key1) + else + let Cm1 = SUB_LIST (i * 16, 16) C in + let Ctail = SUB_LIST ((i + 1) * 16, tail_len) C in + + let res_cs = cipher_stealing Cm1 Ctail tail_len iv key1 in + APPEND (FST res_cs) (SND res_cs)`;; + +(* The main decryption function *) +(* Note: the specification does not handle the case of len < 16, which is + handled in the implementation. *) + +(* AES256-XTS assumes there is at least one block in input *) +(* + C: Input ciphertext represented as a byte list + len: Length of C + iv: Initialization vector (tweak) as an int128 + key1: Key schedule for AES-256 decryption + key2: Key schedule for AES-256 encryption for the tweak + perror: Error output plaintext in case of invalid input length + + return: Output plaintext as a byte list + + When input len < 16, the function returns perror, + which will be the initial value stored in output address. +*) +(* TODO: Challenge lemma: proving that the output is of same length as input *) +(* TODO: Double check if IEEE and NIST spec talks about the error case len < 16 *) +(* TODO: Double check the pseudo code in the spec for tweak caculation in ANEX c *) +let aes256_xts_decrypt = new_definition + `aes256_xts_decrypt + (C:byte list) (len:num) (iv:int128) (key1:int128 list) (key2:int128 list) (perror:byte list) : byte list = + if len < 16 then + perror + else + let tail = len MOD 16 in + let m = (len - tail) DIV 16 in + let i = 0 in + + let iv = xts_init_tweak iv key2 in + if m < 2 then + aes256_xts_decrypt_tail i tail C iv key1 + else + let res = aes256_xts_decrypt_rec 0 (m - 2) C iv key1 in + let Ptail = aes256_xts_decrypt_tail (THD3 res) tail C (SND3 res) key1 in + APPEND (FST3 res) Ptail`;; + +(*******************************************) +(* Test vectors *) + +(* key1: c70a951e84370d1836bdd387607e94e5 7ead95d6f74bf6b3103340cce21b473d @@ -60,23 +232,69 @@ in: 3231302f2e2d2c2b2a292827262524232221201f1e1d1c1b1a191817161514131211100f0e0d *) -let ciphertext = new_definition - `ciphertext = [word 0xc3; word 0x0c; word 0xa8; word 0xf2 +let c0 = new_definition + `c0 = [word 0xc3; word 0x0c; word 0xa8; word 0xf2 ; word 0xed; word 0x57; word 0x30; word 0x7e ; word 0xdc; word 0x87; word 0xe5; word 0x44 ; word 0x86; word 0x7a; word 0xc8; word 0x88] : byte list`;; +let p0 = new_definition + `p0 = [word 0x00; word 0x01; word 0x02; word 0x03 + ; word 0x04; word 0x05; word 0x06; word 0x07 + ; word 0x08; word 0x09; word 0x0a; word 0x0b + ; word 0x0c; word 0x0d; word 0x0e; word 0x0f] : byte list`;; + +let c1 = new_definition + `c1 = [ word 0x75; word 0xe8; word 0x18; word 0x8b; + word 0xcc; word 0xe5; word 0x9a; word 0xda; + word 0x93; word 0x9f; word 0x57; word 0xde; + word 0x2c; word 0xb9; word 0xa4; word 0x89; + word 0xc3; word 0x0c; word 0xa8; word 0xf2; + word 0xed; word 0x57 ] : byte list`;; +let p1 = new_definition + `p1 = [word 0x0; word 0x1; word 0x2; word 0x3; + word 0x4; word 0x5; word 0x6; word 0x7; + word 0x8; word 0x9; word 0xa; word 0xb; + word 0xc; word 0xd; word 0xe; word 0xf; + word 0x10; word 0x11; word 0x12; word 0x13; + word 0x14; word 0x15] : byte list`;; + +let c2 = new_definition + `c2 = [ word 0xc3; word 0x0c; word 0xa8; word 0xf2; + word 0xed; word 0x57; word 0x30; word 0x7e; + word 0xdc; word 0x87; word 0xe5; word 0x44; + word 0x86; word 0x7a; word 0xc8; word 0x88; + word 0x34; word 0x8c; word 0x20; word 0x89; + word 0x28; word 0xd7; word 0x40; word 0x62; + word 0x69; word 0x95; word 0x45; word 0x51; + word 0xcb; word 0x62; word 0x7b; word 0x5b; + word 0xbe; word 0xa4; word 0x77; word 0x68; + word 0xaa; word 0x25; word 0x37; word 0x6e; + word 0x92; word 0x4c; word 0xce; word 0x6a; + word 0x10; word 0x2c; word 0xa2; word 0xe4; + word 0xe1; word 0xc2; word 0x41 ] : byte list`;; +let p2 = new_definition + `p2 = [word 0x0; word 0x1; word 0x2; word 0x3; + word 0x4; word 0x5; word 0x6; word 0x7; + word 0x8; word 0x9; word 0xa; word 0xb; + word 0xc; word 0xd; word 0xe; word 0xf; + word 0x10; word 0x11; word 0x12; word 0x13; + word 0x14; word 0x15; word 0x16; word 0x17; + word 0x18; word 0x19; word 0x1a; word 0x1b; + word 0x1c; word 0x1d; word 0x1e; word 0x1f; + word 0x20; word 0x21; word 0x22; word 0x23; + word 0x24; word 0x25; word 0x26; word 0x27; + word 0x28; word 0x29; word 0x2a; word 0x2b; + word 0x2c; word 0x2d; word 0x2e; word 0x2f; + word 0x30; word 0x31; word 0x32] : byte list`;; + let iv_tweak = new_definition `iv_tweak = (word 0x0000000000000000000000123456789a) : int128`;; + let perror = new_definition `perorr = [ word 0; word 0; word 0; word 0 ; word 0; word 0; word 0; word 0 ; word 0; word 0; word 0; word 0 ; word 0; word 0; word 0; word 0] : byte list`;; -let plaintext = new_definition - `plaintext = [word 0x0f; word 0x0e; word 0x0d; word 0x0c - ; word 0x0b; word 0x0a; word 0x09; word 0x08 - ; word 0x07; word 0x06; word 0x05; word 0x04 - ; word 0x03; word 0x02; word 0x01; word 0x00] : byte list`;; let KEY1 = new_definition `KEY1:int128 list = [ word 0xc70a951e84370d1836bdd387607e94e5 @@ -114,34 +332,13 @@ let KEY2 = new_definition `KEY2:int128 list = ; word 0x21a29367e3cefb30cb775905a6699487 ]`;; -(* -IEEE Standard for Cryptographic Protection of -Data on Block-Oriented Storage Devices -https://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=8637988 - -Section 5.4.1 - -a) T ← AES-enc(Key2, i) ⊗ αj -b) CC ← C ⊕ T -c) PP ← AES-dec(Key1, CC) -d) P ← PP ⊕ T - -*) - -let xts_init_tweak = new_definition - `xts_init_tweak (iv:int128) (key_schedule:int128 list) = - aes256_encrypt iv key_schedule`;; - +(*******************************************) +(* Conversions *) let XTS_INIT_TWEAK_CONV = REWR_CONV xts_init_tweak THENC AESENC_HELPER_CONV;; -(REWRITE_CONV [iv_tweak;KEY2] THENC XTS_INIT_TWEAK_CONV) `xts_init_tweak iv_tweak KEY2`;; - -let aes256_xts_decrypt_round = new_definition - `aes256_xts_decrypt_round (C:int128) (tk:int128) (key_schedule:int128 list) = - let CC = word_xor C tk in - let PP = aes256_decrypt CC key_schedule in - word_xor PP tk`;; +(* (REWRITE_CONV [iv_tweak;KEY2] THENC XTS_INIT_TWEAK_CONV) + `xts_init_tweak iv_tweak KEY2`;; *) let AES256_XTS_DECRYPT_ROUND_CONV = REWRITE_CONV [aes256_xts_decrypt_round] THENC @@ -153,12 +350,6 @@ let AES256_XTS_DECRYPT_ROUND_CONV = (* (REWRITE_CONV [iv_tweak; KEY2] THENC AES256_XTS_DECRYPT_ROUND_CONV) `aes256_xts_decrypt_round iv_tweak iv_tweak KEY2`;; *) -let aes256_xts_decrypt_1block = new_definition - `aes256_xts_decrypt_1block - (C:int128) (iv:int128) (key1:int128 list) (key2:int128 list) = - let tk = xts_init_tweak iv key2 in - aes256_xts_decrypt_round C tk key1`;; - let XTSDEC_1BLOCK_HELPER_CONV = REWR_CONV aes256_xts_decrypt_1block THENC REWRITE_CONV [xts_init_tweak] THENC @@ -174,27 +365,6 @@ time prove (`aes256_xts_decrypt_1block CONV_TAC(LAND_CONV XTSDEC_1BLOCK_HELPER_CONV) THEN REFL_TAC);; *) -(*******************************************) -(* AES-XTS decryption full *) -(* Note: the implementation sequences the calculation of the tweak - for each block, however, the specification will calculate the tweak - from the very beginning for each block. We write the specification - in the sequenced version for proof simplicity. -*) - -(* Helper functions derived from Amanda's code: - https://github.com/amanda-zx/s2n-bignum/blob/sha512/arm/sha512/sha512_specs.ml#L360 -*) -let bytes_to_int128 = define - `bytes_to_int128 (bs : byte list) : int128 = - word_join - (word_join - (word_join (word_join (EL 15 bs) (EL 14 bs) : int16) (word_join (EL 13 bs) (EL 12 bs) : int16) : int32) - (word_join (word_join (EL 11 bs) (EL 10 bs) : int16) (word_join (EL 9 bs) (EL 8 bs) : int16) : int32) : int64) - (word_join - (word_join (word_join (EL 7 bs) (EL 6 bs) : int16) (word_join (EL 5 bs) (EL 4 bs) : int16) : int32) - (word_join (word_join (EL 3 bs) (EL 2 bs) : int16) (word_join (EL 1 bs) (EL 0 bs) : int16) : int32) : int64)`;; - let EL_16_8_CLAUSES = let pat = `EL n [x0;x1;x2;x3;x4;x5;x6;x7;x8;x9;x10;x11;x12;x13;x14;x15]:byte` in map (fun n -> EL_CONV(subst [mk_small_numeral n,`n:num`] pat)) (0--15);; @@ -204,77 +374,21 @@ let BYTES_TO_INT128_CONV = REWRITE_CONV EL_16_8_CLAUSES THENC DEPTH_CONV WORD_RED_CONV;; -BYTES_TO_INT128_CONV `bytes_to_int128 - [word 0x0f; word 0x0e; word 0x0d; word 0x0c - ; word 0x0b; word 0x0a; word 0x09; word 0x08 - ; word 0x07; word 0x06; word 0x05; word 0x04 - ; word 0x03; word 0x02; word 0x01; word 0x00]`;; - -let int128_to_bytes = define - `int128_to_bytes (w : int128) : byte list = - [word_subword w (0, 8); - word_subword w (8, 8); - word_subword w (16, 8); - word_subword w (24, 8); - word_subword w (32, 8); - word_subword w (40, 8); - word_subword w (48, 8); - word_subword w (56, 8); - word_subword w (64, 8); - word_subword w (72, 8); - word_subword w (80, 8); - word_subword w (88, 8); - word_subword w (96, 8); - word_subword w (104, 8); - word_subword w (112, 8); - word_subword w (120, 8)]`;; +(* (REWRITE_CONV [c0] THENC BYTES_TO_INT128_CONV) `bytes_to_int128 c0`;; *) let INT128_TO_BYTES_CONV = REWRITE_CONV [int128_to_bytes] THENC DEPTH_CONV WORD_RED_CONV;; -INT128_TO_BYTES_CONV `int128_to_bytes (word 0x0102030405060708090a0b0c0d0e0f)`;; - - -(* Multiplication by the primitive element \alpha in GF(2^128) *) -let GF_128_mult_by_primitive = new_definition - `GF_128_mult_by_primitive - (tweak:(128)word) = - let shifted = word_shl tweak 1 in - let mask = word_ishr tweak 127 in - word_xor (word_and mask (word 0x87)) shifted`;; +(* INT128_TO_BYTES_CONV `int128_to_bytes (word 0x0102030405060708090a0b0c0d0e0f)`;; *) let GF_128_MULT_BY_PRIMITIVE_CONV = REWRITE_CONV [GF_128_mult_by_primitive] THENC REPEATC let_CONV THENC DEPTH_CONV WORD_RED_CONV;; -GF_128_MULT_BY_PRIMITIVE_CONV `GF_128_mult_by_primitive (word 0xffffffffffffffffffffffffffffffff)`;; - -let FST3 = define `FST3 (x:a#b#c) = FST x`;; -let SND3 = define `SND3 (x:a#b#c) = FST (SND x)`;; -let THD3 = define `THD3 (x:a#b#c) = SND (SND x)`;; - -let eth = prove_general_recursive_function_exists - `?aes256_xts_decrypt_rec. - ! (i:num) (m:num) (C:byte list) (iv:int128) (key1:int128 list). - aes256_xts_decrypt_rec i m C iv key1 : (byte list)#int128#num = - if m < i then ([], iv, i) - else - let current_block = bytes_to_int128 (SUB_LIST (i * 16, 16) C) in - let curr = int128_to_bytes (aes256_xts_decrypt_round current_block iv key1) in - let iv = GF_128_mult_by_primitive iv in - let res = aes256_xts_decrypt_rec (i + 1) m C iv key1 in - (APPEND curr (FST3 res), SND3 res, THD3 res)`;; - -let wfth = prove(hd(hyp eth), - EXISTS_TAC `MEASURE (\(i:num,m:num,C:byte list,iv:int128,key1:int128 list). (m + 1) - i)` THEN - REWRITE_TAC[WF_MEASURE; MEASURE] THEN ARITH_TAC);; - -let exists_lemma = PROVE_HYP wfth eth;; - -(* Note: results are stored in LSByte to MSByte *) -let aes256_xts_decrypt_rec = new_specification ["aes256_xts_decrypt_rec"] exists_lemma;; +(* GF_128_MULT_BY_PRIMITIVE_CONV + `GF_128_mult_by_primitive (word 0xffffffffffffffffffffffffffffffff)`;; *) let rec AES256_XTS_DECRYPT_REC_CONV tm = let BASE_CONV = @@ -304,19 +418,10 @@ let rec AES256_XTS_DECRYPT_REC_CONV tm = else INDUCT_CONV tm | _ -> failwith "AES256_XTS_DECRYPT_REC_CONV: inapplicable";; -(REWRITE_CONV [iv_tweak;KEY1;KEY2;ciphertext] THENC AES256_XTS_DECRYPT_REC_CONV) - `aes256_xts_decrypt_rec 0 0 ciphertext iv_tweak KEY1`;; - -let cipher_stealing = new_definition - `cipher_stealing (block:byte list) (tail:byte list) (tail_len:num) - (iv:int128) (key1:int128 list): (byte list)#(byte list) = - let iv_last = GF_128_mult_by_primitive iv in - let PP = int128_to_bytes (aes256_xts_decrypt_round (bytes_to_int128 block) iv_last key1) in - let Pm = SUB_LIST (0, tail_len) PP in - let CP = SUB_LIST (tail_len, 16 - tail_len) PP in - let CC = bytes_to_int128 (APPEND tail CP) in - let Pm1 = int128_to_bytes (aes256_xts_decrypt_round CC iv key1) in - (Pm1, Pm)`;; +(* +(REWRITE_CONV [iv_tweak;KEY1;KEY2;c0] THENC AES256_XTS_DECRYPT_REC_CONV) + `aes256_xts_decrypt_rec 0 0 c0 iv_tweak KEY1`;; + *) let CIPHER_STEALING_CONV = REWRITE_CONV [cipher_stealing] THENC @@ -332,21 +437,10 @@ let CIPHER_STEALING_CONV = SUBLET_CONV (RAND_CONV AES256_XTS_DECRYPT_ROUND_CONV) THENC SUBLET_CONV INT128_TO_BYTES_CONV THENC let_CONV;; -(REWRITE_CONV [ciphertext;iv_tweak;KEY1] THENC CIPHER_STEALING_CONV) - `cipher_stealing ciphertext [(word 0x0)] 1 iv_tweak KEY1`;; - -(* Depending on the tail, either do one block decryption or do cipher stealing *) -let aes256_xts_decrypt_tail = new_definition - `aes256_xts_decrypt_tail (i:num) (tail_len:num) (C:byte list) (iv:int128) (key1:int128 list) : byte list = - if tail_len = 0 then - let Cm1 = bytes_to_int128 (SUB_LIST (i * 16, 16) C) in - int128_to_bytes (aes256_xts_decrypt_round Cm1 iv key1) - else - let Cm1 = SUB_LIST (i * 16, 16) C in - let Ctail = SUB_LIST ((i + 1) * 16, tail_len) C in - - let res_cs = cipher_stealing Cm1 Ctail tail_len iv key1 in - APPEND (FST res_cs) (SND res_cs)`;; +(* +(REWRITE_CONV [c0;iv_tweak;KEY1] THENC CIPHER_STEALING_CONV) + `cipher_stealing c0 [(word 0x0)] 1 iv_tweak KEY1`;; + *) let AES256_XTS_DECRYPT_TAIL_CONV tm = let ONE_BLOCK_CONV = @@ -378,55 +472,13 @@ let AES256_XTS_DECRYPT_TAIL_CONV tm = else ONE_BLOCK_AND_TAIL_CONV tm | _ -> failwith "AES256_XTS_DECRYPT_TAIL_CONV: inapplicable";; -(REWRITE_CONV [ciphertext;iv_tweak;KEY1;KEY2] THENC AES256_XTS_DECRYPT_TAIL_CONV) - `aes256_xts_decrypt_tail 0 0 ciphertext iv_tweak KEY1`;; - -(REWRITE_CONV [iv_tweak;KEY1;KEY2] THENC AES256_XTS_DECRYPT_TAIL_CONV) -`aes256_xts_decrypt_tail 0 1 - [word 0xc3; word 0x0c; word 0xa8; word 0xf2 - ; word 0xed; word 0x57; word 0x30; word 0x7e - ; word 0xdc; word 0x87; word 0xe5; word 0x44 - ; word 0x86; word 0x7a; word 0xc8; word 0x88; word 0x00] - iv_tweak KEY1`;; - -(* The main decryption function *) -(* Note: the specification does not handle the case of len < 16, which is - handled in the implementation. *) - -(* AES256-XTS assumes there is at least one block in input *) (* - C: Input ciphertext represented as a byte list - len: Length of C - iv: Initialization vector (tweak) as an int128 - key1: Key schedule for AES-256 decryption - key2: Key schedule for AES-256 encryption for the tweak - perror: Error output plaintext in case of invalid input length - - return: Output plaintext as a byte list +(REWRITE_CONV [c0;iv_tweak;KEY1;KEY2] THENC AES256_XTS_DECRYPT_TAIL_CONV) + `aes256_xts_decrypt_tail 0 0 c0 iv_tweak KEY1`;; - When input len < 16, the function returns perror, - which will be the initial value stored in output address. +(REWRITE_CONV [c1;iv_tweak;KEY1;KEY2] THENC AES256_XTS_DECRYPT_TAIL_CONV) + `aes256_xts_decrypt_tail 0 6 c1 iv_tweak KEY1`;; *) -(* TODO: Challenge lemma: proving that the output is of same length as input *) -(* TODO: Double check if IEEE and NIST spec talks about the error case len < 16 *) -(* TODO: Double check the pseudo code in the spec for tweak caculation in ANEX c *) -let aes256_xts_decrypt = new_definition - `aes256_xts_decrypt - (C:byte list) (len:num) (iv:int128) (key1:int128 list) (key2:int128 list) (perror:byte list) : byte list = - if len < 16 then - perror - else - let tail = len MOD 16 in - let m = (len - tail) DIV 16 in - let i = 0 in - - let iv = xts_init_tweak iv key2 in - if m < 2 then - aes256_xts_decrypt_tail i tail C iv key1 - else - let res = aes256_xts_decrypt_rec 0 (m - 2) C iv key1 in - let Ptail = aes256_xts_decrypt_tail (THD3 res) tail C (SND3 res) key1 in - APPEND (FST3 res) Ptail`;; let AES256_XTS_DECRYPT_CONV tm = let ERROR_CONV = @@ -461,13 +513,13 @@ let AES256_XTS_DECRYPT_CONV tm = else BODY_CONV tm | _ -> failwith "AES256_XTS_DECRYPT_CONV: inapplicable";; - +(* (* TODO: figure out why perror isn't expanded out ??*) (REWRITE_CONV [perror] THENC AES256_XTS_DECRYPT_CONV) - `aes256_xts_decrypt ciphertext 5 iv_tweak KEY1 KEY2 perror`;; + `aes256_xts_decrypt c0 5 iv_tweak KEY1 KEY2 perror`;; -(REWRITE_CONV [ciphertext;iv_tweak;KEY1;KEY2;perror] THENC AES256_XTS_DECRYPT_CONV) - `aes256_xts_decrypt ciphertext 16 iv_tweak KEY1 KEY2 perror`;; +(REWRITE_CONV [c0;iv_tweak;KEY1;KEY2;perror] THENC AES256_XTS_DECRYPT_CONV) + `aes256_xts_decrypt c0 16 iv_tweak KEY1 KEY2 perror`;; (* 165 seconds *) time (REWRITE_CONV [iv_tweak;KEY1;KEY2;perror] THENC AES256_XTS_DECRYPT_CONV) @@ -481,48 +533,22 @@ time (REWRITE_CONV [iv_tweak;KEY1;KEY2;perror] THENC AES256_XTS_DECRYPT_CONV) ; word 0x86; word 0x7a; word 0xc8; word 0x88 ; word 0x00] 33 iv_tweak KEY1 KEY2 perror`;; - -(*******************************************) -(* Conversions *) +*) (*******************************************) (* Tests *) (* 1 block : 81 second *) -time (REWRITE_CONV [iv_tweak;KEY1;KEY2;perror] THENC AES256_XTS_DECRYPT_CONV) - `aes256_xts_decrypt - [ word 0xc3; word 0x0c; word 0xa8; word 0xf2; - word 0xed; word 0x57; word 0x30; word 0x7e; - word 0xdc; word 0x87; word 0xe5; word 0x44; - word 0x86; word 0x7a; word 0xc8; word 0x88 ] - 16 iv_tweak KEY1 KEY2 perror`;; +time prove (`aes256_xts_decrypt c0 16 iv_tweak KEY1 KEY2 perror = p0`, + CONV_TAC(LAND_CONV (REWRITE_CONV [c0;iv_tweak;KEY1;KEY2;perror] THENC AES256_XTS_DECRYPT_CONV)) THEN + REWRITE_TAC [p0] THEN REFL_TAC);; (* 1 block + 6 bytes : 121 seconds *) -time (REWRITE_CONV [iv_tweak;KEY1;KEY2;perror] THENC AES256_XTS_DECRYPT_CONV) - `aes256_xts_decrypt - [ word 0x75; word 0xe8; word 0x18; word 0x8b; - word 0xcc; word 0xe5; word 0x9a; word 0xda; - word 0x93; word 0x9f; word 0x57; word 0xde; - word 0x2c; word 0xb9; word 0xa4; word 0x89;eiifcbfhciurugujvrcfbnrlukjdrebhuklngddvufnf - - word 0xc3; word 0x0c; word 0xa8; word 0xf2; - word 0xed; word 0x57 ] - 22 iv_tweak KEY1 KEY2 perror`;; +time prove(`aes256_xts_decrypt c1 22 iv_tweak KEY1 KEY2 perror = p1`, + CONV_TAC(LAND_CONV (REWRITE_CONV [c1;iv_tweak;KEY1;KEY2;perror;p1] THENC AES256_XTS_DECRYPT_CONV)) THEN + REWRITE_TAC [p1] THEN REFL_TAC);; (* 3 blocks + 3 bytes : 206 seconds *) -time (REWRITE_CONV [iv_tweak;KEY1;KEY2;perror] THENC AES256_XTS_DECRYPT_CONV) - `aes256_xts_decrypt - [ word 0xc3; word 0x0c; word 0xa8; word 0xf2; - word 0xed; word 0x57; word 0x30; word 0x7e; - word 0xdc; word 0x87; word 0xe5; word 0x44; - word 0x86; word 0x7a; word 0xc8; word 0x88; - word 0x34; word 0x8c; word 0x20; word 0x89; - word 0x28; word 0xd7; word 0x40; word 0x62; - word 0x69; word 0x95; word 0x45; word 0x51; - word 0xcb; word 0x62; word 0x7b; word 0x5b; - word 0xbe; word 0xa4; word 0x77; word 0x68; - word 0xaa; word 0x25; word 0x37; word 0x6e; - word 0x92; word 0x4c; word 0xce; word 0x6a; - word 0x10; word 0x2c; word 0xa2; word 0xe4; - word 0xe1; word 0xc2; word 0x41 ] - 51 iv_tweak KEY1 KEY2 perror`;; +time prove(`aes256_xts_decrypt c2 51 iv_tweak KEY1 KEY2 perror = p2`, + CONV_TAC(LAND_CONV (REWRITE_CONV [c2;iv_tweak;KEY1;KEY2;perror;p2] THENC AES256_XTS_DECRYPT_CONV)) THEN + REWRITE_TAC [p2] THEN REFL_TAC);; From 52f494b822314a0c94b59f22cbdffc84d5aa278d Mon Sep 17 00:00:00 2001 From: Yan Peng Date: Fri, 22 Aug 2025 09:28:05 -0700 Subject: [PATCH 028/132] The ultimate ultimate clean up to fix perror --- arm/proofs/aes_xts_decrypt_spec.ml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/arm/proofs/aes_xts_decrypt_spec.ml b/arm/proofs/aes_xts_decrypt_spec.ml index 036a39276..377ff3609 100644 --- a/arm/proofs/aes_xts_decrypt_spec.ml +++ b/arm/proofs/aes_xts_decrypt_spec.ml @@ -161,9 +161,9 @@ let aes256_xts_decrypt_tail = new_definition (* TODO: Double check the pseudo code in the spec for tweak caculation in ANEX c *) let aes256_xts_decrypt = new_definition `aes256_xts_decrypt - (C:byte list) (len:num) (iv:int128) (key1:int128 list) (key2:int128 list) (perror:byte list) : byte list = + (C:byte list) (len:num) (iv:int128) (key1:int128 list) (key2:int128 list) (err:byte list) : byte list = if len < 16 then - perror + err else let tail = len MOD 16 in let m = (len - tail) DIV 16 in @@ -291,7 +291,7 @@ let iv_tweak = new_definition `iv_tweak = (word 0x0000000000000000000000123456789a) : int128`;; let perror = new_definition - `perorr = [ word 0; word 0; word 0; word 0 + `perror = [ word 0; word 0; word 0; word 0 ; word 0; word 0; word 0; word 0 ; word 0; word 0; word 0; word 0 ; word 0; word 0; word 0; word 0] : byte list`;; @@ -514,7 +514,6 @@ let AES256_XTS_DECRYPT_CONV tm = | _ -> failwith "AES256_XTS_DECRYPT_CONV: inapplicable";; (* -(* TODO: figure out why perror isn't expanded out ??*) (REWRITE_CONV [perror] THENC AES256_XTS_DECRYPT_CONV) `aes256_xts_decrypt c0 5 iv_tweak KEY1 KEY2 perror`;; From ec3b91ec2552c842c6dadb5796c668f80bd2c5a8 Mon Sep 17 00:00:00 2001 From: Yan Peng Date: Thu, 28 Aug 2025 18:48:44 -0700 Subject: [PATCH 029/132] Update the specification to match the standard for tweak calculation --- arm/proofs/aes_xts_decrypt_spec.ml | 127 +++++++++++++++++------------ 1 file changed, 77 insertions(+), 50 deletions(-) diff --git a/arm/proofs/aes_xts_decrypt_spec.ml b/arm/proofs/aes_xts_decrypt_spec.ml index 377ff3609..91d1afe2d 100644 --- a/arm/proofs/aes_xts_decrypt_spec.ml +++ b/arm/proofs/aes_xts_decrypt_spec.ml @@ -42,12 +42,7 @@ let aes256_xts_decrypt_1block = new_definition aes256_xts_decrypt_round C tk key1`;; (*******************************************) -(* AES-XTS decryption full *) -(* Note: the implementation sequences the calculation of the tweak - for each block, however, the specification will calculate the tweak - from the very beginning for each block. We write the specification - in the sequenced version for proof simplicity. -*) +(* AES-XTS decryption *) (* Helper functions derived from Amanda's code: https://github.com/amanda-zx/s2n-bignum/blob/sha512/arm/sha512/sha512_specs.ml#L360 @@ -89,24 +84,25 @@ let GF_128_mult_by_primitive = new_definition let mask = word_ishr tweak 127 in word_xor (word_and mask (word 0x87)) shifted`;; -let FST3 = define `FST3 (x:a#b#c) = FST x`;; -let SND3 = define `SND3 (x:a#b#c) = FST (SND x)`;; -let THD3 = define `THD3 (x:a#b#c) = SND (SND x)`;; +let calculate_tweak = new_recursive_definition num_RECURSION + `calculate_tweak 0 (iv:(128)word) (key2:int128 list) = xts_init_tweak iv key2 /\ + calculate_tweak (SUC n) (iv:(128)word) (key2:int128 list) = + GF_128_mult_by_primitive (calculate_tweak n iv key2)`;; let eth = prove_general_recursive_function_exists `?aes256_xts_decrypt_rec. - ! (i:num) (m:num) (C:byte list) (iv:int128) (key1:int128 list). - aes256_xts_decrypt_rec i m C iv key1 : (byte list)#int128#num = - if m < i then ([], iv, i) + ! (i:num) (m:num) (C:byte list) (iv:int128) (key1:int128 list) (key2:int128 list). + aes256_xts_decrypt_rec i m C iv key1 key2: (byte list)#num = + if m < i then ([], i) else let current_block = bytes_to_int128 (SUB_LIST (i * 16, 16) C) in - let curr = int128_to_bytes (aes256_xts_decrypt_round current_block iv key1) in - let iv = GF_128_mult_by_primitive iv in - let res = aes256_xts_decrypt_rec (i + 1) m C iv key1 in - (APPEND curr (FST3 res), SND3 res, THD3 res)`;; + let twk = calculate_tweak i iv key2 in + let curr = int128_to_bytes (aes256_xts_decrypt_round current_block twk key1) in + let res = aes256_xts_decrypt_rec (i + 1) m C iv key1 key2 in + (APPEND curr (FST res), SND res)`;; let wfth = prove(hd(hyp eth), - EXISTS_TAC `MEASURE (\(i:num,m:num,C:byte list,iv:int128,key1:int128 list). (m + 1) - i)` THEN + EXISTS_TAC `MEASURE (\(i:num,m:num,C:byte list,iv:int128,key1:int128 list,key2:int128 list). (m + 1) - i)` THEN REWRITE_TAC[WF_MEASURE; MEASURE] THEN ARITH_TAC);; let exists_lemma = PROVE_HYP wfth eth;; @@ -116,7 +112,8 @@ let aes256_xts_decrypt_rec = new_specification ["aes256_xts_decrypt_rec"] exists let cipher_stealing = new_definition `cipher_stealing (block:byte list) (tail:byte list) (tail_len:num) - (iv:int128) (key1:int128 list): (byte list)#(byte list) = + (iv:int128) (i:num) (key1:int128 list) (key2:int128 list): (byte list)#(byte list) = + let iv = calculate_tweak i iv key2 in let iv_last = GF_128_mult_by_primitive iv in let PP = int128_to_bytes (aes256_xts_decrypt_round (bytes_to_int128 block) iv_last key1) in let Pm = SUB_LIST (0, tail_len) PP in @@ -127,15 +124,16 @@ let cipher_stealing = new_definition (* Depending on the tail, either do one block decryption or do cipher stealing *) let aes256_xts_decrypt_tail = new_definition - `aes256_xts_decrypt_tail (i:num) (tail_len:num) (C:byte list) (iv:int128) (key1:int128 list) : byte list = + `aes256_xts_decrypt_tail (i:num) (tail_len:num) (C:byte list) (iv:int128) (key1:int128 list) (key2:int128 list) : byte list = if tail_len = 0 then let Cm1 = bytes_to_int128 (SUB_LIST (i * 16, 16) C) in + let iv = calculate_tweak i iv key2 in int128_to_bytes (aes256_xts_decrypt_round Cm1 iv key1) else let Cm1 = SUB_LIST (i * 16, 16) C in let Ctail = SUB_LIST ((i + 1) * 16, tail_len) C in - let res_cs = cipher_stealing Cm1 Ctail tail_len iv key1 in + let res_cs = cipher_stealing Cm1 Ctail tail_len iv i key1 key2 in APPEND (FST res_cs) (SND res_cs)`;; (* The main decryption function *) @@ -158,24 +156,20 @@ let aes256_xts_decrypt_tail = new_definition *) (* TODO: Challenge lemma: proving that the output is of same length as input *) (* TODO: Double check if IEEE and NIST spec talks about the error case len < 16 *) -(* TODO: Double check the pseudo code in the spec for tweak caculation in ANEX c *) let aes256_xts_decrypt = new_definition `aes256_xts_decrypt (C:byte list) (len:num) (iv:int128) (key1:int128 list) (key2:int128 list) (err:byte list) : byte list = if len < 16 then err else - let tail = len MOD 16 in - let m = (len - tail) DIV 16 in - let i = 0 in - - let iv = xts_init_tweak iv key2 in + let tail_len = len MOD 16 in + let m = (len - tail_len) DIV 16 in if m < 2 then - aes256_xts_decrypt_tail i tail C iv key1 + aes256_xts_decrypt_tail 0 tail_len C iv key1 key2 else - let res = aes256_xts_decrypt_rec 0 (m - 2) C iv key1 in - let Ptail = aes256_xts_decrypt_tail (THD3 res) tail C (SND3 res) key1 in - APPEND (FST3 res) Ptail`;; + let res = aes256_xts_decrypt_rec 0 (m - 2) C iv key1 key2 in + let Ptail = aes256_xts_decrypt_tail (SND res) tail_len C iv key1 key2 in + APPEND (FST res) Ptail`;; (*******************************************) (* Test vectors *) @@ -337,8 +331,10 @@ let KEY2 = new_definition `KEY2:int128 list = let XTS_INIT_TWEAK_CONV = REWR_CONV xts_init_tweak THENC AESENC_HELPER_CONV;; -(* (REWRITE_CONV [iv_tweak;KEY2] THENC XTS_INIT_TWEAK_CONV) - `xts_init_tweak iv_tweak KEY2`;; *) +(* +(REWRITE_CONV [iv_tweak;KEY2] THENC XTS_INIT_TWEAK_CONV) + `xts_init_tweak iv_tweak KEY2`;; + *) let AES256_XTS_DECRYPT_ROUND_CONV = REWRITE_CONV [aes256_xts_decrypt_round] THENC @@ -390,6 +386,33 @@ let GF_128_MULT_BY_PRIMITIVE_CONV = (* GF_128_MULT_BY_PRIMITIVE_CONV `GF_128_mult_by_primitive (word 0xffffffffffffffffffffffffffffffff)`;; *) +let rec CALCULATE_TWEAK_CONV tm = + let BASE_CONV = + ONCE_REWRITE_CONV [calculate_tweak] THENC + XTS_INIT_TWEAK_CONV in + let INDUCT_CONV = + RATOR_CONV(LAND_CONV num_CONV) THENC + ONCE_REWRITE_CONV [CONJUNCT2 calculate_tweak] THENC + RAND_CONV CALCULATE_TWEAK_CONV THENC + GF_128_MULT_BY_PRIMITIVE_CONV in + match tm with + | Comb + (Comb + (Comb + (Const ("calculate_tweak",_), n), + _), + _) -> + if dest_numeral n =/ num 0 + then BASE_CONV tm + else INDUCT_CONV tm + | _ -> failwith "CALCULATE_TWEAK_CONV: inapplicable";; + +(* +(REWRITE_CONV [iv_tweak;KEY2] THENC CALCULATE_TWEAK_CONV) `calculate_tweak 0 iv_tweak KEY2`;; + +(REWRITE_CONV [iv_tweak;KEY2] THENC CALCULATE_TWEAK_CONV) `calculate_tweak 1 iv_tweak KEY2`;; +*) + let rec AES256_XTS_DECRYPT_REC_CONV tm = let BASE_CONV = REWR_CONV aes256_xts_decrypt_rec THENC @@ -399,20 +422,22 @@ let rec AES256_XTS_DECRYPT_REC_CONV tm = DEPTH_CONV NUM_RED_CONV THENC ONCE_DEPTH_CONV SUB_LIST_CONV THENC ONCE_DEPTH_CONV BYTES_TO_INT128_CONV THENC let_CONV THENC + SUBLET_CONV CALCULATE_TWEAK_CONV THENC let_CONV THENC SUBLET_CONV (RAND_CONV AES256_XTS_DECRYPT_ROUND_CONV) THENC SUBLET_CONV INT128_TO_BYTES_CONV THENC let_CONV THENC - SUBLET_CONV GF_128_MULT_BY_PRIMITIVE_CONV THENC let_CONV THENC SUBLET_CONV AES256_XTS_DECRYPT_REC_CONV THENC let_CONV THENC - REWRITE_CONV [FST3;SND3;THD3;APPEND] in + REWRITE_CONV [FST;SND;APPEND] in match tm with | Comb + (Comb (Comb (Comb (Comb (Comb (Const ("aes256_xts_decrypt_rec", _), i), m), _), _), - _) -> + _), + _) -> if dest_numeral m + _), + _) -> if dest_numeral tail_len =/ num 0 then ONE_BLOCK_CONV tm else ONE_BLOCK_AND_TAIL_CONV tm @@ -474,10 +503,10 @@ let AES256_XTS_DECRYPT_TAIL_CONV tm = (* (REWRITE_CONV [c0;iv_tweak;KEY1;KEY2] THENC AES256_XTS_DECRYPT_TAIL_CONV) - `aes256_xts_decrypt_tail 0 0 c0 iv_tweak KEY1`;; + `aes256_xts_decrypt_tail 0 0 c0 iv_tweak KEY1 KEY2`;; (REWRITE_CONV [c1;iv_tweak;KEY1;KEY2] THENC AES256_XTS_DECRYPT_TAIL_CONV) - `aes256_xts_decrypt_tail 0 6 c1 iv_tweak KEY1`;; + `aes256_xts_decrypt_tail 0 6 c1 iv_tweak KEY1 KEY2`;; *) let AES256_XTS_DECRYPT_CONV tm = @@ -485,29 +514,28 @@ let AES256_XTS_DECRYPT_CONV tm = REWR_CONV aes256_xts_decrypt THENC DEPTH_CONV NUM_RED_CONV in let MORE_THAN_2_CONV = - REWRITE_CONV [FST3;SND3;THD3] THENC SUBLET_CONV AES256_XTS_DECRYPT_REC_CONV THENC let_CONV THENC + REWRITE_CONV [FST;SND] THENC SUBLET_CONV AES256_XTS_DECRYPT_TAIL_CONV THENC let_CONV THENC REWRITE_CONV [APPEND] in let BODY_CONV = REWR_CONV aes256_xts_decrypt THENC DEPTH_CONV NUM_RED_CONV THENC let_CONV THENC - DEPTH_CONV NUM_RED_CONV THENC let_CONV THENC let_CONV THENC - SUBLET_CONV XTS_INIT_TWEAK_CONV THENC let_CONV THENC + DEPTH_CONV NUM_RED_CONV THENC let_CONV THENC DEPTH_CONV NUM_RED_CONV THENC (AES256_XTS_DECRYPT_TAIL_CONV ORELSEC MORE_THAN_2_CONV) in match tm with | Comb - (Comb (Comb (Comb (Comb (Comb - (Const ("aes256_xts_decrypt", _), _), len), + (Comb + (Const ("aes256_xts_decrypt", _), _), len), + _), _), _), - _), - _) -> + _) -> if dest_numeral len Date: Thu, 28 Aug 2025 10:34:51 -0700 Subject: [PATCH 030/132] Update clean version of xts decrypt --- arm/aes-xts/aes_xts_decrypt_armv8.S | 602 ++++++++++++++-------------- arm/proofs/aes_xts_decrypt.ml | 90 +++-- 2 files changed, 358 insertions(+), 334 deletions(-) diff --git a/arm/aes-xts/aes_xts_decrypt_armv8.S b/arm/aes-xts/aes_xts_decrypt_armv8.S index 1ea2e1e63..fb6e812e9 100644 --- a/arm/aes-xts/aes_xts_decrypt_armv8.S +++ b/arm/aes-xts/aes_xts_decrypt_armv8.S @@ -16,61 +16,68 @@ #include "_internal_s2n_bignum.h" + .arch armv8-a+crypto S2N_BN_SYM_VISIBILITY_DIRECTIVE(aes_hw_xts_decrypt) S2N_BN_SYM_PRIVACY_DIRECTIVE(aes_hw_xts_decrypt) .text .balign 4 - .arch armv8-a+crypto -#define STACK_BASE_VREGS 0 -#define STACK_SIZE_VREGS (4*16) +#define STACK_SIZE_GPRS 32 //2*16 +#define STACK_SIZE_VREGS 64 //4*16 +#define STACK_SIZE (STACK_SIZE_GPRS + STACK_SIZE_VREGS) -.macro save_vregs - stp d8,d9,[sp,#(STACK_BASE_VREGS + 16*0)] - stp d10,d11,[sp,#(STACK_BASE_VREGS + 16*1)] -.endm +#define STACK_BASE_GPRS 0 +#define STACK_BASE_VREGS STACK_SIZE_GPRS -.macro save_regs - stp x19,x20,[sp,#(STACK_BASE_VREGS + 16*2)] - stp x21,x22,[sp,#(STACK_BASE_VREGS + 16*3)] -.endm +#define save_regs \ + stp x19, x20, [sp, #(STACK_BASE_GPRS + 16*0)] __LF \ + stp x21, x22, [sp, #(STACK_BASE_GPRS + 16*1)] -.macro restore_vregs - ldp d8,d9,[sp,#(STACK_BASE_VREGS + 16*0)] - ldp d10,d11,[sp,#(STACK_BASE_VREGS + 16*1)] -.endm +#define restore_regs \ + ldp x19, x20, [sp, #(STACK_BASE_GPRS + 16*0)] __LF \ + ldp x21, x22, [sp, #(STACK_BASE_GPRS + 16*1)] -.macro restore_regs - ldp x19,x20,[sp,#(STACK_BASE_VREGS + 16*2)] - ldp x21,x22,[sp,#(STACK_BASE_VREGS + 16*3)] -.endm +#define save_vregs \ + stp d8, d9, [sp, #(STACK_BASE_VREGS + 16*0)] __LF \ + stp d10, d11, [sp, #(STACK_BASE_VREGS + 16*1)] __LF \ + stp d12, d13, [sp, #(STACK_BASE_VREGS + 16*2)] __LF \ + stp d14, d15, [sp, #(STACK_BASE_VREGS + 16*3)] + +#define restore_vregs \ + ldp d8, d9, [sp, #(STACK_BASE_VREGS + 16*0)] __LF \ + ldp d10, d11, [sp, #(STACK_BASE_VREGS + 16*1)] __LF \ + ldp d12, d13, [sp, #(STACK_BASE_VREGS + 16*2)] __LF \ + ldp d14, d15, [sp, #(STACK_BASE_VREGS + 16*3)] // A single AES round // Prevent SLOTHY from unfolding because uArchs tend to fuse AESMC+AESE -.macro aesr data, key // @slothy:no-unfold - aese \data, \key - aesmc \data, \data -.endm +#define aesr(data, key) \ + aese data, key __LF \ + aesmc data, data // A single AESD round // Prevent SLOTHY from unfolding because uArchs tend to fuse AESIMC+AESD -.macro aesdr data, key // @slothy:no-unfold - aesd \data, \key - aesimc \data, \data -.endm - -.macro tweak lo, hi - extr x22, x10, x10, #32 - extr x10, x10, x9, #63 - and w11, w19, w22, asr#31 - eor x9, x11, x9, lsl#1 - fmov \lo, x9 - fmov \hi, x10 -.endm +#define aesdr(data, key) \ + aesd data, key __LF \ + aesimc data, data + +#define tweak(lo, hi) \ + extr x22, x10, x10, #32 __LF \ + extr x10, x10, x9, #63 __LF \ + and w11, w19, w22, asr#31 __LF \ + eor x9, x11, x9, lsl#1 __LF \ + fmov lo, x9 __LF \ + fmov hi, x10 + +#define udiv_by_80(src, dst) \ + mov dst, #-0x3333333333333334 __LF \ + movk dst, #0xcccd __LF \ + umulh dst, src, dst __LF \ + lsr dst, dst, #6 S2N_BN_SYMBOL(aes_hw_xts_decrypt): // AARCH64_VALID_CALL_TARGET - sub sp, sp, #STACK_SIZE_VREGS + sub sp, sp, #STACK_SIZE save_vregs save_regs @@ -82,7 +89,7 @@ S2N_BN_SYMBOL(aes_hw_xts_decrypt): Lxts_dec_big_size: // decrypt input size >= 16 bytes and x21, x2, #0xf // store the tail value of length%16 and x2, x2, #-16 // len &= 0x1..110000, now divisible by 16 - subs x2, x2, #16 + // subs x2, x2, #16 // Firstly, encrypt the iv with key2, as the first iv of XEX. ldr w6, [x4,#240] @@ -91,15 +98,15 @@ Lxts_dec_big_size: // decrypt input size >= 16 bytes sub w6, w6, #2 ld1 {v1.4s}, [x4], #16 -Loop_iv_enc: - aesr v6.16b, v0.16b +Loop_dec_iv_enc: + aesr(v6.16b, v0.16b) ld1 {v0.4s}, [x4], #16 subs w6, w6, #2 - aesr v6.16b, v1.16b + aesr(v6.16b, v1.16b) ld1 {v1.4s}, [x4], #16 - b.gt Loop_iv_enc + b.gt Loop_dec_iv_enc - aesr v6.16b, v0.16b + aesr(v6.16b, v0.16b) ld1 {v0.4s}, [x4] aese v6.16b, v1.16b eor v6.16b, v6.16b, v0.16b @@ -110,7 +117,7 @@ Loop_iv_enc: fmov x9, d6 fmov x10, v6.d[1] mov w19, #0x87 - tweak d8, v8.d[1] + tweak(d8, v8.d[1]) mov x7, x3 ld1 {v16.4s,v17.4s},[x7], #32 // load key schedule @@ -127,30 +134,33 @@ Lxts_dec: tst x21,#0xf b.eq Lxts_dec_begin subs x2,x2,#16 - cmp x2, #0 + cmp x2, #16 b.lt Lxts_dec_done // There is one block and a tail, go directy to cipher-stealing Lxts_dec_begin: - cmp x2, #16 + + udiv_by_80(x2, x8) // Number of 5x-unrolled iterations + + cmp x2, #0x20 b.lo Lxts_dec_tail1x // when input = 1 with another block and a tail - subs x2,x2,#32 // bias + cmp x2,#0x30 // bias b.lo Lxts_dec_tail2x // when input size = 2 with another block and a tail // The iv for third block - tweak d9,v9.d[1] + tweak(d9,v9.d[1]) - cmp x2,#16 + cmp x2,#0x40 b.lo Lxts_dec_tail3x // when input size = 3 with another block and a tail // The iv for fourth block - tweak d10,v10.d[1] + tweak(d10,v10.d[1]) - subs x2,x2,#32 + cmp x2,#0x50 b.lo Lxts_dec_tail4x // when input size = 4 with another block and a tail // The iv for fifth block - tweak d11,v11.d[1] + tweak(d11,v11.d[1]) .align 4 Loop5x_xts_dec: @@ -164,83 +174,83 @@ Loop5x_xts_dec: eor v25.16b,v25.16b,v10.16b eor v26.16b,v26.16b,v11.16b - aesdr v0.16b, v16.16b - aesdr v1.16b, v16.16b - aesdr v24.16b, v16.16b - aesdr v25.16b, v16.16b - aesdr v26.16b, v16.16b - - aesdr v0.16b, v17.16b - aesdr v1.16b, v17.16b - aesdr v24.16b, v17.16b - aesdr v25.16b, v17.16b - aesdr v26.16b, v17.16b - - aesdr v0.16b, v12.16b - aesdr v1.16b, v12.16b - aesdr v24.16b, v12.16b - aesdr v25.16b, v12.16b - aesdr v26.16b, v12.16b - - aesdr v0.16b, v13.16b - aesdr v1.16b, v13.16b - aesdr v24.16b, v13.16b - aesdr v25.16b, v13.16b - aesdr v26.16b, v13.16b - - aesdr v0.16b, v14.16b - aesdr v1.16b, v14.16b - aesdr v24.16b, v14.16b - aesdr v25.16b, v14.16b - aesdr v26.16b, v14.16b - - aesdr v0.16b, v15.16b - aesdr v1.16b, v15.16b - aesdr v24.16b, v15.16b - aesdr v25.16b, v15.16b - aesdr v26.16b, v15.16b - - aesdr v0.16b, v4.16b - aesdr v1.16b, v4.16b - aesdr v24.16b, v4.16b - aesdr v25.16b, v4.16b - aesdr v26.16b, v4.16b - - aesdr v0.16b, v5.16b - aesdr v1.16b, v5.16b - aesdr v24.16b, v5.16b - aesdr v25.16b, v5.16b - aesdr v26.16b, v5.16b - - aesdr v0.16b, v18.16b - aesdr v1.16b, v18.16b - aesdr v24.16b, v18.16b - aesdr v25.16b, v18.16b - aesdr v26.16b, v18.16b - - aesdr v0.16b, v19.16b - aesdr v1.16b, v19.16b - aesdr v24.16b, v19.16b - aesdr v25.16b, v19.16b - aesdr v26.16b, v19.16b - - aesdr v0.16b, v20.16b - aesdr v1.16b, v20.16b - aesdr v24.16b, v20.16b - aesdr v25.16b, v20.16b - aesdr v26.16b, v20.16b - - aesdr v0.16b, v21.16b - aesdr v1.16b, v21.16b - aesdr v24.16b, v21.16b - aesdr v25.16b, v21.16b - aesdr v26.16b, v21.16b - - aesdr v0.16b, v22.16b - aesdr v1.16b, v22.16b - aesdr v24.16b, v22.16b - aesdr v25.16b, v22.16b - aesdr v26.16b, v22.16b + aesdr(v0.16b, v16.16b) + aesdr(v1.16b, v16.16b) + aesdr(v24.16b, v16.16b) + aesdr(v25.16b, v16.16b) + aesdr(v26.16b, v16.16b) + + aesdr(v0.16b, v17.16b) + aesdr(v1.16b, v17.16b) + aesdr(v24.16b, v17.16b) + aesdr(v25.16b, v17.16b) + aesdr(v26.16b, v17.16b) + + aesdr(v0.16b, v12.16b) + aesdr(v1.16b, v12.16b) + aesdr(v24.16b, v12.16b) + aesdr(v25.16b, v12.16b) + aesdr(v26.16b, v12.16b) + + aesdr(v0.16b, v13.16b) + aesdr(v1.16b, v13.16b) + aesdr(v24.16b, v13.16b) + aesdr(v25.16b, v13.16b) + aesdr(v26.16b, v13.16b) + + aesdr(v0.16b, v14.16b) + aesdr(v1.16b, v14.16b) + aesdr(v24.16b, v14.16b) + aesdr(v25.16b, v14.16b) + aesdr(v26.16b, v14.16b) + + aesdr(v0.16b, v15.16b) + aesdr(v1.16b, v15.16b) + aesdr(v24.16b, v15.16b) + aesdr(v25.16b, v15.16b) + aesdr(v26.16b, v15.16b) + + aesdr(v0.16b, v4.16b) + aesdr(v1.16b, v4.16b) + aesdr(v24.16b, v4.16b) + aesdr(v25.16b, v4.16b) + aesdr(v26.16b, v4.16b) + + aesdr(v0.16b, v5.16b) + aesdr(v1.16b, v5.16b) + aesdr(v24.16b, v5.16b) + aesdr(v25.16b, v5.16b) + aesdr(v26.16b, v5.16b) + + aesdr(v0.16b, v18.16b) + aesdr(v1.16b, v18.16b) + aesdr(v24.16b, v18.16b) + aesdr(v25.16b, v18.16b) + aesdr(v26.16b, v18.16b) + + aesdr(v0.16b, v19.16b) + aesdr(v1.16b, v19.16b) + aesdr(v24.16b, v19.16b) + aesdr(v25.16b, v19.16b) + aesdr(v26.16b, v19.16b) + + aesdr(v0.16b, v20.16b) + aesdr(v1.16b, v20.16b) + aesdr(v24.16b, v20.16b) + aesdr(v25.16b, v20.16b) + aesdr(v26.16b, v20.16b) + + aesdr(v0.16b, v21.16b) + aesdr(v1.16b, v21.16b) + aesdr(v24.16b, v21.16b) + aesdr(v25.16b, v21.16b) + aesdr(v26.16b, v21.16b) + + aesdr(v0.16b, v22.16b) + aesdr(v1.16b, v22.16b) + aesdr(v24.16b, v22.16b) + aesdr(v25.16b, v22.16b) + aesdr(v26.16b, v22.16b) aesd v0.16b,v23.16b aesd v1.16b,v23.16b @@ -251,49 +261,50 @@ Loop5x_xts_dec: eor v0.16b,v0.16b,v7.16b eor v0.16b,v0.16b,v6.16b // The iv for first block of one iteration - tweak d6,v6.d[1] + tweak(d6,v6.d[1]) eor v1.16b,v1.16b,v7.16b eor v1.16b,v1.16b,v8.16b // The iv for second block - tweak d8,v8.d[1] + tweak(d8,v8.d[1]) eor v24.16b,v24.16b,v7.16b eor v24.16b,v24.16b,v9.16b // The iv for third block - tweak d9,v9.d[1] + tweak(d9,v9.d[1]) eor v25.16b,v25.16b,v7.16b eor v25.16b,v25.16b,v10.16b // The iv for fourth block - tweak d10,v10.d[1] + tweak(d10,v10.d[1]) eor v26.16b,v26.16b,v7.16b eor v26.16b,v26.16b,v11.16b // The iv for fifth block - tweak d11,v11.d[1] + tweak(d11,v11.d[1]) stp q0, q1, [x1], #0x50 stp q24, q25, [x1, #-0x30] str q26, [x1, #-0x10] - subs x2,x2,#0x50 // @slothy:core - b.hs Loop5x_xts_dec + subs x2,x2,#0x50 + subs x8,x8,#1 + cbnz x8, Loop5x_xts_dec Loop5x_dec_after: - cmn x2,#0x10 + cmp x2,#0x40 b.eq Lxts_dec_tail4x // 4 blocks left + 1block and a tail - add x2,x2,#0x50 - cbz x2,Lxts_dec_done // no blocks left + 1block and a tail + cmp x2,#0x30 + b.eq Lxts_dec_tail3x // 3 blocks left + 1block and a tail - subs x2,x2,#0x20 - b.lo Lxts_dec_tail1x // 1 block left + 1block and a tail + cmp x2,#0x20 + b.eq Lxts_dec_tail2x // 2 block left + 1block and a tail - subs x2,x2,#0x10 - b.lo Lxts_dec_tail2x // 2 blocks left + 1block and a tail + cmp x2,#0x10 + b.eq Lxts_dec_tail1x // 1 blocks left + 1block and a tail - b Lxts_dec_tail3x // 3 blocks left + 1block and a tail + b Lxts_dec_done // no blocks left + 1block and a tail .align 4 Lxts_dec_tail4x: @@ -305,70 +316,70 @@ Lxts_dec_tail4x: eor v24.16b,v24.16b,v9.16b eor v25.16b,v25.16b,v10.16b - aesdr v0.16b, v16.16b - aesdr v1.16b, v16.16b - aesdr v24.16b, v16.16b - aesdr v25.16b, v16.16b - - aesdr v0.16b, v17.16b - aesdr v1.16b, v17.16b - aesdr v24.16b, v17.16b - aesdr v25.16b, v17.16b - - aesdr v0.16b, v12.16b - aesdr v1.16b, v12.16b - aesdr v24.16b, v12.16b - aesdr v25.16b, v12.16b - - aesdr v0.16b, v13.16b - aesdr v1.16b, v13.16b - aesdr v24.16b, v13.16b - aesdr v25.16b, v13.16b - - aesdr v0.16b, v14.16b - aesdr v1.16b, v14.16b - aesdr v24.16b, v14.16b - aesdr v25.16b, v14.16b - - aesdr v0.16b, v15.16b - aesdr v1.16b, v15.16b - aesdr v24.16b, v15.16b - aesdr v25.16b, v15.16b - - aesdr v0.16b, v4.16b - aesdr v1.16b, v4.16b - aesdr v24.16b, v4.16b - aesdr v25.16b, v4.16b - - aesdr v0.16b, v5.16b - aesdr v1.16b, v5.16b - aesdr v24.16b, v5.16b - aesdr v25.16b, v5.16b - - aesdr v0.16b, v18.16b - aesdr v1.16b, v18.16b - aesdr v24.16b, v18.16b - aesdr v25.16b, v18.16b - - aesdr v0.16b, v19.16b - aesdr v1.16b, v19.16b - aesdr v24.16b, v19.16b - aesdr v25.16b, v19.16b - - aesdr v0.16b, v20.16b - aesdr v1.16b, v20.16b - aesdr v24.16b, v20.16b - aesdr v25.16b, v20.16b - - aesdr v0.16b, v21.16b - aesdr v1.16b, v21.16b - aesdr v24.16b, v21.16b - aesdr v25.16b, v21.16b - - aesdr v0.16b, v22.16b - aesdr v1.16b, v22.16b - aesdr v24.16b, v22.16b - aesdr v25.16b, v22.16b + aesdr(v0.16b, v16.16b) + aesdr(v1.16b, v16.16b) + aesdr(v24.16b, v16.16b) + aesdr(v25.16b, v16.16b) + + aesdr(v0.16b, v17.16b) + aesdr(v1.16b, v17.16b) + aesdr(v24.16b, v17.16b) + aesdr(v25.16b, v17.16b) + + aesdr(v0.16b, v12.16b) + aesdr(v1.16b, v12.16b) + aesdr(v24.16b, v12.16b) + aesdr(v25.16b, v12.16b) + + aesdr(v0.16b, v13.16b) + aesdr(v1.16b, v13.16b) + aesdr(v24.16b, v13.16b) + aesdr(v25.16b, v13.16b) + + aesdr(v0.16b, v14.16b) + aesdr(v1.16b, v14.16b) + aesdr(v24.16b, v14.16b) + aesdr(v25.16b, v14.16b) + + aesdr(v0.16b, v15.16b) + aesdr(v1.16b, v15.16b) + aesdr(v24.16b, v15.16b) + aesdr(v25.16b, v15.16b) + + aesdr(v0.16b, v4.16b) + aesdr(v1.16b, v4.16b) + aesdr(v24.16b, v4.16b) + aesdr(v25.16b, v4.16b) + + aesdr(v0.16b, v5.16b) + aesdr(v1.16b, v5.16b) + aesdr(v24.16b, v5.16b) + aesdr(v25.16b, v5.16b) + + aesdr(v0.16b, v18.16b) + aesdr(v1.16b, v18.16b) + aesdr(v24.16b, v18.16b) + aesdr(v25.16b, v18.16b) + + aesdr(v0.16b, v19.16b) + aesdr(v1.16b, v19.16b) + aesdr(v24.16b, v19.16b) + aesdr(v25.16b, v19.16b) + + aesdr(v0.16b, v20.16b) + aesdr(v1.16b, v20.16b) + aesdr(v24.16b, v20.16b) + aesdr(v25.16b, v20.16b) + + aesdr(v0.16b, v21.16b) + aesdr(v1.16b, v21.16b) + aesdr(v24.16b, v21.16b) + aesdr(v25.16b, v21.16b) + + aesdr(v0.16b, v22.16b) + aesdr(v1.16b, v22.16b) + aesdr(v24.16b, v22.16b) + aesdr(v25.16b, v22.16b) aesd v0.16b,v23.16b aesd v1.16b,v23.16b @@ -389,7 +400,7 @@ Lxts_dec_tail4x: // The iv for tail fmov x9,d10 fmov x10,v10.d[1] - tweak d6,v6.d[1] + tweak(d6,v6.d[1]) st1 {v0.16b,v1.16b},[x1],#32 st1 {v24.16b,v25.16b},[x1],#32 @@ -406,66 +417,66 @@ Lxts_dec_tail3x: eor v24.16b,v24.16b,v9.16b // First round with v16 - aesdr v0.16b, v16.16b - aesdr v1.16b, v16.16b - aesdr v24.16b, v16.16b + aesdr(v0.16b, v16.16b) + aesdr(v1.16b, v16.16b) + aesdr(v24.16b, v16.16b) // Second round with v17 - aesdr v0.16b, v17.16b - aesdr v1.16b, v17.16b - aesdr v24.16b, v17.16b + aesdr(v0.16b, v17.16b) + aesdr(v1.16b, v17.16b) + aesdr(v24.16b, v17.16b) // Third round with v12 - aesdr v0.16b, v12.16b - aesdr v1.16b, v12.16b - aesdr v24.16b, v12.16b + aesdr(v0.16b, v12.16b) + aesdr(v1.16b, v12.16b) + aesdr(v24.16b, v12.16b) // Fourth round with v13 - aesdr v0.16b, v13.16b - aesdr v1.16b, v13.16b - aesdr v24.16b, v13.16b + aesdr(v0.16b, v13.16b) + aesdr(v1.16b, v13.16b) + aesdr(v24.16b, v13.16b) // Fifth round with v14 - aesdr v0.16b, v14.16b - aesdr v1.16b, v14.16b - aesdr v24.16b, v14.16b + aesdr(v0.16b, v14.16b) + aesdr(v1.16b, v14.16b) + aesdr(v24.16b, v14.16b) // Sixth round with v15 - aesdr v0.16b, v15.16b - aesdr v1.16b, v15.16b - aesdr v24.16b, v15.16b + aesdr(v0.16b, v15.16b) + aesdr(v1.16b, v15.16b) + aesdr(v24.16b, v15.16b) // Seventh round with v4 - aesdr v0.16b, v4.16b - aesdr v1.16b, v4.16b - aesdr v24.16b, v4.16b + aesdr(v0.16b, v4.16b) + aesdr(v1.16b, v4.16b) + aesdr(v24.16b, v4.16b) // Eighth round with v5 - aesdr v0.16b, v5.16b - aesdr v1.16b, v5.16b - aesdr v24.16b, v5.16b + aesdr(v0.16b, v5.16b) + aesdr(v1.16b, v5.16b) + aesdr(v24.16b, v5.16b) // 9th round with v18 - aesdr v0.16b, v18.16b - aesdr v1.16b, v18.16b - aesdr v24.16b, v18.16b + aesdr(v0.16b, v18.16b) + aesdr(v1.16b, v18.16b) + aesdr(v24.16b, v18.16b) // 10th round with v19 - aesdr v0.16b, v19.16b - aesdr v1.16b, v19.16b - aesdr v24.16b, v19.16b + aesdr(v0.16b, v19.16b) + aesdr(v1.16b, v19.16b) + aesdr(v24.16b, v19.16b) - aesdr v0.16b, v20.16b - aesdr v1.16b, v20.16b - aesdr v24.16b, v20.16b + aesdr(v0.16b, v20.16b) + aesdr(v1.16b, v20.16b) + aesdr(v24.16b, v20.16b) - aesdr v0.16b, v21.16b - aesdr v1.16b, v21.16b - aesdr v24.16b, v21.16b + aesdr(v0.16b, v21.16b) + aesdr(v1.16b, v21.16b) + aesdr(v24.16b, v21.16b) - aesdr v0.16b, v22.16b - aesdr v1.16b, v22.16b - aesdr v24.16b, v22.16b + aesdr(v0.16b, v22.16b) + aesdr(v1.16b, v22.16b) + aesdr(v24.16b, v22.16b) aesd v0.16b,v23.16b aesd v1.16b,v23.16b @@ -481,7 +492,7 @@ Lxts_dec_tail3x: // The iv for tail fmov x9,d9 fmov x10,v9.d[1] - tweak d6,v6.d[1] + tweak(d6,v6.d[1]) st1 {v0.16b,v1.16b},[x1],#32 st1 {v24.16b},[x1],#16 @@ -494,53 +505,53 @@ Lxts_dec_tail2x: eor v1.16b,v1.16b,v8.16b // First round with v16 - aesdr v0.16b, v16.16b - aesdr v1.16b, v16.16b + aesdr(v0.16b, v16.16b) + aesdr(v1.16b, v16.16b) // Second round with v17 - aesdr v0.16b, v17.16b - aesdr v1.16b, v17.16b + aesdr(v0.16b, v17.16b) + aesdr(v1.16b, v17.16b) // Third round with v12 - aesdr v0.16b, v12.16b - aesdr v1.16b, v12.16b + aesdr(v0.16b, v12.16b) + aesdr(v1.16b, v12.16b) // Fourth round with v13 - aesdr v0.16b, v13.16b - aesdr v1.16b, v13.16b + aesdr(v0.16b, v13.16b) + aesdr(v1.16b, v13.16b) // Fifth round with v14 - aesdr v0.16b, v14.16b - aesdr v1.16b, v14.16b + aesdr(v0.16b, v14.16b) + aesdr(v1.16b, v14.16b) // Sixth round with v15 - aesdr v0.16b, v15.16b - aesdr v1.16b, v15.16b + aesdr(v0.16b, v15.16b) + aesdr(v1.16b, v15.16b) // Seventh round with v4 - aesdr v0.16b, v4.16b - aesdr v1.16b, v4.16b + aesdr(v0.16b, v4.16b) + aesdr(v1.16b, v4.16b) // Eighth round with v5 - aesdr v0.16b, v5.16b - aesdr v1.16b, v5.16b + aesdr(v0.16b, v5.16b) + aesdr(v1.16b, v5.16b) // 9th round with v18 - aesdr v0.16b, v18.16b - aesdr v1.16b, v18.16b + aesdr(v0.16b, v18.16b) + aesdr(v1.16b, v18.16b) // 10th round with v19 - aesdr v0.16b, v19.16b - aesdr v1.16b, v19.16b + aesdr(v0.16b, v19.16b) + aesdr(v1.16b, v19.16b) - aesdr v0.16b, v20.16b - aesdr v1.16b, v20.16b + aesdr(v0.16b, v20.16b) + aesdr(v1.16b, v20.16b) - aesdr v0.16b, v21.16b - aesdr v1.16b, v21.16b + aesdr(v0.16b, v21.16b) + aesdr(v1.16b, v21.16b) - aesdr v0.16b, v22.16b - aesdr v1.16b, v22.16b + aesdr(v0.16b, v22.16b) + aesdr(v1.16b, v22.16b) aesd v0.16b,v23.16b aesd v1.16b,v23.16b @@ -554,7 +565,7 @@ Lxts_dec_tail2x: // The iv for tail fmov x9,d8 fmov x10,v8.d[1] - tweak d6,v6.d[1] + tweak(d6,v6.d[1]) b Lxts_dec_done Lxts_dec_tail1x: @@ -563,38 +574,38 @@ Lxts_dec_tail1x: eor v0.16b,v0.16b,v6.16b // First round with v16 - aesdr v0.16b, v16.16b + aesdr(v0.16b, v16.16b) // Second round with v17 - aesdr v0.16b, v17.16b + aesdr(v0.16b, v17.16b) // Third round with v12 - aesdr v0.16b, v12.16b + aesdr(v0.16b, v12.16b) // Fourth round with v13 - aesdr v0.16b, v13.16b + aesdr(v0.16b, v13.16b) // Fifth round with v14 - aesdr v0.16b, v14.16b + aesdr(v0.16b, v14.16b) // Sixth round with v15 - aesdr v0.16b, v15.16b + aesdr(v0.16b, v15.16b) // Seventh round with v4 - aesdr v0.16b, v4.16b + aesdr(v0.16b, v4.16b) // Eighth round with v5 - aesdr v0.16b, v5.16b + aesdr(v0.16b, v5.16b) // 9th round with v18 - aesdr v0.16b, v18.16b + aesdr(v0.16b, v18.16b) // 10th round with v19 - aesdr v0.16b, v19.16b + aesdr(v0.16b, v19.16b) - aesdr v0.16b, v20.16b - aesdr v0.16b, v21.16b - aesdr v0.16b, v22.16b + aesdr(v0.16b, v20.16b) + aesdr(v0.16b, v21.16b) + aesdr(v0.16b, v22.16b) aesd v0.16b,v23.16b eor v0.16b,v0.16b,v7.16b @@ -603,7 +614,7 @@ Lxts_dec_tail1x: // tweak for tail fmov x9,d6 fmov x10,v6.d[1] - tweak d6,v6.d[1] + tweak(d6,v6.d[1]) b Lxts_dec_done Lxts_dec_done: @@ -617,7 +628,7 @@ Lxts_dec_done: fmov x9,d6 fmov x10,v6.d[1] - tweak d8,v8.d[1] + tweak(d8,v8.d[1]) ld1 {v0.4s},[x0],#16 @@ -688,10 +699,9 @@ Lxts_dec_done: Lxts_dec_abort: restore_vregs restore_regs - add sp, sp, #STACK_SIZE_VREGS + add sp, sp, #STACK_SIZE ret -#if defined(__ELF__) -// See https://www.airs.com/blog/archives/518. -.section .note.GNU-stack,"",%progbits -#endif +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack, "", %progbits +#endif \ No newline at end of file diff --git a/arm/proofs/aes_xts_decrypt.ml b/arm/proofs/aes_xts_decrypt.ml index 4c3da89bb..7d0b3a137 100644 --- a/arm/proofs/aes_xts_decrypt.ml +++ b/arm/proofs/aes_xts_decrypt.ml @@ -12,17 +12,24 @@ loadt "arm/proofs/aes_xts_decrypt_spec.ml";; (* print_literal_from_elf "arm/aes-xts/aes_xts_decrypt_armv8.o";; *) let aes_xts_decrypt_mc = define_assert_from_elf "aes_xts_decrypt_mc" "arm/aes-xts/aes_xts_decrypt_armv8.o" [ - 0xd10103ff; (* arm_SUB SP SP (rvalue (word 0x40)) *) - 0x6d0027e8; (* arm_STP D8 D9 SP (Immediate_Offset (iword (&0x0))) *) - 0x6d012fea; (* arm_STP D10 D11 SP (Immediate_Offset (iword (&0x10))) *) - 0xa90253f3; (* arm_STP X19 X20 SP (Immediate_Offset (iword (&0x20))) *) - 0xa9035bf5; (* arm_STP X21 X22 SP (Immediate_Offset (iword (&0x30))) *) + 0xd10183ff; (* arm_SUB SP SP (rvalue (word 0x60)) *) + 0x6d0227e8; (* arm_STP D8 D9 SP (Immediate_Offset (iword (&0x20))) *) + 0x6d032fea; (* arm_STP D10 D11 SP (Immediate_Offset (iword (&0x30))) *) + 0x6d0437ec; (* arm_STP D12 D13 SP (Immediate_Offset (iword (&0x40))) *) + 0x6d053fee; (* arm_STP D14 D15 SP (Immediate_Offset (iword (&0x50))) *) + 0xa90053f3; (* arm_STP X19 X20 SP (Immediate_Offset (iword (&0x0))) *) + 0xa9015bf5; (* arm_STP X21 X22 SP (Immediate_Offset (iword (&0x10))) *) 0xf100405f; (* arm_CMP X2 (rvalue (word 0x10)) *) - 0x540055cb; (* arm_BLT (word 0xab8) *) + 0x5400570b; (* arm_BLT (word 0xae0) *) + 0xd503201f; (* arm_NOP *) + 0xd503201f; (* arm_NOP *) + 0xd503201f; (* arm_NOP *) + 0xd503201f; (* arm_NOP *) + 0xd503201f; (* arm_NOP *) + 0xd503201f; (* arm_NOP *) 0xd503201f; (* arm_NOP *) 0x92400c55; (* arm_AND X21 X2 (rvalue (word 0xf)) *) 0x927cec42; (* arm_AND X2 X2 (rvalue (word 0xfffffffffffffff0)) *) - 0xf1004042; (* arm_SUBS X2 X2 (rvalue (word 0x10)) *) 0xb940f086; (* arm_LDR W6 X4 (Immediate_Offset (word 0xf0)) *) 0x4cdf7880; (* arm_LDR Q0 X4 (Postimmediate_Offset (word 0x10)) *) 0x4c4070a6; (* arm_LDR Q6 X5 No_Offset *) @@ -62,28 +69,32 @@ let aes_xts_decrypt_mc = define_assert_from_elf "aes_xts_decrypt_mc" "arm/aes-xt 0xf2400ebf; (* arm_TST X21 (rvalue (word 0xf)) *) 0x54000080; (* arm_BEQ (word 0x10) *) 0xf1004042; (* arm_SUBS X2 X2 (rvalue (word 0x10)) *) - 0xf100005f; (* arm_CMP X2 (rvalue (word 0x0)) *) - 0x5400488b; (* arm_BLT (word 0x910) *) 0xf100405f; (* arm_CMP X2 (rvalue (word 0x10)) *) - 0x54004323; (* arm_BCC (word 0x864) *) - 0xf1008042; (* arm_SUBS X2 X2 (rvalue (word 0x20)) *) - 0x54003a03; (* arm_BCC (word 0x740) *) + 0x5400492b; (* arm_BLT (word 0x924) *) + 0xb202e7e8; (* arm_MOV X8 (rvalue (word 0xcccccccccccccccc)) *) + 0xf29999a8; (* arm_MOVK X8 (word 0xcccd) 0x0 *) + 0x9bc87c48; (* arm_UMULH X8 X2 X8 *) + 0xd346fd08; (* arm_LSR X8 X8 0x6 *) + 0xf100805f; (* arm_CMP X2 (rvalue (word 0x20)) *) + 0x54004343; (* arm_BCC (word 0x868) *) + 0xf100c05f; (* arm_CMP X2 (rvalue (word 0x30)) *) + 0x54003a23; (* arm_BCC (word 0x744) *) 0x93ca8156; (* arm_ROR X22 X10 0x20 *) 0x93c9fd4a; (* arm_EXTR X10 X10 X9 0x3f *) 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 0x1f) *) 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 0x1) *) 0x9e670129; (* arm_FMOV_ItoF Q9 X9 0x0 *) 0x9eaf0149; (* arm_FMOV_ItoF Q9 X10 0x1 *) - 0xf100405f; (* arm_CMP X2 (rvalue (word 0x10)) *) - 0x54002c23; (* arm_BCC (word 0x584) *) + 0xf101005f; (* arm_CMP X2 (rvalue (word 0x40)) *) + 0x54002c43; (* arm_BCC (word 0x588) *) 0x93ca8156; (* arm_ROR X22 X10 0x20 *) 0x93c9fd4a; (* arm_EXTR X10 X10 X9 0x3f *) 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 0x1f) *) 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 0x1) *) 0x9e67012a; (* arm_FMOV_ItoF Q10 X9 0x0 *) 0x9eaf014a; (* arm_FMOV_ItoF Q10 X10 0x1 *) - 0xf1008042; (* arm_SUBS X2 X2 (rvalue (word 0x20)) *) - 0x54001a23; (* arm_BCC (word 0x344) *) + 0xf101405f; (* arm_CMP X2 (rvalue (word 0x50)) *) + 0x54001a43; (* arm_BCC (word 0x348) *) 0x93ca8156; (* arm_ROR X22 X10 0x20 *) 0x93c9fd4a; (* arm_EXTR X10 X10 X9 0x3f *) 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 0x1f) *) @@ -92,6 +103,7 @@ let aes_xts_decrypt_mc = define_assert_from_elf "aes_xts_decrypt_mc" "arm/aes-xt 0x9eaf014b; (* arm_FMOV_ItoF Q11 X10 0x1 *) 0xd503201f; (* arm_NOP *) 0xd503201f; (* arm_NOP *) + 0xd503201f; (* arm_NOP *) 0xacc28400; (* arm_LDP Q0 Q1 X0 (Postimmediate_Offset (iword (&0x50))) *) 0xad7ee418; (* arm_LDP Q24 Q25 X0 (Immediate_Offset (iword (-- &0x30))) *) 0x3cdf001a; (* arm_LDR Q26 X0 (Immediate_Offset (word 0xfffffffffffffff0)) *) @@ -279,17 +291,17 @@ let aes_xts_decrypt_mc = define_assert_from_elf "aes_xts_decrypt_mc" "arm/aes-xt 0xad3ee438; (* arm_STP Q24 Q25 X1 (Immediate_Offset (iword (-- &0x30))) *) 0x3c9f003a; (* arm_STR Q26 X1 (Immediate_Offset (word 0xfffffffffffffff0)) *) 0xf1014042; (* arm_SUBS X2 X2 (rvalue (word 0x50)) *) - 0x54ffe8a2; (* arm_BCS (word 0x1ffd14) *) - 0xb100405f; (* arm_CMN X2 (rvalue (word 0x10)) *) - 0x54000160; (* arm_BEQ (word 0x2c) *) - 0x91014042; (* arm_ADD X2 X2 (rvalue (word 0x50)) *) - 0xb4002d02; (* arm_CBZ X2 (word 0x5a0) *) - 0xf1008042; (* arm_SUBS X2 X2 (rvalue (word 0x20)) *) - 0x540027a3; (* arm_BCC (word 0x4f4) *) - 0xf1004042; (* arm_SUBS X2 X2 (rvalue (word 0x10)) *) - 0x54001e83; (* arm_BCC (word 0x3d0) *) - 0x1400008c; (* arm_B (word 0x230) *) - 0xd503201f; (* arm_NOP *) + 0xf1000508; (* arm_SUBS X8 X8 (rvalue (word 0x1)) *) + 0xb5ffe888; (* arm_CBNZ X8 (word 0x1ffd10) *) + 0xf101005f; (* arm_CMP X2 (rvalue (word 0x40)) *) + 0x54000140; (* arm_BEQ (word 0x28) *) + 0xf100c05f; (* arm_CMP X2 (rvalue (word 0x30)) *) + 0x54001200; (* arm_BEQ (word 0x240) *) + 0xf100805f; (* arm_CMP X2 (rvalue (word 0x20)) *) + 0x54001ea0; (* arm_BEQ (word 0x3d4) *) + 0xf100405f; (* arm_CMP X2 (rvalue (word 0x10)) *) + 0x54002740; (* arm_BEQ (word 0x4e8) *) + 0x14000162; (* arm_B (word 0x588) *) 0xd503201f; (* arm_NOP *) 0xd503201f; (* arm_NOP *) 0x4cdfa000; (* arm_LDP Q0 Q1 X0 (Postimmediate_Offset (word 0x20)) *) @@ -704,11 +716,13 @@ let aes_xts_decrypt_mc = define_assert_from_elf "aes_xts_decrypt_mc" "arm/aes-xt 0x6e201f5a; (* arm_EOR_VEC Q26 Q26 Q0 0x80 *) 0x6e261f5a; (* arm_EOR_VEC Q26 Q26 Q6 0x80 *) 0x4c00703a; (* arm_STR Q26 X1 No_Offset *) - 0x6d4027e8; (* arm_LDP D8 D9 SP (Immediate_Offset (iword (&0x0))) *) - 0x6d412fea; (* arm_LDP D10 D11 SP (Immediate_Offset (iword (&0x10))) *) - 0xa94253f3; (* arm_LDP X19 X20 SP (Immediate_Offset (iword (&0x20))) *) - 0xa9435bf5; (* arm_LDP X21 X22 SP (Immediate_Offset (iword (&0x30))) *) - 0x910103ff; (* arm_ADD SP SP (rvalue (word 0x40)) *) + 0x6d4227e8; (* arm_LDP D8 D9 SP (Immediate_Offset (iword (&0x20))) *) + 0x6d432fea; (* arm_LDP D10 D11 SP (Immediate_Offset (iword (&0x30))) *) + 0x6d4437ec; (* arm_LDP D12 D13 SP (Immediate_Offset (iword (&0x40))) *) + 0x6d453fee; (* arm_LDP D14 D15 SP (Immediate_Offset (iword (&0x50))) *) + 0xa94053f3; (* arm_LDP X19 X20 SP (Immediate_Offset (iword (&0x0))) *) + 0xa9415bf5; (* arm_LDP X21 X22 SP (Immediate_Offset (iword (&0x10))) *) + 0x910183ff; (* arm_ADD SP SP (rvalue (word 0x60)) *) 0xd65f03c0 (* arm_RET X30 *) ];; @@ -775,20 +789,20 @@ let AES_XTS_DECRYPT_CORRECT = prove( nonoverlapping (word pc, LENGTH aes_xts_decrypt_mc) (pt_ptr, 16) ==> ensures arm (\s. aligned_bytes_loaded s (word pc) aes_xts_decrypt_mc /\ - read PC s = word (pc + 20) /\ + read PC s = word (pc + 0x1c) /\ C_ARGUMENTS [ct_ptr; pt_ptr; word 16; key0_ptr; key1_ptr; iv_ptr] s /\ read(memory :> bytes128 ct_ptr) s = ib /\ read(memory :> bytes128 iv_ptr) s = iv /\ set_key_schedule s key0_ptr k00 k01 k02 k03 k04 k05 k06 k07 k08 k09 k0a k0b k0c k0d k0e /\ set_key_schedule s key1_ptr k10 k11 k12 k13 k14 k15 k16 k17 k18 k19 k1a k1b k1c k1d k1e) - (\s. read PC s = word (pc + 0xad0) /\ + (\s. read PC s = word (pc + 0xa10) /\ read(memory :> bytes128 pt_ptr) s = aes256_xts_decrypt_1block ib iv [k00; k01; k02; k03; k04; k05; k06; k07; k08; k09; k0a; k0b; k0c; k0d; k0e] [k10; k11; k12; k13; k14; k15; k16; k17; k18; k19; k1a; k1b; k1c; k1d; k1e] ) (MAYCHANGE [PC] ,, MAYCHANGE [events] ,, - MAYCHANGE [X21;X2;X6;X4;X9;X10;X19;X22;X11;X7;X0;X1] ,, + MAYCHANGE [X21;X2;X6;X4;X9;X10;X19;X22;X11;X7;X0;X1;X8] ,, MAYCHANGE [Q6;Q1;Q0;Q8;Q16;Q17;Q12;Q13;Q14;Q15;Q4;Q5;Q18;Q19;Q20;Q21;Q22;Q23;Q7;Q29;Q24] ,, MAYCHANGE SOME_FLAGS,, MAYCHANGE [memory :> bytes128 pt_ptr]) `, @@ -799,14 +813,14 @@ let AES_XTS_DECRYPT_CORRECT = prove( (* Start symbolic simulation*) ENSURES_INIT_TAC "s0" THEN (* Simulate until the first tweak and verify the first tweak equiv the spec *) - ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (1--64) THEN + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (1--69) THEN FIRST_X_ASSUM(MP_TAC o SPEC `(aes256_encrypt iv [k10; k11; k12; k13; k14; k15; k16; k17; k18; k19; k1a; k1b; k1c; k1d; k1e]):int128` o MATCH_MP (MESON[] `read Q6 s = a ==> !a'. a = a' ==> read Q6 s = a'`)) THEN ANTS_TAC THENL [ASM_REWRITE_TAC[] THEN AESENC_TAC; DISCH_TAC] THEN (* Simulating until finish decrypting one block *) - ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (65--117) THEN + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (70--126) THEN FIRST_X_ASSUM(MP_TAC o SPEC `(aes256_xts_decrypt_1block ib iv [k00; k01; k02; k03; k04; k05; k06; k07; k08; k09; k0a; k0b; k0c; k0d; k0e] @@ -821,6 +835,6 @@ let AES_XTS_DECRYPT_CORRECT = prove( AESDEC_TAC; DISCH_TAC] THEN (* Simulate to the end *) - ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (118--129) THEN + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (127--137) THEN ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC [] );; From 76891bc1a22898f4db8293084407536212acbf14 Mon Sep 17 00:00:00 2001 From: Yan Peng Date: Thu, 28 Aug 2025 19:09:40 -0700 Subject: [PATCH 031/132] Add a structure for the proof --- arm/aes-xts/aes_xts_decrypt_armv8.S | 63 +- arm/proofs/aes_xts_decrypt.ml | 861 +++++++++++++++++++++++++++- arm/proofs/aes_xts_decrypt_spec.ml | 10 +- 3 files changed, 898 insertions(+), 36 deletions(-) diff --git a/arm/aes-xts/aes_xts_decrypt_armv8.S b/arm/aes-xts/aes_xts_decrypt_armv8.S index fb6e812e9..3ee1ed5a9 100644 --- a/arm/aes-xts/aes_xts_decrypt_armv8.S +++ b/arm/aes-xts/aes_xts_decrypt_armv8.S @@ -83,13 +83,12 @@ S2N_BN_SYMBOL(aes_hw_xts_decrypt): cmp x2,#16 // Original input data size bigger than 16, jump to big size processing. - b.lt Lxts_dec_abort + b.lt .Lxts_dec_abort .align 5 -Lxts_dec_big_size: // decrypt input size >= 16 bytes +.Lxts_dec_big_size: // decrypt input size >= 16 bytes and x21, x2, #0xf // store the tail value of length%16 and x2, x2, #-16 // len &= 0x1..110000, now divisible by 16 - // subs x2, x2, #16 // Firstly, encrypt the iv with key2, as the first iv of XEX. ldr w6, [x4,#240] @@ -98,13 +97,13 @@ Lxts_dec_big_size: // decrypt input size >= 16 bytes sub w6, w6, #2 ld1 {v1.4s}, [x4], #16 -Loop_dec_iv_enc: +.Loop_dec_iv_enc: aesr(v6.16b, v0.16b) ld1 {v0.4s}, [x4], #16 subs w6, w6, #2 aesr(v6.16b, v1.16b) ld1 {v1.4s}, [x4], #16 - b.gt Loop_dec_iv_enc + b.gt .Loop_dec_iv_enc aesr(v6.16b, v0.16b) ld1 {v0.4s}, [x4] @@ -130,40 +129,40 @@ Loop_dec_iv_enc: ld1 {v7.4s}, [x7] // decryption -Lxts_dec: +.Lxts_dec: tst x21,#0xf - b.eq Lxts_dec_begin + b.eq .Lxts_dec_begin subs x2,x2,#16 cmp x2, #16 - b.lt Lxts_dec_done // There is one block and a tail, go directy to cipher-stealing + b.lt .Lxts_dec_done // There is one block and a tail, go directy to cipher-stealing -Lxts_dec_begin: +.Lxts_dec_begin: udiv_by_80(x2, x8) // Number of 5x-unrolled iterations cmp x2, #0x20 - b.lo Lxts_dec_tail1x // when input = 1 with another block and a tail + b.lo .Lxts_dec_tail1x // when input = 1 with another block and a tail cmp x2,#0x30 // bias - b.lo Lxts_dec_tail2x // when input size = 2 with another block and a tail + b.lo .Lxts_dec_tail2x // when input size = 2 with another block and a tail // The iv for third block tweak(d9,v9.d[1]) cmp x2,#0x40 - b.lo Lxts_dec_tail3x // when input size = 3 with another block and a tail + b.lo .Lxts_dec_tail3x // when input size = 3 with another block and a tail // The iv for fourth block tweak(d10,v10.d[1]) cmp x2,#0x50 - b.lo Lxts_dec_tail4x // when input size = 4 with another block and a tail + b.lo .Lxts_dec_tail4x // when input size = 4 with another block and a tail // The iv for fifth block tweak(d11,v11.d[1]) .align 4 -Loop5x_xts_dec: +.Loop5x_xts_dec: ldp q0, q1, [x0], #0x50 ldp q24, q25, [x0, #-0x30] ldr q26, [x0, #-0x10] @@ -289,25 +288,25 @@ Loop5x_xts_dec: subs x2,x2,#0x50 subs x8,x8,#1 - cbnz x8, Loop5x_xts_dec + cbnz x8, .Loop5x_xts_dec -Loop5x_dec_after: +.Loop5x_dec_after: cmp x2,#0x40 - b.eq Lxts_dec_tail4x // 4 blocks left + 1block and a tail + b.eq .Lxts_dec_tail4x // 4 blocks left + 1block and a tail cmp x2,#0x30 - b.eq Lxts_dec_tail3x // 3 blocks left + 1block and a tail + b.eq .Lxts_dec_tail3x // 3 blocks left + 1block and a tail cmp x2,#0x20 - b.eq Lxts_dec_tail2x // 2 block left + 1block and a tail + b.eq .Lxts_dec_tail2x // 2 block left + 1block and a tail cmp x2,#0x10 - b.eq Lxts_dec_tail1x // 1 blocks left + 1block and a tail + b.eq .Lxts_dec_tail1x // 1 blocks left + 1block and a tail - b Lxts_dec_done // no blocks left + 1block and a tail + b .Lxts_dec_done // no blocks left + 1block and a tail .align 4 -Lxts_dec_tail4x: +.Lxts_dec_tail4x: ld1 {v0.16b,v1.16b}, [x0],#32 // the first and second blocks ld1 {v24.16b,v25.16b}, [x0],#32 // the third and fourth blocks @@ -405,10 +404,10 @@ Lxts_dec_tail4x: st1 {v0.16b,v1.16b},[x1],#32 st1 {v24.16b,v25.16b},[x1],#32 - b Lxts_dec_done + b .Lxts_dec_done .align 4 -Lxts_dec_tail3x: +.Lxts_dec_tail3x: ld1 {v0.16b,v1.16b}, [x0],#32 ld1 {v24.16b}, [x0],#16 @@ -496,9 +495,9 @@ Lxts_dec_tail3x: st1 {v0.16b,v1.16b},[x1],#32 st1 {v24.16b},[x1],#16 - b Lxts_dec_done // done processing three blocks + b .Lxts_dec_done // done processing three blocks -Lxts_dec_tail2x: +.Lxts_dec_tail2x: ld1 {v0.16b,v1.16b},[x0],#32 // the first block eor v0.16b,v0.16b,v6.16b @@ -566,9 +565,9 @@ Lxts_dec_tail2x: fmov x9,d8 fmov x10,v8.d[1] tweak(d6,v6.d[1]) - b Lxts_dec_done + b .Lxts_dec_done -Lxts_dec_tail1x: +.Lxts_dec_tail1x: ld1 {v0.16b}, [x0],#16 // the first block eor v0.16b,v0.16b,v6.16b @@ -615,11 +614,11 @@ Lxts_dec_tail1x: fmov x9,d6 fmov x10,v6.d[1] tweak(d6,v6.d[1]) - b Lxts_dec_done + b .Lxts_dec_done -Lxts_dec_done: +.Lxts_dec_done: tst x21,#0xf - b.eq Lxts_dec_abort + b.eq .Lxts_dec_abort // Processing the last 1 block and a tail with cipher stealing. // At this point, we know there is 1 block+tail // We need two tweaks, one is already calculated and stored in v6 @@ -696,7 +695,7 @@ Lxts_dec_done: eor v26.16b,v26.16b,v6.16b st1 {v26.16b},[x1] -Lxts_dec_abort: +.Lxts_dec_abort: restore_vregs restore_regs add sp, sp, #STACK_SIZE diff --git a/arm/proofs/aes_xts_decrypt.ml b/arm/proofs/aes_xts_decrypt.ml index 7d0b3a137..88e238665 100644 --- a/arm/proofs/aes_xts_decrypt.ml +++ b/arm/proofs/aes_xts_decrypt.ml @@ -779,11 +779,74 @@ let AESDEC_TAC = AP_THM_TAC THEN AP_TERM_TAC THEN GEN_REWRITE_TAC LAND_CONV [WORD_XOR_SYM] THEN REFL_TAC;; +let TWEAK_UPDATE_CONV = + let ADD_SUC_1 = ARITH_RULE `!n. n + 1 = SUC(n)` in + let ADD_SUC_2 = ARITH_RULE `!n. n + 2 = SUC(n + 1)` in + let ADD_SUC_3 = ARITH_RULE `!n. n + 3 = SUC(n + 2)` in + let ADD_SUC_4 = ARITH_RULE `!n. n + 4 = SUC(n + 3)` in + let ADD_SUC_5 = ARITH_RULE `!n. n + 5 = SUC(n + 4)` in + let ADD_SUC_6 = ARITH_RULE `!n. n + 6 = SUC(n + 5)` in + let ADD_SUC_7 = ARITH_RULE `!n. n + 7 = SUC(n + 6)` in + let ADD_SUC_8 = ARITH_RULE `!n. n + 8 = SUC(n + 7)` in + let ADD_SUC_9 = ARITH_RULE `!n. n + 9 = SUC(n + 8)` in + NUM_REDUCE_CONV THENC + RATOR_CONV (LAND_CONV (num_CONV ORELSEC + FIRST_CONV + [ CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_1]); + CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_2]); + CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_3]); + CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_4]); + CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_5]); + CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_6]); + CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_7]); + CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_8]); + CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_9]);])) THENC + REWRITE_CONV [CONJUNCT2 calculate_tweak] THENC + GF_128_MULT_BY_PRIMITIVE_CONV;; + +let TWEAK_TAC reg ind indm1 = + let lower_term = subst [ind,`ind:num`] `(word_zx:int128->int64) (calculate_tweak ind iv key2)` in + let upper_term = subst [ind,`ind:num`] `(word_subword:int128->num#num->int64) (calculate_tweak ind iv key2) (64,64)` in + let full_term = subst [ind,`ind:num`] `calculate_tweak ind iv key2` in + let full_lemma = subst [reg,`reg:(armstate,int128)component`] `read (reg:(armstate,int128)component) (s:armstate) = a ==> !a'. a = a' ==> read reg s = a'` in + let abbrev_term = subst [indm1,`indm1:num`] `tweak_pre:int128 = (calculate_tweak indm1 iv key2)` in + FIRST_X_ASSUM(MP_TAC o SPEC lower_term + o MATCH_MP (MESON[] `read X9 s = a ==> !a'. a = a' ==> read X9 s = a'`)) THEN + ANTS_TAC THENL [CONV_TAC (RAND_CONV (RAND_CONV TWEAK_UPDATE_CONV)) THEN + ABBREV_TAC abbrev_term THEN + BITBLAST_TAC; DISCH_TAC] THEN + FIRST_X_ASSUM(MP_TAC o SPEC upper_term + o MATCH_MP (MESON[] `read X10 s = a ==> !a'. a = a' ==> read X10 s = a'`)) THEN + ANTS_TAC THENL [CONV_TAC (RAND_CONV (RATOR_CONV (RAND_CONV TWEAK_UPDATE_CONV))) THEN + ABBREV_TAC abbrev_term THEN + BITBLAST_TAC; DISCH_TAC] THEN + FIRST_X_ASSUM(MP_TAC o SPEC full_term + o MATCH_MP (MESON[] full_lemma)) THEN + ANTS_TAC THENL [CONV_TAC (RAND_CONV TWEAK_UPDATE_CONV) THEN + ABBREV_TAC abbrev_term THEN + BITBLAST_TAC; DISCH_TAC];; + +let XTSDEC_TAC reg ind ind_tweak = + let tm = subst [ind, `ind:num`; ind_tweak, `ind_tweak:num`] + `aes256_xts_decrypt_round (bytes_to_int128 (SUB_LIST (ind,0x10) (ct:byte list))) + (calculate_tweak ind_tweak iv key2) key1` in + let lemma = subst [reg, `reg:(armstate,int128)component`] + `read (reg:(armstate,int128)component) (s:armstate) = a ==> !a'. a = a' ==> read reg s = a'` in + let _ = print_term tm in + let _ = print_term lemma in + FIRST_X_ASSUM(MP_TAC o SPEC tm o MATCH_MP (MESON[] lemma)) THEN + ANTS_TAC THENL + [ EXPAND_TAC "key1" THEN + CONV_TAC (RAND_CONV ( + REWRITE_CONV [aes256_xts_decrypt_round] THENC + DEPTH_CONV let_CONV)) THEN + AESDEC_TAC; DISCH_TAC ];; + (** Proof **) -let AES_XTS_DECRYPT_CORRECT = prove( +let AES_XTS_DECRYPT_1BLOCK_CORRECT = prove( `!ct_ptr pt_ptr key0_ptr key1_ptr iv_ptr ib iv - k00 k01 k02 k03 k04 k05 k06 k07 k08 k09 k0a k0b k0c k0d k0e + (k00:int128) k01 k02 k03 k04 k05 k06 k07 k08 k09 k0a k0b k0c k0d k0e k10 k11 k12 k13 k14 k15 k16 k17 k18 k19 k1a k1b k1c k1d k1e pc. nonoverlapping (word pc, LENGTH aes_xts_decrypt_mc) (pt_ptr, 16) @@ -838,3 +901,797 @@ let AES_XTS_DECRYPT_CORRECT = prove( ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (127--137) THEN ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC [] );; + + +(*******************************************) +(* Full proof *) + +(* Taken from Amanda's code at https://github.com/amanda-zx/s2n-bignum/blob/ed25519/arm/sha512/utils.ml *) + +let byte_list_at = define + `byte_list_at (m : byte list) (m_p : int64) s = + ! i. i < LENGTH m ==> read (memory :> bytes8(word_add m_p (word i))) s = EL i m`;; + +let tail_len_lt_16_lemma = prove( + `!tail_len:int64. + word_and len (word 0xf) = tail_len ==> val tail_len < 16`, + BITBLAST_TAC +);; + +let num_blocks_ge_80_lemma = prove( + `!num_blocks:int64. + word_and len (word 0xfffffffffffffff0) = num_blocks /\ val len >= 0x50 + ==> val num_blocks >= 0x50`, + BITBLAST_TAC +);; + +let crock_lemma = prove( + `!a:num b:num. a >= b /\ b > 0 ==> ~(a DIV b = 0)`, + REPEAT GEN_TAC THEN + MP_TAC (SPECL [`a:num`; `b:num`] DIV_EQ_0) THEN + ARITH_TAC +);; + +let word_split_lemma = prove( + `!len:int64. len = word_add (word_and len (word 0xf)) + (word_and len (word 0xfffffffffffffff0))`, + BITBLAST_TAC);; + +let blt_lemma = prove( + `!len:int64 x:num. + val len >= x /\ val len < 2 EXP 63 + ==> (ival (word_sub len (word x)) < &0 <=> ~(ival len - &x = ival (word_sub len (word x))))`, + REPEAT STRIP_TAC THEN + CHEAT_TAC);; + +let UDIV_OPT_LEMMA = prove( + `!n:int64. val n < 2 EXP 64 ==> + word_ushr + ((word ((val (word_and n (word 0xfffffffffffffff0)) * 0xcccccccccccccccd) DIV 0x2 EXP 0x40)):int64) + 0x6 = word ((val n) DIV 0x50)`, + REPEAT STRIP_TAC THEN + CHEAT_TAC);; + +let READ_CT_LEMMA = prove( + `!ct_ptr s ct i. + (forall j. + j < LENGTH ct + ==> read (memory :> bytes8 (word_add ct_ptr (word j))) s = EL j ct) + /\ ~(LENGTH ct < 0x50) + /\ i < LENGTH ct DIV 0x50 ==> + read (memory :> bytes128 (word_add ct_ptr (word_mul (word 0x50) (word i)))) s0 = + bytes_to_int128 (SUB_LIST (i * 80, 16) ct) /\ + read (memory :> bytes128 (word_add (word_add ct_ptr (word_mul (word 0x50) (word i))) (word 0x10))) s = + bytes_to_int128 (SUB_LIST (i * 80 + 16, 16) ct) /\ + read (memory :> bytes128 (word_add (word_add ct_ptr (word_mul (word 0x50) (word i))) (word 0x20))) s = + bytes_to_int128 (SUB_LIST (i * 80 + 32, 16) ct) /\ + read (memory :> bytes128 (word_add (word_add ct_ptr (word_mul (word 0x50) (word i))) (word 0x30))) s = + bytes_to_int128 (SUB_LIST (i * 80 + 48, 16) ct) /\ + read (memory :> bytes128 (word_add (word_add ct_ptr (word_mul (word 0x50) (word i))) (word 0x40))) s = + bytes_to_int128 (SUB_LIST (i * 80 + 64, 16) ct) + `, + CHEAT_TAC +);; + +let READ_CT_TAIL4_LEMMA = prove( + `!ct_ptr s ct len (num_blocks:int64) (num_5blocks_adjusted:int64). + (forall j. + j < LENGTH ct + ==> read (memory :> bytes8 (word_add ct_ptr (word j))) s = EL j ct) + /\ ~(LENGTH ct < 0x50) + /\ val len = LENGTH ct + /\ word_and len (word 0xfffffffffffffff0) = num_blocks + /\ val + (word_sub + (word_sub (num_blocks_adjusted:int64) + (word_mul (word 0x50) num_5blocks_adjusted)) + (word 0x40)) = + 0x0 + ==> + read (memory :> bytes128 (word_add + (word_add ct_ptr (word_mul (word 0x50) num_5blocks_adjusted)) + (word 0x30))) s = + bytes_to_int128 (SUB_LIST (val num_5blocks_adjusted * 16 + 0x30, 16) ct) /\ + read (memory :> bytes128 (word_add + (word_add ct_ptr (word_mul (word 0x50) num_5blocks_adjusted)) + (word 0x20))) s = + bytes_to_int128 (SUB_LIST (val num_5blocks_adjusted * 16 + 0x20, 16) ct) /\ + read (memory :> bytes128 (word_add + (word_add ct_ptr (word_mul (word 0x50) num_5blocks_adjusted)) + (word 0x10))) s = + bytes_to_int128 (SUB_LIST (val num_5blocks_adjusted * 16 + 0x10, 16) ct) /\ + read (memory :> bytes128 + (word_add ct_ptr (word_mul (word 0x50) num_5blocks_adjusted))) s = + bytes_to_int128 (SUB_LIST (val num_5blocks_adjusted * 16, 16) ct) + `, + CHEAT_TAC +);; + +let READ_CT_TAIL3_LEMMA = prove( + `!ct_ptr s ct len (num_blocks:int64) (num_5blocks_adjusted:int64). + (forall j. + j < LENGTH ct + ==> read (memory :> bytes8 (word_add ct_ptr (word j))) s = EL j ct) + /\ ~(LENGTH ct < 0x50) + /\ val len = LENGTH ct + /\ word_and len (word 0xfffffffffffffff0) = num_blocks + /\ val + (word_sub + (word_sub (num_blocks_adjusted:int64) + (word_mul (word 0x50) num_5blocks_adjusted)) + (word 0x30)) = + 0x0 + ==> + read (memory :> bytes128 (word_add + (word_add ct_ptr (word_mul (word 0x50) num_5blocks_adjusted)) + (word 0x20))) s = + bytes_to_int128 (SUB_LIST (val num_5blocks_adjusted * 16 + 0x20, 16) ct) /\ + read (memory :> bytes128 (word_add + (word_add ct_ptr (word_mul (word 0x50) num_5blocks_adjusted)) + (word 0x10))) s = + bytes_to_int128 (SUB_LIST (val num_5blocks_adjusted * 16 + 0x10, 16) ct) /\ + read (memory :> bytes128 + (word_add ct_ptr (word_mul (word 0x50) num_5blocks_adjusted))) s = + bytes_to_int128 (SUB_LIST (val num_5blocks_adjusted * 16, 16) ct) + `, + CHEAT_TAC +);; + +let READ_CT_TAIL2_LEMMA = prove( + `!ct_ptr s ct len (num_blocks:int64) (num_5blocks_adjusted:int64). + (forall j. + j < LENGTH ct + ==> read (memory :> bytes8 (word_add ct_ptr (word j))) s = EL j ct) + /\ ~(LENGTH ct < 0x50) + /\ val len = LENGTH ct + /\ word_and len (word 0xfffffffffffffff0) = num_blocks + /\ val + (word_sub + (word_sub num_blocks_adjusted + (word_mul (word 0x50) num_5blocks_adjusted)) + (word 0x20)) = + 0x0 + ==> + read (memory :> bytes128 (word_add + (word_add ct_ptr (word_mul (word 0x50) num_5blocks_adjusted)) + (word 0x10))) s = + bytes_to_int128 (SUB_LIST (val num_5blocks_adjusted * 16 + 0x10, 16) ct) /\ + read (memory :> bytes128 + (word_add ct_ptr (word_mul (word 0x50) num_5blocks_adjusted))) s = + bytes_to_int128 (SUB_LIST (val num_5blocks_adjusted * 16, 16) ct) + `, + CHEAT_TAC +);; + +let READ_CT_TAIL1_LEMMA = prove( + `!ct_ptr s ct len (num_blocks:int64) (num_5blocks_adjusted:int64). + (forall j. + j < LENGTH ct + ==> read (memory :> bytes8 (word_add ct_ptr (word j))) s = EL j ct) + /\ ~(LENGTH ct < 0x50) + /\ val len = LENGTH ct + /\ word_and len (word 0xfffffffffffffff0) = num_blocks + /\ val + (word_sub + (word_sub num_blocks_adjusted + (word_mul (word 0x50) num_5blocks_adjusted)) + (word 0x10)) = + 0x0 + ==> + read (memory :> bytes128 + (word_add ct_ptr (word_mul (word 0x50) num_5blocks_adjusted))) s = + bytes_to_int128 (SUB_LIST (val num_5blocks_adjusted * 16, 16) ct) + `, + CHEAT_TAC +);; + +let AES_XTS_DECRYPT_CORRECT = prove( + `!ct_ptr pt_ptr ct pt_init key1_ptr key2_ptr iv_ptr iv len + k00 k01 k02 k03 k04 k05 k06 k07 k08 k09 k0a k0b k0c k0d k0e + k10 k11 k12 k13 k14 k15 k16 k17 k18 k19 k1a k1b k1c k1d k1e + pc. + nonoverlapping (word pc, LENGTH aes_xts_decrypt_mc) (pt_ptr, val len) + /\ val len >= 16 /\ val len <= 2 EXP 24 /\ val len = LENGTH ct + ==> ensures arm + (\s. aligned_bytes_loaded s (word pc) aes_xts_decrypt_mc /\ + read PC s = word (pc + 0x1c) /\ + C_ARGUMENTS [ct_ptr; pt_ptr; len; key1_ptr; key2_ptr; iv_ptr] s /\ + byte_list_at ct ct_ptr s /\ + byte_list_at pt_init pt_ptr s /\ + read(memory :> bytes128 iv_ptr) s = iv /\ + set_key_schedule s key1_ptr k00 k01 k02 k03 k04 k05 k06 k07 k08 k09 k0a k0b k0c k0d k0e /\ + set_key_schedule s key2_ptr k10 k11 k12 k13 k14 k15 k16 k17 k18 k19 k1a k1b k1c k1d k1e) + (\s. read PC s = word (pc + 0xb00) /\ + byte_list_at (aes256_xts_decrypt ct (val len) iv + [k00; k01; k02; k03; k04; k05; k06; k07; k08; k09; k0a; k0b; k0c; k0d; k0e] + [k10; k11; k12; k13; k14; k15; k16; k17; k18; k19; k1a; k1b; k1c; k1d; k1e] + pt_init) pt_ptr s + ) + (MAYCHANGE [PC] ,, MAYCHANGE [events] ,, + MAYCHANGE [X21;X2;X6;X4;X9;X10;X19;X22;X11;X7;X0;X1;X8] ,, + MAYCHANGE [Q6;Q1;Q0;Q8;Q9;Q10;Q11;Q16;Q17;Q12;Q13;Q14;Q15; + Q4;Q5;Q18;Q19;Q20;Q21;Q22;Q23;Q7;Q29;Q24;Q25;Q26] ,, + MAYCHANGE SOME_FLAGS,, MAYCHANGE [memory :> bytes(pt_ptr, val len)]) + `, + REWRITE_TAC [(REWRITE_CONV [aes_xts_decrypt_mc] THENC LENGTH_CONV) `LENGTH aes_xts_decrypt_mc`] THEN + REWRITE_TAC[set_key_schedule; C_ARGUMENTS; SOME_FLAGS; NONOVERLAPPING_CLAUSES; byte_list_at] THEN + REPEAT STRIP_TAC THEN + + (* Break len into full blocks and tail *) + SUBGOAL_THEN `len:int64 = word_add (word_and len (word 0xf)) + (word_and len (word 0xfffffffffffffff0))` ASSUME_TAC THENL + [REWRITE_TAC[word_split_lemma]; ALL_TAC] THEN + ABBREV_TAC `num_blocks:int64 = word_and len (word 0xfffffffffffffff0)` THEN + ABBREV_TAC `tail_len:int64 = word_and len (word 0xf)` THEN + ABBREV_TAC `key1:int128 list = [k00; k01; k02; k03; k04; k05; k06; k07; k08; k09; k0a; k0b; k0c; k0d; k0e]` THEN + ABBREV_TAC `key2:int128 list = [k10; k11; k12; k13; k14; k15; k16; k17; k18; k19; k1a; k1b; k1c; k1d; k1e]` THEN + + (* Case splits on length: + len < 16 -- error case + len < 32 -- one block, or one block and a tail + len < 48 -- two blocks, or two blocks and a tail + len < 64 -- three blocks, or three blocks and a tail + len < 80 -- four blocks, or four blocks and a tail + len < 96 -- five blocks, or five blocks and a tail + len >= 96 -- six blocks and up + + Note: for decrypt, because of cipherstealing, there needs to be one extra + block at the end together with the tail to be processed for cipherstealing + *) + ASM_CASES_TAC `val (len:int64) < 96` THENL [CHEAT_TAC; ALL_TAC] THEN + + ABBREV_TAC `num_blocks_adjusted = if val (tail_len:int64) = 0 + then num_blocks else word_sub (num_blocks:int64) (word 0x10)` THEN + ABBREV_TAC `num_5blocks_adjusted = (word (val (num_blocks_adjusted:int64) DIV 0x50)):int64` THEN + + (* Verify properties of the program until the beginning of the loop. + The properties include the invariant, and a bunch of other initial setup. + *) + ENSURES_SEQUENCE_TAC `pc + 0x170` + `\s. + read X0 s = ct_ptr /\ + read X1 s = pt_ptr /\ + read X2 s = num_blocks_adjusted /\ + read X3 s = key1_ptr /\ + read X21 s = tail_len /\ + read X8 s = num_5blocks_adjusted /\ + read Q6 s = calculate_tweak 0 iv key2 /\ + read Q8 s = calculate_tweak 1 iv key2 /\ + read Q9 s = calculate_tweak 2 iv key2 /\ + read Q10 s = calculate_tweak 3 iv key2 /\ + read Q11 s = calculate_tweak 4 iv key2 /\ + read X19 s = word 0x87 /\ + read X10 s = word_subword (calculate_tweak 4 iv key2) (64,64) /\ + read X9 s = word_zx (calculate_tweak 4 iv key2) /\ + read Q16 s = k00 /\ read Q17 s = k01 /\ read Q12 s = k02 /\ read Q13 s = k03 /\ + read Q14 s = k04 /\ read Q15 s = k05 /\ read Q4 s = k06 /\ read Q5 s = k07 /\ + read Q18 s = k08 /\ read Q19 s = k09 /\ read Q20 s = k0a /\ read Q21 s = k0b /\ + read Q22 s = k0c /\ read Q23 s = k0d /\ read Q7 s = k0e /\ + byte_list_at ct ct_ptr s /\ + byte_list_at (aes256_xts_decrypt ct 0 iv key1 key2 pt_init) pt_ptr s /\ + set_key_schedule s key1_ptr k00 k01 k02 k03 k04 k05 k06 k07 k08 k09 k0a k0b k0c k0d k0e` THEN + CONJ_TAC THENL + [ + (* ===> Symbolic Simulation: Start symbolic simulation*) + ENSURES_INIT_TAC "s0" THEN + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (1--2) THEN + (* Discharge if condition *) + SUBGOAL_THEN + `ival (word_sub (word_add (tail_len:int64) (num_blocks:int64)) (word 0x10)) < &0x0 <=> + ~(ival (word_add tail_len num_blocks) - &0x10 = + ival (word_sub (word_add tail_len num_blocks) (word 0x10)))` ASSUME_TAC THENL + [ MATCH_MP_TAC blt_lemma THEN CONJ_TAC THENL + [ UNDISCH_TAC `len:int64 = word_add tail_len num_blocks` THEN + UNDISCH_TAC `val (len:int64) >= 16` THEN + WORD_ARITH_TAC; + UNDISCH_TAC `len:int64 = word_add tail_len num_blocks` THEN + UNDISCH_TAC `val (len:int64) <= 2 EXP 24` THEN + WORD_ARITH_TAC]; + ALL_TAC] THEN + POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th])) THEN + + (* ===> Symbolic Simulation: Symbolic execution for initialization of tweak *) + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (3--69) THEN + (* Prove Q6 stores initial tweak *) + FIRST_X_ASSUM(MP_TAC o SPEC `(calculate_tweak 0 iv key2)` + o MATCH_MP (MESON[] `read Q6 s = a ==> !a'. a = a' ==> read Q6 s = a'`)) THEN + ANTS_TAC THENL + [REWRITE_TAC[CONJUNCT1 calculate_tweak; xts_init_tweak] THEN + EXPAND_TAC "key2" THEN AESENC_TAC; DISCH_TAC] THEN + + (* ===> Symbolic Simulation: Symbolic simulating untill next branch *) + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (70--89) THEN + (* Case split on whether there is a tail *) + FIRST_X_ASSUM MP_TAC THEN + COND_CASES_TAC THENL + [ + (* If there is no tail *) + DISCH_TAC THEN + (* Prove x9, x10 stores lower and upper halves and Q8 stores the full tweak *) + TWEAK_TAC `Q8:(armstate,int128)component` `1:num` `0:num` THEN + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (90--93) THEN + (* Prove the optimized udiv is basically udiv *) + SUBGOAL_THEN `word_ushr ((word ((val (word_and (word_add (tail_len:int64) num_blocks) + (word 0xfffffffffffffff0)) * 0xcccccccccccccccd) DIV 0x2 EXP 0x40)):int64) + 0x6 = word ((val num_blocks) DIV 0x50)` ASSUME_TAC THENL + [ CHEAT_TAC + ; ALL_TAC] THEN + POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th])) THEN + + (* Eliminate 1 block case *) + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (94--95) THEN + SUBGOAL_THEN `~(val (word_and (word_add (tail_len:int64) num_blocks) (word 0xfffffffffffffff0)) < 0x20)` ASSUME_TAC THENL + [CHEAT_TAC; POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th]))] THEN + (* Eliminate 2 blocks case *) + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (96--97) THEN + SUBGOAL_THEN `~(val (word_and (word_add (tail_len:int64) num_blocks) (word 0xfffffffffffffff0)) < 0x30)` ASSUME_TAC THENL + [CHEAT_TAC; POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th]))] THEN + (* Eliminate 3 blocks case and prove Q9 stores tweak 2 *) + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (98--105) THEN + SUBGOAL_THEN `~(val (word_and (word_add (tail_len:int64) num_blocks) (word 0xfffffffffffffff0)) < 0x40)` ASSUME_TAC THENL + [CHEAT_TAC; POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th]))] THEN + TWEAK_TAC `Q9:(armstate,int128)component` `2:num` `1:num` THEN + + (* Eliminate 4 blocks case and Q10 stores tweak 3 *) + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (106--113) THEN + SUBGOAL_THEN `~(val (word_and (word_add (tail_len:int64) num_blocks) (word 0xfffffffffffffff0)) < 0x50)` ASSUME_TAC THENL + [CHEAT_TAC; POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th]))] THEN + TWEAK_TAC `Q10:(armstate,int128)component` `3:num` `2:num` THEN + + (* Must have 5 blocks, execute until start of loop. Q11 stores tweak 4 *) + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (114--122) THEN + TWEAK_TAC `Q11:(armstate,int128)component` `4:num` `3:num` THEN + + ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN + REPEAT CONJ_TAC THENL + [ + CHEAT_TAC; + REWRITE_TAC[SYM (ASSUME `len:int64 = word_add tail_len num_blocks`)] THEN + ASM_REWRITE_TAC[]; + CHEAT_TAC; + ASM_REWRITE_TAC[byte_list_at]; + CHEAT_TAC; + ASM_REWRITE_TAC[set_key_schedule]] + ; ALL_TAC + ] THEN + + (* If there is a tail *) + DISCH_TAC THEN + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (90--92) THEN + (* Discharge if condition *) + SUBGOAL_THEN + `ival + (word_sub + (word_sub + (word_and (word_add (tail_len:int64) num_blocks) + (word 0xfffffffffffffff0)) + (word 0x10)) + (word 0x10)) < + &0x0 <=> + ~(ival + (word_sub + (word_and (word_add tail_len num_blocks) + (word 0xfffffffffffffff0)) + (word 0x10)) - + &0x10 = + ival + (word_sub + (word_sub + (word_and (word_add tail_len num_blocks) + (word 0xfffffffffffffff0)) + (word 0x10)) + (word 0x10)))` ASSUME_TAC THENL + [ CHEAT_TAC; + ALL_TAC] THEN + POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th])) THEN + + (* Prove x9, x10 stores lower and upper halves and Q8 stores the full tweak *) + TWEAK_TAC `Q8:(armstate,int128)component` `1:num` `0:num` THEN + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (93--96) THEN + (* Prove the optimized udiv is basically udiv *) + SUBGOAL_THEN `word_ushr + (word + ((val + (word_sub + (word_and (word_add (tail_len:int64) num_blocks) (word 0xfffffffffffffff0)) + (word 0x10)) * + 0xcccccccccccccccd) DIV + 0x2 EXP 0x40):int64) + 0x6 = word ((val (word_sub num_blocks (word 1))) DIV 0x50)` ASSUME_TAC THENL + [ CHEAT_TAC + ; ALL_TAC] THEN + POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th])) THEN + + (* Eliminate 1 block case *) + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (97--98) THEN + SUBGOAL_THEN `~(val + (word_sub + (word_and (word_add (tail_len:int64) num_blocks) + (word 0xfffffffffffffff0)) + (word 0x10)) < + 0x20)` ASSUME_TAC THENL + [CHEAT_TAC; POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th]))] THEN + (* Eliminate 2 blocks case *) + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (99--100) THEN + SUBGOAL_THEN `~(val + (word_sub + (word_and (word_add (tail_len:int64) num_blocks) + (word 0xfffffffffffffff0)) + (word 0x10)) < + 0x30)` ASSUME_TAC THENL + [CHEAT_TAC; POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th]))] THEN + (* Eliminate 3 blocks case and prove Q9 stores tweak 2 *) + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (101--108) THEN + SUBGOAL_THEN `~(val + (word_sub + (word_and (word_add (tail_len:int64) num_blocks) + (word 0xfffffffffffffff0)) + (word 0x10)) < + 0x40)` ASSUME_TAC THENL + [CHEAT_TAC; POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th]))] THEN + TWEAK_TAC `Q9:(armstate,int128)component` `2:num` `1:num` THEN + + (* Eliminate 4 blocks case and Q10 stores tweak 3 *) + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (109--116) THEN + SUBGOAL_THEN `~(val + (word_sub + (word_and (word_add (tail_len:int64) num_blocks) + (word 0xfffffffffffffff0)) + (word 0x10)) < + 0x50)` ASSUME_TAC THENL + [CHEAT_TAC; POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th]))] THEN + TWEAK_TAC `Q10:(armstate,int128)component` `3:num` `2:num` THEN + + (* Must have 5 blocks, execute until start of loop. Q11 stores tweak 4 *) + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (117--125) THEN + TWEAK_TAC `Q11:(armstate,int128)component` `4:num` `3:num` THEN + + ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN + REPEAT CONJ_TAC THENL + [ + CHEAT_TAC; + REWRITE_TAC[SYM (ASSUME `len:int64 = word_add tail_len num_blocks`)] THEN + ASM_REWRITE_TAC[]; + CHEAT_TAC; + ASM_REWRITE_TAC[byte_list_at]; + CHEAT_TAC; + ASM_REWRITE_TAC[set_key_schedule]] + ; ALL_TAC + ] THEN + + (* Prove the rest of the program *) + (* Setting up the loop invariant *) + + (* Invariant: + X0 holds ct_ptr + i*0x50 + X1 hols pt_ptr + i*0x50 + X3 holds key1_ptr + X21 holds tail_len + + X2 holds number of blocks left + X8 holds number of 5xblocks left + Q6, Q8, Q9, Q10, Q11 holds the next 5 tweaks + X10 stores upper half of last tweak + X9 stores lower half of last tweak + X19 holds 0x87 + Q16, Q17, Q12, Q13, Q14, Q15, Q4, Q5, Q18, Q19, Q20, Q21, Q22, Q23, Q7 stores the key1 + Memory: ct_ptr points to the input data blocks + Memory: Up to the new five blocks in output pt_ptr matche the specification + *) + + ENSURES_WHILE_PAUP_TAC + `0` + `val (num_5blocks_adjusted:int64)` + `pc + 0x170` + `pc + 0x460` + `\i s. + (read X0 s = word_add ct_ptr (word_mul (word 0x50) (word i)) /\ + read X1 s = word_add pt_ptr (word_mul (word 0x50) (word i)) /\ + read X3 s = key1_ptr /\ + read X21 s = tail_len /\ + read X2 s = word_sub num_blocks_adjusted (word_mul (word 0x50) (word i)) /\ + read X8 s = word_sub num_5blocks_adjusted (word i) /\ + read Q6 s = calculate_tweak (i * 5) iv key2 /\ + read Q8 s = calculate_tweak (i * 5 + 1) iv key2 /\ + read Q9 s = calculate_tweak (i * 5 + 2) iv key2 /\ + read Q10 s = calculate_tweak (i * 5 + 3) iv key2 /\ + read Q11 s = calculate_tweak (i * 5 + 4) iv key2 /\ + read X19 s = word 0x87 /\ + read X10 s = word_subword (calculate_tweak (i * 5 + 4) iv key2) (64,64) /\ + read X9 s = word_zx (calculate_tweak (i * 5 + 4) iv key2) /\ + read Q16 s = k00 /\ read Q17 s = k01 /\ read Q12 s = k02 /\ read Q13 s = k03 /\ + read Q14 s = k04 /\ read Q15 s = k05 /\ read Q4 s = k06 /\ read Q5 s = k07 /\ + read Q18 s = k08 /\ read Q19 s = k09 /\ read Q20 s = k0a /\ read Q21 s = k0b /\ + read Q22 s = k0c /\ read Q23 s = k0d /\ read Q7 s = k0e /\ + byte_list_at ct ct_ptr s /\ + byte_list_at (aes256_xts_decrypt ct (i * 5 * 16) iv key1 key2 pt_init) pt_ptr s) /\ + // loop backedge condition + (read ZF s <=> i = val (num_5blocks_adjusted:int64))` THEN + ASM_REWRITE_TAC[] THEN REPEAT CONJ_TAC THENL + [ + (* Subgoal 1. Bound of loop is not zero *) + CHEAT_TAC; + + (* Subgoal 2. Invariant holds before entering the loop *) + REWRITE_TAC[byte_list_at] THEN + ENSURES_INIT_TAC "s0" THEN + ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN + REPEAT CONJ_TAC THENL + [ + WORD_ARITH_TAC; WORD_ARITH_TAC; + CHEAT_TAC; + CHEAT_TAC; + CONV_TAC NUM_REDUCE_CONV; + CONV_TAC NUM_REDUCE_CONV; + CONV_TAC NUM_REDUCE_CONV; + CONV_TAC NUM_REDUCE_CONV; + CONV_TAC NUM_REDUCE_CONV; + CONV_TAC NUM_REDUCE_CONV; + CONV_TAC NUM_REDUCE_CONV; + CONV_TAC NUM_REDUCE_CONV THEN ASM_REWRITE_TAC[byte_list_at] + ]; + + (* Subgoal 3: loop body *) + REPEAT STRIP_TAC THEN + (* ===> Symbolic Simulation: Start symbolic simulation*) + REWRITE_TAC[byte_list_at] THEN + SUBGOAL_THEN `i < LENGTH (ct:byte list) DIV 0x50` ASSUME_TAC THENL + [CHEAT_TAC;ALL_TAC] THEN + SUBGOAL_THEN `~(LENGTH (ct:byte list) < 0x50)` ASSUME_TAC THENL + [CHEAT_TAC;ALL_TAC] THEN + + GHOST_INTRO_TAC `b0:int128` `read (memory :> bytes128 (word_add pt_ptr (word_mul (word 0x50) (word i))))` THEN + GHOST_INTRO_TAC `b1:int128` `read (memory :> bytes128 (word_add (word_add pt_ptr (word_mul (word 0x50) (word i))) (word 0x10)))` THEN + GHOST_INTRO_TAC `b2:int128` `read (memory :> bytes128 (word_add (word_add pt_ptr (word_mul (word 0x50) (word i))) (word 0x20)))` THEN + GHOST_INTRO_TAC `b3:int128` `read (memory :> bytes128 (word_add (word_add pt_ptr (word_mul (word 0x50) (word i))) (word 0x30)))` THEN + GHOST_INTRO_TAC `b4:int128` `read (memory :> bytes128 (word_add (word_add pt_ptr (word_mul (word 0x50) (word i))) (word 0x40)))` THEN + + ENSURES_INIT_TAC "s0" THEN + (* List values for ct_ptr + [0 .. 0x40] *) + MP_TAC (SPECL [`ct_ptr:int64`; `s0:armstate`; `ct:byte list`; `i:num`] READ_CT_LEMMA) THEN + ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (1--151) THEN + (* Prove Q0, Q1, Q24, Q25, Q26 stores correct plaintext *) + (* and prove Q6, Q8, Q9, Q10, Q11 stores correct tweak *) + XTSDEC_TAC `Q0:(armstate,int128)component` `i * 0x50` `i * 0x5` THEN + TWEAK_TAC `Q6:(armstate,int128)component` `i * 5 + 5` `i * 5 + 4` THEN + + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (152--159) THEN + XTSDEC_TAC `Q1:(armstate,int128)component` `i * 0x50 + 0x10` `i * 0x5 + 0x1` THEN + TWEAK_TAC `Q8:(armstate,int128)component` `i * 5 + 6` `i * 5 + 5` THEN + + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (160--167) THEN + XTSDEC_TAC `Q24:(armstate,int128)component` `i * 0x50 + 0x20` `i * 0x5 + 0x2` THEN + TWEAK_TAC `Q9:(armstate,int128)component` `i * 5 + 7` `i * 5 + 6` THEN + + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (168--175) THEN + XTSDEC_TAC `Q25:(armstate,int128)component` `i * 0x50 + 0x30` `i * 0x5 + 0x3` THEN + TWEAK_TAC `Q10:(armstate,int128)component` `i * 5 + 8` `i * 5 + 7` THEN + + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (176--183) THEN + XTSDEC_TAC `Q26:(armstate,int128)component` `i * 0x50 + 0x40` `i * 0x5 + 0x4` THEN + TWEAK_TAC `Q11:(armstate,int128)component` `i * 5 + 9` `i * 5 + 8` THEN + + (* Simulate until end of loop *) + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (184--188) THEN + ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN + REPEAT CONJ_TAC THENL + [ CHEAT_TAC; + CHEAT_TAC; + CHEAT_TAC; + CHEAT_TAC; + CHEAT_TAC; + CHEAT_TAC; + CHEAT_TAC; + CHEAT_TAC; + CHEAT_TAC; + CHEAT_TAC; + CHEAT_TAC; + CHEAT_TAC; + CHEAT_TAC; + CHEAT_TAC; + CHEAT_TAC + ]; + + + (* Subgoal 4: prove backedge is taken if i != val num_5blocks_adjusted *) + REPEAT STRIP_TAC THEN + REWRITE_TAC[byte_list_at] THEN + ENSURES_INIT_TAC "s0" THEN + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (1--1) THEN + SUBGOAL_THEN `~(val (word_sub (num_5blocks_adjusted:int64) (word i)) = 0x0)` ASSUME_TAC THENL + [CHEAT_TAC; ALL_TAC] THEN + POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th])) THEN + ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[]; + + + (* Subgoal 5: Prove the invariant implies post-condition + Backedge instruction is executed here *) + REPEAT STRIP_TAC THEN + REWRITE_TAC[byte_list_at] THEN + SUBGOAL_THEN `~(LENGTH (ct:byte list) < 0x50)` ASSUME_TAC THENL + [CHEAT_TAC;ALL_TAC] THEN + SUBGOAL_THEN `(word (val (num_5blocks_adjusted:int64))):int64 = num_5blocks_adjusted` SUBST_ALL_TAC THENL + [CHEAT_TAC;ALL_TAC] THEN + + GHOST_INTRO_TAC `bt_0:int128` + `read (memory :> bytes128 (word_add pt_ptr (word_mul (word 0x50) (num_5blocks_adjusted:int64))))` THEN + GHOST_INTRO_TAC `bt_1:int128` + `read (memory :> bytes128 (word_add (word_add pt_ptr (word_mul (word 0x50) (num_5blocks_adjusted:int64))) (word 0x10)))` THEN + GHOST_INTRO_TAC `bt_2:int128` + `read (memory :> bytes128 (word_add (word_add (pt_ptr:int64) (word_mul (word 0x50) (num_5blocks_adjusted:int64))) (word 0x20)))` THEN + GHOST_INTRO_TAC `bt_3:int128` + `read (memory :> bytes128 (word_add (word_add (pt_ptr:int64) (word_mul (word 0x50) (num_5blocks_adjusted:int64))) (word 0x30)))` THEN + + ENSURES_INIT_TAC "s0" THEN + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (1--3) THEN + FIRST_X_ASSUM MP_TAC THEN + + COND_CASES_TAC THENL + [ (* Case: len % 0x50 = 0x40 *) + DISCH_TAC THEN + + MP_TAC (SPECL [`ct_ptr:int64`; `s3:armstate`; `ct:byte list`; + `len:int64`; `num_blocks:int64`; `num_5blocks_adjusted:int64`] READ_CT_TAIL4_LEMMA) THEN + ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN + + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (4--125) THEN + XTSDEC_TAC `Q0:(armstate,int128)component` + `val (num_5blocks_adjusted:int64) * 0x10` `val (num_5blocks_adjusted:int64) * 0x5` THEN + XTSDEC_TAC `Q1:(armstate,int128)component` + `val (num_5blocks_adjusted:int64) * 0x10 + 0x10` `val (num_5blocks_adjusted:int64) * 0x5 + 0x1` THEN + XTSDEC_TAC `Q24:(armstate,int128)component` + `val (num_5blocks_adjusted:int64) * 0x10 + 0x20` `val (num_5blocks_adjusted:int64) * 0x5 + 0x2` THEN + XTSDEC_TAC `Q25:(armstate,int128)component` + `val (num_5blocks_adjusted:int64) * 0x10 + 0x30` `val (num_5blocks_adjusted:int64) * 0x5 + 0x3` THEN + + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (126--133) THEN + TWEAK_TAC `Q6:(armstate,int128)component` `val (num_5blocks_adjusted:int64) * 0x5 + 0x4` `val (num_5blocks_adjusted:int64) * 0x5 + 0x3` THEN + + (* The following lemmas are for NONSELFMODIFYING_STATE_UPDATE_TAC when store back to pt_ptr *) + RULE_ASSUM_TAC(REWRITE_RULE + [WORD_RULE `word_mul (word 0x50) num_5blocks_adjusted:int64 = word(0x50 * val num_5blocks_adjusted)`]) THEN + SUBGOAL_THEN `80 * val(num_5blocks_adjusted:int64) + 64 <= val(len:int64)` + ASSUME_TAC THENL [CHEAT_TAC; ALL_TAC] THEN + + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (134--138) THEN + FIRST_X_ASSUM MP_TAC THEN + COND_CASES_TAC THENL + [ + DISCH_TAC THEN + ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN + CHEAT_TAC; + ALL_TAC + ] THEN + (* Cipher stealing branch *) + CHEAT_TAC; + ALL_TAC + ] THEN + + DISCH_TAC THEN + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (4--5) THEN + FIRST_X_ASSUM MP_TAC THEN + COND_CASES_TAC THENL + [ (* Case: len % 0x50 = 0x30 *) + DISCH_TAC THEN + MP_TAC (SPECL [`ct_ptr:int64`; `s5:armstate`; `ct:byte list`; `len:int64`; `num_blocks:int64`; `num_5blocks_adjusted:int64`] READ_CT_TAIL3_LEMMA) THEN + ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN + + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (6--97) THEN + XTSDEC_TAC `Q0:(armstate,int128)component` + `val (num_5blocks_adjusted:int64) * 0x10` `val (num_5blocks_adjusted:int64) * 0x5` THEN + XTSDEC_TAC `Q1:(armstate,int128)component` + `val (num_5blocks_adjusted:int64) * 0x10 + 0x10` `val (num_5blocks_adjusted:int64) * 0x5 + 0x1` THEN + XTSDEC_TAC `Q24:(armstate,int128)component` + `val (num_5blocks_adjusted:int64) * 0x10 + 0x20` `val (num_5blocks_adjusted:int64) * 0x5 + 0x2` THEN + + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (98--105) THEN + TWEAK_TAC `Q6:(armstate,int128)component` `val (num_5blocks_adjusted:int64) * 0x5 + 0x3` `val (num_5blocks_adjusted:int64) * 0x5 + 0x2` THEN + + (* The following lemmas are for NONSELFMODIFYING_STATE_UPDATE_TAC when store back to pt_ptr *) + RULE_ASSUM_TAC(REWRITE_RULE + [WORD_RULE `word_mul (word 0x50) num_5blocks_adjusted:int64 = word(0x50 * val num_5blocks_adjusted)`]) THEN + SUBGOAL_THEN `80 * val(num_5blocks_adjusted:int64) + 48 <= val(len:int64)` + ASSUME_TAC THENL [CHEAT_TAC; ALL_TAC] THEN + + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (106--110) THEN + FIRST_X_ASSUM MP_TAC THEN + COND_CASES_TAC THENL + [ + DISCH_TAC THEN + ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN + CHEAT_TAC; + ALL_TAC + ] THEN + (* Cipher stealing branch *) + CHEAT_TAC; + ALL_TAC + ] THEN + + DISCH_TAC THEN + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (6--7) THEN + FIRST_X_ASSUM MP_TAC THEN + COND_CASES_TAC THENL + [ (* Case: len % 0x50 = 0x20 *) + DISCH_TAC THEN + MP_TAC (SPECL [`ct_ptr:int64`; `s7:armstate`; `ct:byte list`; `len:int64`; `num_blocks:int64`; `num_5blocks_adjusted:int64`] READ_CT_TAIL2_LEMMA) THEN + ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN + + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (8--68) THEN + XTSDEC_TAC `Q0:(armstate,int128)component` + `val (num_5blocks_adjusted:int64) * 0x10` `val (num_5blocks_adjusted:int64) * 0x5` THEN + XTSDEC_TAC `Q1:(armstate,int128)component` + `val (num_5blocks_adjusted:int64) * 0x10 + 0x10` `val (num_5blocks_adjusted:int64) * 0x5 + 0x1` THEN + + (* The following lemmas are for NONSELFMODIFYING_STATE_UPDATE_TAC when store back to pt_ptr *) + RULE_ASSUM_TAC(REWRITE_RULE + [WORD_RULE `word_mul (word 0x50) num_5blocks_adjusted:int64 = word(0x50 * val num_5blocks_adjusted)`]) THEN + SUBGOAL_THEN `80 * val(num_5blocks_adjusted:int64) + 32 <= val(len:int64)` + ASSUME_TAC THENL [CHEAT_TAC; ALL_TAC] THEN + + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (69--77) THEN + TWEAK_TAC `Q6:(armstate,int128)component` `val (num_5blocks_adjusted:int64) * 0x5 + 0x2` `val (num_5blocks_adjusted:int64) * 0x5 + 0x1` THEN + + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (78--80) THEN + FIRST_X_ASSUM MP_TAC THEN + COND_CASES_TAC THENL + [ + DISCH_TAC THEN + ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN + CHEAT_TAC; + ALL_TAC + ] THEN + (* Cipher stealing branch *) + CHEAT_TAC; + ALL_TAC] THEN + + DISCH_TAC THEN + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (8--9) THEN + FIRST_X_ASSUM MP_TAC THEN + COND_CASES_TAC THENL + [ (* Case: len % 0x50 = 0x10 *) + DISCH_TAC THEN + MP_TAC (SPECL [`ct_ptr:int64`; `s9:armstate`; `ct:byte list`; `len:int64`; `num_blocks:int64`; `num_5blocks_adjusted:int64`] READ_CT_TAIL1_LEMMA) THEN + ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN + + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (10--40) THEN + XTSDEC_TAC `Q0:(armstate,int128)component` + `val (num_5blocks_adjusted:int64) * 0x10` `val (num_5blocks_adjusted:int64) * 0x5` THEN + + (* The following lemmas are for NONSELFMODIFYING_STATE_UPDATE_TAC when store back to pt_ptr *) + RULE_ASSUM_TAC(REWRITE_RULE + [WORD_RULE `word_mul (word 0x50) num_5blocks_adjusted:int64 = word(0x50 * val num_5blocks_adjusted)`]) THEN + SUBGOAL_THEN `80 * val(num_5blocks_adjusted:int64) + 16 <= val(len:int64)` + ASSUME_TAC THENL [CHEAT_TAC; ALL_TAC] THEN + + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (41--49) THEN + TWEAK_TAC `Q6:(armstate,int128)component` `val (num_5blocks_adjusted:int64) * 0x5 + 0x1` `val (num_5blocks_adjusted:int64) * 0x5` THEN + + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (50--52) THEN + FIRST_X_ASSUM MP_TAC THEN + COND_CASES_TAC THENL + [ + DISCH_TAC THEN + ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN + CHEAT_TAC; + ALL_TAC + ] THEN + (* Cipher stealing branch *) + CHEAT_TAC; + ALL_TAC] THEN + + (* Case: len % 0x50 = 0 *) + DISCH_TAC THEN + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (10--12) THEN + FIRST_X_ASSUM MP_TAC THEN + COND_CASES_TAC THENL + [ + DISCH_TAC THEN + ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN + CHEAT_TAC; + ALL_TAC + ] THEN + (* Cipher stealing branch *) + CHEAT_TAC + ] +);; diff --git a/arm/proofs/aes_xts_decrypt_spec.ml b/arm/proofs/aes_xts_decrypt_spec.ml index 91d1afe2d..3759537ad 100644 --- a/arm/proofs/aes_xts_decrypt_spec.ml +++ b/arm/proofs/aes_xts_decrypt_spec.ml @@ -172,9 +172,13 @@ let aes256_xts_decrypt = new_definition APPEND (FST res) Ptail`;; (*******************************************) -(* Test vectors *) +(* Test vectors printed from AWS-LC *) (* +The decrypt key schedule is different from encrypt. +This is because AWS-LC uses EQINVCIPHER() for AES decryption. +See 5.3.5 EQINVCIPHER() from NIST.FIPS.197 Advanced Encryption Standard (AES) + key1: c70a951e84370d1836bdd387607e94e5 7ead95d6f74bf6b3103340cce21b473d @@ -564,6 +568,7 @@ time (REWRITE_CONV [iv_tweak;KEY1;KEY2;perror] THENC AES256_XTS_DECRYPT_CONV) (*******************************************) (* Tests *) +(* (* 1 block : 81 second *) time prove (`aes256_xts_decrypt c0 16 iv_tweak KEY1 KEY2 perror = p0`, CONV_TAC(LAND_CONV (REWRITE_CONV [c0;iv_tweak;KEY1;KEY2;perror] THENC AES256_XTS_DECRYPT_CONV)) THEN @@ -574,7 +579,8 @@ time prove(`aes256_xts_decrypt c1 22 iv_tweak KEY1 KEY2 perror = p1`, CONV_TAC(LAND_CONV (REWRITE_CONV [c1;iv_tweak;KEY1;KEY2;perror;p1] THENC AES256_XTS_DECRYPT_CONV)) THEN REWRITE_TAC [p1] THEN REFL_TAC);; -(* 3 blocks + 3 bytes : 206 seconds *) +(* 3 blocks + 3 bytes : 273 seconds *) time prove(`aes256_xts_decrypt c2 51 iv_tweak KEY1 KEY2 perror = p2`, CONV_TAC(LAND_CONV (REWRITE_CONV [c2;iv_tweak;KEY1;KEY2;perror;p2] THENC AES256_XTS_DECRYPT_CONV)) THEN REWRITE_TAC [p2] THEN REFL_TAC);; +*) \ No newline at end of file From bd5a004b4754032b4df50ce2a6863b9b2c46459d Mon Sep 17 00:00:00 2001 From: Yan Peng Date: Wed, 17 Sep 2025 16:14:28 -0700 Subject: [PATCH 032/132] Eliminating some CHEAT_TACs --- arm/proofs/aes_xts_decrypt.ml | 181 +++++++++++++++++++++++++++------- 1 file changed, 143 insertions(+), 38 deletions(-) diff --git a/arm/proofs/aes_xts_decrypt.ml b/arm/proofs/aes_xts_decrypt.ml index 88e238665..4fcad93b2 100644 --- a/arm/proofs/aes_xts_decrypt.ml +++ b/arm/proofs/aes_xts_decrypt.ml @@ -912,6 +912,7 @@ let byte_list_at = define `byte_list_at (m : byte list) (m_p : int64) s = ! i. i < LENGTH m ==> read (memory :> bytes8(word_add m_p (word i))) s = EL i m`;; +(* let tail_len_lt_16_lemma = prove( `!tail_len:int64. word_and len (word 0xf) = tail_len ==> val tail_len < 16`, @@ -931,27 +932,12 @@ let crock_lemma = prove( MP_TAC (SPECL [`a:num`; `b:num`] DIV_EQ_0) THEN ARITH_TAC );; - +*) let word_split_lemma = prove( `!len:int64. len = word_add (word_and len (word 0xf)) (word_and len (word 0xfffffffffffffff0))`, BITBLAST_TAC);; -let blt_lemma = prove( - `!len:int64 x:num. - val len >= x /\ val len < 2 EXP 63 - ==> (ival (word_sub len (word x)) < &0 <=> ~(ival len - &x = ival (word_sub len (word x))))`, - REPEAT STRIP_TAC THEN - CHEAT_TAC);; - -let UDIV_OPT_LEMMA = prove( - `!n:int64. val n < 2 EXP 64 ==> - word_ushr - ((word ((val (word_and n (word 0xfffffffffffffff0)) * 0xcccccccccccccccd) DIV 0x2 EXP 0x40)):int64) - 0x6 = word ((val n) DIV 0x50)`, - REPEAT STRIP_TAC THEN - CHEAT_TAC);; - let READ_CT_LEMMA = prove( `!ct_ptr s ct i. (forall j. @@ -1085,6 +1071,52 @@ let READ_CT_TAIL1_LEMMA = prove( CHEAT_TAC );; +let UDIV_OPT_THM = prove(`!n:num. n < 0x2 EXP 0x40 + ==> (word (val ((word ((n * 0xcccccccccccccccd) DIV 0x2 EXP 0x40)):int64) DIV 0x2 EXP 0x6)):int64 = word (n DIV 0x50)`, + REPEAT STRIP_TAC THEN + REWRITE_TAC[VAL_WORD; DIMINDEX_64] THEN + SUBGOAL_THEN `!p n:num. ~(p = 0) /\ n < p * p ==> n DIV p MOD p = n DIV p` + (MP_TAC o SPECL [`0x2 EXP 0x40`; `n * 0xcccccccccccccccd`]) THENL + [ REPEAT STRIP_TAC THEN + REWRITE_TAC[DIV_MOD] THEN + AP_THM_TAC THEN AP_TERM_TAC THEN + MATCH_MP_TAC MOD_LT THEN + ASM_ARITH_TAC; ALL_TAC] THEN + ANTS_TAC THENL [ASM_ARITH_TAC;ALL_TAC] THEN + DISCH_TAC THEN ASM_REWRITE_TAC[] THEN + AP_TERM_TAC THEN ASM_ARITH_TAC);; + +let NUM_BLOCKS_THM = prove(`!(len:int64) num_blocks tail_len. + len = word_add tail_len num_blocks ==> + word_and len (word 0xfffffffffffffff0) = num_blocks ==> + (word_and (word_add tail_len num_blocks) (word 0xfffffffffffffff0)) = num_blocks`, + BITBLAST_TAC);; + +let TAIL_LEN_THM = prove(`!(len:int64) num_blocks tail_len. + len = word_add tail_len num_blocks ==> + word_and len (word 0xf) = tail_len ==> + (word_and (word_add tail_len num_blocks) (word 0xf)) = tail_len`, + BITBLAST_TAC);; + +let NUM_BLOCKS_BOUND_THM = prove( + `!(len:int64) num_blocks. word_and len (word 0xfffffffffffffff0) = num_blocks + ==> ~(val len < 0x60) + ==> ~(val num_blocks < 0x60)`, + BITBLAST_TAC);; + +let TAIL_LEN_BOUND_THM = prove( + `!(len:int64) tail_len. word_and len (word 0xf) = tail_len + ==> val tail_len < 0x10`, + BITBLAST_TAC);; + +let NUM_BLOCKS_ADJUSTED_BOUND_THM = prove( + `!(num_blocks:int64) (tail_len:int64) num_blocks_adjusted. + (if val tail_len = 0x0 then num_blocks else word_sub num_blocks (word 0x10)) = num_blocks_adjusted + ==> ~(val num_blocks < 0x60) + ==> ~(val num_blocks_adjusted < 0x50)`, + BITBLAST_TAC +);; + let AES_XTS_DECRYPT_CORRECT = prove( `!ct_ptr pt_ptr ct pt_init key1_ptr key2_ptr iv_ptr iv len k00 k01 k02 k03 k04 k05 k06 k07 k08 k09 k0a k0b k0c k0d k0e @@ -1144,6 +1176,23 @@ let AES_XTS_DECRYPT_CORRECT = prove( then num_blocks else word_sub (num_blocks:int64) (word 0x10)` THEN ABBREV_TAC `num_5blocks_adjusted = (word (val (num_blocks_adjusted:int64) DIV 0x50)):int64` THEN + (* Prove once and for all that num_blocks must be greater or equal to six blocks, + num_blocks_adjusted must be greater to equal to five blocks *) + SUBGOAL_THEN `~(val (num_blocks:int64) < 96)` ASSUME_TAC THENL + [ UNDISCH_TAC `~(val (len:int64) < 0x60)` THEN + UNDISCH_TAC `word_and len (word 0xfffffffffffffff0) = (num_blocks:int64)` THEN + MP_TAC (SPECL [`len:int64`; `num_blocks:int64`] NUM_BLOCKS_BOUND_THM) THEN SIMP_TAC[] + ; ALL_TAC] THEN + SUBGOAL_THEN `~(val (num_blocks_adjusted:int64) < 80)` ASSUME_TAC THENL + [ UNDISCH_TAC `~(val (num_blocks:int64) < 96)` THEN + UNDISCH_TAC `(if val (tail_len:int64) = 0x0 + then (num_blocks:int64) + else word_sub num_blocks (word 0x10)) = + num_blocks_adjusted` THEN + MP_TAC (SPECL [`num_blocks:int64`;`tail_len:int64`;`num_blocks_adjusted:int64`] + NUM_BLOCKS_ADJUSTED_BOUND_THM) THEN SIMP_TAC[] + ; ALL_TAC] THEN + (* Verify properties of the program until the beginning of the loop. The properties include the invariant, and a bunch of other initial setup. *) @@ -1175,19 +1224,23 @@ let AES_XTS_DECRYPT_CORRECT = prove( (* ===> Symbolic Simulation: Start symbolic simulation*) ENSURES_INIT_TAC "s0" THEN ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (1--2) THEN + (* Discharge if condition *) SUBGOAL_THEN - `ival (word_sub (word_add (tail_len:int64) (num_blocks:int64)) (word 0x10)) < &0x0 <=> - ~(ival (word_add tail_len num_blocks) - &0x10 = - ival (word_sub (word_add tail_len num_blocks) (word 0x10)))` ASSUME_TAC THENL - [ MATCH_MP_TAC blt_lemma THEN CONJ_TAC THENL - [ UNDISCH_TAC `len:int64 = word_add tail_len num_blocks` THEN - UNDISCH_TAC `val (len:int64) >= 16` THEN - WORD_ARITH_TAC; - UNDISCH_TAC `len:int64 = word_add tail_len num_blocks` THEN - UNDISCH_TAC `val (len:int64) <= 2 EXP 24` THEN - WORD_ARITH_TAC]; + `ival (word_sub (len:int64) (word 0x10)) < &0x0 + <=> ~(ival (len:int64) - &0x10 = ival (word_sub (len:int64) (word 0x10)))` MP_TAC THENL + [ + MP_TAC (BITBLAST_RULE + `val (len:int64) >= 0x10 ==> val len <= 2 EXP 0x18 ==> + ival (word_sub len (word 0x10)) >= &0x0`) THEN + ASM_REWRITE_TAC[] THEN + MP_TAC (BITBLAST_RULE + `val (len:int64) >= 0x10 ==> val len <= 2 EXP 0x18 ==> + ival (len:int64) - &0x10 = ival (word_sub len (word 0x10))`) THEN + ASM_REWRITE_TAC[] THEN + ARITH_TAC; ALL_TAC] THEN + ASM_REWRITE_TAC[] THEN DISCH_TAC THEN POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th])) THEN (* ===> Symbolic Simulation: Symbolic execution for initialization of tweak *) @@ -1207,35 +1260,82 @@ let AES_XTS_DECRYPT_CORRECT = prove( [ (* If there is no tail *) DISCH_TAC THEN + (* Prove val tail_len = 0 and num_blocks = num_blocks_adjusted *) + SUBGOAL_THEN `val (tail_len:int64) = 0` ASSUME_TAC THENL + [ UNDISCH_TAC `val + (word_and (word_and (word_add (tail_len:int64) num_blocks) (word 0xf)) (word 0xf)) = + 0x0` THEN + MP_TAC (SPECL [`len:int64`; `num_blocks:int64`; `tail_len:int64`] TAIL_LEN_THM) THEN + ASM_REWRITE_TAC[] THEN + DISCH_TAC THEN POP_ASSUM(fun th -> REWRITE_TAC[th]) THEN + MP_TAC (SPECL [`len:int64`; `tail_len:int64`] TAIL_LEN_BOUND_THM) THEN + ASM_REWRITE_TAC[] THEN + SUBST1_TAC(ARITH_RULE `0xf = 2 EXP 4 - 1`) THEN + REWRITE_TAC[VAL_WORD_AND_MASK_WORD] THEN + NUM_REDUCE_TAC THEN SIMP_TAC[MOD_LT]; ALL_TAC] THEN + SUBGOAL_THEN `num_blocks_adjusted:int64 = num_blocks:int64` ASSUME_TAC THENL + [ UNDISCH_TAC `(if val (tail_len:int64) = 0x0 + then (num_blocks:int64) + else word_sub num_blocks (word 0x10)) = + num_blocks_adjusted` THEN + UNDISCH_TAC `val (tail_len:int64) = 0` THEN + SIMP_TAC[]; ALL_TAC] THEN + (* Prove x9, x10 stores lower and upper halves and Q8 stores the full tweak *) TWEAK_TAC `Q8:(armstate,int128)component` `1:num` `0:num` THEN ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (90--93) THEN (* Prove the optimized udiv is basically udiv *) - SUBGOAL_THEN `word_ushr ((word ((val (word_and (word_add (tail_len:int64) num_blocks) - (word 0xfffffffffffffff0)) * 0xcccccccccccccccd) DIV 0x2 EXP 0x40)):int64) - 0x6 = word ((val num_blocks) DIV 0x50)` ASSUME_TAC THENL - [ CHEAT_TAC + SUBGOAL_THEN `word_ushr + ((word + ((val + (word_and (word_add (tail_len:int64) num_blocks) + (word 0xfffffffffffffff0)) + * 0xcccccccccccccccd) DIV 0x2 EXP 0x40)):int64) 0x6 = + word ((val num_blocks) DIV 0x50)` ASSUME_TAC THENL + [ + MP_TAC (SPECL [`len:int64`; `num_blocks:int64`; `tail_len:int64`] NUM_BLOCKS_THM) THEN + ASM_REWRITE_TAC[] THEN + DISCH_TAC THEN POP_ASSUM(fun th -> REWRITE_TAC[th]) THEN + MP_TAC (BITBLAST_RULE `val (num_blocks:int64) < 2 EXP 64`) THEN + REWRITE_TAC[word_ushr] THEN + MP_TAC (SPECL [`val (num_blocks:int64)`] UDIV_OPT_THM) THEN SIMP_TAC[] ; ALL_TAC] THEN POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th])) THEN (* Eliminate 1 block case *) ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (94--95) THEN SUBGOAL_THEN `~(val (word_and (word_add (tail_len:int64) num_blocks) (word 0xfffffffffffffff0)) < 0x20)` ASSUME_TAC THENL - [CHEAT_TAC; POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th]))] THEN + [ MP_TAC (SPECL [`len:int64`; `num_blocks:int64`; `tail_len:int64`] NUM_BLOCKS_THM) THEN + ASM_REWRITE_TAC[] THEN + DISCH_TAC THEN POP_ASSUM(fun th -> REWRITE_TAC[th]) THEN + UNDISCH_TAC `~(val (num_blocks:int64) < 0x60)` THEN ARITH_TAC + ; POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th]))] THEN (* Eliminate 2 blocks case *) ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (96--97) THEN SUBGOAL_THEN `~(val (word_and (word_add (tail_len:int64) num_blocks) (word 0xfffffffffffffff0)) < 0x30)` ASSUME_TAC THENL - [CHEAT_TAC; POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th]))] THEN + [ MP_TAC (SPECL [`len:int64`; `num_blocks:int64`; `tail_len:int64`] NUM_BLOCKS_THM) THEN + ASM_REWRITE_TAC[] THEN + DISCH_TAC THEN POP_ASSUM(fun th -> REWRITE_TAC[th]) THEN + UNDISCH_TAC `~(val (num_blocks:int64) < 0x60)` THEN ARITH_TAC + ; POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th]))] THEN (* Eliminate 3 blocks case and prove Q9 stores tweak 2 *) ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (98--105) THEN SUBGOAL_THEN `~(val (word_and (word_add (tail_len:int64) num_blocks) (word 0xfffffffffffffff0)) < 0x40)` ASSUME_TAC THENL - [CHEAT_TAC; POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th]))] THEN + [ MP_TAC (SPECL [`len:int64`; `num_blocks:int64`; `tail_len:int64`] NUM_BLOCKS_THM) THEN + ASM_REWRITE_TAC[] THEN + DISCH_TAC THEN POP_ASSUM(fun th -> REWRITE_TAC[th]) THEN + UNDISCH_TAC `~(val (num_blocks:int64) < 0x60)` THEN ARITH_TAC + ; POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th]))] THEN TWEAK_TAC `Q9:(armstate,int128)component` `2:num` `1:num` THEN (* Eliminate 4 blocks case and Q10 stores tweak 3 *) ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (106--113) THEN SUBGOAL_THEN `~(val (word_and (word_add (tail_len:int64) num_blocks) (word 0xfffffffffffffff0)) < 0x50)` ASSUME_TAC THENL - [CHEAT_TAC; POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th]))] THEN + [ MP_TAC (SPECL [`len:int64`; `num_blocks:int64`; `tail_len:int64`] NUM_BLOCKS_THM) THEN + ASM_REWRITE_TAC[] THEN + DISCH_TAC THEN POP_ASSUM(fun th -> REWRITE_TAC[th]) THEN + UNDISCH_TAC `~(val (num_blocks:int64) < 0x60)` THEN ARITH_TAC + ; POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th]))] THEN TWEAK_TAC `Q10:(armstate,int128)component` `3:num` `2:num` THEN (* Must have 5 blocks, execute until start of loop. Q11 stores tweak 4 *) @@ -1245,12 +1345,17 @@ let AES_XTS_DECRYPT_CORRECT = prove( ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN REPEAT CONJ_TAC THENL [ - CHEAT_TAC; - REWRITE_TAC[SYM (ASSUME `len:int64 = word_add tail_len num_blocks`)] THEN + MP_TAC (SPECL [`len:int64`; `num_blocks:int64`; `tail_len:int64`] NUM_BLOCKS_THM) THEN ASM_REWRITE_TAC[]; - CHEAT_TAC; + MP_TAC (SPECL [`len:int64`; `num_blocks:int64`; `tail_len:int64`] TAIL_LEN_THM) THEN + ASM_REWRITE_TAC[]; + UNDISCH_TAC `word (val (num_blocks_adjusted:int64) DIV 0x50) = (num_5blocks_adjusted:int64)` THEN + UNDISCH_TAC `num_blocks_adjusted:int64 = num_blocks` THEN + SIMP_TAC[]; + ASM_REWRITE_TAC[byte_list_at]; + REWRITE_TAC[aes256_xts_decrypt] THEN + CONV_TAC (DEPTH_CONV NUM_RED_CONV) THEN ASM_REWRITE_TAC[byte_list_at]; - CHEAT_TAC; ASM_REWRITE_TAC[set_key_schedule]] ; ALL_TAC ] THEN From e7f22b822f982218774d07dd7b510d9346dfff7c Mon Sep 17 00:00:00 2001 From: Yan Peng Date: Wed, 17 Sep 2025 16:43:06 -0700 Subject: [PATCH 033/132] Eliminate more CHEAT_TACs and prove a bunch of lemmas --- arm/proofs/aes_xts_decrypt.ml | 988 ++++++++++++++++++++++++---------- 1 file changed, 708 insertions(+), 280 deletions(-) diff --git a/arm/proofs/aes_xts_decrypt.ml b/arm/proofs/aes_xts_decrypt.ml index 4fcad93b2..53743a8b0 100644 --- a/arm/proofs/aes_xts_decrypt.ml +++ b/arm/proofs/aes_xts_decrypt.ml @@ -906,46 +906,344 @@ let AES_XTS_DECRYPT_1BLOCK_CORRECT = prove( (*******************************************) (* Full proof *) -(* Taken from Amanda's code at https://github.com/amanda-zx/s2n-bignum/blob/ed25519/arm/sha512/utils.ml *) - +(* byte_list_at is adapted from Amanda's code at + https://github.com/amanda-zx/s2n-bignum/blob/ed25519/arm/sha512/utils.ml *) let byte_list_at = define - `byte_list_at (m : byte list) (m_p : int64) s = - ! i. i < LENGTH m ==> read (memory :> bytes8(word_add m_p (word i))) s = EL i m`;; + `byte_list_at (m : byte list) (m_p : int64) (len: int64) s = + ! i. i < val len ==> read (memory :> bytes8(word_add m_p (word i))) s = EL i m`;; -(* -let tail_len_lt_16_lemma = prove( - `!tail_len:int64. - word_and len (word 0xf) = tail_len ==> val tail_len < 16`, - BITBLAST_TAC +let word_split_lemma = prove( + `!len:int64. word_add (word_and len (word 0xf)) + (word_and len (word 0xfffffffffffffff0)) = len`, + BITBLAST_TAC);; + +let BYTE_LIST_AT_ADD_ASSUM_TAC new_pos bound = + let rule = subst [new_pos, `new_pos:num`; bound, `bound:num`] + `(pos:num) + bound <= LENGTH (bl:byte list) ==> new_pos < LENGTH bl` in + let p = subst [new_pos, `new_pos:num`] `new_pos:num` in + MP_TAC (ARITH_RULE rule) THEN + ASM_REWRITE_TAC[] THEN DISCH_THEN (LABEL_TAC "tmp") THEN + FIRST_ASSUM(fun th -> MP_TAC(SPEC p th)) THEN + USE_THEN "tmp" (fun th -> REWRITE_TAC[th]) THEN + POP_ASSUM (K ALL_TAC);; + +let BYTES128_TO_BYTES8_THM = prove( + `!pos bl_ptr s. + read (memory :> bytes128 (word_add bl_ptr (word pos))) s = + bytes_to_int128 + [read (memory :> bytes8 (word_add bl_ptr (word (pos + 0x0)))) s; + read (memory :> bytes8 (word_add bl_ptr (word (pos + 0x1)))) s; + read (memory :> bytes8 (word_add bl_ptr (word (pos + 0x2)))) s; + read (memory :> bytes8 (word_add bl_ptr (word (pos + 0x3)))) s; + read (memory :> bytes8 (word_add bl_ptr (word (pos + 0x4)))) s; + read (memory :> bytes8 (word_add bl_ptr (word (pos + 0x5)))) s; + read (memory :> bytes8 (word_add bl_ptr (word (pos + 0x6)))) s; + read (memory :> bytes8 (word_add bl_ptr (word (pos + 0x7)))) s; + read (memory :> bytes8 (word_add bl_ptr (word (pos + 0x8)))) s; + read (memory :> bytes8 (word_add bl_ptr (word (pos + 0x9)))) s; + read (memory :> bytes8 (word_add bl_ptr (word (pos + 0xa)))) s; + read (memory :> bytes8 (word_add bl_ptr (word (pos + 0xb)))) s; + read (memory :> bytes8 (word_add bl_ptr (word (pos + 0xc)))) s; + read (memory :> bytes8 (word_add bl_ptr (word (pos + 0xd)))) s; + read (memory :> bytes8 (word_add bl_ptr (word (pos + 0xe)))) s; + read (memory :> bytes8 (word_add bl_ptr (word (pos + 0xf)))) s]`, + REPEAT STRIP_TAC THEN + REWRITE_TAC[bytes_to_int128] THEN + REWRITE_TAC EL_16_8_CLAUSES THEN + GEN_REWRITE_TAC TOP_DEPTH_CONV [READ_MEMORY_BYTESIZED_SPLIT; WORD_ADD_ASSOC_CONSTS] THEN + CONV_TAC(DEPTH_CONV WORD_NUM_RED_CONV) THEN + ONCE_REWRITE_TAC [ARITH_RULE `pos + 0 = (pos:num)`] THEN + REFL_TAC );; -let num_blocks_ge_80_lemma = prove( - `!num_blocks:int64. - word_and len (word 0xfffffffffffffff0) = num_blocks /\ val len >= 0x50 - ==> val num_blocks >= 0x50`, - BITBLAST_TAC +let SUB_LIST_SUCSPLIT = prove( + `!(l:A list) n p. SUB_LIST(p,SUC n) l = APPEND (SUB_LIST(p,1) l) (SUB_LIST(p+1,n) l)`, + REPEAT STRIP_TAC THEN + REWRITE_TAC [ARITH_RULE `SUC n = 1 + n`] THEN + REWRITE_TAC [SUB_LIST_SPLIT] );; -let crock_lemma = prove( - `!a:num b:num. a >= b /\ b > 0 ==> ~(a DIV b = 0)`, - REPEAT GEN_TAC THEN - MP_TAC (SPECL [`a:num`; `b:num`] DIV_EQ_0) THEN - ARITH_TAC +let SUB_LIST_16_TAC n exp = + let subgoal = subst [exp, `exp:num`] `exp < LENGTH (l:A list)` in + CONV_TAC(RAND_CONV (REWRITE_CONV[num_CONV n; SUB_LIST_SUCSPLIT])) THEN + SUBGOAL_THEN subgoal ASSUME_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN + REWRITE_TAC[SUB_LIST_1] THEN ASM_SIMP_TAC[GSYM ADD_ASSOC] THEN NUM_REDUCE_TAC;; + +let SUB_LIST_16 = prove( + `!(l:A list) n. n + 16 <= LENGTH l ==> + [ EL (n + 0) l; EL (n + 1) l; EL (n + 2) l; EL (n + 3) l; + EL (n + 4) l; EL (n + 5) l; EL (n + 6) l; EL (n + 7) l; + EL (n + 8) l; EL (n + 9) l; EL (n + 10) l; EL (n + 11) l; + EL (n + 12) l; EL (n + 13) l; EL (n + 14) l; EL (n + 15) l + ] = SUB_LIST (n,16) l`, + REPEAT STRIP_TAC THEN + MAP_EVERY (fun i -> + if i == 0 + then SUB_LIST_16_TAC `0x10` `n:num` + else SUB_LIST_16_TAC (mk_numeral (num (16 - i))) + (mk_binop (mk_const("+", [`:num`, `:A`])) (mk_var("n", `:num`)) + (mk_numeral (num i)))) (0--14) THEN + SUBGOAL_THEN `n + 15 < LENGTH (l:A list)` ASSUME_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[APPEND; ARITH_RULE `n + 0 = n`] +);; + +let BYTE_LIST_AT_5BLOCKS = prove( + `! pos bl bl_ptr len s. + byte_list_at bl bl_ptr len s + ==> LENGTH bl = val len + ==> pos + 0x50 <= LENGTH bl + ==> (read (memory :> bytes128 (word_add bl_ptr (word pos))) s = + bytes_to_int128 (SUB_LIST (pos, 0x10) bl) /\ + read (memory :> bytes128 (word_add (word_add bl_ptr (word pos)) (word 0x10))) s = + bytes_to_int128 (SUB_LIST (pos + 0x10, 0x10) bl) /\ + read (memory :> bytes128 (word_add (word_add bl_ptr (word pos)) (word 0x20))) s = + bytes_to_int128 (SUB_LIST (pos + 0x20, 0x10) bl) /\ + read (memory :> bytes128 (word_add (word_add bl_ptr (word pos)) (word 0x30))) s = + bytes_to_int128 (SUB_LIST (pos + 0x30, 0x10) bl) /\ + read (memory :> bytes128 (word_add (word_add bl_ptr (word pos)) (word 0x40))) s = + bytes_to_int128 (SUB_LIST (pos + 0x40, 0x10) bl))`, + REWRITE_TAC[byte_list_at] THEN + REPEAT STRIP_TAC THENL + (* TODO: simplify *) + [ (* Subgoal1 *) + MAP_EVERY (fun i -> BYTE_LIST_AT_ADD_ASSUM_TAC + (mk_binop (mk_const("+", [`:num`, `:A`])) (mk_var("pos", `:num`)) + (mk_numeral (num i))) `0x50`) (0--15) THEN + REWRITE_TAC[WORD_ADD_ASSOC_CONSTS] THEN + REPEAT STRIP_TAC THEN + ASM_REWRITE_TAC[BYTES128_TO_BYTES8_THM; GSYM ADD_ASSOC] THEN + NUM_REDUCE_TAC THEN ASM_REWRITE_TAC[] THEN AP_TERM_TAC THEN + MP_TAC (ISPECL [`bl:byte list`; `pos:num`] SUB_LIST_16) THEN + REWRITE_TAC[GSYM ADD_ASSOC] THEN NUM_REDUCE_TAC THEN + DISCH_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_ARITH_TAC; + (* Subgoal2 *) + MAP_EVERY (fun i -> BYTE_LIST_AT_ADD_ASSUM_TAC + (mk_binop (mk_const("+", [`:num`, `:A`])) (mk_var("pos", `:num`)) + (mk_numeral (num i))) `0x50`) (16--31) THEN + REWRITE_TAC[WORD_ADD_ASSOC_CONSTS] THEN + REPEAT STRIP_TAC THEN + ASM_REWRITE_TAC[BYTES128_TO_BYTES8_THM; GSYM ADD_ASSOC] THEN + NUM_REDUCE_TAC THEN ASM_REWRITE_TAC[] THEN AP_TERM_TAC THEN + MP_TAC (ISPECL [`bl:byte list`; `(pos+0x10):num`] SUB_LIST_16) THEN + REWRITE_TAC[GSYM ADD_ASSOC] THEN NUM_REDUCE_TAC THEN + DISCH_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_ARITH_TAC; + (* Subgoal3 *) + MAP_EVERY (fun i -> BYTE_LIST_AT_ADD_ASSUM_TAC + (mk_binop (mk_const("+", [`:num`, `:A`])) (mk_var("pos", `:num`)) + (mk_numeral (num i))) `0x50`) (32--47) THEN + REWRITE_TAC[WORD_ADD_ASSOC_CONSTS] THEN + REPEAT STRIP_TAC THEN + ASM_REWRITE_TAC[BYTES128_TO_BYTES8_THM; GSYM ADD_ASSOC] THEN + NUM_REDUCE_TAC THEN ASM_REWRITE_TAC[] THEN AP_TERM_TAC THEN + MP_TAC (ISPECL [`bl:byte list`; `(pos+0x20):num`] SUB_LIST_16) THEN + REWRITE_TAC[GSYM ADD_ASSOC] THEN NUM_REDUCE_TAC THEN + DISCH_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_ARITH_TAC; + (* Subgoal4 *) + MAP_EVERY (fun i -> BYTE_LIST_AT_ADD_ASSUM_TAC + (mk_binop (mk_const("+", [`:num`, `:A`])) (mk_var("pos", `:num`)) + (mk_numeral (num i))) `0x50`) (48--63) THEN + REWRITE_TAC[WORD_ADD_ASSOC_CONSTS] THEN + REPEAT STRIP_TAC THEN + ASM_REWRITE_TAC[BYTES128_TO_BYTES8_THM; GSYM ADD_ASSOC] THEN + NUM_REDUCE_TAC THEN ASM_REWRITE_TAC[] THEN AP_TERM_TAC THEN + MP_TAC (ISPECL [`bl:byte list`; `(pos+0x30):num`] SUB_LIST_16) THEN + REWRITE_TAC[GSYM ADD_ASSOC] THEN NUM_REDUCE_TAC THEN + DISCH_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_ARITH_TAC; + (* Subgoal 5 *) + MAP_EVERY (fun i -> BYTE_LIST_AT_ADD_ASSUM_TAC + (mk_binop (mk_const("+", [`:num`, `:A`])) (mk_var("pos", `:num`)) + (mk_numeral (num i))) `0x50`) (64--79) THEN + REWRITE_TAC[WORD_ADD_ASSOC_CONSTS] THEN + REPEAT STRIP_TAC THEN + ASM_REWRITE_TAC[BYTES128_TO_BYTES8_THM; GSYM ADD_ASSOC] THEN + NUM_REDUCE_TAC THEN ASM_REWRITE_TAC[] THEN AP_TERM_TAC THEN + MP_TAC (ISPECL [`bl:byte list`; `(pos+0x40):num`] SUB_LIST_16) THEN + REWRITE_TAC[GSYM ADD_ASSOC] THEN NUM_REDUCE_TAC THEN + DISCH_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_ARITH_TAC + ] +);; + +let BYTE_LIST_AT_4BLOCKS = prove( + `! pos bl bl_ptr len s. + byte_list_at bl bl_ptr len s + ==> LENGTH bl = val len + ==> pos + 0x40 <= LENGTH bl + ==> (read (memory :> bytes128 (word_add bl_ptr (word pos))) s = + bytes_to_int128 (SUB_LIST (pos, 0x10) bl) /\ + read (memory :> bytes128 (word_add (word_add bl_ptr (word pos)) (word 0x10))) s = + bytes_to_int128 (SUB_LIST (pos + 0x10, 0x10) bl) /\ + read (memory :> bytes128 (word_add (word_add bl_ptr (word pos)) (word 0x20))) s = + bytes_to_int128 (SUB_LIST (pos + 0x20, 0x10) bl) /\ + read (memory :> bytes128 (word_add (word_add bl_ptr (word pos)) (word 0x30))) s = + bytes_to_int128 (SUB_LIST (pos + 0x30, 0x10) bl))`, + REWRITE_TAC[byte_list_at] THEN + REPEAT STRIP_TAC THENL + (* TODO: simplify *) + [ (* Subgoal1 *) + MAP_EVERY (fun i -> BYTE_LIST_AT_ADD_ASSUM_TAC + (mk_binop (mk_const("+", [`:num`, `:A`])) (mk_var("pos", `:num`)) + (mk_numeral (num i))) `0x40`) (0--15) THEN + REWRITE_TAC[WORD_ADD_ASSOC_CONSTS] THEN + REPEAT STRIP_TAC THEN + ASM_REWRITE_TAC[BYTES128_TO_BYTES8_THM; GSYM ADD_ASSOC] THEN + NUM_REDUCE_TAC THEN ASM_REWRITE_TAC[] THEN AP_TERM_TAC THEN + MP_TAC (ISPECL [`bl:byte list`; `pos:num`] SUB_LIST_16) THEN + REWRITE_TAC[GSYM ADD_ASSOC] THEN NUM_REDUCE_TAC THEN + DISCH_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_ARITH_TAC; + (* Subgoal2 *) + MAP_EVERY (fun i -> BYTE_LIST_AT_ADD_ASSUM_TAC + (mk_binop (mk_const("+", [`:num`, `:A`])) (mk_var("pos", `:num`)) + (mk_numeral (num i))) `0x40`) (16--31) THEN + REWRITE_TAC[WORD_ADD_ASSOC_CONSTS] THEN + REPEAT STRIP_TAC THEN + ASM_REWRITE_TAC[BYTES128_TO_BYTES8_THM; GSYM ADD_ASSOC] THEN + NUM_REDUCE_TAC THEN ASM_REWRITE_TAC[] THEN AP_TERM_TAC THEN + MP_TAC (ISPECL [`bl:byte list`; `(pos+0x10):num`] SUB_LIST_16) THEN + REWRITE_TAC[GSYM ADD_ASSOC] THEN NUM_REDUCE_TAC THEN + DISCH_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_ARITH_TAC; + (* Subgoal3 *) + MAP_EVERY (fun i -> BYTE_LIST_AT_ADD_ASSUM_TAC + (mk_binop (mk_const("+", [`:num`, `:A`])) (mk_var("pos", `:num`)) + (mk_numeral (num i))) `0x40`) (32--47) THEN + REWRITE_TAC[WORD_ADD_ASSOC_CONSTS] THEN + REPEAT STRIP_TAC THEN + ASM_REWRITE_TAC[BYTES128_TO_BYTES8_THM; GSYM ADD_ASSOC] THEN + NUM_REDUCE_TAC THEN ASM_REWRITE_TAC[] THEN AP_TERM_TAC THEN + MP_TAC (ISPECL [`bl:byte list`; `(pos+0x20):num`] SUB_LIST_16) THEN + REWRITE_TAC[GSYM ADD_ASSOC] THEN NUM_REDUCE_TAC THEN + DISCH_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_ARITH_TAC; + (* Subgoal4 *) + MAP_EVERY (fun i -> BYTE_LIST_AT_ADD_ASSUM_TAC + (mk_binop (mk_const("+", [`:num`, `:A`])) (mk_var("pos", `:num`)) + (mk_numeral (num i))) `0x40`) (48--63) THEN + REWRITE_TAC[WORD_ADD_ASSOC_CONSTS] THEN + REPEAT STRIP_TAC THEN + ASM_REWRITE_TAC[BYTES128_TO_BYTES8_THM; GSYM ADD_ASSOC] THEN + NUM_REDUCE_TAC THEN ASM_REWRITE_TAC[] THEN AP_TERM_TAC THEN + MP_TAC (ISPECL [`bl:byte list`; `(pos+0x30):num`] SUB_LIST_16) THEN + REWRITE_TAC[GSYM ADD_ASSOC] THEN NUM_REDUCE_TAC THEN + DISCH_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_ARITH_TAC + ] +);; + +let BYTE_LIST_AT_3BLOCKS = prove( + `! pos bl bl_ptr len s. + byte_list_at bl bl_ptr len s + ==> LENGTH bl = val len + ==> pos + 0x30 <= LENGTH bl + ==> (read (memory :> bytes128 (word_add bl_ptr (word pos))) s = + bytes_to_int128 (SUB_LIST (pos, 0x10) bl) /\ + read (memory :> bytes128 (word_add (word_add bl_ptr (word pos)) (word 0x10))) s = + bytes_to_int128 (SUB_LIST (pos + 0x10, 0x10) bl) /\ + read (memory :> bytes128 (word_add (word_add bl_ptr (word pos)) (word 0x20))) s = + bytes_to_int128 (SUB_LIST (pos + 0x20, 0x10) bl))`, + REWRITE_TAC[byte_list_at] THEN + REPEAT STRIP_TAC THENL + (* TODO: simplify *) + [ (* Subgoal1 *) + MAP_EVERY (fun i -> BYTE_LIST_AT_ADD_ASSUM_TAC + (mk_binop (mk_const("+", [`:num`, `:A`])) (mk_var("pos", `:num`)) + (mk_numeral (num i))) `0x30`) (0--15) THEN + REWRITE_TAC[WORD_ADD_ASSOC_CONSTS] THEN + REPEAT STRIP_TAC THEN + ASM_REWRITE_TAC[BYTES128_TO_BYTES8_THM; GSYM ADD_ASSOC] THEN + NUM_REDUCE_TAC THEN ASM_REWRITE_TAC[] THEN AP_TERM_TAC THEN + MP_TAC (ISPECL [`bl:byte list`; `pos:num`] SUB_LIST_16) THEN + REWRITE_TAC[GSYM ADD_ASSOC] THEN NUM_REDUCE_TAC THEN + DISCH_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_ARITH_TAC; + (* Subgoal2 *) + MAP_EVERY (fun i -> BYTE_LIST_AT_ADD_ASSUM_TAC + (mk_binop (mk_const("+", [`:num`, `:A`])) (mk_var("pos", `:num`)) + (mk_numeral (num i))) `0x30`) (16--31) THEN + REWRITE_TAC[WORD_ADD_ASSOC_CONSTS] THEN + REPEAT STRIP_TAC THEN + ASM_REWRITE_TAC[BYTES128_TO_BYTES8_THM; GSYM ADD_ASSOC] THEN + NUM_REDUCE_TAC THEN ASM_REWRITE_TAC[] THEN AP_TERM_TAC THEN + MP_TAC (ISPECL [`bl:byte list`; `(pos+0x10):num`] SUB_LIST_16) THEN + REWRITE_TAC[GSYM ADD_ASSOC] THEN NUM_REDUCE_TAC THEN + DISCH_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_ARITH_TAC; + (* Subgoal3 *) + MAP_EVERY (fun i -> BYTE_LIST_AT_ADD_ASSUM_TAC + (mk_binop (mk_const("+", [`:num`, `:A`])) (mk_var("pos", `:num`)) + (mk_numeral (num i))) `0x30`) (32--47) THEN + REWRITE_TAC[WORD_ADD_ASSOC_CONSTS] THEN + REPEAT STRIP_TAC THEN + ASM_REWRITE_TAC[BYTES128_TO_BYTES8_THM; GSYM ADD_ASSOC] THEN + NUM_REDUCE_TAC THEN ASM_REWRITE_TAC[] THEN AP_TERM_TAC THEN + MP_TAC (ISPECL [`bl:byte list`; `(pos+0x20):num`] SUB_LIST_16) THEN + REWRITE_TAC[GSYM ADD_ASSOC] THEN NUM_REDUCE_TAC THEN + DISCH_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_ARITH_TAC + ] +);; + +let BYTE_LIST_AT_2BLOCKS = prove( + `! pos bl bl_ptr len s. + byte_list_at bl bl_ptr len s + ==> LENGTH bl = val len + ==> pos + 0x20 <= LENGTH bl + ==> (read (memory :> bytes128 (word_add bl_ptr (word pos))) s = + bytes_to_int128 (SUB_LIST (pos, 0x10) bl) /\ + read (memory :> bytes128 (word_add (word_add bl_ptr (word pos)) (word 0x10))) s = + bytes_to_int128 (SUB_LIST (pos + 0x10, 0x10) bl))`, + REWRITE_TAC[byte_list_at] THEN + REPEAT STRIP_TAC THENL + (* TODO: simplify *) + [ (* Subgoal1 *) + MAP_EVERY (fun i -> BYTE_LIST_AT_ADD_ASSUM_TAC + (mk_binop (mk_const("+", [`:num`, `:A`])) (mk_var("pos", `:num`)) + (mk_numeral (num i))) `0x20`) (0--15) THEN + REWRITE_TAC[WORD_ADD_ASSOC_CONSTS] THEN + REPEAT STRIP_TAC THEN + ASM_REWRITE_TAC[BYTES128_TO_BYTES8_THM; GSYM ADD_ASSOC] THEN + NUM_REDUCE_TAC THEN ASM_REWRITE_TAC[] THEN AP_TERM_TAC THEN + MP_TAC (ISPECL [`bl:byte list`; `pos:num`] SUB_LIST_16) THEN + REWRITE_TAC[GSYM ADD_ASSOC] THEN NUM_REDUCE_TAC THEN + DISCH_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_ARITH_TAC; + (* Subgoal2 *) + MAP_EVERY (fun i -> BYTE_LIST_AT_ADD_ASSUM_TAC + (mk_binop (mk_const("+", [`:num`, `:A`])) (mk_var("pos", `:num`)) + (mk_numeral (num i))) `0x20`) (16--31) THEN + REWRITE_TAC[WORD_ADD_ASSOC_CONSTS] THEN + REPEAT STRIP_TAC THEN + ASM_REWRITE_TAC[BYTES128_TO_BYTES8_THM; GSYM ADD_ASSOC] THEN + NUM_REDUCE_TAC THEN ASM_REWRITE_TAC[] THEN AP_TERM_TAC THEN + MP_TAC (ISPECL [`bl:byte list`; `(pos+0x10):num`] SUB_LIST_16) THEN + REWRITE_TAC[GSYM ADD_ASSOC] THEN NUM_REDUCE_TAC THEN + DISCH_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_ARITH_TAC + ] +);; + +let BYTE_LIST_AT_1BLOCKS = prove( + `! pos bl bl_ptr len s. + byte_list_at bl bl_ptr len s + ==> LENGTH bl = val len + ==> pos + 0x10 <= LENGTH bl + ==> read (memory :> bytes128 (word_add bl_ptr (word pos))) s = + bytes_to_int128 (SUB_LIST (pos, 0x10) bl)`, + REWRITE_TAC[byte_list_at] THEN + REPEAT STRIP_TAC THENL + (* TODO: simplify *) + [ (* Subgoal1 *) + MAP_EVERY (fun i -> BYTE_LIST_AT_ADD_ASSUM_TAC + (mk_binop (mk_const("+", [`:num`, `:A`])) (mk_var("pos", `:num`)) + (mk_numeral (num i))) `0x10`) (0--15) THEN + REWRITE_TAC[WORD_ADD_ASSOC_CONSTS] THEN + REPEAT STRIP_TAC THEN + ASM_REWRITE_TAC[BYTES128_TO_BYTES8_THM; GSYM ADD_ASSOC] THEN + NUM_REDUCE_TAC THEN ASM_REWRITE_TAC[] THEN AP_TERM_TAC THEN + MP_TAC (ISPECL [`bl:byte list`; `pos:num`] SUB_LIST_16) THEN + REWRITE_TAC[GSYM ADD_ASSOC] THEN NUM_REDUCE_TAC THEN + DISCH_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_ARITH_TAC + ] );; -*) -let word_split_lemma = prove( - `!len:int64. len = word_add (word_and len (word 0xf)) - (word_and len (word 0xfffffffffffffff0))`, - BITBLAST_TAC);; let READ_CT_LEMMA = prove( - `!ct_ptr s ct i. - (forall j. - j < LENGTH ct - ==> read (memory :> bytes8 (word_add ct_ptr (word j))) s = EL j ct) - /\ ~(LENGTH ct < 0x50) - /\ i < LENGTH ct DIV 0x50 ==> - read (memory :> bytes128 (word_add ct_ptr (word_mul (word 0x50) (word i)))) s0 = + `!ct_ptr i (len:int64) (ct:byte list) s. + (forall j. j < val len ==> read (memory :> bytes8 (word_add ct_ptr (word j))) s = EL j ct) + /\ i * 0x50 + 0x50 <= val len + /\ LENGTH ct = val len + ==> + read (memory :> bytes128 (word_add ct_ptr (word_mul (word 0x50) (word i)))) s = bytes_to_int128 (SUB_LIST (i * 80, 16) ct) /\ read (memory :> bytes128 (word_add (word_add ct_ptr (word_mul (word 0x50) (word i))) (word 0x10))) s = bytes_to_int128 (SUB_LIST (i * 80 + 16, 16) ct) /\ @@ -956,119 +1254,108 @@ let READ_CT_LEMMA = prove( read (memory :> bytes128 (word_add (word_add ct_ptr (word_mul (word 0x50) (word i))) (word 0x40))) s = bytes_to_int128 (SUB_LIST (i * 80 + 64, 16) ct) `, - CHEAT_TAC + REPEAT GEN_TAC THEN STRIP_TAC THEN + REWRITE_TAC [WORD_RULE `word_mul (word 0x50) (word i) = word (i * 80)`] THEN + MP_TAC + (SPECL [`(i * 80):num`; `ct:byte list`; `ct_ptr:int64`; `len:int64`; `s:armstate`] + BYTE_LIST_AT_5BLOCKS) THEN + REWRITE_TAC[byte_list_at] THEN ASM_SIMP_TAC[] );; let READ_CT_TAIL4_LEMMA = prove( - `!ct_ptr s ct len (num_blocks:int64) (num_5blocks_adjusted:int64). - (forall j. - j < LENGTH ct - ==> read (memory :> bytes8 (word_add ct_ptr (word j))) s = EL j ct) - /\ ~(LENGTH ct < 0x50) - /\ val len = LENGTH ct - /\ word_and len (word 0xfffffffffffffff0) = num_blocks - /\ val - (word_sub - (word_sub (num_blocks_adjusted:int64) - (word_mul (word 0x50) num_5blocks_adjusted)) - (word 0x40)) = - 0x0 + `!ct_ptr (num_5blocks_adjusted:int64) (len:int64) (ct:byte list) s. + (forall j. j < val len ==> read (memory :> bytes8 (word_add ct_ptr (word j))) s = EL j ct) + /\ val num_5blocks_adjusted * 0x50 + 0x40 <= val len + /\ LENGTH ct = val len ==> read (memory :> bytes128 (word_add (word_add ct_ptr (word_mul (word 0x50) num_5blocks_adjusted)) (word 0x30))) s = - bytes_to_int128 (SUB_LIST (val num_5blocks_adjusted * 16 + 0x30, 16) ct) /\ + bytes_to_int128 (SUB_LIST (val num_5blocks_adjusted * 80 + 0x30, 16) ct) /\ read (memory :> bytes128 (word_add (word_add ct_ptr (word_mul (word 0x50) num_5blocks_adjusted)) (word 0x20))) s = - bytes_to_int128 (SUB_LIST (val num_5blocks_adjusted * 16 + 0x20, 16) ct) /\ + bytes_to_int128 (SUB_LIST (val num_5blocks_adjusted * 80 + 0x20, 16) ct) /\ read (memory :> bytes128 (word_add (word_add ct_ptr (word_mul (word 0x50) num_5blocks_adjusted)) (word 0x10))) s = - bytes_to_int128 (SUB_LIST (val num_5blocks_adjusted * 16 + 0x10, 16) ct) /\ + bytes_to_int128 (SUB_LIST (val num_5blocks_adjusted * 80 + 0x10, 16) ct) /\ read (memory :> bytes128 (word_add ct_ptr (word_mul (word 0x50) num_5blocks_adjusted))) s = - bytes_to_int128 (SUB_LIST (val num_5blocks_adjusted * 16, 16) ct) + bytes_to_int128 (SUB_LIST (val num_5blocks_adjusted * 80, 16) ct) `, - CHEAT_TAC + REPEAT GEN_TAC THEN STRIP_TAC THEN + REWRITE_TAC [WORD_RULE `(word_mul (word 0x50) (num_5blocks_adjusted:int64)) = word (val num_5blocks_adjusted * 80)`] THEN + MP_TAC + (SPECL [`(val (num_5blocks_adjusted:int64) * 80):num`; `ct:byte list`; `ct_ptr:int64`; `len:int64`; `s:armstate`] + BYTE_LIST_AT_4BLOCKS) THEN + REWRITE_TAC[byte_list_at] THEN ASM_SIMP_TAC[] );; let READ_CT_TAIL3_LEMMA = prove( - `!ct_ptr s ct len (num_blocks:int64) (num_5blocks_adjusted:int64). - (forall j. - j < LENGTH ct - ==> read (memory :> bytes8 (word_add ct_ptr (word j))) s = EL j ct) - /\ ~(LENGTH ct < 0x50) - /\ val len = LENGTH ct - /\ word_and len (word 0xfffffffffffffff0) = num_blocks - /\ val - (word_sub - (word_sub (num_blocks_adjusted:int64) - (word_mul (word 0x50) num_5blocks_adjusted)) - (word 0x30)) = - 0x0 + `!ct_ptr (num_5blocks_adjusted:int64) (len:int64) (ct:byte list) s. + (forall j. j < val len ==> read (memory :> bytes8 (word_add ct_ptr (word j))) s = EL j ct) + /\ val num_5blocks_adjusted * 0x50 + 0x30 <= val len + /\ LENGTH ct = val len ==> read (memory :> bytes128 (word_add (word_add ct_ptr (word_mul (word 0x50) num_5blocks_adjusted)) (word 0x20))) s = - bytes_to_int128 (SUB_LIST (val num_5blocks_adjusted * 16 + 0x20, 16) ct) /\ + bytes_to_int128 (SUB_LIST (val num_5blocks_adjusted * 80 + 0x20, 16) ct) /\ read (memory :> bytes128 (word_add (word_add ct_ptr (word_mul (word 0x50) num_5blocks_adjusted)) (word 0x10))) s = - bytes_to_int128 (SUB_LIST (val num_5blocks_adjusted * 16 + 0x10, 16) ct) /\ + bytes_to_int128 (SUB_LIST (val num_5blocks_adjusted * 80 + 0x10, 16) ct) /\ read (memory :> bytes128 (word_add ct_ptr (word_mul (word 0x50) num_5blocks_adjusted))) s = - bytes_to_int128 (SUB_LIST (val num_5blocks_adjusted * 16, 16) ct) + bytes_to_int128 (SUB_LIST (val num_5blocks_adjusted * 80, 16) ct) `, - CHEAT_TAC + REPEAT GEN_TAC THEN STRIP_TAC THEN + REWRITE_TAC [WORD_RULE `(word_mul (word 0x50) (num_5blocks_adjusted:int64)) = word (val num_5blocks_adjusted * 80)`] THEN + MP_TAC + (SPECL [`(val (num_5blocks_adjusted:int64) * 80):num`; `ct:byte list`; `ct_ptr:int64`; `len:int64`; `s:armstate`] + BYTE_LIST_AT_3BLOCKS) THEN + REWRITE_TAC[byte_list_at] THEN ASM_SIMP_TAC[] );; let READ_CT_TAIL2_LEMMA = prove( - `!ct_ptr s ct len (num_blocks:int64) (num_5blocks_adjusted:int64). - (forall j. - j < LENGTH ct - ==> read (memory :> bytes8 (word_add ct_ptr (word j))) s = EL j ct) - /\ ~(LENGTH ct < 0x50) - /\ val len = LENGTH ct - /\ word_and len (word 0xfffffffffffffff0) = num_blocks - /\ val - (word_sub - (word_sub num_blocks_adjusted - (word_mul (word 0x50) num_5blocks_adjusted)) - (word 0x20)) = - 0x0 + `!ct_ptr (num_5blocks_adjusted:int64) (len:int64) (ct:byte list) s. + (forall j. j < val len ==> read (memory :> bytes8 (word_add ct_ptr (word j))) s = EL j ct) + /\ val num_5blocks_adjusted * 0x50 + 0x20 <= val len + /\ LENGTH ct = val len ==> read (memory :> bytes128 (word_add (word_add ct_ptr (word_mul (word 0x50) num_5blocks_adjusted)) (word 0x10))) s = - bytes_to_int128 (SUB_LIST (val num_5blocks_adjusted * 16 + 0x10, 16) ct) /\ + bytes_to_int128 (SUB_LIST (val num_5blocks_adjusted * 80 + 0x10, 16) ct) /\ read (memory :> bytes128 (word_add ct_ptr (word_mul (word 0x50) num_5blocks_adjusted))) s = - bytes_to_int128 (SUB_LIST (val num_5blocks_adjusted * 16, 16) ct) + bytes_to_int128 (SUB_LIST (val num_5blocks_adjusted * 80, 16) ct) `, - CHEAT_TAC + REPEAT GEN_TAC THEN STRIP_TAC THEN + REWRITE_TAC [WORD_RULE `(word_mul (word 0x50) (num_5blocks_adjusted:int64)) = word (val num_5blocks_adjusted * 80)`] THEN + MP_TAC + (SPECL [`(val (num_5blocks_adjusted:int64) * 80):num`; `ct:byte list`; `ct_ptr:int64`; `len:int64`; `s:armstate`] + BYTE_LIST_AT_2BLOCKS) THEN + REWRITE_TAC[byte_list_at] THEN ASM_SIMP_TAC[] );; let READ_CT_TAIL1_LEMMA = prove( - `!ct_ptr s ct len (num_blocks:int64) (num_5blocks_adjusted:int64). - (forall j. - j < LENGTH ct - ==> read (memory :> bytes8 (word_add ct_ptr (word j))) s = EL j ct) - /\ ~(LENGTH ct < 0x50) - /\ val len = LENGTH ct - /\ word_and len (word 0xfffffffffffffff0) = num_blocks - /\ val - (word_sub - (word_sub num_blocks_adjusted - (word_mul (word 0x50) num_5blocks_adjusted)) - (word 0x10)) = - 0x0 + `!ct_ptr (num_5blocks_adjusted:int64) (len:int64) (ct:byte list) s. + (forall j. j < val len ==> read (memory :> bytes8 (word_add ct_ptr (word j))) s = EL j ct) + /\ val num_5blocks_adjusted * 0x50 + 0x10 <= val len + /\ LENGTH ct = val len ==> read (memory :> bytes128 (word_add ct_ptr (word_mul (word 0x50) num_5blocks_adjusted))) s = - bytes_to_int128 (SUB_LIST (val num_5blocks_adjusted * 16, 16) ct) + bytes_to_int128 (SUB_LIST (val num_5blocks_adjusted * 80, 16) ct) `, - CHEAT_TAC + REPEAT GEN_TAC THEN STRIP_TAC THEN + REWRITE_TAC [WORD_RULE `(word_mul (word 0x50) (num_5blocks_adjusted:int64)) = word (val num_5blocks_adjusted * 80)`] THEN + MP_TAC + (SPECL [`(val (num_5blocks_adjusted:int64) * 80):num`; `ct:byte list`; `ct_ptr:int64`; `len:int64`; `s:armstate`] + BYTE_LIST_AT_1BLOCKS) THEN + REWRITE_TAC[byte_list_at] THEN ASM_SIMP_TAC[] );; let UDIV_OPT_THM = prove(`!n:num. n < 0x2 EXP 0x40 @@ -1086,30 +1373,40 @@ let UDIV_OPT_THM = prove(`!n:num. n < 0x2 EXP 0x40 DISCH_TAC THEN ASM_REWRITE_TAC[] THEN AP_TERM_TAC THEN ASM_ARITH_TAC);; +(* let NUM_BLOCKS_THM = prove(`!(len:int64) num_blocks tail_len. - len = word_add tail_len num_blocks ==> + word_add tail_len num_blocks = len ==> word_and len (word 0xfffffffffffffff0) = num_blocks ==> (word_and (word_add tail_len num_blocks) (word 0xfffffffffffffff0)) = num_blocks`, BITBLAST_TAC);; +*) +(* let TAIL_LEN_THM = prove(`!(len:int64) num_blocks tail_len. - len = word_add tail_len num_blocks ==> + word_add tail_len num_blocks = len ==> word_and len (word 0xf) = tail_len ==> (word_and (word_add tail_len num_blocks) (word 0xf)) = tail_len`, BITBLAST_TAC);; +*) -let NUM_BLOCKS_BOUND_THM = prove( +let NUM_BLOCKS_LO_BOUND_THM = prove( `!(len:int64) num_blocks. word_and len (word 0xfffffffffffffff0) = num_blocks ==> ~(val len < 0x60) ==> ~(val num_blocks < 0x60)`, BITBLAST_TAC);; +let NUM_BLOCKS_HI_BOUND_THM = prove( + `!(len:int64) num_blocks. word_and len (word 0xfffffffffffffff0) = num_blocks + ==> val len <= 2 EXP 24 + ==> val num_blocks <= 2 EXP 24`, + BITBLAST_TAC);; + let TAIL_LEN_BOUND_THM = prove( `!(len:int64) tail_len. word_and len (word 0xf) = tail_len ==> val tail_len < 0x10`, BITBLAST_TAC);; -let NUM_BLOCKS_ADJUSTED_BOUND_THM = prove( +let NUM_BLOCKS_ADJUSTED_LO_BOUND_THM = prove( `!(num_blocks:int64) (tail_len:int64) num_blocks_adjusted. (if val tail_len = 0x0 then num_blocks else word_sub num_blocks (word 0x10)) = num_blocks_adjusted ==> ~(val num_blocks < 0x60) @@ -1117,19 +1414,59 @@ let NUM_BLOCKS_ADJUSTED_BOUND_THM = prove( BITBLAST_TAC );; +let NUM_BLOCKS_ADJUSTED_HI_BOUND_THM = prove( + `!(num_blocks:int64) (tail_len:int64) num_blocks_adjusted. + (if val tail_len = 0x0 then num_blocks else word_sub num_blocks (word 0x10)) = num_blocks_adjusted + ==> val num_blocks <= 2 EXP 24 + ==> ~(val num_blocks < 0x60) + ==> val num_blocks_adjusted <= 2 EXP 24`, + BITBLAST_TAC +);; + +let NUM_5BLOCKS_ADJUSTED_LO_BOUND_THM = prove( + `!(num_blocks_adjusted:int64) (num_5blocks_adjusted:int64). + val num_blocks_adjusted <= 0x2 EXP 0x18 + ==> ~(val num_blocks_adjusted < 0x50) + ==> word (val num_blocks_adjusted DIV 0x50) = num_5blocks_adjusted + ==> 0x0 < val num_5blocks_adjusted`, + REPEAT STRIP_TAC THEN + EXPAND_TAC "num_5blocks_adjusted" THEN + REWRITE_TAC[VAL_WORD; DIMINDEX_64] THEN + UNDISCH_TAC `~(val (num_blocks_adjusted:int64) < 0x50)` THEN + ABBREV_TAC `n = val (num_blocks_adjusted:int64)` THEN + SUBGOAL_THEN `n DIV 80 < 2 EXP 64` ASSUME_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[MOD_LT] THEN + ARITH_TAC +);; + +let NUM_BLOCKS_LT_LEN_THM = prove( + `!(len:int64). val (word_and len (word 0xfffffffffffffff0)) <= val len`, + BITBLAST_TAC +);; + +let NUM_BLOCKS_ADJUSTED_LT_LEN_THM = prove( + `!(len:int64) num_blocks. + word_and len (word 0xfffffffffffffff0) = num_blocks + ==> ~(val num_blocks < 0x60) + ==> val (word_sub num_blocks (word 0x10)) <= val len`, + BITBLAST_TAC +);; + let AES_XTS_DECRYPT_CORRECT = prove( `!ct_ptr pt_ptr ct pt_init key1_ptr key2_ptr iv_ptr iv len k00 k01 k02 k03 k04 k05 k06 k07 k08 k09 k0a k0b k0c k0d k0e k10 k11 k12 k13 k14 k15 k16 k17 k18 k19 k1a k1b k1c k1d k1e pc. nonoverlapping (word pc, LENGTH aes_xts_decrypt_mc) (pt_ptr, val len) - /\ val len >= 16 /\ val len <= 2 EXP 24 /\ val len = LENGTH ct + /\ nonoverlapping (ct_ptr, val len) (pt_ptr, val len) + /\ val len >= 16 /\ val len <= 2 EXP 24 /\ LENGTH ct = val len ==> ensures arm (\s. aligned_bytes_loaded s (word pc) aes_xts_decrypt_mc /\ read PC s = word (pc + 0x1c) /\ C_ARGUMENTS [ct_ptr; pt_ptr; len; key1_ptr; key2_ptr; iv_ptr] s /\ - byte_list_at ct ct_ptr s /\ - byte_list_at pt_init pt_ptr s /\ + byte_list_at ct ct_ptr len s /\ + byte_list_at pt_init pt_ptr len s /\ read(memory :> bytes128 iv_ptr) s = iv /\ set_key_schedule s key1_ptr k00 k01 k02 k03 k04 k05 k06 k07 k08 k09 k0a k0b k0c k0d k0e /\ set_key_schedule s key2_ptr k10 k11 k12 k13 k14 k15 k16 k17 k18 k19 k1a k1b k1c k1d k1e) @@ -1137,7 +1474,7 @@ let AES_XTS_DECRYPT_CORRECT = prove( byte_list_at (aes256_xts_decrypt ct (val len) iv [k00; k01; k02; k03; k04; k05; k06; k07; k08; k09; k0a; k0b; k0c; k0d; k0e] [k10; k11; k12; k13; k14; k15; k16; k17; k18; k19; k1a; k1b; k1c; k1d; k1e] - pt_init) pt_ptr s + pt_init) pt_ptr len s ) (MAYCHANGE [PC] ,, MAYCHANGE [events] ,, MAYCHANGE [X21;X2;X6;X4;X9;X10;X19;X22;X11;X7;X0;X1;X8] ,, @@ -1150,8 +1487,8 @@ let AES_XTS_DECRYPT_CORRECT = prove( REPEAT STRIP_TAC THEN (* Break len into full blocks and tail *) - SUBGOAL_THEN `len:int64 = word_add (word_and len (word 0xf)) - (word_and len (word 0xfffffffffffffff0))` ASSUME_TAC THENL + SUBGOAL_THEN `word_add (word_and len (word 0xf)) + (word_and len (word 0xfffffffffffffff0)) = len:int64` ASSUME_TAC THENL [REWRITE_TAC[word_split_lemma]; ALL_TAC] THEN ABBREV_TAC `num_blocks:int64 = word_and len (word 0xfffffffffffffff0)` THEN ABBREV_TAC `tail_len:int64 = word_and len (word 0xf)` THEN @@ -1176,13 +1513,18 @@ let AES_XTS_DECRYPT_CORRECT = prove( then num_blocks else word_sub (num_blocks:int64) (word 0x10)` THEN ABBREV_TAC `num_5blocks_adjusted = (word (val (num_blocks_adjusted:int64) DIV 0x50)):int64` THEN - (* Prove once and for all that num_blocks must be greater or equal to six blocks, - num_blocks_adjusted must be greater to equal to five blocks *) + (* Prove once and for all the bounds for num_blocks, num_blocks_adjusted + and num_5blocks_adjusted *) SUBGOAL_THEN `~(val (num_blocks:int64) < 96)` ASSUME_TAC THENL [ UNDISCH_TAC `~(val (len:int64) < 0x60)` THEN UNDISCH_TAC `word_and len (word 0xfffffffffffffff0) = (num_blocks:int64)` THEN - MP_TAC (SPECL [`len:int64`; `num_blocks:int64`] NUM_BLOCKS_BOUND_THM) THEN SIMP_TAC[] - ; ALL_TAC] THEN + MP_TAC (SPECL [`len:int64`; `num_blocks:int64`] NUM_BLOCKS_LO_BOUND_THM) THEN + SIMP_TAC[]; ALL_TAC] THEN + SUBGOAL_THEN `val (num_blocks:int64) <= 2 EXP 24` ASSUME_TAC THENL + [ UNDISCH_TAC `val (len:int64) <= 2 EXP 24` THEN + UNDISCH_TAC `word_and len (word 0xfffffffffffffff0) = (num_blocks:int64)` THEN + MP_TAC (SPECL [`len:int64`; `num_blocks:int64`] NUM_BLOCKS_HI_BOUND_THM) THEN + SIMP_TAC[]; ALL_TAC] THEN SUBGOAL_THEN `~(val (num_blocks_adjusted:int64) < 80)` ASSUME_TAC THENL [ UNDISCH_TAC `~(val (num_blocks:int64) < 96)` THEN UNDISCH_TAC `(if val (tail_len:int64) = 0x0 @@ -1190,8 +1532,47 @@ let AES_XTS_DECRYPT_CORRECT = prove( else word_sub num_blocks (word 0x10)) = num_blocks_adjusted` THEN MP_TAC (SPECL [`num_blocks:int64`;`tail_len:int64`;`num_blocks_adjusted:int64`] - NUM_BLOCKS_ADJUSTED_BOUND_THM) THEN SIMP_TAC[] + NUM_BLOCKS_ADJUSTED_LO_BOUND_THM) THEN SIMP_TAC[] + ; ALL_TAC] THEN + SUBGOAL_THEN `val (num_blocks_adjusted:int64) <= 2 EXP 24` ASSUME_TAC THENL + [ UNDISCH_TAC `val (num_blocks:int64) <= 2 EXP 24` THEN + UNDISCH_TAC `~(val (num_blocks:int64) < 96)` THEN + UNDISCH_TAC `(if val (tail_len:int64) = 0x0 + then (num_blocks:int64) + else word_sub num_blocks (word 0x10)) = + num_blocks_adjusted` THEN + MP_TAC (SPECL [`num_blocks:int64`;`tail_len:int64`;`num_blocks_adjusted:int64`] + NUM_BLOCKS_ADJUSTED_HI_BOUND_THM) THEN SIMP_TAC[] ; ALL_TAC] THEN + SUBGOAL_THEN `0 < val (num_5blocks_adjusted:int64)` ASSUME_TAC THENL + [ UNDISCH_TAC `word (val (num_blocks_adjusted:int64) DIV 0x50) = (num_5blocks_adjusted:int64)` THEN + UNDISCH_TAC `~(val (num_blocks_adjusted:int64) < 0x50)` THEN + UNDISCH_TAC `val (num_blocks_adjusted:int64) <= 0x2 EXP 0x18` THEN + MP_TAC (SPECL [`num_blocks_adjusted:int64`; `num_5blocks_adjusted:int64`] + NUM_5BLOCKS_ADJUSTED_LO_BOUND_THM) THEN SIMP_TAC[] + ; ALL_TAC] THEN + (* relationship between variables *) + SUBGOAL_THEN `val (num_blocks:int64) <= val (len:int64)` ASSUME_TAC THENL + [ EXPAND_TAC "num_blocks" THEN SIMP_TAC[NUM_BLOCKS_LT_LEN_THM]; ALL_TAC] THEN + SUBGOAL_THEN `val (num_blocks_adjusted:int64) <= val (len:int64)` ASSUME_TAC THENL + [ EXPAND_TAC "num_blocks_adjusted" THEN + COND_CASES_TAC THENL + [ ASM_SIMP_TAC[]; + UNDISCH_TAC `~(val (num_blocks:int64) < 0x60)` THEN + UNDISCH_TAC `word_and (len:int64) (word 0xfffffffffffffff0) = (num_blocks:int64)` THEN + MP_TAC (SPECL [`len:int64`; `num_blocks:int64`] NUM_BLOCKS_ADJUSTED_LT_LEN_THM) THEN + SIMP_TAC[]]; ALL_TAC] THEN + SUBGOAL_THEN `val (num_5blocks_adjusted:int64) * 0x50 <= val (num_blocks_adjusted:int64)` ASSUME_TAC THENL + [ EXPAND_TAC "num_5blocks_adjusted" THEN + REWRITE_TAC [VAL_WORD; DIMINDEX_64] THEN + UNDISCH_TAC `val (num_blocks_adjusted:int64) <= 0x2 EXP 0x18` THEN + ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `val (num_5blocks_adjusted:int64) * 0x50 <= val (len:int64)` ASSUME_TAC THENL + [ EXPAND_TAC "num_5blocks_adjusted" THEN + REWRITE_TAC [VAL_WORD; DIMINDEX_64] THEN + UNDISCH_TAC `val (num_blocks_adjusted:int64) <= 0x2 EXP 0x18` THEN + UNDISCH_TAC `val (num_blocks_adjusted:int64) <= val (len:int64)` THEN + ARITH_TAC; ALL_TAC] THEN (* Verify properties of the program until the beginning of the loop. The properties include the invariant, and a bunch of other initial setup. @@ -1216,8 +1597,8 @@ let AES_XTS_DECRYPT_CORRECT = prove( read Q14 s = k04 /\ read Q15 s = k05 /\ read Q4 s = k06 /\ read Q5 s = k07 /\ read Q18 s = k08 /\ read Q19 s = k09 /\ read Q20 s = k0a /\ read Q21 s = k0b /\ read Q22 s = k0c /\ read Q23 s = k0d /\ read Q7 s = k0e /\ - byte_list_at ct ct_ptr s /\ - byte_list_at (aes256_xts_decrypt ct 0 iv key1 key2 pt_init) pt_ptr s /\ + byte_list_at ct ct_ptr len s /\ + byte_list_at (aes256_xts_decrypt ct 0 iv key1 key2 pt_init) pt_ptr (word 0) s /\ set_key_schedule s key1_ptr k00 k01 k02 k03 k04 k05 k06 k07 k08 k09 k0a k0b k0c k0d k0e` THEN CONJ_TAC THENL [ @@ -1262,12 +1643,7 @@ let AES_XTS_DECRYPT_CORRECT = prove( DISCH_TAC THEN (* Prove val tail_len = 0 and num_blocks = num_blocks_adjusted *) SUBGOAL_THEN `val (tail_len:int64) = 0` ASSUME_TAC THENL - [ UNDISCH_TAC `val - (word_and (word_and (word_add (tail_len:int64) num_blocks) (word 0xf)) (word 0xf)) = - 0x0` THEN - MP_TAC (SPECL [`len:int64`; `num_blocks:int64`; `tail_len:int64`] TAIL_LEN_THM) THEN - ASM_REWRITE_TAC[] THEN - DISCH_TAC THEN POP_ASSUM(fun th -> REWRITE_TAC[th]) THEN + [ UNDISCH_TAC `val (word_and (tail_len:int64) (word 0xf)) = 0x0` THEN MP_TAC (SPECL [`len:int64`; `tail_len:int64`] TAIL_LEN_BOUND_THM) THEN ASM_REWRITE_TAC[] THEN SUBST1_TAC(ARITH_RULE `0xf = 2 EXP 4 - 1`) THEN @@ -1286,17 +1662,10 @@ let AES_XTS_DECRYPT_CORRECT = prove( ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (90--93) THEN (* Prove the optimized udiv is basically udiv *) SUBGOAL_THEN `word_ushr - ((word - ((val - (word_and (word_add (tail_len:int64) num_blocks) - (word 0xfffffffffffffff0)) - * 0xcccccccccccccccd) DIV 0x2 EXP 0x40)):int64) 0x6 = + ((word ((val (num_blocks:int64) * 0xcccccccccccccccd) DIV 0x2 EXP 0x40)):int64) + 0x6 = word ((val num_blocks) DIV 0x50)` ASSUME_TAC THENL - [ - MP_TAC (SPECL [`len:int64`; `num_blocks:int64`; `tail_len:int64`] NUM_BLOCKS_THM) THEN - ASM_REWRITE_TAC[] THEN - DISCH_TAC THEN POP_ASSUM(fun th -> REWRITE_TAC[th]) THEN - MP_TAC (BITBLAST_RULE `val (num_blocks:int64) < 2 EXP 64`) THEN + [ MP_TAC (BITBLAST_RULE `val (num_blocks:int64) < 2 EXP 64`) THEN REWRITE_TAC[word_ushr] THEN MP_TAC (SPECL [`val (num_blocks:int64)`] UDIV_OPT_THM) THEN SIMP_TAC[] ; ALL_TAC] THEN @@ -1304,37 +1673,25 @@ let AES_XTS_DECRYPT_CORRECT = prove( (* Eliminate 1 block case *) ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (94--95) THEN - SUBGOAL_THEN `~(val (word_and (word_add (tail_len:int64) num_blocks) (word 0xfffffffffffffff0)) < 0x20)` ASSUME_TAC THENL - [ MP_TAC (SPECL [`len:int64`; `num_blocks:int64`; `tail_len:int64`] NUM_BLOCKS_THM) THEN - ASM_REWRITE_TAC[] THEN - DISCH_TAC THEN POP_ASSUM(fun th -> REWRITE_TAC[th]) THEN - UNDISCH_TAC `~(val (num_blocks:int64) < 0x60)` THEN ARITH_TAC + SUBGOAL_THEN `~(val (num_blocks:int64) < 0x20)` ASSUME_TAC THENL + [ UNDISCH_TAC `~(val (num_blocks:int64) < 0x60)` THEN ARITH_TAC ; POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th]))] THEN (* Eliminate 2 blocks case *) ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (96--97) THEN - SUBGOAL_THEN `~(val (word_and (word_add (tail_len:int64) num_blocks) (word 0xfffffffffffffff0)) < 0x30)` ASSUME_TAC THENL - [ MP_TAC (SPECL [`len:int64`; `num_blocks:int64`; `tail_len:int64`] NUM_BLOCKS_THM) THEN - ASM_REWRITE_TAC[] THEN - DISCH_TAC THEN POP_ASSUM(fun th -> REWRITE_TAC[th]) THEN - UNDISCH_TAC `~(val (num_blocks:int64) < 0x60)` THEN ARITH_TAC + SUBGOAL_THEN `~(val (num_blocks:int64) < 0x30)` ASSUME_TAC THENL + [ UNDISCH_TAC `~(val (num_blocks:int64) < 0x60)` THEN ARITH_TAC ; POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th]))] THEN (* Eliminate 3 blocks case and prove Q9 stores tweak 2 *) ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (98--105) THEN - SUBGOAL_THEN `~(val (word_and (word_add (tail_len:int64) num_blocks) (word 0xfffffffffffffff0)) < 0x40)` ASSUME_TAC THENL - [ MP_TAC (SPECL [`len:int64`; `num_blocks:int64`; `tail_len:int64`] NUM_BLOCKS_THM) THEN - ASM_REWRITE_TAC[] THEN - DISCH_TAC THEN POP_ASSUM(fun th -> REWRITE_TAC[th]) THEN - UNDISCH_TAC `~(val (num_blocks:int64) < 0x60)` THEN ARITH_TAC + SUBGOAL_THEN `~(val (num_blocks:int64) < 0x40)` ASSUME_TAC THENL + [ UNDISCH_TAC `~(val (num_blocks:int64) < 0x60)` THEN ARITH_TAC ; POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th]))] THEN TWEAK_TAC `Q9:(armstate,int128)component` `2:num` `1:num` THEN (* Eliminate 4 blocks case and Q10 stores tweak 3 *) ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (106--113) THEN - SUBGOAL_THEN `~(val (word_and (word_add (tail_len:int64) num_blocks) (word 0xfffffffffffffff0)) < 0x50)` ASSUME_TAC THENL - [ MP_TAC (SPECL [`len:int64`; `num_blocks:int64`; `tail_len:int64`] NUM_BLOCKS_THM) THEN - ASM_REWRITE_TAC[] THEN - DISCH_TAC THEN POP_ASSUM(fun th -> REWRITE_TAC[th]) THEN - UNDISCH_TAC `~(val (num_blocks:int64) < 0x60)` THEN ARITH_TAC + SUBGOAL_THEN `~(val (num_blocks:int64) < 0x50)` ASSUME_TAC THENL + [ UNDISCH_TAC `~(val (num_blocks:int64) < 0x60)` THEN ARITH_TAC ; POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th]))] THEN TWEAK_TAC `Q10:(armstate,int128)component` `3:num` `2:num` THEN @@ -1345,49 +1702,56 @@ let AES_XTS_DECRYPT_CORRECT = prove( ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN REPEAT CONJ_TAC THENL [ - MP_TAC (SPECL [`len:int64`; `num_blocks:int64`; `tail_len:int64`] NUM_BLOCKS_THM) THEN + EXPAND_TAC "num_5blocks_adjusted" THEN + EXPAND_TAC "num_blocks_adjusted" THEN ASM_REWRITE_TAC[]; - MP_TAC (SPECL [`len:int64`; `num_blocks:int64`; `tail_len:int64`] TAIL_LEN_THM) THEN - ASM_REWRITE_TAC[]; - UNDISCH_TAC `word (val (num_blocks_adjusted:int64) DIV 0x50) = (num_5blocks_adjusted:int64)` THEN - UNDISCH_TAC `num_blocks_adjusted:int64 = num_blocks` THEN - SIMP_TAC[]; ASM_REWRITE_TAC[byte_list_at]; REWRITE_TAC[aes256_xts_decrypt] THEN CONV_TAC (DEPTH_CONV NUM_RED_CONV) THEN - ASM_REWRITE_TAC[byte_list_at]; + ASM_REWRITE_TAC[byte_list_at] THEN + REWRITE_TAC[VAL_WORD_0] THEN ARITH_TAC; ASM_REWRITE_TAC[set_key_schedule]] ; ALL_TAC ] THEN (* If there is a tail *) DISCH_TAC THEN + (* Prove ~ tail_len = 0 *) + SUBGOAL_THEN `~(val (tail_len:int64) = 0)` ASSUME_TAC THENL + [ UNDISCH_TAC `~(val (word_and (tail_len:int64) (word 0xf)) = 0x0)` THEN + MP_TAC (SPECL [`len:int64`; `tail_len:int64`] TAIL_LEN_BOUND_THM) THEN + ASM_REWRITE_TAC[] THEN + SUBST1_TAC(ARITH_RULE `0xf = 2 EXP 4 - 1`) THEN + REWRITE_TAC[VAL_WORD_AND_MASK_WORD] THEN + NUM_REDUCE_TAC THEN SIMP_TAC[MOD_LT] + ; ALL_TAC] THEN + (* Prove num_blocks_adjusted = word_sub num_blocks (word 0x10) *) + SUBGOAL_THEN `word_sub num_blocks (word 0x10) = num_blocks_adjusted:int64` ASSUME_TAC THENL + [ UNDISCH_TAC `(if val (tail_len:int64) = 0x0 + then (num_blocks:int64) + else word_sub num_blocks (word 0x10)) = num_blocks_adjusted` THEN + ASM_REWRITE_TAC[]; ALL_TAC] THEN + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (90--92) THEN (* Discharge if condition *) SUBGOAL_THEN - `ival - (word_sub - (word_sub - (word_and (word_add (tail_len:int64) num_blocks) - (word 0xfffffffffffffff0)) - (word 0x10)) - (word 0x10)) < - &0x0 <=> - ~(ival - (word_sub - (word_and (word_add tail_len num_blocks) - (word 0xfffffffffffffff0)) - (word 0x10)) - - &0x10 = - ival - (word_sub - (word_sub - (word_and (word_add tail_len num_blocks) - (word 0xfffffffffffffff0)) - (word 0x10)) - (word 0x10)))` ASSUME_TAC THENL - [ CHEAT_TAC; + `ival (word_sub (num_blocks_adjusted:int64) (word 0x10)) < &0x0 <=> + ~(ival (num_blocks_adjusted:int64) - &0x10 = + ival (word_sub (num_blocks_adjusted:int64) (word 0x10)))` MP_TAC THENL + [ + MP_TAC (BITBLAST_RULE + `~(val (num_blocks_adjusted:int64) < 0x50) ==> + val num_blocks_adjusted <= 2 EXP 0x18 ==> + ival (word_sub num_blocks_adjusted (word 0x10)) >= &0x0`) THEN + ASM_REWRITE_TAC[] THEN + MP_TAC (BITBLAST_RULE + `~(val (num_blocks_adjusted:int64) < 0x50) ==> + val num_blocks_adjusted <= 2 EXP 0x18 ==> + ival (num_blocks_adjusted:int64) - &0x10 = ival (word_sub num_blocks_adjusted (word 0x10))`) THEN + ASM_REWRITE_TAC[] THEN + ARITH_TAC; ALL_TAC] THEN + DISCH_TAC THEN POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th])) THEN (* Prove x9, x10 stores lower and upper halves and Q8 stores the full tweak *) @@ -1395,56 +1759,33 @@ let AES_XTS_DECRYPT_CORRECT = prove( ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (93--96) THEN (* Prove the optimized udiv is basically udiv *) SUBGOAL_THEN `word_ushr - (word - ((val - (word_sub - (word_and (word_add (tail_len:int64) num_blocks) (word 0xfffffffffffffff0)) - (word 0x10)) * - 0xcccccccccccccccd) DIV - 0x2 EXP 0x40):int64) - 0x6 = word ((val (word_sub num_blocks (word 1))) DIV 0x50)` ASSUME_TAC THENL - [ CHEAT_TAC + ((word ((val (num_blocks_adjusted:int64) * 0xcccccccccccccccd) DIV 0x2 EXP 0x40)):int64) + 0x6 = word ((val num_blocks_adjusted) DIV 0x50)` ASSUME_TAC THENL + [ MP_TAC (BITBLAST_RULE `val (num_blocks_adjusted:int64) < 2 EXP 64`) THEN + REWRITE_TAC[word_ushr] THEN + MP_TAC (SPECL [`val (num_blocks_adjusted:int64)`] UDIV_OPT_THM) THEN SIMP_TAC[] ; ALL_TAC] THEN POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th])) THEN (* Eliminate 1 block case *) ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (97--98) THEN - SUBGOAL_THEN `~(val - (word_sub - (word_and (word_add (tail_len:int64) num_blocks) - (word 0xfffffffffffffff0)) - (word 0x10)) < - 0x20)` ASSUME_TAC THENL - [CHEAT_TAC; POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th]))] THEN + SUBGOAL_THEN `~(val (num_blocks_adjusted:int64) < 0x20)` ASSUME_TAC THENL + [ UNDISCH_TAC `~(val (num_blocks_adjusted:int64) < 0x50)` THEN ARITH_TAC + ; POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th]))] THEN (* Eliminate 2 blocks case *) ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (99--100) THEN - SUBGOAL_THEN `~(val - (word_sub - (word_and (word_add (tail_len:int64) num_blocks) - (word 0xfffffffffffffff0)) - (word 0x10)) < - 0x30)` ASSUME_TAC THENL - [CHEAT_TAC; POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th]))] THEN + SUBGOAL_THEN `~(val (num_blocks_adjusted:int64) < 0x30)` ASSUME_TAC THENL + [ UNDISCH_TAC `~(val (num_blocks_adjusted:int64) < 0x50)` THEN ARITH_TAC + ; POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th]))] THEN (* Eliminate 3 blocks case and prove Q9 stores tweak 2 *) ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (101--108) THEN - SUBGOAL_THEN `~(val - (word_sub - (word_and (word_add (tail_len:int64) num_blocks) - (word 0xfffffffffffffff0)) - (word 0x10)) < - 0x40)` ASSUME_TAC THENL - [CHEAT_TAC; POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th]))] THEN + SUBGOAL_THEN `~(val (num_blocks_adjusted:int64) < 0x40)` ASSUME_TAC THENL + [ UNDISCH_TAC `~(val (num_blocks_adjusted:int64) < 0x50)` THEN ARITH_TAC + ; POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th]))] THEN TWEAK_TAC `Q9:(armstate,int128)component` `2:num` `1:num` THEN (* Eliminate 4 blocks case and Q10 stores tweak 3 *) ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (109--116) THEN - SUBGOAL_THEN `~(val - (word_sub - (word_and (word_add (tail_len:int64) num_blocks) - (word 0xfffffffffffffff0)) - (word 0x10)) < - 0x50)` ASSUME_TAC THENL - [CHEAT_TAC; POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th]))] THEN TWEAK_TAC `Q10:(armstate,int128)component` `3:num` `2:num` THEN (* Must have 5 blocks, execute until start of loop. Q11 stores tweak 4 *) @@ -1453,13 +1794,11 @@ let AES_XTS_DECRYPT_CORRECT = prove( ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN REPEAT CONJ_TAC THENL - [ - CHEAT_TAC; - REWRITE_TAC[SYM (ASSUME `len:int64 = word_add tail_len num_blocks`)] THEN - ASM_REWRITE_TAC[]; - CHEAT_TAC; - ASM_REWRITE_TAC[byte_list_at]; - CHEAT_TAC; + [ ASM_REWRITE_TAC[byte_list_at]; + REWRITE_TAC[aes256_xts_decrypt] THEN + CONV_TAC (DEPTH_CONV NUM_RED_CONV) THEN + ASM_REWRITE_TAC[byte_list_at] THEN + REWRITE_TAC [VAL_WORD_0] THEN ARITH_TAC; ASM_REWRITE_TAC[set_key_schedule]] ; ALL_TAC ] THEN @@ -1508,15 +1847,13 @@ let AES_XTS_DECRYPT_CORRECT = prove( read Q14 s = k04 /\ read Q15 s = k05 /\ read Q4 s = k06 /\ read Q5 s = k07 /\ read Q18 s = k08 /\ read Q19 s = k09 /\ read Q20 s = k0a /\ read Q21 s = k0b /\ read Q22 s = k0c /\ read Q23 s = k0d /\ read Q7 s = k0e /\ - byte_list_at ct ct_ptr s /\ - byte_list_at (aes256_xts_decrypt ct (i * 5 * 16) iv key1 key2 pt_init) pt_ptr s) /\ + byte_list_at ct ct_ptr len s /\ + byte_list_at (aes256_xts_decrypt ct (80 * i) iv key1 key2 pt_init) pt_ptr (word (80 * i)) s) /\ // loop backedge condition (read ZF s <=> i = val (num_5blocks_adjusted:int64))` THEN ASM_REWRITE_TAC[] THEN REPEAT CONJ_TAC THENL [ - (* Subgoal 1. Bound of loop is not zero *) - CHEAT_TAC; - + (* Subgoal 1. Bound of loop is not zero -- automatically discharged by asm *) (* Subgoal 2. Invariant holds before entering the loop *) REWRITE_TAC[byte_list_at] THEN ENSURES_INIT_TAC "s0" THEN @@ -1524,8 +1861,7 @@ let AES_XTS_DECRYPT_CORRECT = prove( REPEAT CONJ_TAC THENL [ WORD_ARITH_TAC; WORD_ARITH_TAC; - CHEAT_TAC; - CHEAT_TAC; + WORD_ARITH_TAC; WORD_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV; CONV_TAC NUM_REDUCE_CONV; CONV_TAC NUM_REDUCE_CONV; @@ -1533,17 +1869,13 @@ let AES_XTS_DECRYPT_CORRECT = prove( CONV_TAC NUM_REDUCE_CONV; CONV_TAC NUM_REDUCE_CONV; CONV_TAC NUM_REDUCE_CONV; - CONV_TAC NUM_REDUCE_CONV THEN ASM_REWRITE_TAC[byte_list_at] + CONV_TAC (ONCE_DEPTH_CONV NUM_REDUCE_CONV) THEN REWRITE_TAC[VAL_WORD_0] THEN ARITH_TAC ]; (* Subgoal 3: loop body *) REPEAT STRIP_TAC THEN (* ===> Symbolic Simulation: Start symbolic simulation*) - REWRITE_TAC[byte_list_at] THEN - SUBGOAL_THEN `i < LENGTH (ct:byte list) DIV 0x50` ASSUME_TAC THENL - [CHEAT_TAC;ALL_TAC] THEN - SUBGOAL_THEN `~(LENGTH (ct:byte list) < 0x50)` ASSUME_TAC THENL - [CHEAT_TAC;ALL_TAC] THEN + ASM_REWRITE_TAC[byte_list_at] THEN GHOST_INTRO_TAC `b0:int128` `read (memory :> bytes128 (word_add pt_ptr (word_mul (word 0x50) (word i))))` THEN GHOST_INTRO_TAC `b1:int128` `read (memory :> bytes128 (word_add (word_add pt_ptr (word_mul (word 0x50) (word i))) (word 0x10)))` THEN @@ -1552,8 +1884,14 @@ let AES_XTS_DECRYPT_CORRECT = prove( GHOST_INTRO_TAC `b4:int128` `read (memory :> bytes128 (word_add (word_add pt_ptr (word_mul (word 0x50) (word i))) (word 0x40)))` THEN ENSURES_INIT_TAC "s0" THEN + SUBGOAL_THEN `i * 0x50 + 0x50 <= val (len:int64)` ASSUME_TAC THENL + [ SUBGOAL_THEN `i + 1 <= val (num_5blocks_adjusted:int64)` MP_TAC THENL + [ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `(i + 1) * 0x50 <= val (len:int64)` MP_TAC THENL + [ASM_ARITH_TAC; ALL_TAC] THEN + ARITH_TAC; ALL_TAC] THEN (* List values for ct_ptr + [0 .. 0x40] *) - MP_TAC (SPECL [`ct_ptr:int64`; `s0:armstate`; `ct:byte list`; `i:num`] READ_CT_LEMMA) THEN + MP_TAC (SPECL [`ct_ptr:int64`; `i:num`; `len:int64`; `ct:byte list`; `s0:armstate`] READ_CT_LEMMA) THEN ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (1--151) THEN (* Prove Q0, Q1, Q24, Q25, Q26 stores correct plaintext *) @@ -1577,24 +1915,43 @@ let AES_XTS_DECRYPT_CORRECT = prove( XTSDEC_TAC `Q26:(armstate,int128)component` `i * 0x50 + 0x40` `i * 0x5 + 0x4` THEN TWEAK_TAC `Q11:(armstate,int128)component` `i * 5 + 9` `i * 5 + 8` THEN + (* The following lemmas are for NONSELFMODIFYING_STATE_UPDATE_TAC when store back to pt_ptr, + and for the MAYCHANGE clauses *) + RULE_ASSUM_TAC(REWRITE_RULE + [WORD_RULE `word_mul (word 0x50) (word i):int64 = word(0x50 * i)`]) THEN + (* Simulate until end of loop *) + (* TODO: previous pt_ptr blocks are removed from hypotheses!!!! *) ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (184--188) THEN ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN REPEAT CONJ_TAC THENL - [ CHEAT_TAC; - CHEAT_TAC; - CHEAT_TAC; - CHEAT_TAC; - CHEAT_TAC; - CHEAT_TAC; - CHEAT_TAC; - CHEAT_TAC; - CHEAT_TAC; - CHEAT_TAC; - CHEAT_TAC; - CHEAT_TAC; - CHEAT_TAC; + [ REWRITE_TAC[WORD_RULE `word_mul (word 0x50) (word (i + 1)):int64 = word_add (word(0x50 * i)) (word 0x50)`] THEN + REWRITE_TAC[WORD_ADD_ASSOC]; + REWRITE_TAC[WORD_RULE `word_mul (word 0x50) (word (i + 1)):int64 = word_add (word(0x50 * i)) (word 0x50)`] THEN + REWRITE_TAC[WORD_ADD_ASSOC]; + REWRITE_TAC[WORD_RULE `word_mul (word 0x50) (word (i + 1)):int64 = word_add (word(0x50 * i)) (word 0x50)`] THEN + CONV_TAC WORD_RULE; + CONV_TAC WORD_RULE; + REWRITE_TAC[WORD_RULE `(i + 0x1) * 0x5 = i * 0x5 + 0x5`]; + REWRITE_TAC[WORD_RULE `(i + 0x1) * 0x5 + 0x1 = i * 0x5 + 0x6`]; + REWRITE_TAC[WORD_RULE `(i + 0x1) * 0x5 + 0x2 = i * 0x5 + 0x7`]; + REWRITE_TAC[WORD_RULE `(i + 0x1) * 0x5 + 0x3 = i * 0x5 + 0x8`]; + REWRITE_TAC[WORD_RULE `(i + 0x1) * 0x5 + 0x4 = i * 0x5 + 0x9`]; + REWRITE_TAC[WORD_RULE `(i + 0x1) * 0x5 + 0x4 = i * 0x5 + 0x9`]; + REWRITE_TAC[WORD_RULE `(i + 0x1) * 0x5 + 0x4 = i * 0x5 + 0x9`]; CHEAT_TAC; + SUBGOAL_THEN `i + 1 < 2 EXP 64` ASSUME_TAC THENL + [CHEAT_TAC; ALL_TAC] THEN + EQ_TAC THENL + [ REWRITE_TAC[WORD_RULE `!x:int64 a b. (word_sub (word_sub x a) b) = word_sub x (word_add a b)`] THEN + ASM_SIMP_TAC[WORD_RULE `!a b. a + b < 2 EXP 64 ==> (word_add (word a) (word b)) = word (a + b)`] THEN + REWRITE_TAC[VAL_EQ_0; WORD_SUB_EQ_0] THEN + DISCH_TAC THEN ASM_REWRITE_TAC[] THEN + IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT]; + REWRITE_TAC[WORD_RULE `!x:int64 a b. (word_sub (word_sub x a) b) = word_sub x (word_add a b)`] THEN + ASM_SIMP_TAC[WORD_RULE `!a b. a + b < 2 EXP 64 ==> (word_add (word a) (word b)) = word (a + b)`] THEN + REWRITE_TAC[VAL_EQ_0; WORD_SUB_EQ_0; WORD_VAL] + ]; CHEAT_TAC ]; @@ -1605,19 +1962,16 @@ let AES_XTS_DECRYPT_CORRECT = prove( ENSURES_INIT_TAC "s0" THEN ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (1--1) THEN SUBGOAL_THEN `~(val (word_sub (num_5blocks_adjusted:int64) (word i)) = 0x0)` ASSUME_TAC THENL - [CHEAT_TAC; ALL_TAC] THEN + [ UNDISCH_TAC `i < val (num_5blocks_adjusted:int64)` THEN WORD_ARITH_TAC; ALL_TAC] THEN POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th])) THEN - ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[]; + ENSURES_FINAL_STATE_TAC THEN ASM_SIMP_TAC[]; (* Subgoal 5: Prove the invariant implies post-condition Backedge instruction is executed here *) REPEAT STRIP_TAC THEN REWRITE_TAC[byte_list_at] THEN - SUBGOAL_THEN `~(LENGTH (ct:byte list) < 0x50)` ASSUME_TAC THENL - [CHEAT_TAC;ALL_TAC] THEN - SUBGOAL_THEN `(word (val (num_5blocks_adjusted:int64))):int64 = num_5blocks_adjusted` SUBST_ALL_TAC THENL - [CHEAT_TAC;ALL_TAC] THEN + SUBST_ALL_TAC (WORD_RULE `(word (val (num_5blocks_adjusted:int64))):int64 = num_5blocks_adjusted`) THEN GHOST_INTRO_TAC `bt_0:int128` `read (memory :> bytes128 (word_add pt_ptr (word_mul (word 0x50) (num_5blocks_adjusted:int64))))` THEN @@ -1636,19 +1990,38 @@ let AES_XTS_DECRYPT_CORRECT = prove( [ (* Case: len % 0x50 = 0x40 *) DISCH_TAC THEN - MP_TAC (SPECL [`ct_ptr:int64`; `s3:armstate`; `ct:byte list`; - `len:int64`; `num_blocks:int64`; `num_5blocks_adjusted:int64`] READ_CT_TAIL4_LEMMA) THEN + SUBGOAL_THEN `val (num_5blocks_adjusted:int64) * 0x50 + 0x40 <= val (len:int64)` ASSUME_TAC THENL + [ SUBGOAL_THEN `val (num_5blocks_adjusted:int64) * 0x50 + 0x40 = val (num_blocks_adjusted:int64)` MP_TAC THENL + [ UNDISCH_TAC `val (word_sub + (word_sub (num_blocks_adjusted:int64) + (word_mul (word 0x50) (num_5blocks_adjusted:int64))) + (word 0x40)) = + 0x0` THEN + REWRITE_TAC [VAL_EQ_0; WORD_SUB_EQ_0] THEN + REWRITE_TAC [WORD_RULE `!x:int64. word_mul (word 0x50) x = word(val x * 0x50)`] THEN + REWRITE_TAC[GSYM VAL_EQ] THEN + SUBGOAL_THEN `val (num_5blocks_adjusted:int64) * 0x50 < 2 EXP 64` MP_TAC THENL + [ UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 <= val (num_blocks_adjusted:int64)` THEN + UNDISCH_TAC `val (num_blocks_adjusted:int64) <= 2 EXP 24` THEN + ARITH_TAC; ALL_TAC] THEN + REWRITE_TAC[VAL_WORD_SUB_CASES] THEN + SIMP_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN + UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 <= val (num_blocks_adjusted:int64)` THEN + NUM_REDUCE_TAC THEN ARITH_TAC; ALL_TAC] THEN + UNDISCH_TAC `val (num_blocks_adjusted:int64) <= val (len:int64)` THEN + ARITH_TAC; ALL_TAC] THEN + MP_TAC (SPECL [`ct_ptr:int64`; `num_5blocks_adjusted:int64`; `len:int64`; `ct:byte list`; `s3:armstate`] READ_CT_TAIL4_LEMMA) THEN ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (4--125) THEN XTSDEC_TAC `Q0:(armstate,int128)component` - `val (num_5blocks_adjusted:int64) * 0x10` `val (num_5blocks_adjusted:int64) * 0x5` THEN + `val (num_5blocks_adjusted:int64) * 0x50` `val (num_5blocks_adjusted:int64) * 0x5` THEN XTSDEC_TAC `Q1:(armstate,int128)component` - `val (num_5blocks_adjusted:int64) * 0x10 + 0x10` `val (num_5blocks_adjusted:int64) * 0x5 + 0x1` THEN + `val (num_5blocks_adjusted:int64) * 0x50 + 0x10` `val (num_5blocks_adjusted:int64) * 0x5 + 0x1` THEN XTSDEC_TAC `Q24:(armstate,int128)component` - `val (num_5blocks_adjusted:int64) * 0x10 + 0x20` `val (num_5blocks_adjusted:int64) * 0x5 + 0x2` THEN + `val (num_5blocks_adjusted:int64) * 0x50 + 0x20` `val (num_5blocks_adjusted:int64) * 0x5 + 0x2` THEN XTSDEC_TAC `Q25:(armstate,int128)component` - `val (num_5blocks_adjusted:int64) * 0x10 + 0x30` `val (num_5blocks_adjusted:int64) * 0x5 + 0x3` THEN + `val (num_5blocks_adjusted:int64) * 0x50 + 0x30` `val (num_5blocks_adjusted:int64) * 0x5 + 0x3` THEN ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (126--133) THEN TWEAK_TAC `Q6:(armstate,int128)component` `val (num_5blocks_adjusted:int64) * 0x5 + 0x4` `val (num_5blocks_adjusted:int64) * 0x5 + 0x3` THEN @@ -1656,8 +2029,6 @@ let AES_XTS_DECRYPT_CORRECT = prove( (* The following lemmas are for NONSELFMODIFYING_STATE_UPDATE_TAC when store back to pt_ptr *) RULE_ASSUM_TAC(REWRITE_RULE [WORD_RULE `word_mul (word 0x50) num_5blocks_adjusted:int64 = word(0x50 * val num_5blocks_adjusted)`]) THEN - SUBGOAL_THEN `80 * val(num_5blocks_adjusted:int64) + 64 <= val(len:int64)` - ASSUME_TAC THENL [CHEAT_TAC; ALL_TAC] THEN ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (134--138) THEN FIRST_X_ASSUM MP_TAC THEN @@ -1679,16 +2050,37 @@ let AES_XTS_DECRYPT_CORRECT = prove( COND_CASES_TAC THENL [ (* Case: len % 0x50 = 0x30 *) DISCH_TAC THEN - MP_TAC (SPECL [`ct_ptr:int64`; `s5:armstate`; `ct:byte list`; `len:int64`; `num_blocks:int64`; `num_5blocks_adjusted:int64`] READ_CT_TAIL3_LEMMA) THEN + + SUBGOAL_THEN `val (num_5blocks_adjusted:int64) * 0x50 + 0x30 <= val (len:int64)` ASSUME_TAC THENL + [ SUBGOAL_THEN `val (num_5blocks_adjusted:int64) * 0x50 + 0x30 = val (num_blocks_adjusted:int64)` MP_TAC THENL + [ UNDISCH_TAC `val (word_sub + (word_sub (num_blocks_adjusted:int64) + (word_mul (word 0x50) (num_5blocks_adjusted:int64))) + (word 0x30)) = + 0x0` THEN + REWRITE_TAC [VAL_EQ_0; WORD_SUB_EQ_0] THEN + REWRITE_TAC [WORD_RULE `!x:int64. word_mul (word 0x50) x = word(val x * 0x50)`] THEN + REWRITE_TAC[GSYM VAL_EQ] THEN + SUBGOAL_THEN `val (num_5blocks_adjusted:int64) * 0x50 < 2 EXP 64` MP_TAC THENL + [ UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 <= val (num_blocks_adjusted:int64)` THEN + UNDISCH_TAC `val (num_blocks_adjusted:int64) <= 2 EXP 24` THEN + ARITH_TAC; ALL_TAC] THEN + REWRITE_TAC[VAL_WORD_SUB_CASES] THEN + SIMP_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN + UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 <= val (num_blocks_adjusted:int64)` THEN + NUM_REDUCE_TAC THEN ARITH_TAC; ALL_TAC] THEN + UNDISCH_TAC `val (num_blocks_adjusted:int64) <= val (len:int64)` THEN + ARITH_TAC; ALL_TAC] THEN + MP_TAC (SPECL [`ct_ptr:int64`; `num_5blocks_adjusted:int64`; `len:int64`; `ct:byte list`; `s5:armstate`] READ_CT_TAIL3_LEMMA) THEN ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (6--97) THEN XTSDEC_TAC `Q0:(armstate,int128)component` - `val (num_5blocks_adjusted:int64) * 0x10` `val (num_5blocks_adjusted:int64) * 0x5` THEN + `val (num_5blocks_adjusted:int64) * 0x50` `val (num_5blocks_adjusted:int64) * 0x5` THEN XTSDEC_TAC `Q1:(armstate,int128)component` - `val (num_5blocks_adjusted:int64) * 0x10 + 0x10` `val (num_5blocks_adjusted:int64) * 0x5 + 0x1` THEN + `val (num_5blocks_adjusted:int64) * 0x50 + 0x10` `val (num_5blocks_adjusted:int64) * 0x5 + 0x1` THEN XTSDEC_TAC `Q24:(armstate,int128)component` - `val (num_5blocks_adjusted:int64) * 0x10 + 0x20` `val (num_5blocks_adjusted:int64) * 0x5 + 0x2` THEN + `val (num_5blocks_adjusted:int64) * 0x50 + 0x20` `val (num_5blocks_adjusted:int64) * 0x5 + 0x2` THEN ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (98--105) THEN TWEAK_TAC `Q6:(armstate,int128)component` `val (num_5blocks_adjusted:int64) * 0x5 + 0x3` `val (num_5blocks_adjusted:int64) * 0x5 + 0x2` THEN @@ -1696,8 +2088,6 @@ let AES_XTS_DECRYPT_CORRECT = prove( (* The following lemmas are for NONSELFMODIFYING_STATE_UPDATE_TAC when store back to pt_ptr *) RULE_ASSUM_TAC(REWRITE_RULE [WORD_RULE `word_mul (word 0x50) num_5blocks_adjusted:int64 = word(0x50 * val num_5blocks_adjusted)`]) THEN - SUBGOAL_THEN `80 * val(num_5blocks_adjusted:int64) + 48 <= val(len:int64)` - ASSUME_TAC THENL [CHEAT_TAC; ALL_TAC] THEN ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (106--110) THEN FIRST_X_ASSUM MP_TAC THEN @@ -1719,20 +2109,39 @@ let AES_XTS_DECRYPT_CORRECT = prove( COND_CASES_TAC THENL [ (* Case: len % 0x50 = 0x20 *) DISCH_TAC THEN - MP_TAC (SPECL [`ct_ptr:int64`; `s7:armstate`; `ct:byte list`; `len:int64`; `num_blocks:int64`; `num_5blocks_adjusted:int64`] READ_CT_TAIL2_LEMMA) THEN + + SUBGOAL_THEN `val (num_5blocks_adjusted:int64) * 0x50 + 0x20 <= val (len:int64)` ASSUME_TAC THENL + [ SUBGOAL_THEN `val (num_5blocks_adjusted:int64) * 0x50 + 0x20 = val (num_blocks_adjusted:int64)` MP_TAC THENL + [ UNDISCH_TAC `val (word_sub + (word_sub (num_blocks_adjusted:int64) + (word_mul (word 0x50) (num_5blocks_adjusted:int64))) + (word 0x20)) = + 0x0` THEN + REWRITE_TAC [VAL_EQ_0; WORD_SUB_EQ_0] THEN + REWRITE_TAC [WORD_RULE `!x:int64. word_mul (word 0x50) x = word(val x * 0x50)`] THEN + REWRITE_TAC[GSYM VAL_EQ] THEN + SUBGOAL_THEN `val (num_5blocks_adjusted:int64) * 0x50 < 2 EXP 64` MP_TAC THENL + [ UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 <= val (num_blocks_adjusted:int64)` THEN + UNDISCH_TAC `val (num_blocks_adjusted:int64) <= 2 EXP 24` THEN + ARITH_TAC; ALL_TAC] THEN + REWRITE_TAC[VAL_WORD_SUB_CASES] THEN + SIMP_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN + UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 <= val (num_blocks_adjusted:int64)` THEN + NUM_REDUCE_TAC THEN ARITH_TAC; ALL_TAC] THEN + UNDISCH_TAC `val (num_blocks_adjusted:int64) <= val (len:int64)` THEN + ARITH_TAC; ALL_TAC] THEN + MP_TAC (SPECL [`ct_ptr:int64`; `num_5blocks_adjusted:int64`; `len:int64`; `ct:byte list`; `s7:armstate`] READ_CT_TAIL2_LEMMA) THEN ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (8--68) THEN XTSDEC_TAC `Q0:(armstate,int128)component` - `val (num_5blocks_adjusted:int64) * 0x10` `val (num_5blocks_adjusted:int64) * 0x5` THEN + `val (num_5blocks_adjusted:int64) * 0x50` `val (num_5blocks_adjusted:int64) * 0x5` THEN XTSDEC_TAC `Q1:(armstate,int128)component` - `val (num_5blocks_adjusted:int64) * 0x10 + 0x10` `val (num_5blocks_adjusted:int64) * 0x5 + 0x1` THEN + `val (num_5blocks_adjusted:int64) * 0x50 + 0x10` `val (num_5blocks_adjusted:int64) * 0x5 + 0x1` THEN (* The following lemmas are for NONSELFMODIFYING_STATE_UPDATE_TAC when store back to pt_ptr *) RULE_ASSUM_TAC(REWRITE_RULE [WORD_RULE `word_mul (word 0x50) num_5blocks_adjusted:int64 = word(0x50 * val num_5blocks_adjusted)`]) THEN - SUBGOAL_THEN `80 * val(num_5blocks_adjusted:int64) + 32 <= val(len:int64)` - ASSUME_TAC THENL [CHEAT_TAC; ALL_TAC] THEN ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (69--77) THEN TWEAK_TAC `Q6:(armstate,int128)component` `val (num_5blocks_adjusted:int64) * 0x5 + 0x2` `val (num_5blocks_adjusted:int64) * 0x5 + 0x1` THEN @@ -1756,18 +2165,37 @@ let AES_XTS_DECRYPT_CORRECT = prove( COND_CASES_TAC THENL [ (* Case: len % 0x50 = 0x10 *) DISCH_TAC THEN - MP_TAC (SPECL [`ct_ptr:int64`; `s9:armstate`; `ct:byte list`; `len:int64`; `num_blocks:int64`; `num_5blocks_adjusted:int64`] READ_CT_TAIL1_LEMMA) THEN + + SUBGOAL_THEN `val (num_5blocks_adjusted:int64) * 0x50 + 0x10 <= val (len:int64)` ASSUME_TAC THENL + [ SUBGOAL_THEN `val (num_5blocks_adjusted:int64) * 0x50 + 0x10 = val (num_blocks_adjusted:int64)` MP_TAC THENL + [ UNDISCH_TAC `val (word_sub + (word_sub (num_blocks_adjusted:int64) + (word_mul (word 0x50) (num_5blocks_adjusted:int64))) + (word 0x10)) = + 0x0` THEN + REWRITE_TAC [VAL_EQ_0; WORD_SUB_EQ_0] THEN + REWRITE_TAC [WORD_RULE `!x:int64. word_mul (word 0x50) x = word(val x * 0x50)`] THEN + REWRITE_TAC[GSYM VAL_EQ] THEN + SUBGOAL_THEN `val (num_5blocks_adjusted:int64) * 0x50 < 2 EXP 64` MP_TAC THENL + [ UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 <= val (num_blocks_adjusted:int64)` THEN + UNDISCH_TAC `val (num_blocks_adjusted:int64) <= 2 EXP 24` THEN + ARITH_TAC; ALL_TAC] THEN + REWRITE_TAC[VAL_WORD_SUB_CASES] THEN + SIMP_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN + UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 <= val (num_blocks_adjusted:int64)` THEN + NUM_REDUCE_TAC THEN ARITH_TAC; ALL_TAC] THEN + UNDISCH_TAC `val (num_blocks_adjusted:int64) <= val (len:int64)` THEN + ARITH_TAC; ALL_TAC] THEN + MP_TAC (SPECL [`ct_ptr:int64`; `num_5blocks_adjusted:int64`; `len:int64`; `ct:byte list`; `s9:armstate`] READ_CT_TAIL1_LEMMA) THEN ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (10--40) THEN XTSDEC_TAC `Q0:(armstate,int128)component` - `val (num_5blocks_adjusted:int64) * 0x10` `val (num_5blocks_adjusted:int64) * 0x5` THEN + `val (num_5blocks_adjusted:int64) * 0x50` `val (num_5blocks_adjusted:int64) * 0x5` THEN (* The following lemmas are for NONSELFMODIFYING_STATE_UPDATE_TAC when store back to pt_ptr *) RULE_ASSUM_TAC(REWRITE_RULE [WORD_RULE `word_mul (word 0x50) num_5blocks_adjusted:int64 = word(0x50 * val num_5blocks_adjusted)`]) THEN - SUBGOAL_THEN `80 * val(num_5blocks_adjusted:int64) + 16 <= val(len:int64)` - ASSUME_TAC THENL [CHEAT_TAC; ALL_TAC] THEN ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (41--49) THEN TWEAK_TAC `Q6:(armstate,int128)component` `val (num_5blocks_adjusted:int64) * 0x5 + 0x1` `val (num_5blocks_adjusted:int64) * 0x5` THEN From 3893ef432eced8e73a63f4d014f7790ce5b005fd Mon Sep 17 00:00:00 2001 From: Yan Peng Date: Wed, 24 Sep 2025 11:53:18 -0700 Subject: [PATCH 034/132] Fixing MAYCHANGE and preserved registers --- arm/proofs/aes_xts_decrypt.ml | 108 ++++++++++++++++++++++++++++------ 1 file changed, 90 insertions(+), 18 deletions(-) diff --git a/arm/proofs/aes_xts_decrypt.ml b/arm/proofs/aes_xts_decrypt.ml index 53743a8b0..68ab49210 100644 --- a/arm/proofs/aes_xts_decrypt.ml +++ b/arm/proofs/aes_xts_decrypt.ml @@ -1476,16 +1476,33 @@ let AES_XTS_DECRYPT_CORRECT = prove( [k10; k11; k12; k13; k14; k15; k16; k17; k18; k19; k1a; k1b; k1c; k1d; k1e] pt_init) pt_ptr len s ) - (MAYCHANGE [PC] ,, MAYCHANGE [events] ,, - MAYCHANGE [X21;X2;X6;X4;X9;X10;X19;X22;X11;X7;X0;X1;X8] ,, - MAYCHANGE [Q6;Q1;Q0;Q8;Q9;Q10;Q11;Q16;Q17;Q12;Q13;Q14;Q15; - Q4;Q5;Q18;Q19;Q20;Q21;Q22;Q23;Q7;Q29;Q24;Q25;Q26] ,, - MAYCHANGE SOME_FLAGS,, MAYCHANGE [memory :> bytes(pt_ptr, val len)]) + (MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI,, + MAYCHANGE [X19; X20; X21; X22],, + MAYCHANGE [Q8; Q9; Q10; Q11; Q12; Q13; Q14; Q15],, + MAYCHANGE [memory :> bytes(pt_ptr, val len)]) `, REWRITE_TAC [(REWRITE_CONV [aes_xts_decrypt_mc] THENC LENGTH_CONV) `LENGTH aes_xts_decrypt_mc`] THEN - REWRITE_TAC[set_key_schedule; C_ARGUMENTS; SOME_FLAGS; NONOVERLAPPING_CLAUSES; byte_list_at] THEN + REWRITE_TAC[set_key_schedule; C_ARGUMENTS; SOME_FLAGS; + NONOVERLAPPING_CLAUSES; byte_list_at; + MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI] THEN REPEAT STRIP_TAC THEN + (* These are for top-level wrapper function + (* Add values for preserved registers *) + ENSURES_PRESERVED_TAC "x19_init" `X19` THEN + ENSURES_PRESERVED_TAC "x20_init" `X20` THEN + ENSURES_PRESERVED_TAC "x21_init" `X21` THEN + ENSURES_PRESERVED_TAC "x22_init" `X22` THEN + ENSURES_PRESERVED_DREG_TAC "d8_init" `D8` THEN + ENSURES_PRESERVED_DREG_TAC "d9_init" `D9` THEN + ENSURES_PRESERVED_DREG_TAC "d10_init" `D10` THEN + ENSURES_PRESERVED_DREG_TAC "d11_init" `D11` THEN + ENSURES_PRESERVED_DREG_TAC "d12_init" `D12` THEN + ENSURES_PRESERVED_DREG_TAC "d13_init" `D13` THEN + ENSURES_PRESERVED_DREG_TAC "d14_init" `D14` THEN + ENSURES_PRESERVED_DREG_TAC "d15_init" `D15` THEN +*) + (* Break len into full blocks and tail *) SUBGOAL_THEN `word_add (word_and len (word 0xf)) (word_and len (word 0xfffffffffffffff0)) = len:int64` ASSUME_TAC THENL @@ -1874,6 +1891,32 @@ let AES_XTS_DECRYPT_CORRECT = prove( (* Subgoal 3: loop body *) REPEAT STRIP_TAC THEN + + SUBGOAL_THEN `i * 0x50 + 0x50 <= val (len:int64)` ASSUME_TAC THENL + [ SUBGOAL_THEN `i + 1 <= val (num_5blocks_adjusted:int64)` MP_TAC THENL + [ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `(i + 1) * 0x50 <= val (len:int64)` MP_TAC THENL + [ASM_ARITH_TAC; ALL_TAC] THEN + ARITH_TAC; ALL_TAC] THEN + + MATCH_MP_TAC ENSURES_FRAME_SUBSUMED THEN + EXISTS_TAC `MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI ,, + MAYCHANGE [X19; X20; X21; X22],, + MAYCHANGE [Q8; Q9; Q10; Q11; Q12; Q13; Q14; Q15],, + MAYCHANGE [memory :> bytes128 (word_add pt_ptr (word (0x50 * i))); + memory :> bytes128 (word_add pt_ptr (word (0x50 * i + 0x10))); + memory :> bytes128 (word_add pt_ptr (word (0x50 * i + 0x20))); + memory :> bytes128 (word_add pt_ptr (word (0x50 * i + 0x30))); + memory :> bytes128 (word_add pt_ptr (word (0x50 * i + 0x40)))]` THEN + REWRITE_TAC[MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI] THEN + CONJ_TAC THENL [ + REPEAT (GEN_REWRITE_TAC ONCE_DEPTH_CONV [GSYM SEQ_ASSOC] THEN + MATCH_MP_TAC SUBSUMED_SEQ THEN REWRITE_TAC[SUBSUMED_REFL]) THEN + REWRITE_TAC [ARITH_RULE `0x50 * i = i * 0x50`] THEN + (* SUBSUMED_MAYCHANGE_TAC *) + CHEAT_TAC + ; ALL_TAC] THEN + (* ===> Symbolic Simulation: Start symbolic simulation*) ASM_REWRITE_TAC[byte_list_at] THEN @@ -1884,12 +1927,6 @@ let AES_XTS_DECRYPT_CORRECT = prove( GHOST_INTRO_TAC `b4:int128` `read (memory :> bytes128 (word_add (word_add pt_ptr (word_mul (word 0x50) (word i))) (word 0x40)))` THEN ENSURES_INIT_TAC "s0" THEN - SUBGOAL_THEN `i * 0x50 + 0x50 <= val (len:int64)` ASSUME_TAC THENL - [ SUBGOAL_THEN `i + 1 <= val (num_5blocks_adjusted:int64)` MP_TAC THENL - [ASM_ARITH_TAC; ALL_TAC] THEN - SUBGOAL_THEN `(i + 1) * 0x50 <= val (len:int64)` MP_TAC THENL - [ASM_ARITH_TAC; ALL_TAC] THEN - ARITH_TAC; ALL_TAC] THEN (* List values for ct_ptr + [0 .. 0x40] *) MP_TAC (SPECL [`ct_ptr:int64`; `i:num`; `len:int64`; `ct:byte list`; `s0:armstate`] READ_CT_LEMMA) THEN ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN @@ -1941,7 +1978,10 @@ let AES_XTS_DECRYPT_CORRECT = prove( REWRITE_TAC[WORD_RULE `(i + 0x1) * 0x5 + 0x4 = i * 0x5 + 0x9`]; CHEAT_TAC; SUBGOAL_THEN `i + 1 < 2 EXP 64` ASSUME_TAC THENL - [CHEAT_TAC; ALL_TAC] THEN + [ UNDISCH_TAC `i < val (num_5blocks_adjusted:int64)` THEN + EXPAND_TAC "num_5blocks_adjusted" THEN + UNDISCH_TAC `val (num_blocks_adjusted:int64) <= 0x2 EXP 0x18` THEN + REWRITE_TAC [VAL_WORD; DIMINDEX_64] THEN ARITH_TAC; ALL_TAC] THEN EQ_TAC THENL [ REWRITE_TAC[WORD_RULE `!x:int64 a b. (word_sub (word_sub x a) b) = word_sub x (word_add a b)`] THEN ASM_SIMP_TAC[WORD_RULE `!a b. a + b < 2 EXP 64 ==> (word_add (word a) (word b)) = word (a + b)`] THEN @@ -1950,9 +1990,7 @@ let AES_XTS_DECRYPT_CORRECT = prove( IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT]; REWRITE_TAC[WORD_RULE `!x:int64 a b. (word_sub (word_sub x a) b) = word_sub x (word_add a b)`] THEN ASM_SIMP_TAC[WORD_RULE `!a b. a + b < 2 EXP 64 ==> (word_add (word a) (word b)) = word (a + b)`] THEN - REWRITE_TAC[VAL_EQ_0; WORD_SUB_EQ_0; WORD_VAL] - ]; - CHEAT_TAC + REWRITE_TAC[VAL_EQ_0; WORD_SUB_EQ_0; WORD_VAL]] ]; @@ -1982,6 +2020,41 @@ let AES_XTS_DECRYPT_CORRECT = prove( GHOST_INTRO_TAC `bt_3:int128` `read (memory :> bytes128 (word_add (word_add (pt_ptr:int64) (word_mul (word 0x50) (num_5blocks_adjusted:int64))) (word 0x30)))` THEN + MATCH_MP_TAC ENSURES_FRAME_SUBSUMED THEN + EXISTS_TAC `MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI ,, + MAYCHANGE [X19; X20; X21; X22],, + MAYCHANGE [Q8; Q9; Q10; Q11; Q12; Q13; Q14; Q15],, + if val (num_5blocks_adjusted:int64) * 0x50 + 0x40 <= val (len:int64) + then + MAYCHANGE [memory :> bytes128 (word_add pt_ptr (word (0x50 * val (num_5blocks_adjusted:int64)))); + memory :> bytes128 (word_add pt_ptr (word (0x50 * val num_5blocks_adjusted + 0x10))); + memory :> bytes128 (word_add pt_ptr (word (0x50 * val num_5blocks_adjusted + 0x20))); + memory :> bytes128 (word_add pt_ptr (word (0x50 * val num_5blocks_adjusted + 0x30)))] + else + (if val (num_5blocks_adjusted:int64) * 0x50 + 0x30 <= val (len:int64) + then + MAYCHANGE [memory :> bytes128 (word_add pt_ptr (word (0x50 * val (num_5blocks_adjusted:int64)))); + memory :> bytes128 (word_add pt_ptr (word (0x50 * val num_5blocks_adjusted + 0x10))); + memory :> bytes128 (word_add pt_ptr (word (0x50 * val num_5blocks_adjusted + 0x20)))] + else + (if val (num_5blocks_adjusted:int64) * 0x50 + 0x20 <= val (len:int64) + then + MAYCHANGE [memory :> bytes128 (word_add pt_ptr (word (0x50 * val (num_5blocks_adjusted:int64)))); + memory :> bytes128 (word_add pt_ptr (word (0x50 * val num_5blocks_adjusted + 0x10)))] + else + (if val (num_5blocks_adjusted:int64) * 0x50 + 0x10 <= val (len:int64) + then + MAYCHANGE [memory :> bytes128 (word_add pt_ptr (word (0x50 * val (num_5blocks_adjusted:int64))))] + else + MAYCHANGE [])))` THEN + REWRITE_TAC[MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI] THEN + CONJ_TAC THENL [ + REPEAT (GEN_REWRITE_TAC ONCE_DEPTH_CONV [GSYM SEQ_ASSOC] THEN + MATCH_MP_TAC SUBSUMED_SEQ THEN REWRITE_TAC[SUBSUMED_REFL]) THEN + (* SUBSUMED_MAYCHANGE_TAC *) + CHEAT_TAC + ; ALL_TAC] THEN + ENSURES_INIT_TAC "s0" THEN ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (1--3) THEN FIRST_X_ASSUM MP_TAC THEN @@ -2037,8 +2110,7 @@ let AES_XTS_DECRYPT_CORRECT = prove( DISCH_TAC THEN ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN CHEAT_TAC; - ALL_TAC - ] THEN + ALL_TAC] THEN (* Cipher stealing branch *) CHEAT_TAC; ALL_TAC From 39f7f44c2823d604dd4f1bee0813b5e543b5955d Mon Sep 17 00:00:00 2001 From: Yan Peng Date: Thu, 25 Sep 2025 17:15:04 -0700 Subject: [PATCH 035/132] WIP: proving main goal --- arm/proofs/aes_xts_decrypt.ml | 52 +++++++++++++++++++++++++++++------ 1 file changed, 44 insertions(+), 8 deletions(-) diff --git a/arm/proofs/aes_xts_decrypt.ml b/arm/proofs/aes_xts_decrypt.ml index 68ab49210..901216556 100644 --- a/arm/proofs/aes_xts_decrypt.ml +++ b/arm/proofs/aes_xts_decrypt.ml @@ -5,6 +5,7 @@ use_file_raise_failure := true;; arm_print_log := true;; +components_print_log := true;; needs "arm/proofs/base.ml";; loadt "arm/proofs/aes_xts_decrypt_spec.ml";; @@ -1453,6 +1454,15 @@ let NUM_BLOCKS_ADJUSTED_LT_LEN_THM = prove( BITBLAST_TAC );; +let BYTE_LIST_TO_NUM_THM = prove( + `!len (bl:byte list) s. + (forall i. i < len + ==> read (memory :> bytes8 (word_add pt_ptr (word i))) s = EL i bl) + <=> + (read (memory :> bytes (pt_ptr, len)) s = num_of_bytelist bl)`, + CHEAT_TAC +);; + let AES_XTS_DECRYPT_CORRECT = prove( `!ct_ptr pt_ptr ct pt_init key1_ptr key2_ptr iv_ptr iv len k00 k01 k02 k03 k04 k05 k06 k07 k08 k09 k0a k0b k0c k0d k0e @@ -1912,10 +1922,8 @@ let AES_XTS_DECRYPT_CORRECT = prove( CONJ_TAC THENL [ REPEAT (GEN_REWRITE_TAC ONCE_DEPTH_CONV [GSYM SEQ_ASSOC] THEN MATCH_MP_TAC SUBSUMED_SEQ THEN REWRITE_TAC[SUBSUMED_REFL]) THEN - REWRITE_TAC [ARITH_RULE `0x50 * i = i * 0x50`] THEN - (* SUBSUMED_MAYCHANGE_TAC *) - CHEAT_TAC - ; ALL_TAC] THEN + ABBREV_TAC `vallen = val (len:int64)` THEN + SUBSUMED_MAYCHANGE_TAC; ALL_TAC] THEN (* ===> Symbolic Simulation: Start symbolic simulation*) ASM_REWRITE_TAC[byte_list_at] THEN @@ -1957,8 +1965,13 @@ let AES_XTS_DECRYPT_CORRECT = prove( RULE_ASSUM_TAC(REWRITE_RULE [WORD_RULE `word_mul (word 0x50) (word i):int64 = word(0x50 * i)`]) THEN + (* Rewrite to help reasoning about nonoverlapping + so that the universally quantified assumption stays. *) + SUBGOAL_THEN `val ((word (0x50 * i)):int64) = 0x50 * i` ASSUME_TAC THENL [ + IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN ASM_ARITH_TAC; ALL_TAC] THEN + POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th])) THEN + (* Simulate until end of loop *) - (* TODO: previous pt_ptr blocks are removed from hypotheses!!!! *) ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (184--188) THEN ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN REPEAT CONJ_TAC THENL @@ -1976,7 +1989,24 @@ let AES_XTS_DECRYPT_CORRECT = prove( REWRITE_TAC[WORD_RULE `(i + 0x1) * 0x5 + 0x4 = i * 0x5 + 0x9`]; REWRITE_TAC[WORD_RULE `(i + 0x1) * 0x5 + 0x4 = i * 0x5 + 0x9`]; REWRITE_TAC[WORD_RULE `(i + 0x1) * 0x5 + 0x4 = i * 0x5 + 0x9`]; - CHEAT_TAC; + (* WIP *) + REWRITE_TAC[ARITH_RULE `0x50 * (i + 0x1) = 0x50 * i + 0x50`] THEN + SUBGOAL_THEN `val ((word (0x50 * i + 0x50)):int64) = 0x50 * i + 0x50` ASSUME_TAC THENL [ + IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN + UNDISCH_TAC `i * 0x50 + 0x50 <= val (len:int64)` THEN + UNDISCH_TAC `val (len:int64) <= 2 EXP 24` THEN + ARITH_TAC; ALL_TAC] THEN + ASM_REWRITE_TAC[] THEN + + UNDISCH_TAC + `forall i'. + i' < 0x50 * i + ==> read (memory :> bytes8 (word_add pt_ptr (word i'))) s188 = + EL i' (aes256_xts_decrypt ct (0x50 * i) iv key1 key2 pt_init)` THEN + REWRITE_TAC[BYTE_LIST_TO_NUM_THM] THEN + + CHEAT_TAC + ; SUBGOAL_THEN `i + 1 < 2 EXP 64` ASSUME_TAC THENL [ UNDISCH_TAC `i < val (num_5blocks_adjusted:int64)` THEN EXPAND_TAC "num_5blocks_adjusted" THEN @@ -2111,8 +2141,14 @@ let AES_XTS_DECRYPT_CORRECT = prove( ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN CHEAT_TAC; ALL_TAC] THEN - (* Cipher stealing branch *) - CHEAT_TAC; + + (* WIP: Cipher stealing branch *) + DISCH_TAC THEN + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (139--147) THEN + TWEAK_TAC `Q8:(armstate,int128)component` `val (num_5blocks_adjusted:int64) * 0x5 + 0x5` `val (num_5blocks_adjusted:int64) * 0x5 + 0x4` THEN + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (148--148) THEN + CHEAT_TAC + ; ALL_TAC ] THEN From a4545a8f0258c321fb00c1a282fb5395704dc691 Mon Sep 17 00:00:00 2001 From: Yan Peng Date: Fri, 26 Sep 2025 15:05:12 -0700 Subject: [PATCH 036/132] Simplify specification --- arm/proofs/aes_xts_decrypt_spec.ml | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/arm/proofs/aes_xts_decrypt_spec.ml b/arm/proofs/aes_xts_decrypt_spec.ml index 3759537ad..0b161ae91 100644 --- a/arm/proofs/aes_xts_decrypt_spec.ml +++ b/arm/proofs/aes_xts_decrypt_spec.ml @@ -92,14 +92,14 @@ let calculate_tweak = new_recursive_definition num_RECURSION let eth = prove_general_recursive_function_exists `?aes256_xts_decrypt_rec. ! (i:num) (m:num) (C:byte list) (iv:int128) (key1:int128 list) (key2:int128 list). - aes256_xts_decrypt_rec i m C iv key1 key2: (byte list)#num = - if m < i then ([], i) + aes256_xts_decrypt_rec i m C iv key1 key2: byte list = + if m < i then [] else let current_block = bytes_to_int128 (SUB_LIST (i * 16, 16) C) in let twk = calculate_tweak i iv key2 in let curr = int128_to_bytes (aes256_xts_decrypt_round current_block twk key1) in let res = aes256_xts_decrypt_rec (i + 1) m C iv key1 key2 in - (APPEND curr (FST res), SND res)`;; + APPEND curr res`;; let wfth = prove(hd(hyp eth), EXISTS_TAC `MEASURE (\(i:num,m:num,C:byte list,iv:int128,key1:int128 list,key2:int128 list). (m + 1) - i)` THEN @@ -168,8 +168,8 @@ let aes256_xts_decrypt = new_definition aes256_xts_decrypt_tail 0 tail_len C iv key1 key2 else let res = aes256_xts_decrypt_rec 0 (m - 2) C iv key1 key2 in - let Ptail = aes256_xts_decrypt_tail (SND res) tail_len C iv key1 key2 in - APPEND (FST res) Ptail`;; + let Ptail = aes256_xts_decrypt_tail (m - 1) tail_len C iv key1 key2 in + APPEND res Ptail`;; (*******************************************) (* Test vectors printed from AWS-LC *) @@ -430,7 +430,7 @@ let rec AES256_XTS_DECRYPT_REC_CONV tm = SUBLET_CONV (RAND_CONV AES256_XTS_DECRYPT_ROUND_CONV) THENC SUBLET_CONV INT128_TO_BYTES_CONV THENC let_CONV THENC SUBLET_CONV AES256_XTS_DECRYPT_REC_CONV THENC let_CONV THENC - REWRITE_CONV [FST;SND;APPEND] in + REWRITE_CONV [APPEND] in match tm with | Comb (Comb @@ -450,7 +450,7 @@ let rec AES256_XTS_DECRYPT_REC_CONV tm = (* (REWRITE_CONV [iv_tweak;KEY1;KEY2;c0] THENC AES256_XTS_DECRYPT_REC_CONV) `aes256_xts_decrypt_rec 0 0 c0 iv_tweak KEY1 KEY2`;; - *) +*) let CIPHER_STEALING_CONV = REWRITE_CONV [cipher_stealing] THENC @@ -519,7 +519,6 @@ let AES256_XTS_DECRYPT_CONV tm = DEPTH_CONV NUM_RED_CONV in let MORE_THAN_2_CONV = SUBLET_CONV AES256_XTS_DECRYPT_REC_CONV THENC let_CONV THENC - REWRITE_CONV [FST;SND] THENC SUBLET_CONV AES256_XTS_DECRYPT_TAIL_CONV THENC let_CONV THENC REWRITE_CONV [APPEND] in let BODY_CONV = From 4a582cede411fcaf435231cfecb38e73975addf0 Mon Sep 17 00:00:00 2001 From: Yan Peng Date: Fri, 26 Sep 2025 17:44:16 -0700 Subject: [PATCH 037/132] WIP: proving main goal --- arm/proofs/aes_xts_decrypt.ml | 573 +++++++++++++++++++++++++++++++++- 1 file changed, 568 insertions(+), 5 deletions(-) diff --git a/arm/proofs/aes_xts_decrypt.ml b/arm/proofs/aes_xts_decrypt.ml index 901216556..e0cb11a14 100644 --- a/arm/proofs/aes_xts_decrypt.ml +++ b/arm/proofs/aes_xts_decrypt.ml @@ -1463,6 +1463,276 @@ let BYTE_LIST_TO_NUM_THM = prove( CHEAT_TAC );; +let MEMORY_BYTES_BOUND = prove + (`read (memory :> bytes (x,16)) s < 2 EXP dimindex (:128)`, + REWRITE_TAC[READ_COMPONENT_COMPOSE; DIMINDEX_128] THEN + SUBST1_TAC(ARITH_RULE `128 = 8 * 16`) THEN REWRITE_TAC[READ_BYTES_BOUND] + );; + +(* Copied from bignum_copy_row_from_table_8n.ml *) +let READ_MEMORY_BYTES_BYTES128 = prove(`!z s. + read (memory :> bytes (z,16)) s = val (read (memory :> bytes128 z) s)`, + REPEAT GEN_TAC THEN + REWRITE_TAC[el 1 (CONJUNCTS READ_MEMORY_BYTESIZED_SPLIT)] THEN + REWRITE_TAC[VAL_WORD_JOIN;DIMINDEX_64;DIMINDEX_128] THEN + IMP_REWRITE_TAC[MOD_LT] THEN + REWRITE_TAC[ARITH_RULE`2 EXP 128 = 2 EXP 64 * 2 EXP 64`] THEN + IMP_REWRITE_TAC[LT_MULT_ADD_MULT] THEN + REWRITE_TAC[VAL_BOUND_64;ARITH_RULE`0<2 EXP 64`;LE_REFL] THEN + REWRITE_TAC[ARITH_RULE`16 = 8*(1+1)`;GSYM BIGNUM_FROM_MEMORY_BYTES;BIGNUM_FROM_MEMORY_STEP;BIGNUM_FROM_MEMORY_SING] THEN + REWRITE_TAC[ARITH_RULE`8*1=8`;ARITH_RULE`64*1=64`] THEN ARITH_TAC);; + +let READ_MEMORY_BYTES128_BYTES = prove(`!z s. + read (memory :> bytes128 z) s = word (read (memory :> bytes (z,16)) s)`, + REPEAT STRIP_TAC THEN + ONCE_REWRITE_TAC[GSYM VAL_EQ] THEN + IMP_REWRITE_TAC [VAL_WORD_EQ] THEN + CONJ_TAC THENL [REWRITE_TAC [READ_MEMORY_BYTES_BYTES128]; ALL_TAC] THEN + REWRITE_TAC [MEMORY_BYTES_BOUND] + );; + +let NUM_OF_BYTELIST_APPEND = prove + (`!l1 l2. num_of_bytelist (APPEND l1 l2) = + num_of_bytelist l1 + 2 EXP (8 * LENGTH l1) * num_of_bytelist l2`, + LIST_INDUCT_TAC THENL + [ REWRITE_TAC[APPEND; LENGTH; num_of_bytelist; MULT_CLAUSES; EXP; ADD_CLAUSES]; + REWRITE_TAC[APPEND; LENGTH; num_of_bytelist] THEN + ASM_REWRITE_TAC[] THEN + REWRITE_TAC[MULT_SUC; EXP_ADD] THEN + REWRITE_TAC[MULT_ASSOC; LEFT_ADD_DISTRIB] THEN + ARITH_TAC]);; + +let NUM_OF_BYTELIST_OF_SUB_LIST = prove( + `!sz len (x:byte list). + sz <= LENGTH x ==> + num_of_bytelist (SUB_LIST (0, sz + len) x) = + num_of_bytelist (SUB_LIST (0, sz) x) + + 2 EXP (8 * sz) * num_of_bytelist (SUB_LIST (sz, len) x)`, + REPEAT STRIP_TAC THEN + SUBST1_TAC(ISPECL [`x:byte list`; `sz:num`; `len:num`; `0:num`] SUB_LIST_SPLIT) THEN + REWRITE_TAC[NUM_OF_BYTELIST_APPEND] THEN + ASM_SIMP_TAC[LENGTH_SUB_LIST; SUB_0; MIN; ARITH_RULE `0 + sz = sz`] +);; + +let VAL_OF_BYTES_TO_INT128_EQ_NUM_OF_BYTELIST = prove( + `!x:byte list. LENGTH x = 16 ==> val (bytes_to_int128 x) = num_of_bytelist x`, + REPEAT STRIP_TAC THEN + CHEAT_TAC +);; + +let READ_BYTES_AND_BYTE128_SPLIT = prove( + `!(pt_ptr:int64) (sz:num) (x:byte list) (s:armstate). + sz + 16 <= LENGTH x ==> + read (memory :> bytes128 (word_add pt_ptr (word sz))) s = bytes_to_int128 (SUB_LIST (sz, 0x10) x) + /\ read (memory :> bytes (pt_ptr, sz)) s = num_of_bytelist (SUB_LIST (0, sz) x) + ==> read (memory :> bytes (pt_ptr,sz + 0x10)) s = num_of_bytelist (SUB_LIST (0, sz + 0x10) x)`, + REWRITE_TAC[READ_MEMORY_BYTES128_BYTES] THEN + REPEAT STRIP_TAC THEN + + SUBGOAL_THEN `sz <= LENGTH (x:byte list)` ASSUME_TAC THENL + [ UNDISCH_TAC `sz + 16 <= LENGTH (x:byte list)` THEN ARITH_TAC; ALL_TAC ] THEN + + SUBGOAL_THEN `16 <= LENGTH (x:byte list) - sz` ASSUME_TAC THENL + [ UNDISCH_TAC `sz + 16 <= LENGTH (x:byte list)` THEN ARITH_TAC; ALL_TAC ] THEN + + SUBGOAL_THEN `read (memory :> bytes (pt_ptr, sz + 16)) s = + read (memory :> bytes (pt_ptr, sz)) s + + 2 EXP (8 * sz) * (read (memory :> bytes (word_add pt_ptr (word sz), 16)) s)` SUBST1_TAC THENL + [ REWRITE_TAC[READ_COMPONENT_COMPOSE] THEN + REWRITE_TAC[READ_BYTES_COMBINE]; ALL_TAC] THEN + + ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN `read (memory :> bytes (word_add pt_ptr (word sz),0x10)) s = + val (bytes_to_int128 (SUB_LIST (sz,0x10) x))` SUBST1_TAC THENL + [ UNDISCH_THEN + `word (read (memory :> bytes (word_add (pt_ptr:int64) (word sz),0x10)) s) = + bytes_to_int128 (SUB_LIST (sz,0x10) x)` + (fun th -> MP_TAC (AP_TERM `val:int128->num` th)) THEN + IMP_REWRITE_TAC[VAL_WORD] THEN + SUBGOAL_THEN `read (memory :> bytes (word_add pt_ptr (word sz),0x10)) s < 2 EXP dimindex (:128)` ASSUME_TAC THENL + [ SIMP_TAC[MEMORY_BYTES_BOUND] ; ALL_TAC] THEN + SUBST_ALL_TAC DIMINDEX_128 THEN + ASM_SIMP_TAC[MOD_LT]; ALL_TAC] THEN + + IMP_REWRITE_TAC[NUM_OF_BYTELIST_OF_SUB_LIST] THEN + IMP_REWRITE_TAC[VAL_OF_BYTES_TO_INT128_EQ_NUM_OF_BYTELIST] THEN + REWRITE_TAC[LENGTH_SUB_LIST; MIN] THEN ASM_SIMP_TAC[] + );; + + +let SUB_LIST_APPEND_RIGHT_LEMMA = prove( + `!(x:A list) y n m. LENGTH x = n ==> SUB_LIST (n,m) (APPEND x y) = SUB_LIST (0,m) y`, + LIST_INDUCT_TAC THENL + [ REPEAT GEN_TAC THEN + SIMP_TAC[CONJUNCT1 LENGTH; APPEND; SUB_LIST_CLAUSES]; + + ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN + INDUCT_TAC THENL[ + SIMP_TAC[LENGTH_EQ_NIL] THEN REWRITE_TAC[APPEND]; + ASM_SIMP_TAC[APPEND; LENGTH; SUB_LIST_CLAUSES; SUC_INJ]]]);; + +let SUB_LIST_LENGTH_IMPLIES = prove( + `!(l:A list) n. LENGTH l = n ==> SUB_LIST(0,n) l = l`, + REPEAT STRIP_TAC THEN + UNDISCH_THEN `LENGTH (l:A list) = n` (fun th -> REWRITE_TAC[GSYM th]) THEN + REWRITE_TAC[SUB_LIST_LENGTH] +);; + +let LENGTH_OF_INT128_TO_BYTES = prove( + `!x. LENGTH(int128_to_bytes x) = 16`, + STRIP_TAC THEN + REWRITE_TAC[int128_to_bytes] THEN + REWRITE_TAC[LENGTH] THEN + CONV_TAC NUM_REDUCE_CONV +);; + +(* Properties that we prove about the specification functions *) +let LENGTH_OF_AES256_XTS_DECRYPT_REC = prove( + `!(i:num) (m:num) (C:byte list) (iv:int128) (key1:int128 list) (key2:int128 list). + LENGTH(aes256_xts_decrypt_rec i m C iv key1 key2) = (if m < i then 0 else (m - i + 1) * 0x10)`, + REPEAT GEN_TAC THEN + (* Wellfounded induction with measure (m + 1) - i + Note that the parentheses are essential because of the precedence of + and - *) + WF_INDUCT_TAC `(m + 1) - i` THEN + ONCE_REWRITE_TAC[aes256_xts_decrypt_rec] THEN + COND_CASES_TAC THENL + [ SIMP_TAC[LENGTH_EQ_NIL]; + SIMP_TAC[] THEN + REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + REWRITE_TAC[LENGTH_APPEND] THEN + SUBGOAL_THEN `~(m < i) ==> (m + 1) - (i + 1) < (m + 1) - i` ASSUME_TAC THENL + [ ASM_ARITH_TAC ; ALL_TAC ] THEN + ASM_SIMP_TAC[] THEN + REWRITE_TAC[LENGTH_OF_INT128_TO_BYTES] THEN + COND_CASES_TAC THENL + [ASM_ARITH_TAC; ASM_ARITH_TAC]] +);; + +let LENGTH_OF_FST_OF_CIPHER_STEALING = prove( + `!(block:byte list) (tail:byte list) (tail_len:num) + (iv:int128) (i:num) (key1:int128 list) (key2:int128 list). + LENGTH (FST (cipher_stealing block tail tail_len iv i key1 key2)) = 16`, + REPEAT STRIP_TAC THEN + REWRITE_TAC[cipher_stealing] THEN + ASM_REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + REWRITE_TAC[LENGTH_OF_INT128_TO_BYTES] +);; + +let LENGTH_OF_SND_OF_CIPHER_STEALING = prove( + `!(block:byte list) (tail:byte list) (tail_len:num) + (iv:int128) (i:num) (key1:int128 list) (key2:int128 list). + LENGTH (SND (cipher_stealing block tail tail_len iv i key1 key2)) = MIN tail_len 16`, + REPEAT STRIP_TAC THEN + REWRITE_TAC[cipher_stealing] THEN + ASM_REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + REWRITE_TAC[LENGTH_SUB_LIST] THEN + REWRITE_TAC[LENGTH_OF_INT128_TO_BYTES] THEN + REWRITE_TAC[MIN] THEN + CONV_TAC NUM_REDUCE_CONV +);; + +let LENGTH_OF_AES256_XTS_DECRYPT_TAIL = prove( + `! (i:num) (tail_len:num) (C:byte list) (iv:int128) (key1:int128 list) (key2:int128 list). + LENGTH(aes256_xts_decrypt_tail i tail_len C iv key1 key2) = 0x10 + MIN tail_len 16`, + REPEAT STRIP_TAC THEN + REWRITE_TAC[aes256_xts_decrypt_tail] THEN + COND_CASES_TAC THENL [ + ASM_REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + REWRITE_TAC[LENGTH_OF_INT128_TO_BYTES] THEN + REWRITE_TAC[ADD_CLAUSES; MIN] THEN + CONV_TAC NUM_REDUCE_CONV; + + REWRITE_TAC[LET_DEF; LET_END_DEF; LENGTH_APPEND] THEN + REWRITE_TAC[LENGTH_OF_FST_OF_CIPHER_STEALING] THEN + REWRITE_TAC[LENGTH_OF_SND_OF_CIPHER_STEALING]] +);; + +(* The arithmetic reasoning in this proof is surprisingly hard *) +let LENGTH_OF_AES256_XTS_DECRYPT = prove( + `! (len:num) (ct:byte list) (iv:int128) (key1:int128 list) (key2:int128 list) (pt_init:byte list). + ~(len < 16) ==> LENGTH(aes256_xts_decrypt ct len iv key1 key2 pt_init) = len`, + REPEAT STRIP_TAC THEN + ASM_REWRITE_TAC[aes256_xts_decrypt] THEN + REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + SUBGOAL_THEN `len MOD 0x10 < 16` ASSUME_TAC THENL + [ MP_TAC (SPEC `16` (SPEC `len:num` MOD_LT_EQ)) THEN + CONV_TAC NUM_REDUCE_CONV THEN ARITH_TAC + ; ALL_TAC ] THEN + COND_CASES_TAC THENL + [ + REWRITE_TAC[LENGTH_OF_AES256_XTS_DECRYPT_TAIL] THEN + REWRITE_TAC[MIN] THEN + SUBGOAL_THEN `len MOD 16 <= 16` ASSUME_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[] THEN + SUBGOAL_THEN `len - len MOD 16 <= 32` ASSUME_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `len <= 48` ASSUME_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `(len - len MOD 16) DIV 16 = 0 \/ (len - len MOD 16) DIV 16 = 1` STRIP_ASSUME_TAC THENL + [ ASM_ARITH_TAC; + + (* case: (len - len MOD 0x10) DIV 0x10 = 0x0 *) + MP_TAC (SPECL [`len - len MOD 0x10`; `0x10`] DIV_EQ_0) THEN + CONV_TAC NUM_REDUCE_CONV THEN ASM_SIMP_TAC[] THEN DISCH_TAC THEN + SUBGOAL_THEN `len - len MOD 0x10 = 0` ASSUME_TAC THENL + [ MP_TAC (SPECL [`len - len MOD 0x10`; `0x10`] DIVISION) THEN + CONV_TAC NUM_REDUCE_CONV THEN + DISCH_THEN (fun th -> SUBST1_TAC (CONJUNCT1 th)) THEN + ASM_REWRITE_TAC[MULT_CLAUSES; ADD_CLAUSES] THEN + CHEAT_TAC + ; ALL_TAC] THEN + SUBGOAL_THEN `len MOD 0x10 <= len` ASSUME_TAC THENL + [CHEAT_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[] THEN ASM_ARITH_TAC; + + (* case: (len - len MOD 0x10) DIV 0x10 = 0x1 *) + SUBGOAL_THEN `len - len MOD 16 = 16` ASSUME_TAC THENL [ + CHEAT_TAC; ALL_TAC] THEN + ASM_ARITH_TAC + ]; + + REWRITE_TAC[LENGTH_APPEND] THEN + REWRITE_TAC[LENGTH_OF_AES256_XTS_DECRYPT_REC] THEN + SUBGOAL_THEN `~((len - len MOD 0x10) DIV 0x10 - 0x2 < 0x0)` ASSUME_TAC THENL + [CHEAT_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[] THEN + ASM_REWRITE_TAC[LENGTH_OF_AES256_XTS_DECRYPT_TAIL; MIN; SUB_0] THEN + CHEAT_TAC + ] +);; + +let BYTES_TO_INT128_OF_INT128_TO_BYTES = prove( + `!x. bytes_to_int128 (int128_to_bytes x) = x`, + GEN_TAC THEN + REWRITE_TAC[int128_to_bytes; bytes_to_int128] THEN + REWRITE_TAC EL_16_8_CLAUSES THEN + BITBLAST_TAC +);; + + +let AES256_XTS_DECRYPT_TAIL_WHEN_1BLOCK = prove( + `!(n:num) (ct:byte list) (iv:int128) (key1:int128 list) (key2:int128 list). + bytes_to_int128 + (aes256_xts_decrypt_tail n 0x0 ct iv key1 key2) = + aes256_xts_decrypt_round + (bytes_to_int128 (SUB_LIST (n * 0x10,0x10) ct)) + (calculate_tweak n iv key2) key1`, + REPEAT STRIP_TAC THEN + REWRITE_TAC[aes256_xts_decrypt_tail] THEN + REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + REWRITE_TAC[BYTES_TO_INT128_OF_INT128_TO_BYTES] +);; + +let SUB_LIST_OF_AES256_XTS_DECRYPT_FULL_BLOCKS = prove( + `!(i:num) (ct:byte list) (iv:int128) + (key1:int128 list) (key2:int128 list) (pt_init:byte list). + (SUB_LIST (0,16 * i) + (aes256_xts_decrypt ct (16 * i + 16) iv key1 key2 pt_init)) + = (if i > 0 then (aes256_xts_decrypt ct (16 * i) iv key1 key2 pt_init) else pt_init)`, + CHEAT_TAC +);; + let AES_XTS_DECRYPT_CORRECT = prove( `!ct_ptr pt_ptr ct pt_init key1_ptr key2_ptr iv_ptr iv len k00 k01 k02 k03 k04 k05 k06 k07 k08 k09 k0a k0b k0c k0d k0e @@ -1966,7 +2236,8 @@ let AES_XTS_DECRYPT_CORRECT = prove( [WORD_RULE `word_mul (word 0x50) (word i):int64 = word(0x50 * i)`]) THEN (* Rewrite to help reasoning about nonoverlapping - so that the universally quantified assumption stays. *) + so that the universally quantified assumption stays. + See: https://hol-light.zulipchat.com/#narrow/channel/474190-s2n-bignum/topic/.E2.9C.94.20Symbolic.20simulation.20removed.20assumption/with/541554894 *) SUBGOAL_THEN `val ((word (0x50 * i)):int64) = 0x50 * i` ASSUME_TAC THENL [ IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN ASM_ARITH_TAC; ALL_TAC] THEN POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th])) THEN @@ -1989,7 +2260,7 @@ let AES_XTS_DECRYPT_CORRECT = prove( REWRITE_TAC[WORD_RULE `(i + 0x1) * 0x5 + 0x4 = i * 0x5 + 0x9`]; REWRITE_TAC[WORD_RULE `(i + 0x1) * 0x5 + 0x4 = i * 0x5 + 0x9`]; REWRITE_TAC[WORD_RULE `(i + 0x1) * 0x5 + 0x4 = i * 0x5 + 0x9`]; - (* WIP *) + (* The following is the main proof for inductive step *) REWRITE_TAC[ARITH_RULE `0x50 * (i + 0x1) = 0x50 * i + 0x50`] THEN SUBGOAL_THEN `val ((word (0x50 * i + 0x50)):int64) = 0x50 * i + 0x50` ASSUME_TAC THENL [ IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN @@ -1998,15 +2269,307 @@ let AES_XTS_DECRYPT_CORRECT = prove( ARITH_TAC; ALL_TAC] THEN ASM_REWRITE_TAC[] THEN + (* Remove quantifier *) UNDISCH_TAC `forall i'. i' < 0x50 * i ==> read (memory :> bytes8 (word_add pt_ptr (word i'))) s188 = EL i' (aes256_xts_decrypt ct (0x50 * i) iv key1 key2 pt_init)` THEN - REWRITE_TAC[BYTE_LIST_TO_NUM_THM] THEN + REWRITE_TAC[BYTE_LIST_TO_NUM_THM] THEN DISCH_TAC THEN + + (* Prove one block equivalence and reduce proving the following: + `read (memory :> bytes (pt_ptr,0x50 * i + 0x50)) s188 = + num_of_bytelist + (aes256_xts_decrypt ct (0x50 * i + 0x50) iv key1 key2 pt_init)` + to: + `read (memory :> bytes (pt_ptr,0x10 * 0x5 * i + 0x40)) s188 = + num_of_bytelist + (aes256_xts_decrypt ct (0x10 * 0x5 * i + 0x40) iv key1 key2 pt_init)` *) + IMP_REWRITE_TAC[ARITH_RULE `0x50 * i + 0x50 = (0x50 * i + 0x40) + 0x10`; READ_BYTES_AND_BYTE128_SPLIT] THEN + EXISTS_TAC `(aes256_xts_decrypt ct (0x50 * i + 0x50) iv key1 key2 pt_init)` THEN + REPEAT CONJ_TAC THENL [ + REWRITE_TAC [ARITH_RULE `(0x50 * i + 0x40) + 0x10 = 0x50 * i + 0x50`] THEN + + MP_TAC (SPECL [`0x50 * i + 0x50:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; + `key2:int128 list`; `pt_init:byte list`] LENGTH_OF_AES256_XTS_DECRYPT) THEN + ANTS_TAC THENL [UNDISCH_TAC `0 <= i` THEN ARITH_TAC; ALL_TAC] THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES]; + + MP_TAC (SPECL [`0x50 * i + 0x50:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; + `key2:int128 list`; `pt_init:byte list`] LENGTH_OF_AES256_XTS_DECRYPT) THEN + ANTS_TAC THENL [UNDISCH_TAC `0 <= i` THEN ARITH_TAC; ALL_TAC] THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN ARITH_TAC; + + (* Establish that one xts decrypt round is the same as + selecting one block of bytes from calling the top-level function. *) + REWRITE_TAC[aes256_xts_decrypt] THEN + SIMP_TAC[ARITH_RULE `~(0x50 * i + 0x50 < 0x10)`] THEN + SUBGOAL_THEN `(0x50 * i + 0x50) MOD 0x10 = 0` SUBST1_TAC THENL + [ REWRITE_TAC[ARITH_RULE `80 * i + 80 = 16 * (5 * i + 5)`] THEN + REWRITE_TAC[MOD_MULT] + ; ALL_TAC] THEN + CONV_TAC (DEPTH_CONV let_CONV) THEN + REWRITE_TAC[SUB_0; ARITH_RULE `(0x50 * i + 0x50) DIV 0x10 = 0x5 * i + 0x5`] THEN + SIMP_TAC[ARITH_RULE `~(0x5 * i + 0x5 < 0x2)`; + ARITH_RULE `(0x5 * i + 0x5) - 0x2 = 0x5 * i + 0x3`; + ARITH_RULE `(0x5 * i + 0x5) - 0x1 = 0x5 * i + 0x4`] THEN + + MP_TAC (SPECL [`0`;`5 * i + 3:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + LENGTH_OF_AES256_XTS_DECRYPT_REC) THEN + SIMP_TAC[ARITH_RULE `~(5 * i + 3 < 0)`; + ARITH_RULE `((0x5 * i + 0x3) - 0x0 + 0x1) * 0x10 = 0x50 * i + 0x40`] THEN + IMP_REWRITE_TAC[SUB_LIST_APPEND_RIGHT_LEMMA] THEN DISCH_TAC THEN + + MP_TAC (SPECL [`5 * i + 4:num`; `0x0:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + LENGTH_OF_AES256_XTS_DECRYPT_TAIL) THEN + CONV_TAC NUM_REDUCE_CONV THEN REWRITE_TAC[ADD_0] THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN + + REWRITE_TAC[AES256_XTS_DECRYPT_TAIL_WHEN_1BLOCK] THEN + SIMP_TAC[ARITH_RULE `i * 0x50 + 0x40 = (i * 0x5 + 0x4) * 0x10`; + ARITH_RULE `i * 0x5 = 0x5 * i`]; + + (* Proving that reading previous bytes is the same as the spec *) + REWRITE_TAC[ARITH_RULE `0x50 * i + 0x40 = 0x10 * (5 * i + 4)`; + ARITH_RULE `0x50 * i + 0x50 = 0x10 * (5 * i + 4) + 0x10`] THEN + REWRITE_TAC[SUB_LIST_OF_AES256_XTS_DECRYPT_FULL_BLOCKS] THEN + SUBGOAL_THEN `5 * i + 4 > 0` ASSUME_TAC THENL[ ARITH_TAC; ALL_TAC] THEN + ASM_REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC] THEN CONV_TAC NUM_REDUCE_CONV + ] THEN + + IMP_REWRITE_TAC[ARITH_RULE `0x50 * i + 0x40 = (0x50 * i + 0x30) + 0x10`; READ_BYTES_AND_BYTE128_SPLIT] THEN + EXISTS_TAC `(aes256_xts_decrypt ct (0x50 * i + 0x40) iv key1 key2 pt_init)` THEN + REPEAT CONJ_TAC THENL [ + REWRITE_TAC [ARITH_RULE `(0x50 * i + 0x30) + 0x10 = 0x50 * i + 0x40`] THEN + + MP_TAC (SPECL [`0x50 * i + 0x40:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; + `key2:int128 list`; `pt_init:byte list`] LENGTH_OF_AES256_XTS_DECRYPT) THEN + ANTS_TAC THENL [UNDISCH_TAC `0 <= i` THEN ARITH_TAC; ALL_TAC] THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES]; + + MP_TAC (SPECL [`0x50 * i + 0x40:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; + `key2:int128 list`; `pt_init:byte list`] LENGTH_OF_AES256_XTS_DECRYPT) THEN + ANTS_TAC THENL [UNDISCH_TAC `0 <= i` THEN ARITH_TAC; ALL_TAC] THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN ARITH_TAC; + + (* Establish that one xts decrypt round is the same as + selecting one block of bytes from calling the top-level function. *) + REWRITE_TAC[aes256_xts_decrypt] THEN + SIMP_TAC[ARITH_RULE `~(0x50 * i + 0x40 < 0x10)`] THEN + SUBGOAL_THEN `(0x50 * i + 0x40) MOD 0x10 = 0` SUBST1_TAC THENL + [ REWRITE_TAC[ARITH_RULE `80 * i + 64 = 16 * (5 * i + 4)`] THEN + REWRITE_TAC[MOD_MULT] + ; ALL_TAC] THEN + CONV_TAC (DEPTH_CONV let_CONV) THEN + REWRITE_TAC[SUB_0; ARITH_RULE `(0x50 * i + 0x40) DIV 0x10 = 0x5 * i + 0x4`] THEN + SIMP_TAC[ARITH_RULE `~(0x5 * i + 0x4 < 0x2)`; + ARITH_RULE `(0x5 * i + 0x4) - 0x2 = 0x5 * i + 0x2`; + ARITH_RULE `(0x5 * i + 0x4) - 0x1 = 0x5 * i + 0x3`] THEN + + MP_TAC (SPECL [`0`;`5 * i + 2:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + LENGTH_OF_AES256_XTS_DECRYPT_REC) THEN + SIMP_TAC[ARITH_RULE `~(5 * i + 2 < 0)`; + ARITH_RULE `((0x5 * i + 0x2) - 0x0 + 0x1) * 0x10 = 0x50 * i + 0x30`] THEN + IMP_REWRITE_TAC[SUB_LIST_APPEND_RIGHT_LEMMA] THEN DISCH_TAC THEN + + MP_TAC (SPECL [`5 * i + 3:num`; `0x0:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + LENGTH_OF_AES256_XTS_DECRYPT_TAIL) THEN + CONV_TAC NUM_REDUCE_CONV THEN REWRITE_TAC[ADD_0] THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN + + REWRITE_TAC[AES256_XTS_DECRYPT_TAIL_WHEN_1BLOCK] THEN + SIMP_TAC[ARITH_RULE `i * 0x50 + 0x30= (i * 0x5 + 0x3) * 0x10`; + ARITH_RULE `i * 0x5 = 0x5 * i`]; + + (* Proving that reading previous bytes is the same as the spec *) + REWRITE_TAC[ARITH_RULE `0x50 * i + 0x30 = 0x10 * (5 * i + 3)`; + ARITH_RULE `0x50 * i + 0x40 = 0x10 * (5 * i + 3) + 0x10`] THEN + REWRITE_TAC[SUB_LIST_OF_AES256_XTS_DECRYPT_FULL_BLOCKS] THEN + SUBGOAL_THEN `5 * i + 3 > 0` ASSUME_TAC THENL[ ARITH_TAC; ALL_TAC] THEN + ASM_REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC] THEN CONV_TAC NUM_REDUCE_CONV + ] THEN + + IMP_REWRITE_TAC[ARITH_RULE `0x50 * i + 0x30 = (0x50 * i + 0x20) + 0x10`; READ_BYTES_AND_BYTE128_SPLIT] THEN + EXISTS_TAC `(aes256_xts_decrypt ct (0x50 * i + 0x30) iv key1 key2 pt_init)` THEN + REPEAT CONJ_TAC THENL [ + REWRITE_TAC [ARITH_RULE `(0x50 * i + 0x20) + 0x10 = 0x50 * i + 0x30`] THEN + + MP_TAC (SPECL [`0x50 * i + 0x30:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; + `key2:int128 list`; `pt_init:byte list`] LENGTH_OF_AES256_XTS_DECRYPT) THEN + ANTS_TAC THENL [UNDISCH_TAC `0 <= i` THEN ARITH_TAC; ALL_TAC] THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES]; + + MP_TAC (SPECL [`0x50 * i + 0x30:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; + `key2:int128 list`; `pt_init:byte list`] LENGTH_OF_AES256_XTS_DECRYPT) THEN + ANTS_TAC THENL [UNDISCH_TAC `0 <= i` THEN ARITH_TAC; ALL_TAC] THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN ARITH_TAC; + + (* Establish that one xts decrypt round is the same as + selecting one block of bytes from calling the top-level function. *) + REWRITE_TAC[aes256_xts_decrypt] THEN + SIMP_TAC[ARITH_RULE `~(0x50 * i + 0x30 < 0x10)`] THEN + SUBGOAL_THEN `(0x50 * i + 0x30) MOD 0x10 = 0` SUBST1_TAC THENL + [ REWRITE_TAC[ARITH_RULE `80 * i + 48 = 16 * (5 * i + 3)`] THEN + REWRITE_TAC[MOD_MULT] + ; ALL_TAC] THEN + CONV_TAC (DEPTH_CONV let_CONV) THEN + REWRITE_TAC[SUB_0; ARITH_RULE `(0x50 * i + 0x30) DIV 0x10 = 0x5 * i + 0x3`] THEN + SIMP_TAC[ARITH_RULE `~(0x5 * i + 0x3 < 0x2)`; + ARITH_RULE `(0x5 * i + 0x3) - 0x2 = 0x5 * i + 0x1`; + ARITH_RULE `(0x5 * i + 0x3) - 0x1 = 0x5 * i + 0x2`] THEN + + MP_TAC (SPECL [`0`;`5 * i + 1:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + LENGTH_OF_AES256_XTS_DECRYPT_REC) THEN + SIMP_TAC[ARITH_RULE `~(5 * i + 1 < 0)`] THEN + REWRITE_TAC[ARITH_RULE `((0x5 * i + 0x1) - 0x0 + 0x1) * 0x10 = 0x50 * i + 0x20`] THEN + IMP_REWRITE_TAC[SUB_LIST_APPEND_RIGHT_LEMMA] THEN DISCH_TAC THEN + + MP_TAC (SPECL [`5 * i + 2:num`; `0x0:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + LENGTH_OF_AES256_XTS_DECRYPT_TAIL) THEN + CONV_TAC NUM_REDUCE_CONV THEN REWRITE_TAC[ADD_0] THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN + + REWRITE_TAC[AES256_XTS_DECRYPT_TAIL_WHEN_1BLOCK] THEN + SIMP_TAC[ARITH_RULE `i * 0x50 + 0x20 = (i * 0x5 + 0x2) * 0x10`; + ARITH_RULE `i * 0x5 = 0x5 * i`]; + + (* Proving that reading previous bytes is the same as the spec *) + REWRITE_TAC[ARITH_RULE `0x50 * i + 0x20 = 0x10 * (5 * i + 2)`; + ARITH_RULE `0x50 * i + 0x30 = 0x10 * (5 * i + 2) + 0x10`] THEN + REWRITE_TAC[SUB_LIST_OF_AES256_XTS_DECRYPT_FULL_BLOCKS] THEN + SUBGOAL_THEN `5 * i + 2 > 0` ASSUME_TAC THENL[ ARITH_TAC; ALL_TAC] THEN + ASM_REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC] THEN CONV_TAC NUM_REDUCE_CONV + ] THEN + + REWRITE_TAC[ARITH_RULE `0x50 * i + 0x20 = (0x50 * i + 0x10) + 0x10`] THEN + (* Use SPECL to force IMP_REWRITE_TAC to apply once once *) + IMP_REWRITE_TAC[(SPECL [`pt_ptr:int64`; `(0x50 * i + 0x10):num`; + `x:byte list`; `s188:armstate`] READ_BYTES_AND_BYTE128_SPLIT)] THEN + EXISTS_TAC `(aes256_xts_decrypt ct (0x50 * i + 0x20) iv key1 key2 pt_init)` THEN + REPEAT CONJ_TAC THENL [ + REWRITE_TAC [ARITH_RULE `(0x50 * i + 0x10) + 0x10 = 0x50 * i + 0x20`] THEN + + MP_TAC (SPECL [`0x50 * i + 0x20:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; + `key2:int128 list`; `pt_init:byte list`] LENGTH_OF_AES256_XTS_DECRYPT) THEN + ANTS_TAC THENL [UNDISCH_TAC `0 <= i` THEN ARITH_TAC; ALL_TAC] THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES]; + + MP_TAC (SPECL [`0x50 * i + 0x20:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; + `key2:int128 list`; `pt_init:byte list`] LENGTH_OF_AES256_XTS_DECRYPT) THEN + ANTS_TAC THENL [UNDISCH_TAC `0 <= i` THEN ARITH_TAC; ALL_TAC] THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN ARITH_TAC; + + (* Establish that one xts decrypt round is the same as + selecting one block of bytes from calling the top-level function. *) + REWRITE_TAC[aes256_xts_decrypt] THEN + SIMP_TAC[ARITH_RULE `~(0x50 * i + 0x20 < 0x10)`] THEN + SUBGOAL_THEN `(0x50 * i + 0x20) MOD 0x10 = 0` SUBST1_TAC THENL + [ REWRITE_TAC[ARITH_RULE `80 * i + 32 = 16 * (5 * i + 2)`] THEN + REWRITE_TAC[MOD_MULT] + ; ALL_TAC] THEN + CONV_TAC (DEPTH_CONV let_CONV) THEN + REWRITE_TAC[SUB_0; ARITH_RULE `(0x50 * i + 0x20) DIV 0x10 = 0x5 * i + 0x2`] THEN + SIMP_TAC[ARITH_RULE `~(0x5 * i + 0x2 < 0x2)`; + ARITH_RULE `(0x5 * i + 0x2) - 0x2 = 0x5 * i`; + ARITH_RULE `(0x5 * i + 0x2) - 0x1 = 0x5 * i + 0x1`] THEN + + MP_TAC (SPECL [`0`;`5 * i:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + LENGTH_OF_AES256_XTS_DECRYPT_REC) THEN + SIMP_TAC[ARITH_RULE `~(5 * i < 0)`; + ARITH_RULE `(0x5 * i - 0x0 + 0x1) * 0x10 = 0x50 * i + 0x10`] THEN + IMP_REWRITE_TAC[SUB_LIST_APPEND_RIGHT_LEMMA] THEN DISCH_TAC THEN + + MP_TAC (SPECL [`5 * i + 1:num`; `0x0:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + LENGTH_OF_AES256_XTS_DECRYPT_TAIL) THEN + CONV_TAC NUM_REDUCE_CONV THEN REWRITE_TAC[ADD_0] THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN + + REWRITE_TAC[AES256_XTS_DECRYPT_TAIL_WHEN_1BLOCK] THEN + SIMP_TAC[ARITH_RULE `i * 0x50 + 0x10 = (i * 0x5 + 0x1) * 0x10`; + ARITH_RULE `i * 0x5 = 0x5 * i`]; + + (* Proving that reading previous bytes is the same as the spec *) + REWRITE_TAC[ARITH_RULE `0x50 * i + 0x10 = 0x10 * (5 * i + 1)`; + ARITH_RULE `0x50 * i + 0x20 = 0x10 * (5 * i + 1) + 0x10`] THEN + REWRITE_TAC[SUB_LIST_OF_AES256_XTS_DECRYPT_FULL_BLOCKS] THEN + SUBGOAL_THEN `5 * i + 1 > 0` ASSUME_TAC THENL[ ARITH_TAC; ALL_TAC] THEN + ASM_REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC] THEN CONV_TAC NUM_REDUCE_CONV + ] THEN + + IMP_REWRITE_TAC[READ_BYTES_AND_BYTE128_SPLIT] THEN + EXISTS_TAC `(aes256_xts_decrypt ct (0x50 * i + 0x10) iv key1 key2 pt_init)` THEN + REPEAT CONJ_TAC THENL [ + MP_TAC (SPECL [`0x50 * i + 0x10:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; + `key2:int128 list`; `pt_init:byte list`] LENGTH_OF_AES256_XTS_DECRYPT) THEN + ANTS_TAC THENL [UNDISCH_TAC `0 <= i` THEN ARITH_TAC; ALL_TAC] THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES]; + + MP_TAC (SPECL [`0x50 * i + 0x10:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; + `key2:int128 list`; `pt_init:byte list`] LENGTH_OF_AES256_XTS_DECRYPT) THEN + ANTS_TAC THENL [UNDISCH_TAC `0 <= i` THEN ARITH_TAC; ALL_TAC] THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN ARITH_TAC; + + (* Establish that one xts decrypt round is the same as + selecting one block of bytes from calling the top-level function. *) + REWRITE_TAC[aes256_xts_decrypt] THEN + SIMP_TAC[ARITH_RULE `~(0x50 * i + 0x10 < 0x10)`] THEN + SUBGOAL_THEN `(0x50 * i + 0x10) MOD 0x10 = 0` SUBST1_TAC THENL + [ REWRITE_TAC[ARITH_RULE `80 * i + 16 = 16 * (5 * i + 1)`] THEN + REWRITE_TAC[MOD_MULT] + ; ALL_TAC] THEN + CONV_TAC (DEPTH_CONV let_CONV) THEN + REWRITE_TAC[SUB_0; ARITH_RULE `(0x50 * i + 0x10) DIV 0x10 = 0x5 * i + 0x1`] THEN + (* Two cases: i = 0 then execute tail branch, else execute recursion branch *) + COND_CASES_TAC THENL + [ SUBGOAL_THEN `i = 0` SUBST1_TAC THENL + [ UNDISCH_TAC `5 * i + 1 < 2` THEN + UNDISCH_TAC `0 <= i` THEN + ARITH_TAC + ; ALL_TAC] THEN CONV_TAC NUM_REDUCE_CONV THEN + + MP_TAC (SPECL [`0x0:num`; `0x0:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + LENGTH_OF_AES256_XTS_DECRYPT_TAIL) THEN + CONV_TAC NUM_REDUCE_CONV THEN REWRITE_TAC[ADD_0] THEN DISCH_TAC THEN + IMP_REWRITE_TAC[(ISPECL [`(aes256_xts_decrypt_tail 0x0 0x0 ct iv key1 key2):byte list`; + `0x10:num`] SUB_LIST_LENGTH_IMPLIES)] THEN + + REWRITE_TAC[AES256_XTS_DECRYPT_TAIL_WHEN_1BLOCK] THEN + CONV_TAC NUM_REDUCE_CONV; + + SIMP_TAC[ARITH_RULE `(0x5 * i + 0x1) - 0x2 = 0x5 * i - 0x1`; + ARITH_RULE `(0x5 * i + 0x1) - 0x1 = 0x5 * i`] THEN + + MP_TAC (SPECL [`0`;`5 * i - 1:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + LENGTH_OF_AES256_XTS_DECRYPT_REC) THEN + SUBGOAL_THEN `~(0x5 * i - 0x1 < 0x0)` ASSUME_TAC THENL + [ UNDISCH_TAC `~(0x5 * i + 0x1 < 0x2)` THEN ARITH_TAC; ALL_TAC ] THEN + ASM_SIMP_TAC[] THEN + IMP_REWRITE_TAC[ARITH_RULE `~(0x5 * i + 0x1 < 0x2) ==> (0x5 * i - 1 - 0x0 + 0x1) * 0x10 = 0x50 * i`] THEN + IMP_REWRITE_TAC[SUB_LIST_APPEND_RIGHT_LEMMA] THEN DISCH_TAC THEN + + MP_TAC (SPECL [`5 * i:num`; `0x0:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + LENGTH_OF_AES256_XTS_DECRYPT_TAIL) THEN + CONV_TAC NUM_REDUCE_CONV THEN REWRITE_TAC[ADD_0] THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN + + REWRITE_TAC[AES256_XTS_DECRYPT_TAIL_WHEN_1BLOCK] THEN + SIMP_TAC[ARITH_RULE `i * 0x50 = (i * 0x5) * 0x10`; + ARITH_RULE `i * 0x5 = 0x5 * i`]]; + + (* Proving that reading previous bytes is the same as the spec *) + REWRITE_TAC[ARITH_RULE `0x50 * i = 0x10 * 5 * i`; + ARITH_RULE `0x50 * i + 0x10 = 0x10 * 5 * i + 0x10`] THEN + REWRITE_TAC[SUB_LIST_OF_AES256_XTS_DECRYPT_FULL_BLOCKS] THEN + COND_CASES_TAC THENL [ + REFL_TAC; + AP_TERM_TAC THEN + SUBGOAL_THEN `i = 0` ASSUME_TAC THENL + [ UNDISCH_TAC `~(0x5 * i > 0x0)` THEN ARITH_TAC ; ALL_TAC] THEN + ASM_SIMP_TAC[] THEN CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[aes256_xts_decrypt] THEN + CONV_TAC NUM_REDUCE_CONV + ]]; - CHEAT_TAC - ; SUBGOAL_THEN `i + 1 < 2 EXP 64` ASSUME_TAC THENL [ UNDISCH_TAC `i < val (num_5blocks_adjusted:int64)` THEN EXPAND_TAC "num_5blocks_adjusted" THEN From 71f0f3158ff0bd489fb6dfd480b3d08182dc4c47 Mon Sep 17 00:00:00 2001 From: Yan Peng Date: Wed, 1 Oct 2025 14:19:40 -0700 Subject: [PATCH 038/132] Further simplify the spec --- arm/proofs/aes_xts_decrypt_spec.ml | 57 ++++++++++++------------------ 1 file changed, 23 insertions(+), 34 deletions(-) diff --git a/arm/proofs/aes_xts_decrypt_spec.ml b/arm/proofs/aes_xts_decrypt_spec.ml index 0b161ae91..d37d5e170 100644 --- a/arm/proofs/aes_xts_decrypt_spec.ml +++ b/arm/proofs/aes_xts_decrypt_spec.ml @@ -147,20 +147,17 @@ let aes256_xts_decrypt_tail = new_definition iv: Initialization vector (tweak) as an int128 key1: Key schedule for AES-256 decryption key2: Key schedule for AES-256 encryption for the tweak - perror: Error output plaintext in case of invalid input length return: Output plaintext as a byte list - When input len < 16, the function returns perror, - which will be the initial value stored in output address. + When input len < 16, the function returns []. *) -(* TODO: Challenge lemma: proving that the output is of same length as input *) (* TODO: Double check if IEEE and NIST spec talks about the error case len < 16 *) let aes256_xts_decrypt = new_definition `aes256_xts_decrypt - (C:byte list) (len:num) (iv:int128) (key1:int128 list) (key2:int128 list) (err:byte list) : byte list = + (C:byte list) (len:num) (iv:int128) (key1:int128 list) (key2:int128 list) : byte list = if len < 16 then - err + [] else let tail_len = len MOD 16 in let m = (len - tail_len) DIV 16 in @@ -288,12 +285,6 @@ let p2 = new_definition let iv_tweak = new_definition `iv_tweak = (word 0x0000000000000000000000123456789a) : int128`;; -let perror = new_definition - `perror = [ word 0; word 0; word 0; word 0 - ; word 0; word 0; word 0; word 0 - ; word 0; word 0; word 0; word 0 - ; word 0; word 0; word 0; word 0] : byte list`;; - let KEY1 = new_definition `KEY1:int128 list = [ word 0xc70a951e84370d1836bdd387607e94e5 ; word 0x7ead95d6f74bf6b3103340cce21b473d @@ -529,29 +520,27 @@ let AES256_XTS_DECRYPT_CONV tm = (AES256_XTS_DECRYPT_TAIL_CONV ORELSEC MORE_THAN_2_CONV) in match tm with | Comb - (Comb - (Comb - (Comb - (Comb - (Comb - (Const ("aes256_xts_decrypt", _), _), len), - _), - _), - _), - _) -> + (Comb + (Comb + (Comb + (Comb + (Const ("aes256_xts_decrypt", _), _), len), + _), + _), + _) -> if dest_numeral len failwith "AES256_XTS_DECRYPT_CONV: inapplicable";; (* -(REWRITE_CONV [perror] THENC AES256_XTS_DECRYPT_CONV) - `aes256_xts_decrypt c0 5 iv_tweak KEY1 KEY2 perror`;; +AES256_XTS_DECRYPT_CONV + `aes256_xts_decrypt c0 5 iv_tweak KEY1 KEY2`;; -(REWRITE_CONV [c0;iv_tweak;KEY1;KEY2;perror] THENC AES256_XTS_DECRYPT_CONV) - `aes256_xts_decrypt c0 16 iv_tweak KEY1 KEY2 perror`;; +(REWRITE_CONV [c0;iv_tweak;KEY1;KEY2] THENC AES256_XTS_DECRYPT_CONV) + `aes256_xts_decrypt c0 16 iv_tweak KEY1 KEY2`;; -time (REWRITE_CONV [iv_tweak;KEY1;KEY2;perror] THENC AES256_XTS_DECRYPT_CONV) +time (REWRITE_CONV [iv_tweak;KEY1;KEY2] THENC AES256_XTS_DECRYPT_CONV) `aes256_xts_decrypt [word 0xc3; word 0x0c; word 0xa8; word 0xf2 ; word 0xed; word 0x57; word 0x30; word 0x7e ; word 0xdc; word 0x87; word 0xe5; word 0x44 @@ -561,7 +550,7 @@ time (REWRITE_CONV [iv_tweak;KEY1;KEY2;perror] THENC AES256_XTS_DECRYPT_CONV) ; word 0xdc; word 0x87; word 0xe5; word 0x44 ; word 0x86; word 0x7a; word 0xc8; word 0x88 ; word 0x00] - 33 iv_tweak KEY1 KEY2 perror`;; + 33 iv_tweak KEY1 KEY2`;; *) (*******************************************) @@ -569,17 +558,17 @@ time (REWRITE_CONV [iv_tweak;KEY1;KEY2;perror] THENC AES256_XTS_DECRYPT_CONV) (* (* 1 block : 81 second *) -time prove (`aes256_xts_decrypt c0 16 iv_tweak KEY1 KEY2 perror = p0`, - CONV_TAC(LAND_CONV (REWRITE_CONV [c0;iv_tweak;KEY1;KEY2;perror] THENC AES256_XTS_DECRYPT_CONV)) THEN +time prove (`aes256_xts_decrypt c0 16 iv_tweak KEY1 KEY2 = p0`, + CONV_TAC(LAND_CONV (REWRITE_CONV [c0;iv_tweak;KEY1;KEY2] THENC AES256_XTS_DECRYPT_CONV)) THEN REWRITE_TAC [p0] THEN REFL_TAC);; (* 1 block + 6 bytes : 121 seconds *) -time prove(`aes256_xts_decrypt c1 22 iv_tweak KEY1 KEY2 perror = p1`, - CONV_TAC(LAND_CONV (REWRITE_CONV [c1;iv_tweak;KEY1;KEY2;perror;p1] THENC AES256_XTS_DECRYPT_CONV)) THEN +time prove(`aes256_xts_decrypt c1 22 iv_tweak KEY1 KEY2 = p1`, + CONV_TAC(LAND_CONV (REWRITE_CONV [c1;iv_tweak;KEY1;KEY2;p1] THENC AES256_XTS_DECRYPT_CONV)) THEN REWRITE_TAC [p1] THEN REFL_TAC);; (* 3 blocks + 3 bytes : 273 seconds *) -time prove(`aes256_xts_decrypt c2 51 iv_tweak KEY1 KEY2 perror = p2`, - CONV_TAC(LAND_CONV (REWRITE_CONV [c2;iv_tweak;KEY1;KEY2;perror;p2] THENC AES256_XTS_DECRYPT_CONV)) THEN +time prove(`aes256_xts_decrypt c2 51 iv_tweak KEY1 KEY2 = p2`, + CONV_TAC(LAND_CONV (REWRITE_CONV [c2;iv_tweak;KEY1;KEY2;p2] THENC AES256_XTS_DECRYPT_CONV)) THEN REWRITE_TAC [p2] THEN REFL_TAC);; *) \ No newline at end of file From e9e93aecf668a039408b761075dc8c810dae36b6 Mon Sep 17 00:00:00 2001 From: Yan Peng Date: Wed, 1 Oct 2025 14:20:00 -0700 Subject: [PATCH 039/132] WIP: proving main goal --- arm/proofs/aes_xts_decrypt.ml | 221 ++++++++++++++++++++++++++-------- 1 file changed, 173 insertions(+), 48 deletions(-) diff --git a/arm/proofs/aes_xts_decrypt.ml b/arm/proofs/aes_xts_decrypt.ml index e0cb11a14..360b7fef7 100644 --- a/arm/proofs/aes_xts_decrypt.ml +++ b/arm/proofs/aes_xts_decrypt.ml @@ -1460,7 +1460,7 @@ let BYTE_LIST_TO_NUM_THM = prove( ==> read (memory :> bytes8 (word_add pt_ptr (word i))) s = EL i bl) <=> (read (memory :> bytes (pt_ptr, len)) s = num_of_bytelist bl)`, - CHEAT_TAC + CHEAT_TAC );; let MEMORY_BYTES_BOUND = prove @@ -1649,8 +1649,8 @@ let LENGTH_OF_AES256_XTS_DECRYPT_TAIL = prove( (* The arithmetic reasoning in this proof is surprisingly hard *) let LENGTH_OF_AES256_XTS_DECRYPT = prove( - `! (len:num) (ct:byte list) (iv:int128) (key1:int128 list) (key2:int128 list) (pt_init:byte list). - ~(len < 16) ==> LENGTH(aes256_xts_decrypt ct len iv key1 key2 pt_init) = len`, + `! (len:num) (ct:byte list) (iv:int128) (key1:int128 list) (key2:int128 list). + ~(len < 16) ==> LENGTH(aes256_xts_decrypt ct len iv key1 key2) = len`, REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[aes256_xts_decrypt] THEN REWRITE_TAC[LET_DEF; LET_END_DEF] THEN @@ -1724,17 +1724,135 @@ let AES256_XTS_DECRYPT_TAIL_WHEN_1BLOCK = prove( REWRITE_TAC[BYTES_TO_INT128_OF_INT128_TO_BYTES] );; +let LENGTH_OF_AES256_XTS_DECRYPT_REC_TRIVIAL = prove( + `!(ct:byte list) (iv:int128) (key1:int128 list) (key2:int128 list). + LENGTH (aes256_xts_decrypt_rec 0x0 0x0 ct iv key1 key2) = 16`, + REPEAT STRIP_TAC THEN + REWRITE_TAC[LENGTH_OF_AES256_XTS_DECRYPT_REC] THEN + CONV_TAC NUM_REDUCE_CONV +);; + +let AES256_XTS_DECRYPT_REC_EQ_TAIL_TRIVIAL = prove( + `!(ct:byte list) (iv:int128) (key1:int128 list) (key2:int128 list). + aes256_xts_decrypt_rec 0x0 0x0 ct iv key1 key2 = + aes256_xts_decrypt_tail 0x0 0x0 ct iv key1 key2`, + REPEAT STRIP_TAC THEN + ONCE_REWRITE_TAC[aes256_xts_decrypt_rec] THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + ONCE_REWRITE_TAC[aes256_xts_decrypt_rec] THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[APPEND_NIL] THEN + + REWRITE_TAC[aes256_xts_decrypt_tail] THEN + REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + CONV_TAC NUM_REDUCE_CONV +);; + +let AES256_XTS_DECRYPT_REC_EQ_TAIL = prove( + `!(i:num) (k:num) (ct:byte list) (iv:int128) (key1:int128 list) (key2:int128 list). + k >= i ==> + aes256_xts_decrypt_rec i (k + 1) ct iv key1 key2 = + APPEND (aes256_xts_decrypt_rec i k ct iv key1 key2) + (aes256_xts_decrypt_tail (k + 1) 0x0 ct iv key1 key2)`, + REPEAT GEN_TAC THEN + WF_INDUCT_TAC `(k + 1) - i` THEN + STRIP_TAC THEN + GEN_REWRITE_TAC (RATOR_CONV o ONCE_DEPTH_CONV) [aes256_xts_decrypt_rec] THEN + SUBGOAL_THEN `~(k + 0x1 < i)` ASSUME_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[] THEN + REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + SUBGOAL_THEN `(k + 1) - (i + 1) < (k + 1) - i` ASSUME_TAC THENL [ ASM_ARITH_TAC; ALL_TAC] THEN + FIRST_X_ASSUM (MP_TAC o SPECL [`k:num`; `i + 1:num`]) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN + ASM_CASES_TAC `k >= i + 1` THENL + [ + ASM_SIMP_TAC[] THEN DISCH_TAC THEN + REWRITE_TAC[APPEND_ASSOC] THEN + AP_THM_TAC THEN + GEN_REWRITE_TAC (RAND_CONV o ONCE_DEPTH_CONV) [aes256_xts_decrypt_rec] THEN + SUBGOAL_THEN `~(k < i)` ASSUME_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[] THEN + REWRITE_TAC[LET_DEF; LET_END_DEF]; ALL_TAC + ] THEN + SUBGOAL_THEN `k:num = i` ASSUME_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + ONCE_REWRITE_TAC[aes256_xts_decrypt_rec] THEN + REWRITE_TAC[LT_REFL; LET_DEF; LET_END_DEF] THEN + ONCE_REWRITE_TAC[aes256_xts_decrypt_rec] THEN + REWRITE_TAC[ARITH_RULE `i < i + 1`; APPEND_NIL] THEN + AP_TERM_TAC THEN + REWRITE_TAC[aes256_xts_decrypt_tail; LET_DEF; LET_END_DEF] +);; + + let SUB_LIST_OF_AES256_XTS_DECRYPT_FULL_BLOCKS = prove( - `!(i:num) (ct:byte list) (iv:int128) - (key1:int128 list) (key2:int128 list) (pt_init:byte list). + `!(i:num) (ct:byte list) (iv:int128) (key1:int128 list) (key2:int128 list). (SUB_LIST (0,16 * i) - (aes256_xts_decrypt ct (16 * i + 16) iv key1 key2 pt_init)) - = (if i > 0 then (aes256_xts_decrypt ct (16 * i) iv key1 key2 pt_init) else pt_init)`, - CHEAT_TAC + (aes256_xts_decrypt ct (16 * i + 16) iv key1 key2)) + = aes256_xts_decrypt ct (16 * i) iv key1 key2`, + REPEAT STRIP_TAC THEN + + (* when i = 0, trivial *) + ASM_CASES_TAC `i = 0` THENL + [ + ASM_REWRITE_TAC[] THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[CONJUNCT1 SUB_LIST; aes256_xts_decrypt] THEN + CONV_TAC NUM_REDUCE_CONV; + ALL_TAC + ] THEN + + (* when i = 1, using aes256_xts_decrypt_tail *) + ASM_CASES_TAC `i = 1` THENL + [ + ASM_REWRITE_TAC[] THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[aes256_xts_decrypt] THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + CONV_TAC NUM_REDUCE_CONV THEN + MP_TAC (SPECL [`ct:byte list`; `iv:int128`; `key1: int128 list`; `key2: int128 list`] + LENGTH_OF_AES256_XTS_DECRYPT_REC_TRIVIAL) THEN + DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_APPEND_LEFT] THEN + CONV_TAC NUM_REDUCE_CONV THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN + REWRITE_TAC[AES256_XTS_DECRYPT_REC_EQ_TAIL_TRIVIAL]; + ALL_TAC + ] THEN + + (* when i >= 2, using aes256_xts_decrypt_rec *) + + REWRITE_TAC[aes256_xts_decrypt] THEN + CONV_TAC NUM_REDUCE_CONV THEN + SUBGOAL_THEN `~(0x10 * i < 0x10)` ASSUME_TAC THENL + [ ASM_ARITH_TAC ; ALL_TAC] THEN + SUBGOAL_THEN `~(0x10 * i + 0x10 < 0x10)` ASSUME_TAC THENL + [ ASM_ARITH_TAC ; ALL_TAC] THEN + ASM_SIMP_TAC[] THEN + REWRITE_TAC[ARITH_RULE `16 * i + 16 = 16 * (i + 1)`; MOD_MULT] THEN + IMP_REWRITE_TAC[LET_DEF;LET_END_DEF;SUB_0;DIV_MULT] THEN + CONV_TAC NUM_REDUCE_CONV THEN + SUBGOAL_THEN `~(i < 0x2)` ASSUME_TAC THENL + [ ASM_ARITH_TAC ; ALL_TAC] THEN + SUBGOAL_THEN `~(i + 1 < 0x2)` ASSUME_TAC THENL + [ ASM_ARITH_TAC ; ALL_TAC] THEN + ASM_SIMP_TAC[ARITH_RULE `(i + 0x1) - 0x2 = i - 1`; ADD_SUB] THEN + SUBGOAL_THEN `LENGTH (aes256_xts_decrypt_rec 0x0 (i - 0x1) ct iv key1 key2) = 16 * i` ASSUME_TAC THENL + [ REWRITE_TAC[LENGTH_OF_AES256_XTS_DECRYPT_REC] THEN + ASM_ARITH_TAC; ALL_TAC] THEN + IMP_REWRITE_TAC[SUB_LIST_APPEND_LEFT; SUB_LIST_LENGTH_IMPLIES] THEN + CONJ_TAC THENL [ALL_TAC; ARITH_TAC] THEN + SUBGOAL_THEN `i - 1 = i - 2 + 1` ASSUME_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC ] THEN + ASM_REWRITE_TAC[] THEN + IMP_REWRITE_TAC[AES256_XTS_DECRYPT_REC_EQ_TAIL] THEN + ASM_ARITH_TAC );; let AES_XTS_DECRYPT_CORRECT = prove( - `!ct_ptr pt_ptr ct pt_init key1_ptr key2_ptr iv_ptr iv len + `!ct_ptr pt_ptr ct key1_ptr key2_ptr iv_ptr iv len k00 k01 k02 k03 k04 k05 k06 k07 k08 k09 k0a k0b k0c k0d k0e k10 k11 k12 k13 k14 k15 k16 k17 k18 k19 k1a k1b k1c k1d k1e pc. @@ -1746,15 +1864,14 @@ let AES_XTS_DECRYPT_CORRECT = prove( read PC s = word (pc + 0x1c) /\ C_ARGUMENTS [ct_ptr; pt_ptr; len; key1_ptr; key2_ptr; iv_ptr] s /\ byte_list_at ct ct_ptr len s /\ - byte_list_at pt_init pt_ptr len s /\ read(memory :> bytes128 iv_ptr) s = iv /\ set_key_schedule s key1_ptr k00 k01 k02 k03 k04 k05 k06 k07 k08 k09 k0a k0b k0c k0d k0e /\ set_key_schedule s key2_ptr k10 k11 k12 k13 k14 k15 k16 k17 k18 k19 k1a k1b k1c k1d k1e) (\s. read PC s = word (pc + 0xb00) /\ byte_list_at (aes256_xts_decrypt ct (val len) iv [k00; k01; k02; k03; k04; k05; k06; k07; k08; k09; k0a; k0b; k0c; k0d; k0e] - [k10; k11; k12; k13; k14; k15; k16; k17; k18; k19; k1a; k1b; k1c; k1d; k1e] - pt_init) pt_ptr len s + [k10; k11; k12; k13; k14; k15; k16; k17; k18; k19; k1a; k1b; k1c; k1d; k1e]) + pt_ptr len s ) (MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI,, MAYCHANGE [X19; X20; X21; X22],, @@ -1895,7 +2012,7 @@ let AES_XTS_DECRYPT_CORRECT = prove( read Q18 s = k08 /\ read Q19 s = k09 /\ read Q20 s = k0a /\ read Q21 s = k0b /\ read Q22 s = k0c /\ read Q23 s = k0d /\ read Q7 s = k0e /\ byte_list_at ct ct_ptr len s /\ - byte_list_at (aes256_xts_decrypt ct 0 iv key1 key2 pt_init) pt_ptr (word 0) s /\ + byte_list_at (aes256_xts_decrypt ct 0 iv key1 key2) pt_ptr (word 0) s /\ set_key_schedule s key1_ptr k00 k01 k02 k03 k04 k05 k06 k07 k08 k09 k0a k0b k0c k0d k0e` THEN CONJ_TAC THENL [ @@ -2145,7 +2262,7 @@ let AES_XTS_DECRYPT_CORRECT = prove( read Q18 s = k08 /\ read Q19 s = k09 /\ read Q20 s = k0a /\ read Q21 s = k0b /\ read Q22 s = k0c /\ read Q23 s = k0d /\ read Q7 s = k0e /\ byte_list_at ct ct_ptr len s /\ - byte_list_at (aes256_xts_decrypt ct (80 * i) iv key1 key2 pt_init) pt_ptr (word (80 * i)) s) /\ + byte_list_at (aes256_xts_decrypt ct (80 * i) iv key1 key2) pt_ptr (word (80 * i)) s) /\ // loop backedge condition (read ZF s <=> i = val (num_5blocks_adjusted:int64))` THEN ASM_REWRITE_TAC[] THEN REPEAT CONJ_TAC THENL @@ -2274,29 +2391,29 @@ let AES_XTS_DECRYPT_CORRECT = prove( `forall i'. i' < 0x50 * i ==> read (memory :> bytes8 (word_add pt_ptr (word i'))) s188 = - EL i' (aes256_xts_decrypt ct (0x50 * i) iv key1 key2 pt_init)` THEN + EL i' (aes256_xts_decrypt ct (0x50 * i) iv key1 key2)` THEN REWRITE_TAC[BYTE_LIST_TO_NUM_THM] THEN DISCH_TAC THEN (* Prove one block equivalence and reduce proving the following: `read (memory :> bytes (pt_ptr,0x50 * i + 0x50)) s188 = num_of_bytelist - (aes256_xts_decrypt ct (0x50 * i + 0x50) iv key1 key2 pt_init)` + (aes256_xts_decrypt ct (0x50 * i + 0x50) iv key1 key2)` to: `read (memory :> bytes (pt_ptr,0x10 * 0x5 * i + 0x40)) s188 = num_of_bytelist - (aes256_xts_decrypt ct (0x10 * 0x5 * i + 0x40) iv key1 key2 pt_init)` *) + (aes256_xts_decrypt ct (0x10 * 0x5 * i + 0x40) iv key1 key2)` *) IMP_REWRITE_TAC[ARITH_RULE `0x50 * i + 0x50 = (0x50 * i + 0x40) + 0x10`; READ_BYTES_AND_BYTE128_SPLIT] THEN - EXISTS_TAC `(aes256_xts_decrypt ct (0x50 * i + 0x50) iv key1 key2 pt_init)` THEN + EXISTS_TAC `(aes256_xts_decrypt ct (0x50 * i + 0x50) iv key1 key2)` THEN REPEAT CONJ_TAC THENL [ REWRITE_TAC [ARITH_RULE `(0x50 * i + 0x40) + 0x10 = 0x50 * i + 0x50`] THEN MP_TAC (SPECL [`0x50 * i + 0x50:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; - `key2:int128 list`; `pt_init:byte list`] LENGTH_OF_AES256_XTS_DECRYPT) THEN + `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT) THEN ANTS_TAC THENL [UNDISCH_TAC `0 <= i` THEN ARITH_TAC; ALL_TAC] THEN DISCH_TAC THEN IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES]; MP_TAC (SPECL [`0x50 * i + 0x50:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; - `key2:int128 list`; `pt_init:byte list`] LENGTH_OF_AES256_XTS_DECRYPT) THEN + `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT) THEN ANTS_TAC THENL [UNDISCH_TAC `0 <= i` THEN ARITH_TAC; ALL_TAC] THEN DISCH_TAC THEN IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN ARITH_TAC; @@ -2333,22 +2450,21 @@ let AES_XTS_DECRYPT_CORRECT = prove( REWRITE_TAC[ARITH_RULE `0x50 * i + 0x40 = 0x10 * (5 * i + 4)`; ARITH_RULE `0x50 * i + 0x50 = 0x10 * (5 * i + 4) + 0x10`] THEN REWRITE_TAC[SUB_LIST_OF_AES256_XTS_DECRYPT_FULL_BLOCKS] THEN - SUBGOAL_THEN `5 * i + 4 > 0` ASSUME_TAC THENL[ ARITH_TAC; ALL_TAC] THEN ASM_REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC] THEN CONV_TAC NUM_REDUCE_CONV ] THEN IMP_REWRITE_TAC[ARITH_RULE `0x50 * i + 0x40 = (0x50 * i + 0x30) + 0x10`; READ_BYTES_AND_BYTE128_SPLIT] THEN - EXISTS_TAC `(aes256_xts_decrypt ct (0x50 * i + 0x40) iv key1 key2 pt_init)` THEN + EXISTS_TAC `(aes256_xts_decrypt ct (0x50 * i + 0x40) iv key1 key2)` THEN REPEAT CONJ_TAC THENL [ REWRITE_TAC [ARITH_RULE `(0x50 * i + 0x30) + 0x10 = 0x50 * i + 0x40`] THEN MP_TAC (SPECL [`0x50 * i + 0x40:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; - `key2:int128 list`; `pt_init:byte list`] LENGTH_OF_AES256_XTS_DECRYPT) THEN + `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT) THEN ANTS_TAC THENL [UNDISCH_TAC `0 <= i` THEN ARITH_TAC; ALL_TAC] THEN DISCH_TAC THEN IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES]; MP_TAC (SPECL [`0x50 * i + 0x40:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; - `key2:int128 list`; `pt_init:byte list`] LENGTH_OF_AES256_XTS_DECRYPT) THEN + `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT) THEN ANTS_TAC THENL [UNDISCH_TAC `0 <= i` THEN ARITH_TAC; ALL_TAC] THEN DISCH_TAC THEN IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN ARITH_TAC; @@ -2385,22 +2501,21 @@ let AES_XTS_DECRYPT_CORRECT = prove( REWRITE_TAC[ARITH_RULE `0x50 * i + 0x30 = 0x10 * (5 * i + 3)`; ARITH_RULE `0x50 * i + 0x40 = 0x10 * (5 * i + 3) + 0x10`] THEN REWRITE_TAC[SUB_LIST_OF_AES256_XTS_DECRYPT_FULL_BLOCKS] THEN - SUBGOAL_THEN `5 * i + 3 > 0` ASSUME_TAC THENL[ ARITH_TAC; ALL_TAC] THEN ASM_REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC] THEN CONV_TAC NUM_REDUCE_CONV ] THEN IMP_REWRITE_TAC[ARITH_RULE `0x50 * i + 0x30 = (0x50 * i + 0x20) + 0x10`; READ_BYTES_AND_BYTE128_SPLIT] THEN - EXISTS_TAC `(aes256_xts_decrypt ct (0x50 * i + 0x30) iv key1 key2 pt_init)` THEN + EXISTS_TAC `(aes256_xts_decrypt ct (0x50 * i + 0x30) iv key1 key2)` THEN REPEAT CONJ_TAC THENL [ REWRITE_TAC [ARITH_RULE `(0x50 * i + 0x20) + 0x10 = 0x50 * i + 0x30`] THEN MP_TAC (SPECL [`0x50 * i + 0x30:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; - `key2:int128 list`; `pt_init:byte list`] LENGTH_OF_AES256_XTS_DECRYPT) THEN + `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT) THEN ANTS_TAC THENL [UNDISCH_TAC `0 <= i` THEN ARITH_TAC; ALL_TAC] THEN DISCH_TAC THEN IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES]; MP_TAC (SPECL [`0x50 * i + 0x30:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; - `key2:int128 list`; `pt_init:byte list`] LENGTH_OF_AES256_XTS_DECRYPT) THEN + `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT) THEN ANTS_TAC THENL [UNDISCH_TAC `0 <= i` THEN ARITH_TAC; ALL_TAC] THEN DISCH_TAC THEN IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN ARITH_TAC; @@ -2437,7 +2552,6 @@ let AES_XTS_DECRYPT_CORRECT = prove( REWRITE_TAC[ARITH_RULE `0x50 * i + 0x20 = 0x10 * (5 * i + 2)`; ARITH_RULE `0x50 * i + 0x30 = 0x10 * (5 * i + 2) + 0x10`] THEN REWRITE_TAC[SUB_LIST_OF_AES256_XTS_DECRYPT_FULL_BLOCKS] THEN - SUBGOAL_THEN `5 * i + 2 > 0` ASSUME_TAC THENL[ ARITH_TAC; ALL_TAC] THEN ASM_REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC] THEN CONV_TAC NUM_REDUCE_CONV ] THEN @@ -2445,17 +2559,17 @@ let AES_XTS_DECRYPT_CORRECT = prove( (* Use SPECL to force IMP_REWRITE_TAC to apply once once *) IMP_REWRITE_TAC[(SPECL [`pt_ptr:int64`; `(0x50 * i + 0x10):num`; `x:byte list`; `s188:armstate`] READ_BYTES_AND_BYTE128_SPLIT)] THEN - EXISTS_TAC `(aes256_xts_decrypt ct (0x50 * i + 0x20) iv key1 key2 pt_init)` THEN + EXISTS_TAC `(aes256_xts_decrypt ct (0x50 * i + 0x20) iv key1 key2)` THEN REPEAT CONJ_TAC THENL [ REWRITE_TAC [ARITH_RULE `(0x50 * i + 0x10) + 0x10 = 0x50 * i + 0x20`] THEN MP_TAC (SPECL [`0x50 * i + 0x20:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; - `key2:int128 list`; `pt_init:byte list`] LENGTH_OF_AES256_XTS_DECRYPT) THEN + `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT) THEN ANTS_TAC THENL [UNDISCH_TAC `0 <= i` THEN ARITH_TAC; ALL_TAC] THEN DISCH_TAC THEN IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES]; MP_TAC (SPECL [`0x50 * i + 0x20:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; - `key2:int128 list`; `pt_init:byte list`] LENGTH_OF_AES256_XTS_DECRYPT) THEN + `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT) THEN ANTS_TAC THENL [UNDISCH_TAC `0 <= i` THEN ARITH_TAC; ALL_TAC] THEN DISCH_TAC THEN IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN ARITH_TAC; @@ -2492,20 +2606,19 @@ let AES_XTS_DECRYPT_CORRECT = prove( REWRITE_TAC[ARITH_RULE `0x50 * i + 0x10 = 0x10 * (5 * i + 1)`; ARITH_RULE `0x50 * i + 0x20 = 0x10 * (5 * i + 1) + 0x10`] THEN REWRITE_TAC[SUB_LIST_OF_AES256_XTS_DECRYPT_FULL_BLOCKS] THEN - SUBGOAL_THEN `5 * i + 1 > 0` ASSUME_TAC THENL[ ARITH_TAC; ALL_TAC] THEN ASM_REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC] THEN CONV_TAC NUM_REDUCE_CONV ] THEN IMP_REWRITE_TAC[READ_BYTES_AND_BYTE128_SPLIT] THEN - EXISTS_TAC `(aes256_xts_decrypt ct (0x50 * i + 0x10) iv key1 key2 pt_init)` THEN + EXISTS_TAC `(aes256_xts_decrypt ct (0x50 * i + 0x10) iv key1 key2)` THEN REPEAT CONJ_TAC THENL [ MP_TAC (SPECL [`0x50 * i + 0x10:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; - `key2:int128 list`; `pt_init:byte list`] LENGTH_OF_AES256_XTS_DECRYPT) THEN + `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT) THEN ANTS_TAC THENL [UNDISCH_TAC `0 <= i` THEN ARITH_TAC; ALL_TAC] THEN DISCH_TAC THEN IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES]; MP_TAC (SPECL [`0x50 * i + 0x10:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; - `key2:int128 list`; `pt_init:byte list`] LENGTH_OF_AES256_XTS_DECRYPT) THEN + `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT) THEN ANTS_TAC THENL [UNDISCH_TAC `0 <= i` THEN ARITH_TAC; ALL_TAC] THEN DISCH_TAC THEN IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN ARITH_TAC; @@ -2559,16 +2672,7 @@ let AES_XTS_DECRYPT_CORRECT = prove( (* Proving that reading previous bytes is the same as the spec *) REWRITE_TAC[ARITH_RULE `0x50 * i = 0x10 * 5 * i`; ARITH_RULE `0x50 * i + 0x10 = 0x10 * 5 * i + 0x10`] THEN - REWRITE_TAC[SUB_LIST_OF_AES256_XTS_DECRYPT_FULL_BLOCKS] THEN - COND_CASES_TAC THENL [ - REFL_TAC; - AP_TERM_TAC THEN - SUBGOAL_THEN `i = 0` ASSUME_TAC THENL - [ UNDISCH_TAC `~(0x5 * i > 0x0)` THEN ARITH_TAC ; ALL_TAC] THEN - ASM_SIMP_TAC[] THEN CONV_TAC NUM_REDUCE_CONV THEN - REWRITE_TAC[aes256_xts_decrypt] THEN - CONV_TAC NUM_REDUCE_CONV - ]]; + REWRITE_TAC[SUB_LIST_OF_AES256_XTS_DECRYPT_FULL_BLOCKS]]; SUBGOAL_THEN `i + 1 < 2 EXP 64` ASSUME_TAC THENL [ UNDISCH_TAC `i < val (num_5blocks_adjusted:int64)` THEN @@ -2644,8 +2748,20 @@ let AES_XTS_DECRYPT_CORRECT = prove( CONJ_TAC THENL [ REPEAT (GEN_REWRITE_TAC ONCE_DEPTH_CONV [GSYM SEQ_ASSOC] THEN MATCH_MP_TAC SUBSUMED_SEQ THEN REWRITE_TAC[SUBSUMED_REFL]) THEN - (* SUBSUMED_MAYCHANGE_TAC *) - CHEAT_TAC + REPEAT COND_CASES_TAC THENL + [ ABBREV_TAC `tmp = val (num_5blocks_adjusted:int64)` THEN + ABBREV_TAC `vallen = val (len:int64)` THEN + SUBSUMED_MAYCHANGE_TAC; + ABBREV_TAC `tmp = val (num_5blocks_adjusted:int64)` THEN + ABBREV_TAC `vallen = val (len:int64)` THEN + SUBSUMED_MAYCHANGE_TAC; + ABBREV_TAC `tmp = val (num_5blocks_adjusted:int64)` THEN + ABBREV_TAC `vallen = val (len:int64)` THEN + SUBSUMED_MAYCHANGE_TAC; + ABBREV_TAC `tmp = val (num_5blocks_adjusted:int64)` THEN + ABBREV_TAC `vallen = val (len:int64)` THEN + SUBSUMED_MAYCHANGE_TAC; + SUBSUMED_MAYCHANGE_TAC] ; ALL_TAC] THEN ENSURES_INIT_TAC "s0" THEN @@ -2679,6 +2795,15 @@ let AES_XTS_DECRYPT_CORRECT = prove( MP_TAC (SPECL [`ct_ptr:int64`; `num_5blocks_adjusted:int64`; `len:int64`; `ct:byte list`; `s3:armstate`] READ_CT_TAIL4_LEMMA) THEN ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN + (* Rewrite to help reasoning about nonoverlapping + so that the universally quantified assumption stays. + See: https://hol-light.zulipchat.com/#narrow/channel/474190-s2n-bignum/topic/.E2.9C.94.20Symbolic.20simulation.20removed.20assumption/with/541554894 *) + SUBGOAL_THEN `0x50 * (val (num_5blocks_adjusted:int64)) < 0x2 EXP 0x40` ASSUME_TAC THENL [CHEAT_TAC; ALL_TAC] THEN + SUBGOAL_THEN `val ((word (0x50 * val (num_5blocks_adjusted:int64))):int64) = 0x50 * val num_5blocks_adjusted` ASSUME_TAC THENL [ + IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN ASM_ARITH_TAC; ALL_TAC] THEN + POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th])) THEN + + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (4--125) THEN XTSDEC_TAC `Q0:(armstate,int128)component` `val (num_5blocks_adjusted:int64) * 0x50` `val (num_5blocks_adjusted:int64) * 0x5` THEN From 37f7de3910348d519493431639cab82d55db6ccd Mon Sep 17 00:00:00 2001 From: Yan Peng Date: Thu, 2 Oct 2025 16:44:18 -0700 Subject: [PATCH 040/132] Update the spec --- arm/proofs/aes_xts_decrypt_spec.ml | 37 ++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 7 deletions(-) diff --git a/arm/proofs/aes_xts_decrypt_spec.ml b/arm/proofs/aes_xts_decrypt_spec.ml index d37d5e170..2156c10f4 100644 --- a/arm/proofs/aes_xts_decrypt_spec.ml +++ b/arm/proofs/aes_xts_decrypt_spec.ml @@ -49,13 +49,36 @@ let aes256_xts_decrypt_1block = new_definition *) let bytes_to_int128 = define `bytes_to_int128 (bs : byte list) : int128 = - word_join - (word_join - (word_join (word_join (EL 15 bs) (EL 14 bs) : int16) (word_join (EL 13 bs) (EL 12 bs) : int16) : int32) - (word_join (word_join (EL 11 bs) (EL 10 bs) : int16) (word_join (EL 9 bs) (EL 8 bs) : int16) : int32) : int64) - (word_join - (word_join (word_join (EL 7 bs) (EL 6 bs) : int16) (word_join (EL 5 bs) (EL 4 bs) : int16) : int32) - (word_join (word_join (EL 3 bs) (EL 2 bs) : int16) (word_join (EL 1 bs) (EL 0 bs) : int16) : int32) : int64)`;; + (word_join:120 word->8 word->int128) + ((word_join:112 word->8 word->120 word) + ((word_join:104 word->8 word->112 word) + ((word_join:96 word->8 word->104 word) + ((word_join:88 word->8 word->96 word) + ((word_join:80 word->8 word->88 word) + ((word_join:72 word->8 word->80 word) + ((word_join:64 word->8 word->72 word) + ((word_join:56 word->8 word->64 word) + ((word_join:48 word->8 word->56 word) + ((word_join:40 word->8 word->48 word) + ((word_join:32 word->8 word->40 word) + ((word_join:24 word->8 word->32 word) + ((word_join:16 word->8 word->24 word) + ((word_join:8 word->8 word->16 word) + (EL 15 bs) (EL 14 bs)) + (EL 13 bs)) + (EL 12 bs)) + (EL 11 bs)) + (EL 10 bs)) + (EL 9 bs)) + (EL 8 bs)) + (EL 7 bs)) + (EL 6 bs)) + (EL 5 bs)) + (EL 4 bs)) + (EL 3 bs)) + (EL 2 bs)) + (EL 1 bs)) + (EL 0 bs)`;; let int128_to_bytes = define `int128_to_bytes (w : int128) : byte list = From 16f0fe2c2cbe26953eb5bfc64810565535a6fd24 Mon Sep 17 00:00:00 2001 From: Yan Peng Date: Thu, 2 Oct 2025 17:53:39 -0700 Subject: [PATCH 041/132] WIP: prove main goal --- arm/proofs/aes_xts_decrypt.ml | 123 +++++++++++++++++++++------------- 1 file changed, 78 insertions(+), 45 deletions(-) diff --git a/arm/proofs/aes_xts_decrypt.ml b/arm/proofs/aes_xts_decrypt.ml index 360b7fef7..0330f8ac8 100644 --- a/arm/proofs/aes_xts_decrypt.ml +++ b/arm/proofs/aes_xts_decrypt.ml @@ -1514,10 +1514,68 @@ let NUM_OF_BYTELIST_OF_SUB_LIST = prove( ASM_SIMP_TAC[LENGTH_SUB_LIST; SUB_0; MIN; ARITH_RULE `0 + sz = sz`] );; +let WORD_JOIN_BOUND_TAC x y = + REWRITE_TAC[VAL_WORD_JOIN; DIMINDEX_CLAUSES] THEN + CONV_TAC NUM_REDUCE_CONV THEN + IMP_REWRITE_TAC[MOD_LT] THEN + CONJ_TAC THENL[ REWRITE_TAC[ADD_SYM]; ALL_TAC ] THEN + MP_TAC (ISPECL [x] VAL_BOUND) THEN + MP_TAC (ISPECL [y] VAL_BOUND) THEN + REWRITE_TAC[DIMINDEX_CLAUSES] THEN + CONV_TAC NUM_REDUCE_CONV THEN + ARITH_TAC;; + let VAL_OF_BYTES_TO_INT128_EQ_NUM_OF_BYTELIST = prove( `!x:byte list. LENGTH x = 16 ==> val (bytes_to_int128 x) = num_of_bytelist x`, REPEAT STRIP_TAC THEN - CHEAT_TAC + (* conversion for breaking down a list *) + MP_TAC ((GEN_REWRITE_CONV I [LENGTH_EQ_LIST_OF_SEQ] THENC + RAND_CONV LIST_OF_SEQ_CONV) `LENGTH (x:byte list) = 16`) THEN + ASM_SIMP_TAC[] THEN + DISCH_THEN (fun th -> ONCE_REWRITE_TAC[th]) THEN + REWRITE_TAC[bytes_to_int128] THEN + REWRITE_TAC EL_16_8_CLAUSES THEN + REPEAT_N 16 (ONCE_REWRITE_TAC[num_of_bytelist]) THEN + REWRITE_TAC[CONJUNCT1 num_of_bytelist] THEN + MAP_EVERY ABBREV_TAC + [`x0 = EL 0 x:byte`; `x1 = EL 1 x:byte`; `x2 = EL 2 x:byte`; `x3 = EL 3 x:byte`; + `x4 = EL 4 x:byte`; `x5 = EL 5 x:byte`; `x6 = EL 6 x:byte`; `x7 = EL 7 x:byte`; + `x8 = EL 8 x:byte`; `x9 = EL 9 x:byte`; `x10 = EL 10 x:byte`; `x11 = EL 11 x:byte`; + `x12 = EL 12 x:byte`; `x13 = EL 13 x:byte`; `x14 = EL 14 x:byte`; `x15 = EL 15 x:byte`] THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[ADD_0] THEN + (* reduce RHS to LHS *) + SUBGOAL_THEN `val (x14:byte) + 0x100 * val (x15:byte) = val ((word_join x15 x14):int16)` SUBST1_TAC THENL + [ WORD_JOIN_BOUND_TAC `x15:byte` `x14:byte`; ALL_TAC] THEN ABBREV_TAC `y14:int16 = word_join (x15:byte) (x14:byte)` THEN + SUBGOAL_THEN `val (x13:byte) + 0x100 * val (y14:16 word) = val ((word_join y14 x13):24 word)` SUBST1_TAC THENL + [ WORD_JOIN_BOUND_TAC `y14:16 word` `x13:byte`; ALL_TAC] THEN ABBREV_TAC `y13:24 word = word_join (y14:16 word) (x13:byte)` THEN + SUBGOAL_THEN `val (x12:byte) + 0x100 * val (y13:24 word) = val ((word_join y13 x12):32 word)` SUBST1_TAC THENL + [ WORD_JOIN_BOUND_TAC `y13:24 word` `x12:byte`; ALL_TAC] THEN ABBREV_TAC `y12:32 word = word_join (y13:24 word) (x12:byte)` THEN + SUBGOAL_THEN `val (x11:byte) + 0x100 * val (y12:32 word) = val ((word_join y12 x11):40 word)` SUBST1_TAC THENL + [ WORD_JOIN_BOUND_TAC `y12:32 word` `x11:byte`; ALL_TAC] THEN ABBREV_TAC `y11:40 word = word_join (y12:32 word) (x11:byte)` THEN + SUBGOAL_THEN `val (x10:byte) + 0x100 * val (y11:40 word) = val ((word_join y11 x10):48 word)` SUBST1_TAC THENL + [ WORD_JOIN_BOUND_TAC `y11:40 word` `x10:byte`; ALL_TAC] THEN ABBREV_TAC `y10:48 word = word_join (y11:40 word) (x10:byte)` THEN + SUBGOAL_THEN `val (x9:byte) + 0x100 * val (y10:48 word) = val ((word_join y10 x9):56 word)` SUBST1_TAC THENL + [ WORD_JOIN_BOUND_TAC `y10:48 word` `x9:byte`; ALL_TAC] THEN ABBREV_TAC `y9:56 word = word_join (y10:48 word) (x9:byte)` THEN + SUBGOAL_THEN `val (x8:byte) + 0x100 * val (y9:56 word) = val ((word_join y9 x8):64 word)` SUBST1_TAC THENL + [ WORD_JOIN_BOUND_TAC `y9:56 word` `x8:byte`; ALL_TAC] THEN ABBREV_TAC `y8:64 word = word_join (y9:56 word) (x8:byte)` THEN + SUBGOAL_THEN `val (x7:byte) + 0x100 * val (y8:64 word) = val ((word_join y8 x7):72 word)` SUBST1_TAC THENL + [ WORD_JOIN_BOUND_TAC `y8:64 word` `x7:byte`; ALL_TAC] THEN ABBREV_TAC `y7:72 word = word_join (y8:64 word) (x7:byte)` THEN + SUBGOAL_THEN `val (x6:byte) + 0x100 * val (y7:72 word) = val ((word_join y7 x6):80 word)` SUBST1_TAC THENL + [ WORD_JOIN_BOUND_TAC `y7:72 word` `x6:byte`; ALL_TAC] THEN ABBREV_TAC `y6:80 word = word_join (y7:72 word) (x6:byte)` THEN + SUBGOAL_THEN `val (x5:byte) + 0x100 * val (y6:80 word) = val ((word_join y6 x5):88 word)` SUBST1_TAC THENL + [ WORD_JOIN_BOUND_TAC `y6:80 word` `x5:byte`; ALL_TAC] THEN ABBREV_TAC `y5:88 word = word_join (y6:80 word) (x5:byte)` THEN + SUBGOAL_THEN `val (x4:byte) + 0x100 * val (y5:88 word) = val ((word_join y5 x4):96 word)` SUBST1_TAC THENL + [ WORD_JOIN_BOUND_TAC `y5:88 word` `x4:byte`; ALL_TAC] THEN ABBREV_TAC `y4:96 word = word_join (y5:88 word) (x4:byte)` THEN + SUBGOAL_THEN `val (x3:byte) + 0x100 * val (y4:96 word) = val ((word_join y4 x3):104 word)` SUBST1_TAC THENL + [ WORD_JOIN_BOUND_TAC `y4:96 word` `x3:byte`; ALL_TAC] THEN ABBREV_TAC `y3:104 word = word_join (y4:96 word) (x3:byte)` THEN + SUBGOAL_THEN `val (x2:byte) + 0x100 * val (y3:104 word) = val ((word_join y3 x2):112 word)` SUBST1_TAC THENL + [ WORD_JOIN_BOUND_TAC `y3:104 word` `x2:byte`; ALL_TAC] THEN ABBREV_TAC `y2:112 word = word_join (y3:104 word) (x2:byte)` THEN + SUBGOAL_THEN `val (x1:byte) + 0x100 * val (y2:112 word) = val ((word_join y2 x1):120 word)` SUBST1_TAC THENL + [ WORD_JOIN_BOUND_TAC `y2:112 word` `x1:byte`; ALL_TAC] THEN ABBREV_TAC `y1:120 word = word_join (y2:112 word) (x1:byte)` THEN + SUBGOAL_THEN `val (x0:byte) + 0x100 * val (y1:120 word) = val ((word_join y1 x0):128 word)` SUBST1_TAC THENL + [ WORD_JOIN_BOUND_TAC `y1:120 word` `x0:byte`; ALL_TAC] THEN ABBREV_TAC `y0:128 word = word_join (y1:120 word) (x0:byte)` THEN + REFL_TAC );; let READ_BYTES_AND_BYTE128_SPLIT = prove( @@ -1647,59 +1705,34 @@ let LENGTH_OF_AES256_XTS_DECRYPT_TAIL = prove( REWRITE_TAC[LENGTH_OF_SND_OF_CIPHER_STEALING]] );; -(* The arithmetic reasoning in this proof is surprisingly hard *) + let LENGTH_OF_AES256_XTS_DECRYPT = prove( `! (len:num) (ct:byte list) (iv:int128) (key1:int128 list) (key2:int128 list). ~(len < 16) ==> LENGTH(aes256_xts_decrypt ct len iv key1 key2) = len`, REPEAT STRIP_TAC THEN - ASM_REWRITE_TAC[aes256_xts_decrypt] THEN - REWRITE_TAC[LET_DEF; LET_END_DEF] THEN - SUBGOAL_THEN `len MOD 0x10 < 16` ASSUME_TAC THENL - [ MP_TAC (SPEC `16` (SPEC `len:num` MOD_LT_EQ)) THEN - CONV_TAC NUM_REDUCE_CONV THEN ARITH_TAC - ; ALL_TAC ] THEN - COND_CASES_TAC THENL + + ASM_CASES_TAC `len < 32` THENL [ - REWRITE_TAC[LENGTH_OF_AES256_XTS_DECRYPT_TAIL] THEN - REWRITE_TAC[MIN] THEN - SUBGOAL_THEN `len MOD 16 <= 16` ASSUME_TAC THENL - [ ASM_ARITH_TAC; ALL_TAC] THEN + REWRITE_TAC[aes256_xts_decrypt] THEN ASM_SIMP_TAC[] THEN - SUBGOAL_THEN `len - len MOD 16 <= 32` ASSUME_TAC THENL - [ ASM_ARITH_TAC; ALL_TAC] THEN - SUBGOAL_THEN `len <= 48` ASSUME_TAC THENL - [ ASM_ARITH_TAC; ALL_TAC] THEN - SUBGOAL_THEN `(len - len MOD 16) DIV 16 = 0 \/ (len - len MOD 16) DIV 16 = 1` STRIP_ASSUME_TAC THENL - [ ASM_ARITH_TAC; - - (* case: (len - len MOD 0x10) DIV 0x10 = 0x0 *) - MP_TAC (SPECL [`len - len MOD 0x10`; `0x10`] DIV_EQ_0) THEN - CONV_TAC NUM_REDUCE_CONV THEN ASM_SIMP_TAC[] THEN DISCH_TAC THEN - SUBGOAL_THEN `len - len MOD 0x10 = 0` ASSUME_TAC THENL - [ MP_TAC (SPECL [`len - len MOD 0x10`; `0x10`] DIVISION) THEN - CONV_TAC NUM_REDUCE_CONV THEN - DISCH_THEN (fun th -> SUBST1_TAC (CONJUNCT1 th)) THEN - ASM_REWRITE_TAC[MULT_CLAUSES; ADD_CLAUSES] THEN - CHEAT_TAC - ; ALL_TAC] THEN - SUBGOAL_THEN `len MOD 0x10 <= len` ASSUME_TAC THENL - [CHEAT_TAC; ALL_TAC] THEN - ASM_SIMP_TAC[] THEN ASM_ARITH_TAC; - - (* case: (len - len MOD 0x10) DIV 0x10 = 0x1 *) - SUBGOAL_THEN `len - len MOD 16 = 16` ASSUME_TAC THENL [ - CHEAT_TAC; ALL_TAC] THEN - ASM_ARITH_TAC - ]; - - REWRITE_TAC[LENGTH_APPEND] THEN - REWRITE_TAC[LENGTH_OF_AES256_XTS_DECRYPT_REC] THEN - SUBGOAL_THEN `~((len - len MOD 0x10) DIV 0x10 - 0x2 < 0x0)` ASSUME_TAC THENL + REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + SUBGOAL_THEN `(len - len MOD 0x10) DIV 0x10 < 0x2` ASSUME_TAC THENL [CHEAT_TAC; ALL_TAC] THEN ASM_SIMP_TAC[] THEN - ASM_REWRITE_TAC[LENGTH_OF_AES256_XTS_DECRYPT_TAIL; MIN; SUB_0] THEN + REWRITE_TAC[LENGTH_OF_AES256_XTS_DECRYPT_TAIL] THEN CHEAT_TAC - ] + ; ALL_TAC + ] THEN + + REWRITE_TAC[aes256_xts_decrypt] THEN + ASM_SIMP_TAC[] THEN + REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + SUBGOAL_THEN `~((len - len MOD 0x10) DIV 0x10 < 0x2)` ASSUME_TAC THENL + [CHEAT_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[LENGTH_APPEND] THEN + REWRITE_TAC[LENGTH_OF_AES256_XTS_DECRYPT_TAIL] THEN + REWRITE_TAC[LENGTH_OF_AES256_XTS_DECRYPT_REC] THEN + CHEAT_TAC );; let BYTES_TO_INT128_OF_INT128_TO_BYTES = prove( From 4fe026f74af4e375bbffb1af0ae0653245bfeea1 Mon Sep 17 00:00:00 2001 From: Yan Peng Date: Thu, 2 Oct 2025 18:25:30 -0700 Subject: [PATCH 042/132] Revert "Update the spec" This reverts commit 51f0d081d32f75b2927674d4d20f549fc7443027. --- arm/proofs/aes_xts_decrypt_spec.ml | 37 ++++++------------------------ 1 file changed, 7 insertions(+), 30 deletions(-) diff --git a/arm/proofs/aes_xts_decrypt_spec.ml b/arm/proofs/aes_xts_decrypt_spec.ml index 2156c10f4..d37d5e170 100644 --- a/arm/proofs/aes_xts_decrypt_spec.ml +++ b/arm/proofs/aes_xts_decrypt_spec.ml @@ -49,36 +49,13 @@ let aes256_xts_decrypt_1block = new_definition *) let bytes_to_int128 = define `bytes_to_int128 (bs : byte list) : int128 = - (word_join:120 word->8 word->int128) - ((word_join:112 word->8 word->120 word) - ((word_join:104 word->8 word->112 word) - ((word_join:96 word->8 word->104 word) - ((word_join:88 word->8 word->96 word) - ((word_join:80 word->8 word->88 word) - ((word_join:72 word->8 word->80 word) - ((word_join:64 word->8 word->72 word) - ((word_join:56 word->8 word->64 word) - ((word_join:48 word->8 word->56 word) - ((word_join:40 word->8 word->48 word) - ((word_join:32 word->8 word->40 word) - ((word_join:24 word->8 word->32 word) - ((word_join:16 word->8 word->24 word) - ((word_join:8 word->8 word->16 word) - (EL 15 bs) (EL 14 bs)) - (EL 13 bs)) - (EL 12 bs)) - (EL 11 bs)) - (EL 10 bs)) - (EL 9 bs)) - (EL 8 bs)) - (EL 7 bs)) - (EL 6 bs)) - (EL 5 bs)) - (EL 4 bs)) - (EL 3 bs)) - (EL 2 bs)) - (EL 1 bs)) - (EL 0 bs)`;; + word_join + (word_join + (word_join (word_join (EL 15 bs) (EL 14 bs) : int16) (word_join (EL 13 bs) (EL 12 bs) : int16) : int32) + (word_join (word_join (EL 11 bs) (EL 10 bs) : int16) (word_join (EL 9 bs) (EL 8 bs) : int16) : int32) : int64) + (word_join + (word_join (word_join (EL 7 bs) (EL 6 bs) : int16) (word_join (EL 5 bs) (EL 4 bs) : int16) : int32) + (word_join (word_join (EL 3 bs) (EL 2 bs) : int16) (word_join (EL 1 bs) (EL 0 bs) : int16) : int32) : int64)`;; let int128_to_bytes = define `int128_to_bytes (w : int128) : byte list = From 84b25ef4141ae93b682f45a57b6508fd014eede4 Mon Sep 17 00:00:00 2001 From: Yan Peng Date: Fri, 3 Oct 2025 10:24:06 -0700 Subject: [PATCH 043/132] Finished: prove main goal --- arm/proofs/aes_xts_decrypt.ml | 507 +++++++++++++++++++++++++--------- 1 file changed, 374 insertions(+), 133 deletions(-) diff --git a/arm/proofs/aes_xts_decrypt.ml b/arm/proofs/aes_xts_decrypt.ml index 0330f8ac8..c3c8de7b5 100644 --- a/arm/proofs/aes_xts_decrypt.ml +++ b/arm/proofs/aes_xts_decrypt.ml @@ -928,6 +928,12 @@ let BYTE_LIST_AT_ADD_ASSUM_TAC new_pos bound = USE_THEN "tmp" (fun th -> REWRITE_TAC[th]) THEN POP_ASSUM (K ALL_TAC);; +let WORD_JOIN_ASSOC_16_8 = WORD_BLAST + `!(x0:byte) (x1:byte) (x2:byte) (x3:byte). + word_join (word_join x3 x2:int16) + (word_join x1 x0:int16):int32 = + word_join (word_join (word_join x3 x2:int32) x1:int32) x0`;; + let BYTES128_TO_BYTES8_THM = prove( `!pos bl_ptr s. read (memory :> bytes128 (word_add bl_ptr (word pos))) s = @@ -1005,7 +1011,6 @@ let BYTE_LIST_AT_5BLOCKS = prove( bytes_to_int128 (SUB_LIST (pos + 0x40, 0x10) bl))`, REWRITE_TAC[byte_list_at] THEN REPEAT STRIP_TAC THENL - (* TODO: simplify *) [ (* Subgoal1 *) MAP_EVERY (fun i -> BYTE_LIST_AT_ADD_ASSUM_TAC (mk_binop (mk_const("+", [`:num`, `:A`])) (mk_var("pos", `:num`)) @@ -1079,7 +1084,6 @@ let BYTE_LIST_AT_4BLOCKS = prove( bytes_to_int128 (SUB_LIST (pos + 0x30, 0x10) bl))`, REWRITE_TAC[byte_list_at] THEN REPEAT STRIP_TAC THENL - (* TODO: simplify *) [ (* Subgoal1 *) MAP_EVERY (fun i -> BYTE_LIST_AT_ADD_ASSUM_TAC (mk_binop (mk_const("+", [`:num`, `:A`])) (mk_var("pos", `:num`)) @@ -1140,7 +1144,6 @@ let BYTE_LIST_AT_3BLOCKS = prove( bytes_to_int128 (SUB_LIST (pos + 0x20, 0x10) bl))`, REWRITE_TAC[byte_list_at] THEN REPEAT STRIP_TAC THENL - (* TODO: simplify *) [ (* Subgoal1 *) MAP_EVERY (fun i -> BYTE_LIST_AT_ADD_ASSUM_TAC (mk_binop (mk_const("+", [`:num`, `:A`])) (mk_var("pos", `:num`)) @@ -1188,7 +1191,6 @@ let BYTE_LIST_AT_2BLOCKS = prove( bytes_to_int128 (SUB_LIST (pos + 0x10, 0x10) bl))`, REWRITE_TAC[byte_list_at] THEN REPEAT STRIP_TAC THENL - (* TODO: simplify *) [ (* Subgoal1 *) MAP_EVERY (fun i -> BYTE_LIST_AT_ADD_ASSUM_TAC (mk_binop (mk_const("+", [`:num`, `:A`])) (mk_var("pos", `:num`)) @@ -1223,7 +1225,6 @@ let BYTE_LIST_AT_1BLOCKS = prove( bytes_to_int128 (SUB_LIST (pos, 0x10) bl)`, REWRITE_TAC[byte_list_at] THEN REPEAT STRIP_TAC THENL - (* TODO: simplify *) [ (* Subgoal1 *) MAP_EVERY (fun i -> BYTE_LIST_AT_ADD_ASSUM_TAC (mk_binop (mk_const("+", [`:num`, `:A`])) (mk_var("pos", `:num`)) @@ -1374,22 +1375,6 @@ let UDIV_OPT_THM = prove(`!n:num. n < 0x2 EXP 0x40 DISCH_TAC THEN ASM_REWRITE_TAC[] THEN AP_TERM_TAC THEN ASM_ARITH_TAC);; -(* -let NUM_BLOCKS_THM = prove(`!(len:int64) num_blocks tail_len. - word_add tail_len num_blocks = len ==> - word_and len (word 0xfffffffffffffff0) = num_blocks ==> - (word_and (word_add tail_len num_blocks) (word 0xfffffffffffffff0)) = num_blocks`, - BITBLAST_TAC);; -*) - -(* -let TAIL_LEN_THM = prove(`!(len:int64) num_blocks tail_len. - word_add tail_len num_blocks = len ==> - word_and len (word 0xf) = tail_len ==> - (word_and (word_add tail_len num_blocks) (word 0xf)) = tail_len`, - BITBLAST_TAC);; -*) - let NUM_BLOCKS_LO_BOUND_THM = prove( `!(len:int64) num_blocks. word_and len (word 0xfffffffffffffff0) = num_blocks ==> ~(val len < 0x60) @@ -1454,13 +1439,208 @@ let NUM_BLOCKS_ADJUSTED_LT_LEN_THM = prove( BITBLAST_TAC );; +let NUM_OF_BYTELIST_APPEND = prove + (`!l1 l2. num_of_bytelist (APPEND l1 l2) = + num_of_bytelist l1 + 2 EXP (8 * LENGTH l1) * num_of_bytelist l2`, + LIST_INDUCT_TAC THENL + [ REWRITE_TAC[APPEND; LENGTH; num_of_bytelist; MULT_CLAUSES; EXP; ADD_CLAUSES]; + REWRITE_TAC[APPEND; LENGTH; num_of_bytelist] THEN + ASM_REWRITE_TAC[] THEN + REWRITE_TAC[MULT_SUC; EXP_ADD] THEN + REWRITE_TAC[MULT_ASSOC; LEFT_ADD_DISTRIB] THEN + ARITH_TAC]);; + +let NUM_OF_BYTELIST_OF_SUB_LIST = prove( + `!sz len (x:byte list). + sz <= LENGTH x ==> + num_of_bytelist (SUB_LIST (0, sz + len) x) = + num_of_bytelist (SUB_LIST (0, sz) x) + + 2 EXP (8 * sz) * num_of_bytelist (SUB_LIST (sz, len) x)`, + REPEAT STRIP_TAC THEN + SUBST1_TAC(ISPECL [`x:byte list`; `sz:num`; `len:num`; `0:num`] SUB_LIST_SPLIT) THEN + REWRITE_TAC[NUM_OF_BYTELIST_APPEND] THEN + ASM_SIMP_TAC[LENGTH_SUB_LIST; SUB_0; MIN; ARITH_RULE `0 + sz = sz`] +);; + +let MEMORY_READ_SUBSET_LEMMA = prove + (`!len (bl:byte list) s. + (forall i. + i < SUC len + ==> read (memory :> bytes8 (word_add pt_ptr (word i))) s = EL i bl) ==> + (forall i. + i < len + ==> read (memory :> bytes8 (word_add pt_ptr (word i))) s = EL i bl) /\ + read (memory :> bytes (word_add pt_ptr (word len),1)) s = + val(read (memory :> bytes8 (word_add pt_ptr (word len))) s) + `, + REPEAT GEN_TAC THEN + DISCH_TAC THEN + CONJ_TAC THENL + [ GEN_TAC THEN DISCH_TAC THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_REWRITE_TAC[LT_SUC_LE] THEN + ASM_ARITH_TAC; + ALL_TAC] THEN + REWRITE_TAC[bytes8; READ_COMPONENT_COMPOSE; asword; through; read] THEN + REWRITE_TAC[VAL_WORD; DIMINDEX_8] THEN + CONV_TAC NUM_REDUCE_CONV THEN + IMP_REWRITE_TAC[MOD_LT] THEN + MP_TAC (ISPECL [`(word_add (pt_ptr:int64) (word len)):int64`; `1:num`; `(read memory s):int64->byte`] READ_BYTES_BOUND) THEN + CONV_TAC NUM_REDUCE_CONV +);; + +let BYTE_LIST_AT_SPLIT = prove( + `!len (bl:byte list) s. + SUC len <= LENGTH bl ==> + ((forall i. + i < SUC len + ==> read (memory :> bytes8 (word_add pt_ptr (word i))) s = EL i bl) <=> + ((forall i. + i < len + ==> read (memory :> bytes8 (word_add pt_ptr (word i))) s = EL i bl) /\ + read (memory :> bytes8 (word_add pt_ptr (word len))) s = EL len bl))`, + REPEAT STRIP_TAC THEN + EQ_TAC THENL + [ STRIP_TAC THEN + CONJ_TAC THENL + [ ASM_SIMP_TAC[ARITH_RULE `i < len ==> i < SUC len`]; + ASM_SIMP_TAC[ARITH_RULE `len < SUC len`]]; + ALL_TAC ] THEN + REPEAT STRIP_TAC THEN + ASM_CASES_TAC `i < len` THENL + [ FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_SIMP_TAC[]; + SUBGOAL_THEN `i = len:num` SUBST1_TAC THENL + [ASM_ARITH_TAC; ASM_REWRITE_TAC[]] + ] +);; + + +let MEMORY_READ_BYTES_SUBSET_LEMMA = prove( + `!len (bl:byte list) s. + SUC len <= LENGTH bl ==> + read (memory :> bytes (pt_ptr,SUC len)) s = + num_of_bytelist (SUB_LIST (0x0,SUC len) bl) ==> + read (memory :> bytes (pt_ptr,len)) s = + num_of_bytelist (SUB_LIST (0x0,len) bl) /\ + read (memory :> bytes8 (word_add pt_ptr (word len))) s = EL len bl`, + REPEAT GEN_TAC THEN STRIP_TAC THEN + SUBGOAL_THEN `SUC len = len + 1` SUBST_ALL_TAC THENL [ARITH_TAC; ALL_TAC] THEN + REWRITE_TAC[READ_COMPONENT_COMPOSE] THEN + SUBGOAL_THEN `len <= LENGTH (bl:byte list)` ASSUME_TAC THENL [ ASM_ARITH_TAC; ALL_TAC] THEN + (* Use READ_BYTES_COMBINE to decompose the memory read *) + MP_TAC(ISPECL [`pt_ptr:int64`; `len:num`; `1:num`; `(read memory s):int64->byte`] READ_BYTES_COMBINE) THEN + DISCH_TAC THEN + (* Use SUB_LIST_SPLIT to decompose the byte list *) + MP_TAC(ISPECL [`bl:byte list`; `len:num`; `1:num`; `0:num`] SUB_LIST_SPLIT) THEN + REWRITE_TAC[ADD_CLAUSES] THEN DISCH_TAC THEN + (* Decompose num_of_bytelist *) + SUBGOAL_THEN + `num_of_bytelist (SUB_LIST (0,len + 1) (bl:byte list)) = + num_of_bytelist (SUB_LIST (0,len) bl) + + 2 EXP (8 * len) * num_of_bytelist (SUB_LIST (len,1) bl)` + ASSUME_TAC THENL + [ ASM_REWRITE_TAC[] THEN + REWRITE_TAC[NUM_OF_BYTELIST_APPEND] THEN + AP_TERM_TAC THEN AP_THM_TAC THEN REPEAT_N 3 AP_TERM_TAC THEN + IMP_REWRITE_TAC[LENGTH_SUB_LIST; MIN; SUB_0] THEN + ASM_SIMP_TAC[] + ; ALL_TAC] THEN + (* Rewrite in goal *) + ASM_REWRITE_TAC[] THEN + DISCH_TAC THEN + CONJ_TAC THENL + [ (* First part: read (memory :> bytes (pt_ptr,len)) s = num_of_bytelist (SUB_LIST (0,len) bl) *) + FIRST_X_ASSUM(MP_TAC o AP_TERM `\x. x MOD 2 EXP (8 * len)`) THEN + ASM_REWRITE_TAC[] THEN + REWRITE_TAC[MOD_MULT_ADD; MOD_LT] THEN + REWRITE_TAC[READ_BYTES_MOD; MIN] THEN + SIMP_TAC[ARITH_RULE `len <= len`] THEN + DISCH_TAC THEN + IMP_REWRITE_TAC[MOD_LT] THEN + MP_TAC (SPEC `(SUB_LIST (0,len) bl:byte list)` NUM_OF_BYTELIST_BOUND) THEN + IMP_REWRITE_TAC[LENGTH_SUB_LIST; SUB_0; MIN] THEN + SUBGOAL_THEN `256 EXP len = 2 EXP (8 * len)` SUBST1_TAC THENL + [ REWRITE_TAC[ARITH_RULE `256 = 2 EXP 8`; EXP_EXP]; ALL_TAC] THEN + SIMP_TAC[]; + ALL_TAC + ] THEN + (* Second part: read (memory :> bytes8 (word_add pt_ptr (word len))) s = EL len bl *) + FIRST_X_ASSUM(MP_TAC o AP_TERM `\x. x DIV 2 EXP (8 * len)`) THEN + ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN `~(0x2 EXP (0x8 * len) = 0x0)` ASSUME_TAC THENL + [ REWRITE_TAC[EXP_EQ_0; ARITH_EQ]; ALL_TAC] THEN + IMP_REWRITE_TAC[DIV_MULT_ADD] THEN + SUBGOAL_THEN `read (bytes (pt_ptr,len)) (read memory s) < 0x2 EXP (0x8 * len)` ASSUME_TAC THENL + [ REWRITE_TAC[READ_BYTES_BOUND]; ALL_TAC] THEN + SUBGOAL_THEN `num_of_bytelist (SUB_LIST (0x0,len) bl) < 0x2 EXP (0x8 * len)` ASSUME_TAC THENL + [ MP_TAC (SPEC `(SUB_LIST (0,len) bl:byte list)` NUM_OF_BYTELIST_BOUND) THEN + IMP_REWRITE_TAC[LENGTH_SUB_LIST; SUB_0; MIN] THEN + SUBGOAL_THEN `256 EXP len = 2 EXP (8 * len)` SUBST1_TAC THENL + [ REWRITE_TAC[ARITH_RULE `256 = 2 EXP 8`; EXP_EXP]; ALL_TAC] THEN SIMP_TAC[]; ALL_TAC] THEN + IMP_REWRITE_TAC[DIV_LT; ADD] THEN + (* Some rewrites to close the goal *) + REWRITE_TAC[bytes8; READ_COMPONENT_COMPOSE; asword; through; read] THEN + SUBGOAL_THEN `len < LENGTH (bl:byte list)` ASSUME_TAC THENL [ ASM_ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[SUB_LIST_1] THEN + REWRITE_TAC[num_of_bytelist; MULT_CLAUSES; ADD_CLAUSES; WORD_VAL] +);; + let BYTE_LIST_TO_NUM_THM = prove( `!len (bl:byte list) s. - (forall i. i < len - ==> read (memory :> bytes8 (word_add pt_ptr (word i))) s = EL i bl) - <=> - (read (memory :> bytes (pt_ptr, len)) s = num_of_bytelist bl)`, - CHEAT_TAC + len <= LENGTH bl ==> + ((forall i. i < len + ==> read (memory :> bytes8 (word_add pt_ptr (word i))) s = EL i bl) <=> + (read (memory :> bytes (pt_ptr, len)) s = num_of_bytelist (SUB_LIST (0, len) bl)))`, + REPEAT GEN_TAC THEN + SPEC_TAC (`len:num`, `len:num`) THEN + (* Base case: len = 0 *) + INDUCT_TAC THENL + [ STRIP_TAC THEN + REWRITE_TAC[READ_COMPONENT_COMPOSE; READ_BYTES_TRIVIAL; + CONJUNCT1 SUB_LIST; CONJUNCT1 num_of_bytelist] THEN + GEN_TAC THEN MESON_TAC[ARITH_RULE `~(i < 0)`]; + ALL_TAC] THEN + + (* Inductive step: left to right *) + STRIP_TAC THEN + EQ_TAC THENL + [ MP_TAC (ARITH_RULE `SUC len <= LENGTH (bl:byte list) ==> len <= LENGTH bl`) THEN + ASM_SIMP_TAC[] THEN REPEAT DISCH_TAC THEN + MP_TAC (SPECL [`len:num`; `bl:byte list`; `s:armstate`] MEMORY_READ_SUBSET_LEMMA) THEN + ASM_SIMP_TAC[] THEN + DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN + REWRITE_TAC[READ_COMPONENT_COMPOSE; ADD1] THEN + ONCE_REWRITE_TAC[READ_BYTES_COMBINE] THEN + REWRITE_TAC[SUB_LIST_SPLIT; NUM_OF_BYTELIST_APPEND; CONJUNCT1 ADD] THEN + IMP_REWRITE_TAC[ARITH_RULE `a = c ==> (a + b = c + d) = (b = d)`] THEN + CONJ_TAC THENL [ + REWRITE_TAC[LENGTH_SUB_LIST; MIN; SUB_0] THEN + ASM_SIMP_TAC[] THEN + AP_TERM_TAC THEN + REWRITE_TAC[GSYM READ_COMPONENT_COMPOSE] THEN + FIRST_X_ASSUM (fun th -> MP_TAC (SPEC `len:num` th)) THEN + REWRITE_TAC[ARITH_RULE `len < SUC len`] THEN + SUBGOAL_THEN `len < LENGTH (bl:byte list)` ASSUME_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC] THEN + ASM_REWRITE_TAC[SUB_LIST_1; num_of_bytelist] THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[ADD_0] THEN + STRIP_TAC THEN AP_TERM_TAC THEN ASM_SIMP_TAC[] + ; ALL_TAC] THEN + REWRITE_TAC[GSYM READ_COMPONENT_COMPOSE] THEN + ASM_SIMP_TAC[] + ; ALL_TAC] THEN + + (* Inductive step: right to left *) + MP_TAC (ARITH_RULE `SUC len <= LENGTH (bl:byte list) ==> len <= LENGTH bl`) THEN + ASM_SIMP_TAC[] THEN REPEAT DISCH_TAC THEN + MP_TAC (SPECL [`len:num`; `bl:byte list`; `s:armstate`] MEMORY_READ_BYTES_SUBSET_LEMMA) THEN + ASM_SIMP_TAC[] THEN + DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN + IMP_REWRITE_TAC[BYTE_LIST_AT_SPLIT] THEN + CONJ_TAC THENL [ASM_SIMP_TAC[]; ALL_TAC] THEN + ASM_SIMP_TAC[] );; let MEMORY_BYTES_BOUND = prove @@ -1491,29 +1671,6 @@ let READ_MEMORY_BYTES128_BYTES = prove(`!z s. REWRITE_TAC [MEMORY_BYTES_BOUND] );; -let NUM_OF_BYTELIST_APPEND = prove - (`!l1 l2. num_of_bytelist (APPEND l1 l2) = - num_of_bytelist l1 + 2 EXP (8 * LENGTH l1) * num_of_bytelist l2`, - LIST_INDUCT_TAC THENL - [ REWRITE_TAC[APPEND; LENGTH; num_of_bytelist; MULT_CLAUSES; EXP; ADD_CLAUSES]; - REWRITE_TAC[APPEND; LENGTH; num_of_bytelist] THEN - ASM_REWRITE_TAC[] THEN - REWRITE_TAC[MULT_SUC; EXP_ADD] THEN - REWRITE_TAC[MULT_ASSOC; LEFT_ADD_DISTRIB] THEN - ARITH_TAC]);; - -let NUM_OF_BYTELIST_OF_SUB_LIST = prove( - `!sz len (x:byte list). - sz <= LENGTH x ==> - num_of_bytelist (SUB_LIST (0, sz + len) x) = - num_of_bytelist (SUB_LIST (0, sz) x) + - 2 EXP (8 * sz) * num_of_bytelist (SUB_LIST (sz, len) x)`, - REPEAT STRIP_TAC THEN - SUBST1_TAC(ISPECL [`x:byte list`; `sz:num`; `len:num`; `0:num`] SUB_LIST_SPLIT) THEN - REWRITE_TAC[NUM_OF_BYTELIST_APPEND] THEN - ASM_SIMP_TAC[LENGTH_SUB_LIST; SUB_0; MIN; ARITH_RULE `0 + sz = sz`] -);; - let WORD_JOIN_BOUND_TAC x y = REWRITE_TAC[VAL_WORD_JOIN; DIMINDEX_CLAUSES] THEN CONV_TAC NUM_REDUCE_CONV THEN @@ -1525,6 +1682,48 @@ let WORD_JOIN_BOUND_TAC x y = CONV_TAC NUM_REDUCE_CONV THEN ARITH_TAC;; +let WORD_JOIN_16_8_ASSOC = WORD_BLAST + `!(x0:byte) (x1:byte) (x2:byte) (x3:byte) + (x4:byte) (x5:byte) (x6:byte) (x7:byte) + (x8:byte) (x9:byte) (x10:byte) (x11:byte) + (x12:byte) (x13:byte) (x14:byte) (x15:byte). + (word_join + (word_join + (word_join (word_join x15 x14 : int16) (word_join x13 x12 : int16) : int32) + (word_join (word_join x11 x10 : int16) (word_join x9 x8 : int16) : int32) : int64) + (word_join + (word_join (word_join x7 x6 : int16) (word_join x5 x4 : int16) : int32) + (word_join (word_join x3 x2 : int16) (word_join x1 x0 : int16) : int32) : int64)) = + (word_join + (word_join + (word_join + (word_join + (word_join + (word_join + (word_join + (word_join + (word_join + (word_join + (word_join + (word_join + (word_join + (word_join + (word_join x15 x14:16 word) + x13:24 word) + x12:32 word) + x11:40 word) + x10:48 word) + x9:56 word) + x8:64 word) + x7:72 word) + x6:80 word) + x5:88 word) + x4:96 word) + x3:104 word) + x2:112 word) + x1:120 word) + x0:128 word)`;; + let VAL_OF_BYTES_TO_INT128_EQ_NUM_OF_BYTELIST = prove( `!x:byte list. LENGTH x = 16 ==> val (bytes_to_int128 x) = num_of_bytelist x`, REPEAT STRIP_TAC THEN @@ -1543,7 +1742,7 @@ let VAL_OF_BYTES_TO_INT128_EQ_NUM_OF_BYTELIST = prove( `x8 = EL 8 x:byte`; `x9 = EL 9 x:byte`; `x10 = EL 10 x:byte`; `x11 = EL 11 x:byte`; `x12 = EL 12 x:byte`; `x13 = EL 13 x:byte`; `x14 = EL 14 x:byte`; `x15 = EL 15 x:byte`] THEN CONV_TAC NUM_REDUCE_CONV THEN - REWRITE_TAC[ADD_0] THEN + REWRITE_TAC[ADD_0; WORD_JOIN_16_8_ASSOC] THEN (* reduce RHS to LHS *) SUBGOAL_THEN `val (x14:byte) + 0x100 * val (x15:byte) = val ((word_join x15 x14):int16)` SUBST1_TAC THENL [ WORD_JOIN_BOUND_TAC `x15:byte` `x14:byte`; ALL_TAC] THEN ABBREV_TAC `y14:int16 = word_join (x15:byte) (x14:byte)` THEN @@ -1644,7 +1843,9 @@ let LENGTH_OF_INT128_TO_BYTES = prove( CONV_TAC NUM_REDUCE_CONV );; +(* ********************************************************** *) (* Properties that we prove about the specification functions *) + let LENGTH_OF_AES256_XTS_DECRYPT_REC = prove( `!(i:num) (m:num) (C:byte list) (iv:int128) (key1:int128 list) (key2:int128 list). LENGTH(aes256_xts_decrypt_rec i m C iv key1 key2) = (if m < i then 0 else (m - i + 1) * 0x10)`, @@ -1705,34 +1906,77 @@ let LENGTH_OF_AES256_XTS_DECRYPT_TAIL = prove( REWRITE_TAC[LENGTH_OF_SND_OF_CIPHER_STEALING]] );; +let LENGTH_OF_AES256_XTS_DECRYPT_REC_TRIVIAL = prove( + `!(ct:byte list) (iv:int128) (key1:int128 list) (key2:int128 list). + LENGTH (aes256_xts_decrypt_rec 0x0 0x0 ct iv key1 key2) = 16`, + REPEAT STRIP_TAC THEN + REWRITE_TAC[LENGTH_OF_AES256_XTS_DECRYPT_REC] THEN + CONV_TAC NUM_REDUCE_CONV +);; + +let LENGTH_OF_AES256_XTS_DECRYPT_TAIL_TRIVIAL = prove( + `!(ct:byte list) (iv:int128) (key1:int128 list) (key2:int128 list). + LENGTH(aes256_xts_decrypt_tail 0 0 ct iv key1 key2) = 16`, + REPEAT STRIP_TAC THEN + REWRITE_TAC[LENGTH_OF_AES256_XTS_DECRYPT_TAIL] THEN + CONV_TAC NUM_REDUCE_CONV +);; -let LENGTH_OF_AES256_XTS_DECRYPT = prove( - `! (len:num) (ct:byte list) (iv:int128) (key1:int128 list) (key2:int128 list). - ~(len < 16) ==> LENGTH(aes256_xts_decrypt ct len iv key1 key2) = len`, +let AES256_XTS_DECRYPT_REC_EQ_TAIL_TRIVIAL = prove( + `!(ct:byte list) (iv:int128) (key1:int128 list) (key2:int128 list). + aes256_xts_decrypt_rec 0x0 0x0 ct iv key1 key2 = + aes256_xts_decrypt_tail 0x0 0x0 ct iv key1 key2`, REPEAT STRIP_TAC THEN + ONCE_REWRITE_TAC[aes256_xts_decrypt_rec] THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + ONCE_REWRITE_TAC[aes256_xts_decrypt_rec] THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[APPEND_NIL] THEN + + REWRITE_TAC[aes256_xts_decrypt_tail] THEN + REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + CONV_TAC NUM_REDUCE_CONV +);; - ASM_CASES_TAC `len < 32` THENL +let LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS = prove( + `! (i:num) (ct:byte list) (iv:int128) (key1:int128 list) (key2:int128 list). + LENGTH(aes256_xts_decrypt ct (0x10 * i) iv key1 key2) = 0x10 * i`, + REPEAT STRIP_TAC THEN + SPEC_TAC (`i:num`, `i:num`) THEN + INDUCT_TAC THENL [ + CONV_TAC NUM_REDUCE_CONV THEN REWRITE_TAC[aes256_xts_decrypt] THEN - ASM_SIMP_TAC[] THEN - REWRITE_TAC[LET_DEF; LET_END_DEF] THEN - SUBGOAL_THEN `(len - len MOD 0x10) DIV 0x10 < 0x2` ASSUME_TAC THENL - [CHEAT_TAC; ALL_TAC] THEN - ASM_SIMP_TAC[] THEN - REWRITE_TAC[LENGTH_OF_AES256_XTS_DECRYPT_TAIL] THEN - CHEAT_TAC + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[LENGTH_EQ_NIL]; + ALL_TAC] THEN + + REWRITE_TAC[ADD1; LEFT_ADD_DISTRIB] THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[aes256_xts_decrypt] THEN + + ASM_CASES_TAC `i = 0` THENL + [ ASM_SIMP_TAC[] THEN + CONV_TAC NUM_REDUCE_CONV THEN + IMP_REWRITE_TAC[LET_DEF;LET_END_DEF;SUB_0] THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[LENGTH_OF_AES256_XTS_DECRYPT_TAIL_TRIVIAL] ; ALL_TAC ] THEN - REWRITE_TAC[aes256_xts_decrypt] THEN - ASM_SIMP_TAC[] THEN - REWRITE_TAC[LET_DEF; LET_END_DEF] THEN - SUBGOAL_THEN `~((len - len MOD 0x10) DIV 0x10 < 0x2)` ASSUME_TAC THENL - [CHEAT_TAC; ALL_TAC] THEN - ASM_SIMP_TAC[LENGTH_APPEND] THEN - REWRITE_TAC[LENGTH_OF_AES256_XTS_DECRYPT_TAIL] THEN + SUBGOAL_THEN `~(0x10 * i + 0x10 < 0x10)` ASSUME_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC ] THEN ASM_SIMP_TAC[] THEN + REWRITE_TAC[ARITH_RULE `0x10 * i + 0x10 = 0x10 * (i + 1)`; MOD_MULT] THEN + IMP_REWRITE_TAC[LET_DEF; LET_END_DEF;SUB_0;DIV_MULT] THEN + CONJ_TAC THENL [ALL_TAC; ARITH_TAC] THEN + SUBGOAL_THEN `~(i + 0x1 < 0x2)` ASSUME_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC] THEN ASM_SIMP_TAC[] THEN + REWRITE_TAC[LENGTH_APPEND] THEN REWRITE_TAC[LENGTH_OF_AES256_XTS_DECRYPT_REC] THEN - CHEAT_TAC + REWRITE_TAC[LENGTH_OF_AES256_XTS_DECRYPT_TAIL] THEN + CONV_TAC NUM_REDUCE_CONV THEN + ASM_ARITH_TAC );; let BYTES_TO_INT128_OF_INT128_TO_BYTES = prove( @@ -1757,31 +2001,6 @@ let AES256_XTS_DECRYPT_TAIL_WHEN_1BLOCK = prove( REWRITE_TAC[BYTES_TO_INT128_OF_INT128_TO_BYTES] );; -let LENGTH_OF_AES256_XTS_DECRYPT_REC_TRIVIAL = prove( - `!(ct:byte list) (iv:int128) (key1:int128 list) (key2:int128 list). - LENGTH (aes256_xts_decrypt_rec 0x0 0x0 ct iv key1 key2) = 16`, - REPEAT STRIP_TAC THEN - REWRITE_TAC[LENGTH_OF_AES256_XTS_DECRYPT_REC] THEN - CONV_TAC NUM_REDUCE_CONV -);; - -let AES256_XTS_DECRYPT_REC_EQ_TAIL_TRIVIAL = prove( - `!(ct:byte list) (iv:int128) (key1:int128 list) (key2:int128 list). - aes256_xts_decrypt_rec 0x0 0x0 ct iv key1 key2 = - aes256_xts_decrypt_tail 0x0 0x0 ct iv key1 key2`, - REPEAT STRIP_TAC THEN - ONCE_REWRITE_TAC[aes256_xts_decrypt_rec] THEN - CONV_TAC NUM_REDUCE_CONV THEN - REWRITE_TAC[LET_DEF; LET_END_DEF] THEN - ONCE_REWRITE_TAC[aes256_xts_decrypt_rec] THEN - CONV_TAC NUM_REDUCE_CONV THEN - REWRITE_TAC[APPEND_NIL] THEN - - REWRITE_TAC[aes256_xts_decrypt_tail] THEN - REWRITE_TAC[LET_DEF; LET_END_DEF] THEN - CONV_TAC NUM_REDUCE_CONV -);; - let AES256_XTS_DECRYPT_REC_EQ_TAIL = prove( `!(i:num) (k:num) (ct:byte list) (iv:int128) (key1:int128 list) (key2:int128 list). k >= i ==> @@ -2425,7 +2644,19 @@ let AES_XTS_DECRYPT_CORRECT = prove( i' < 0x50 * i ==> read (memory :> bytes8 (word_add pt_ptr (word i'))) s188 = EL i' (aes256_xts_decrypt ct (0x50 * i) iv key1 key2)` THEN - REWRITE_TAC[BYTE_LIST_TO_NUM_THM] THEN DISCH_TAC THEN + MP_TAC (SPECL [`0x50 * i + 0x50:num`; `(aes256_xts_decrypt ct (0x50 * i + 0x50) iv key1 key2):byte list`; `s188:armstate`] BYTE_LIST_TO_NUM_THM) THEN + ANTS_TAC THENL[ + REWRITE_TAC[ARITH_RULE `0x50 * i + 0x50 = 0x10 * (5 * i + 5)`; + LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS] THEN ARITH_TAC + ; ALL_TAC] THEN + DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN + MP_TAC (SPECL [`0x50 * i:num`; `(aes256_xts_decrypt ct (0x50 * i) iv key1 key2):byte list`; `s188:armstate`] BYTE_LIST_TO_NUM_THM) THEN + ANTS_TAC THENL[ + REWRITE_TAC[ARITH_RULE `0x50 * i = 0x10 * 5 * i`; + LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS] THEN ARITH_TAC + ; ALL_TAC] THEN + DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN + DISCH_TAC THEN (* Prove one block equivalence and reduce proving the following: `read (memory :> bytes (pt_ptr,0x50 * i + 0x50)) s188 = @@ -2438,16 +2669,12 @@ let AES_XTS_DECRYPT_CORRECT = prove( IMP_REWRITE_TAC[ARITH_RULE `0x50 * i + 0x50 = (0x50 * i + 0x40) + 0x10`; READ_BYTES_AND_BYTE128_SPLIT] THEN EXISTS_TAC `(aes256_xts_decrypt ct (0x50 * i + 0x50) iv key1 key2)` THEN REPEAT CONJ_TAC THENL [ - REWRITE_TAC [ARITH_RULE `(0x50 * i + 0x40) + 0x10 = 0x50 * i + 0x50`] THEN + REWRITE_TAC [ARITH_RULE `(0x50 * i + 0x40) + 0x10 = 0x50 * i + 0x50`]; - MP_TAC (SPECL [`0x50 * i + 0x50:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; - `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT) THEN - ANTS_TAC THENL [UNDISCH_TAC `0 <= i` THEN ARITH_TAC; ALL_TAC] THEN DISCH_TAC THEN - IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES]; - - MP_TAC (SPECL [`0x50 * i + 0x50:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; - `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT) THEN - ANTS_TAC THENL [UNDISCH_TAC `0 <= i` THEN ARITH_TAC; ALL_TAC] THEN DISCH_TAC THEN + MP_TAC (SPECL [`0x5 * i + 0x5:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; + `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN + REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC; GSYM ADD_ASSOC] THEN + CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC THEN IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN ARITH_TAC; (* Establish that one xts decrypt round is the same as @@ -2491,14 +2718,16 @@ let AES_XTS_DECRYPT_CORRECT = prove( REPEAT CONJ_TAC THENL [ REWRITE_TAC [ARITH_RULE `(0x50 * i + 0x30) + 0x10 = 0x50 * i + 0x40`] THEN - MP_TAC (SPECL [`0x50 * i + 0x40:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; - `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT) THEN - ANTS_TAC THENL [UNDISCH_TAC `0 <= i` THEN ARITH_TAC; ALL_TAC] THEN DISCH_TAC THEN + MP_TAC (SPECL [`0x5 * i + 0x4:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; + `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN + REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC; GSYM ADD_ASSOC] THEN + CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC THEN IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES]; - MP_TAC (SPECL [`0x50 * i + 0x40:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; - `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT) THEN - ANTS_TAC THENL [UNDISCH_TAC `0 <= i` THEN ARITH_TAC; ALL_TAC] THEN DISCH_TAC THEN + MP_TAC (SPECL [`0x5 * i + 0x4:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; + `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN + REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC; GSYM ADD_ASSOC] THEN + CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC THEN IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN ARITH_TAC; (* Establish that one xts decrypt round is the same as @@ -2542,14 +2771,16 @@ let AES_XTS_DECRYPT_CORRECT = prove( REPEAT CONJ_TAC THENL [ REWRITE_TAC [ARITH_RULE `(0x50 * i + 0x20) + 0x10 = 0x50 * i + 0x30`] THEN - MP_TAC (SPECL [`0x50 * i + 0x30:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; - `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT) THEN - ANTS_TAC THENL [UNDISCH_TAC `0 <= i` THEN ARITH_TAC; ALL_TAC] THEN DISCH_TAC THEN + MP_TAC (SPECL [`0x5 * i + 0x3:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; + `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN + REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC; GSYM ADD_ASSOC] THEN + CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC THEN IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES]; - MP_TAC (SPECL [`0x50 * i + 0x30:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; - `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT) THEN - ANTS_TAC THENL [UNDISCH_TAC `0 <= i` THEN ARITH_TAC; ALL_TAC] THEN DISCH_TAC THEN + MP_TAC (SPECL [`0x5 * i + 0x3:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; + `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN + REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC; GSYM ADD_ASSOC] THEN + CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC THEN IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN ARITH_TAC; (* Establish that one xts decrypt round is the same as @@ -2596,14 +2827,16 @@ let AES_XTS_DECRYPT_CORRECT = prove( REPEAT CONJ_TAC THENL [ REWRITE_TAC [ARITH_RULE `(0x50 * i + 0x10) + 0x10 = 0x50 * i + 0x20`] THEN - MP_TAC (SPECL [`0x50 * i + 0x20:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; - `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT) THEN - ANTS_TAC THENL [UNDISCH_TAC `0 <= i` THEN ARITH_TAC; ALL_TAC] THEN DISCH_TAC THEN - IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES]; + MP_TAC (SPECL [`0x5 * i + 0x2:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; + `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN + REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC; GSYM ADD_ASSOC] THEN + CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN ARITH_TAC; - MP_TAC (SPECL [`0x50 * i + 0x20:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; - `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT) THEN - ANTS_TAC THENL [UNDISCH_TAC `0 <= i` THEN ARITH_TAC; ALL_TAC] THEN DISCH_TAC THEN + MP_TAC (SPECL [`0x5 * i + 0x2:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; + `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN + REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC; GSYM ADD_ASSOC] THEN + CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC THEN IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN ARITH_TAC; (* Establish that one xts decrypt round is the same as @@ -2642,17 +2875,22 @@ let AES_XTS_DECRYPT_CORRECT = prove( ASM_REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC] THEN CONV_TAC NUM_REDUCE_CONV ] THEN - IMP_REWRITE_TAC[READ_BYTES_AND_BYTE128_SPLIT] THEN - EXISTS_TAC `(aes256_xts_decrypt ct (0x50 * i + 0x10) iv key1 key2)` THEN + IMP_REWRITE_TAC[(SPECL [`pt_ptr:int64`; `(0x50 * i):num`; + `(aes256_xts_decrypt ct (0x50 * i + 0x10) iv key1 key2):byte list`; `s188:armstate`] + READ_BYTES_AND_BYTE128_SPLIT)] THEN + EXISTS_TAC `ct:byte list` THEN EXISTS_TAC `iv:int128` THEN + EXISTS_TAC `key1:int128 list` THEN EXISTS_TAC `key2:int128 list` THEN REPEAT CONJ_TAC THENL [ - MP_TAC (SPECL [`0x50 * i + 0x10:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; - `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT) THEN - ANTS_TAC THENL [UNDISCH_TAC `0 <= i` THEN ARITH_TAC; ALL_TAC] THEN DISCH_TAC THEN - IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES]; + MP_TAC (SPECL [`0x5 * i + 0x1:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; + `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN + REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC; GSYM ADD_ASSOC] THEN + CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN ARITH_TAC; - MP_TAC (SPECL [`0x50 * i + 0x10:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; - `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT) THEN - ANTS_TAC THENL [UNDISCH_TAC `0 <= i` THEN ARITH_TAC; ALL_TAC] THEN DISCH_TAC THEN + MP_TAC (SPECL [`0x5 * i + 0x1:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; + `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN + REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC; GSYM ADD_ASSOC] THEN + CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC THEN IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN ARITH_TAC; (* Establish that one xts decrypt round is the same as @@ -2705,7 +2943,10 @@ let AES_XTS_DECRYPT_CORRECT = prove( (* Proving that reading previous bytes is the same as the spec *) REWRITE_TAC[ARITH_RULE `0x50 * i = 0x10 * 5 * i`; ARITH_RULE `0x50 * i + 0x10 = 0x10 * 5 * i + 0x10`] THEN - REWRITE_TAC[SUB_LIST_OF_AES256_XTS_DECRYPT_FULL_BLOCKS]]; + REWRITE_TAC[SUB_LIST_OF_AES256_XTS_DECRYPT_FULL_BLOCKS] THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN + REWRITE_TAC[LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS] + ]; SUBGOAL_THEN `i + 1 < 2 EXP 64` ASSUME_TAC THENL [ UNDISCH_TAC `i < val (num_5blocks_adjusted:int64)` THEN From e7eff1841e89929e39d4f5b8c6b878685c93fe46 Mon Sep 17 00:00:00 2001 From: Yan Peng Date: Sun, 5 Oct 2025 22:43:11 -0700 Subject: [PATCH 044/132] WIP: prove tail --- arm/proofs/aes_xts_decrypt.ml | 319 +++++++++++++++++++++++++++++++--- 1 file changed, 298 insertions(+), 21 deletions(-) diff --git a/arm/proofs/aes_xts_decrypt.ml b/arm/proofs/aes_xts_decrypt.ml index c3c8de7b5..e9a5fd4cd 100644 --- a/arm/proofs/aes_xts_decrypt.ml +++ b/arm/proofs/aes_xts_decrypt.ml @@ -2541,6 +2541,7 @@ let AES_XTS_DECRYPT_CORRECT = prove( (* Subgoal 3: loop body *) REPEAT STRIP_TAC THEN + (* TODO: add a comment explaining what this bound is for *) SUBGOAL_THEN `i * 0x50 + 0x50 <= val (len:int64)` ASSUME_TAC THENL [ SUBGOAL_THEN `i + 1 <= val (num_5blocks_adjusted:int64)` MP_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN @@ -2567,12 +2568,6 @@ let AES_XTS_DECRYPT_CORRECT = prove( (* ===> Symbolic Simulation: Start symbolic simulation*) ASM_REWRITE_TAC[byte_list_at] THEN - GHOST_INTRO_TAC `b0:int128` `read (memory :> bytes128 (word_add pt_ptr (word_mul (word 0x50) (word i))))` THEN - GHOST_INTRO_TAC `b1:int128` `read (memory :> bytes128 (word_add (word_add pt_ptr (word_mul (word 0x50) (word i))) (word 0x10)))` THEN - GHOST_INTRO_TAC `b2:int128` `read (memory :> bytes128 (word_add (word_add pt_ptr (word_mul (word 0x50) (word i))) (word 0x20)))` THEN - GHOST_INTRO_TAC `b3:int128` `read (memory :> bytes128 (word_add (word_add pt_ptr (word_mul (word 0x50) (word i))) (word 0x30)))` THEN - GHOST_INTRO_TAC `b4:int128` `read (memory :> bytes128 (word_add (word_add pt_ptr (word_mul (word 0x50) (word i))) (word 0x40)))` THEN - ENSURES_INIT_TAC "s0" THEN (* List values for ct_ptr + [0 .. 0x40] *) MP_TAC (SPECL [`ct_ptr:int64`; `i:num`; `len:int64`; `ct:byte list`; `s0:armstate`] READ_CT_LEMMA) THEN @@ -2647,13 +2642,15 @@ let AES_XTS_DECRYPT_CORRECT = prove( MP_TAC (SPECL [`0x50 * i + 0x50:num`; `(aes256_xts_decrypt ct (0x50 * i + 0x50) iv key1 key2):byte list`; `s188:armstate`] BYTE_LIST_TO_NUM_THM) THEN ANTS_TAC THENL[ REWRITE_TAC[ARITH_RULE `0x50 * i + 0x50 = 0x10 * (5 * i + 5)`; - LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS] THEN ARITH_TAC + LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS] THEN + ARITH_TAC ; ALL_TAC] THEN DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN MP_TAC (SPECL [`0x50 * i:num`; `(aes256_xts_decrypt ct (0x50 * i) iv key1 key2):byte list`; `s188:armstate`] BYTE_LIST_TO_NUM_THM) THEN ANTS_TAC THENL[ REWRITE_TAC[ARITH_RULE `0x50 * i = 0x10 * 5 * i`; - LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS] THEN ARITH_TAC + LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS] THEN + ARITH_TAC ; ALL_TAC] THEN DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN DISCH_TAC THEN @@ -2982,15 +2979,6 @@ let AES_XTS_DECRYPT_CORRECT = prove( REWRITE_TAC[byte_list_at] THEN SUBST_ALL_TAC (WORD_RULE `(word (val (num_5blocks_adjusted:int64))):int64 = num_5blocks_adjusted`) THEN - GHOST_INTRO_TAC `bt_0:int128` - `read (memory :> bytes128 (word_add pt_ptr (word_mul (word 0x50) (num_5blocks_adjusted:int64))))` THEN - GHOST_INTRO_TAC `bt_1:int128` - `read (memory :> bytes128 (word_add (word_add pt_ptr (word_mul (word 0x50) (num_5blocks_adjusted:int64))) (word 0x10)))` THEN - GHOST_INTRO_TAC `bt_2:int128` - `read (memory :> bytes128 (word_add (word_add (pt_ptr:int64) (word_mul (word 0x50) (num_5blocks_adjusted:int64))) (word 0x20)))` THEN - GHOST_INTRO_TAC `bt_3:int128` - `read (memory :> bytes128 (word_add (word_add (pt_ptr:int64) (word_mul (word 0x50) (num_5blocks_adjusted:int64))) (word 0x30)))` THEN - MATCH_MP_TAC ENSURES_FRAME_SUBSUMED THEN EXISTS_TAC `MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI ,, MAYCHANGE [X19; X20; X21; X22],, @@ -3069,10 +3057,13 @@ let AES_XTS_DECRYPT_CORRECT = prove( MP_TAC (SPECL [`ct_ptr:int64`; `num_5blocks_adjusted:int64`; `len:int64`; `ct:byte list`; `s3:armstate`] READ_CT_TAIL4_LEMMA) THEN ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN - (* Rewrite to help reasoning about nonoverlapping + (* Assumptions that help with reasoning about nonoverlapping so that the universally quantified assumption stays. See: https://hol-light.zulipchat.com/#narrow/channel/474190-s2n-bignum/topic/.E2.9C.94.20Symbolic.20simulation.20removed.20assumption/with/541554894 *) - SUBGOAL_THEN `0x50 * (val (num_5blocks_adjusted:int64)) < 0x2 EXP 0x40` ASSUME_TAC THENL [CHEAT_TAC; ALL_TAC] THEN + SUBGOAL_THEN `0x50 * (val (num_5blocks_adjusted:int64)) < 0x2 EXP 0x40` ASSUME_TAC THENL + [ UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 <= val (num_blocks_adjusted:int64)` THEN + UNDISCH_TAC `val (num_blocks_adjusted:int64) <= 0x2 EXP 0x18` THEN + ARITH_TAC; ALL_TAC] THEN SUBGOAL_THEN `val ((word (0x50 * val (num_5blocks_adjusted:int64))):int64) = 0x50 * val num_5blocks_adjusted` ASSUME_TAC THENL [ IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN ASM_ARITH_TAC; ALL_TAC] THEN POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th])) THEN @@ -3095,16 +3086,302 @@ let AES_XTS_DECRYPT_CORRECT = prove( RULE_ASSUM_TAC(REWRITE_RULE [WORD_RULE `word_mul (word 0x50) num_5blocks_adjusted:int64 = word(0x50 * val num_5blocks_adjusted)`]) THEN + (* TODO: there is a non-overlapping issue in the symbolic simulation that the third block is missing *) ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (134--138) THEN FIRST_X_ASSUM MP_TAC THEN COND_CASES_TAC THENL [ DISCH_TAC THEN ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN - CHEAT_TAC; + SUBGOAL_THEN `val (len:int64) = 0x50 * val (num_5blocks_adjusted:int64) + 0x40` ASSUME_TAC THENL + [ CHEAT_TAC; ALL_TAC] THEN + ASM_REWRITE_TAC[] THEN + + (* TODO: Manually add the assumption as a temporary fix *) + SUBGOAL_THEN `read + (memory :> + bytes128 + (word_add (pt_ptr:int64) (word (0x50 * val (num_5blocks_adjusted:int64) + 0x20)))) + s138 = + aes256_xts_decrypt_round + (bytes_to_int128 + (SUB_LIST (val num_5blocks_adjusted * 0x50 + 0x20,0x10) ct)) + (calculate_tweak (val num_5blocks_adjusted * 0x5 + 0x2) iv key2) + key1` ASSUME_TAC THENL [CHEAT_TAC; ALL_TAC] THEN + (* TODO: ??? *) + RULE_ASSUM_TAC(REWRITE_RULE + [WORD_RULE `(word_add (word_add pt_ptr (word (0x50 * val num_5blocks_adjusted))) + (word 0x30)) = (word_add (pt_ptr:int64) (word (0x50 * val (num_5blocks_adjusted:int64) + 0x30)))`]) THEN + + (* Remove quantifier *) + UNDISCH_TAC + `forall i. + i < 0x50 * val (num_5blocks_adjusted:int64) + ==> read (memory :> bytes8 (word_add pt_ptr (word i))) s138 = + EL i (aes256_xts_decrypt ct (0x50 * val num_5blocks_adjusted) iv key1 key2)` THEN + MP_TAC (SPECL [`0x50 * val (num_5blocks_adjusted:int64) + 0x40:num`; + `(aes256_xts_decrypt ct (0x50 * val (num_5blocks_adjusted:int64) + 0x40) iv key1 key2):byte list`; + `s138:armstate`] BYTE_LIST_TO_NUM_THM) THEN + ANTS_TAC THENL[ + REWRITE_TAC[ARITH_RULE `0x50 * i + 0x40 = 0x10 * (5 * i + 4)`; + LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS] THEN + ARITH_TAC + ; ALL_TAC] THEN + DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN + MP_TAC (SPECL [`0x50 * val (num_5blocks_adjusted:int64):num`; + `(aes256_xts_decrypt ct (0x50 * val (num_5blocks_adjusted:int64)) iv key1 key2):byte list`; + `s138:armstate`] BYTE_LIST_TO_NUM_THM) THEN + ANTS_TAC THENL[ + REWRITE_TAC[ARITH_RULE `0x50 * i = 0x10 * 5 * i`; + LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS] THEN + ARITH_TAC + ; ALL_TAC] THEN + DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN + DISCH_TAC THEN + + IMP_REWRITE_TAC[ARITH_RULE `0x50 * i + 0x40 = (0x50 * i + 0x30) + 0x10`; READ_BYTES_AND_BYTE128_SPLIT] THEN + EXISTS_TAC `(aes256_xts_decrypt ct (0x50 * val (num_5blocks_adjusted:int64) + 0x40) iv key1 key2)` THEN + REPEAT CONJ_TAC THENL [ + REWRITE_TAC [ARITH_RULE `(0x50 * i + 0x30) + 0x10 = 0x50 * i + 0x40`]; + + MP_TAC (SPECL [`0x5 * val (num_5blocks_adjusted:int64) + 0x4:num`; + `ct:byte list`; `iv:int128`; `key1:int128 list`; + `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN + REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC; GSYM ADD_ASSOC] THEN + CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC THEN + ASM_REWRITE_TAC[] THEN ARITH_TAC; + + (* Establish that one xts decrypt round is the same as + selecting one block of bytes from calling the top-level function. *) + REWRITE_TAC[aes256_xts_decrypt] THEN + SIMP_TAC[ARITH_RULE `~(0x50 * val (num_5blocks_adjusted:int64) + 0x40 < 0x10)`] THEN + SUBGOAL_THEN `(0x50 * val (num_5blocks_adjusted:int64) + 0x40) MOD 0x10 = 0` SUBST1_TAC THENL + [ REWRITE_TAC[ARITH_RULE `80 * i + 64 = 16 * (5 * i + 4)`] THEN + REWRITE_TAC[MOD_MULT] + ; ALL_TAC] THEN + CONV_TAC (DEPTH_CONV let_CONV) THEN + REWRITE_TAC[SUB_0; ARITH_RULE `(0x50 * i + 0x40) DIV 0x10 = 0x5 * i + 0x4`] THEN + SIMP_TAC[ARITH_RULE `~(0x5 * i + 0x4 < 0x2)`; + ARITH_RULE `(0x5 * i + 0x4) - 0x2 = 0x5 * i + 0x2`; + ARITH_RULE `(0x5 * i + 0x4) - 0x1 = 0x5 * i + 0x3`] THEN + + MP_TAC (SPECL [`0`;`5 * val (num_5blocks_adjusted:int64) + 2:num`; + `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + LENGTH_OF_AES256_XTS_DECRYPT_REC) THEN + SIMP_TAC[ARITH_RULE `~(5 * i + 2 < 0)`; + ARITH_RULE `((0x5 * i + 0x2) - 0x0 + 0x1) * 0x10 = 0x50 * i + 0x30`] THEN + IMP_REWRITE_TAC[SUB_LIST_APPEND_RIGHT_LEMMA] THEN DISCH_TAC THEN + + MP_TAC (SPECL [`5 * val (num_5blocks_adjusted:int64) + 3:num`; + `0x0:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + LENGTH_OF_AES256_XTS_DECRYPT_TAIL) THEN + CONV_TAC NUM_REDUCE_CONV THEN REWRITE_TAC[ADD_0] THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN + + REWRITE_TAC[AES256_XTS_DECRYPT_TAIL_WHEN_1BLOCK] THEN + ASM_SIMP_TAC[ARITH_RULE `(i * 0x5 + 0x3) * 0x10 = i * 0x50 + 0x30`; + ARITH_RULE `5 * i + 3 = i * 5 + 3`]; + + (* Proving that reading previous bytes is the same as the spec *) + REWRITE_TAC[ARITH_RULE `0x50 * i + 0x30 = 0x10 * (5 * i + 3)`; + ARITH_RULE `0x50 * i + 0x40 = 0x10 * (5 * i + 3) + 0x10`] THEN + REWRITE_TAC[SUB_LIST_OF_AES256_XTS_DECRYPT_FULL_BLOCKS] THEN + ASM_REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC] THEN CONV_TAC NUM_REDUCE_CONV + ] THEN + + IMP_REWRITE_TAC[ARITH_RULE `0x50 * i + 0x30 = (0x50 * i + 0x20) + 0x10`; READ_BYTES_AND_BYTE128_SPLIT] THEN + EXISTS_TAC `(aes256_xts_decrypt ct (0x50 * val (num_5blocks_adjusted:int64) + 0x30) iv key1 key2)` THEN + REPEAT CONJ_TAC THENL [ + MP_TAC (SPECL [`0x5 * val (num_5blocks_adjusted:int64) + 0x3:num`; + `ct:byte list`; `iv:int128`; `key1:int128 list`; + `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN + REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC; GSYM ADD_ASSOC] THEN + CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES]; + + REWRITE_TAC [ARITH_RULE `(0x50 * i + 0x20) + 0x10 = 0x50 * i + 0x30`] THEN + MP_TAC (SPECL [`0x5 * val (num_5blocks_adjusted:int64) + 0x3:num`; + `ct:byte list`; `iv:int128`; `key1:int128 list`; + `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN + REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC; GSYM ADD_ASSOC] THEN + CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN ARITH_TAC; + + (* Establish that one xts decrypt round is the same as + selecting one block of bytes from calling the top-level function. *) + REWRITE_TAC[aes256_xts_decrypt] THEN + SIMP_TAC[ARITH_RULE `~(0x50 * i + 0x30 < 0x10)`] THEN + SUBGOAL_THEN `(0x50 * val (num_5blocks_adjusted:int64) + 0x30) MOD 0x10 = 0` SUBST1_TAC THENL + [ REWRITE_TAC[ARITH_RULE `80 * i + 48 = 16 * (5 * i + 3)`] THEN + REWRITE_TAC[MOD_MULT] + ; ALL_TAC] THEN + CONV_TAC (DEPTH_CONV let_CONV) THEN + REWRITE_TAC[SUB_0; ARITH_RULE `(0x50 * i + 0x30) DIV 0x10 = 0x5 * i + 0x3`] THEN + SIMP_TAC[ARITH_RULE `~(0x5 * i + 0x3 < 0x2)`; + ARITH_RULE `(0x5 * i + 0x3) - 0x2 = 0x5 * i + 0x1`; + ARITH_RULE `(0x5 * i + 0x3) - 0x1 = 0x5 * i + 0x2`] THEN + + MP_TAC (SPECL [`0`;`5 * val (num_5blocks_adjusted:int64) + 1:num`; + `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + LENGTH_OF_AES256_XTS_DECRYPT_REC) THEN + SIMP_TAC[ARITH_RULE `~(5 * i + 1 < 0)`] THEN + REWRITE_TAC[ARITH_RULE `((0x5 * i + 0x1) - 0x0 + 0x1) * 0x10 = 0x50 * i + 0x20`] THEN + IMP_REWRITE_TAC[SUB_LIST_APPEND_RIGHT_LEMMA] THEN DISCH_TAC THEN + + MP_TAC (SPECL [`5 * val (num_5blocks_adjusted:int64) + 2:num`; `0x0:num`; + `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + LENGTH_OF_AES256_XTS_DECRYPT_TAIL) THEN + CONV_TAC NUM_REDUCE_CONV THEN REWRITE_TAC[ADD_0] THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN + + REWRITE_TAC[AES256_XTS_DECRYPT_TAIL_WHEN_1BLOCK] THEN + ASM_SIMP_TAC[ARITH_RULE `(i * 0x5 + 0x2) * 0x10 = i * 0x50 + 0x20`; + ARITH_RULE `5 * i + 2 = i * 5 + 2`]; + + (* Proving that reading previous bytes is the same as the spec *) + REWRITE_TAC[ARITH_RULE `0x50 * i + 0x20 = 0x10 * (5 * i + 2)`; + ARITH_RULE `0x50 * i + 0x30 = 0x10 * (5 * i + 2) + 0x10`] THEN + REWRITE_TAC[SUB_LIST_OF_AES256_XTS_DECRYPT_FULL_BLOCKS] THEN + ASM_REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC] THEN CONV_TAC NUM_REDUCE_CONV + ] THEN + + REWRITE_TAC[ARITH_RULE `0x50 * i + 0x20 = (0x50 * i + 0x10) + 0x10`] THEN + (* Use SPECL to force IMP_REWRITE_TAC to apply once once *) + IMP_REWRITE_TAC[(SPECL [`pt_ptr:int64`; `(0x50 * val (num_5blocks_adjusted:int64) + 0x10):num`; + `x:byte list`; `s188:armstate`] READ_BYTES_AND_BYTE128_SPLIT)] THEN + EXISTS_TAC `(aes256_xts_decrypt ct (0x50 * val (num_5blocks_adjusted:int64) + 0x20) iv key1 key2)` THEN + REPEAT CONJ_TAC THENL [ + MP_TAC (SPECL [`0x5 * val (num_5blocks_adjusted:int64) + 0x2:num`; + `ct:byte list`; `iv:int128`; `key1:int128 list`; + `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN + REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC; GSYM ADD_ASSOC] THEN + CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN ARITH_TAC; + + MP_TAC (SPECL [`0x5 * val (num_5blocks_adjusted:int64) + 0x2:num`; + `ct:byte list`; `iv:int128`; `key1:int128 list`; + `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN + REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC; GSYM ADD_ASSOC] THEN + CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN ARITH_TAC; + + (* Establish that one xts decrypt round is the same as + selecting one block of bytes from calling the top-level function. *) + REWRITE_TAC[aes256_xts_decrypt] THEN + SIMP_TAC[ARITH_RULE `~(0x50 * i + 0x20 < 0x10)`] THEN + SUBGOAL_THEN `(0x50 * val (num_5blocks_adjusted:int64) + 0x20) MOD 0x10 = 0` SUBST1_TAC THENL + [ REWRITE_TAC[ARITH_RULE `80 * i + 32 = 16 * (5 * i + 2)`] THEN + REWRITE_TAC[MOD_MULT] + ; ALL_TAC] THEN + CONV_TAC (DEPTH_CONV let_CONV) THEN + REWRITE_TAC[SUB_0; ARITH_RULE `(0x50 * i + 0x20) DIV 0x10 = 0x5 * i + 0x2`] THEN + SIMP_TAC[ARITH_RULE `~(0x5 * i + 0x2 < 0x2)`; + ARITH_RULE `(0x5 * i + 0x2) - 0x2 = 0x5 * i`; + ARITH_RULE `(0x5 * i + 0x2) - 0x1 = 0x5 * i + 0x1`] THEN + + MP_TAC (SPECL [`0`;`5 * val (num_5blocks_adjusted:int64):num`; + `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + LENGTH_OF_AES256_XTS_DECRYPT_REC) THEN + SIMP_TAC[ARITH_RULE `~(5 * i < 0)`; + ARITH_RULE `(0x5 * i - 0x0 + 0x1) * 0x10 = 0x50 * i + 0x10`] THEN + IMP_REWRITE_TAC[SUB_LIST_APPEND_RIGHT_LEMMA] THEN DISCH_TAC THEN + + MP_TAC (SPECL [`5 * val (num_5blocks_adjusted:int64) + 1:num`; `0x0:num`; + `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + LENGTH_OF_AES256_XTS_DECRYPT_TAIL) THEN + CONV_TAC NUM_REDUCE_CONV THEN REWRITE_TAC[ADD_0] THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN + + REWRITE_TAC[AES256_XTS_DECRYPT_TAIL_WHEN_1BLOCK] THEN + SIMP_TAC[ARITH_RULE `i * 0x50 + 0x10 = (i * 0x5 + 0x1) * 0x10`; + ARITH_RULE `i * 0x5 = 0x5 * i`]; + + (* Proving that reading previous bytes is the same as the spec *) + REWRITE_TAC[ARITH_RULE `0x50 * i + 0x10 = 0x10 * (5 * i + 1)`; + ARITH_RULE `0x50 * i + 0x20 = 0x10 * (5 * i + 1) + 0x10`] THEN + REWRITE_TAC[SUB_LIST_OF_AES256_XTS_DECRYPT_FULL_BLOCKS] THEN + ASM_REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC] THEN CONV_TAC NUM_REDUCE_CONV + ] THEN + + IMP_REWRITE_TAC[(SPECL [`pt_ptr:int64`; `(0x50 * val (num_5blocks_adjusted:int64)):num`; + `(aes256_xts_decrypt ct (0x50 * val (num_5blocks_adjusted:int64) + 0x10) iv key1 key2):byte list`; + `s188:armstate`] + READ_BYTES_AND_BYTE128_SPLIT)] THEN + EXISTS_TAC `ct:byte list` THEN EXISTS_TAC `iv:int128` THEN + EXISTS_TAC `key1:int128 list` THEN EXISTS_TAC `key2:int128 list` THEN + REPEAT CONJ_TAC THENL [ + MP_TAC (SPECL [`0x5 * val (num_5blocks_adjusted:int64) + 0x1:num`; + `ct:byte list`; `iv:int128`; `key1:int128 list`; + `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN + REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC; GSYM ADD_ASSOC] THEN + CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN ARITH_TAC; + + MP_TAC (SPECL [`0x5 * val (num_5blocks_adjusted:int64) + 0x1:num`; + `ct:byte list`; `iv:int128`; `key1:int128 list`; + `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN + REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC; GSYM ADD_ASSOC] THEN + CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN ARITH_TAC; + + (* Establish that one xts decrypt round is the same as + selecting one block of bytes from calling the top-level function. *) + REWRITE_TAC[aes256_xts_decrypt] THEN + SIMP_TAC[ARITH_RULE `~(0x50 * i + 0x10 < 0x10)`] THEN + SUBGOAL_THEN `(0x50 * val (num_5blocks_adjusted:int64) + 0x10) MOD 0x10 = 0` SUBST1_TAC THENL + [ REWRITE_TAC[ARITH_RULE `80 * i + 16 = 16 * (5 * i + 1)`] THEN + REWRITE_TAC[MOD_MULT] + ; ALL_TAC] THEN + CONV_TAC (DEPTH_CONV let_CONV) THEN + REWRITE_TAC[SUB_0; ARITH_RULE `(0x50 * i + 0x10) DIV 0x10 = 0x5 * i + 0x1`] THEN + (* Two cases: i = 0 then execute tail branch, else execute recursion branch *) + COND_CASES_TAC THENL + [ SUBGOAL_THEN `val (num_5blocks_adjusted:int64) = 0` SUBST1_TAC THENL + [ UNDISCH_TAC `5 * val (num_5blocks_adjusted:int64) + 1 < 2` THEN + UNDISCH_TAC `0 < val (num_5blocks_adjusted:int64)` THEN + ARITH_TAC + ; ALL_TAC] THEN CONV_TAC NUM_REDUCE_CONV THEN + + MP_TAC (SPECL [`0x0:num`; `0x0:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + LENGTH_OF_AES256_XTS_DECRYPT_TAIL) THEN + CONV_TAC NUM_REDUCE_CONV THEN REWRITE_TAC[ADD_0] THEN DISCH_TAC THEN + IMP_REWRITE_TAC[(ISPECL [`(aes256_xts_decrypt_tail 0x0 0x0 ct iv key1 key2):byte list`; + `0x10:num`] SUB_LIST_LENGTH_IMPLIES)] THEN + + REWRITE_TAC[AES256_XTS_DECRYPT_TAIL_WHEN_1BLOCK] THEN + CONV_TAC NUM_REDUCE_CONV; + + SIMP_TAC[ARITH_RULE `(0x5 * i + 0x1) - 0x2 = 0x5 * i - 0x1`; + ARITH_RULE `(0x5 * i + 0x1) - 0x1 = 0x5 * i`] THEN + + MP_TAC (SPECL [`0`;`5 * val (num_5blocks_adjusted:int64) - 1:num`; + `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + LENGTH_OF_AES256_XTS_DECRYPT_REC) THEN + SUBGOAL_THEN `~(0x5 * val (num_5blocks_adjusted:int64) - 0x1 < 0x0)` ASSUME_TAC THENL + [ UNDISCH_TAC `~(0x5 * val (num_5blocks_adjusted:int64) + 0x1 < 0x2)` THEN ARITH_TAC; ALL_TAC ] THEN + ASM_SIMP_TAC[] THEN + IMP_REWRITE_TAC[ARITH_RULE `~(0x5 * i + 0x1 < 0x2) ==> (0x5 * i - 1 - 0x0 + 0x1) * 0x10 = 0x50 * i`] THEN + IMP_REWRITE_TAC[SUB_LIST_APPEND_RIGHT_LEMMA] THEN DISCH_TAC THEN + + MP_TAC (SPECL [`5 * val (num_5blocks_adjusted:int64):num`; + `0x0:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + LENGTH_OF_AES256_XTS_DECRYPT_TAIL) THEN + CONV_TAC NUM_REDUCE_CONV THEN REWRITE_TAC[ADD_0] THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN + + REWRITE_TAC[AES256_XTS_DECRYPT_TAIL_WHEN_1BLOCK] THEN + SIMP_TAC[ARITH_RULE `i * 0x50 = (i * 0x5) * 0x10`; + ARITH_RULE `i * 0x5 = 0x5 * i`]]; + + (* Proving that reading previous bytes is the same as the spec *) + REWRITE_TAC[ARITH_RULE `0x50 * i = 0x10 * 5 * i`; + ARITH_RULE `0x50 * i + 0x10 = 0x10 * 5 * i + 0x10`] THEN + REWRITE_TAC[SUB_LIST_OF_AES256_XTS_DECRYPT_FULL_BLOCKS] THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN + REWRITE_TAC[LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS] + ]; ALL_TAC] THEN - (* WIP: Cipher stealing branch *) DISCH_TAC THEN ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (139--147) THEN TWEAK_TAC `Q8:(armstate,int128)component` `val (num_5blocks_adjusted:int64) * 0x5 + 0x5` `val (num_5blocks_adjusted:int64) * 0x5 + 0x4` THEN From 4902ff67056920c6895d29348aa45a20ead90550 Mon Sep 17 00:00:00 2001 From: Yan Peng Date: Mon, 6 Oct 2025 23:54:05 -0700 Subject: [PATCH 045/132] Restructure proof to add a cut point before cipher stealing and finish up the invariant proof --- arm/proofs/aes_xts_decrypt.ml | 1431 ++++++++++++++++++++++++--------- 1 file changed, 1034 insertions(+), 397 deletions(-) diff --git a/arm/proofs/aes_xts_decrypt.ml b/arm/proofs/aes_xts_decrypt.ml index e9a5fd4cd..c96e63b47 100644 --- a/arm/proofs/aes_xts_decrypt.ml +++ b/arm/proofs/aes_xts_decrypt.ml @@ -1843,6 +1843,17 @@ let LENGTH_OF_INT128_TO_BYTES = prove( CONV_TAC NUM_REDUCE_CONV );; +let DIVISION_BY_80_LEMMA = prove( + `!(a:num) b. a DIV 0x50 = b ==> + ~(a - b * 0x50 - 0x10 = 0x0) ==> + ~(a - b * 0x50 - 0x20 = 0x0) ==> + ~(a - b * 0x50 - 0x30 = 0x0) ==> + ~(a - b * 0x50 - 0x40 = 0x0) ==> + b * 0x50 = a`, + CHEAT_TAC +);; + + (* ********************************************************** *) (* Properties that we prove about the specification functions *) @@ -2103,6 +2114,30 @@ let SUB_LIST_OF_AES256_XTS_DECRYPT_FULL_BLOCKS = prove( ASM_ARITH_TAC );; +let tail_cases_in_byte = new_definition +`tail_cases_in_byte (i:int64) (len:int64) : num = + if val i * 0x50 + 0x40 = val len then 0x50 * val i + 0x40 + else + if val i * 0x50 + 0x30 = val len then 0x50 * val i + 0x30 + else + if val i * 0x50 + 0x20 = val len then 0x50 * val i + 0x20 + else + if val i * 0x50 + 0x10 = val len then 0x50 * val i + 0x10 + else 0x50 * val i`;; + +(* For X9 and X10, they stand for i * 0x5 + 4 when number of blocks is divisible by 5 *) +let tail_cases_in_index = new_definition +`tail_cases_in_index (i:int64) (len:int64) (last:bool) : num = + if val i * 0x50 + 0x40 = val len then val i * 0x5 + 4 + else + if val i * 0x50 + 0x30 = val len then val i * 0x5 + 3 + else + if val i * 0x50 + 0x20 = val len then val i * 0x5 + 2 + else + if val i * 0x50 + 0x10 = val len then val i * 0x5 + 1 + else + if last then val i * 0x5 else val i * 0x5 + 4`;; + let AES_XTS_DECRYPT_CORRECT = prove( `!ct_ptr pt_ptr ct key1_ptr key2_ptr iv_ptr iv len k00 k01 k02 k03 k04 k05 k06 k07 k08 k09 k0a k0b k0c k0d k0e @@ -2110,6 +2145,7 @@ let AES_XTS_DECRYPT_CORRECT = prove( pc. nonoverlapping (word pc, LENGTH aes_xts_decrypt_mc) (pt_ptr, val len) /\ nonoverlapping (ct_ptr, val len) (pt_ptr, val len) + /\ nonoverlapping (key1_ptr, 260) (pt_ptr, val len) /\ val len >= 16 /\ val len <= 2 EXP 24 /\ LENGTH ct = val len ==> ensures arm (\s. aligned_bytes_loaded s (word pc) aes_xts_decrypt_mc /\ @@ -2266,210 +2302,211 @@ let AES_XTS_DECRYPT_CORRECT = prove( byte_list_at ct ct_ptr len s /\ byte_list_at (aes256_xts_decrypt ct 0 iv key1 key2) pt_ptr (word 0) s /\ set_key_schedule s key1_ptr k00 k01 k02 k03 k04 k05 k06 k07 k08 k09 k0a k0b k0c k0d k0e` THEN - CONJ_TAC THENL - [ - (* ===> Symbolic Simulation: Start symbolic simulation*) - ENSURES_INIT_TAC "s0" THEN - ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (1--2) THEN - - (* Discharge if condition *) - SUBGOAL_THEN - `ival (word_sub (len:int64) (word 0x10)) < &0x0 - <=> ~(ival (len:int64) - &0x10 = ival (word_sub (len:int64) (word 0x10)))` MP_TAC THENL - [ - MP_TAC (BITBLAST_RULE - `val (len:int64) >= 0x10 ==> val len <= 2 EXP 0x18 ==> - ival (word_sub len (word 0x10)) >= &0x0`) THEN - ASM_REWRITE_TAC[] THEN - MP_TAC (BITBLAST_RULE - `val (len:int64) >= 0x10 ==> val len <= 2 EXP 0x18 ==> - ival (len:int64) - &0x10 = ival (word_sub len (word 0x10))`) THEN - ASM_REWRITE_TAC[] THEN - ARITH_TAC; - ALL_TAC] THEN - ASM_REWRITE_TAC[] THEN DISCH_TAC THEN - POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th])) THEN - - (* ===> Symbolic Simulation: Symbolic execution for initialization of tweak *) - ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (3--69) THEN - (* Prove Q6 stores initial tweak *) - FIRST_X_ASSUM(MP_TAC o SPEC `(calculate_tweak 0 iv key2)` - o MATCH_MP (MESON[] `read Q6 s = a ==> !a'. a = a' ==> read Q6 s = a'`)) THEN - ANTS_TAC THENL - [REWRITE_TAC[CONJUNCT1 calculate_tweak; xts_init_tweak] THEN - EXPAND_TAC "key2" THEN AESENC_TAC; DISCH_TAC] THEN - - (* ===> Symbolic Simulation: Symbolic simulating untill next branch *) - ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (70--89) THEN - (* Case split on whether there is a tail *) - FIRST_X_ASSUM MP_TAC THEN - COND_CASES_TAC THENL - [ - (* If there is no tail *) - DISCH_TAC THEN - (* Prove val tail_len = 0 and num_blocks = num_blocks_adjusted *) - SUBGOAL_THEN `val (tail_len:int64) = 0` ASSUME_TAC THENL - [ UNDISCH_TAC `val (word_and (tail_len:int64) (word 0xf)) = 0x0` THEN - MP_TAC (SPECL [`len:int64`; `tail_len:int64`] TAIL_LEN_BOUND_THM) THEN - ASM_REWRITE_TAC[] THEN - SUBST1_TAC(ARITH_RULE `0xf = 2 EXP 4 - 1`) THEN - REWRITE_TAC[VAL_WORD_AND_MASK_WORD] THEN - NUM_REDUCE_TAC THEN SIMP_TAC[MOD_LT]; ALL_TAC] THEN - SUBGOAL_THEN `num_blocks_adjusted:int64 = num_blocks:int64` ASSUME_TAC THENL - [ UNDISCH_TAC `(if val (tail_len:int64) = 0x0 - then (num_blocks:int64) - else word_sub num_blocks (word 0x10)) = - num_blocks_adjusted` THEN - UNDISCH_TAC `val (tail_len:int64) = 0` THEN - SIMP_TAC[]; ALL_TAC] THEN - - (* Prove x9, x10 stores lower and upper halves and Q8 stores the full tweak *) - TWEAK_TAC `Q8:(armstate,int128)component` `1:num` `0:num` THEN - ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (90--93) THEN - (* Prove the optimized udiv is basically udiv *) - SUBGOAL_THEN `word_ushr - ((word ((val (num_blocks:int64) * 0xcccccccccccccccd) DIV 0x2 EXP 0x40)):int64) - 0x6 = - word ((val num_blocks) DIV 0x50)` ASSUME_TAC THENL - [ MP_TAC (BITBLAST_RULE `val (num_blocks:int64) < 2 EXP 64`) THEN - REWRITE_TAC[word_ushr] THEN - MP_TAC (SPECL [`val (num_blocks:int64)`] UDIV_OPT_THM) THEN SIMP_TAC[] - ; ALL_TAC] THEN - POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th])) THEN - - (* Eliminate 1 block case *) - ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (94--95) THEN - SUBGOAL_THEN `~(val (num_blocks:int64) < 0x20)` ASSUME_TAC THENL - [ UNDISCH_TAC `~(val (num_blocks:int64) < 0x60)` THEN ARITH_TAC - ; POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th]))] THEN - (* Eliminate 2 blocks case *) - ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (96--97) THEN - SUBGOAL_THEN `~(val (num_blocks:int64) < 0x30)` ASSUME_TAC THENL - [ UNDISCH_TAC `~(val (num_blocks:int64) < 0x60)` THEN ARITH_TAC - ; POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th]))] THEN - (* Eliminate 3 blocks case and prove Q9 stores tweak 2 *) - ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (98--105) THEN - SUBGOAL_THEN `~(val (num_blocks:int64) < 0x40)` ASSUME_TAC THENL - [ UNDISCH_TAC `~(val (num_blocks:int64) < 0x60)` THEN ARITH_TAC - ; POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th]))] THEN - TWEAK_TAC `Q9:(armstate,int128)component` `2:num` `1:num` THEN - - (* Eliminate 4 blocks case and Q10 stores tweak 3 *) - ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (106--113) THEN - SUBGOAL_THEN `~(val (num_blocks:int64) < 0x50)` ASSUME_TAC THENL - [ UNDISCH_TAC `~(val (num_blocks:int64) < 0x60)` THEN ARITH_TAC - ; POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th]))] THEN - TWEAK_TAC `Q10:(armstate,int128)component` `3:num` `2:num` THEN - - (* Must have 5 blocks, execute until start of loop. Q11 stores tweak 4 *) - ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (114--122) THEN - TWEAK_TAC `Q11:(armstate,int128)component` `4:num` `3:num` THEN - - ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN - REPEAT CONJ_TAC THENL - [ - EXPAND_TAC "num_5blocks_adjusted" THEN - EXPAND_TAC "num_blocks_adjusted" THEN - ASM_REWRITE_TAC[]; - ASM_REWRITE_TAC[byte_list_at]; - REWRITE_TAC[aes256_xts_decrypt] THEN - CONV_TAC (DEPTH_CONV NUM_RED_CONV) THEN - ASM_REWRITE_TAC[byte_list_at] THEN - REWRITE_TAC[VAL_WORD_0] THEN ARITH_TAC; - ASM_REWRITE_TAC[set_key_schedule]] - ; ALL_TAC - ] THEN - - (* If there is a tail *) - DISCH_TAC THEN - (* Prove ~ tail_len = 0 *) - SUBGOAL_THEN `~(val (tail_len:int64) = 0)` ASSUME_TAC THENL - [ UNDISCH_TAC `~(val (word_and (tail_len:int64) (word 0xf)) = 0x0)` THEN - MP_TAC (SPECL [`len:int64`; `tail_len:int64`] TAIL_LEN_BOUND_THM) THEN - ASM_REWRITE_TAC[] THEN - SUBST1_TAC(ARITH_RULE `0xf = 2 EXP 4 - 1`) THEN - REWRITE_TAC[VAL_WORD_AND_MASK_WORD] THEN - NUM_REDUCE_TAC THEN SIMP_TAC[MOD_LT] - ; ALL_TAC] THEN - (* Prove num_blocks_adjusted = word_sub num_blocks (word 0x10) *) - SUBGOAL_THEN `word_sub num_blocks (word 0x10) = num_blocks_adjusted:int64` ASSUME_TAC THENL - [ UNDISCH_TAC `(if val (tail_len:int64) = 0x0 - then (num_blocks:int64) - else word_sub num_blocks (word 0x10)) = num_blocks_adjusted` THEN - ASM_REWRITE_TAC[]; ALL_TAC] THEN - - ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (90--92) THEN - (* Discharge if condition *) - SUBGOAL_THEN - `ival (word_sub (num_blocks_adjusted:int64) (word 0x10)) < &0x0 <=> - ~(ival (num_blocks_adjusted:int64) - &0x10 = - ival (word_sub (num_blocks_adjusted:int64) (word 0x10)))` MP_TAC THENL - [ - MP_TAC (BITBLAST_RULE - `~(val (num_blocks_adjusted:int64) < 0x50) ==> - val num_blocks_adjusted <= 2 EXP 0x18 ==> - ival (word_sub num_blocks_adjusted (word 0x10)) >= &0x0`) THEN - ASM_REWRITE_TAC[] THEN - MP_TAC (BITBLAST_RULE - `~(val (num_blocks_adjusted:int64) < 0x50) ==> - val num_blocks_adjusted <= 2 EXP 0x18 ==> - ival (num_blocks_adjusted:int64) - &0x10 = ival (word_sub num_blocks_adjusted (word 0x10))`) THEN - ASM_REWRITE_TAC[] THEN - ARITH_TAC; - ALL_TAC] THEN - DISCH_TAC THEN - POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th])) THEN - - (* Prove x9, x10 stores lower and upper halves and Q8 stores the full tweak *) - TWEAK_TAC `Q8:(armstate,int128)component` `1:num` `0:num` THEN - ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (93--96) THEN - (* Prove the optimized udiv is basically udiv *) - SUBGOAL_THEN `word_ushr - ((word ((val (num_blocks_adjusted:int64) * 0xcccccccccccccccd) DIV 0x2 EXP 0x40)):int64) - 0x6 = word ((val num_blocks_adjusted) DIV 0x50)` ASSUME_TAC THENL - [ MP_TAC (BITBLAST_RULE `val (num_blocks_adjusted:int64) < 2 EXP 64`) THEN - REWRITE_TAC[word_ushr] THEN - MP_TAC (SPECL [`val (num_blocks_adjusted:int64)`] UDIV_OPT_THM) THEN SIMP_TAC[] - ; ALL_TAC] THEN - POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th])) THEN - - (* Eliminate 1 block case *) - ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (97--98) THEN - SUBGOAL_THEN `~(val (num_blocks_adjusted:int64) < 0x20)` ASSUME_TAC THENL - [ UNDISCH_TAC `~(val (num_blocks_adjusted:int64) < 0x50)` THEN ARITH_TAC + CONJ_TAC THENL + [ + (* ===> Symbolic Simulation: Start symbolic simulation*) + ENSURES_INIT_TAC "s0" THEN + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (1--2) THEN + (* Discharge if condition *) + SUBGOAL_THEN + `ival (word_sub (len:int64) (word 0x10)) < &0x0 + <=> ~(ival (len:int64) - &0x10 = ival (word_sub (len:int64) (word 0x10)))` MP_TAC THENL + [ + MP_TAC (BITBLAST_RULE + `val (len:int64) >= 0x10 ==> val len <= 2 EXP 0x18 ==> + ival (word_sub len (word 0x10)) >= &0x0`) THEN + ASM_REWRITE_TAC[] THEN + MP_TAC (BITBLAST_RULE + `val (len:int64) >= 0x10 ==> val len <= 2 EXP 0x18 ==> + ival (len:int64) - &0x10 = ival (word_sub len (word 0x10))`) THEN + ASM_REWRITE_TAC[] THEN + ARITH_TAC; + ALL_TAC] THEN + ASM_REWRITE_TAC[] THEN DISCH_TAC THEN + POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th])) THEN + (* ===> Symbolic Simulation: Symbolic execution for initialization of tweak *) + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (3--69) THEN + (* Prove Q6 stores initial tweak *) + FIRST_X_ASSUM(MP_TAC o SPEC `(calculate_tweak 0 iv key2)` + o MATCH_MP (MESON[] `read Q6 s = a ==> !a'. a = a' ==> read Q6 s = a'`)) THEN + ANTS_TAC THENL + [REWRITE_TAC[CONJUNCT1 calculate_tweak; xts_init_tweak] THEN + EXPAND_TAC "key2" THEN AESENC_TAC; DISCH_TAC] THEN + (* ===> Symbolic Simulation: Symbolic simulating untill next branch *) + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (70--89) THEN + (* Case split on whether there is a tail *) + FIRST_X_ASSUM MP_TAC THEN + COND_CASES_TAC THENL + [ + (* If there is no tail *) + DISCH_TAC THEN + (* Prove val tail_len = 0 and num_blocks = num_blocks_adjusted *) + SUBGOAL_THEN `val (tail_len:int64) = 0` ASSUME_TAC THENL + [ UNDISCH_TAC `val (word_and (tail_len:int64) (word 0xf)) = 0x0` THEN + MP_TAC (SPECL [`len:int64`; `tail_len:int64`] TAIL_LEN_BOUND_THM) THEN + ASM_REWRITE_TAC[] THEN + SUBST1_TAC(ARITH_RULE `0xf = 2 EXP 4 - 1`) THEN + REWRITE_TAC[VAL_WORD_AND_MASK_WORD] THEN + NUM_REDUCE_TAC THEN SIMP_TAC[MOD_LT]; ALL_TAC] THEN + SUBGOAL_THEN `num_blocks_adjusted:int64 = num_blocks:int64` ASSUME_TAC THENL + [ UNDISCH_TAC `(if val (tail_len:int64) = 0x0 + then (num_blocks:int64) + else word_sub num_blocks (word 0x10)) = + num_blocks_adjusted` THEN + UNDISCH_TAC `val (tail_len:int64) = 0` THEN + SIMP_TAC[]; ALL_TAC] THEN + (* Prove x9, x10 stores lower and upper halves and Q8 stores the full tweak *) + TWEAK_TAC `Q8:(armstate,int128)component` `1:num` `0:num` THEN + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (90--93) THEN + (* Prove the optimized udiv is basically udiv *) + SUBGOAL_THEN `word_ushr + ((word ((val (num_blocks:int64) * 0xcccccccccccccccd) DIV 0x2 EXP 0x40)):int64) + 0x6 = + word ((val num_blocks) DIV 0x50)` ASSUME_TAC THENL + [ MP_TAC (BITBLAST_RULE `val (num_blocks:int64) < 2 EXP 64`) THEN + REWRITE_TAC[word_ushr] THEN + MP_TAC (SPECL [`val (num_blocks:int64)`] UDIV_OPT_THM) THEN SIMP_TAC[] + ; ALL_TAC] THEN + POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th])) THEN + (* Eliminate 1 block case *) + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (94--95) THEN + SUBGOAL_THEN `~(val (num_blocks:int64) < 0x20)` ASSUME_TAC THENL + [ UNDISCH_TAC `~(val (num_blocks:int64) < 0x60)` THEN ARITH_TAC ; POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th]))] THEN - (* Eliminate 2 blocks case *) - ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (99--100) THEN - SUBGOAL_THEN `~(val (num_blocks_adjusted:int64) < 0x30)` ASSUME_TAC THENL - [ UNDISCH_TAC `~(val (num_blocks_adjusted:int64) < 0x50)` THEN ARITH_TAC + (* Eliminate 2 blocks case *) + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (96--97) THEN + SUBGOAL_THEN `~(val (num_blocks:int64) < 0x30)` ASSUME_TAC THENL + [ UNDISCH_TAC `~(val (num_blocks:int64) < 0x60)` THEN ARITH_TAC ; POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th]))] THEN - (* Eliminate 3 blocks case and prove Q9 stores tweak 2 *) - ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (101--108) THEN - SUBGOAL_THEN `~(val (num_blocks_adjusted:int64) < 0x40)` ASSUME_TAC THENL - [ UNDISCH_TAC `~(val (num_blocks_adjusted:int64) < 0x50)` THEN ARITH_TAC + (* Eliminate 3 blocks case and prove Q9 stores tweak 2 *) + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (98--105) THEN + SUBGOAL_THEN `~(val (num_blocks:int64) < 0x40)` ASSUME_TAC THENL + [ UNDISCH_TAC `~(val (num_blocks:int64) < 0x60)` THEN ARITH_TAC ; POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th]))] THEN - TWEAK_TAC `Q9:(armstate,int128)component` `2:num` `1:num` THEN - - (* Eliminate 4 blocks case and Q10 stores tweak 3 *) - ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (109--116) THEN - TWEAK_TAC `Q10:(armstate,int128)component` `3:num` `2:num` THEN - - (* Must have 5 blocks, execute until start of loop. Q11 stores tweak 4 *) - ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (117--125) THEN - TWEAK_TAC `Q11:(armstate,int128)component` `4:num` `3:num` THEN - - ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN - REPEAT CONJ_TAC THENL - [ ASM_REWRITE_TAC[byte_list_at]; - REWRITE_TAC[aes256_xts_decrypt] THEN - CONV_TAC (DEPTH_CONV NUM_RED_CONV) THEN - ASM_REWRITE_TAC[byte_list_at] THEN - REWRITE_TAC [VAL_WORD_0] THEN ARITH_TAC; - ASM_REWRITE_TAC[set_key_schedule]] - ; ALL_TAC - ] THEN - - (* Prove the rest of the program *) + TWEAK_TAC `Q9:(armstate,int128)component` `2:num` `1:num` THEN + (* Eliminate 4 blocks case and Q10 stores tweak 3 *) + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (106--113) THEN + SUBGOAL_THEN `~(val (num_blocks:int64) < 0x50)` ASSUME_TAC THENL + [ UNDISCH_TAC `~(val (num_blocks:int64) < 0x60)` THEN ARITH_TAC + ; POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th]))] THEN + TWEAK_TAC `Q10:(armstate,int128)component` `3:num` `2:num` THEN + (* Must have 5 blocks, execute until start of loop. Q11 stores tweak 4 *) + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (114--122) THEN + TWEAK_TAC `Q11:(armstate,int128)component` `4:num` `3:num` THEN + ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN + REPEAT CONJ_TAC THENL + [ + EXPAND_TAC "num_5blocks_adjusted" THEN + EXPAND_TAC "num_blocks_adjusted" THEN + ASM_REWRITE_TAC[]; + ASM_REWRITE_TAC[byte_list_at]; + REWRITE_TAC[aes256_xts_decrypt] THEN + CONV_TAC (DEPTH_CONV NUM_RED_CONV) THEN + ASM_REWRITE_TAC[byte_list_at] THEN + REWRITE_TAC[VAL_WORD_0] THEN ARITH_TAC; + ASM_REWRITE_TAC[set_key_schedule]] + ; ALL_TAC + ] THEN + (* If there is a tail *) + DISCH_TAC THEN + (* Prove ~ tail_len = 0 *) + SUBGOAL_THEN `~(val (tail_len:int64) = 0)` ASSUME_TAC THENL + [ UNDISCH_TAC `~(val (word_and (tail_len:int64) (word 0xf)) = 0x0)` THEN + MP_TAC (SPECL [`len:int64`; `tail_len:int64`] TAIL_LEN_BOUND_THM) THEN + ASM_REWRITE_TAC[] THEN + SUBST1_TAC(ARITH_RULE `0xf = 2 EXP 4 - 1`) THEN + REWRITE_TAC[VAL_WORD_AND_MASK_WORD] THEN + NUM_REDUCE_TAC THEN SIMP_TAC[MOD_LT] + ; ALL_TAC] THEN + (* Prove num_blocks_adjusted = word_sub num_blocks (word 0x10) *) + SUBGOAL_THEN `word_sub num_blocks (word 0x10) = num_blocks_adjusted:int64` ASSUME_TAC THENL + [ UNDISCH_TAC `(if val (tail_len:int64) = 0x0 + then (num_blocks:int64) + else word_sub num_blocks (word 0x10)) = num_blocks_adjusted` THEN + ASM_REWRITE_TAC[]; ALL_TAC] THEN + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (90--92) THEN + (* Discharge if condition *) + SUBGOAL_THEN + `ival (word_sub (num_blocks_adjusted:int64) (word 0x10)) < &0x0 <=> + ~(ival (num_blocks_adjusted:int64) - &0x10 = + ival (word_sub (num_blocks_adjusted:int64) (word 0x10)))` MP_TAC THENL + [ + MP_TAC (BITBLAST_RULE + `~(val (num_blocks_adjusted:int64) < 0x50) ==> + val num_blocks_adjusted <= 2 EXP 0x18 ==> + ival (word_sub num_blocks_adjusted (word 0x10)) >= &0x0`) THEN + ASM_REWRITE_TAC[] THEN + MP_TAC (BITBLAST_RULE + `~(val (num_blocks_adjusted:int64) < 0x50) ==> + val num_blocks_adjusted <= 2 EXP 0x18 ==> + ival (num_blocks_adjusted:int64) - &0x10 = ival (word_sub num_blocks_adjusted (word 0x10))`) THEN + ASM_REWRITE_TAC[] THEN + ARITH_TAC; + ALL_TAC] THEN + DISCH_TAC THEN + POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th])) THEN + (* Prove x9, x10 stores lower and upper halves and Q8 stores the full tweak *) + TWEAK_TAC `Q8:(armstate,int128)component` `1:num` `0:num` THEN + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (93--96) THEN + (* Prove the optimized udiv is basically udiv *) + SUBGOAL_THEN `word_ushr + ((word ((val (num_blocks_adjusted:int64) * 0xcccccccccccccccd) DIV 0x2 EXP 0x40)):int64) + 0x6 = word ((val num_blocks_adjusted) DIV 0x50)` ASSUME_TAC THENL + [ MP_TAC (BITBLAST_RULE `val (num_blocks_adjusted:int64) < 2 EXP 64`) THEN + REWRITE_TAC[word_ushr] THEN + MP_TAC (SPECL [`val (num_blocks_adjusted:int64)`] UDIV_OPT_THM) THEN SIMP_TAC[] + ; ALL_TAC] THEN + POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th])) THEN + (* Eliminate 1 block case *) + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (97--98) THEN + SUBGOAL_THEN `~(val (num_blocks_adjusted:int64) < 0x20)` ASSUME_TAC THENL + [ UNDISCH_TAC `~(val (num_blocks_adjusted:int64) < 0x50)` THEN ARITH_TAC + ; POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th]))] THEN + (* Eliminate 2 blocks case *) + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (99--100) THEN + SUBGOAL_THEN `~(val (num_blocks_adjusted:int64) < 0x30)` ASSUME_TAC THENL + [ UNDISCH_TAC `~(val (num_blocks_adjusted:int64) < 0x50)` THEN ARITH_TAC + ; POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th]))] THEN + (* Eliminate 3 blocks case and prove Q9 stores tweak 2 *) + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (101--108) THEN + SUBGOAL_THEN `~(val (num_blocks_adjusted:int64) < 0x40)` ASSUME_TAC THENL + [ UNDISCH_TAC `~(val (num_blocks_adjusted:int64) < 0x50)` THEN ARITH_TAC + ; POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th]))] THEN + TWEAK_TAC `Q9:(armstate,int128)component` `2:num` `1:num` THEN + (* Eliminate 4 blocks case and Q10 stores tweak 3 *) + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (109--116) THEN + TWEAK_TAC `Q10:(armstate,int128)component` `3:num` `2:num` THEN + (* Must have 5 blocks, execute until start of loop. Q11 stores tweak 4 *) + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (117--125) THEN + TWEAK_TAC `Q11:(armstate,int128)component` `4:num` `3:num` THEN + ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN + REPEAT CONJ_TAC THENL + [ ASM_REWRITE_TAC[byte_list_at]; + REWRITE_TAC[aes256_xts_decrypt] THEN + CONV_TAC (DEPTH_CONV NUM_RED_CONV) THEN + ASM_REWRITE_TAC[byte_list_at] THEN + REWRITE_TAC [VAL_WORD_0] THEN ARITH_TAC; + ASM_REWRITE_TAC[set_key_schedule]] + ; ALL_TAC + ] THEN + + (* Prove property until right before cipher stealing *) + ENSURES_SEQUENCE_TAC `pc + 0xa0c` + `\s. + read X0 s = word_add ct_ptr (word (tail_cases_in_byte num_5blocks_adjusted num_blocks_adjusted)) /\ + read X1 s = word_add pt_ptr (word (tail_cases_in_byte num_5blocks_adjusted num_blocks_adjusted)) /\ + read X3 s = key1_ptr /\ + read X21 s = tail_len /\ + read Q6 s = calculate_tweak (tail_cases_in_index num_5blocks_adjusted num_blocks_adjusted T) iv key2 /\ + read X19 s = word 0x87 /\ + read X10 s = word_subword (calculate_tweak (tail_cases_in_index num_5blocks_adjusted num_blocks_adjusted F) iv key2) (64,64) /\ + read X9 s = word_zx (calculate_tweak (tail_cases_in_index num_5blocks_adjusted num_blocks_adjusted F) iv key2) /\ + byte_list_at ct ct_ptr len s /\ + byte_list_at (aes256_xts_decrypt ct (tail_cases_in_byte num_5blocks_adjusted num_blocks_adjusted) iv key1 key2) + pt_ptr (word (tail_cases_in_byte num_5blocks_adjusted num_blocks_adjusted)) s /\ + set_key_schedule s key1_ptr k00 k01 k02 k03 k04 k05 k06 k07 k08 k09 k0a k0b k0c k0d k0e` THEN + CONJ_TAC THENL + [ (* Setting up the loop invariant *) (* Invariant: @@ -2514,14 +2551,15 @@ let AES_XTS_DECRYPT_CORRECT = prove( read Q18 s = k08 /\ read Q19 s = k09 /\ read Q20 s = k0a /\ read Q21 s = k0b /\ read Q22 s = k0c /\ read Q23 s = k0d /\ read Q7 s = k0e /\ byte_list_at ct ct_ptr len s /\ - byte_list_at (aes256_xts_decrypt ct (80 * i) iv key1 key2) pt_ptr (word (80 * i)) s) /\ + byte_list_at (aes256_xts_decrypt ct (80 * i) iv key1 key2) pt_ptr (word (80 * i)) s /\ + set_key_schedule s key1_ptr k00 k01 k02 k03 k04 k05 k06 k07 k08 k09 k0a k0b k0c k0d k0e) /\ // loop backedge condition (read ZF s <=> i = val (num_5blocks_adjusted:int64))` THEN ASM_REWRITE_TAC[] THEN REPEAT CONJ_TAC THENL [ (* Subgoal 1. Bound of loop is not zero -- automatically discharged by asm *) (* Subgoal 2. Invariant holds before entering the loop *) - REWRITE_TAC[byte_list_at] THEN + REWRITE_TAC[byte_list_at; set_key_schedule] THEN ENSURES_INIT_TAC "s0" THEN ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN REPEAT CONJ_TAC THENL @@ -2566,7 +2604,7 @@ let AES_XTS_DECRYPT_CORRECT = prove( SUBSUMED_MAYCHANGE_TAC; ALL_TAC] THEN (* ===> Symbolic Simulation: Start symbolic simulation*) - ASM_REWRITE_TAC[byte_list_at] THEN + ASM_REWRITE_TAC[byte_list_at; set_key_schedule] THEN ENSURES_INIT_TAC "s0" THEN (* List values for ct_ptr + [0 .. 0x40] *) @@ -2964,7 +3002,7 @@ let AES_XTS_DECRYPT_CORRECT = prove( (* Subgoal 4: prove backedge is taken if i != val num_5blocks_adjusted *) REPEAT STRIP_TAC THEN - REWRITE_TAC[byte_list_at] THEN + REWRITE_TAC[byte_list_at; set_key_schedule] THEN ENSURES_INIT_TAC "s0" THEN ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (1--1) THEN SUBGOAL_THEN `~(val (word_sub (num_5blocks_adjusted:int64) (word i)) = 0x0)` ASSUME_TAC THENL @@ -2976,32 +3014,32 @@ let AES_XTS_DECRYPT_CORRECT = prove( (* Subgoal 5: Prove the invariant implies post-condition Backedge instruction is executed here *) REPEAT STRIP_TAC THEN - REWRITE_TAC[byte_list_at] THEN + REWRITE_TAC[byte_list_at; set_key_schedule] THEN SUBST_ALL_TAC (WORD_RULE `(word (val (num_5blocks_adjusted:int64))):int64 = num_5blocks_adjusted`) THEN MATCH_MP_TAC ENSURES_FRAME_SUBSUMED THEN EXISTS_TAC `MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI ,, MAYCHANGE [X19; X20; X21; X22],, MAYCHANGE [Q8; Q9; Q10; Q11; Q12; Q13; Q14; Q15],, - if val (num_5blocks_adjusted:int64) * 0x50 + 0x40 <= val (len:int64) + if val (num_5blocks_adjusted:int64) * 0x50 + 0x40 = val (num_blocks_adjusted:int64) then MAYCHANGE [memory :> bytes128 (word_add pt_ptr (word (0x50 * val (num_5blocks_adjusted:int64)))); memory :> bytes128 (word_add pt_ptr (word (0x50 * val num_5blocks_adjusted + 0x10))); memory :> bytes128 (word_add pt_ptr (word (0x50 * val num_5blocks_adjusted + 0x20))); memory :> bytes128 (word_add pt_ptr (word (0x50 * val num_5blocks_adjusted + 0x30)))] else - (if val (num_5blocks_adjusted:int64) * 0x50 + 0x30 <= val (len:int64) + (if val (num_5blocks_adjusted:int64) * 0x50 + 0x30 = val (num_blocks_adjusted:int64) then MAYCHANGE [memory :> bytes128 (word_add pt_ptr (word (0x50 * val (num_5blocks_adjusted:int64)))); memory :> bytes128 (word_add pt_ptr (word (0x50 * val num_5blocks_adjusted + 0x10))); memory :> bytes128 (word_add pt_ptr (word (0x50 * val num_5blocks_adjusted + 0x20)))] else - (if val (num_5blocks_adjusted:int64) * 0x50 + 0x20 <= val (len:int64) + (if val (num_5blocks_adjusted:int64) * 0x50 + 0x20 = val (num_blocks_adjusted:int64) then MAYCHANGE [memory :> bytes128 (word_add pt_ptr (word (0x50 * val (num_5blocks_adjusted:int64)))); memory :> bytes128 (word_add pt_ptr (word (0x50 * val num_5blocks_adjusted + 0x10)))] else - (if val (num_5blocks_adjusted:int64) * 0x50 + 0x10 <= val (len:int64) + (if val (num_5blocks_adjusted:int64) * 0x50 + 0x10 = val (num_blocks_adjusted:int64) then MAYCHANGE [memory :> bytes128 (word_add pt_ptr (word (0x50 * val (num_5blocks_adjusted:int64))))] else @@ -3011,16 +3049,24 @@ let AES_XTS_DECRYPT_CORRECT = prove( REPEAT (GEN_REWRITE_TAC ONCE_DEPTH_CONV [GSYM SEQ_ASSOC] THEN MATCH_MP_TAC SUBSUMED_SEQ THEN REWRITE_TAC[SUBSUMED_REFL]) THEN REPEAT COND_CASES_TAC THENL - [ ABBREV_TAC `tmp = val (num_5blocks_adjusted:int64)` THEN + [ SUBGOAL_THEN `0x50 * val (num_5blocks_adjusted:int64) + 0x40 <= val (len:int64)` ASSUME_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC] THEN + ABBREV_TAC `val5blocks = val (num_5blocks_adjusted:int64)` THEN ABBREV_TAC `vallen = val (len:int64)` THEN SUBSUMED_MAYCHANGE_TAC; - ABBREV_TAC `tmp = val (num_5blocks_adjusted:int64)` THEN + SUBGOAL_THEN `0x50 * val (num_5blocks_adjusted:int64) + 0x30 <= val (len:int64)` ASSUME_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC] THEN + ABBREV_TAC `val5blocks = val (num_5blocks_adjusted:int64)` THEN ABBREV_TAC `vallen = val (len:int64)` THEN SUBSUMED_MAYCHANGE_TAC; - ABBREV_TAC `tmp = val (num_5blocks_adjusted:int64)` THEN + SUBGOAL_THEN `0x50 * val (num_5blocks_adjusted:int64) + 0x20 <= val (len:int64)` ASSUME_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC] THEN + ABBREV_TAC `val5blocks = val (num_5blocks_adjusted:int64)` THEN ABBREV_TAC `vallen = val (len:int64)` THEN SUBSUMED_MAYCHANGE_TAC; - ABBREV_TAC `tmp = val (num_5blocks_adjusted:int64)` THEN + SUBGOAL_THEN `0x50 * val (num_5blocks_adjusted:int64) + 0x10 <= val (len:int64)` ASSUME_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC] THEN + ABBREV_TAC `val5blocks = val (num_5blocks_adjusted:int64)` THEN ABBREV_TAC `vallen = val (len:int64)` THEN SUBSUMED_MAYCHANGE_TAC; SUBSUMED_MAYCHANGE_TAC] @@ -3029,29 +3075,30 @@ let AES_XTS_DECRYPT_CORRECT = prove( ENSURES_INIT_TAC "s0" THEN ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (1--3) THEN FIRST_X_ASSUM MP_TAC THEN - COND_CASES_TAC THENL [ (* Case: len % 0x50 = 0x40 *) DISCH_TAC THEN + SUBGOAL_THEN `val (num_5blocks_adjusted:int64) * 0x50 + 0x40 = val (num_blocks_adjusted:int64)` ASSUME_TAC THENL + [ UNDISCH_TAC `val (word_sub + (word_sub (num_blocks_adjusted:int64) + (word_mul (word 0x50) (num_5blocks_adjusted:int64))) + (word 0x40)) = + 0x0` THEN + REWRITE_TAC [VAL_EQ_0; WORD_SUB_EQ_0] THEN + REWRITE_TAC [WORD_RULE `!x:int64. word_mul (word 0x50) x = word(val x * 0x50)`] THEN + REWRITE_TAC[GSYM VAL_EQ] THEN + SUBGOAL_THEN `val (num_5blocks_adjusted:int64) * 0x50 < 2 EXP 64` MP_TAC THENL + [ UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 <= val (num_blocks_adjusted:int64)` THEN + UNDISCH_TAC `val (num_blocks_adjusted:int64) <= 2 EXP 24` THEN + ARITH_TAC; ALL_TAC] THEN + REWRITE_TAC[VAL_WORD_SUB_CASES] THEN + SIMP_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN + UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 <= val (num_blocks_adjusted:int64)` THEN + NUM_REDUCE_TAC THEN ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `val (num_5blocks_adjusted:int64) * 0x50 + 0x40 <= val (len:int64)` ASSUME_TAC THENL - [ SUBGOAL_THEN `val (num_5blocks_adjusted:int64) * 0x50 + 0x40 = val (num_blocks_adjusted:int64)` MP_TAC THENL - [ UNDISCH_TAC `val (word_sub - (word_sub (num_blocks_adjusted:int64) - (word_mul (word 0x50) (num_5blocks_adjusted:int64))) - (word 0x40)) = - 0x0` THEN - REWRITE_TAC [VAL_EQ_0; WORD_SUB_EQ_0] THEN - REWRITE_TAC [WORD_RULE `!x:int64. word_mul (word 0x50) x = word(val x * 0x50)`] THEN - REWRITE_TAC[GSYM VAL_EQ] THEN - SUBGOAL_THEN `val (num_5blocks_adjusted:int64) * 0x50 < 2 EXP 64` MP_TAC THENL - [ UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 <= val (num_blocks_adjusted:int64)` THEN - UNDISCH_TAC `val (num_blocks_adjusted:int64) <= 2 EXP 24` THEN - ARITH_TAC; ALL_TAC] THEN - REWRITE_TAC[VAL_WORD_SUB_CASES] THEN - SIMP_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN - UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 <= val (num_blocks_adjusted:int64)` THEN - NUM_REDUCE_TAC THEN ARITH_TAC; ALL_TAC] THEN + [ UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 + 0x40 = val (num_blocks_adjusted:int64)` THEN UNDISCH_TAC `val (num_blocks_adjusted:int64) <= val (len:int64)` THEN ARITH_TAC; ALL_TAC] THEN MP_TAC (SPECL [`ct_ptr:int64`; `num_5blocks_adjusted:int64`; `len:int64`; `ct:byte list`; `s3:armstate`] READ_CT_TAIL4_LEMMA) THEN @@ -3087,22 +3134,31 @@ let AES_XTS_DECRYPT_CORRECT = prove( [WORD_RULE `word_mul (word 0x50) num_5blocks_adjusted:int64 = word(0x50 * val num_5blocks_adjusted)`]) THEN (* TODO: there is a non-overlapping issue in the symbolic simulation that the third block is missing *) - ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (134--138) THEN - FIRST_X_ASSUM MP_TAC THEN - COND_CASES_TAC THENL + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (134--136) THEN + ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN + REPEAT CONJ_TAC THENL [ - DISCH_TAC THEN - ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN - SUBGOAL_THEN `val (len:int64) = 0x50 * val (num_5blocks_adjusted:int64) + 0x40` ASSUME_TAC THENL - [ CHEAT_TAC; ALL_TAC] THEN - ASM_REWRITE_TAC[] THEN + REWRITE_TAC[tail_cases_in_byte] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; + REWRITE_TAC[tail_cases_in_byte] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; + REWRITE_TAC[tail_cases_in_index] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; + REWRITE_TAC[tail_cases_in_index] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; + REWRITE_TAC[tail_cases_in_index] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; + + REWRITE_TAC[tail_cases_in_byte] THEN ASM_SIMP_TAC[LE_REFL] THEN + SUBGOAL_THEN `val ((word (0x50 * val (num_5blocks_adjusted:int64) + 0x40)):int64) = + 0x50 * val num_5blocks_adjusted + 0x40` ASSUME_TAC THENL + [ IMP_REWRITE_TAC[VAL_WORD; MOD_LT; DIMINDEX_64] THEN + UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 + 0x40 <= val (len:int64)` THEN + UNDISCH_TAC `val (len:int64) <= 0x2 EXP 0x18` THEN + ARITH_TAC; ALL_TAC] THEN + POP_ASSUM(fun th -> REWRITE_TAC[th]) THEN (* TODO: Manually add the assumption as a temporary fix *) SUBGOAL_THEN `read (memory :> bytes128 (word_add (pt_ptr:int64) (word (0x50 * val (num_5blocks_adjusted:int64) + 0x20)))) - s138 = + s136 = aes256_xts_decrypt_round (bytes_to_int128 (SUB_LIST (val num_5blocks_adjusted * 0x50 + 0x20,0x10) ct)) @@ -3117,11 +3173,11 @@ let AES_XTS_DECRYPT_CORRECT = prove( UNDISCH_TAC `forall i. i < 0x50 * val (num_5blocks_adjusted:int64) - ==> read (memory :> bytes8 (word_add pt_ptr (word i))) s138 = + ==> read (memory :> bytes8 (word_add pt_ptr (word i))) s136 = EL i (aes256_xts_decrypt ct (0x50 * val num_5blocks_adjusted) iv key1 key2)` THEN MP_TAC (SPECL [`0x50 * val (num_5blocks_adjusted:int64) + 0x40:num`; `(aes256_xts_decrypt ct (0x50 * val (num_5blocks_adjusted:int64) + 0x40) iv key1 key2):byte list`; - `s138:armstate`] BYTE_LIST_TO_NUM_THM) THEN + `s136:armstate`] BYTE_LIST_TO_NUM_THM) THEN ANTS_TAC THENL[ REWRITE_TAC[ARITH_RULE `0x50 * i + 0x40 = 0x10 * (5 * i + 4)`; LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS] THEN @@ -3130,7 +3186,7 @@ let AES_XTS_DECRYPT_CORRECT = prove( DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN MP_TAC (SPECL [`0x50 * val (num_5blocks_adjusted:int64):num`; `(aes256_xts_decrypt ct (0x50 * val (num_5blocks_adjusted:int64)) iv key1 key2):byte list`; - `s138:armstate`] BYTE_LIST_TO_NUM_THM) THEN + `s136:armstate`] BYTE_LIST_TO_NUM_THM) THEN ANTS_TAC THENL[ REWRITE_TAC[ARITH_RULE `0x50 * i = 0x10 * 5 * i`; LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS] THEN @@ -3378,18 +3434,9 @@ let AES_XTS_DECRYPT_CORRECT = prove( ARITH_RULE `0x50 * i + 0x10 = 0x10 * 5 * i + 0x10`] THEN REWRITE_TAC[SUB_LIST_OF_AES256_XTS_DECRYPT_FULL_BLOCKS] THEN IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN - REWRITE_TAC[LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS] - ]; - ALL_TAC] THEN - - DISCH_TAC THEN - ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (139--147) THEN - TWEAK_TAC `Q8:(armstate,int128)component` `val (num_5blocks_adjusted:int64) * 0x5 + 0x5` `val (num_5blocks_adjusted:int64) * 0x5 + 0x4` THEN - ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (148--148) THEN - CHEAT_TAC - ; - ALL_TAC - ] THEN + REWRITE_TAC[LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS]] + ] + ; ALL_TAC] THEN DISCH_TAC THEN ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (4--5) THEN @@ -3397,30 +3444,44 @@ let AES_XTS_DECRYPT_CORRECT = prove( COND_CASES_TAC THENL [ (* Case: len % 0x50 = 0x30 *) DISCH_TAC THEN - + SUBGOAL_THEN `val (num_5blocks_adjusted:int64) * 0x50 + 0x30 = val (num_blocks_adjusted:int64)` ASSUME_TAC THENL + [ UNDISCH_TAC `val (word_sub + (word_sub (num_blocks_adjusted:int64) + (word_mul (word 0x50) (num_5blocks_adjusted:int64))) + (word 0x30)) = + 0x0` THEN + REWRITE_TAC [VAL_EQ_0; WORD_SUB_EQ_0] THEN + REWRITE_TAC [WORD_RULE `!x:int64. word_mul (word 0x50) x = word(val x * 0x50)`] THEN + REWRITE_TAC[GSYM VAL_EQ] THEN + SUBGOAL_THEN `val (num_5blocks_adjusted:int64) * 0x50 < 2 EXP 64` MP_TAC THENL + [ UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 <= val (num_blocks_adjusted:int64)` THEN + UNDISCH_TAC `val (num_blocks_adjusted:int64) <= 2 EXP 24` THEN + ARITH_TAC; ALL_TAC] THEN + REWRITE_TAC[VAL_WORD_SUB_CASES] THEN + SIMP_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN + UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 <= val (num_blocks_adjusted:int64)` THEN + NUM_REDUCE_TAC THEN ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `~(val (num_5blocks_adjusted:int64) * 0x50 + 0x40 = val (num_blocks_adjusted:int64))` ASSUME_TAC THENL + [ UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 + 0x30 = val (num_blocks_adjusted:int64)` THEN + ARITH_TAC; ALL_TAC] THEN SUBGOAL_THEN `val (num_5blocks_adjusted:int64) * 0x50 + 0x30 <= val (len:int64)` ASSUME_TAC THENL - [ SUBGOAL_THEN `val (num_5blocks_adjusted:int64) * 0x50 + 0x30 = val (num_blocks_adjusted:int64)` MP_TAC THENL - [ UNDISCH_TAC `val (word_sub - (word_sub (num_blocks_adjusted:int64) - (word_mul (word 0x50) (num_5blocks_adjusted:int64))) - (word 0x30)) = - 0x0` THEN - REWRITE_TAC [VAL_EQ_0; WORD_SUB_EQ_0] THEN - REWRITE_TAC [WORD_RULE `!x:int64. word_mul (word 0x50) x = word(val x * 0x50)`] THEN - REWRITE_TAC[GSYM VAL_EQ] THEN - SUBGOAL_THEN `val (num_5blocks_adjusted:int64) * 0x50 < 2 EXP 64` MP_TAC THENL - [ UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 <= val (num_blocks_adjusted:int64)` THEN - UNDISCH_TAC `val (num_blocks_adjusted:int64) <= 2 EXP 24` THEN - ARITH_TAC; ALL_TAC] THEN - REWRITE_TAC[VAL_WORD_SUB_CASES] THEN - SIMP_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN - UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 <= val (num_blocks_adjusted:int64)` THEN - NUM_REDUCE_TAC THEN ARITH_TAC; ALL_TAC] THEN + [ UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 + 0x30 = val (num_blocks_adjusted:int64)` THEN UNDISCH_TAC `val (num_blocks_adjusted:int64) <= val (len:int64)` THEN ARITH_TAC; ALL_TAC] THEN MP_TAC (SPECL [`ct_ptr:int64`; `num_5blocks_adjusted:int64`; `len:int64`; `ct:byte list`; `s5:armstate`] READ_CT_TAIL3_LEMMA) THEN ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN + (* Assumptions that help with reasoning about nonoverlapping + so that the universally quantified assumption stays. + See: https://hol-light.zulipchat.com/#narrow/channel/474190-s2n-bignum/topic/.E2.9C.94.20Symbolic.20simulation.20removed.20assumption/with/541554894 *) + SUBGOAL_THEN `0x50 * (val (num_5blocks_adjusted:int64)) < 0x2 EXP 0x40` ASSUME_TAC THENL + [ UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 <= val (num_blocks_adjusted:int64)` THEN + UNDISCH_TAC `val (num_blocks_adjusted:int64) <= 0x2 EXP 0x18` THEN + ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `val ((word (0x50 * val (num_5blocks_adjusted:int64))):int64) = 0x50 * val num_5blocks_adjusted` ASSUME_TAC THENL [ + IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN ASM_ARITH_TAC; ALL_TAC] THEN + POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th])) THEN + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (6--97) THEN XTSDEC_TAC `Q0:(armstate,int128)component` `val (num_5blocks_adjusted:int64) * 0x50` `val (num_5blocks_adjusted:int64) * 0x5` THEN @@ -3436,142 +3497,718 @@ let AES_XTS_DECRYPT_CORRECT = prove( RULE_ASSUM_TAC(REWRITE_RULE [WORD_RULE `word_mul (word 0x50) num_5blocks_adjusted:int64 = word(0x50 * val num_5blocks_adjusted)`]) THEN - ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (106--110) THEN - FIRST_X_ASSUM MP_TAC THEN - COND_CASES_TAC THENL + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (106--108) THEN + ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN + REPEAT CONJ_TAC THENL [ + REWRITE_TAC[tail_cases_in_byte] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; + REWRITE_TAC[tail_cases_in_byte] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; + REWRITE_TAC[tail_cases_in_index] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; + REWRITE_TAC[tail_cases_in_index] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; + REWRITE_TAC[tail_cases_in_index] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; + + REWRITE_TAC[tail_cases_in_byte] THEN ASM_SIMP_TAC[LE_REFL] THEN + SUBGOAL_THEN `val ((word (0x50 * val (num_5blocks_adjusted:int64) + 0x30)):int64) = + 0x50 * val num_5blocks_adjusted + 0x30` ASSUME_TAC THENL + [ IMP_REWRITE_TAC[VAL_WORD; MOD_LT; DIMINDEX_64] THEN + UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 + 0x30 <= val (len:int64)` THEN + UNDISCH_TAC `val (len:int64) <= 0x2 EXP 0x18` THEN + ARITH_TAC; ALL_TAC] THEN + POP_ASSUM(fun th -> REWRITE_TAC[th]) THEN + + (* Remove quantifier *) + UNDISCH_TAC + `forall i. + i < 0x50 * val (num_5blocks_adjusted:int64) + ==> read (memory :> bytes8 (word_add pt_ptr (word i))) s108 = + EL i (aes256_xts_decrypt ct (0x50 * val num_5blocks_adjusted) iv key1 key2)` THEN + MP_TAC (SPECL [`0x50 * val (num_5blocks_adjusted:int64) + 0x30:num`; + `(aes256_xts_decrypt ct (0x50 * val (num_5blocks_adjusted:int64) + 0x30) iv key1 key2):byte list`; + `s108:armstate`] BYTE_LIST_TO_NUM_THM) THEN + ANTS_TAC THENL[ + REWRITE_TAC[ARITH_RULE `0x50 * i + 0x30 = 0x10 * (5 * i + 3)`; + LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS] THEN + ARITH_TAC + ; ALL_TAC] THEN + DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN + MP_TAC (SPECL [`0x50 * val (num_5blocks_adjusted:int64):num`; + `(aes256_xts_decrypt ct (0x50 * val (num_5blocks_adjusted:int64)) iv key1 key2):byte list`; + `s108:armstate`] BYTE_LIST_TO_NUM_THM) THEN + ANTS_TAC THENL[ + REWRITE_TAC[ARITH_RULE `0x50 * i = 0x10 * 5 * i`; + LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS] THEN + ARITH_TAC + ; ALL_TAC] THEN + DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN DISCH_TAC THEN - ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN - CHEAT_TAC; - ALL_TAC - ] THEN - (* Cipher stealing branch *) - CHEAT_TAC; - ALL_TAC - ] THEN - DISCH_TAC THEN - ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (6--7) THEN - FIRST_X_ASSUM MP_TAC THEN - COND_CASES_TAC THENL - [ (* Case: len % 0x50 = 0x20 *) - DISCH_TAC THEN + IMP_REWRITE_TAC[ARITH_RULE `0x50 * i + 0x30 = (0x50 * i + 0x20) + 0x10`; READ_BYTES_AND_BYTE128_SPLIT] THEN + EXISTS_TAC `(aes256_xts_decrypt ct (0x50 * val (num_5blocks_adjusted:int64) + 0x30) iv key1 key2)` THEN + REPEAT CONJ_TAC THENL [ + MP_TAC (SPECL [`0x5 * val (num_5blocks_adjusted:int64) + 0x3:num`; + `ct:byte list`; `iv:int128`; `key1:int128 list`; + `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN + REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC; GSYM ADD_ASSOC] THEN + CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES]; - SUBGOAL_THEN `val (num_5blocks_adjusted:int64) * 0x50 + 0x20 <= val (len:int64)` ASSUME_TAC THENL - [ SUBGOAL_THEN `val (num_5blocks_adjusted:int64) * 0x50 + 0x20 = val (num_blocks_adjusted:int64)` MP_TAC THENL - [ UNDISCH_TAC `val (word_sub - (word_sub (num_blocks_adjusted:int64) - (word_mul (word 0x50) (num_5blocks_adjusted:int64))) - (word 0x20)) = - 0x0` THEN - REWRITE_TAC [VAL_EQ_0; WORD_SUB_EQ_0] THEN - REWRITE_TAC [WORD_RULE `!x:int64. word_mul (word 0x50) x = word(val x * 0x50)`] THEN - REWRITE_TAC[GSYM VAL_EQ] THEN - SUBGOAL_THEN `val (num_5blocks_adjusted:int64) * 0x50 < 2 EXP 64` MP_TAC THENL - [ UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 <= val (num_blocks_adjusted:int64)` THEN - UNDISCH_TAC `val (num_blocks_adjusted:int64) <= 2 EXP 24` THEN - ARITH_TAC; ALL_TAC] THEN - REWRITE_TAC[VAL_WORD_SUB_CASES] THEN - SIMP_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN - UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 <= val (num_blocks_adjusted:int64)` THEN - NUM_REDUCE_TAC THEN ARITH_TAC; ALL_TAC] THEN - UNDISCH_TAC `val (num_blocks_adjusted:int64) <= val (len:int64)` THEN - ARITH_TAC; ALL_TAC] THEN - MP_TAC (SPECL [`ct_ptr:int64`; `num_5blocks_adjusted:int64`; `len:int64`; `ct:byte list`; `s7:armstate`] READ_CT_TAIL2_LEMMA) THEN - ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN + REWRITE_TAC [ARITH_RULE `(0x50 * i + 0x20) + 0x10 = 0x50 * i + 0x30`] THEN + MP_TAC (SPECL [`0x5 * val (num_5blocks_adjusted:int64) + 0x3:num`; + `ct:byte list`; `iv:int128`; `key1:int128 list`; + `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN + REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC; GSYM ADD_ASSOC] THEN + CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN ARITH_TAC; - ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (8--68) THEN - XTSDEC_TAC `Q0:(armstate,int128)component` - `val (num_5blocks_adjusted:int64) * 0x50` `val (num_5blocks_adjusted:int64) * 0x5` THEN - XTSDEC_TAC `Q1:(armstate,int128)component` - `val (num_5blocks_adjusted:int64) * 0x50 + 0x10` `val (num_5blocks_adjusted:int64) * 0x5 + 0x1` THEN + (* Establish that one xts decrypt round is the same as + selecting one block of bytes from calling the top-level function. *) + REWRITE_TAC[aes256_xts_decrypt] THEN + SIMP_TAC[ARITH_RULE `~(0x50 * i + 0x30 < 0x10)`] THEN + SUBGOAL_THEN `(0x50 * val (num_5blocks_adjusted:int64) + 0x30) MOD 0x10 = 0` SUBST1_TAC THENL + [ REWRITE_TAC[ARITH_RULE `80 * i + 48 = 16 * (5 * i + 3)`] THEN + REWRITE_TAC[MOD_MULT] + ; ALL_TAC] THEN + CONV_TAC (DEPTH_CONV let_CONV) THEN + REWRITE_TAC[SUB_0; ARITH_RULE `(0x50 * i + 0x30) DIV 0x10 = 0x5 * i + 0x3`] THEN + SIMP_TAC[ARITH_RULE `~(0x5 * i + 0x3 < 0x2)`; + ARITH_RULE `(0x5 * i + 0x3) - 0x2 = 0x5 * i + 0x1`; + ARITH_RULE `(0x5 * i + 0x3) - 0x1 = 0x5 * i + 0x2`] THEN - (* The following lemmas are for NONSELFMODIFYING_STATE_UPDATE_TAC when store back to pt_ptr *) - RULE_ASSUM_TAC(REWRITE_RULE - [WORD_RULE `word_mul (word 0x50) num_5blocks_adjusted:int64 = word(0x50 * val num_5blocks_adjusted)`]) THEN + MP_TAC (SPECL [`0`;`5 * val (num_5blocks_adjusted:int64) + 1:num`; + `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + LENGTH_OF_AES256_XTS_DECRYPT_REC) THEN + SIMP_TAC[ARITH_RULE `~(5 * i + 1 < 0)`] THEN + REWRITE_TAC[ARITH_RULE `((0x5 * i + 0x1) - 0x0 + 0x1) * 0x10 = 0x50 * i + 0x20`] THEN + IMP_REWRITE_TAC[SUB_LIST_APPEND_RIGHT_LEMMA] THEN DISCH_TAC THEN - ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (69--77) THEN - TWEAK_TAC `Q6:(armstate,int128)component` `val (num_5blocks_adjusted:int64) * 0x5 + 0x2` `val (num_5blocks_adjusted:int64) * 0x5 + 0x1` THEN + MP_TAC (SPECL [`5 * val (num_5blocks_adjusted:int64) + 2:num`; `0x0:num`; + `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + LENGTH_OF_AES256_XTS_DECRYPT_TAIL) THEN + CONV_TAC NUM_REDUCE_CONV THEN REWRITE_TAC[ADD_0] THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN - ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (78--80) THEN - FIRST_X_ASSUM MP_TAC THEN - COND_CASES_TAC THENL - [ - DISCH_TAC THEN - ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN - CHEAT_TAC; - ALL_TAC - ] THEN - (* Cipher stealing branch *) - CHEAT_TAC; - ALL_TAC] THEN + REWRITE_TAC[AES256_XTS_DECRYPT_TAIL_WHEN_1BLOCK] THEN + ASM_SIMP_TAC[ARITH_RULE `(i * 0x5 + 0x2) * 0x10 = i * 0x50 + 0x20`; + ARITH_RULE `5 * i + 2 = i * 5 + 2`]; - DISCH_TAC THEN - ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (8--9) THEN - FIRST_X_ASSUM MP_TAC THEN - COND_CASES_TAC THENL - [ (* Case: len % 0x50 = 0x10 *) - DISCH_TAC THEN + (* Proving that reading previous bytes is the same as the spec *) + REWRITE_TAC[ARITH_RULE `0x50 * i + 0x20 = 0x10 * (5 * i + 2)`; + ARITH_RULE `0x50 * i + 0x30 = 0x10 * (5 * i + 2) + 0x10`] THEN + REWRITE_TAC[SUB_LIST_OF_AES256_XTS_DECRYPT_FULL_BLOCKS] THEN + ASM_REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC] THEN CONV_TAC NUM_REDUCE_CONV + ] THEN - SUBGOAL_THEN `val (num_5blocks_adjusted:int64) * 0x50 + 0x10 <= val (len:int64)` ASSUME_TAC THENL - [ SUBGOAL_THEN `val (num_5blocks_adjusted:int64) * 0x50 + 0x10 = val (num_blocks_adjusted:int64)` MP_TAC THENL - [ UNDISCH_TAC `val (word_sub - (word_sub (num_blocks_adjusted:int64) - (word_mul (word 0x50) (num_5blocks_adjusted:int64))) - (word 0x10)) = - 0x0` THEN - REWRITE_TAC [VAL_EQ_0; WORD_SUB_EQ_0] THEN - REWRITE_TAC [WORD_RULE `!x:int64. word_mul (word 0x50) x = word(val x * 0x50)`] THEN - REWRITE_TAC[GSYM VAL_EQ] THEN - SUBGOAL_THEN `val (num_5blocks_adjusted:int64) * 0x50 < 2 EXP 64` MP_TAC THENL - [ UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 <= val (num_blocks_adjusted:int64)` THEN - UNDISCH_TAC `val (num_blocks_adjusted:int64) <= 2 EXP 24` THEN - ARITH_TAC; ALL_TAC] THEN - REWRITE_TAC[VAL_WORD_SUB_CASES] THEN - SIMP_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN - UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 <= val (num_blocks_adjusted:int64)` THEN - NUM_REDUCE_TAC THEN ARITH_TAC; ALL_TAC] THEN - UNDISCH_TAC `val (num_blocks_adjusted:int64) <= val (len:int64)` THEN - ARITH_TAC; ALL_TAC] THEN - MP_TAC (SPECL [`ct_ptr:int64`; `num_5blocks_adjusted:int64`; `len:int64`; `ct:byte list`; `s9:armstate`] READ_CT_TAIL1_LEMMA) THEN - ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN + REWRITE_TAC[ARITH_RULE `0x50 * i + 0x20 = (0x50 * i + 0x10) + 0x10`] THEN + (* Use SPECL to force IMP_REWRITE_TAC to apply once once *) + IMP_REWRITE_TAC[(SPECL [`pt_ptr:int64`; `(0x50 * val (num_5blocks_adjusted:int64) + 0x10):num`; + `x:byte list`; `s108:armstate`] READ_BYTES_AND_BYTE128_SPLIT)] THEN + EXISTS_TAC `(aes256_xts_decrypt ct (0x50 * val (num_5blocks_adjusted:int64) + 0x20) iv key1 key2)` THEN + REPEAT CONJ_TAC THENL [ + MP_TAC (SPECL [`0x5 * val (num_5blocks_adjusted:int64) + 0x2:num`; + `ct:byte list`; `iv:int128`; `key1:int128 list`; + `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN + REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC; GSYM ADD_ASSOC] THEN + CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN ARITH_TAC; - ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (10--40) THEN - XTSDEC_TAC `Q0:(armstate,int128)component` - `val (num_5blocks_adjusted:int64) * 0x50` `val (num_5blocks_adjusted:int64) * 0x5` THEN + MP_TAC (SPECL [`0x5 * val (num_5blocks_adjusted:int64) + 0x2:num`; + `ct:byte list`; `iv:int128`; `key1:int128 list`; + `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN + REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC; GSYM ADD_ASSOC] THEN + CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN ARITH_TAC; - (* The following lemmas are for NONSELFMODIFYING_STATE_UPDATE_TAC when store back to pt_ptr *) - RULE_ASSUM_TAC(REWRITE_RULE - [WORD_RULE `word_mul (word 0x50) num_5blocks_adjusted:int64 = word(0x50 * val num_5blocks_adjusted)`]) THEN + (* Establish that one xts decrypt round is the same as + selecting one block of bytes from calling the top-level function. *) + REWRITE_TAC[aes256_xts_decrypt] THEN + SIMP_TAC[ARITH_RULE `~(0x50 * i + 0x20 < 0x10)`] THEN + SUBGOAL_THEN `(0x50 * val (num_5blocks_adjusted:int64) + 0x20) MOD 0x10 = 0` SUBST1_TAC THENL + [ REWRITE_TAC[ARITH_RULE `80 * i + 32 = 16 * (5 * i + 2)`] THEN + REWRITE_TAC[MOD_MULT] + ; ALL_TAC] THEN + CONV_TAC (DEPTH_CONV let_CONV) THEN + REWRITE_TAC[SUB_0; ARITH_RULE `(0x50 * i + 0x20) DIV 0x10 = 0x5 * i + 0x2`] THEN + SIMP_TAC[ARITH_RULE `~(0x5 * i + 0x2 < 0x2)`; + ARITH_RULE `(0x5 * i + 0x2) - 0x2 = 0x5 * i`; + ARITH_RULE `(0x5 * i + 0x2) - 0x1 = 0x5 * i + 0x1`] THEN - ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (41--49) THEN - TWEAK_TAC `Q6:(armstate,int128)component` `val (num_5blocks_adjusted:int64) * 0x5 + 0x1` `val (num_5blocks_adjusted:int64) * 0x5` THEN + MP_TAC (SPECL [`0`;`5 * val (num_5blocks_adjusted:int64):num`; + `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + LENGTH_OF_AES256_XTS_DECRYPT_REC) THEN + SIMP_TAC[ARITH_RULE `~(5 * i < 0)`; + ARITH_RULE `(0x5 * i - 0x0 + 0x1) * 0x10 = 0x50 * i + 0x10`] THEN + IMP_REWRITE_TAC[SUB_LIST_APPEND_RIGHT_LEMMA] THEN DISCH_TAC THEN - ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (50--52) THEN - FIRST_X_ASSUM MP_TAC THEN - COND_CASES_TAC THENL - [ - DISCH_TAC THEN - ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN - CHEAT_TAC; - ALL_TAC - ] THEN - (* Cipher stealing branch *) - CHEAT_TAC; - ALL_TAC] THEN + MP_TAC (SPECL [`5 * val (num_5blocks_adjusted:int64) + 1:num`; `0x0:num`; + `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + LENGTH_OF_AES256_XTS_DECRYPT_TAIL) THEN + CONV_TAC NUM_REDUCE_CONV THEN REWRITE_TAC[ADD_0] THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN - (* Case: len % 0x50 = 0 *) - DISCH_TAC THEN - ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (10--12) THEN - FIRST_X_ASSUM MP_TAC THEN - COND_CASES_TAC THENL - [ - DISCH_TAC THEN - ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN - CHEAT_TAC; - ALL_TAC - ] THEN - (* Cipher stealing branch *) - CHEAT_TAC - ] + REWRITE_TAC[AES256_XTS_DECRYPT_TAIL_WHEN_1BLOCK] THEN + SIMP_TAC[ARITH_RULE `i * 0x50 + 0x10 = (i * 0x5 + 0x1) * 0x10`; + ARITH_RULE `i * 0x5 = 0x5 * i`]; + + (* Proving that reading previous bytes is the same as the spec *) + REWRITE_TAC[ARITH_RULE `0x50 * i + 0x10 = 0x10 * (5 * i + 1)`; + ARITH_RULE `0x50 * i + 0x20 = 0x10 * (5 * i + 1) + 0x10`] THEN + REWRITE_TAC[SUB_LIST_OF_AES256_XTS_DECRYPT_FULL_BLOCKS] THEN + ASM_REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC] THEN CONV_TAC NUM_REDUCE_CONV + ] THEN + + IMP_REWRITE_TAC[(SPECL [`pt_ptr:int64`; `(0x50 * val (num_5blocks_adjusted:int64)):num`; + `(aes256_xts_decrypt ct (0x50 * val (num_5blocks_adjusted:int64) + 0x10) iv key1 key2):byte list`; + `s108:armstate`] + READ_BYTES_AND_BYTE128_SPLIT)] THEN + EXISTS_TAC `ct:byte list` THEN EXISTS_TAC `iv:int128` THEN + EXISTS_TAC `key1:int128 list` THEN EXISTS_TAC `key2:int128 list` THEN + REPEAT CONJ_TAC THENL [ + MP_TAC (SPECL [`0x5 * val (num_5blocks_adjusted:int64) + 0x1:num`; + `ct:byte list`; `iv:int128`; `key1:int128 list`; + `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN + REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC; GSYM ADD_ASSOC] THEN + CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN ARITH_TAC; + + MP_TAC (SPECL [`0x5 * val (num_5blocks_adjusted:int64) + 0x1:num`; + `ct:byte list`; `iv:int128`; `key1:int128 list`; + `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN + REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC; GSYM ADD_ASSOC] THEN + CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN ARITH_TAC; + + (* Establish that one xts decrypt round is the same as + selecting one block of bytes from calling the top-level function. *) + REWRITE_TAC[aes256_xts_decrypt] THEN + SIMP_TAC[ARITH_RULE `~(0x50 * i + 0x10 < 0x10)`] THEN + SUBGOAL_THEN `(0x50 * val (num_5blocks_adjusted:int64) + 0x10) MOD 0x10 = 0` SUBST1_TAC THENL + [ REWRITE_TAC[ARITH_RULE `80 * i + 16 = 16 * (5 * i + 1)`] THEN + REWRITE_TAC[MOD_MULT] + ; ALL_TAC] THEN + CONV_TAC (DEPTH_CONV let_CONV) THEN + REWRITE_TAC[SUB_0; ARITH_RULE `(0x50 * i + 0x10) DIV 0x10 = 0x5 * i + 0x1`] THEN + (* Two cases: i = 0 then execute tail branch, else execute recursion branch *) + COND_CASES_TAC THENL + [ SUBGOAL_THEN `val (num_5blocks_adjusted:int64) = 0` SUBST1_TAC THENL + [ UNDISCH_TAC `5 * val (num_5blocks_adjusted:int64) + 1 < 2` THEN + UNDISCH_TAC `0 < val (num_5blocks_adjusted:int64)` THEN + ARITH_TAC + ; ALL_TAC] THEN CONV_TAC NUM_REDUCE_CONV THEN + + MP_TAC (SPECL [`0x0:num`; `0x0:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + LENGTH_OF_AES256_XTS_DECRYPT_TAIL) THEN + CONV_TAC NUM_REDUCE_CONV THEN REWRITE_TAC[ADD_0] THEN DISCH_TAC THEN + IMP_REWRITE_TAC[(ISPECL [`(aes256_xts_decrypt_tail 0x0 0x0 ct iv key1 key2):byte list`; + `0x10:num`] SUB_LIST_LENGTH_IMPLIES)] THEN + + REWRITE_TAC[AES256_XTS_DECRYPT_TAIL_WHEN_1BLOCK] THEN + CONV_TAC NUM_REDUCE_CONV; + + SIMP_TAC[ARITH_RULE `(0x5 * i + 0x1) - 0x2 = 0x5 * i - 0x1`; + ARITH_RULE `(0x5 * i + 0x1) - 0x1 = 0x5 * i`] THEN + + MP_TAC (SPECL [`0`;`5 * val (num_5blocks_adjusted:int64) - 1:num`; + `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + LENGTH_OF_AES256_XTS_DECRYPT_REC) THEN + SUBGOAL_THEN `~(0x5 * val (num_5blocks_adjusted:int64) - 0x1 < 0x0)` ASSUME_TAC THENL + [ UNDISCH_TAC `~(0x5 * val (num_5blocks_adjusted:int64) + 0x1 < 0x2)` THEN ARITH_TAC; ALL_TAC ] THEN + ASM_SIMP_TAC[] THEN + IMP_REWRITE_TAC[ARITH_RULE `~(0x5 * i + 0x1 < 0x2) ==> (0x5 * i - 1 - 0x0 + 0x1) * 0x10 = 0x50 * i`] THEN + IMP_REWRITE_TAC[SUB_LIST_APPEND_RIGHT_LEMMA] THEN DISCH_TAC THEN + + MP_TAC (SPECL [`5 * val (num_5blocks_adjusted:int64):num`; + `0x0:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + LENGTH_OF_AES256_XTS_DECRYPT_TAIL) THEN + CONV_TAC NUM_REDUCE_CONV THEN REWRITE_TAC[ADD_0] THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN + + REWRITE_TAC[AES256_XTS_DECRYPT_TAIL_WHEN_1BLOCK] THEN + SIMP_TAC[ARITH_RULE `i * 0x50 = (i * 0x5) * 0x10`; + ARITH_RULE `i * 0x5 = 0x5 * i`]]; + + (* Proving that reading previous bytes is the same as the spec *) + REWRITE_TAC[ARITH_RULE `0x50 * i = 0x10 * 5 * i`; + ARITH_RULE `0x50 * i + 0x10 = 0x10 * 5 * i + 0x10`] THEN + REWRITE_TAC[SUB_LIST_OF_AES256_XTS_DECRYPT_FULL_BLOCKS] THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN + REWRITE_TAC[LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS]] + ] + ; ALL_TAC ] THEN + + DISCH_TAC THEN + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (6--7) THEN + FIRST_X_ASSUM MP_TAC THEN + COND_CASES_TAC THENL + [ (* Case: len % 0x50 = 0x20 *) + DISCH_TAC THEN + + SUBGOAL_THEN `val (num_5blocks_adjusted:int64) * 0x50 + 0x20 = val (num_blocks_adjusted:int64)` ASSUME_TAC THENL + [ UNDISCH_TAC `val (word_sub + (word_sub (num_blocks_adjusted:int64) + (word_mul (word 0x50) (num_5blocks_adjusted:int64))) + (word 0x20)) = + 0x0` THEN + REWRITE_TAC [VAL_EQ_0; WORD_SUB_EQ_0] THEN + REWRITE_TAC [WORD_RULE `!x:int64. word_mul (word 0x50) x = word(val x * 0x50)`] THEN + REWRITE_TAC[GSYM VAL_EQ] THEN + SUBGOAL_THEN `val (num_5blocks_adjusted:int64) * 0x50 < 2 EXP 64` MP_TAC THENL + [ UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 <= val (num_blocks_adjusted:int64)` THEN + UNDISCH_TAC `val (num_blocks_adjusted:int64) <= 2 EXP 24` THEN + ARITH_TAC; ALL_TAC] THEN + REWRITE_TAC[VAL_WORD_SUB_CASES] THEN + SIMP_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN + UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 <= val (num_blocks_adjusted:int64)` THEN + NUM_REDUCE_TAC THEN ARITH_TAC; ALL_TAC] THEN + + SUBGOAL_THEN `~(val (num_5blocks_adjusted:int64) * 0x50 + 0x40 = val (num_blocks_adjusted:int64))` ASSUME_TAC THENL + [ UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 + 0x20 = val (num_blocks_adjusted:int64)` THEN + ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `~(val (num_5blocks_adjusted:int64) * 0x50 + 0x30 = val (num_blocks_adjusted:int64))` ASSUME_TAC THENL + [ UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 + 0x20 = val (num_blocks_adjusted:int64)` THEN + ARITH_TAC; ALL_TAC] THEN + + SUBGOAL_THEN `val (num_5blocks_adjusted:int64) * 0x50 + 0x20 <= val (len:int64)` ASSUME_TAC THENL + [ UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 + 0x20 = val (num_blocks_adjusted:int64)` THEN + UNDISCH_TAC `val (num_blocks_adjusted:int64) <= val (len:int64)` THEN + ARITH_TAC; ALL_TAC] THEN + MP_TAC (SPECL [`ct_ptr:int64`; `num_5blocks_adjusted:int64`; `len:int64`; `ct:byte list`; `s7:armstate`] READ_CT_TAIL2_LEMMA) THEN + ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN + + (* Assumptions that help with reasoning about nonoverlapping + so that the universally quantified assumption stays. + See: https://hol-light.zulipchat.com/#narrow/channel/474190-s2n-bignum/topic/.E2.9C.94.20Symbolic.20simulation.20removed.20assumption/with/541554894 *) + SUBGOAL_THEN `0x50 * (val (num_5blocks_adjusted:int64)) < 0x2 EXP 0x40` ASSUME_TAC THENL + [ UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 <= val (num_blocks_adjusted:int64)` THEN + UNDISCH_TAC `val (num_blocks_adjusted:int64) <= 0x2 EXP 0x18` THEN + ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `val ((word (0x50 * val (num_5blocks_adjusted:int64))):int64) = 0x50 * val num_5blocks_adjusted` ASSUME_TAC THENL [ + IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN ASM_ARITH_TAC; ALL_TAC] THEN + POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th])) THEN + + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (8--68) THEN + XTSDEC_TAC `Q0:(armstate,int128)component` + `val (num_5blocks_adjusted:int64) * 0x50` `val (num_5blocks_adjusted:int64) * 0x5` THEN + XTSDEC_TAC `Q1:(armstate,int128)component` + `val (num_5blocks_adjusted:int64) * 0x50 + 0x10` `val (num_5blocks_adjusted:int64) * 0x5 + 0x1` THEN + + (* The following lemmas are for NONSELFMODIFYING_STATE_UPDATE_TAC when store back to pt_ptr *) + RULE_ASSUM_TAC(REWRITE_RULE + [WORD_RULE `word_mul (word 0x50) num_5blocks_adjusted:int64 = word(0x50 * val num_5blocks_adjusted)`]) THEN + + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (69--77) THEN + TWEAK_TAC `Q6:(armstate,int128)component` `val (num_5blocks_adjusted:int64) * 0x5 + 0x2` `val (num_5blocks_adjusted:int64) * 0x5 + 0x1` THEN + + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (78--78) THEN + ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN + REPEAT CONJ_TAC THENL + [ + REWRITE_TAC[tail_cases_in_byte] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; + REWRITE_TAC[tail_cases_in_byte] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; + REWRITE_TAC[tail_cases_in_index] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; + REWRITE_TAC[tail_cases_in_index] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; + REWRITE_TAC[tail_cases_in_index] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; + + REWRITE_TAC[tail_cases_in_byte] THEN ASM_SIMP_TAC[LE_REFL] THEN + SUBGOAL_THEN `val ((word (0x50 * val (num_5blocks_adjusted:int64) + 0x20)):int64) = 0x50 * val num_5blocks_adjusted + 0x20` ASSUME_TAC THENL + [ IMP_REWRITE_TAC[VAL_WORD; MOD_LT; DIMINDEX_64] THEN + UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 + 0x20 <= val (len:int64)` THEN + UNDISCH_TAC `val (len:int64) <= 0x2 EXP 0x18` THEN + ARITH_TAC; ALL_TAC] THEN + POP_ASSUM(fun th -> REWRITE_TAC[th]) THEN + + (* Remove quantifier *) + UNDISCH_TAC + `forall i. + i < 0x50 * val (num_5blocks_adjusted:int64) + ==> read (memory :> bytes8 (word_add pt_ptr (word i))) s78 = + EL i (aes256_xts_decrypt ct (0x50 * val num_5blocks_adjusted) iv key1 key2)` THEN + MP_TAC (SPECL [`0x50 * val (num_5blocks_adjusted:int64) + 0x20:num`; + `(aes256_xts_decrypt ct (0x50 * val (num_5blocks_adjusted:int64) + 0x20) iv key1 key2):byte list`; + `s78:armstate`] BYTE_LIST_TO_NUM_THM) THEN + ANTS_TAC THENL[ + REWRITE_TAC[ARITH_RULE `0x50 * i + 0x20 = 0x10 * (5 * i + 2)`; + LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS] THEN + ARITH_TAC + ; ALL_TAC] THEN + DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN + MP_TAC (SPECL [`0x50 * val (num_5blocks_adjusted:int64):num`; + `(aes256_xts_decrypt ct (0x50 * val (num_5blocks_adjusted:int64)) iv key1 key2):byte list`; + `s78:armstate`] BYTE_LIST_TO_NUM_THM) THEN + ANTS_TAC THENL[ + REWRITE_TAC[ARITH_RULE `0x50 * i = 0x10 * 5 * i`; + LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS] THEN + ARITH_TAC + ; ALL_TAC] THEN + DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN + DISCH_TAC THEN + + REWRITE_TAC[ARITH_RULE `0x50 * i + 0x20 = (0x50 * i + 0x10) + 0x10`] THEN + (* Use SPECL to force IMP_REWRITE_TAC to apply once once *) + IMP_REWRITE_TAC[(SPECL [`pt_ptr:int64`; `(0x50 * val (num_5blocks_adjusted:int64) + 0x10):num`; + `x:byte list`; `s78:armstate`] READ_BYTES_AND_BYTE128_SPLIT)] THEN + EXISTS_TAC `(aes256_xts_decrypt ct (0x50 * val (num_5blocks_adjusted:int64) + 0x20) iv key1 key2)` THEN + REPEAT CONJ_TAC THENL [ + MP_TAC (SPECL [`0x5 * val (num_5blocks_adjusted:int64) + 0x2:num`; + `ct:byte list`; `iv:int128`; `key1:int128 list`; + `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN + REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC; GSYM ADD_ASSOC] THEN + CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN ARITH_TAC; + + MP_TAC (SPECL [`0x5 * val (num_5blocks_adjusted:int64) + 0x2:num`; + `ct:byte list`; `iv:int128`; `key1:int128 list`; + `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN + REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC; GSYM ADD_ASSOC] THEN + CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN ARITH_TAC; + + (* Establish that one xts decrypt round is the same as + selecting one block of bytes from calling the top-level function. *) + REWRITE_TAC[aes256_xts_decrypt] THEN + SIMP_TAC[ARITH_RULE `~(0x50 * i + 0x20 < 0x10)`] THEN + SUBGOAL_THEN `(0x50 * val (num_5blocks_adjusted:int64) + 0x20) MOD 0x10 = 0` SUBST1_TAC THENL + [ REWRITE_TAC[ARITH_RULE `80 * i + 32 = 16 * (5 * i + 2)`] THEN + REWRITE_TAC[MOD_MULT] + ; ALL_TAC] THEN + CONV_TAC (DEPTH_CONV let_CONV) THEN + REWRITE_TAC[SUB_0; ARITH_RULE `(0x50 * i + 0x20) DIV 0x10 = 0x5 * i + 0x2`] THEN + SIMP_TAC[ARITH_RULE `~(0x5 * i + 0x2 < 0x2)`; + ARITH_RULE `(0x5 * i + 0x2) - 0x2 = 0x5 * i`; + ARITH_RULE `(0x5 * i + 0x2) - 0x1 = 0x5 * i + 0x1`] THEN + + MP_TAC (SPECL [`0`;`5 * val (num_5blocks_adjusted:int64):num`; + `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + LENGTH_OF_AES256_XTS_DECRYPT_REC) THEN + SIMP_TAC[ARITH_RULE `~(5 * i < 0)`; + ARITH_RULE `(0x5 * i - 0x0 + 0x1) * 0x10 = 0x50 * i + 0x10`] THEN + IMP_REWRITE_TAC[SUB_LIST_APPEND_RIGHT_LEMMA] THEN DISCH_TAC THEN + + MP_TAC (SPECL [`5 * val (num_5blocks_adjusted:int64) + 1:num`; `0x0:num`; + `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + LENGTH_OF_AES256_XTS_DECRYPT_TAIL) THEN + CONV_TAC NUM_REDUCE_CONV THEN REWRITE_TAC[ADD_0] THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN + + REWRITE_TAC[AES256_XTS_DECRYPT_TAIL_WHEN_1BLOCK] THEN + SIMP_TAC[ARITH_RULE `i * 0x50 + 0x10 = (i * 0x5 + 0x1) * 0x10`; + ARITH_RULE `i * 0x5 = 0x5 * i`]; + + (* Proving that reading previous bytes is the same as the spec *) + REWRITE_TAC[ARITH_RULE `0x50 * i + 0x10 = 0x10 * (5 * i + 1)`; + ARITH_RULE `0x50 * i + 0x20 = 0x10 * (5 * i + 1) + 0x10`] THEN + REWRITE_TAC[SUB_LIST_OF_AES256_XTS_DECRYPT_FULL_BLOCKS] THEN + ASM_REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC] THEN CONV_TAC NUM_REDUCE_CONV + ] THEN + + IMP_REWRITE_TAC[(SPECL [`pt_ptr:int64`; `(0x50 * val (num_5blocks_adjusted:int64)):num`; + `(aes256_xts_decrypt ct (0x50 * val (num_5blocks_adjusted:int64) + 0x10) iv key1 key2):byte list`; + `s78:armstate`] + READ_BYTES_AND_BYTE128_SPLIT)] THEN + EXISTS_TAC `ct:byte list` THEN EXISTS_TAC `iv:int128` THEN + EXISTS_TAC `key1:int128 list` THEN EXISTS_TAC `key2:int128 list` THEN + REPEAT CONJ_TAC THENL [ + MP_TAC (SPECL [`0x5 * val (num_5blocks_adjusted:int64) + 0x1:num`; + `ct:byte list`; `iv:int128`; `key1:int128 list`; + `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN + REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC; GSYM ADD_ASSOC] THEN + CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN ARITH_TAC; + + MP_TAC (SPECL [`0x5 * val (num_5blocks_adjusted:int64) + 0x1:num`; + `ct:byte list`; `iv:int128`; `key1:int128 list`; + `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN + REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC; GSYM ADD_ASSOC] THEN + CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN ARITH_TAC; + + (* Establish that one xts decrypt round is the same as + selecting one block of bytes from calling the top-level function. *) + REWRITE_TAC[aes256_xts_decrypt] THEN + SIMP_TAC[ARITH_RULE `~(0x50 * i + 0x10 < 0x10)`] THEN + SUBGOAL_THEN `(0x50 * val (num_5blocks_adjusted:int64) + 0x10) MOD 0x10 = 0` SUBST1_TAC THENL + [ REWRITE_TAC[ARITH_RULE `80 * i + 16 = 16 * (5 * i + 1)`] THEN + REWRITE_TAC[MOD_MULT] + ; ALL_TAC] THEN + CONV_TAC (DEPTH_CONV let_CONV) THEN + REWRITE_TAC[SUB_0; ARITH_RULE `(0x50 * i + 0x10) DIV 0x10 = 0x5 * i + 0x1`] THEN + (* Two cases: i = 0 then execute tail branch, else execute recursion branch *) + COND_CASES_TAC THENL + [ SUBGOAL_THEN `val (num_5blocks_adjusted:int64) = 0` SUBST1_TAC THENL + [ UNDISCH_TAC `5 * val (num_5blocks_adjusted:int64) + 1 < 2` THEN + UNDISCH_TAC `0 < val (num_5blocks_adjusted:int64)` THEN + ARITH_TAC + ; ALL_TAC] THEN CONV_TAC NUM_REDUCE_CONV THEN + + MP_TAC (SPECL [`0x0:num`; `0x0:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + LENGTH_OF_AES256_XTS_DECRYPT_TAIL) THEN + CONV_TAC NUM_REDUCE_CONV THEN REWRITE_TAC[ADD_0] THEN DISCH_TAC THEN + IMP_REWRITE_TAC[(ISPECL [`(aes256_xts_decrypt_tail 0x0 0x0 ct iv key1 key2):byte list`; + `0x10:num`] SUB_LIST_LENGTH_IMPLIES)] THEN + + REWRITE_TAC[AES256_XTS_DECRYPT_TAIL_WHEN_1BLOCK] THEN + CONV_TAC NUM_REDUCE_CONV; + + SIMP_TAC[ARITH_RULE `(0x5 * i + 0x1) - 0x2 = 0x5 * i - 0x1`; + ARITH_RULE `(0x5 * i + 0x1) - 0x1 = 0x5 * i`] THEN + + MP_TAC (SPECL [`0`;`5 * val (num_5blocks_adjusted:int64) - 1:num`; + `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + LENGTH_OF_AES256_XTS_DECRYPT_REC) THEN + SUBGOAL_THEN `~(0x5 * val (num_5blocks_adjusted:int64) - 0x1 < 0x0)` ASSUME_TAC THENL + [ UNDISCH_TAC `~(0x5 * val (num_5blocks_adjusted:int64) + 0x1 < 0x2)` THEN ARITH_TAC; ALL_TAC ] THEN + ASM_SIMP_TAC[] THEN + IMP_REWRITE_TAC[ARITH_RULE `~(0x5 * i + 0x1 < 0x2) ==> (0x5 * i - 1 - 0x0 + 0x1) * 0x10 = 0x50 * i`] THEN + IMP_REWRITE_TAC[SUB_LIST_APPEND_RIGHT_LEMMA] THEN DISCH_TAC THEN + + MP_TAC (SPECL [`5 * val (num_5blocks_adjusted:int64):num`; + `0x0:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + LENGTH_OF_AES256_XTS_DECRYPT_TAIL) THEN + CONV_TAC NUM_REDUCE_CONV THEN REWRITE_TAC[ADD_0] THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN + + REWRITE_TAC[AES256_XTS_DECRYPT_TAIL_WHEN_1BLOCK] THEN + SIMP_TAC[ARITH_RULE `i * 0x50 = (i * 0x5) * 0x10`; + ARITH_RULE `i * 0x5 = 0x5 * i`]]; + + (* Proving that reading previous bytes is the same as the spec *) + REWRITE_TAC[ARITH_RULE `0x50 * i = 0x10 * 5 * i`; + ARITH_RULE `0x50 * i + 0x10 = 0x10 * 5 * i + 0x10`] THEN + REWRITE_TAC[SUB_LIST_OF_AES256_XTS_DECRYPT_FULL_BLOCKS] THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN + REWRITE_TAC[LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS]] + ]; ALL_TAC] THEN + + DISCH_TAC THEN + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (8--9) THEN + FIRST_X_ASSUM MP_TAC THEN + COND_CASES_TAC THENL + [ (* Case: len % 0x50 = 0x10 *) + DISCH_TAC THEN + + SUBGOAL_THEN `val (num_5blocks_adjusted:int64) * 0x50 + 0x10 = val (num_blocks_adjusted:int64)` ASSUME_TAC THENL + [ UNDISCH_TAC `val (word_sub + (word_sub (num_blocks_adjusted:int64) + (word_mul (word 0x50) (num_5blocks_adjusted:int64))) + (word 0x10)) = + 0x0` THEN + REWRITE_TAC [VAL_EQ_0; WORD_SUB_EQ_0] THEN + REWRITE_TAC [WORD_RULE `!x:int64. word_mul (word 0x50) x = word(val x * 0x50)`] THEN + REWRITE_TAC[GSYM VAL_EQ] THEN + SUBGOAL_THEN `val (num_5blocks_adjusted:int64) * 0x50 < 2 EXP 64` MP_TAC THENL + [ UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 <= val (num_blocks_adjusted:int64)` THEN + UNDISCH_TAC `val (num_blocks_adjusted:int64) <= 2 EXP 24` THEN + ARITH_TAC; ALL_TAC] THEN + REWRITE_TAC[VAL_WORD_SUB_CASES] THEN + SIMP_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN + UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 <= val (num_blocks_adjusted:int64)` THEN + NUM_REDUCE_TAC THEN ARITH_TAC; ALL_TAC] THEN + + SUBGOAL_THEN `~(val (num_5blocks_adjusted:int64) * 0x50 + 0x40 = val (num_blocks_adjusted:int64))` ASSUME_TAC THENL + [ UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 + 0x10 = val (num_blocks_adjusted:int64)` THEN + ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `~(val (num_5blocks_adjusted:int64) * 0x50 + 0x30 = val (num_blocks_adjusted:int64))` ASSUME_TAC THENL + [ UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 + 0x10 = val (num_blocks_adjusted:int64)` THEN + ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `~(val (num_5blocks_adjusted:int64) * 0x50 + 0x20 = val (num_blocks_adjusted:int64))` ASSUME_TAC THENL + [ UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 + 0x10 = val (num_blocks_adjusted:int64)` THEN + ARITH_TAC; ALL_TAC] THEN + + SUBGOAL_THEN `val (num_5blocks_adjusted:int64) * 0x50 + 0x10 <= val (len:int64)` ASSUME_TAC THENL + [ UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 + 0x10 = val (num_blocks_adjusted:int64)` THEN + UNDISCH_TAC `val (num_blocks_adjusted:int64) <= val (len:int64)` THEN + ARITH_TAC; ALL_TAC] THEN + MP_TAC (SPECL [`ct_ptr:int64`; `num_5blocks_adjusted:int64`; `len:int64`; `ct:byte list`; `s9:armstate`] READ_CT_TAIL1_LEMMA) THEN + ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN + + (* Assumptions that help with reasoning about nonoverlapping + so that the universally quantified assumption stays. + See: https://hol-light.zulipchat.com/#narrow/channel/474190-s2n-bignum/topic/.E2.9C.94.20Symbolic.20simulation.20removed.20assumption/with/541554894 *) + SUBGOAL_THEN `0x50 * (val (num_5blocks_adjusted:int64)) < 0x2 EXP 0x40` ASSUME_TAC THENL + [ UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 <= val (num_blocks_adjusted:int64)` THEN + UNDISCH_TAC `val (num_blocks_adjusted:int64) <= 0x2 EXP 0x18` THEN + ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `val ((word (0x50 * val (num_5blocks_adjusted:int64))):int64) = 0x50 * val num_5blocks_adjusted` ASSUME_TAC THENL [ + IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN ASM_ARITH_TAC; ALL_TAC] THEN + POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th])) THEN + + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (10--40) THEN + XTSDEC_TAC `Q0:(armstate,int128)component` + `val (num_5blocks_adjusted:int64) * 0x50` `val (num_5blocks_adjusted:int64) * 0x5` THEN + + (* The following lemmas are for NONSELFMODIFYING_STATE_UPDATE_TAC when store back to pt_ptr *) + RULE_ASSUM_TAC(REWRITE_RULE + [WORD_RULE `word_mul (word 0x50) num_5blocks_adjusted:int64 = word(0x50 * val num_5blocks_adjusted)`]) THEN + + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (41--49) THEN + TWEAK_TAC `Q6:(armstate,int128)component` `val (num_5blocks_adjusted:int64) * 0x5 + 0x1` `val (num_5blocks_adjusted:int64) * 0x5` THEN + + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (50--50) THEN + ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN + REPEAT CONJ_TAC THENL + [ + REWRITE_TAC[tail_cases_in_byte] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; + REWRITE_TAC[tail_cases_in_byte] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; + REWRITE_TAC[tail_cases_in_index] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; + REWRITE_TAC[tail_cases_in_index] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; + REWRITE_TAC[tail_cases_in_index] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; + + REWRITE_TAC[tail_cases_in_byte] THEN ASM_SIMP_TAC[LE_REFL] THEN + SUBGOAL_THEN `val ((word (0x50 * val (num_5blocks_adjusted:int64) + 0x10)):int64) = + 0x50 * val num_5blocks_adjusted + 0x10` ASSUME_TAC THENL + [ IMP_REWRITE_TAC[VAL_WORD; MOD_LT; DIMINDEX_64] THEN + UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 + 0x10 <= val (len:int64)` THEN + UNDISCH_TAC `val (len:int64) <= 0x2 EXP 0x18` THEN + ARITH_TAC; ALL_TAC] THEN + POP_ASSUM(fun th -> REWRITE_TAC[th]) THEN + + (* Remove quantifier *) + UNDISCH_TAC + `forall i. + i < 0x50 * val (num_5blocks_adjusted:int64) + ==> read (memory :> bytes8 (word_add pt_ptr (word i))) s50 = + EL i (aes256_xts_decrypt ct (0x50 * val num_5blocks_adjusted) iv key1 key2)` THEN + MP_TAC (SPECL [`0x50 * val (num_5blocks_adjusted:int64) + 0x10:num`; + `(aes256_xts_decrypt ct (0x50 * val (num_5blocks_adjusted:int64) + 0x10) iv key1 key2):byte list`; + `s50:armstate`] BYTE_LIST_TO_NUM_THM) THEN + ANTS_TAC THENL[ + REWRITE_TAC[ARITH_RULE `0x50 * i + 0x10 = 0x10 * (5 * i + 1)`; + LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS] THEN + ARITH_TAC + ; ALL_TAC] THEN + DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN + MP_TAC (SPECL [`0x50 * val (num_5blocks_adjusted:int64):num`; + `(aes256_xts_decrypt ct (0x50 * val (num_5blocks_adjusted:int64)) iv key1 key2):byte list`; + `s50:armstate`] BYTE_LIST_TO_NUM_THM) THEN + ANTS_TAC THENL[ + REWRITE_TAC[ARITH_RULE `0x50 * i = 0x10 * 5 * i`; + LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS] THEN + ARITH_TAC + ; ALL_TAC] THEN + DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN + DISCH_TAC THEN + + IMP_REWRITE_TAC[(SPECL [`pt_ptr:int64`; `(0x50 * val (num_5blocks_adjusted:int64)):num`; + `(aes256_xts_decrypt ct (0x50 * val (num_5blocks_adjusted:int64) + 0x10) iv key1 key2):byte list`; + `s50:armstate`] + READ_BYTES_AND_BYTE128_SPLIT)] THEN + EXISTS_TAC `ct:byte list` THEN EXISTS_TAC `iv:int128` THEN + EXISTS_TAC `key1:int128 list` THEN EXISTS_TAC `key2:int128 list` THEN + REPEAT CONJ_TAC THENL [ + MP_TAC (SPECL [`0x5 * val (num_5blocks_adjusted:int64) + 0x1:num`; + `ct:byte list`; `iv:int128`; `key1:int128 list`; + `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN + REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC; GSYM ADD_ASSOC] THEN + CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN ARITH_TAC; + + MP_TAC (SPECL [`0x5 * val (num_5blocks_adjusted:int64) + 0x1:num`; + `ct:byte list`; `iv:int128`; `key1:int128 list`; + `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN + REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC; GSYM ADD_ASSOC] THEN + CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN ARITH_TAC; + + (* Establish that one xts decrypt round is the same as + selecting one block of bytes from calling the top-level function. *) + REWRITE_TAC[aes256_xts_decrypt] THEN + SIMP_TAC[ARITH_RULE `~(0x50 * i + 0x10 < 0x10)`] THEN + SUBGOAL_THEN `(0x50 * val (num_5blocks_adjusted:int64) + 0x10) MOD 0x10 = 0` SUBST1_TAC THENL + [ REWRITE_TAC[ARITH_RULE `80 * i + 16 = 16 * (5 * i + 1)`] THEN + REWRITE_TAC[MOD_MULT] + ; ALL_TAC] THEN + CONV_TAC (DEPTH_CONV let_CONV) THEN + REWRITE_TAC[SUB_0; ARITH_RULE `(0x50 * i + 0x10) DIV 0x10 = 0x5 * i + 0x1`] THEN + (* Two cases: i = 0 then execute tail branch, else execute recursion branch *) + COND_CASES_TAC THENL + [ SUBGOAL_THEN `val (num_5blocks_adjusted:int64) = 0` SUBST1_TAC THENL + [ UNDISCH_TAC `5 * val (num_5blocks_adjusted:int64) + 1 < 2` THEN + UNDISCH_TAC `0 < val (num_5blocks_adjusted:int64)` THEN + ARITH_TAC + ; ALL_TAC] THEN CONV_TAC NUM_REDUCE_CONV THEN + + MP_TAC (SPECL [`0x0:num`; `0x0:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + LENGTH_OF_AES256_XTS_DECRYPT_TAIL) THEN + CONV_TAC NUM_REDUCE_CONV THEN REWRITE_TAC[ADD_0] THEN DISCH_TAC THEN + IMP_REWRITE_TAC[(ISPECL [`(aes256_xts_decrypt_tail 0x0 0x0 ct iv key1 key2):byte list`; + `0x10:num`] SUB_LIST_LENGTH_IMPLIES)] THEN + + REWRITE_TAC[AES256_XTS_DECRYPT_TAIL_WHEN_1BLOCK] THEN + CONV_TAC NUM_REDUCE_CONV; + + SIMP_TAC[ARITH_RULE `(0x5 * i + 0x1) - 0x2 = 0x5 * i - 0x1`; + ARITH_RULE `(0x5 * i + 0x1) - 0x1 = 0x5 * i`] THEN + + MP_TAC (SPECL [`0`;`5 * val (num_5blocks_adjusted:int64) - 1:num`; + `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + LENGTH_OF_AES256_XTS_DECRYPT_REC) THEN + SUBGOAL_THEN `~(0x5 * val (num_5blocks_adjusted:int64) - 0x1 < 0x0)` ASSUME_TAC THENL + [ UNDISCH_TAC `~(0x5 * val (num_5blocks_adjusted:int64) + 0x1 < 0x2)` THEN ARITH_TAC; ALL_TAC ] THEN + ASM_SIMP_TAC[] THEN + IMP_REWRITE_TAC[ARITH_RULE `~(0x5 * i + 0x1 < 0x2) ==> (0x5 * i - 1 - 0x0 + 0x1) * 0x10 = 0x50 * i`] THEN + IMP_REWRITE_TAC[SUB_LIST_APPEND_RIGHT_LEMMA] THEN DISCH_TAC THEN + + MP_TAC (SPECL [`5 * val (num_5blocks_adjusted:int64):num`; + `0x0:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + LENGTH_OF_AES256_XTS_DECRYPT_TAIL) THEN + CONV_TAC NUM_REDUCE_CONV THEN REWRITE_TAC[ADD_0] THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN + + REWRITE_TAC[AES256_XTS_DECRYPT_TAIL_WHEN_1BLOCK] THEN + SIMP_TAC[ARITH_RULE `i * 0x50 = (i * 0x5) * 0x10`; + ARITH_RULE `i * 0x5 = 0x5 * i`]]; + + (* Proving that reading previous bytes is the same as the spec *) + REWRITE_TAC[ARITH_RULE `0x50 * i = 0x10 * 5 * i`; + ARITH_RULE `0x50 * i + 0x10 = 0x10 * 5 * i + 0x10`] THEN + REWRITE_TAC[SUB_LIST_OF_AES256_XTS_DECRYPT_FULL_BLOCKS] THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN + REWRITE_TAC[LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS]] + ] + ; ALL_TAC] THEN + + (* Case: len % 0x50 = 0 *) + DISCH_TAC THEN + SUBGOAL_THEN `val (num_5blocks_adjusted:int64) * 0x50 = val (num_blocks_adjusted:int64)` ASSUME_TAC THENL + [ SUBGOAL_THEN `~(val (num_blocks_adjusted:int64) - val (num_5blocks_adjusted:int64) * 0x50 - 0x40 = 0)` MP_TAC THENL + [ CHEAT_TAC; ALL_TAC] THEN + SUBGOAL_THEN `~(val (num_blocks_adjusted:int64) - val (num_5blocks_adjusted:int64) * 0x50 - 0x30 = 0)` MP_TAC THENL + [ CHEAT_TAC; ALL_TAC] THEN + SUBGOAL_THEN `~(val (num_blocks_adjusted:int64) - val (num_5blocks_adjusted:int64) * 0x50 - 0x20 = 0)` MP_TAC THENL + [ CHEAT_TAC; ALL_TAC] THEN + SUBGOAL_THEN `~(val (num_blocks_adjusted:int64) - val (num_5blocks_adjusted:int64) * 0x50 - 0x10 = 0)` MP_TAC THENL + [ CHEAT_TAC; ALL_TAC] THEN + SUBGOAL_THEN `val (num_blocks_adjusted:int64) DIV 0x50 = val (num_5blocks_adjusted:int64)` MP_TAC THENL + [ CHEAT_TAC; ALL_TAC] THEN + SIMP_TAC[SPECL [`val (num_blocks_adjusted:int64)`; `val (num_5blocks_adjusted:int64)`] DIVISION_BY_80_LEMMA] + ; ALL_TAC] THEN + + SUBGOAL_THEN `~(val (num_5blocks_adjusted:int64) * 0x50 + 0x40 = val (num_blocks_adjusted:int64))` ASSUME_TAC THENL + [ UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 = val (num_blocks_adjusted:int64)` THEN + ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `~(val (num_5blocks_adjusted:int64) * 0x50 + 0x30 = val (num_blocks_adjusted:int64))` ASSUME_TAC THENL + [ UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 = val (num_blocks_adjusted:int64)` THEN + ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `~(val (num_5blocks_adjusted:int64) * 0x50 + 0x20 = val (num_blocks_adjusted:int64))` ASSUME_TAC THENL + [ UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 = val (num_blocks_adjusted:int64)` THEN + ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `~(val (num_5blocks_adjusted:int64) * 0x50 + 0x10 = val (num_blocks_adjusted:int64))` ASSUME_TAC THENL + [ UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 = val (num_blocks_adjusted:int64)` THEN + ARITH_TAC; ALL_TAC] THEN + + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (10--10) THEN + ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN + REPEAT CONJ_TAC THENL + [ + REWRITE_TAC[tail_cases_in_byte] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; + REWRITE_TAC[tail_cases_in_byte] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; + REWRITE_TAC[tail_cases_in_index] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; + REWRITE_TAC[tail_cases_in_index] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; + REWRITE_TAC[tail_cases_in_index] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; + REWRITE_TAC[tail_cases_in_byte] THEN ASM_SIMP_TAC[LE_REFL] + ] + ] (* End of loop invariant proof *) + ; ALL_TAC] THEN + + (* prove the rest of the program, basically cipher stealing *) + CHEAT_TAC );; From 5e47b52c78a15f007c3a90a9896ac9f19772e3cc Mon Sep 17 00:00:00 2001 From: Yan Peng Date: Wed, 8 Oct 2025 11:51:49 -0700 Subject: [PATCH 046/132] Update the program with respect to AWS-LC PR2734 --- arm/aes-xts/aes_xts_decrypt_armv8.S | 109 ++++-------- arm/proofs/aes_xts_decrypt.ml | 258 ++++++++++++++++++---------- 2 files changed, 205 insertions(+), 162 deletions(-) diff --git a/arm/aes-xts/aes_xts_decrypt_armv8.S b/arm/aes-xts/aes_xts_decrypt_armv8.S index 3ee1ed5a9..2889e65f5 100644 --- a/arm/aes-xts/aes_xts_decrypt_armv8.S +++ b/arm/aes-xts/aes_xts_decrypt_armv8.S @@ -13,15 +13,15 @@ // // Standard ARM ABI: X0 = in, X1 = out, X2 = length, X3 = key1, X4 = key2, X5 = iv, returns X1 // ---------------------------------------------------------------------------- - #include "_internal_s2n_bignum.h" - .arch armv8-a+crypto + .arch armv8-a+crypto S2N_BN_SYM_VISIBILITY_DIRECTIVE(aes_hw_xts_decrypt) S2N_BN_SYM_PRIVACY_DIRECTIVE(aes_hw_xts_decrypt) .text .balign 4 + #define STACK_SIZE_GPRS 32 //2*16 #define STACK_SIZE_VREGS 64 //4*16 #define STACK_SIZE (STACK_SIZE_GPRS + STACK_SIZE_VREGS) @@ -137,7 +137,6 @@ S2N_BN_SYMBOL(aes_hw_xts_decrypt): b.lt .Lxts_dec_done // There is one block and a tail, go directy to cipher-stealing .Lxts_dec_begin: - udiv_by_80(x2, x8) // Number of 5x-unrolled iterations cmp x2, #0x20 @@ -415,52 +414,42 @@ S2N_BN_SYMBOL(aes_hw_xts_decrypt): eor v1.16b,v1.16b,v8.16b eor v24.16b,v24.16b,v9.16b - // First round with v16 aesdr(v0.16b, v16.16b) aesdr(v1.16b, v16.16b) aesdr(v24.16b, v16.16b) - // Second round with v17 aesdr(v0.16b, v17.16b) aesdr(v1.16b, v17.16b) aesdr(v24.16b, v17.16b) - // Third round with v12 aesdr(v0.16b, v12.16b) aesdr(v1.16b, v12.16b) aesdr(v24.16b, v12.16b) - // Fourth round with v13 aesdr(v0.16b, v13.16b) aesdr(v1.16b, v13.16b) aesdr(v24.16b, v13.16b) - // Fifth round with v14 aesdr(v0.16b, v14.16b) aesdr(v1.16b, v14.16b) aesdr(v24.16b, v14.16b) - // Sixth round with v15 aesdr(v0.16b, v15.16b) aesdr(v1.16b, v15.16b) aesdr(v24.16b, v15.16b) - // Seventh round with v4 aesdr(v0.16b, v4.16b) aesdr(v1.16b, v4.16b) aesdr(v24.16b, v4.16b) - // Eighth round with v5 aesdr(v0.16b, v5.16b) aesdr(v1.16b, v5.16b) aesdr(v24.16b, v5.16b) - // 9th round with v18 aesdr(v0.16b, v18.16b) aesdr(v1.16b, v18.16b) aesdr(v24.16b, v18.16b) - // 10th round with v19 aesdr(v0.16b, v19.16b) aesdr(v1.16b, v19.16b) aesdr(v24.16b, v19.16b) @@ -503,43 +492,34 @@ S2N_BN_SYMBOL(aes_hw_xts_decrypt): eor v0.16b,v0.16b,v6.16b eor v1.16b,v1.16b,v8.16b - // First round with v16 aesdr(v0.16b, v16.16b) aesdr(v1.16b, v16.16b) - // Second round with v17 aesdr(v0.16b, v17.16b) aesdr(v1.16b, v17.16b) - // Third round with v12 aesdr(v0.16b, v12.16b) aesdr(v1.16b, v12.16b) - // Fourth round with v13 + aesdr(v0.16b, v13.16b) aesdr(v1.16b, v13.16b) - // Fifth round with v14 aesdr(v0.16b, v14.16b) aesdr(v1.16b, v14.16b) - // Sixth round with v15 aesdr(v0.16b, v15.16b) aesdr(v1.16b, v15.16b) - // Seventh round with v4 aesdr(v0.16b, v4.16b) aesdr(v1.16b, v4.16b) - // Eighth round with v5 aesdr(v0.16b, v5.16b) aesdr(v1.16b, v5.16b) - // 9th round with v18 aesdr(v0.16b, v18.16b) aesdr(v1.16b, v18.16b) - // 10th round with v19 aesdr(v0.16b, v19.16b) aesdr(v1.16b, v19.16b) @@ -572,34 +552,24 @@ S2N_BN_SYMBOL(aes_hw_xts_decrypt): eor v0.16b,v0.16b,v6.16b - // First round with v16 aesdr(v0.16b, v16.16b) - // Second round with v17 aesdr(v0.16b, v17.16b) - // Third round with v12 aesdr(v0.16b, v12.16b) - // Fourth round with v13 aesdr(v0.16b, v13.16b) - // Fifth round with v14 aesdr(v0.16b, v14.16b) - // Sixth round with v15 aesdr(v0.16b, v15.16b) - // Seventh round with v4 aesdr(v0.16b, v4.16b) - // Eighth round with v5 aesdr(v0.16b, v5.16b) - // 9th round with v18 aesdr(v0.16b, v18.16b) - // 10th round with v19 aesdr(v0.16b, v19.16b) aesdr(v0.16b, v20.16b) @@ -634,25 +604,23 @@ S2N_BN_SYMBOL(aes_hw_xts_decrypt): // Decrypt the second to last block .Lxts_dec_1st_done: eor v26.16b,v0.16b,v8.16b - ldr w6,[x3,#240] - ld1 {v0.4s},[x3],#16 - sub w6,w6,#2 - ld1 {v1.4s},[x3],#16 -.Loop_final_2nd_dec: - aesd v26.16b,v0.16b - aesimc v26.16b,v26.16b - ld1 {v0.4s},[x3],#16 // load key schedule... - subs w6,w6,#2 - aesd v26.16b,v1.16b - aesimc v26.16b,v26.16b - ld1 {v1.4s},[x3],#16 // load key schedule... - b.gt .Loop_final_2nd_dec - - aesd v26.16b,v0.16b - aesimc v26.16b,v26.16b - ld1 {v0.4s},[x3] - aesd v26.16b,v1.16b - eor v26.16b,v26.16b,v0.16b + + aesdr(v26.16b, v16.16b) + aesdr(v26.16b, v17.16b) + aesdr(v26.16b, v12.16b) + aesdr(v26.16b, v13.16b) + aesdr(v26.16b, v14.16b) + aesdr(v26.16b, v15.16b) + aesdr(v26.16b, v4.16b) + aesdr(v26.16b, v5.16b) + aesdr(v26.16b, v18.16b) + aesdr(v26.16b, v19.16b) + aesdr(v26.16b, v20.16b) + aesdr(v26.16b, v21.16b) + aesdr(v26.16b, v22.16b) + aesd v26.16b,v23.16b + eor v26.16b,v26.16b,v7.16b + eor v26.16b,v26.16b,v8.16b st1 {v26.16b},[x1] @@ -673,25 +641,22 @@ S2N_BN_SYMBOL(aes_hw_xts_decrypt): eor v26.16b,v26.16b,v6.16b // Decrypt the composite block to get the last second plain text block - ldr w6,[x7,#240] - ld1 {v0.16b},[x7],#16 - sub w6,w6,#2 - ld1 {v1.16b},[x7],#16 -.Loop_final_dec: - aesd v26.16b,v0.16b - aesimc v26.16b,v26.16b - ld1 {v0.4s},[x7],#16 // load key schedule... - subs w6,w6,#2 - aesd v26.16b,v1.16b - aesimc v26.16b,v26.16b - ld1 {v1.4s},[x7],#16 // load key schedule... - b.gt .Loop_final_dec - - aesd v26.16b,v0.16b - aesimc v26.16b,v26.16b - ld1 {v0.4s},[x7] - aesd v26.16b,v1.16b - eor v26.16b,v26.16b,v0.16b + aesdr(v26.16b, v16.16b) + aesdr(v26.16b, v17.16b) + aesdr(v26.16b, v12.16b) + aesdr(v26.16b, v13.16b) + aesdr(v26.16b, v14.16b) + aesdr(v26.16b, v15.16b) + aesdr(v26.16b, v4.16b) + aesdr(v26.16b, v5.16b) + aesdr(v26.16b, v18.16b) + aesdr(v26.16b, v19.16b) + aesdr(v26.16b, v20.16b) + aesdr(v26.16b, v21.16b) + aesdr(v26.16b, v22.16b) + aesd v26.16b,v23.16b + eor v26.16b,v26.16b,v7.16b + eor v26.16b,v26.16b,v6.16b st1 {v26.16b},[x1] @@ -703,4 +668,4 @@ S2N_BN_SYMBOL(aes_hw_xts_decrypt): #if defined(__linux__) && defined(__ELF__) .section .note.GNU-stack, "", %progbits -#endif \ No newline at end of file +#endif diff --git a/arm/proofs/aes_xts_decrypt.ml b/arm/proofs/aes_xts_decrypt.ml index c96e63b47..f01ce2563 100644 --- a/arm/proofs/aes_xts_decrypt.ml +++ b/arm/proofs/aes_xts_decrypt.ml @@ -21,7 +21,7 @@ let aes_xts_decrypt_mc = define_assert_from_elf "aes_xts_decrypt_mc" "arm/aes-xt 0xa90053f3; (* arm_STP X19 X20 SP (Immediate_Offset (iword (&0x0))) *) 0xa9015bf5; (* arm_STP X21 X22 SP (Immediate_Offset (iword (&0x10))) *) 0xf100405f; (* arm_CMP X2 (rvalue (word 0x10)) *) - 0x5400570b; (* arm_BLT (word 0xae0) *) + 0x540059cb; (* arm_BLT (word 0xb38) *) 0xd503201f; (* arm_NOP *) 0xd503201f; (* arm_NOP *) 0xd503201f; (* arm_NOP *) @@ -657,7 +657,7 @@ let aes_xts_decrypt_mc = define_assert_from_elf "aes_xts_decrypt_mc" "arm/aes-xt 0x9eaf0146; (* arm_FMOV_ItoF Q6 X10 0x1 *) 0x14000001; (* arm_B (word 0x4) *) 0xf2400ebf; (* arm_TST X21 (rvalue (word 0xf)) *) - 0x54000780; (* arm_BEQ (word 0xf0) *) + 0x54000a40; (* arm_BEQ (word 0x148) *) 0xaa0303e7; (* arm_MOV X7 X3 *) 0x9e6600c9; (* arm_FMOV_FtoI X9 Q6 0x0 0x40 *) 0x9eae00ca; (* arm_FMOV_FtoI X10 Q6 0x1 0x40 *) @@ -669,23 +669,34 @@ let aes_xts_decrypt_mc = define_assert_from_elf "aes_xts_decrypt_mc" "arm/aes-xt 0x9eaf0148; (* arm_FMOV_ItoF Q8 X10 0x1 *) 0x4cdf7800; (* arm_LDR Q0 X0 (Postimmediate_Offset (word 0x10)) *) 0x6e281c1a; (* arm_EOR_VEC Q26 Q0 Q8 0x80 *) - 0xb940f066; (* arm_LDR W6 X3 (Immediate_Offset (word 0xf0)) *) - 0x4cdf7860; (* arm_LDR Q0 X3 (Postimmediate_Offset (word 0x10)) *) - 0x510008c6; (* arm_SUB W6 W6 (rvalue (word 0x2)) *) - 0x4cdf7861; (* arm_LDR Q1 X3 (Postimmediate_Offset (word 0x10)) *) - 0x4e28581a; (* arm_AESD Q26 Q0 *) + 0x4e285a1a; (* arm_AESD Q26 Q16 *) 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) - 0x4cdf7860; (* arm_LDR Q0 X3 (Postimmediate_Offset (word 0x10)) *) - 0x710008c6; (* arm_SUBS W6 W6 (rvalue (word 0x2)) *) - 0x4e28583a; (* arm_AESD Q26 Q1 *) + 0x4e285a3a; (* arm_AESD Q26 Q17 *) 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) - 0x4cdf7861; (* arm_LDR Q1 X3 (Postimmediate_Offset (word 0x10)) *) - 0x54ffff2c; (* arm_BGT (word 0x1fffe4) *) - 0x4e28581a; (* arm_AESD Q26 Q0 *) + 0x4e28599a; (* arm_AESD Q26 Q12 *) + 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) + 0x4e2859ba; (* arm_AESD Q26 Q13 *) + 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) + 0x4e2859da; (* arm_AESD Q26 Q14 *) + 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) + 0x4e2859fa; (* arm_AESD Q26 Q15 *) + 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) + 0x4e28589a; (* arm_AESD Q26 Q4 *) + 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) + 0x4e2858ba; (* arm_AESD Q26 Q5 *) + 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) + 0x4e285a5a; (* arm_AESD Q26 Q18 *) + 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) + 0x4e285a7a; (* arm_AESD Q26 Q19 *) + 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) + 0x4e285a9a; (* arm_AESD Q26 Q20 *) + 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) + 0x4e285aba; (* arm_AESD Q26 Q21 *) 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) - 0x4c407860; (* arm_LDR Q0 X3 No_Offset *) - 0x4e28583a; (* arm_AESD Q26 Q1 *) - 0x6e201f5a; (* arm_EOR_VEC Q26 Q26 Q0 0x80 *) + 0x4e285ada; (* arm_AESD Q26 Q22 *) + 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) + 0x4e285afa; (* arm_AESD Q26 Q23 *) + 0x6e271f5a; (* arm_EOR_VEC Q26 Q26 Q7 0x80 *) 0x6e281f5a; (* arm_EOR_VEC Q26 Q26 Q8 0x80 *) 0x4c00703a; (* arm_STR Q26 X1 No_Offset *) 0xaa0003f4; (* arm_MOV X20 X0 *) @@ -698,23 +709,34 @@ let aes_xts_decrypt_mc = define_assert_from_elf "aes_xts_decrypt_mc" "arm/aes-xt 0x54ffff6c; (* arm_BGT (word 0x1fffec) *) 0x4c40703a; (* arm_LDR Q26 X1 No_Offset *) 0x6e261f5a; (* arm_EOR_VEC Q26 Q26 Q6 0x80 *) - 0xb940f0e6; (* arm_LDR W6 X7 (Immediate_Offset (word 0xf0)) *) - 0x4cdf70e0; (* arm_LDR Q0 X7 (Postimmediate_Offset (word 0x10)) *) - 0x510008c6; (* arm_SUB W6 W6 (rvalue (word 0x2)) *) - 0x4cdf70e1; (* arm_LDR Q1 X7 (Postimmediate_Offset (word 0x10)) *) - 0x4e28581a; (* arm_AESD Q26 Q0 *) + 0x4e285a1a; (* arm_AESD Q26 Q16 *) 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) - 0x4cdf78e0; (* arm_LDR Q0 X7 (Postimmediate_Offset (word 0x10)) *) - 0x710008c6; (* arm_SUBS W6 W6 (rvalue (word 0x2)) *) - 0x4e28583a; (* arm_AESD Q26 Q1 *) + 0x4e285a3a; (* arm_AESD Q26 Q17 *) 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) - 0x4cdf78e1; (* arm_LDR Q1 X7 (Postimmediate_Offset (word 0x10)) *) - 0x54ffff2c; (* arm_BGT (word 0x1fffe4) *) - 0x4e28581a; (* arm_AESD Q26 Q0 *) + 0x4e28599a; (* arm_AESD Q26 Q12 *) + 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) + 0x4e2859ba; (* arm_AESD Q26 Q13 *) + 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) + 0x4e2859da; (* arm_AESD Q26 Q14 *) 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) - 0x4c4078e0; (* arm_LDR Q0 X7 No_Offset *) - 0x4e28583a; (* arm_AESD Q26 Q1 *) - 0x6e201f5a; (* arm_EOR_VEC Q26 Q26 Q0 0x80 *) + 0x4e2859fa; (* arm_AESD Q26 Q15 *) + 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) + 0x4e28589a; (* arm_AESD Q26 Q4 *) + 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) + 0x4e2858ba; (* arm_AESD Q26 Q5 *) + 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) + 0x4e285a5a; (* arm_AESD Q26 Q18 *) + 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) + 0x4e285a7a; (* arm_AESD Q26 Q19 *) + 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) + 0x4e285a9a; (* arm_AESD Q26 Q20 *) + 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) + 0x4e285aba; (* arm_AESD Q26 Q21 *) + 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) + 0x4e285ada; (* arm_AESD Q26 Q22 *) + 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) + 0x4e285afa; (* arm_AESD Q26 Q23 *) + 0x6e271f5a; (* arm_EOR_VEC Q26 Q26 Q7 0x80 *) 0x6e261f5a; (* arm_EOR_VEC Q26 Q26 Q6 0x80 *) 0x4c00703a; (* arm_STR Q26 X1 No_Offset *) 0x6d4227e8; (* arm_LDP D8 D9 SP (Immediate_Offset (iword (&0x20))) *) @@ -833,8 +855,6 @@ let XTSDEC_TAC reg ind ind_tweak = (calculate_tweak ind_tweak iv key2) key1` in let lemma = subst [reg, `reg:(armstate,int128)component`] `read (reg:(armstate,int128)component) (s:armstate) = a ==> !a'. a = a' ==> read reg s = a'` in - let _ = print_term tm in - let _ = print_term lemma in FIRST_X_ASSUM(MP_TAC o SPEC tm o MATCH_MP (MESON[] lemma)) THEN ANTS_TAC THENL [ EXPAND_TAC "key1" THEN @@ -1843,13 +1863,26 @@ let LENGTH_OF_INT128_TO_BYTES = prove( CONV_TAC NUM_REDUCE_CONV );; +let DIVISION_REMAINDER_CASES = prove + (`!a b. a DIV 80 = b ==> + let r = a MOD 80 in + a = b * 80 + r /\ r < 80`, + REPEAT STRIP_TAC THEN + REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + CONJ_TAC THENL + [ EXPAND_TAC "b" THEN REWRITE_TAC[GSYM DIVISION_SIMP]; + REWRITE_TAC[MOD_LT_EQ] THEN ARITH_TAC]);; + let DIVISION_BY_80_LEMMA = prove( - `!(a:num) b. a DIV 0x50 = b ==> - ~(a - b * 0x50 - 0x10 = 0x0) ==> - ~(a - b * 0x50 - 0x20 = 0x0) ==> - ~(a - b * 0x50 - 0x30 = 0x0) ==> + `!(a:num) b. a DIV 0x50 = b /\ + 0x10 divides a /\ + ~(a - b * 0x50 - 0x10 = 0x0) /\ + ~(a - b * 0x50 - 0x20 = 0x0) /\ + ~(a - b * 0x50 - 0x30 = 0x0) /\ ~(a - b * 0x50 - 0x40 = 0x0) ==> b * 0x50 = a`, + REPEAT STRIP_TAC THEN + REWRITE_TAC[divides] THEN CHEAT_TAC );; @@ -2114,8 +2147,8 @@ let SUB_LIST_OF_AES256_XTS_DECRYPT_FULL_BLOCKS = prove( ASM_ARITH_TAC );; -let tail_cases_in_byte = new_definition -`tail_cases_in_byte (i:int64) (len:int64) : num = +let acc_len = new_definition +`acc_len (i:int64) (len:int64) : num = if val i * 0x50 + 0x40 = val len then 0x50 * val i + 0x40 else if val i * 0x50 + 0x30 = val len then 0x50 * val i + 0x30 @@ -2126,8 +2159,8 @@ let tail_cases_in_byte = new_definition else 0x50 * val i`;; (* For X9 and X10, they stand for i * 0x5 + 4 when number of blocks is divisible by 5 *) -let tail_cases_in_index = new_definition -`tail_cases_in_index (i:int64) (len:int64) (last:bool) : num = +let acc_blocks = new_definition +`acc_blocks (i:int64) (len:int64) (last:bool) : num = if val i * 0x50 + 0x40 = val len then val i * 0x5 + 4 else if val i * 0x50 + 0x30 = val len then val i * 0x5 + 3 @@ -2155,7 +2188,7 @@ let AES_XTS_DECRYPT_CORRECT = prove( read(memory :> bytes128 iv_ptr) s = iv /\ set_key_schedule s key1_ptr k00 k01 k02 k03 k04 k05 k06 k07 k08 k09 k0a k0b k0c k0d k0e /\ set_key_schedule s key2_ptr k10 k11 k12 k13 k14 k15 k16 k17 k18 k19 k1a k1b k1c k1d k1e) - (\s. read PC s = word (pc + 0xb00) /\ + (\s. read PC s = word (pc + 0xb58) /\ byte_list_at (aes256_xts_decrypt ct (val len) iv [k00; k01; k02; k03; k04; k05; k06; k07; k08; k09; k0a; k0b; k0c; k0d; k0e] [k10; k11; k12; k13; k14; k15; k16; k17; k18; k19; k1a; k1b; k1c; k1d; k1e]) @@ -2493,17 +2526,17 @@ let AES_XTS_DECRYPT_CORRECT = prove( (* Prove property until right before cipher stealing *) ENSURES_SEQUENCE_TAC `pc + 0xa0c` `\s. - read X0 s = word_add ct_ptr (word (tail_cases_in_byte num_5blocks_adjusted num_blocks_adjusted)) /\ - read X1 s = word_add pt_ptr (word (tail_cases_in_byte num_5blocks_adjusted num_blocks_adjusted)) /\ + read X0 s = word_add ct_ptr (word (acc_len num_5blocks_adjusted num_blocks_adjusted)) /\ + read X1 s = word_add pt_ptr (word (acc_len num_5blocks_adjusted num_blocks_adjusted)) /\ read X3 s = key1_ptr /\ read X21 s = tail_len /\ - read Q6 s = calculate_tweak (tail_cases_in_index num_5blocks_adjusted num_blocks_adjusted T) iv key2 /\ + read Q6 s = calculate_tweak (acc_blocks num_5blocks_adjusted num_blocks_adjusted T) iv key2 /\ read X19 s = word 0x87 /\ - read X10 s = word_subword (calculate_tweak (tail_cases_in_index num_5blocks_adjusted num_blocks_adjusted F) iv key2) (64,64) /\ - read X9 s = word_zx (calculate_tweak (tail_cases_in_index num_5blocks_adjusted num_blocks_adjusted F) iv key2) /\ + read X10 s = word_subword (calculate_tweak (acc_blocks num_5blocks_adjusted num_blocks_adjusted F) iv key2) (64,64) /\ + read X9 s = word_zx (calculate_tweak (acc_blocks num_5blocks_adjusted num_blocks_adjusted F) iv key2) /\ byte_list_at ct ct_ptr len s /\ - byte_list_at (aes256_xts_decrypt ct (tail_cases_in_byte num_5blocks_adjusted num_blocks_adjusted) iv key1 key2) - pt_ptr (word (tail_cases_in_byte num_5blocks_adjusted num_blocks_adjusted)) s /\ + byte_list_at (aes256_xts_decrypt ct (acc_len num_5blocks_adjusted num_blocks_adjusted) iv key1 key2) + pt_ptr (word (acc_len num_5blocks_adjusted num_blocks_adjusted)) s /\ set_key_schedule s key1_ptr k00 k01 k02 k03 k04 k05 k06 k07 k08 k09 k0a k0b k0c k0d k0e` THEN CONJ_TAC THENL [ @@ -3138,13 +3171,13 @@ let AES_XTS_DECRYPT_CORRECT = prove( ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN REPEAT CONJ_TAC THENL [ - REWRITE_TAC[tail_cases_in_byte] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; - REWRITE_TAC[tail_cases_in_byte] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; - REWRITE_TAC[tail_cases_in_index] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; - REWRITE_TAC[tail_cases_in_index] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; - REWRITE_TAC[tail_cases_in_index] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; + REWRITE_TAC[acc_len] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; + REWRITE_TAC[acc_len] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; + REWRITE_TAC[acc_blocks] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; + REWRITE_TAC[acc_blocks] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; + REWRITE_TAC[acc_blocks] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; - REWRITE_TAC[tail_cases_in_byte] THEN ASM_SIMP_TAC[LE_REFL] THEN + REWRITE_TAC[acc_len] THEN ASM_SIMP_TAC[LE_REFL] THEN SUBGOAL_THEN `val ((word (0x50 * val (num_5blocks_adjusted:int64) + 0x40)):int64) = 0x50 * val num_5blocks_adjusted + 0x40` ASSUME_TAC THENL [ IMP_REWRITE_TAC[VAL_WORD; MOD_LT; DIMINDEX_64] THEN @@ -3501,13 +3534,13 @@ let AES_XTS_DECRYPT_CORRECT = prove( ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN REPEAT CONJ_TAC THENL [ - REWRITE_TAC[tail_cases_in_byte] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; - REWRITE_TAC[tail_cases_in_byte] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; - REWRITE_TAC[tail_cases_in_index] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; - REWRITE_TAC[tail_cases_in_index] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; - REWRITE_TAC[tail_cases_in_index] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; + REWRITE_TAC[acc_len] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; + REWRITE_TAC[acc_len] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; + REWRITE_TAC[acc_blocks] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; + REWRITE_TAC[acc_blocks] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; + REWRITE_TAC[acc_blocks] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; - REWRITE_TAC[tail_cases_in_byte] THEN ASM_SIMP_TAC[LE_REFL] THEN + REWRITE_TAC[acc_len] THEN ASM_SIMP_TAC[LE_REFL] THEN SUBGOAL_THEN `val ((word (0x50 * val (num_5blocks_adjusted:int64) + 0x30)):int64) = 0x50 * val num_5blocks_adjusted + 0x30` ASSUME_TAC THENL [ IMP_REWRITE_TAC[VAL_WORD; MOD_LT; DIMINDEX_64] THEN @@ -3802,13 +3835,13 @@ let AES_XTS_DECRYPT_CORRECT = prove( ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN REPEAT CONJ_TAC THENL [ - REWRITE_TAC[tail_cases_in_byte] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; - REWRITE_TAC[tail_cases_in_byte] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; - REWRITE_TAC[tail_cases_in_index] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; - REWRITE_TAC[tail_cases_in_index] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; - REWRITE_TAC[tail_cases_in_index] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; + REWRITE_TAC[acc_len] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; + REWRITE_TAC[acc_len] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; + REWRITE_TAC[acc_blocks] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; + REWRITE_TAC[acc_blocks] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; + REWRITE_TAC[acc_blocks] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; - REWRITE_TAC[tail_cases_in_byte] THEN ASM_SIMP_TAC[LE_REFL] THEN + REWRITE_TAC[acc_len] THEN ASM_SIMP_TAC[LE_REFL] THEN SUBGOAL_THEN `val ((word (0x50 * val (num_5blocks_adjusted:int64) + 0x20)):int64) = 0x50 * val num_5blocks_adjusted + 0x20` ASSUME_TAC THENL [ IMP_REWRITE_TAC[VAL_WORD; MOD_LT; DIMINDEX_64] THEN UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 + 0x20 <= val (len:int64)` THEN @@ -4046,13 +4079,13 @@ let AES_XTS_DECRYPT_CORRECT = prove( ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN REPEAT CONJ_TAC THENL [ - REWRITE_TAC[tail_cases_in_byte] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; - REWRITE_TAC[tail_cases_in_byte] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; - REWRITE_TAC[tail_cases_in_index] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; - REWRITE_TAC[tail_cases_in_index] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; - REWRITE_TAC[tail_cases_in_index] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; + REWRITE_TAC[acc_len] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; + REWRITE_TAC[acc_len] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; + REWRITE_TAC[acc_blocks] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; + REWRITE_TAC[acc_blocks] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; + REWRITE_TAC[acc_blocks] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; - REWRITE_TAC[tail_cases_in_byte] THEN ASM_SIMP_TAC[LE_REFL] THEN + REWRITE_TAC[acc_len] THEN ASM_SIMP_TAC[LE_REFL] THEN SUBGOAL_THEN `val ((word (0x50 * val (num_5blocks_adjusted:int64) + 0x10)):int64) = 0x50 * val num_5blocks_adjusted + 0x10` ASSUME_TAC THENL [ IMP_REWRITE_TAC[VAL_WORD; MOD_LT; DIMINDEX_64] THEN @@ -4169,17 +4202,16 @@ let AES_XTS_DECRYPT_CORRECT = prove( (* Case: len % 0x50 = 0 *) DISCH_TAC THEN SUBGOAL_THEN `val (num_5blocks_adjusted:int64) * 0x50 = val (num_blocks_adjusted:int64)` ASSUME_TAC THENL - [ SUBGOAL_THEN `~(val (num_blocks_adjusted:int64) - val (num_5blocks_adjusted:int64) * 0x50 - 0x40 = 0)` MP_TAC THENL - [ CHEAT_TAC; ALL_TAC] THEN - SUBGOAL_THEN `~(val (num_blocks_adjusted:int64) - val (num_5blocks_adjusted:int64) * 0x50 - 0x30 = 0)` MP_TAC THENL - [ CHEAT_TAC; ALL_TAC] THEN - SUBGOAL_THEN `~(val (num_blocks_adjusted:int64) - val (num_5blocks_adjusted:int64) * 0x50 - 0x20 = 0)` MP_TAC THENL - [ CHEAT_TAC; ALL_TAC] THEN - SUBGOAL_THEN `~(val (num_blocks_adjusted:int64) - val (num_5blocks_adjusted:int64) * 0x50 - 0x10 = 0)` MP_TAC THENL - [ CHEAT_TAC; ALL_TAC] THEN - SUBGOAL_THEN `val (num_blocks_adjusted:int64) DIV 0x50 = val (num_5blocks_adjusted:int64)` MP_TAC THENL - [ CHEAT_TAC; ALL_TAC] THEN - SIMP_TAC[SPECL [`val (num_blocks_adjusted:int64)`; `val (num_5blocks_adjusted:int64)`] DIVISION_BY_80_LEMMA] + [ MATCH_MP_TAC (SPECL [`val (num_blocks_adjusted:int64)`; `val (num_5blocks_adjusted:int64)`] DIVISION_BY_80_LEMMA) THEN + REPEAT CONJ_TAC THENL + [ + CHEAT_TAC; + CHEAT_TAC; + CHEAT_TAC; + CHEAT_TAC; + CHEAT_TAC; + CHEAT_TAC + ] ; ALL_TAC] THEN SUBGOAL_THEN `~(val (num_5blocks_adjusted:int64) * 0x50 + 0x40 = val (num_blocks_adjusted:int64))` ASSUME_TAC THENL @@ -4199,16 +4231,62 @@ let AES_XTS_DECRYPT_CORRECT = prove( ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN REPEAT CONJ_TAC THENL [ - REWRITE_TAC[tail_cases_in_byte] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; - REWRITE_TAC[tail_cases_in_byte] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; - REWRITE_TAC[tail_cases_in_index] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; - REWRITE_TAC[tail_cases_in_index] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; - REWRITE_TAC[tail_cases_in_index] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; - REWRITE_TAC[tail_cases_in_byte] THEN ASM_SIMP_TAC[LE_REFL] + REWRITE_TAC[acc_len] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; + REWRITE_TAC[acc_len] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; + REWRITE_TAC[acc_blocks] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; + REWRITE_TAC[acc_blocks] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; + REWRITE_TAC[acc_blocks] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; + REWRITE_TAC[acc_len] THEN ASM_SIMP_TAC[LE_REFL] ] ] (* End of loop invariant proof *) ; ALL_TAC] THEN (* prove the rest of the program, basically cipher stealing *) - CHEAT_TAC + REWRITE_TAC[byte_list_at; set_key_schedule] THEN + (* Start symbolic simulation*) + ENSURES_INIT_TAC "s0" THEN + (* Simulate until the first tweak and verify the first tweak equiv the spec *) + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (1--2) THEN + FIRST_X_ASSUM MP_TAC THEN + COND_CASES_TAC THENL + [ (* tail = 0 *) + DISCH_TAC THEN + ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN `val (word (acc_len (num_5blocks_adjusted:int64) (num_blocks_adjusted:int64)):int64) = + acc_len num_5blocks_adjusted num_blocks_adjusted` ASSUME_TAC THENL + [ CHEAT_TAC; ALL_TAC] THEN + POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th])) THEN + (* Prove that acc_len is equal to total len because there is no tail *) + SUBGOAL_THEN `val (len:int64) = + acc_len (num_5blocks_adjusted:int64) (num_blocks_adjusted:int64)` SUBST1_TAC THENL + [ CHEAT_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[]; + ALL_TAC + ] THEN + + (* cipher stealing branch *) + DISCH_TAC THEN + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (1--9) THEN + (* Simplify Q8 *) + FIRST_X_ASSUM(MP_TAC + o SPEC `calculate_tweak ((acc_blocks (num_5blocks_adjusted:int64) (num_blocks_adjusted:int64) T) + 1) (iv:int128) (key2:int128 list)` + o MATCH_MP (MESON[] `read (reg:(armstate,int128)component) (s:armstate) = a ==> !a'. a = a' ==> read reg s = a'`)) THEN + ANTS_TAC THENL + [ CHEAT_TAC; DISCH_TAC] THEN + + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (10--40) THEN + + let tm = subst [`(acc_len (num_5blocks_adjusted:int64) (num_blocks_adjusted:int64)):num`, `ind:num`; + `(acc_blocks (num_5blocks_adjusted:int64) (num_blocks_adjusted:int64) T):num`, `ind_tweak:num`] + `aes256_xts_decrypt_round (bytes_to_int128 (SUB_LIST (ind,0x10) (ct:byte list))) + (calculate_tweak ind_tweak iv key2) key1` in + let lemma = subst [`Q26:(armstate,int128)component`, `reg:(armstate,int128)component`] + `read (reg:(armstate,int128)component) (s:armstate) = a ==> !a'. a = a' ==> read reg s = a'` in + FIRST_X_ASSUM(MP_TAC o SPEC tm o MATCH_MP (MESON[] lemma)) THEN + ANTS_TAC THENL + [ EXPAND_TAC "key1" THEN + CONV_TAC (RAND_CONV ( + REWRITE_CONV [aes256_xts_decrypt_round] THENC + DEPTH_CONV let_CONV)) THEN + AESDEC_TAC; DISCH_TAC ] );; From 66f1ac0408e898e15d27d65f9eba8e336fb658a9 Mon Sep 17 00:00:00 2001 From: Yan Peng Date: Wed, 8 Oct 2025 18:52:44 -0700 Subject: [PATCH 047/132] Finished: verify cipher stealing --- arm/proofs/aes_xts_decrypt.ml | 2264 +++++++++++++++++++++++++++++++-- 1 file changed, 2181 insertions(+), 83 deletions(-) diff --git a/arm/proofs/aes_xts_decrypt.ml b/arm/proofs/aes_xts_decrypt.ml index f01ce2563..aa463f005 100644 --- a/arm/proofs/aes_xts_decrypt.ml +++ b/arm/proofs/aes_xts_decrypt.ml @@ -4,8 +4,8 @@ *) use_file_raise_failure := true;; -arm_print_log := true;; -components_print_log := true;; +arm_print_log := false;; +components_print_log := false;; needs "arm/proofs/base.ml";; loadt "arm/proofs/aes_xts_decrypt_spec.ml";; @@ -1380,6 +1380,23 @@ let READ_CT_TAIL1_LEMMA = prove( REWRITE_TAC[byte_list_at] THEN ASM_SIMP_TAC[] );; +let READ_CT_LAST_LEMMA = prove( + `!ct_ptr (curr_len:num) (len:int64) (ct:byte list) s. + (forall j. j < val len ==> read (memory :> bytes8 (word_add ct_ptr (word j))) s = EL j ct) + /\ curr_len + 0x10 <= val len + /\ LENGTH ct = val len + ==> + read (memory :> bytes128 (word_add ct_ptr (word curr_len))) s = + bytes_to_int128 (SUB_LIST (curr_len, 16) ct) + `, + REPEAT GEN_TAC THEN STRIP_TAC THEN + MP_TAC + (SPECL [`curr_len:num`; `ct:byte list`; `ct_ptr:int64`; `len:int64`; `s:armstate`] + BYTE_LIST_AT_1BLOCKS) THEN + REWRITE_TAC[byte_list_at] THEN ASM_SIMP_TAC[] +);; + + let UDIV_OPT_THM = prove(`!n:num. n < 0x2 EXP 0x40 ==> (word (val ((word ((n * 0xcccccccccccccccd) DIV 0x2 EXP 0x40)):int64) DIV 0x2 EXP 0x6)):int64 = word (n DIV 0x50)`, REPEAT STRIP_TAC THEN @@ -1510,7 +1527,7 @@ let MEMORY_READ_SUBSET_LEMMA = prove );; let BYTE_LIST_AT_SPLIT = prove( - `!len (bl:byte list) s. + `!len (bl:byte list) (pt_ptr:int64) s. SUC len <= LENGTH bl ==> ((forall i. i < SUC len @@ -1535,6 +1552,219 @@ let BYTE_LIST_AT_SPLIT = prove( ] );; +let HD_SUB_LIST_CONS = prove + (`!(h:A) (t:A list) n. 0 < n ==> HD (SUB_LIST (0,n) (CONS h t)) = h`, + REPEAT GEN_TAC THEN STRIP_TAC THEN + MP_TAC(SPEC `n:num` num_CASES) THEN + ASM_SIMP_TAC[ARITH_RULE `0 < n ==> ~(n = 0)`] THEN + DISCH_THEN(X_CHOOSE_THEN `m:num` SUBST_ALL_TAC) THEN + REWRITE_TAC[SUB_LIST_CLAUSES; HD]);; + +let HD_SUB_LIST_CONS_GENERAL = prove( + `!p n (l:A list). p < LENGTH l /\ 0 < n ==> HD (SUB_LIST (p,n) l) = EL p l`, + INDUCT_TAC THENL + [ + GEN_TAC THEN + LIST_INDUCT_TAC THENL + [ + REWRITE_TAC[LENGTH] THEN ARITH_TAC; + REPEAT STRIP_TAC THEN + REWRITE_TAC[EL; HD] THEN + MP_TAC (SPECL [`h:A`; `t:A list`; `n:num`] HD_SUB_LIST_CONS) THEN + ASM_SIMP_TAC[] + ]; ALL_TAC + ] THEN + GEN_TAC THEN + LIST_INDUCT_TAC THENL + [ + REWRITE_TAC[LENGTH] THEN ARITH_TAC; + REPEAT STRIP_TAC THEN + REWRITE_TAC[SUB_LIST_CLAUSES] THEN + REWRITE_TAC[EL; TL] THEN + FIRST_X_ASSUM (fun th -> MATCH_MP_TAC (SPECL [`n:num`; `t:A list`] th)) THEN + ASM_SIMP_TAC[] THEN + UNDISCH_TAC `SUC p < LENGTH (CONS h (t:A list))` THEN + REWRITE_TAC[LENGTH] THEN + ARITH_TAC + ] +);; + +let TL_SUB_LIST_CONS = prove +(`!(h:A) (t:A list) n. 0 < n ==> TL (SUB_LIST (0,n) (CONS h t)) = SUB_LIST (0, n - 1) t`, + REPEAT GEN_TAC THEN STRIP_TAC THEN + MP_TAC(SPEC `n:num` num_CASES) THEN + ASM_SIMP_TAC[ARITH_RULE `0 < n ==> ~(n = 0)`] THEN + DISCH_THEN(X_CHOOSE_THEN `m:num` SUBST_ALL_TAC) THEN + REWRITE_TAC[SUB_LIST_CLAUSES; TL] THEN + REWRITE_TAC[ARITH_RULE `SUC m - 1 = m`]);; + +let TL_SUB_LIST_CONS_GENERAL = prove( + `!p n (l:A list). p < LENGTH l ==> 0 < n + ==> TL (SUB_LIST (p, n) l) = SUB_LIST (p + 1, n - 1) l`, + INDUCT_TAC THENL + [ + GEN_TAC THEN + LIST_INDUCT_TAC THENL + [ + REWRITE_TAC[LENGTH] THEN ARITH_TAC; + CONV_TAC NUM_REDUCE_CONV THEN + REPEAT STRIP_TAC THEN + MP_TAC (SPECL [`h:A`; `t:A list`; `n:num`] TL_SUB_LIST_CONS) THEN + ASM_SIMP_TAC[num_CONV `1`; SUB_LIST_CLAUSES] + ]; ALL_TAC + ] THEN + GEN_TAC THEN + LIST_INDUCT_TAC THENL + [ + REWRITE_TAC[LENGTH] THEN ARITH_TAC; + REPEAT STRIP_TAC THEN + REWRITE_TAC[ARITH_RULE `SUC p + 1 = SUC (p + 1)`] THEN + REWRITE_TAC[SUB_LIST_CLAUSES] THEN + FIRST_X_ASSUM (fun th -> MP_TAC (SPECL [`n:num`; `t:A list`] th)) THEN + SUBGOAL_THEN `p < LENGTH (t:A list)` ASSUME_TAC THENL + [ UNDISCH_TAC `SUC p < LENGTH (CONS h (t:A list))` THEN + REWRITE_TAC[LENGTH] THEN ARITH_TAC + ; ALL_TAC] THEN + ASM_SIMP_TAC[] + ] +);; + +let EL_SUB_LIST_TRIVIAL = prove( + `!i n (l:A list). i < LENGTH l /\ 0 < n ==> EL 0x0 (SUB_LIST (i, n) l) = EL i l`, + REWRITE_TAC[EL] THEN + SIMP_TAC[HD_SUB_LIST_CONS_GENERAL] +);; + +let EL_SUB_LIST = prove( + `!(i:num) n (l:A list). i < n /\ n <= LENGTH l ==> + EL i (SUB_LIST (0, n) l) = EL i l`, + INDUCT_TAC THENL + [ (* i = 0 *) + ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN + LIST_INDUCT_TAC THENL + [ + REPEAT STRIP_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_TRIVIAL] THEN + REWRITE_TAC[LENGTH] THEN + ARITH_TAC; ALL_TAC + ] THEN + REPEAT STRIP_TAC THEN + IMP_REWRITE_TAC[EL; HD; HD_SUB_LIST_CONS]; + ALL_TAC + ] THEN + (* i != 0 *) + ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN + LIST_INDUCT_TAC THENL + [ + REPEAT STRIP_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_TRIVIAL] THEN + REWRITE_TAC[LENGTH] THEN + ARITH_TAC; ALL_TAC + ] THEN + REPEAT STRIP_TAC THEN + REWRITE_TAC[EL; TL] THEN + IMP_REWRITE_TAC[TL_SUB_LIST_CONS] THEN + REPEAT CONJ_TAC THENL + [ ASM_SIMP_TAC[ARITH_RULE `SUC i < n ==> i < n - 1`]; + SUBGOAL_THEN `LENGTH (CONS h (t:A list)) = SUC (LENGTH t)` ASSUME_TAC THENL + [ REWRITE_TAC[LENGTH]; ALL_TAC ] THEN + ASM_ARITH_TAC; + MP_TAC (ARITH_RULE `SUC i < n ==> 0 < n`) THEN + ASM_SIMP_TAC[] + ] +);; + +let EL_SUB_LIST_GENERAL = prove( + `!p (l:A list) i n. i >= p /\ i < p + n /\ p + n <= LENGTH l ==> + EL (i - p) (SUB_LIST (p, n) l) = EL i l`, + INDUCT_TAC THENL + [ IMP_REWRITE_TAC[ADD; SUB_0; EL_SUB_LIST]; + ALL_TAC + ] THEN + LIST_INDUCT_TAC THENL + [ REWRITE_TAC[SUB_LIST_CLAUSES; LENGTH] THEN + REPEAT STRIP_TAC THEN + ASM_ARITH_TAC; + ALL_TAC + ] THEN + REWRITE_TAC[LENGTH] THEN + REPEAT STRIP_TAC THEN + REWRITE_TAC[SUB_LIST_CLAUSES] THEN + SUBGOAL_THEN `EL i (CONS h (t:A list)) = EL (i - 1) t` SUBST1_TAC THENL + [ SUBGOAL_THEN `i = SUC (i - 1)` SUBST1_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC] THEN + REWRITE_TAC[EL; TL] THEN + AP_THM_TAC THEN AP_TERM_TAC THEN + ARITH_TAC; ALL_TAC] THEN + REWRITE_TAC[ARITH_RULE `i - SUC p = i - 1 - p`] THEN + FIRST_X_ASSUM (fun th -> MP_TAC (SPECL [`t:A list`; `(i - 1):num`; `n:num`] th)) THEN + ANTS_TAC THENL [ ASM_ARITH_TAC; ALL_TAC ] THEN + SIMP_TAC[] +);; + +let EL_SUB_LIST_SHIFT = prove( + `!(i:num) p (l:A list) n. 0 < i /\ i < n /\ n <= LENGTH l - p ==> + EL (i - 1) (SUB_LIST (p + 1, n - 1) l) = EL i (SUB_LIST (p, n) l)`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN `EL i (SUB_LIST (p, n) (l:A list)) = EL (SUC (i - 1)) (SUB_LIST (p, SUC (n - 1)) l)` SUBST1_TAC THENL + [ IMP_REWRITE_TAC[ARITH_RULE `0 < i ==> SUC (i - 1) = i`] THEN + ASM_ARITH_TAC; ALL_TAC ] THEN + DISJ_CASES_TAC (ISPEC `l:(A)list` list_CASES) THENL [ + FIRST_X_ASSUM SUBST_ALL_TAC THEN + UNDISCH_TAC `n <= LENGTH ([]:A list) - p` THEN + REWRITE_TAC[LENGTH] THEN + ASM_ARITH_TAC; ALL_TAC + ] THEN + + REPEAT_N 2 (FIRST_X_ASSUM CHOOSE_TAC) THEN + FIRST_X_ASSUM SUBST_ALL_TAC THEN + REWRITE_TAC[EL; TL] THEN + IMP_REWRITE_TAC[TL_SUB_LIST_CONS_GENERAL] THEN + IMP_REWRITE_TAC[ARITH_RULE `0 < n ==> SUC (n - 1) = n`] THEN + ASM_ARITH_TAC + );; + +let BYTE_LIST_AT_SPLIT_BACKWARDS = prove( + `!(pt_ptr:int64) i len curr_len bl s. + 0 <= i ==> i < len ==> len < 16 ==> LENGTH bl >= 16 ==> + (forall j. + j < len - (i + 1) + ==> read (memory :> bytes8 + (word_add (word_add pt_ptr (word (curr_len + 16 + i + 1))) + (word j))) s = + EL j (SUB_LIST (i + 1, len - (i + 1)) bl)) ==> + read (memory :> bytes8 (word_add pt_ptr (word (curr_len + 16 + i)))) s = (EL i bl) ==> + forall j. + j < len - i + ==> read (memory :> bytes8 + (word_add (word_add pt_ptr (word (curr_len + 16 + i))) + (word j))) s = + EL j (SUB_LIST (i, len - i) bl) + `, + REPEAT GEN_TAC THEN + REPEAT STRIP_TAC THEN + ASM_CASES_TAC `j > 0` THENL + [ + FIRST_X_ASSUM(MP_TAC o SPEC `j - 1`) THEN + ANTS_TAC THENL[ ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `(word_add (word_add (pt_ptr:int64) (word (curr_len + 0x10 + i + 0x1))) + (word (j - 0x1))) = (word_add (word_add pt_ptr (word (curr_len + 0x10 + i))) (word j))` SUBST1_TAC THENL + [ REWRITE_TAC[WORD_RULE `word_add (word_add a (word b)) (word c) = word_add a (word (b + c))`] THEN + AP_TERM_TAC THEN AP_TERM_TAC THEN + ASM_ARITH_TAC; ALL_TAC] THEN + SIMP_TAC[] THEN DISCH_TAC THEN + IMP_REWRITE_TAC[ARITH_RULE `len - (i + 1) = len - i - 1`; + EL_SUB_LIST_SHIFT] THEN + ASM_ARITH_TAC; + ALL_TAC + ] THEN + + SUBGOAL_THEN `j = 0` SUBST_ALL_TAC THENL[ASM_ARITH_TAC;ALL_TAC] THEN + REWRITE_TAC[WORD_ADD_0] THEN + ASM_REWRITE_TAC[] THEN + IMP_REWRITE_TAC[EL_SUB_LIST_TRIVIAL] THEN + ASM_ARITH_TAC +);; let MEMORY_READ_BYTES_SUBSET_LEMMA = prove( `!len (bl:byte list) s. @@ -1607,7 +1837,7 @@ let MEMORY_READ_BYTES_SUBSET_LEMMA = prove( );; let BYTE_LIST_TO_NUM_THM = prove( - `!len (bl:byte list) s. + `!len (pt_ptr:int64) (bl:byte list) s. len <= LENGTH bl ==> ((forall i. i < len ==> read (memory :> bytes8 (word_add pt_ptr (word i))) s = EL i bl) <=> @@ -1848,6 +2078,52 @@ let SUB_LIST_APPEND_RIGHT_LEMMA = prove( SIMP_TAC[LENGTH_EQ_NIL] THEN REWRITE_TAC[APPEND]; ASM_SIMP_TAC[APPEND; LENGTH; SUB_LIST_CLAUSES; SUC_INJ]]]);; +let SUB_LIST_APPEND_RIGHT_GENERAL = prove( + `!(x:A list) y n m p. LENGTH x = p ==> n >= p ==> + SUB_LIST (n,m) (APPEND x y) = SUB_LIST (n - p,m) y`, + LIST_INDUCT_TAC THENL + [ + REPEAT GEN_TAC THEN + SIMP_TAC[CONJUNCT1 LENGTH; APPEND; SUB_LIST_CLAUSES] THEN + DISCH_THEN (fun th -> REWRITE_TAC[GSYM th]) THEN + REWRITE_TAC[SUB_0]; + + ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN + INDUCT_TAC THENL + [ + REPEAT STRIP_TAC THEN + SUBGOAL_THEN `p = 0` SUBST_ALL_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN + CONV_TAC NUM_REDUCE_CONV THEN + SUBGOAL_THEN `CONS h t = ([]:A list)` ASSUME_TAC THENL + [ UNDISCH_TAC `LENGTH (CONS h (t:A list)) = 0` THEN + SIMP_TAC[LENGTH_EQ_NIL]; ALL_TAC] THEN + ASM_REWRITE_TAC[] THEN + REWRITE_TAC[APPEND]; + + REPEAT STRIP_TAC THEN + SUBGOAL_THEN `p > 0` ASSUME_TAC THENL + [ UNDISCH_TAC `LENGTH (CONS h (t:A list)) = p` THEN + ASM_REWRITE_TAC[LENGTH] THEN + MP_TAC (SPEC `LENGTH (t:A list)` (ARITH_RULE `!x. SUC x > 0`)) THEN + ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `LENGTH (t:A list) = p - 1` ASSUME_TAC THENL + [ UNDISCH_TAC `LENGTH (CONS h (t:A list)) = p` THEN + ASM_REWRITE_TAC[LENGTH] THEN + MP_TAC (SPECL [`LENGTH (t:A list)`; `p:num`] (ARITH_RULE `!n m. SUC n = m ==> n = m - 1`)) THEN + SIMP_TAC[]; ALL_TAC] THEN + SUBGOAL_THEN `n >= p - 1` ASSUME_TAC THENL + [ MP_TAC (ARITH_RULE `SUC n >= p /\ p > 0 ==> n >= p - 1`) THEN + ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `SUC n - p = n - (p - 1)` ASSUME_TAC THENL + [ MP_TAC (ARITH_RULE `SUC n >= p /\ p > 0 ==> SUC n - p = n - (p - 1)`) THEN + ASM_ARITH_TAC; ALL_TAC] THEN + ASM_REWRITE_TAC[APPEND; LENGTH; SUB_LIST_CLAUSES; SUC_INJ] THEN + FIRST_X_ASSUM (fun th -> MP_TAC (SPECL [`y:A list`; `n:num`; `m:num`; `(p-1):num`] th)) THEN + ASM_SIMP_TAC[] + ] + ] +);; + let SUB_LIST_LENGTH_IMPLIES = prove( `!(l:A list) n. LENGTH l = n ==> SUB_LIST(0,n) l = l`, REPEAT STRIP_TAC THEN @@ -1855,6 +2131,173 @@ let SUB_LIST_LENGTH_IMPLIES = prove( REWRITE_TAC[SUB_LIST_LENGTH] );; +let SUB_LIST_IDEMPOTENT_P = prove( + `!p n (l:(A)list). SUB_LIST (0,n) (SUB_LIST (p,n) l) = SUB_LIST (p,n) l`, + INDUCT_TAC THENL[ + REWRITE_TAC[SUB_LIST_IDEMPOTENT]; + + REPEAT STRIP_TAC THEN + DISJ_CASES_TAC (ISPEC `l:(A)list` list_CASES) THENL [ + ASM_REWRITE_TAC[] THEN REWRITE_TAC[SUB_LIST_CLAUSES]; + ALL_TAC + ] THEN + FIRST_X_ASSUM MP_TAC THEN STRIP_TAC THEN + ASM_REWRITE_TAC[] THEN REWRITE_TAC[SUB_LIST_CLAUSES] THEN + ASM_REWRITE_TAC[] + ]);; + +let SUB_LIST_MIN_RIGHT = prove( + `!p (l:(A)list) (n:num) m. SUB_LIST (0,n) (SUB_LIST (p,m) l) = SUB_LIST (p, MIN n m) l`, + REPEAT STRIP_TAC THEN + ASM_CASES_TAC `(m:num) <= n` THENL [ + FIRST_X_ASSUM MP_TAC THEN REWRITE_TAC[LE_EXISTS] THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[SUB_LIST_SPLIT;ADD_CLAUSES;ARITH_RULE`MIN ((x:num)+y) x = x`] THEN + REWRITE_TAC[SUB_LIST_IDEMPOTENT_P] THEN + GEN_REWRITE_TAC RAND_CONV [GSYM APPEND_NIL] THEN + AP_TERM_TAC THEN MATCH_MP_TAC SUB_LIST_TRIVIAL THEN + REWRITE_TAC[LENGTH_SUB_LIST] THEN ARITH_TAC; ALL_TAC] THEN + + IMP_REWRITE_TAC[ARITH_RULE `~(m <= n) ==> MIN n m = n`] THEN + FIRST_X_ASSUM MP_TAC THEN REWRITE_TAC[NOT_LE;LT_EXISTS] THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[SUB_LIST_SPLIT;ADD_CLAUSES;ARITH_RULE`MIN (x:num) (x+y) = x`] THEN + + MP_TAC (ISPECL [`l:A list`; `p:num`; `n:num`] LENGTH_SUB_LIST) THEN + ASM_CASES_TAC `n <= LENGTH (l:A list) - p` THENL [ + IMP_REWRITE_TAC[ARITH_RULE `!n m. n <= m ==> MIN n m = n`] THEN + DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_APPEND_LEFT] THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN + ARITH_TAC; ALL_TAC + ] THEN + + IMP_REWRITE_TAC[ARITH_RULE `!n m. ~(n <= m) ==> MIN n m = m`] THEN + SUBGOAL_THEN `SUB_LIST (p + n,SUC d) (l:A list) = []` SUBST1_TAC THENL + [ MATCH_MP_TAC SUB_LIST_TRIVIAL THEN + ASM_ARITH_TAC; ALL_TAC] THEN + REWRITE_TAC[APPEND_NIL] THEN + REWRITE_TAC[SUB_LIST_IDEMPOTENT_P] +);; + +let SUB_LIST_MIN_LEFT = prove( + `!q (l:A list) n m. + SUB_LIST (q,n) (SUB_LIST (0,m) l) = SUB_LIST (q, MIN n (m - q)) l`, + REPEAT STRIP_TAC THEN + ASM_CASES_TAC `n <= m - q` THENL [ + IMP_REWRITE_TAC[ARITH_RULE `x <= y ==> MIN x y = x`] THEN + UNDISCH_TAC `n <= m - q` THEN + MAP_EVERY SPEC1_TAC [`n:num`; `l:A list`; `q:num`; `m:num`] THEN + (* Induct over m *) + INDUCT_TAC THENL + [ + REPEAT STRIP_TAC THEN + IMP_REWRITE_TAC[ARITH_RULE `n <= 0 - q ==> n = 0`] THEN + REWRITE_TAC[SUB_LIST_CLAUSES]; + + INDUCT_TAC THENL + [ + REWRITE_TAC[SUB_0] THEN + REPEAT STRIP_TAC THEN + MP_TAC (SPECL [`0:num`; `l:A list`; `n:num`; `SUC m:num`] SUB_LIST_MIN_RIGHT) THEN + IMP_REWRITE_TAC[ARITH_RULE `x <= y ==> MIN x y = x`]; + + LIST_INDUCT_TAC THENL[ + REWRITE_TAC[SUB_LIST_CLAUSES]; + REWRITE_TAC[SUB_LIST_CLAUSES] THEN + REPEAT STRIP_TAC THEN + FIRST_X_ASSUM + (fun th -> MP_TAC + (SPECL [`q:num`; `t:A list`; `n:num`] th)) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN + SIMP_TAC[] + ] + ] + ]; ALL_TAC + ] THEN + + (* Case n > m - q*) + IMP_REWRITE_TAC[ARITH_RULE `~(x <= y) ==> MIN x y = y`] THEN + UNDISCH_TAC `~(n <= m - q)` THEN + MAP_EVERY SPEC1_TAC [`n:num`; `l:A list`; `q:num`; `m:num`] THEN + INDUCT_TAC THENL + [ + REPEAT STRIP_TAC THEN + REWRITE_TAC[ARITH_RULE `0 - q = 0`] THEN + REWRITE_TAC[SUB_LIST_CLAUSES]; + + INDUCT_TAC THENL + [ + REWRITE_TAC[SUB_0] THEN + REPEAT STRIP_TAC THEN + MP_TAC (SPECL [`0:num`; `l:A list`; `n:num`; `SUC m:num`] SUB_LIST_MIN_RIGHT) THEN + IMP_REWRITE_TAC[ARITH_RULE `~(x <= y) ==> MIN x y = y`]; + + LIST_INDUCT_TAC THENL[ + REWRITE_TAC[SUB_LIST_CLAUSES]; + REWRITE_TAC[SUB_LIST_CLAUSES] THEN + REPEAT STRIP_TAC THEN + REWRITE_TAC[ARITH_RULE `SUC m - SUC q = m - q`] THEN + FIRST_X_ASSUM + (fun th -> MP_TAC + (SPECL [`q:num`; `t:A list`; `n:num`] th)) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN + SIMP_TAC[] + ] + ] + ] +);; + +let SUB_LIST_MIN_GENERAL = prove( + `!p q (l:(A)list) (n:num) m. + SUB_LIST (q,n) (SUB_LIST (p,m) l) = SUB_LIST (p + q, MIN n (m - q)) l`, + REPEAT STRIP_TAC THEN + (* Case n <= m - q *) + ASM_CASES_TAC `n <= m - q` THENL [ + IMP_REWRITE_TAC[ARITH_RULE `x <= y ==> MIN x y = x`] THEN + (* Induct over p *) + UNDISCH_TAC `n <= m - q` THEN + MAP_EVERY SPEC1_TAC [`m:num`; `n:num`; `l:A list`; `q:num`; `p:num`] THEN + INDUCT_TAC THENL + [ + REWRITE_TAC[ADD] THEN + REPEAT STRIP_TAC THEN + MP_TAC (SPECL [`q:num`; `l:A list`; `n:num`; `m:num`] SUB_LIST_MIN_LEFT) THEN + IMP_REWRITE_TAC[ARITH_RULE `x <= y ==> MIN x y = x`]; + ALL_TAC + ] THEN + + ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN + LIST_INDUCT_TAC THENL[ + REWRITE_TAC[SUB_LIST_CLAUSES]; + REWRITE_TAC[ARITH_RULE `SUC p + q = SUC (p + q)`] THEN + REWRITE_TAC[SUB_LIST_CLAUSES] THEN + ASM_REWRITE_TAC[] + ]; ALL_TAC + ] THEN + + (* Case n > m - q*) + IMP_REWRITE_TAC[ARITH_RULE `~(x <= y) ==> MIN x y = y`] THEN + UNDISCH_TAC `~(n <= m - q)` THEN + MAP_EVERY SPEC1_TAC [`m:num`; `n:num`; `l:A list`; `q:num`; `p:num`] THEN + INDUCT_TAC THENL + [ + REWRITE_TAC[ADD] THEN + REPEAT STRIP_TAC THEN + MP_TAC (SPECL [`q:num`; `l:A list`; `n:num`; `m:num`] SUB_LIST_MIN_LEFT) THEN + IMP_REWRITE_TAC[ARITH_RULE `~(x <= y) ==> MIN x y = y`]; + ALL_TAC + ] THEN + + ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN + LIST_INDUCT_TAC THENL[ + REWRITE_TAC[SUB_LIST_CLAUSES]; + REWRITE_TAC[ARITH_RULE `SUC p + q = SUC (p + q)`] THEN + REWRITE_TAC[SUB_LIST_CLAUSES] THEN + ASM_REWRITE_TAC[] + ] +);; + let LENGTH_OF_INT128_TO_BYTES = prove( `!x. LENGTH(int128_to_bytes x) = 16`, STRIP_TAC THEN @@ -1863,6 +2306,86 @@ let LENGTH_OF_INT128_TO_BYTES = prove( CONV_TAC NUM_REDUCE_CONV );; +let SUB_LIST_OF_INT128_TO_BYTES = prove( + `!x. SUB_LIST (0, 16) (int128_to_bytes x) = int128_to_bytes x`, + GEN_TAC THEN + MP_TAC (SPEC `x:int128` LENGTH_OF_INT128_TO_BYTES) THEN + DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] +);; + +let ELEM_TAC i = + CONV_TAC (RAND_CONV (REWRITE_CONV [num_CONV i])) THEN + REWRITE_TAC[bytelist_of_num] THEN + REWRITE_TAC[CONS_11] THEN + CONJ_TAC THENL [ + REWRITE_TAC[word_subword] THEN + AP_TERM_TAC THEN + (ARITH_TAC ORELSE + ( ASM_REWRITE_TAC[CONJUNCT1 EXP; DIV_1; DIV_DIV] THEN + CONV_TAC NUM_REDUCE_CONV)); ALL_TAC];; + +let INT128_TO_BYTES_EQ_BYTELIST_OF_NUM = prove( + `!x. int128_to_bytes x = bytelist_of_num 16 (val x)`, + GEN_TAC THEN + REWRITE_TAC[int128_to_bytes] THEN + + MAP_EVERY (fun i -> ELEM_TAC (mk_numeral (num i))) (List.rev (2 -- 16)) THEN + CONV_TAC (RAND_CONV (REWRITE_CONV [num_CONV `1`])) THEN + REWRITE_TAC[bytelist_of_num] THEN + REWRITE_TAC[CONS_11] THEN + REWRITE_TAC[word_subword] THEN + AP_TERM_TAC THEN + ASM_REWRITE_TAC[DIV_DIV] THEN + CONV_TAC NUM_REDUCE_CONV +);; + +let NUM_OF_BYTELIST_OF_INT128_TO_BYTES = prove( + `!x. num_of_bytelist (int128_to_bytes x) = val x`, + GEN_TAC THEN + REWRITE_TAC[INT128_TO_BYTES_EQ_BYTELIST_OF_NUM] THEN + REWRITE_TAC[NUM_OF_BYTELIST_OF_NUM] THEN + SUBGOAL_THEN `val (x:int128) < 2 EXP 128` ASSUME_TAC THENL + [ MP_TAC (ISPEC `x:int128` VAL_BOUND) THEN + REWRITE_TAC[DIMINDEX_128] THEN + ARITH_TAC; ALL_TAC + ] THEN + IMP_REWRITE_TAC[MOD_LT] THEN + ASM_ARITH_TAC +);; + +let BYTES_TO_INT128_OF_INT128_TO_BYTES = prove( + `!x. bytes_to_int128 (int128_to_bytes x) = x`, + GEN_TAC THEN + REWRITE_TAC[int128_to_bytes; bytes_to_int128] THEN + REWRITE_TAC EL_16_8_CLAUSES THEN + BITBLAST_TAC +);; + +let INT128_TO_BYTES_OF_BYTES_TO_INT128 = prove( + `!x. LENGTH x = 16 ==> int128_to_bytes (bytes_to_int128 x) = x`, + REPEAT STRIP_TAC THEN + MP_TAC ((GEN_REWRITE_CONV I [LENGTH_EQ_LIST_OF_SEQ] THENC + RAND_CONV LIST_OF_SEQ_CONV) `LENGTH (x:byte list) = 16`) THEN + ASM_SIMP_TAC[] THEN + DISCH_THEN (fun th -> ONCE_REWRITE_TAC[th]) THEN + REWRITE_TAC[bytes_to_int128] THEN + REWRITE_TAC EL_16_8_CLAUSES THEN + REWRITE_TAC[int128_to_bytes] THEN + REWRITE_TAC[CONS_11] THEN + REPEAT (CONJ_TAC THEN BITBLAST_TAC) +);; + +let CALCULATE_TWEAK_EXPAND = prove( + `!x iv key. + GF_128_mult_by_primitive (calculate_tweak x iv key) = + calculate_tweak (x + 0x1) iv key`, + REPEAT GEN_TAC THEN + REWRITE_TAC[ARITH_RULE `x + 1 = SUC x`] THEN + CONV_TAC (RAND_CONV (REWRITE_CONV[CONJUNCT2 calculate_tweak])) THEN + REFL_TAC +);; + let DIVISION_REMAINDER_CASES = prove (`!a b. a DIV 80 = b ==> let r = a MOD 80 in @@ -1876,16 +2399,256 @@ let DIVISION_REMAINDER_CASES = prove let DIVISION_BY_80_LEMMA = prove( `!(a:num) b. a DIV 0x50 = b /\ 0x10 divides a /\ - ~(a - b * 0x50 - 0x10 = 0x0) /\ - ~(a - b * 0x50 - 0x20 = 0x0) /\ - ~(a - b * 0x50 - 0x30 = 0x0) /\ - ~(a - b * 0x50 - 0x40 = 0x0) ==> + ~(a - b * 0x50 = 0x10) /\ + ~(a - b * 0x50 = 0x20) /\ + ~(a - b * 0x50 = 0x30) /\ + ~(a - b * 0x50 = 0x40) ==> b * 0x50 = a`, REPEAT STRIP_TAC THEN - REWRITE_TAC[divides] THEN - CHEAT_TAC + (* Use the division theorem: a = b * 0x50 + (a MOD 0x50) *) + MP_TAC (SPECL [`a:num`; `0x50`] DIVISION) THEN + CONV_TAC NUM_REDUCE_CONV THEN + REPEAT STRIP_TAC THEN + + (* We have a = b * 0x50 + (a MOD 0x50) and a DIV 0x50 = b *) + SUBGOAL_THEN `a = b * 0x50 + (a MOD 0x50)` ASSUME_TAC THENL [ + ASM_ARITH_TAC; ALL_TAC] THEN + + (* Show that a MOD 0x50 = 0 by case analysis *) + SUBGOAL_THEN `a MOD 0x50 = 0` ASSUME_TAC THENL [ + (* Since 0x10 divides a, we know a = k * 0x10 for some k *) + UNDISCH_TAC `0x10 divides a` THEN + REWRITE_TAC[divides] THEN + STRIP_TAC THEN + + (* The remainder a MOD 0x50 must be a multiple of 0x10 and < 0x50 *) + (* So it's one of: 0, 0x10, 0x20, 0x30, 0x40 *) + SUBGOAL_THEN `(a MOD 0x50 = 0) \/ (a MOD 0x50 = 0x10) \/ + (a MOD 0x50 = 0x20) \/ (a MOD 0x50 = 0x30) \/ + (a MOD 0x50 = 0x40)` ASSUME_TAC THENL + [ ASM_REWRITE_TAC[] THEN + + SUBGOAL_THEN `(0x10 * x) MOD 0x50 = (x MOD 5) * 0x10` SUBST1_TAC THENL [ + SUBGOAL_THEN `0x50 = 5 * 0x10` SUBST1_TAC THENL [ + CONV_TAC NUM_REDUCE_CONV; ALL_TAC] THEN + MP_TAC (SPECL [`0x10 * x`; `0x10`; `5`] MOD_MULT_MOD) THEN + REWRITE_TAC[MOD_MULT; ADD_CLAUSES] THEN + IMP_REWRITE_TAC[DIV_MULT] THEN + CONV_TAC NUM_REDUCE_CONV THEN + SIMP_TAC[] THEN DISCH_TAC THEN + REWRITE_TAC[MULT_SYM] + ; ALL_TAC] THEN + + SUBGOAL_THEN `x MOD 5 < 5` ASSUME_TAC THENL [ + REWRITE_TAC[MOD_LT_EQ] THEN CONV_TAC NUM_REDUCE_CONV; ALL_TAC] THEN + SUBGOAL_THEN `x MOD 5 = 0 \/ x MOD 5 = 1 \/ x MOD 5 = 2 \/ x MOD 5 = 3 \/ x MOD 5 = 4` ASSUME_TAC THENL [ + UNDISCH_TAC `x MOD 0x5 < 0x5` THEN ARITH_TAC ; ALL_TAC] THEN + + REPEAT (FIRST_X_ASSUM DISJ_CASES_TAC) THENL + [ ASM_REWRITE_TAC[] THEN CONV_TAC NUM_REDUCE_CONV; + ASM_REWRITE_TAC[] THEN CONV_TAC NUM_REDUCE_CONV; + ASM_REWRITE_TAC[] THEN CONV_TAC NUM_REDUCE_CONV; + ASM_REWRITE_TAC[] THEN CONV_TAC NUM_REDUCE_CONV; + ASM_REWRITE_TAC[] THEN CONV_TAC NUM_REDUCE_CONV] + ; ALL_TAC] THEN + + (* Now eliminate the non-zero cases using the assumptions *) + SUBGOAL_THEN `~(a MOD 0x50 = 0x10)` ASSUME_TAC THENL + [ UNDISCH_TAC `~(a - b * 0x50 = 0x10)` THEN + UNDISCH_TAC `a = b * 0x50 + a MOD 0x50` THEN + ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `~(a MOD 0x50 = 0x20)` ASSUME_TAC THENL + [ UNDISCH_TAC `~(a - b * 0x50 = 0x20)` THEN + UNDISCH_TAC `a = b * 0x50 + a MOD 0x50` THEN + ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `~(a MOD 0x50 = 0x30)` ASSUME_TAC THENL + [ UNDISCH_TAC `~(a - b * 0x50 = 0x30)` THEN + UNDISCH_TAC `a = b * 0x50 + a MOD 0x50` THEN + ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `~(a MOD 0x50 = 0x40)` ASSUME_TAC THENL + [ UNDISCH_TAC `~(a - b * 0x50 = 0x40)` THEN + UNDISCH_TAC `a = b * 0x50 + a MOD 0x50` THEN + ARITH_TAC; ALL_TAC] THEN + + ASM_MESON_TAC[]; ALL_TAC + ] THEN + + (* Finally conclude b * 0x50 = a *) + ASM_ARITH_TAC );; +let WORD_AND_MASK16 = prove( + `word_and (len:int64) (word 0xfffffffffffffff0) = word_sub len (word_and len (word 0xf))`, + BITBLAST_TAC +);; + +let WORD_AND_MASK16_EQ_0 = prove( + `!(x:int64). val x < 16 ==> ~(val x = 0x0) ==> ~(val (word_and x (word 0xf)) = 0x0)`, + BITBLAST_TAC);; + +(* Surprisingly hard to prove *) +let NUM_BLOCKS_TO_VAL = prove( + `!(len:int64). word_and len (word 0xfffffffffffffff0) = word (16 * (val len DIV 16))`, + GEN_TAC THEN + REWRITE_TAC[WORD_AND_MASK16] THEN + REWRITE_TAC[GSYM VAL_EQ] THEN + SUBGOAL_THEN `16 * val (len:int64) DIV 16 = val len - (val len MOD 16)` SUBST1_TAC THENL + [REWRITE_TAC[DIVISION_SIMP] THEN ARITH_TAC; ALL_TAC] THEN + REWRITE_TAC[ARITH_RULE `0xf = 2 EXP 4 - 1`] THEN + REWRITE_TAC[WORD_AND_MASK_WORD] THEN + CONV_TAC NUM_REDUCE_CONV THEN + + REWRITE_TAC[VAL_WORD_SUB] THEN + SUBGOAL_THEN `val (len:int64) >= val ((word (val len MOD 0x10)):int64)` ASSUME_TAC THENL [ + REWRITE_TAC[VAL_WORD; DIMINDEX_64; GE] THEN + MP_TAC (SPECL [`val (len:int64) MOD 0x10`; `0x2 EXP 0x40`] MOD_LE) THEN + ARITH_TAC; + ALL_TAC + ] THEN + REWRITE_TAC[VAL_WORD; DIMINDEX_64] THEN + + SUBGOAL_THEN `val (len:int64) MOD 0x10 < 0x2 EXP 0x40` ASSUME_TAC THENL + [ TRANS_TAC LET_TRANS `val (len:int64)` THEN + REWRITE_TAC[VAL_BOUND_64; MOD_LE]; ALL_TAC] THEN + + SUBGOAL_THEN `val (len:int64) MOD 0x10 MOD 0x2 EXP 0x40 = val len MOD 0x10` ASSUME_TAC THENL + [ MP_TAC (SPECL [`val (len:int64) MOD 0x10`; `0x2 EXP 0x40`] MOD_LT) THEN + ASM_SIMP_TAC[]; ALL_TAC] THEN + ASM_REWRITE_TAC[] THEN + + MP_TAC (SPECL [`val (len:int64)`; `0x2 EXP 0x40`; `val (len:int64) MOD 0x10`] + (ARITH_RULE `!a b c. c <= a ==> c <= b ==> a + b - c = (a - c) + b`)) THEN + ANTS_TAC THENL [ REWRITE_TAC[MOD_LE]; ALL_TAC] THEN + ANTS_TAC THENL [ ASM_ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[] THEN DISCH_TAC THEN + + MP_TAC (SPECL [`1`; `0x2 EXP 0x40`; `val (len:int64) - val len MOD 0x10`] + (CONJUNCT1 (CONJUNCT2 (CONJUNCT2 MOD_MULT_ADD)))) THEN + CONV_TAC NUM_REDUCE_CONV + );; + +let NUM_BLOCKS_MINUS1_TO_VAL = prove( + `!(len:int64). val len >= 16 ==> + word_sub (word_and (len:int64) (word 0xfffffffffffffff0)) (word 0x10) = + word (16 * (val len DIV 16 - 1))`, + REWRITE_TAC[NUM_BLOCKS_TO_VAL] THEN + REPEAT STRIP_TAC THEN + REWRITE_TAC[LEFT_SUB_DISTRIB; WORD_SUB] THEN + CONV_TAC NUM_REDUCE_CONV THEN + SUBGOAL_THEN `0x10 <= 0x10 * val (len:int64) DIV 0x10` ASSUME_TAC THENL + [ MP_TAC (SPECL [`0x10`; `val (len:int64)`; `1`] LE_RDIV_EQ) THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[GSYM GE] THEN + ASM_SIMP_TAC[] THEN + ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[] +);; + +let BREAK_ONE_BLOCK_INTO_BYTES = prove( + `!(addr:int64) (s:armstate) (p:int128). + read (memory :> bytes128 addr) s = p <=> + (read (memory :> bytes8 addr) s = EL 0 (int128_to_bytes p) /\ + read (memory :> bytes8 (word_add addr (word 1))) s = EL 1 (int128_to_bytes p) /\ + read (memory :> bytes8 (word_add addr (word 2))) s = EL 2 (int128_to_bytes p) /\ + read (memory :> bytes8 (word_add addr (word 3))) s = EL 3 (int128_to_bytes p) /\ + read (memory :> bytes8 (word_add addr (word 4))) s = EL 4 (int128_to_bytes p) /\ + read (memory :> bytes8 (word_add addr (word 5))) s = EL 5 (int128_to_bytes p) /\ + read (memory :> bytes8 (word_add addr (word 6))) s = EL 6 (int128_to_bytes p) /\ + read (memory :> bytes8 (word_add addr (word 7))) s = EL 7 (int128_to_bytes p) /\ + read (memory :> bytes8 (word_add addr (word 8))) s = EL 8 (int128_to_bytes p) /\ + read (memory :> bytes8 (word_add addr (word 9))) s = EL 9 (int128_to_bytes p) /\ + read (memory :> bytes8 (word_add addr (word 10))) s = EL 10 (int128_to_bytes p) /\ + read (memory :> bytes8 (word_add addr (word 11))) s = EL 11 (int128_to_bytes p) /\ + read (memory :> bytes8 (word_add addr (word 12))) s = EL 12 (int128_to_bytes p) /\ + read (memory :> bytes8 (word_add addr (word 13))) s = EL 13 (int128_to_bytes p) /\ + read (memory :> bytes8 (word_add addr (word 14))) s = EL 14 (int128_to_bytes p) /\ + read (memory :> bytes8 (word_add addr (word 15))) s = EL 15 (int128_to_bytes p)) + `, + REPEAT GEN_TAC THEN + EQ_TAC THENL[ + STRIP_TAC THEN + MP_TAC (SPECL [`0:num`; `addr:int64`; `s:armstate`] BYTES128_TO_BYTES8_THM) THEN + REWRITE_TAC[WORD_ADD_0] THEN CONV_TAC NUM_REDUCE_CONV THEN + ASM_REWRITE_TAC[] THEN + DISCH_TAC THEN + REWRITE_TAC[int128_to_bytes] THEN + REWRITE_TAC EL_16_8_CLAUSES THEN + ASM_REWRITE_TAC[] THEN + REWRITE_TAC[bytes_to_int128] THEN + REWRITE_TAC EL_16_8_CLAUSES THEN + REWRITE_TAC[WORD_ADD_0] THEN + ABBREV_TAC `x0 = read (memory :> bytes8 (addr:int64)) s` THEN + ABBREV_TAC `x1 = read (memory :> bytes8 (word_add (addr:int64) (word 0x1))) s` THEN + ABBREV_TAC `x2 = read (memory :> bytes8 (word_add (addr:int64) (word 0x2))) s` THEN + ABBREV_TAC `x3 = read (memory :> bytes8 (word_add (addr:int64) (word 0x3))) s` THEN + ABBREV_TAC `x4 = read (memory :> bytes8 (word_add (addr:int64) (word 0x4))) s` THEN + ABBREV_TAC `x5 = read (memory :> bytes8 (word_add (addr:int64) (word 0x5))) s` THEN + ABBREV_TAC `x6 = read (memory :> bytes8 (word_add (addr:int64) (word 0x6))) s` THEN + ABBREV_TAC `x7 = read (memory :> bytes8 (word_add (addr:int64) (word 0x7))) s` THEN + ABBREV_TAC `x8 = read (memory :> bytes8 (word_add (addr:int64) (word 0x8))) s` THEN + ABBREV_TAC `x9 = read (memory :> bytes8 (word_add (addr:int64) (word 0x9))) s` THEN + ABBREV_TAC `xa = read (memory :> bytes8 (word_add (addr:int64) (word 0xa))) s` THEN + ABBREV_TAC `xb = read (memory :> bytes8 (word_add (addr:int64) (word 0xb))) s` THEN + ABBREV_TAC `xc = read (memory :> bytes8 (word_add (addr:int64) (word 0xc))) s` THEN + ABBREV_TAC `xd = read (memory :> bytes8 (word_add (addr:int64) (word 0xd))) s` THEN + ABBREV_TAC `xe = read (memory :> bytes8 (word_add (addr:int64) (word 0xe))) s` THEN + ABBREV_TAC `xf = read (memory :> bytes8 (word_add (addr:int64) (word 0xf))) s` THEN + REPEAT STRIP_TAC THEN + REPEAT BITBLAST_TAC; ALL_TAC] THEN + + REPEAT STRIP_TAC THEN + MP_TAC (SPECL [`0:num`; `addr:int64`; `s:armstate`] BYTES128_TO_BYTES8_THM) THEN + CONV_TAC NUM_REDUCE_CONV THEN REWRITE_TAC[WORD_ADD_0] THEN + ASM_REWRITE_TAC[] THEN + DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN + REWRITE_TAC[int128_to_bytes] THEN + REWRITE_TAC EL_16_8_CLAUSES THEN + REWRITE_TAC[bytes_to_int128] THEN + REWRITE_TAC EL_16_8_CLAUSES THEN + BITBLAST_TAC +);; + +let SELECT_ONE_BYTE_FROM_BLOCK = prove( + `!(addr:int64) (off:int64) (s:armstate) (p:int128). + read (memory :> bytes128 addr) s = p ==> + val off < 16 ==> + read (memory :> bytes8 (word_add addr off)) s = EL (val off) (int128_to_bytes p)`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM (STRIP_ASSUME_TAC o + MATCH_MP (fst (EQ_IMP_RULE + (SPECL [`addr:int64`; `s:armstate`; `p:int128`] BREAK_ONE_BLOCK_INTO_BYTES)))) THEN + SUBGOAL_THEN `word_add addr (off:int64) = word_add addr (word (val off))` SUBST1_TAC THENL + [REWRITE_TAC[WORD_VAL]; ALL_TAC] THEN + UNDISCH_TAC `val (off:int64) < 16` THEN + SPEC_TAC (`val (off:int64)`, `n:num`) THEN + CONV_TAC EXPAND_CASES_CONV THEN + ASM_REWRITE_TAC[WORD_ADD_0] +);; + +let SELECT_ONE_BYTE_FROM_FORALL = prove( + `!(ptr:int64) (len:int64) (addr:int64) (bl:byte list) (s:armstate). + (forall j. j < val len ==> read (memory :> bytes8 (word_add ptr (word j))) s = EL j bl) ==> + val addr < val len ==> + LENGTH bl = val len ==> + read (memory :> bytes8 (word_add ptr addr)) s = EL (val addr) bl`, + REPEAT STRIP_TAC THEN + FIRST_X_ASSUM (MP_TAC o SPEC `val (addr:int64)`) THEN + ASM_REWRITE_TAC[] THEN + REWRITE_TAC[WORD_VAL] +);; + +let IVAL_WORD_LT = prove( + `!i. i < 2 EXP 63 ==> ival ((word i):int64) = &i`, + GEN_TAC THEN DISCH_TAC THEN + REWRITE_TAC[ival; DIMINDEX_64; ARITH_RULE `64 - 1 = 63`] THEN + REWRITE_TAC[VAL_WORD; DIMINDEX_64] THEN + SUBGOAL_THEN `i < 2 EXP 64` ASSUME_TAC THENL + [ TRANS_TAC LT_TRANS `2 EXP 63` THEN + ASM_REWRITE_TAC[] THEN + CONV_TAC NUM_REDUCE_CONV; + ALL_TAC] THEN + ASM_SIMP_TAC[MOD_LT] +);; (* ********************************************************** *) (* Properties that we prove about the specification functions *) @@ -2023,14 +2786,60 @@ let LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS = prove( ASM_ARITH_TAC );; -let BYTES_TO_INT128_OF_INT128_TO_BYTES = prove( - `!x. bytes_to_int128 (int128_to_bytes x) = x`, - GEN_TAC THEN - REWRITE_TAC[int128_to_bytes; bytes_to_int128] THEN - REWRITE_TAC EL_16_8_CLAUSES THEN - BITBLAST_TAC -);; +let LENGTH_OF_AES256_XTS_DECRYPT = prove( + `! (i:num) (tail_len:num) (ct:byte list) (iv:int128) (key1:int128 list) (key2:int128 list). + ~(tail_len = 0) /\ tail_len < 16 ==> + LENGTH(aes256_xts_decrypt ct (16 * i + 16 + tail_len) iv key1 key2) = 16 * i + 16 + tail_len`, + REPEAT STRIP_TAC THEN + (* Case 1: i = 0 *) + ASM_CASES_TAC `i = 0` THENL + [ + ASM_SIMP_TAC[ADD_ASSOC] THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[aes256_xts_decrypt] THEN + SUBGOAL_THEN `~(0x10 + tail_len < 0x10)` ASSUME_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `(0x10 + tail_len) MOD 0x10 = tail_len` ASSUME_TAC THENL + [ REWRITE_TAC[ARITH_RULE `0x10 + tail_len = 1 * 16 + tail_len`] THEN + IMP_REWRITE_TAC[MOD_MULT_ADD; MOD_LT]; ALL_TAC] THEN + ASM_SIMP_TAC[] THEN + REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + SUBGOAL_THEN `((0x10 + tail_len) - tail_len) DIV 0x10 = 1` SUBST1_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC ] THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[LENGTH_OF_AES256_XTS_DECRYPT_TAIL] THEN + ASM_ARITH_TAC; + ALL_TAC + ] THEN + + (* Case 2: i >= 1 *) + ASM_CASES_TAC `i >= 1` THENL + [ + REWRITE_TAC[aes256_xts_decrypt] THEN + SUBGOAL_THEN `(0x10 * i + 0x10 + tail_len) MOD 0x10 = tail_len` SUBST1_TAC THENL + [ REWRITE_TAC[ADD_ASSOC; ARITH_RULE `0x10 * i + 0x10 = 16 * (i + 1)`] THEN + IMP_REWRITE_TAC[MOD_MULT_ADD; MOD_LT]; ALL_TAC] THEN + SUBGOAL_THEN `~(0x10 * i + 0x10 + tail_len < 0x10)` ASSUME_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[] THEN + REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + SUBGOAL_THEN `((0x10 * i + 0x10 + tail_len) - tail_len) DIV 0x10 = i + 1` SUBST1_TAC THENL + [ REWRITE_TAC[ARITH_RULE `(0x10 * i + 0x10 + tail_len) - tail_len = 16 * (i + 1)`] THEN + IMP_REWRITE_TAC[DIV_MULT] THEN + ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `~(i + 1 < 2)` ASSUME_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[] THEN + IMP_REWRITE_TAC[ARITH_RULE `(i + 1) - 2 = i - 1`; ADD_SUB] THEN + REWRITE_TAC[LENGTH_APPEND] THEN + IMP_REWRITE_TAC[LENGTH_OF_AES256_XTS_DECRYPT_REC] THEN + IMP_REWRITE_TAC[LENGTH_OF_AES256_XTS_DECRYPT_TAIL] THEN + ASM_ARITH_TAC; + ALL_TAC + ] THEN + ASM_ARITH_TAC +);; let AES256_XTS_DECRYPT_TAIL_WHEN_1BLOCK = prove( `!(n:num) (ct:byte list) (iv:int128) (key1:int128 list) (key2:int128 list). @@ -2119,7 +2928,6 @@ let SUB_LIST_OF_AES256_XTS_DECRYPT_FULL_BLOCKS = prove( ] THEN (* when i >= 2, using aes256_xts_decrypt_rec *) - REWRITE_TAC[aes256_xts_decrypt] THEN CONV_TAC NUM_REDUCE_CONV THEN SUBGOAL_THEN `~(0x10 * i < 0x10)` ASSUME_TAC THENL @@ -2147,6 +2955,94 @@ let SUB_LIST_OF_AES256_XTS_DECRYPT_FULL_BLOCKS = prove( ASM_ARITH_TAC );; +let SUB_LIST_OF_AES256_XTS_DECRYPT = prove( + `!(i:num) (tail_len:num) (ct:byte list) (iv:int128) (key1:int128 list) (key2:int128 list). + ~(tail_len = 0) /\ tail_len < 16 ==> + (SUB_LIST (0,16 * i) + (aes256_xts_decrypt ct (16 * i + 16 + tail_len) iv key1 key2)) + = aes256_xts_decrypt ct (16 * i) iv key1 key2`, + REPEAT STRIP_TAC THEN + (* Case 1: i = 0 *) + ASM_CASES_TAC `i = 0` THENL + [ + ASM_REWRITE_TAC[] THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[ADD; SUB_LIST_CLAUSES; aes256_xts_decrypt] THEN + CONV_TAC NUM_REDUCE_CONV; + ALL_TAC + ] THEN + (* Case 2: i = 1 *) + ASM_CASES_TAC `i = 1` THENL + [ + ASM_REWRITE_TAC[] THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[aes256_xts_decrypt; ADD_ASSOC] THEN + CONV_TAC NUM_REDUCE_CONV THEN + SUBGOAL_THEN `~(0x20 + tail_len < 0x10)` ASSUME_TAC THENL [ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[] THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + CONV_TAC NUM_REDUCE_CONV THEN + SUBGOAL_THEN `(0x20 + tail_len) MOD 0x10 = tail_len` ASSUME_TAC THENL + [ ASM_SIMP_TAC[ARITH_RULE `32 = 2 * 16`; MOD_MULT_ADD] THEN + IMP_REWRITE_TAC[MOD_LT] + ; ALL_TAC] THEN + SUBGOAL_THEN `((0x20 + tail_len) - (0x20 + tail_len) MOD 0x10) DIV 0x10 = 0x2` ASSUME_TAC THENL + [ ASM_REWRITE_TAC[ADD_ASSOC; ADD_SUB] THEN + ARITH_TAC ; ALL_TAC] THEN + ASM_SIMP_TAC[] THEN + CONV_TAC NUM_REDUCE_CONV THEN + ASM_REWRITE_TAC[] THEN + MP_TAC (SPECL [`ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT_REC_TRIVIAL) THEN + DISCH_TAC THEN IMP_REWRITE_TAC[SUB_LIST_APPEND_LEFT] THEN + REWRITE_TAC[AES256_XTS_DECRYPT_REC_EQ_TAIL_TRIVIAL] THEN + MP_TAC (SPECL [`ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT_TAIL_TRIVIAL) THEN + DISCH_TAC THEN IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN + ARITH_TAC; + ALL_TAC + ] THEN + + (* Case 3: i >= 2 *) + ASM_CASES_TAC `i >= 2` THENL + [ + ASM_REWRITE_TAC[ADD_ASSOC] THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[aes256_xts_decrypt] THEN + SUBGOAL_THEN `~(0x10 * i < 0x10)` ASSUME_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `~((0x10 * i + 0x10) + tail_len < 0x10)` ASSUME_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[LET_DEF; LET_END_DEF] THEN + SUBGOAL_THEN `((0x10 * i + 0x10) + tail_len) MOD 0x10 = tail_len` SUBST1_TAC THENL + [ REWRITE_TAC[ARITH_RULE `0x10 * i + 0x10 = 16 * (i + 1)`] THEN + IMP_REWRITE_TAC[MOD_MULT_ADD; MOD_LT] + ; ALL_TAC] THEN + REWRITE_TAC[ADD_SUB; MOD_MULT; SUB_0; + ARITH_RULE `0x10 * i + 0x10 = 16 * (i + 1)`] THEN + IMP_REWRITE_TAC[DIV_MULT] THEN + SUBGOAL_THEN `~(i + 1 < 2)` ASSUME_TAC THENL [ ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `~(i < 2)` ASSUME_TAC THENL [ ASM_ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[ADD_SUB; ARITH_RULE `(i + 1) - 2 = i - 1`] THEN + CONV_TAC NUM_REDUCE_CONV THEN + MP_TAC (SPECL [`0:num`; `(i - 1):num`; `ct:byte list`; `iv:int128`; + `key1:int128 list`; `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT_REC) THEN + SUBGOAL_THEN `~((i - 1) < 0)` ASSUME_TAC THENL [ ASM_ARITH_TAC; ALL_TAC] THEN + IMP_REWRITE_TAC[ARITH_RULE `i >= 2 ==> i - 0x1 - 0x0 + 0x1 = i`] THEN + IMP_REWRITE_TAC[SUB_LIST_APPEND_LEFT] THEN + SIMP_TAC[ARITH_RULE `16 * i <= i * 16`] THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN + SIMP_TAC[ARITH_RULE `i * 16 = 16 * i`] THEN + DISCH_TAC THEN + MP_TAC (SPECL [`0`; `(i-2):num`; `ct:byte list`; `iv:int128`; + `key1:int128 list`; `key2:int128 list`] AES256_XTS_DECRYPT_REC_EQ_TAIL) THEN + ANTS_TAC THENL [ ASM_ARITH_TAC; ALL_TAC ] THEN + IMP_REWRITE_TAC[ARITH_RULE `i >= 2 ==> i - 0x2 + 0x1 = i - 1`]; + ALL_TAC + ] THEN + + ASM_ARITH_TAC +);; + let acc_len = new_definition `acc_len (i:int64) (len:int64) : num = if val i * 0x50 + 0x40 = val len then 0x50 * val i + 0x40 @@ -2158,6 +3054,57 @@ let acc_len = new_definition if val i * 0x50 + 0x10 = val len then 0x50 * val i + 0x10 else 0x50 * val i`;; +let VALUE_OF_ACC_LEN = prove( + `!(i:int64) (len:int64). + val i * 0x50 <= val len ==> + val len DIV 0x50 = val i ==> + 0x10 divides val len ==> + acc_len i len = val len`, + REPEAT STRIP_TAC THEN + REWRITE_TAC[acc_len] THEN + REPEAT COND_CASES_TAC THENL + [ + ASM_ARITH_TAC; + ASM_ARITH_TAC; + ASM_ARITH_TAC; + ASM_ARITH_TAC; + REWRITE_TAC[ARITH_RULE `!a. 0x50 * a = a * 0x50`] THEN + SUBGOAL_THEN `val (i:int64) * 0x50 = val (len:int64)` ASSUME_TAC THENL + [ MATCH_MP_TAC (SPECL [`val (len:int64)`; `val (i:int64)`] DIVISION_BY_80_LEMMA) THEN + REPEAT CONJ_TAC THENL + [ + ASM_SIMP_TAC[]; + ASM_SIMP_TAC[]; + UNDISCH_TAC `~(val (i:int64) * 0x50 + 0x10 = val (len:int64))` THEN + UNDISCH_TAC `val (i:int64) * 0x50 <= val (len:int64)` THEN + ARITH_TAC; + UNDISCH_TAC `~(val (i:int64) * 0x50 + 0x20 = val (len:int64))` THEN + UNDISCH_TAC `val (i:int64) * 0x50 <= val (len:int64)` THEN + ARITH_TAC; + UNDISCH_TAC `~(val (i:int64) * 0x50 + 0x30 = val (len:int64))` THEN + UNDISCH_TAC `val (i:int64) * 0x50 <= val (len:int64)` THEN + ARITH_TAC; + UNDISCH_TAC `~(val (i:int64) * 0x50 + 0x40 = val (len:int64))` THEN + UNDISCH_TAC `val (i:int64) * 0x50 <= val (len:int64)` THEN + ARITH_TAC + ]; ALL_TAC] THEN + ASM_ARITH_TAC + ] +);; + +let BOUND_OF_ACC_LEN = prove( + `!(i:int64) (len:int64) x. + val i * 0x50 <= val len ==> + val len DIV 0x50 = val i ==> + 0x10 divides val len ==> + val len < x ==> acc_len i len < x`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN `acc_len i len = val (len:int64)` ASSUME_TAC THENL + [ MP_TAC (SPECL [`i:int64`; `len:int64`] VALUE_OF_ACC_LEN) THEN + ASM_SIMP_TAC[]; ALL_TAC] THEN + ASM_ARITH_TAC +);; + (* For X9 and X10, they stand for i * 0x5 + 4 when number of blocks is divisible by 5 *) let acc_blocks = new_definition `acc_blocks (i:int64) (len:int64) (last:bool) : num = @@ -2171,7 +3118,353 @@ let acc_blocks = new_definition else if last then val i * 0x5 else val i * 0x5 + 4`;; -let AES_XTS_DECRYPT_CORRECT = prove( +let cipher_stealing_inv = new_definition +`cipher_stealing_inv (i:num) (curr_len:num) (tail_len:num) (PP:int128) (ct:byte list): int128 = + bytes_to_int128( + APPEND (SUB_LIST (0, i) (int128_to_bytes PP)) + (APPEND (SUB_LIST (i, tail_len - i) (SUB_LIST (curr_len + 16, tail_len) ct)) + (SUB_LIST (tail_len, 16 - tail_len) (int128_to_bytes PP))))`;; + + +let CIPHER_STEALING_BYTE_EQUAL = prove( + `!(i:num) (curr_len:num) (tail_len:int64) (PP:int128) (ct:byte list). + i < val tail_len /\ val tail_len < 16 ==> + curr_len + 16 + val tail_len = LENGTH ct ==> + let InvPP = cipher_stealing_inv (i + 1) curr_len (val tail_len) PP ct + and InvPP' = cipher_stealing_inv i curr_len (val tail_len) PP ct in + (!j. 0 <= j /\ j < 16 /\ ~(j = i) ==> EL j (int128_to_bytes InvPP) = EL j (int128_to_bytes InvPP')) /\ + EL i (int128_to_bytes InvPP') = word_zx (EL (curr_len + 16 + i) ct)`, + REPEAT STRIP_TAC THEN + REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + CONJ_TAC THENL + [ + REPEAT STRIP_TAC THEN + REWRITE_TAC[cipher_stealing_inv] THEN + IMP_REWRITE_TAC[INT128_TO_BYTES_OF_BYTES_TO_INT128] THEN + REPEAT CONJ_TAC THENL + [ + (* Three cases: 0 <= j < i, i < j < val tail_len, val tail_len <= j < 16 *) + ASM_CASES_TAC `j < i` THENL + [ + SUBGOAL_THEN `j < LENGTH (SUB_LIST (0x0,i + 0x1) (int128_to_bytes PP))` ASSUME_TAC THENL + [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN + ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `j < LENGTH (SUB_LIST (0x0,i) (int128_to_bytes PP))` ASSUME_TAC THENL + [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN + ASM_ARITH_TAC ; ALL_TAC] THEN + REWRITE_TAC[EL_APPEND] THEN + ASM_SIMP_TAC[] THEN + MP_TAC (ISPECL [`j:num`; `i:num`; `(int128_to_bytes PP):byte list`] EL_SUB_LIST) THEN + ANTS_TAC THENL + [ REWRITE_TAC[LENGTH_OF_INT128_TO_BYTES] THEN + ASM_ARITH_TAC; ALL_TAC ] THEN + MP_TAC (ISPECL [`j:num`; `(i + 1):num`; `(int128_to_bytes PP):byte list`] EL_SUB_LIST) THEN + ANTS_TAC THENL + [ REWRITE_TAC[LENGTH_OF_INT128_TO_BYTES] THEN + ASM_ARITH_TAC; ALL_TAC ] THEN + SIMP_TAC[]; ALL_TAC + ] THEN + ASM_CASES_TAC `j < val (tail_len:int64)` THENL + [ + SUBGOAL_THEN `j > i` ASSUME_TAC THENL[ASM_ARITH_TAC; ALL_TAC] THEN + REWRITE_TAC[EL_APPEND] THEN + SUBGOAL_THEN `LENGTH (SUB_LIST (0x0,i + 0x1) (int128_to_bytes PP)) = i + 1` SUBST1_TAC THENL + [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN + ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `LENGTH (SUB_LIST (0x0,i) (int128_to_bytes PP)) = i` SUBST1_TAC THENL + [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN + ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `LENGTH (SUB_LIST (i + 0x1,val (tail_len:int64) - (i + 0x1)) + (SUB_LIST (curr_len + 0x10,val tail_len) (ct:byte list))) + = val tail_len - (i + 1)` SUBST1_TAC THENL + [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN + ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `LENGTH (SUB_LIST (i,val (tail_len:int64) - i) + (SUB_LIST (curr_len + 0x10,val tail_len) (ct:byte list))) + = val tail_len - i` SUBST1_TAC THENL + [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN + ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `~(j < i)` ASSUME_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `~(j < i + 1)` ASSUME_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `j - i < val (tail_len:int64) - i` ASSUME_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `j - (i + 1) < val (tail_len:int64) - (i + 1)` ASSUME_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[] THEN + MP_TAC (ISPECL [`(j - i):num`; `i:num`; + `(SUB_LIST (curr_len + 16,val (tail_len:int64)) (ct:byte list)):byte list`; + `(val (tail_len:int64) - i):num`] EL_SUB_LIST_SHIFT) THEN + ASM_SIMP_TAC[] THEN + ANTS_TAC THENL [ REWRITE_TAC[LENGTH_SUB_LIST] THEN ASM_ARITH_TAC; ALL_TAC] THEN + IMP_REWRITE_TAC[ARITH_RULE `!i j. j > i ==> j - i - 1 = j - (i + 1)`] THEN + ASM_ARITH_TAC; ALL_TAC + ] THEN + (* j >= val tail_len *) + REWRITE_TAC[EL_APPEND] THEN + SUBGOAL_THEN `LENGTH (SUB_LIST (0x0,i + 0x1) (int128_to_bytes PP)) = i + 1` SUBST1_TAC THENL + [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN + ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `LENGTH (SUB_LIST (0x0,i) (int128_to_bytes PP)) = i` SUBST1_TAC THENL + [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN + ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `LENGTH (SUB_LIST (i + 0x1,val (tail_len:int64) - (i + 0x1)) + (SUB_LIST (curr_len + 0x10,val tail_len) (ct:byte list))) + = val tail_len - (i + 1)` SUBST1_TAC THENL + [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN + ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `LENGTH (SUB_LIST (i,val (tail_len:int64) - i) + (SUB_LIST (curr_len + 0x10,val tail_len) (ct:byte list))) + = val tail_len - i` SUBST1_TAC THENL + [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN + ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `~(j < i)` ASSUME_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `~(j < i + 1)` ASSUME_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `~(j - i < val (tail_len:int64) - i)` ASSUME_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `~(j - (i + 1) < val (tail_len:int64) - (i + 1))` ASSUME_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[] THEN + AP_THM_TAC THEN AP_TERM_TAC THEN + ASM_ARITH_TAC; + + REWRITE_TAC[LENGTH_APPEND] THEN + REWRITE_TAC[LENGTH_SUB_LIST] THEN + REWRITE_TAC[LENGTH_OF_INT128_TO_BYTES] THEN + CONV_TAC NUM_REDUCE_CONV THEN + IMP_REWRITE_TAC[ARITH_RULE `i < 16 ==> MIN i 16 = i`] THEN + SUBGOAL_THEN `LENGTH (ct:byte list) - (curr_len + 16) = val (tail_len:int64)` SUBST1_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC ] THEN + REWRITE_TAC[ARITH_RULE `!x. MIN x x = x`] THEN + ASM_ARITH_TAC; + + REWRITE_TAC[LENGTH_APPEND] THEN + REWRITE_TAC[LENGTH_SUB_LIST] THEN + REWRITE_TAC[LENGTH_OF_INT128_TO_BYTES] THEN + CONV_TAC NUM_REDUCE_CONV THEN + IMP_REWRITE_TAC[ARITH_RULE `i < 16 ==> MIN (i + 1) 16 = i + 1`] THEN + SUBGOAL_THEN `LENGTH (ct:byte list) - (curr_len + 16) = val (tail_len:int64)` SUBST1_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC ] THEN + REWRITE_TAC[ARITH_RULE `!x. MIN x x = x`] THEN + ASM_ARITH_TAC + ] ; ALL_TAC + ] THEN + + REWRITE_TAC[cipher_stealing_inv] THEN + IMP_REWRITE_TAC[INT128_TO_BYTES_OF_BYTES_TO_INT128] THEN + CONJ_TAC THENL [ + REWRITE_TAC[EL_APPEND] THEN + SUBGOAL_THEN `LENGTH (SUB_LIST (0x0,i) (int128_to_bytes PP)) = i` SUBST1_TAC THENL + [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN + ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `LENGTH (SUB_LIST (i,val (tail_len:int64) - i) + (SUB_LIST (curr_len + 0x10,val tail_len) (ct:byte list))) + = val tail_len - i` SUBST1_TAC THENL + [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN + ASM_ARITH_TAC; ALL_TAC] THEN + SIMP_TAC[ARITH_RULE `~(i < i)`; SUB_REFL] THEN + SUBGOAL_THEN `0 < val (tail_len:int64) - i` ASSUME_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[] THEN + MP_TAC (ISPECL [`curr_len + 0x10:num`; `i:num`; `ct:byte list`; + `val (tail_len:int64) - i:num`; `val (tail_len:int64)`] SUB_LIST_MIN_GENERAL) THEN + REWRITE_TAC[ARITH_RULE `!a. MIN a a = a`; GSYM ADD_ASSOC] THEN + DISCH_THEN (fun th -> (REWRITE_TAC [th])) THEN + REWRITE_TAC[WORD_ZX_TRIVIAL; EL] THEN + MATCH_MP_TAC HD_SUB_LIST_CONS_GENERAL THEN + ASM_ARITH_TAC; ALL_TAC] THEN + REWRITE_TAC[LENGTH_APPEND] THEN + REWRITE_TAC[LENGTH_SUB_LIST] THEN + REWRITE_TAC[LENGTH_OF_INT128_TO_BYTES] THEN + CONV_TAC NUM_REDUCE_CONV THEN + ASM_ARITH_TAC +);; + +let CIPHER_STEALING_INV_SELECT = prove( + `!(i:num) (curr_len:num) (tail_len:int64) (PP:int128) (ct:byte list). + i < val tail_len ==> val tail_len < 16 ==> + curr_len + 16 + (val tail_len) = LENGTH ct ==> + EL i (int128_to_bytes (cipher_stealing_inv (i + 1) curr_len (val tail_len) PP ct)) = + EL i (int128_to_bytes PP)`, + REPEAT STRIP_TAC THEN + REWRITE_TAC[cipher_stealing_inv] THEN + IMP_REWRITE_TAC[INT128_TO_BYTES_OF_BYTES_TO_INT128] THEN + CONJ_TAC THENL [ + SUBGOAL_THEN `LENGTH (SUB_LIST (0x0,i + 1) (int128_to_bytes PP)) <= i + 1` ASSUME_TAC THENL + [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN + ARITH_TAC; ALL_TAC] THEN + REWRITE_TAC[EL_APPEND] THEN + SUBGOAL_THEN `i < LENGTH (SUB_LIST (0x0,i + 0x1) (int128_to_bytes PP))` ASSUME_TAC THENL + [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN + ASM_ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[] THEN + MATCH_MP_TAC EL_SUB_LIST THEN + REWRITE_TAC[LENGTH_OF_INT128_TO_BYTES] THEN + ASM_ARITH_TAC; ALL_TAC + ] THEN + + REWRITE_TAC[LENGTH_APPEND] THEN + REWRITE_TAC[LENGTH_SUB_LIST] THEN + REWRITE_TAC[LENGTH_OF_INT128_TO_BYTES] THEN + CONV_TAC NUM_REDUCE_CONV THEN + IMP_REWRITE_TAC[ARITH_RULE `i < 16 ==> MIN (i + 1) 16 = i + 1`] THEN + SUBGOAL_THEN `LENGTH (ct:byte list) - (curr_len + 16) = val (tail_len:int64)` SUBST1_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC ] THEN + REWRITE_TAC[ARITH_RULE `!x. MIN x x = x`] THEN + ASM_ARITH_TAC +);; + +let CIPHER_STEALING_INV_SIMP_TAC i = + ( FIRST_ASSUM (fun th -> MATCH_MP_TAC(SPEC i th)) THEN CONV_TAC NUM_REDUCE_CONV) ORELSE + ( ASM_REWRITE_TAC[] THEN + REWRITE_TAC[WORD_RULE `!a b. word_add ((word a):int64) (word b) = word (a + b)`] THEN + REWRITE_TAC[GSYM ADD_ASSOC] THEN + CONV_TAC NUM_REDUCE_CONV THEN + IMP_REWRITE_TAC[WORD_ZX_ZX; WORD_ZX_TRIVIAL] THEN + REWRITE_TAC[DIMINDEX_8; DIMINDEX_32; DIMINDEX_64] THEN + IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN + ASM_ARITH_TAC);; + +let TAIL_SWAP_CASE_TAC case = + let c_tm = `case:num` in + let v_tm = `v:num` in + let v = rand (concl (NUM_RED_CONV (subst [case,c_tm] `0x10 + case`))) in + let r1 = subst [case,c_tm; v,v_tm] `curr_len + 0x10 + case = curr_len + v` in + let t1 = subst [case,c_tm] `(cipher_stealing_inv case curr_len (val (tail_len:int64)) PP ct):int128` in + POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th]) THEN REWRITE_TAC[th]) THEN + (* Simplify so that symbolic execution could match up, but couldn't use + CONV_TAC NUM_REDUCE_CONV because of non-overlapping *) + RULE_ASSUM_TAC(REWRITE_RULE[ARITH_RULE r1]) THEN + RULE_ASSUM_TAC(REWRITE_RULE[ARITH_RULE `curr_len + 0x10 + 0x1 = curr_len + 0x11`]) THEN + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (1--5) THEN + RULE_ASSUM_TAC(REWRITE_RULE[GSYM ADD_ASSOC]) THEN + RULE_ASSUM_TAC (CONV_RULE NUM_REDUCE_CONV) THEN + ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN + REPEAT CONJ_TAC THENL + [ + REWRITE_TAC[ + WORD_RULE `!(a:int64) b c. word_add (word_add a b) c = word_add a (word_add b c)`; + WORD_RULE `!a b. word_add ((word a):int64) (word b) = word (a + b)`]; + + MATCH_MP_TAC (snd (EQ_IMP_RULE (SPECL [`(word_add pt_ptr (word curr_len)):int64`; + `s5:armstate`; t1] BREAK_ONE_BLOCK_INTO_BYTES))) THEN + REWRITE_TAC[ + WORD_RULE `!(a:int64) b c. word_add (word_add a b) c = word_add a (word_add b c)`; + WORD_RULE `!a b. word_add ((word a):int64) (word b) = word (a + b)`] THEN + ASM_REWRITE_TAC[] THEN + CONV_TAC NUM_REDUCE_CONV THEN + + MP_TAC (SPECL [case; `curr_len:num`; `tail_len:int64`; `PP:int128`; `ct:byte list`] + CIPHER_STEALING_BYTE_EQUAL) THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + STRIP_TAC THEN + + MAP_EVERY (fun i -> CONJ_TAC THENL + [CIPHER_STEALING_INV_SIMP_TAC (mk_numeral (num i)); ALL_TAC]) + (0--0xe) THEN + CIPHER_STEALING_INV_SIMP_TAC `0xf:num`; + + MP_TAC (SPECL [`pt_ptr:int64`; case; `val (tail_len:int64)`; + `curr_len:num`; `(int128_to_bytes PP):byte list`; `s5:armstate`] + BYTE_LIST_AT_SPLIT_BACKWARDS) THEN + CONV_TAC NUM_REDUCE_CONV THEN + ASM_SIMP_TAC[] THEN + ANTS_TAC THENL + [ IMP_REWRITE_TAC[WORD_ZX_ZX] THEN + REWRITE_TAC[DIMINDEX_8; DIMINDEX_32; DIMINDEX_64] THEN + MP_TAC (SPECL [case; `curr_len:num`; `tail_len:int64`; `PP:int128`; `ct:byte list`] + CIPHER_STEALING_INV_SELECT) THEN + CONV_TAC NUM_REDUCE_CONV THEN + ASM_SIMP_TAC[] + ; ALL_TAC ] THEN + MESON_TAC[]; + + WORD_ARITH_TAC; + WORD_ARITH_TAC + ];; + +let TAIL_SWAP_ASM_CASES_TAC case = + let c_tm = `case:num` in + let asm_case = subst [case, c_tm] `(i:num) = case` in + ASM_CASES_TAC asm_case THENL [ TAIL_SWAP_CASE_TAC case; ALL_TAC] THEN + MP_TAC (SPECL [case; `i:num`] LE_LT) THEN + ASM_SIMP_TAC[] THEN + DISCH_TAC THEN + MP_TAC (SPECL [case; `i:num`] LE_SUC_LT) THEN + ASM_SIMP_TAC[] THEN + CONV_TAC NUM_REDUCE_CONV THEN + ASM_SIMP_TAC[] THEN + DISCH_TAC;; + + +let BREAK_DATA_INTO_PARTS = prove( + `!curr_len (tail_len:int64) (pt_ptr:int64) (s:armstate). + ((forall i. i < curr_len + ==> read (memory :> bytes8 (word_add pt_ptr (word i))) s = EL i bl) /\ + (forall i. i < 16 + ==> read (memory :> bytes8 (word_add (word_add pt_ptr (word curr_len)) (word i))) s = + EL i (SUB_LIST (curr_len, 16 + val tail_len) bl)) /\ + (forall i. i < val tail_len + ==> read (memory :> bytes8 + (word_add (word_add pt_ptr (word (curr_len + 0x10))) (word i))) s = + EL i (SUB_LIST (curr_len + 16, val tail_len) bl))) ==> + forall i. + i < curr_len + 0x10 + val tail_len + ==> read (memory :> bytes8 (word_add pt_ptr (word i))) s = EL i bl`, + REPEAT GEN_TAC THEN + DISCH_THEN (CONJUNCTS_THEN2 (LABEL_TAC "H1") + (CONJUNCTS_THEN2 (LABEL_TAC "H2") (LABEL_TAC "H3"))) THEN + REPEAT STRIP_TAC THEN + + ASM_CASES_TAC `i < curr_len` THENL + [ + FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[]; + ALL_TAC + ] THEN + + ASM_CASES_TAC `i < curr_len + 16` THENL + [ + USE_THEN "H2" (fun th -> MP_TAC (SPEC `i - curr_len` th)) THEN + REMOVE_THEN "H2" (K ALL_TAC) THEN + SUBGOAL_THEN `(word_add (word_add (pt_ptr:int64) (word curr_len)) (word (i - curr_len))) + = (word_add pt_ptr (word i))` ASSUME_TAC THENL + [ REWRITE_TAC[WORD_RULE `word_add (word_add a (word b)) (word c) = word_add a (word (b + c))`] THEN + AP_TERM_TAC THEN AP_TERM_TAC THEN + ASM_ARITH_TAC; ALL_TAC] THEN + ASM_REWRITE_TAC[] THEN + ANTS_TAC THENL[ASM_ARITH_TAC; ALL_TAC] THEN + SIMP_TAC[] THEN DISCH_TAC THEN + IMP_REWRITE_TAC[EL_SUB_LIST_GENERAL] THEN + ASM_ARITH_TAC; + ALL_TAC + ] THEN + + ASM_CASES_TAC `i < curr_len + 16 + val (tail_len:int64)` THENL + [ + USE_THEN "H3" (fun th -> MP_TAC (SPEC `i - curr_len - 16` th)) THEN + REMOVE_THEN "H3" (K ALL_TAC) THEN + SUBGOAL_THEN `(word_add (word_add (pt_ptr:int64) (word (curr_len + 0x10))) + (word (i - curr_len - 0x10))) = (word_add pt_ptr (word i))` ASSUME_TAC THENL + [ REWRITE_TAC[WORD_RULE `word_add (word_add a (word b)) (word c) = word_add a (word (b + c))`] THEN + AP_TERM_TAC THEN AP_TERM_TAC THEN + ASM_ARITH_TAC; ALL_TAC] THEN + ASM_REWRITE_TAC[] THEN + ANTS_TAC THENL[ASM_ARITH_TAC; ALL_TAC] THEN + SIMP_TAC[] THEN DISCH_TAC THEN + REWRITE_TAC[ARITH_RULE `i - curr_len - 16 = i - (curr_len + 16)`] THEN + IMP_REWRITE_TAC[EL_SUB_LIST_GENERAL] THEN + ASM_ARITH_TAC; + ALL_TAC + ] THEN + + ASM_ARITH_TAC +);; + +let AES_XTS_DECRYPT_CORRECT = time prove( `!ct_ptr pt_ptr ct key1_ptr key2_ptr iv_ptr iv len k00 k01 k02 k03 k04 k05 k06 k07 k08 k09 k0a k0b k0c k0d k0e k10 k11 k12 k13 k14 k15 k16 k17 k18 k19 k1a k1b k1c k1d k1e @@ -2286,6 +3579,14 @@ let AES_XTS_DECRYPT_CORRECT = prove( MP_TAC (SPECL [`num_blocks_adjusted:int64`; `num_5blocks_adjusted:int64`] NUM_5BLOCKS_ADJUSTED_LO_BOUND_THM) THEN SIMP_TAC[] ; ALL_TAC] THEN + SUBGOAL_THEN `val (tail_len:int64) < 16` ASSUME_TAC THENL + [ EXPAND_TAC "tail_len" THEN + REWRITE_TAC[ARITH_RULE `0xf = 2 EXP 4 - 1`] THEN + REWRITE_TAC[VAL_WORD_AND_MASK_WORD] THEN + CONV_TAC NUM_REDUCE_CONV THEN + SIMP_TAC[MOD_LT_EQ] THEN + CONV_TAC NUM_REDUCE_CONV + ; ALL_TAC] THEN (* relationship between variables *) SUBGOAL_THEN `val (num_blocks:int64) <= val (len:int64)` ASSUME_TAC THENL [ EXPAND_TAC "num_blocks" THEN SIMP_TAC[NUM_BLOCKS_LT_LEN_THM]; ALL_TAC] THEN @@ -2380,7 +3681,7 @@ let AES_XTS_DECRYPT_CORRECT = prove( ASM_REWRITE_TAC[] THEN SUBST1_TAC(ARITH_RULE `0xf = 2 EXP 4 - 1`) THEN REWRITE_TAC[VAL_WORD_AND_MASK_WORD] THEN - NUM_REDUCE_TAC THEN SIMP_TAC[MOD_LT]; ALL_TAC] THEN + NUM_REDUCE_TAC THEN IMP_REWRITE_TAC[MOD_LT]; ALL_TAC] THEN SUBGOAL_THEN `num_blocks_adjusted:int64 = num_blocks:int64` ASSUME_TAC THENL [ UNDISCH_TAC `(if val (tail_len:int64) = 0x0 then (num_blocks:int64) @@ -2449,7 +3750,7 @@ let AES_XTS_DECRYPT_CORRECT = prove( ASM_REWRITE_TAC[] THEN SUBST1_TAC(ARITH_RULE `0xf = 2 EXP 4 - 1`) THEN REWRITE_TAC[VAL_WORD_AND_MASK_WORD] THEN - NUM_REDUCE_TAC THEN SIMP_TAC[MOD_LT] + NUM_REDUCE_TAC THEN IMP_REWRITE_TAC[MOD_LT] ; ALL_TAC] THEN (* Prove num_blocks_adjusted = word_sub num_blocks (word 0x10) *) SUBGOAL_THEN `word_sub num_blocks (word 0x10) = num_blocks_adjusted:int64` ASSUME_TAC THENL @@ -2534,10 +3835,13 @@ let AES_XTS_DECRYPT_CORRECT = prove( read X19 s = word 0x87 /\ read X10 s = word_subword (calculate_tweak (acc_blocks num_5blocks_adjusted num_blocks_adjusted F) iv key2) (64,64) /\ read X9 s = word_zx (calculate_tweak (acc_blocks num_5blocks_adjusted num_blocks_adjusted F) iv key2) /\ + read Q16 s = k00 /\ read Q17 s = k01 /\ read Q12 s = k02 /\ read Q13 s = k03 /\ + read Q14 s = k04 /\ read Q15 s = k05 /\ read Q4 s = k06 /\ read Q5 s = k07 /\ + read Q18 s = k08 /\ read Q19 s = k09 /\ read Q20 s = k0a /\ read Q21 s = k0b /\ + read Q22 s = k0c /\ read Q23 s = k0d /\ read Q7 s = k0e /\ byte_list_at ct ct_ptr len s /\ byte_list_at (aes256_xts_decrypt ct (acc_len num_5blocks_adjusted num_blocks_adjusted) iv key1 key2) - pt_ptr (word (acc_len num_5blocks_adjusted num_blocks_adjusted)) s /\ - set_key_schedule s key1_ptr k00 k01 k02 k03 k04 k05 k06 k07 k08 k09 k0a k0b k0c k0d k0e` THEN + pt_ptr (word (acc_len num_5blocks_adjusted num_blocks_adjusted)) s` THEN CONJ_TAC THENL [ (* Setting up the loop invariant *) @@ -2584,15 +3888,14 @@ let AES_XTS_DECRYPT_CORRECT = prove( read Q18 s = k08 /\ read Q19 s = k09 /\ read Q20 s = k0a /\ read Q21 s = k0b /\ read Q22 s = k0c /\ read Q23 s = k0d /\ read Q7 s = k0e /\ byte_list_at ct ct_ptr len s /\ - byte_list_at (aes256_xts_decrypt ct (80 * i) iv key1 key2) pt_ptr (word (80 * i)) s /\ - set_key_schedule s key1_ptr k00 k01 k02 k03 k04 k05 k06 k07 k08 k09 k0a k0b k0c k0d k0e) /\ + byte_list_at (aes256_xts_decrypt ct (80 * i) iv key1 key2) pt_ptr (word (80 * i)) s) /\ // loop backedge condition (read ZF s <=> i = val (num_5blocks_adjusted:int64))` THEN ASM_REWRITE_TAC[] THEN REPEAT CONJ_TAC THENL [ (* Subgoal 1. Bound of loop is not zero -- automatically discharged by asm *) (* Subgoal 2. Invariant holds before entering the loop *) - REWRITE_TAC[byte_list_at; set_key_schedule] THEN + REWRITE_TAC[byte_list_at] THEN ENSURES_INIT_TAC "s0" THEN ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN REPEAT CONJ_TAC THENL @@ -2637,7 +3940,7 @@ let AES_XTS_DECRYPT_CORRECT = prove( SUBSUMED_MAYCHANGE_TAC; ALL_TAC] THEN (* ===> Symbolic Simulation: Start symbolic simulation*) - ASM_REWRITE_TAC[byte_list_at; set_key_schedule] THEN + ASM_REWRITE_TAC[byte_list_at] THEN ENSURES_INIT_TAC "s0" THEN (* List values for ct_ptr + [0 .. 0x40] *) @@ -2710,14 +4013,14 @@ let AES_XTS_DECRYPT_CORRECT = prove( i' < 0x50 * i ==> read (memory :> bytes8 (word_add pt_ptr (word i'))) s188 = EL i' (aes256_xts_decrypt ct (0x50 * i) iv key1 key2)` THEN - MP_TAC (SPECL [`0x50 * i + 0x50:num`; `(aes256_xts_decrypt ct (0x50 * i + 0x50) iv key1 key2):byte list`; `s188:armstate`] BYTE_LIST_TO_NUM_THM) THEN + MP_TAC (SPECL [`0x50 * i + 0x50:num`; `pt_ptr:int64`; `(aes256_xts_decrypt ct (0x50 * i + 0x50) iv key1 key2):byte list`; `s188:armstate`] BYTE_LIST_TO_NUM_THM) THEN ANTS_TAC THENL[ REWRITE_TAC[ARITH_RULE `0x50 * i + 0x50 = 0x10 * (5 * i + 5)`; LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS] THEN ARITH_TAC ; ALL_TAC] THEN DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN - MP_TAC (SPECL [`0x50 * i:num`; `(aes256_xts_decrypt ct (0x50 * i) iv key1 key2):byte list`; `s188:armstate`] BYTE_LIST_TO_NUM_THM) THEN + MP_TAC (SPECL [`0x50 * i:num`; `pt_ptr:int64`; `(aes256_xts_decrypt ct (0x50 * i) iv key1 key2):byte list`; `s188:armstate`] BYTE_LIST_TO_NUM_THM) THEN ANTS_TAC THENL[ REWRITE_TAC[ARITH_RULE `0x50 * i = 0x10 * 5 * i`; LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS] THEN @@ -3035,7 +4338,7 @@ let AES_XTS_DECRYPT_CORRECT = prove( (* Subgoal 4: prove backedge is taken if i != val num_5blocks_adjusted *) REPEAT STRIP_TAC THEN - REWRITE_TAC[byte_list_at; set_key_schedule] THEN + REWRITE_TAC[byte_list_at] THEN ENSURES_INIT_TAC "s0" THEN ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (1--1) THEN SUBGOAL_THEN `~(val (word_sub (num_5blocks_adjusted:int64) (word i)) = 0x0)` ASSUME_TAC THENL @@ -3047,7 +4350,7 @@ let AES_XTS_DECRYPT_CORRECT = prove( (* Subgoal 5: Prove the invariant implies post-condition Backedge instruction is executed here *) REPEAT STRIP_TAC THEN - REWRITE_TAC[byte_list_at; set_key_schedule] THEN + REWRITE_TAC[byte_list_at] THEN SUBST_ALL_TAC (WORD_RULE `(word (val (num_5blocks_adjusted:int64))):int64 = num_5blocks_adjusted`) THEN MATCH_MP_TAC ENSURES_FRAME_SUBSUMED THEN @@ -3208,7 +4511,7 @@ let AES_XTS_DECRYPT_CORRECT = prove( i < 0x50 * val (num_5blocks_adjusted:int64) ==> read (memory :> bytes8 (word_add pt_ptr (word i))) s136 = EL i (aes256_xts_decrypt ct (0x50 * val num_5blocks_adjusted) iv key1 key2)` THEN - MP_TAC (SPECL [`0x50 * val (num_5blocks_adjusted:int64) + 0x40:num`; + MP_TAC (SPECL [`0x50 * val (num_5blocks_adjusted:int64) + 0x40:num`; `pt_ptr:int64`; `(aes256_xts_decrypt ct (0x50 * val (num_5blocks_adjusted:int64) + 0x40) iv key1 key2):byte list`; `s136:armstate`] BYTE_LIST_TO_NUM_THM) THEN ANTS_TAC THENL[ @@ -3217,7 +4520,7 @@ let AES_XTS_DECRYPT_CORRECT = prove( ARITH_TAC ; ALL_TAC] THEN DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN - MP_TAC (SPECL [`0x50 * val (num_5blocks_adjusted:int64):num`; + MP_TAC (SPECL [`0x50 * val (num_5blocks_adjusted:int64):num`; `pt_ptr:int64`; `(aes256_xts_decrypt ct (0x50 * val (num_5blocks_adjusted:int64)) iv key1 key2):byte list`; `s136:armstate`] BYTE_LIST_TO_NUM_THM) THEN ANTS_TAC THENL[ @@ -3555,7 +4858,7 @@ let AES_XTS_DECRYPT_CORRECT = prove( i < 0x50 * val (num_5blocks_adjusted:int64) ==> read (memory :> bytes8 (word_add pt_ptr (word i))) s108 = EL i (aes256_xts_decrypt ct (0x50 * val num_5blocks_adjusted) iv key1 key2)` THEN - MP_TAC (SPECL [`0x50 * val (num_5blocks_adjusted:int64) + 0x30:num`; + MP_TAC (SPECL [`0x50 * val (num_5blocks_adjusted:int64) + 0x30:num`; `pt_ptr:int64`; `(aes256_xts_decrypt ct (0x50 * val (num_5blocks_adjusted:int64) + 0x30) iv key1 key2):byte list`; `s108:armstate`] BYTE_LIST_TO_NUM_THM) THEN ANTS_TAC THENL[ @@ -3564,7 +4867,7 @@ let AES_XTS_DECRYPT_CORRECT = prove( ARITH_TAC ; ALL_TAC] THEN DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN - MP_TAC (SPECL [`0x50 * val (num_5blocks_adjusted:int64):num`; + MP_TAC (SPECL [`0x50 * val (num_5blocks_adjusted:int64):num`; `pt_ptr:int64`; `(aes256_xts_decrypt ct (0x50 * val (num_5blocks_adjusted:int64)) iv key1 key2):byte list`; `s108:armstate`] BYTE_LIST_TO_NUM_THM) THEN ANTS_TAC THENL[ @@ -3855,7 +5158,7 @@ let AES_XTS_DECRYPT_CORRECT = prove( i < 0x50 * val (num_5blocks_adjusted:int64) ==> read (memory :> bytes8 (word_add pt_ptr (word i))) s78 = EL i (aes256_xts_decrypt ct (0x50 * val num_5blocks_adjusted) iv key1 key2)` THEN - MP_TAC (SPECL [`0x50 * val (num_5blocks_adjusted:int64) + 0x20:num`; + MP_TAC (SPECL [`0x50 * val (num_5blocks_adjusted:int64) + 0x20:num`; `pt_ptr:int64`; `(aes256_xts_decrypt ct (0x50 * val (num_5blocks_adjusted:int64) + 0x20) iv key1 key2):byte list`; `s78:armstate`] BYTE_LIST_TO_NUM_THM) THEN ANTS_TAC THENL[ @@ -3864,7 +5167,7 @@ let AES_XTS_DECRYPT_CORRECT = prove( ARITH_TAC ; ALL_TAC] THEN DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN - MP_TAC (SPECL [`0x50 * val (num_5blocks_adjusted:int64):num`; + MP_TAC (SPECL [`0x50 * val (num_5blocks_adjusted:int64):num`; `pt_ptr:int64`; `(aes256_xts_decrypt ct (0x50 * val (num_5blocks_adjusted:int64)) iv key1 key2):byte list`; `s78:armstate`] BYTE_LIST_TO_NUM_THM) THEN ANTS_TAC THENL[ @@ -4100,7 +5403,7 @@ let AES_XTS_DECRYPT_CORRECT = prove( i < 0x50 * val (num_5blocks_adjusted:int64) ==> read (memory :> bytes8 (word_add pt_ptr (word i))) s50 = EL i (aes256_xts_decrypt ct (0x50 * val num_5blocks_adjusted) iv key1 key2)` THEN - MP_TAC (SPECL [`0x50 * val (num_5blocks_adjusted:int64) + 0x10:num`; + MP_TAC (SPECL [`0x50 * val (num_5blocks_adjusted:int64) + 0x10:num`; `pt_ptr:int64`; `(aes256_xts_decrypt ct (0x50 * val (num_5blocks_adjusted:int64) + 0x10) iv key1 key2):byte list`; `s50:armstate`] BYTE_LIST_TO_NUM_THM) THEN ANTS_TAC THENL[ @@ -4109,7 +5412,7 @@ let AES_XTS_DECRYPT_CORRECT = prove( ARITH_TAC ; ALL_TAC] THEN DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN - MP_TAC (SPECL [`0x50 * val (num_5blocks_adjusted:int64):num`; + MP_TAC (SPECL [`0x50 * val (num_5blocks_adjusted:int64):num`; `pt_ptr:int64`; `(aes256_xts_decrypt ct (0x50 * val (num_5blocks_adjusted:int64)) iv key1 key2):byte list`; `s50:armstate`] BYTE_LIST_TO_NUM_THM) THEN ANTS_TAC THENL[ @@ -4205,13 +5508,173 @@ let AES_XTS_DECRYPT_CORRECT = prove( [ MATCH_MP_TAC (SPECL [`val (num_blocks_adjusted:int64)`; `val (num_5blocks_adjusted:int64)`] DIVISION_BY_80_LEMMA) THEN REPEAT CONJ_TAC THENL [ - CHEAT_TAC; - CHEAT_TAC; - CHEAT_TAC; - CHEAT_TAC; - CHEAT_TAC; - CHEAT_TAC - ] + EXPAND_TAC "num_5blocks_adjusted" THEN + IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN + UNDISCH_TAC `val (num_blocks_adjusted:int64) <= 0x2 EXP 0x18` THEN + ARITH_TAC; + + EXPAND_TAC "num_blocks_adjusted" THEN + EXPAND_TAC "num_blocks" THEN + COND_CASES_TAC THENL + [ + REWRITE_TAC[NUM_BLOCKS_TO_VAL] THEN + IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT; DIVIDES_RMUL; DIVIDES_REFL] THEN + UNDISCH_TAC `val (len:int64) <= 0x2 EXP 0x18` THEN + ARITH_TAC; + + IMP_REWRITE_TAC[NUM_BLOCKS_MINUS1_TO_VAL] THEN + IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT; DIVIDES_RMUL; DIVIDES_REFL] THEN + UNDISCH_TAC `val (len:int64) <= 0x2 EXP 0x18` THEN + ARITH_TAC]; + + UNDISCH_TAC `~(val (word_sub + (word_sub (num_blocks_adjusted:int64) + (word_mul (word 0x50) (num_5blocks_adjusted:int64))) + (word 0x10)) = 0x0)` THEN + REWRITE_TAC[CONTRAPOS_THM] THEN + REWRITE_TAC[VAL_WORD_SUB_EQ_0; VAL_WORD_MUL; VAL_WORD; DIMINDEX_64; + ARITH_RULE `0x10 MOD 0x2 EXP 0x40 = 0x10`] THEN + REWRITE_TAC[VAL_WORD_SUB; VAL_WORD_MUL; VAL_WORD; DIMINDEX_64; + ARITH_RULE `0x50 MOD 0x2 EXP 0x40 = 0x50`] THEN + + SUBGOAL_THEN `0x50 * val (num_5blocks_adjusted:int64) < 2 EXP 64` ASSUME_TAC THENL + [ UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 <= val (len:int64)` THEN + UNDISCH_TAC `val (len:int64) <= 0x2 EXP 0x18` THEN + ARITH_TAC; ALL_TAC] THEN + MP_TAC (SPECL [`0x50 * val (num_5blocks_adjusted:int64)`; `2 EXP 64`] MOD_LT) THEN + ANTS_TAC THENL [ASM_SIMP_TAC[]; ALL_TAC] THEN + SIMP_TAC[] THEN DISCH_TAC THEN + + MP_TAC (SPECL [`val (num_blocks_adjusted:int64)`; `0x2 EXP 0x40`; + `0x50 * val (num_5blocks_adjusted:int64)`] + (ARITH_RULE `!a b c. c <= a ==> c <= b ==> a + b - c = (a - c) + b`)) THEN + ANTS_TAC THENL [ + UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 <= val (num_blocks_adjusted:int64)` THEN + SIMP_TAC[MULT_SYM]; ALL_TAC] THEN + ANTS_TAC THENL [ + UNDISCH_TAC `0x50 * val (num_5blocks_adjusted:int64) < 2 EXP 64` THEN + ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[] THEN DISCH_TAC THEN + + MP_TAC (SPECL [`1`; `0x2 EXP 0x40`; + `val (num_blocks_adjusted:int64) - 0x50 * val (num_5blocks_adjusted:int64)`] + (CONJUNCT1 (CONJUNCT2 (CONJUNCT2 MOD_MULT_ADD)))) THEN + REWRITE_TAC[ARITH_RULE `1 * 2 EXP 64 = 2 EXP 64`] THEN + SIMP_TAC[] THEN DISCH_TAC THEN + SIMP_TAC[MULT_SYM] THEN DISCH_TAC THEN + CONV_TAC NUM_REDUCE_CONV; + + UNDISCH_TAC `~(val (word_sub + (word_sub (num_blocks_adjusted:int64) + (word_mul (word 0x50) (num_5blocks_adjusted:int64))) + (word 0x20)) = 0x0)` THEN + REWRITE_TAC[CONTRAPOS_THM] THEN + REWRITE_TAC[VAL_WORD_SUB_EQ_0; VAL_WORD_MUL; VAL_WORD; DIMINDEX_64; + ARITH_RULE `0x20 MOD 0x2 EXP 0x40 = 0x20`] THEN + REWRITE_TAC[VAL_WORD_SUB; VAL_WORD_MUL; VAL_WORD; DIMINDEX_64; + ARITH_RULE `0x50 MOD 0x2 EXP 0x40 = 0x50`] THEN + + SUBGOAL_THEN `0x50 * val (num_5blocks_adjusted:int64) < 2 EXP 64` ASSUME_TAC THENL + [ UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 <= val (len:int64)` THEN + UNDISCH_TAC `val (len:int64) <= 0x2 EXP 0x18` THEN + ARITH_TAC; ALL_TAC] THEN + MP_TAC (SPECL [`0x50 * val (num_5blocks_adjusted:int64)`; `2 EXP 64`] MOD_LT) THEN + ANTS_TAC THENL [ASM_SIMP_TAC[]; ALL_TAC] THEN + SIMP_TAC[] THEN DISCH_TAC THEN + + MP_TAC (SPECL [`val (num_blocks_adjusted:int64)`; `0x2 EXP 0x40`; + `0x50 * val (num_5blocks_adjusted:int64)`] + (ARITH_RULE `!a b c. c <= a ==> c <= b ==> a + b - c = (a - c) + b`)) THEN + ANTS_TAC THENL [ + UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 <= val (num_blocks_adjusted:int64)` THEN + SIMP_TAC[MULT_SYM]; ALL_TAC] THEN + ANTS_TAC THENL [ + UNDISCH_TAC `0x50 * val (num_5blocks_adjusted:int64) < 2 EXP 64` THEN + ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[] THEN DISCH_TAC THEN + + MP_TAC (SPECL [`1`; `0x2 EXP 0x40`; + `val (num_blocks_adjusted:int64) - 0x50 * val (num_5blocks_adjusted:int64)`] + (CONJUNCT1 (CONJUNCT2 (CONJUNCT2 MOD_MULT_ADD)))) THEN + REWRITE_TAC[ARITH_RULE `1 * 2 EXP 64 = 2 EXP 64`] THEN + SIMP_TAC[] THEN DISCH_TAC THEN + SIMP_TAC[MULT_SYM] THEN DISCH_TAC THEN + CONV_TAC NUM_REDUCE_CONV; + + UNDISCH_TAC `~(val (word_sub + (word_sub (num_blocks_adjusted:int64) + (word_mul (word 0x50) (num_5blocks_adjusted:int64))) + (word 0x30)) = 0x0)` THEN + REWRITE_TAC[CONTRAPOS_THM] THEN + REWRITE_TAC[VAL_WORD_SUB_EQ_0; VAL_WORD_MUL; VAL_WORD; DIMINDEX_64; + ARITH_RULE `0x30 MOD 0x2 EXP 0x40 = 0x30`] THEN + REWRITE_TAC[VAL_WORD_SUB; VAL_WORD_MUL; VAL_WORD; DIMINDEX_64; + ARITH_RULE `0x50 MOD 0x2 EXP 0x40 = 0x50`] THEN + + SUBGOAL_THEN `0x50 * val (num_5blocks_adjusted:int64) < 2 EXP 64` ASSUME_TAC THENL + [ UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 <= val (len:int64)` THEN + UNDISCH_TAC `val (len:int64) <= 0x2 EXP 0x18` THEN + ARITH_TAC; ALL_TAC] THEN + MP_TAC (SPECL [`0x50 * val (num_5blocks_adjusted:int64)`; `2 EXP 64`] MOD_LT) THEN + ANTS_TAC THENL [ASM_SIMP_TAC[]; ALL_TAC] THEN + SIMP_TAC[] THEN DISCH_TAC THEN + + MP_TAC (SPECL [`val (num_blocks_adjusted:int64)`; `0x2 EXP 0x40`; + `0x50 * val (num_5blocks_adjusted:int64)`] + (ARITH_RULE `!a b c. c <= a ==> c <= b ==> a + b - c = (a - c) + b`)) THEN + ANTS_TAC THENL [ + UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 <= val (num_blocks_adjusted:int64)` THEN + SIMP_TAC[MULT_SYM]; ALL_TAC] THEN + ANTS_TAC THENL [ + UNDISCH_TAC `0x50 * val (num_5blocks_adjusted:int64) < 2 EXP 64` THEN + ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[] THEN DISCH_TAC THEN + + MP_TAC (SPECL [`1`; `0x2 EXP 0x40`; + `val (num_blocks_adjusted:int64) - 0x50 * val (num_5blocks_adjusted:int64)`] + (CONJUNCT1 (CONJUNCT2 (CONJUNCT2 MOD_MULT_ADD)))) THEN + REWRITE_TAC[ARITH_RULE `1 * 2 EXP 64 = 2 EXP 64`] THEN + SIMP_TAC[] THEN DISCH_TAC THEN + SIMP_TAC[MULT_SYM] THEN DISCH_TAC THEN + CONV_TAC NUM_REDUCE_CONV; + + UNDISCH_TAC `~(val (word_sub + (word_sub (num_blocks_adjusted:int64) + (word_mul (word 0x50) (num_5blocks_adjusted:int64))) + (word 0x40)) = 0x0)` THEN + REWRITE_TAC[CONTRAPOS_THM] THEN + REWRITE_TAC[VAL_WORD_SUB_EQ_0; VAL_WORD_MUL; VAL_WORD; DIMINDEX_64; + ARITH_RULE `0x40 MOD 0x2 EXP 0x40 = 0x40`] THEN + REWRITE_TAC[VAL_WORD_SUB; VAL_WORD_MUL; VAL_WORD; DIMINDEX_64; + ARITH_RULE `0x50 MOD 0x2 EXP 0x40 = 0x50`] THEN + + SUBGOAL_THEN `0x50 * val (num_5blocks_adjusted:int64) < 2 EXP 64` ASSUME_TAC THENL + [ UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 <= val (len:int64)` THEN + UNDISCH_TAC `val (len:int64) <= 0x2 EXP 0x18` THEN + ARITH_TAC; ALL_TAC] THEN + MP_TAC (SPECL [`0x50 * val (num_5blocks_adjusted:int64)`; `2 EXP 64`] MOD_LT) THEN + ANTS_TAC THENL [ASM_SIMP_TAC[]; ALL_TAC] THEN + SIMP_TAC[] THEN DISCH_TAC THEN + + MP_TAC (SPECL [`val (num_blocks_adjusted:int64)`; `0x2 EXP 0x40`; + `0x50 * val (num_5blocks_adjusted:int64)`] + (ARITH_RULE `!a b c. c <= a ==> c <= b ==> a + b - c = (a - c) + b`)) THEN + ANTS_TAC THENL [ + UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 <= val (num_blocks_adjusted:int64)` THEN + SIMP_TAC[MULT_SYM]; ALL_TAC] THEN + ANTS_TAC THENL [ + UNDISCH_TAC `0x50 * val (num_5blocks_adjusted:int64) < 2 EXP 64` THEN + ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[] THEN DISCH_TAC THEN + + MP_TAC (SPECL [`1`; `0x2 EXP 0x40`; + `val (num_blocks_adjusted:int64) - 0x50 * val (num_5blocks_adjusted:int64)`] + (CONJUNCT1 (CONJUNCT2 (CONJUNCT2 MOD_MULT_ADD)))) THEN + REWRITE_TAC[ARITH_RULE `1 * 2 EXP 64 = 2 EXP 64`] THEN + SIMP_TAC[] THEN DISCH_TAC THEN + SIMP_TAC[MULT_SYM] THEN DISCH_TAC THEN + CONV_TAC NUM_REDUCE_CONV + ] ; ALL_TAC] THEN SUBGOAL_THEN `~(val (num_5blocks_adjusted:int64) * 0x50 + 0x40 = val (num_blocks_adjusted:int64))` ASSUME_TAC THENL @@ -4241,52 +5704,687 @@ let AES_XTS_DECRYPT_CORRECT = prove( ] (* End of loop invariant proof *) ; ALL_TAC] THEN - (* prove the rest of the program, basically cipher stealing *) - REWRITE_TAC[byte_list_at; set_key_schedule] THEN - (* Start symbolic simulation*) - ENSURES_INIT_TAC "s0" THEN - (* Simulate until the first tweak and verify the first tweak equiv the spec *) - ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (1--2) THEN - FIRST_X_ASSUM MP_TAC THEN - COND_CASES_TAC THENL - [ (* tail = 0 *) - DISCH_TAC THEN + (* Prove more properties about num_blocks_adjusted and num_5blocks_adjusted *) + SUBGOAL_THEN `val (num_blocks_adjusted:int64) DIV 0x50 = val (num_5blocks_adjusted:int64)` ASSUME_TAC THENL + [ EXPAND_TAC "num_5blocks_adjusted" THEN + IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN + UNDISCH_TAC `val (num_blocks_adjusted:int64) <= 0x2 EXP 0x18` THEN + ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `0x10 divides val (num_blocks_adjusted:int64)` ASSUME_TAC THENL + [ EXPAND_TAC "num_blocks_adjusted" THEN + EXPAND_TAC "num_blocks" THEN + COND_CASES_TAC THENL + [ REWRITE_TAC[NUM_BLOCKS_TO_VAL] THEN + IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT; DIVIDES_RMUL; DIVIDES_REFL] THEN + UNDISCH_TAC `val (len:int64) <= 0x2 EXP 0x18` THEN + ARITH_TAC; + + IMP_REWRITE_TAC[NUM_BLOCKS_MINUS1_TO_VAL] THEN + IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT; DIVIDES_RMUL; DIVIDES_REFL] THEN + UNDISCH_TAC `val (len:int64) <= 0x2 EXP 0x18` THEN + ARITH_TAC]; ALL_TAC] THEN + + (* If no tail, execute to the end *) + ASM_CASES_TAC `val (tail_len:int64) = 0` THENL + [ + REWRITE_TAC[byte_list_at] THEN + ENSURES_INIT_TAC "s0" THEN + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (1--2) THEN + (* Discharge if condition *) + SUBGOAL_THEN `val (word_and (tail_len:int64) (word 0xf)) = 0x0` MP_TAC THENL + [ UNDISCH_TAC `val (tail_len:int64) = 0x0` THEN BITBLAST_TAC; ALL_TAC] THEN + ASM_REWRITE_TAC[] THEN DISCH_TAC THEN + POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th])) THEN + ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN `val (word (acc_len (num_5blocks_adjusted:int64) (num_blocks_adjusted:int64)):int64) = acc_len num_5blocks_adjusted num_blocks_adjusted` ASSUME_TAC THENL - [ CHEAT_TAC; ALL_TAC] THEN + [ IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN + MP_TAC (SPECL [`num_5blocks_adjusted:int64`; `num_blocks_adjusted:int64`; `2 EXP 64`] + BOUND_OF_ACC_LEN) THEN + ANTS_TAC THENL [ ASM_ARITH_TAC; ALL_TAC] THEN + ANTS_TAC THENL [ ASM_SIMP_TAC[]; ALL_TAC] THEN + ANTS_TAC THENL [ ASM_SIMP_TAC[]; ALL_TAC] THEN + ANTS_TAC THENL [ ASM_ARITH_TAC; ALL_TAC] THEN + SIMP_TAC[]; ALL_TAC] THEN POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th])) THEN (* Prove that acc_len is equal to total len because there is no tail *) SUBGOAL_THEN `val (len:int64) = acc_len (num_5blocks_adjusted:int64) (num_blocks_adjusted:int64)` SUBST1_TAC THENL - [ CHEAT_TAC; ALL_TAC] THEN - ASM_SIMP_TAC[]; - ALL_TAC + [ SUBGOAL_THEN `len = (num_blocks:int64)` SUBST1_TAC THENL + [ EXPAND_TAC "len" THEN + SUBGOAL_THEN `tail_len:int64 = word 0` ASSUME_TAC THENL + [ REWRITE_TAC[GSYM VAL_EQ_0] THEN ASM_REWRITE_TAC[]; ALL_TAC] THEN + REWRITE_TAC[ASSUME `tail_len:int64 = word 0`; WORD_ADD_0] + ; ALL_TAC] THEN + SUBGOAL_THEN `num_blocks = (num_blocks_adjusted:int64)` SUBST1_TAC THENL + [ EXPAND_TAC "num_blocks_adjusted" THEN + REWRITE_TAC[ASSUME `val (tail_len:int64) = 0`] + ; ALL_TAC] THEN + REWRITE_TAC[acc_len] THEN + REPEAT_N 4 (COND_CASES_TAC THENL[ASM_ARITH_TAC; ALL_TAC]) THEN + + CONV_TAC SYM_CONV THEN + REWRITE_TAC[ARITH_RULE `!a. 0x50 * a = a * 0x50`] THEN + MATCH_MP_TAC (SPECL [`val (num_blocks_adjusted:int64)`; `val (num_5blocks_adjusted:int64)`] DIVISION_BY_80_LEMMA) THEN + REPEAT CONJ_TAC THENL + [ + ASM_SIMP_TAC[]; + ASM_SIMP_TAC[]; + + UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 <= val (num_blocks_adjusted:int64)` THEN + UNDISCH_TAC `~(val (num_5blocks_adjusted:int64) * 0x50 + 0x10 = val (num_blocks_adjusted:int64))` THEN + ARITH_TAC; + + UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 <= val (num_blocks_adjusted:int64)` THEN + UNDISCH_TAC `~(val (num_5blocks_adjusted:int64) * 0x50 + 0x20 = val (num_blocks_adjusted:int64))` THEN + ARITH_TAC; + + UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 <= val (num_blocks_adjusted:int64)` THEN + UNDISCH_TAC `~(val (num_5blocks_adjusted:int64) * 0x50 + 0x30 = val (num_blocks_adjusted:int64))` THEN + ARITH_TAC; + + UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 <= val (num_blocks_adjusted:int64)` THEN + UNDISCH_TAC `~(val (num_5blocks_adjusted:int64) * 0x50 + 0x40 = val (num_blocks_adjusted:int64))` THEN + ARITH_TAC] + ; ALL_TAC] THEN + ASM_SIMP_TAC[] + ; ALL_TAC] THEN + + (* The cipher stealing branch *) + (* Break the rest of the program into two parts: before byte-swap and after. + This is because byte-swap needs another invariant proof. *) + ABBREV_TAC `curr_len = (acc_len (num_5blocks_adjusted:int64) (num_blocks_adjusted:int64)):num` THEN + ABBREV_TAC `curr_blocks = (acc_blocks (num_5blocks_adjusted:int64) (num_blocks_adjusted:int64) T):num` THEN + + SUBGOAL_THEN `curr_len + 0x10 <= val (len:int64)` ASSUME_TAC THENL + [ EXPAND_TAC "curr_len" THEN + MP_TAC (SPECL [`num_5blocks_adjusted:int64`; `num_blocks_adjusted:int64`] VALUE_OF_ACC_LEN) THEN + REPEAT_N 3 (ANTS_TAC THENL [ASM_ARITH_TAC ORELSE ASM_SIMP_TAC[]; ALL_TAC]) THEN + SIMP_TAC[] THEN DISCH_TAC THEN + EXPAND_TAC "num_blocks_adjusted" THEN + SIMP_TAC[ASSUME `~(val (tail_len:int64) = 0)`] THEN + UNDISCH_TAC `val (num_blocks:int64) <= val (len:int64)` THEN + UNDISCH_TAC `~(val (num_blocks:int64) < 0x60)` THEN + WORD_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `val ((word curr_len):int64) = curr_len` ASSUME_TAC THENL + [ IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN + EXPAND_TAC "curr_len" THEN + MP_TAC (SPECL [`num_5blocks_adjusted:int64`; `num_blocks_adjusted:int64`; `2 EXP 64`] + BOUND_OF_ACC_LEN) THEN + ANTS_TAC THENL [ ASM_ARITH_TAC; ALL_TAC] THEN + ANTS_TAC THENL [ ASM_SIMP_TAC[]; ALL_TAC] THEN + ANTS_TAC THENL [ ASM_SIMP_TAC[]; ALL_TAC] THEN + ANTS_TAC THENL [ ASM_ARITH_TAC; ALL_TAC] THEN + SIMP_TAC[]; ALL_TAC] THEN + + ENSURES_SEQUENCE_TAC `pc + 0xab8` + `\s. + read X0 s = word_add (word_add ct_ptr (word curr_len)) (word 0x10) /\ + read X1 s = word_add pt_ptr (word curr_len) /\ + read X21 s = tail_len /\ + read Q6 s = calculate_tweak curr_blocks iv key2 /\ + read Q16 s = k00 /\ read Q17 s = k01 /\ read Q12 s = k02 /\ read Q13 s = k03 /\ + read Q14 s = k04 /\ read Q15 s = k05 /\ read Q4 s = k06 /\ read Q5 s = k07 /\ + read Q18 s = k08 /\ read Q19 s = k09 /\ read Q20 s = k0a /\ read Q21 s = k0b /\ + read Q22 s = k0c /\ read Q23 s = k0d /\ read Q7 s = k0e /\ + + byte_list_at ct ct_ptr len s /\ + byte_list_at (aes256_xts_decrypt ct curr_len iv key1 key2) pt_ptr (word curr_len) s /\ + read (memory :> bytes128 (word_add pt_ptr (word curr_len))) s = + aes256_xts_decrypt_round + (bytes_to_int128 (SUB_LIST (curr_len,0x10) ct)) + (calculate_tweak (curr_blocks + 0x1) iv key2) + key1` THEN + CONJ_TAC THENL + [ + MATCH_MP_TAC ENSURES_FRAME_SUBSUMED THEN + EXISTS_TAC `MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI ,, + MAYCHANGE [X19; X20; X21; X22],, + MAYCHANGE [Q8; Q9; Q10; Q11; Q12; Q13; Q14; Q15],, + MAYCHANGE [memory :> bytes128 (word_add pt_ptr (word curr_len))]` THEN + REWRITE_TAC[MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI] THEN + CONJ_TAC THENL [ + REPEAT (GEN_REWRITE_TAC ONCE_DEPTH_CONV [GSYM SEQ_ASSOC] THEN + MATCH_MP_TAC SUBSUMED_SEQ THEN REWRITE_TAC[SUBSUMED_REFL]) THEN + ABBREV_TAC `vallen = val (len:int64)` THEN + SUBSUMED_MAYCHANGE_TAC; ALL_TAC] THEN + + REWRITE_TAC[byte_list_at] THEN + UNDISCH_THEN `val ((word curr_len):int64) = curr_len` + (fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th]) THEN REWRITE_TAC[th]) THEN + + ENSURES_INIT_TAC "s0" THEN + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (1--2) THEN + + (* Discharge if condition *) + SUBGOAL_THEN `~(val (word_and (tail_len:int64) (word 0xf)) = 0x0)` MP_TAC THENL + [ UNDISCH_TAC `~(val (tail_len:int64) = 0x0)` THEN + UNDISCH_TAC `val (tail_len:int64) < 16` THEN + MP_TAC (SPEC `tail_len:int64` WORD_AND_MASK16_EQ_0) THEN + SIMP_TAC[]; ALL_TAC] THEN + ASM_REWRITE_TAC[] THEN DISCH_TAC THEN + POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th])) THEN + + (* Decrypt last block *) + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (3--11) THEN + TWEAK_TAC `Q8:(armstate,int128)component` `(curr_blocks + 1):num` `curr_blocks:num` THEN + MP_TAC (SPECL [`ct_ptr:int64`; `curr_len:num`; `len:int64`; `ct:byte list`; `s11:armstate`] READ_CT_LAST_LEMMA) THEN + ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (12--42) THEN + XTSDEC_TAC `Q26:(armstate,int128)component` `curr_len:num` `(curr_blocks + 1):num` THEN + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (43--43) THEN + + ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] + ; ALL_TAC ] THEN - (* cipher stealing branch *) - DISCH_TAC THEN - ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (1--9) THEN - (* Simplify Q8 *) - FIRST_X_ASSUM(MP_TAC - o SPEC `calculate_tweak ((acc_blocks (num_5blocks_adjusted:int64) (num_blocks_adjusted:int64) T) + 1) (iv:int128) (key2:int128 list)` - o MATCH_MP (MESON[] `read (reg:(armstate,int128)component) (s:armstate) = a ==> !a'. a = a' ==> read reg s = a'`)) THEN - ANTS_TAC THENL - [ CHEAT_TAC; DISCH_TAC] THEN + ABBREV_TAC `PP = aes256_xts_decrypt_round + (bytes_to_int128 (SUB_LIST (curr_len,0x10) (ct:byte list))) + (calculate_tweak (curr_blocks + 0x1) (iv:int128) (key2:int128 list)) + (key1:int128 list)` THEN + SUBGOAL_THEN `curr_len + 16 + val (tail_len:int64) = val (len:int64)` ASSUME_TAC THENL + [ REWRITE_TAC[GSYM (ASSUME `acc_len num_5blocks_adjusted num_blocks_adjusted = curr_len`)] THEN + MP_TAC (SPECL [`num_5blocks_adjusted:int64`; `num_blocks_adjusted:int64`] VALUE_OF_ACC_LEN) THEN + ANTS_TAC THENL[ASM_ARITH_TAC; ALL_TAC] THEN + ANTS_TAC THENL[ASM_ARITH_TAC; ALL_TAC] THEN + ANTS_TAC THENL[ASM_SIMP_TAC[]; ALL_TAC] THEN + SIMP_TAC[] THEN DISCH_TAC THEN + EXPAND_TAC "num_blocks_adjusted" THEN + UNDISCH_TAC `~(val (tail_len:int64) = 0)` THEN + SIMP_TAC[] THEN DISCH_TAC THEN + ASM_SIMP_TAC[VAL_WORD_SUB; DIMINDEX_64; VAL_WORD; + ARITH_RULE `16 MOD 2 EXP 64 = 16`] THEN + MP_TAC (SPECL [`val (num_blocks:int64)`; `0x2 EXP 0x40`; `16`] + (ARITH_RULE `!a b c. c <= a ==> c <= b ==> a + b - c = (a - c) + b`)) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN + ANTS_TAC THENL [ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[] THEN DISCH_TAC THEN + MP_TAC (SPECL [`1`; `0x2 EXP 0x40`; `val (num_blocks:int64) - 16`] + (CONJUNCT1 (CONJUNCT2 (CONJUNCT2 MOD_MULT_ADD)))) THEN + SIMP_TAC[ARITH_RULE `!x. 1 * x = x`] THEN DISCH_TAC THEN + IMP_REWRITE_TAC[MOD_LT] THEN + CONJ_TAC THENL [ + SUBGOAL_THEN `val (num_blocks:int64) - 0x10 + 0x10 + val (tail_len:int64) + = val num_blocks + val tail_len` SUBST1_TAC THENL + [ IMP_REWRITE_TAC[ADD_ASSOC; SUB_ADD] THEN ASM_ARITH_TAC; ALL_TAC] THEN + EXPAND_TAC "len" THEN + REWRITE_TAC[VAL_WORD_ADD] THEN + IMP_REWRITE_TAC[MOD_LT; DIMINDEX_64] THEN + CONJ_TAC THENL [ARITH_TAC; ASM_ARITH_TAC]; + ALL_TAC + ] THEN + ASM_ARITH_TAC; ALL_TAC] THEN + (* Invariant proof for .composite_dec_loop *) + (* Invariant: + X0 points to tail of ct + X1 points to starting of last full block of pt + X13 points to tail of pt + X20 points to tail of ct + X21 holds tail_len + Q6 holds second to last tweak + Q16 ... Q7 holds the key schedule for encryption + + Memory: ct_ptr points to the input + Memory: Up to the last block, the output matches the specification + Memory: For the last block, for each byte + [0,i) -- previous decrption result + [i,tail_len) -- equal corresponding ct tail bytes + [tail_len,16] -- previous decryption result + Memory: For the tail, for each byte + [i,tail_len) -- copied over from last pt block + *) + ENSURES_WHILE_PADOWN_TAC + `val (tail_len:int64)` + `0` + `pc + 0xac0` + `pc + 0xad4` + `\i s. + ( read X0 s = word_add (word_add ct_ptr (word curr_len)) (word 0x10) /\ + read X1 s = word_add pt_ptr (word curr_len) /\ + read X13 s = word_add (word_add pt_ptr (word curr_len)) (word 0x10) /\ + read X20 s = word_add (word_add ct_ptr (word curr_len)) (word 0x10) /\ + read X21 s = (word i):int64 /\ + read Q6 s = calculate_tweak curr_blocks iv key2 /\ + read Q16 s = k00 /\ read Q17 s = k01 /\ read Q12 s = k02 /\ read Q13 s = k03 /\ + read Q14 s = k04 /\ read Q15 s = k05 /\ read Q4 s = k06 /\ read Q5 s = k07 /\ + read Q18 s = k08 /\ read Q19 s = k09 /\ read Q20 s = k0a /\ read Q21 s = k0b /\ + read Q22 s = k0c /\ read Q23 s = k0d /\ read Q7 s = k0e /\ + byte_list_at ct ct_ptr len s /\ + byte_list_at (aes256_xts_decrypt ct curr_len iv key1 key2) pt_ptr (word curr_len) s /\ - ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (10--40) THEN + read (memory :> bytes128 (word_add pt_ptr (word curr_len))) s = + cipher_stealing_inv i curr_len (val (tail_len:int64)) PP ct /\ - let tm = subst [`(acc_len (num_5blocks_adjusted:int64) (num_blocks_adjusted:int64)):num`, `ind:num`; - `(acc_blocks (num_5blocks_adjusted:int64) (num_blocks_adjusted:int64) T):num`, `ind_tweak:num`] - `aes256_xts_decrypt_round (bytes_to_int128 (SUB_LIST (ind,0x10) (ct:byte list))) - (calculate_tweak ind_tweak iv key2) key1` in - let lemma = subst [`Q26:(armstate,int128)component`, `reg:(armstate,int128)component`] - `read (reg:(armstate,int128)component) (s:armstate) = a ==> !a'. a = a' ==> read reg s = a'` in - FIRST_X_ASSUM(MP_TAC o SPEC tm o MATCH_MP (MESON[] lemma)) THEN - ANTS_TAC THENL - [ EXPAND_TAC "key1" THEN - CONV_TAC (RAND_CONV ( - REWRITE_CONV [aes256_xts_decrypt_round] THENC - DEPTH_CONV let_CONV)) THEN - AESDEC_TAC; DISCH_TAC ] + byte_list_at (SUB_LIST (i, val tail_len - i) (int128_to_bytes PP)) + (word_add pt_ptr (word (curr_len + 0x10 + i))) + (word ((val tail_len) - i)) s) /\ + // loop backedge condition + (read ZF s <=> i = 0) /\ + (read NF s <=> ival ((word i):int64) < &0) /\ + (read VF s <=> ~(ival ((word (i + 1)):int64) - &1 = ival ((word i):int64)))` THEN + ASM_REWRITE_TAC[] THEN REPEAT CONJ_TAC THENL + [ + (* Subgoal1: 0 < val tail_len *) + ASM_ARITH_TAC; + + (* Subgoal2: invariant holds before entering loop *) + REWRITE_TAC[byte_list_at] THEN + UNDISCH_THEN `val ((word curr_len):int64) = curr_len` + (fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th]) THEN REWRITE_TAC[th]) THEN + + ENSURES_INIT_TAC "s0" THEN + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (1--2) THEN + ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN + REPEAT CONJ_TAC THENL + [ + REWRITE_TAC[WORD_VAL]; + + REWRITE_TAC[cipher_stealing_inv; SUB_REFL] THEN + SUBGOAL_THEN `SUB_LIST (val (tail_len:int64),0x0) (SUB_LIST (curr_len + 16,val tail_len) (ct:byte list)) = []` SUBST1_TAC THENL + [ REWRITE_TAC[SUB_LIST_CLAUSES]; ALL_TAC] THEN + REWRITE_TAC[CONJUNCT1 APPEND] THEN + SUBGOAL_THEN `APPEND (SUB_LIST (0x0,val (tail_len:int64)) (int128_to_bytes PP)) + (SUB_LIST (val tail_len,0x10 - val tail_len) (int128_to_bytes PP)) = + (int128_to_bytes PP)` SUBST1_TAC THENL + [ MP_TAC (ISPECL [`int128_to_bytes PP`; `val (tail_len:int64)`; `16 - val (tail_len:int64)`; `0`] (GSYM SUB_LIST_SPLIT)) THEN + IMP_REWRITE_TAC[ADD_CLAUSES; ARITH_RULE `!x. x < 16 ==> x + 16 - x = 16`] THEN + DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES; LENGTH_OF_INT128_TO_BYTES] + ; ALL_TAC] THEN + REWRITE_TAC[BYTES_TO_INT128_OF_INT128_TO_BYTES]; + + REWRITE_TAC[VAL_WORD_0] THEN ARITH_TAC + ]; + + (* Subgoal 3: inductive step *) + REPEAT STRIP_TAC THEN + + (* For non-overlapping and MAYCHANGE address reasoning *) + SUBGOAL_THEN `curr_len + 16 + i < val (len:int64)` ASSUME_TAC THENL + [ REWRITE_TAC[GSYM (ASSUME `acc_len num_5blocks_adjusted num_blocks_adjusted = curr_len`)] THEN + MP_TAC (SPECL [`num_5blocks_adjusted:int64`; `num_blocks_adjusted:int64`] VALUE_OF_ACC_LEN) THEN + REPEAT_N 3 (ANTS_TAC THENL [ASM_ARITH_TAC ORELSE ASM_SIMP_TAC[]; ALL_TAC]) THEN + SIMP_TAC[] THEN DISCH_TAC THEN + EXPAND_TAC "num_blocks_adjusted" THEN + SIMP_TAC[ASSUME `~(val (tail_len:int64) = 0)`] THEN + REWRITE_TAC[VAL_WORD_SUB; DIMINDEX_64] THEN + MP_TAC (SPECL [`val (num_blocks:int64)`; `0x2 EXP 0x40`; `val ((word 0x10):int64)`] + (ARITH_RULE `!a b c. c <= a ==> c <= b ==> a + b - c = (a - c) + b`)) THEN + ANTS_TAC THENL [ + IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN ASM_ARITH_TAC + ; ALL_TAC] THEN + ANTS_TAC THENL [ WORD_ARITH_TAC; ALL_TAC] THEN + SIMP_TAC[] THEN DISCH_TAC THEN + MP_TAC (SPECL [`1`; `0x2 EXP 0x40`; `val (num_blocks:int64) - val ((word 0x10):int64)`] + (CONJUNCT1 (CONJUNCT2 (CONJUNCT2 MOD_MULT_ADD)))) THEN + SIMP_TAC[ARITH_RULE `!x. 1 * x = x`] THEN DISCH_TAC THEN + IMP_REWRITE_TAC[MOD_LT] THEN + IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN + CONV_TAC NUM_REDUCE_CONV THEN + EXPAND_TAC "len" THEN + IMP_REWRITE_TAC[VAL_WORD_ADD; DIMINDEX_64; MOD_LT] THEN + UNDISCH_TAC `val (num_blocks:int64) <= val (len:int64)` THEN + UNDISCH_TAC `~(val (num_blocks:int64) < 0x60)` THEN + UNDISCH_TAC `val (num_blocks:int64) <= 0x2 EXP 0x18` THEN + UNDISCH_TAC `i < val (tail_len:int64)` THEN + UNDISCH_TAC `val (tail_len:int64) < 0x10` THEN + ARITH_TAC + ; ALL_TAC] THEN + + MATCH_MP_TAC ENSURES_FRAME_SUBSUMED THEN + EXISTS_TAC `MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI ,, + MAYCHANGE [X19; X20; X21; X22],, + MAYCHANGE [Q8; Q9; Q10; Q11; Q12; Q13; Q14; Q15],, + MAYCHANGE [memory :> bytes8 (word_add pt_ptr (word (curr_len + 0x10 + i)))],, + MAYCHANGE [memory :> bytes8 (word_add pt_ptr (word (curr_len + i)))]` THEN + REWRITE_TAC[MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI] THEN + CONJ_TAC THENL [ + REPEAT (GEN_REWRITE_TAC ONCE_DEPTH_CONV [GSYM SEQ_ASSOC] THEN + MATCH_MP_TAC SUBSUMED_SEQ THEN REWRITE_TAC[SUBSUMED_REFL]) THEN + ABBREV_TAC `vallen = val (len:int64)` THEN + SUBSUMED_MAYCHANGE_TAC; ALL_TAC] THEN + + REWRITE_TAC[byte_list_at] THEN + UNDISCH_THEN `val ((word curr_len):int64) = curr_len` + (fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th]) THEN REWRITE_TAC[th]) THEN + ENSURES_INIT_TAC "s0" THEN + + SUBGOAL_THEN `val ((word (val (tail_len:int64) - i)):int64) = val tail_len - i` SUBST_ALL_TAC THENL + [ IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN + UNDISCH_TAC `i < val (tail_len:int64)` THEN + UNDISCH_TAC `val (tail_len:int64) < 0x10` THEN + ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `val ((word (val (tail_len:int64) - (i + 0x1))):int64) = val tail_len - (i + 1)` SUBST_ALL_TAC THENL + [ IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN + UNDISCH_TAC `i < val (tail_len:int64)` THEN + UNDISCH_TAC `val (tail_len:int64) < 0x10` THEN + ARITH_TAC; ALL_TAC] THEN + + SUBGOAL_THEN `word_sub ((word (i + 0x1)):int64) (word 0x1) = word i` ASSUME_TAC THENL + [ REWRITE_TAC[GSYM VAL_EQ; VAL_WORD_SUB; DIMINDEX_64] THEN + MP_TAC (SPECL [`val ((word (i + 0x1)):int64)`; `0x2 EXP 0x40`; `val ((word 0x1):int64)`] + (ARITH_RULE `!a b c. c <= a ==> c <= b ==> a + b - c = (a - c) + b`)) THEN + ANTS_TAC THENL [ + IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN ASM_ARITH_TAC + ; ALL_TAC] THEN + ANTS_TAC THENL [ WORD_ARITH_TAC; ALL_TAC] THEN + SIMP_TAC[] THEN DISCH_TAC THEN + MP_TAC (SPECL [`1`; `0x2 EXP 0x40`; `val ((word (i + 0x1)):int64) - val ((word 0x1):int64)`] + (CONJUNCT1 (CONJUNCT2 (CONJUNCT2 MOD_MULT_ADD)))) THEN + SIMP_TAC[ARITH_RULE `!x. 1 * x = x`] THEN DISCH_TAC THEN + IMP_REWRITE_TAC[MOD_LT] THEN + CONJ_TAC THENL + [ SUBGOAL_THEN `i + 1 < 2 EXP 64` MP_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN + IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN + ARITH_TAC; + UNDISCH_TAC `i < val (tail_len:int64)` THEN + UNDISCH_TAC `val (tail_len:int64) < 0x10` THEN + WORD_ARITH_TAC] + ; ALL_TAC] THEN + + MP_TAC (SPECL [`(word_add pt_ptr (word curr_len)):int64`; `word i:int64`; `s0:armstate`; + `(cipher_stealing_inv (i + 0x1) curr_len (val (tail_len:int64)) PP ct):int128`] + SELECT_ONE_BYTE_FROM_BLOCK) THEN + + SUBGOAL_THEN `val ((word i):int64) < 0x10` ASSUME_TAC THENL + [ UNDISCH_TAC `i < val (tail_len:int64)` THEN + UNDISCH_TAC `val (tail_len:int64) < 0x10` THEN + WORD_ARITH_TAC; ALL_TAC ] THEN + ASM_SIMP_TAC[] THEN + REPEAT STRIP_TAC THEN + + MP_TAC (SPECL [`ct_ptr:int64`; `len:int64`; + `(word_add (word (curr_len + 0x10)) (word i)):int64`; + `ct:byte list`; `s0:armstate`] SELECT_ONE_BYTE_FROM_FORALL) THEN + SUBGOAL_THEN `val (word_add ((word (curr_len + 0x10)):int64) (word i)) < val (len:int64)` ASSUME_TAC THENL + [ REWRITE_TAC[WORD_RULE `!a b. word_add ((word a):int64) (word b) = word (a + b)`] THEN + IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN + ASM_ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[] THEN + STRIP_TAC THEN + + (* Break the `read (memory :> bytes128 (word_add pt_ptr (word curr_len))) s0 + into bytes using BREAK_ONE_BLOCK_INTO_BYTES *) + MP_TAC (SPECL [`(word_add pt_ptr (word curr_len)):int64`; `s0:armstate`; + `(cipher_stealing_inv (i + 0x1) curr_len (val (tail_len:int64)) PP ct):int128`] + BREAK_ONE_BLOCK_INTO_BYTES) THEN + ASM_SIMP_TAC[] THEN REPEAT STRIP_TAC THEN + + (* For address matching when symbolic simulation *) + SUBGOAL_THEN `word_add (ct_ptr:int64) (word_add (word (curr_len + 0x10)) (word i)) = + word_add ct_ptr (word (curr_len + 16 + i))` SUBST_ALL_TAC THENL + [ REWRITE_TAC[WORD_RULE `!a b. word_add ((word a):int64) (word b) = word (a + b)`; ADD_ASSOC] + ; ALL_TAC] THEN + SUBGOAL_THEN `!x. word_add (word_add (pt_ptr:int64) (word curr_len)) (word x) = + word_add pt_ptr (word (curr_len + x))` ASSUME_TAC THENL + [ GEN_TAC THEN REWRITE_TAC[ + WORD_RULE `!(a:int64) b c. word_add (word_add a b) c = word_add a (word_add b c)`; + WORD_RULE `!a b. word_add ((word a):int64) (word b) = word (a + b)`] + ; ALL_TAC] THEN + POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th])) THEN + + (* case analysis based on i = 0 ... 14, this is unavoidable because symbolic execution + needs to know which byte is being overwritten in pt_ptr to properly update the state. *) + MAP_EVERY (fun i -> TAIL_SWAP_ASM_CASES_TAC (mk_numeral (num i))) (0--14) THEN + UNDISCH_TAC `15 <= i` THEN + UNDISCH_TAC `i < val (tail_len:int64)` THEN + UNDISCH_TAC `val (tail_len:int64) < 16` THEN + ARITH_TAC; + + (* Subgoal 4: *) + REPEAT STRIP_TAC THEN + REWRITE_TAC[byte_list_at] THEN + ENSURES_INIT_TAC "s0" THEN + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (1--1) THEN + SUBGOAL_THEN `ival ((word i):int64) < &0x0 <=> + ~(ival ((word (i + 0x1)):int64) - &0x1 = ival ((word i):int64))` ASSUME_TAC THENL + [ SUBGOAL_THEN `ival ((word i):int64) = &i` ASSUME_TAC THENL + [ MATCH_MP_TAC IVAL_WORD_LT THEN + UNDISCH_TAC `i < val (tail_len:int64)` THEN + UNDISCH_TAC `val (tail_len:int64) < 0x10` THEN + ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `ival ((word (i + 0x1)):int64) = &(i + 1)` ASSUME_TAC THENL + [ MATCH_MP_TAC IVAL_WORD_LT THEN + UNDISCH_TAC `i < val (tail_len:int64)` THEN + UNDISCH_TAC `val (tail_len:int64) < 0x10` THEN + ARITH_TAC; ALL_TAC] THEN + ASM_REWRITE_TAC[] THEN + ARITH_TAC; ALL_TAC] THEN + POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th])) THEN + ENSURES_FINAL_STATE_TAC THEN ASM_SIMP_TAC[]; + + (* Subgoal 5: *) + REPEAT STRIP_TAC THEN + REWRITE_TAC[byte_list_at] THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[cipher_stealing_inv; CONJUNCT1 SUB_LIST; CONJUNCT1 APPEND] THEN + REWRITE_TAC[SUB_0] THEN + ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN `val ((word (val (tail_len:int64))):int64) = val tail_len` SUBST1_TAC THENL + [ IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `(SUB_LIST (0x0,val (tail_len:int64)) (SUB_LIST (curr_len + 16,val tail_len) (ct:byte list))) = + (SUB_LIST (curr_len + 16,val tail_len) ct)` SUBST1_TAC THENL + [ IMP_REWRITE_TAC[SUB_LIST_REFL] THEN + ASM_REWRITE_TAC[LENGTH_SUB_LIST; MIN] THEN + ASM_ARITH_TAC; ALL_TAC] THEN + + MATCH_MP_TAC ENSURES_FRAME_SUBSUMED THEN + EXISTS_TAC `MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI ,, + MAYCHANGE [X19; X20; X21; X22],, + MAYCHANGE [Q8; Q9; Q10; Q11; Q12; Q13; Q14; Q15],, + MAYCHANGE [memory :> bytes128 (word_add pt_ptr (word curr_len))]` THEN + REWRITE_TAC[MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI] THEN + CONJ_TAC THENL [ + REPEAT (GEN_REWRITE_TAC ONCE_DEPTH_CONV [GSYM SEQ_ASSOC] THEN + MATCH_MP_TAC SUBSUMED_SEQ THEN REWRITE_TAC[SUBSUMED_REFL]) THEN + ABBREV_TAC `vallen = val (len:int64)` THEN + SUBSUMED_MAYCHANGE_TAC; ALL_TAC] THEN + + ENSURES_INIT_TAC "s0" THEN + + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (1--32) THEN + ABBREV_TAC `combinedPP = bytes_to_int128 + (APPEND (SUB_LIST (curr_len + 16,val (tail_len:int64)) (ct:byte list)) + (SUB_LIST (val tail_len,0x10 - val tail_len) + (int128_to_bytes (PP:int128))))` THEN + FIRST_X_ASSUM(MP_TAC o SPEC `aes256_xts_decrypt_round combinedPP + (calculate_tweak curr_blocks iv key2) key1` o MATCH_MP (MESON[] + `read (Q26:(armstate,int128)component) (s:armstate) = a ==> !a'. a = a' ==> read Q26 s = a'`)) THEN + ANTS_TAC THENL + [ EXPAND_TAC "key1" THEN + CONV_TAC (RAND_CONV ( + REWRITE_CONV [aes256_xts_decrypt_round] THENC + DEPTH_CONV let_CONV)) THEN + AESDEC_TAC; DISCH_TAC ] THEN + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (33--33) THEN + ENSURES_FINAL_STATE_TAC THEN ASM_SIMP_TAC[] THEN + + UNDISCH_THEN `curr_len + 16 + val (tail_len:int64) = val (len:int64)` + (fun th -> SUBST1_TAC (GSYM th)) THEN + SUBGOAL_THEN `~(curr_len < 16)` ASSUME_TAC THENL + [ REWRITE_TAC[GSYM (ASSUME `acc_len num_5blocks_adjusted num_blocks_adjusted = curr_len`)] THEN + REWRITE_TAC[acc_len] THEN + COND_CASES_TAC THENL [ ARITH_TAC; ALL_TAC] THEN + COND_CASES_TAC THENL [ ARITH_TAC; ALL_TAC] THEN + COND_CASES_TAC THENL [ ARITH_TAC; ALL_TAC] THEN + COND_CASES_TAC THENL [ ARITH_TAC; ALL_TAC] THEN + UNDISCH_TAC `0x0 < val (num_5blocks_adjusted:int64)` THEN + ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `curr_len = 16 * curr_blocks` SUBST_ALL_TAC THENL + [ REWRITE_TAC[GSYM (ASSUME `acc_len num_5blocks_adjusted num_blocks_adjusted = curr_len`)] THEN + EXPAND_TAC "curr_blocks" THEN + REWRITE_TAC[acc_len; acc_blocks] THEN + COND_CASES_TAC THENL [SIMP_TAC[] THEN ARITH_TAC; ALL_TAC] THEN SIMP_TAC[] THEN + COND_CASES_TAC THENL [SIMP_TAC[] THEN ARITH_TAC; ALL_TAC] THEN SIMP_TAC[] THEN + COND_CASES_TAC THENL [SIMP_TAC[] THEN ARITH_TAC; ALL_TAC] THEN SIMP_TAC[] THEN + COND_CASES_TAC THENL [SIMP_TAC[] THEN ARITH_TAC; ALL_TAC] THEN SIMP_TAC[] THEN + ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `curr_blocks >= 1` ASSUME_TAC THENL + [ UNDISCH_TAC `~(16 * curr_blocks < 16)` THEN ARITH_TAC; ALL_TAC] THEN + + MATCH_MP_TAC BREAK_DATA_INTO_PARTS THEN + REPEAT CONJ_TAC THENL + [ + (* 1. Result correct up to curr_len *) + UNDISCH_TAC `forall i. + i < 16 * curr_blocks + ==> read (memory :> bytes8 (word_add (pt_ptr:int64) (word i))) s33 = + EL i (aes256_xts_decrypt (ct:byte list) (16 * curr_blocks) (iv:int128) + (key1:int128 list) (key2:int128 list))` THEN + MP_TAC (SPECL [`16 * curr_blocks:num`; `pt_ptr:int64`; + `(aes256_xts_decrypt ct (16 * curr_blocks + 0x10 + val (tail_len:int64)) iv key1 key2):byte list`; + `s33:armstate`] BYTE_LIST_TO_NUM_THM) THEN + ANTS_TAC THENL[ + IMP_REWRITE_TAC[LENGTH_OF_AES256_XTS_DECRYPT] THEN + ARITH_TAC; ALL_TAC] THEN + DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN + MP_TAC (SPECL [`16 * curr_blocks:num`; `pt_ptr:int64`; + `(aes256_xts_decrypt ct (16 * curr_blocks) iv key1 key2):byte list`; + `s33:armstate`] BYTE_LIST_TO_NUM_THM) THEN + ANTS_TAC THENL[ + REWRITE_TAC[LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS] THEN + ARITH_TAC; ALL_TAC] THEN + DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN + + DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN + AP_TERM_TAC THEN + MP_TAC (SPECL [`curr_blocks:num`; `ct:byte list`; `iv:int128`; + `key1:int128 list`; `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN + REWRITE_TAC[ADD_0] THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_OF_AES256_XTS_DECRYPT] THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES]; + + (* 2. Last full block is correct *) + MP_TAC (SPECL [`16:num`; `(word_add pt_ptr (word (0x10 * curr_blocks))):int64`; + `(SUB_LIST (0x10 * curr_blocks,0x10 + val (tail_len:int64)) + (aes256_xts_decrypt ct (0x10 * curr_blocks + 0x10 + val tail_len) + iv key1 key2)):byte list`; + `s33:armstate`] BYTE_LIST_TO_NUM_THM) THEN + ANTS_TAC THENL[ + REWRITE_TAC[LENGTH_SUB_LIST] THEN + IMP_REWRITE_TAC[LENGTH_OF_AES256_XTS_DECRYPT] THEN + ARITH_TAC; ALL_TAC] THEN + DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN + + (* Proving last full block correct *) + REWRITE_TAC[READ_MEMORY_BYTES_BYTES128] THEN + ASM_REWRITE_TAC[] THEN + REWRITE_TAC[SUB_LIST_MIN_RIGHT; MIN] THEN + SIMP_TAC[ARITH_RULE `!x. 0x10 <= 0x10 + x`] THEN + REWRITE_TAC[aes256_xts_decrypt] THEN + SIMP_TAC[ARITH_RULE `!x y. ~(x + 16 + y < 16)`] THEN + REWRITE_TAC[ARITH_RULE `0x10 * curr_blocks + 0x10 + val tail_len = + 0x10 * (curr_blocks + 1) + val tail_len`] THEN + REWRITE_TAC[MOD_MULT_ADD] THEN + ASM_SIMP_TAC[MOD_LT] THEN + REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + REWRITE_TAC[ARITH_RULE + `((0x10 * (curr_blocks + 0x1) + val tail_len) - val tail_len) DIV 0x10 = + (0x10 * (curr_blocks + 0x1)) DIV 0x10`] THEN + IMP_REWRITE_TAC[DIV_MULT; ARITH_RULE `~(16 = 0)`] THEN + IMP_REWRITE_TAC[ARITH_RULE `curr_blocks >= 1 ==> ~(curr_blocks + 1 < 2)`] THEN + IMP_REWRITE_TAC[ADD_SUB; ARITH_RULE `((curr_blocks + 0x1) - 0x2) = curr_blocks - 1`] THEN + + MP_TAC (SPECL [`0:num`; `(curr_blocks - 1):num`; `ct:byte list`; `iv:int128`; + `key1:int128 list`; `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT_REC) THEN + ASM_SIMP_TAC[ARITH_RULE `curr_blocks >= 1 ==> ~(curr_blocks - 1 < 0)`] THEN + IMP_REWRITE_TAC[SUB_0; ARITH_RULE `curr_blocks >= 1 ==> curr_blocks - 1 + 1 = curr_blocks`] THEN + ONCE_REWRITE_TAC[ARITH_RULE `curr_blocks * 16 = 16 * curr_blocks`] THEN + DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_APPEND_RIGHT_LEMMA] THEN + + REWRITE_TAC[aes256_xts_decrypt_tail] THEN + ASM_SIMP_TAC[LET_DEF; LET_END_DEF] THEN + + MP_TAC (SPECL [`(SUB_LIST (curr_blocks * 0x10,0x10) ct):byte list`; + `(SUB_LIST ((curr_blocks + 0x1) * 0x10,val (tail_len:int64)) ct):byte list`; + `val (tail_len:int64)`; `iv:int128`; `curr_blocks:num`; `key1:int128 list`; + `key2:int128 list`] LENGTH_OF_FST_OF_CIPHER_STEALING) THEN + DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_APPEND_LEFT; ARITH_RULE `16 <= 16`] THEN + + REWRITE_TAC[cipher_stealing; LET_DEF; LET_END_DEF] THEN + REWRITE_TAC[SUB_LIST_OF_INT128_TO_BYTES; + NUM_OF_BYTELIST_OF_INT128_TO_BYTES; CALCULATE_TWEAK_EXPAND; + ARITH_RULE `curr_blocks * 16 = 16 * curr_blocks`; + ARITH_RULE `0x10 * (curr_blocks + 0x1) = 16 * curr_blocks + 16`] THEN + EXPAND_TAC "combinedPP" THEN + EXPAND_TAC "PP" THEN + REFL_TAC; + + (* 3. Proving tail is correct *) + UNDISCH_TAC + `forall i. i < val (tail_len:int64) + ==> read (memory :> bytes8 + (word_add (word_add pt_ptr (word (0x10 * curr_blocks + 0x10))) + (word i))) s33 = + EL i (SUB_LIST (0x0,val tail_len) (int128_to_bytes PP))` THEN + MP_TAC (SPECL [`val (tail_len:int64):num`; `(word_add pt_ptr (word (0x10 * curr_blocks + 0x10))):int64`; + `(SUB_LIST (0x0,val (tail_len:int64)) (int128_to_bytes PP)):byte list`; + `s33:armstate`] BYTE_LIST_TO_NUM_THM) THEN + ANTS_TAC THENL[ + REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN + CONV_TAC NUM_REDUCE_CONV THEN + UNDISCH_TAC `val (tail_len:int64) < 0x10` THEN + ARITH_TAC; ALL_TAC] THEN + DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN + MP_TAC (SPECL [`val (tail_len:int64):num`; `(word_add pt_ptr (word (0x10 * curr_blocks + 0x10))):int64`; + `(SUB_LIST (0x10 * curr_blocks + 0x10,val (tail_len:int64)) + (aes256_xts_decrypt ct (0x10 * curr_blocks + 0x10 + val tail_len) iv key1 key2)):byte list`; + `s33:armstate`] BYTE_LIST_TO_NUM_THM) THEN + ANTS_TAC THENL[ + REWRITE_TAC[LENGTH_SUB_LIST] THEN + IMP_REWRITE_TAC[LENGTH_OF_AES256_XTS_DECRYPT] THEN + ARITH_TAC; ALL_TAC] THEN + DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN + + DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN + AP_TERM_TAC THEN + REWRITE_TAC[SUB_LIST_IDEMPOTENT] THEN + REWRITE_TAC[SUB_LIST_MIN_RIGHT; MIN; LE_REFL] THEN + + REWRITE_TAC[aes256_xts_decrypt; + ARITH_RULE `~(0x10 * curr_blocks + 0x10 + val (tail_len:int64) < 0x10)`] THEN + REWRITE_TAC[ARITH_RULE `0x10 * curr_blocks + 0x10 + val tail_len = + 0x10 * (curr_blocks + 1) + val tail_len`] THEN + REWRITE_TAC[MOD_MULT_ADD] THEN + ASM_SIMP_TAC[MOD_LT] THEN + REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + REWRITE_TAC[ARITH_RULE + `((0x10 * (curr_blocks + 0x1) + val tail_len) - val tail_len) DIV 0x10 = + (0x10 * (curr_blocks + 0x1)) DIV 0x10`] THEN + IMP_REWRITE_TAC[DIV_MULT; ARITH_RULE `~(16 = 0)`] THEN + IMP_REWRITE_TAC[ARITH_RULE `curr_blocks >= 1 ==> ~(curr_blocks + 1 < 2)`] THEN + IMP_REWRITE_TAC[ADD_SUB; ARITH_RULE `((curr_blocks + 0x1) - 0x2) = curr_blocks - 1`] THEN + + MP_TAC (ISPECL [`(aes256_xts_decrypt_rec 0x0 (curr_blocks - 0x1) ct iv key1 key2):byte list`; + `(aes256_xts_decrypt_tail curr_blocks (val (tail_len:int64)) ct iv key1 key2):byte list`; + `0x10 * curr_blocks + 0x10:num`; `val (tail_len:int64)`; `0x10 * curr_blocks:num` + ] SUB_LIST_APPEND_RIGHT_GENERAL) THEN + ANTS_TAC THENL + [ REWRITE_TAC[LENGTH_OF_AES256_XTS_DECRYPT_REC] THEN + UNDISCH_TAC `curr_blocks >= 1` THEN + ARITH_TAC; ALL_TAC] THEN + ANTS_TAC THENL [ ARITH_TAC; ALL_TAC] THEN + DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN + + REWRITE_TAC[ARITH_RULE `(0x10 * curr_blocks + 0x10) - 0x10 * curr_blocks = 0x10`] THEN + REWRITE_TAC[aes256_xts_decrypt_tail] THEN + ASM_SIMP_TAC[LET_DEF; LET_END_DEF] THEN + + MP_TAC (SPECL [`(SUB_LIST (curr_blocks * 0x10,0x10) ct):byte list`; + `(SUB_LIST ((curr_blocks + 0x1) * 0x10,val (tail_len:int64)) ct):byte list`; + `val (tail_len:int64)`; `iv:int128`; `curr_blocks:num`; `key1:int128 list`; + `key2:int128 list`] LENGTH_OF_FST_OF_CIPHER_STEALING) THEN + DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_APPEND_RIGHT_LEMMA; ARITH_RULE `16 <= 16`] THEN + + REWRITE_TAC[cipher_stealing; LET_DEF; LET_END_DEF; SUB_LIST_IDEMPOTENT] THEN + EXPAND_TAC "PP" THEN + REWRITE_TAC[ARITH_RULE `curr_blocks * 0x10 = 0x10 * curr_blocks`; + CALCULATE_TWEAK_EXPAND] + ] + ] );; From 2a9540ea5c5fa59009511c14c93d98640ec10050 Mon Sep 17 00:00:00 2001 From: Yan Peng Date: Tue, 21 Oct 2025 20:37:15 -0700 Subject: [PATCH 048/132] Tried to fix the non-overlapping issue --- arm/proofs/aes_xts_decrypt.ml | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/arm/proofs/aes_xts_decrypt.ml b/arm/proofs/aes_xts_decrypt.ml index aa463f005..0c0913e0b 100644 --- a/arm/proofs/aes_xts_decrypt.ml +++ b/arm/proofs/aes_xts_decrypt.ml @@ -4,8 +4,8 @@ *) use_file_raise_failure := true;; -arm_print_log := false;; -components_print_log := false;; +arm_print_log := true;; +components_print_log := true;; needs "arm/proofs/base.ml";; loadt "arm/proofs/aes_xts_decrypt_spec.ml";; @@ -4466,10 +4466,12 @@ let AES_XTS_DECRYPT_CORRECT = time prove( TWEAK_TAC `Q6:(armstate,int128)component` `val (num_5blocks_adjusted:int64) * 0x5 + 0x4` `val (num_5blocks_adjusted:int64) * 0x5 + 0x3` THEN (* The following lemmas are for NONSELFMODIFYING_STATE_UPDATE_TAC when store back to pt_ptr *) - RULE_ASSUM_TAC(REWRITE_RULE - [WORD_RULE `word_mul (word 0x50) num_5blocks_adjusted:int64 = word(0x50 * val num_5blocks_adjusted)`]) THEN + CHANGED_TAC (RULE_ASSUM_TAC(REWRITE_RULE + [WORD_RULE `word_mul (word 0x50) num_5blocks_adjusted:int64 = word(0x50 * val num_5blocks_adjusted)`])) THEN + CHANGED_TAC (RULE_ASSUM_TAC(REWRITE_RULE + [WORD_RULE `!base m n. word_add (word_add base (word m)) (word n) = word_add base (word(m + n))`])) THEN - (* TODO: there is a non-overlapping issue in the symbolic simulation that the third block is missing *) + (* TODO: Still have the same problem *) ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (134--136) THEN ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN REPEAT CONJ_TAC THENL From a84575d1e972d1064519d979d3f30561e6a1d246 Mon Sep 17 00:00:00 2001 From: Yan Peng Date: Tue, 21 Oct 2025 23:01:12 -0700 Subject: [PATCH 049/132] Fixing some issues --- arm/proofs/aes_xts_decrypt.ml | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/arm/proofs/aes_xts_decrypt.ml b/arm/proofs/aes_xts_decrypt.ml index 0c0913e0b..5a46f338e 100644 --- a/arm/proofs/aes_xts_decrypt.ml +++ b/arm/proofs/aes_xts_decrypt.ml @@ -3338,7 +3338,6 @@ let TAIL_SWAP_CASE_TAC case = (* Simplify so that symbolic execution could match up, but couldn't use CONV_TAC NUM_REDUCE_CONV because of non-overlapping *) RULE_ASSUM_TAC(REWRITE_RULE[ARITH_RULE r1]) THEN - RULE_ASSUM_TAC(REWRITE_RULE[ARITH_RULE `curr_len + 0x10 + 0x1 = curr_len + 0x11`]) THEN ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (1--5) THEN RULE_ASSUM_TAC(REWRITE_RULE[GSYM ADD_ASSOC]) THEN RULE_ASSUM_TAC (CONV_RULE NUM_REDUCE_CONV) THEN @@ -3361,6 +3360,8 @@ let TAIL_SWAP_CASE_TAC case = CIPHER_STEALING_BYTE_EQUAL) THEN CONV_TAC NUM_REDUCE_CONV THEN REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + ANTS_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN + ANTS_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN STRIP_TAC THEN MAP_EVERY (fun i -> CONJ_TAC THENL @@ -3371,6 +3372,7 @@ let TAIL_SWAP_CASE_TAC case = MP_TAC (SPECL [`pt_ptr:int64`; case; `val (tail_len:int64)`; `curr_len:num`; `(int128_to_bytes PP):byte list`; `s5:armstate`] BYTE_LIST_AT_SPLIT_BACKWARDS) THEN + REWRITE_TAC[LENGTH_OF_INT128_TO_BYTES] THEN CONV_TAC NUM_REDUCE_CONV THEN ASM_SIMP_TAC[] THEN ANTS_TAC THENL @@ -3403,7 +3405,8 @@ let TAIL_SWAP_ASM_CASES_TAC case = let BREAK_DATA_INTO_PARTS = prove( `!curr_len (tail_len:int64) (pt_ptr:int64) (s:armstate). - ((forall i. i < curr_len + ((curr_len + 0x10 + val tail_len <= LENGTH bl) /\ + (forall i. i < curr_len ==> read (memory :> bytes8 (word_add pt_ptr (word i))) s = EL i bl) /\ (forall i. i < 16 ==> read (memory :> bytes8 (word_add (word_add pt_ptr (word curr_len)) (word i))) s = @@ -3416,8 +3419,9 @@ let BREAK_DATA_INTO_PARTS = prove( i < curr_len + 0x10 + val tail_len ==> read (memory :> bytes8 (word_add pt_ptr (word i))) s = EL i bl`, REPEAT GEN_TAC THEN - DISCH_THEN (CONJUNCTS_THEN2 (LABEL_TAC "H1") - (CONJUNCTS_THEN2 (LABEL_TAC "H2") (LABEL_TAC "H3"))) THEN + DISCH_THEN (CONJUNCTS_THEN2 (LABEL_TAC "H") + (CONJUNCTS_THEN2 (LABEL_TAC "H1") + (CONJUNCTS_THEN2 (LABEL_TAC "H2") (LABEL_TAC "H3")))) THEN REPEAT STRIP_TAC THEN ASM_CASES_TAC `i < curr_len` THENL @@ -3464,6 +3468,7 @@ let BREAK_DATA_INTO_PARTS = prove( ASM_ARITH_TAC );; + let AES_XTS_DECRYPT_CORRECT = time prove( `!ct_ptr pt_ptr ct key1_ptr key2_ptr iv_ptr iv len k00 k01 k02 k03 k04 k05 k06 k07 k08 k09 k0a k0b k0c k0d k0e @@ -6229,6 +6234,9 @@ let AES_XTS_DECRYPT_CORRECT = time prove( MATCH_MP_TAC BREAK_DATA_INTO_PARTS THEN REPEAT CONJ_TAC THENL [ + (* 0. Trivial *) + IMP_REWRITE_TAC[LENGTH_OF_AES256_XTS_DECRYPT] THEN ARITH_TAC; + (* 1. Result correct up to curr_len *) UNDISCH_TAC `forall i. i < 16 * curr_blocks From 21c97d67c764cb743d9264bf40aa60fd70e6de4f Mon Sep 17 00:00:00 2001 From: Yan Peng Date: Tue, 21 Oct 2025 23:33:40 -0700 Subject: [PATCH 050/132] Prepare for bounded proofs --- arm/proofs/aes_xts_decrypt.ml | 2930 ++++++++++++++++++--------------- 1 file changed, 1626 insertions(+), 1304 deletions(-) diff --git a/arm/proofs/aes_xts_decrypt.ml b/arm/proofs/aes_xts_decrypt.ml index 5a46f338e..ccdf69689 100644 --- a/arm/proofs/aes_xts_decrypt.ml +++ b/arm/proofs/aes_xts_decrypt.ml @@ -3468,9 +3468,10 @@ let BREAK_DATA_INTO_PARTS = prove( ASM_ARITH_TAC );; +(* Assembly proofs *) -let AES_XTS_DECRYPT_CORRECT = time prove( - `!ct_ptr pt_ptr ct key1_ptr key2_ptr iv_ptr iv len +let CIPHER_STEALING_CORRECT = time prove( + `!ct_ptr pt_ptr ct key1_ptr iv len k00 k01 k02 k03 k04 k05 k06 k07 k08 k09 k0a k0b k0c k0d k0e k10 k11 k12 k13 k14 k15 k16 k17 k18 k19 k1a k1b k1c k1d k1e pc. @@ -3478,144 +3479,1144 @@ let AES_XTS_DECRYPT_CORRECT = time prove( /\ nonoverlapping (ct_ptr, val len) (pt_ptr, val len) /\ nonoverlapping (key1_ptr, 260) (pt_ptr, val len) /\ val len >= 16 /\ val len <= 2 EXP 24 /\ LENGTH ct = val len + /\ word_add tail_len num_blocks = len + /\ word_and len (word 0xfffffffffffffff0) = num_blocks + /\ word_and len (word 0xf) = tail_len + /\ [k00; k01; k02; k03; k04; k05; k06; k07; k08; k09; k0a; k0b; k0c; k0d; k0e] = key1 + /\ ~(val len < 0x60) + /\ (if val tail_len = 0x0 then num_blocks else word_sub num_blocks (word 0x10)) = num_blocks_adjusted + /\ word (val num_blocks_adjusted DIV 0x50) = num_5blocks_adjusted + /\ ~(val num_blocks < 0x60) + /\ val num_blocks <= 0x2 EXP 0x18 + /\ ~(val num_blocks_adjusted < 0x50) + /\ val num_blocks_adjusted <= 0x2 EXP 0x18 + /\ 0x0 < val num_5blocks_adjusted + /\ val tail_len < 0x10 + /\ val num_blocks <= val len + /\ val num_blocks_adjusted <= val len + /\ val num_5blocks_adjusted * 0x50 <= val num_blocks_adjusted + /\ val num_5blocks_adjusted * 0x50 <= val len ==> ensures arm (\s. aligned_bytes_loaded s (word pc) aes_xts_decrypt_mc /\ - read PC s = word (pc + 0x1c) /\ - C_ARGUMENTS [ct_ptr; pt_ptr; len; key1_ptr; key2_ptr; iv_ptr] s /\ + read PC s = word (pc + 0xa0c) /\ + read X0 s = word_add ct_ptr (word (acc_len num_5blocks_adjusted num_blocks_adjusted)) /\ + read X1 s = word_add pt_ptr (word (acc_len num_5blocks_adjusted num_blocks_adjusted)) /\ + read X3 s = key1_ptr /\ + read X21 s = tail_len /\ + read Q6 s = calculate_tweak (acc_blocks num_5blocks_adjusted num_blocks_adjusted T) iv key2 /\ + read X19 s = word 0x87 /\ + read X10 s = word_subword (calculate_tweak (acc_blocks num_5blocks_adjusted num_blocks_adjusted F) iv key2) (64,64) /\ + read X9 s = word_zx (calculate_tweak (acc_blocks num_5blocks_adjusted num_blocks_adjusted F) iv key2) /\ + read Q16 s = k00 /\ read Q17 s = k01 /\ read Q12 s = k02 /\ read Q13 s = k03 /\ + read Q14 s = k04 /\ read Q15 s = k05 /\ read Q4 s = k06 /\ read Q5 s = k07 /\ + read Q18 s = k08 /\ read Q19 s = k09 /\ read Q20 s = k0a /\ read Q21 s = k0b /\ + read Q22 s = k0c /\ read Q23 s = k0d /\ read Q7 s = k0e /\ byte_list_at ct ct_ptr len s /\ - read(memory :> bytes128 iv_ptr) s = iv /\ - set_key_schedule s key1_ptr k00 k01 k02 k03 k04 k05 k06 k07 k08 k09 k0a k0b k0c k0d k0e /\ - set_key_schedule s key2_ptr k10 k11 k12 k13 k14 k15 k16 k17 k18 k19 k1a k1b k1c k1d k1e) + byte_list_at (aes256_xts_decrypt ct (acc_len num_5blocks_adjusted num_blocks_adjusted) iv key1 key2) + pt_ptr (word (acc_len num_5blocks_adjusted num_blocks_adjusted)) s) (\s. read PC s = word (pc + 0xb58) /\ - byte_list_at (aes256_xts_decrypt ct (val len) iv - [k00; k01; k02; k03; k04; k05; k06; k07; k08; k09; k0a; k0b; k0c; k0d; k0e] - [k10; k11; k12; k13; k14; k15; k16; k17; k18; k19; k1a; k1b; k1c; k1d; k1e]) - pt_ptr len s + byte_list_at (aes256_xts_decrypt ct (val len) iv key1 key2) pt_ptr len s ) (MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI,, MAYCHANGE [X19; X20; X21; X22],, MAYCHANGE [Q8; Q9; Q10; Q11; Q12; Q13; Q14; Q15],, MAYCHANGE [memory :> bytes(pt_ptr, val len)]) `, - REWRITE_TAC [(REWRITE_CONV [aes_xts_decrypt_mc] THENC LENGTH_CONV) `LENGTH aes_xts_decrypt_mc`] THEN - REWRITE_TAC[set_key_schedule; C_ARGUMENTS; SOME_FLAGS; - NONOVERLAPPING_CLAUSES; byte_list_at; - MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI] THEN - REPEAT STRIP_TAC THEN + REWRITE_TAC [(REWRITE_CONV [aes_xts_decrypt_mc] THENC LENGTH_CONV) `LENGTH aes_xts_decrypt_mc`] THEN + REWRITE_TAC[set_key_schedule; C_ARGUMENTS; SOME_FLAGS; + NONOVERLAPPING_CLAUSES; byte_list_at; + MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI] THEN + REPEAT STRIP_TAC THEN - (* These are for top-level wrapper function - (* Add values for preserved registers *) - ENSURES_PRESERVED_TAC "x19_init" `X19` THEN - ENSURES_PRESERVED_TAC "x20_init" `X20` THEN - ENSURES_PRESERVED_TAC "x21_init" `X21` THEN - ENSURES_PRESERVED_TAC "x22_init" `X22` THEN - ENSURES_PRESERVED_DREG_TAC "d8_init" `D8` THEN - ENSURES_PRESERVED_DREG_TAC "d9_init" `D9` THEN - ENSURES_PRESERVED_DREG_TAC "d10_init" `D10` THEN - ENSURES_PRESERVED_DREG_TAC "d11_init" `D11` THEN - ENSURES_PRESERVED_DREG_TAC "d12_init" `D12` THEN - ENSURES_PRESERVED_DREG_TAC "d13_init" `D13` THEN - ENSURES_PRESERVED_DREG_TAC "d14_init" `D14` THEN - ENSURES_PRESERVED_DREG_TAC "d15_init" `D15` THEN -*) + (* Prove more properties about num_blocks_adjusted and num_5blocks_adjusted *) + SUBGOAL_THEN `val (num_blocks_adjusted:int64) DIV 0x50 = val (num_5blocks_adjusted:int64)` ASSUME_TAC THENL + [ EXPAND_TAC "num_5blocks_adjusted" THEN + IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN + UNDISCH_TAC `val (num_blocks_adjusted:int64) <= 0x2 EXP 0x18` THEN + ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `0x10 divides val (num_blocks_adjusted:int64)` ASSUME_TAC THENL + [ EXPAND_TAC "num_blocks_adjusted" THEN + EXPAND_TAC "num_blocks" THEN + COND_CASES_TAC THENL + [ REWRITE_TAC[NUM_BLOCKS_TO_VAL] THEN + IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT; DIVIDES_RMUL; DIVIDES_REFL] THEN + UNDISCH_TAC `val (len:int64) <= 0x2 EXP 0x18` THEN + ARITH_TAC; - (* Break len into full blocks and tail *) - SUBGOAL_THEN `word_add (word_and len (word 0xf)) - (word_and len (word 0xfffffffffffffff0)) = len:int64` ASSUME_TAC THENL - [REWRITE_TAC[word_split_lemma]; ALL_TAC] THEN - ABBREV_TAC `num_blocks:int64 = word_and len (word 0xfffffffffffffff0)` THEN - ABBREV_TAC `tail_len:int64 = word_and len (word 0xf)` THEN - ABBREV_TAC `key1:int128 list = [k00; k01; k02; k03; k04; k05; k06; k07; k08; k09; k0a; k0b; k0c; k0d; k0e]` THEN - ABBREV_TAC `key2:int128 list = [k10; k11; k12; k13; k14; k15; k16; k17; k18; k19; k1a; k1b; k1c; k1d; k1e]` THEN + IMP_REWRITE_TAC[NUM_BLOCKS_MINUS1_TO_VAL] THEN + IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT; DIVIDES_RMUL; DIVIDES_REFL] THEN + UNDISCH_TAC `val (len:int64) <= 0x2 EXP 0x18` THEN + ARITH_TAC]; ALL_TAC] THEN - (* Case splits on length: - len < 16 -- error case - len < 32 -- one block, or one block and a tail - len < 48 -- two blocks, or two blocks and a tail - len < 64 -- three blocks, or three blocks and a tail - len < 80 -- four blocks, or four blocks and a tail - len < 96 -- five blocks, or five blocks and a tail - len >= 96 -- six blocks and up + (* If no tail, execute to the end *) + ASM_CASES_TAC `val (tail_len:int64) = 0` THENL + [ + ENSURES_INIT_TAC "s0" THEN + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (1--2) THEN + (* Discharge if condition *) + SUBGOAL_THEN `val (word_and (tail_len:int64) (word 0xf)) = 0x0` MP_TAC THENL + [ UNDISCH_TAC `val (tail_len:int64) = 0x0` THEN BITBLAST_TAC; ALL_TAC] THEN + ASM_REWRITE_TAC[] THEN DISCH_TAC THEN + POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th])) THEN + + ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN + + SUBGOAL_THEN `val (word (acc_len (num_5blocks_adjusted:int64) (num_blocks_adjusted:int64)):int64) = + acc_len num_5blocks_adjusted num_blocks_adjusted` ASSUME_TAC THENL + [ IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN + MP_TAC (SPECL [`num_5blocks_adjusted:int64`; `num_blocks_adjusted:int64`; `2 EXP 64`] + BOUND_OF_ACC_LEN) THEN + ANTS_TAC THENL [ ASM_ARITH_TAC; ALL_TAC] THEN + ANTS_TAC THENL [ ASM_SIMP_TAC[]; ALL_TAC] THEN + ANTS_TAC THENL [ ASM_SIMP_TAC[]; ALL_TAC] THEN + ANTS_TAC THENL [ ASM_ARITH_TAC; ALL_TAC] THEN + SIMP_TAC[]; ALL_TAC] THEN + POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th])) THEN + (* Prove that acc_len is equal to total len because there is no tail *) + SUBGOAL_THEN `val (len:int64) = + acc_len (num_5blocks_adjusted:int64) (num_blocks_adjusted:int64)` SUBST1_TAC THENL + [ SUBGOAL_THEN `len = (num_blocks:int64)` SUBST1_TAC THENL + [ EXPAND_TAC "len" THEN + SUBGOAL_THEN `tail_len:int64 = word 0` ASSUME_TAC THENL + [ REWRITE_TAC[GSYM VAL_EQ_0] THEN ASM_REWRITE_TAC[]; ALL_TAC] THEN + REWRITE_TAC[ASSUME `tail_len:int64 = word 0`; WORD_ADD_0] + ; ALL_TAC] THEN + SUBGOAL_THEN `num_blocks = (num_blocks_adjusted:int64)` SUBST1_TAC THENL + [ EXPAND_TAC "num_blocks_adjusted" THEN + REWRITE_TAC[ASSUME `val (tail_len:int64) = 0`] + ; ALL_TAC] THEN + REWRITE_TAC[acc_len] THEN + REPEAT_N 4 (COND_CASES_TAC THENL[ASM_ARITH_TAC; ALL_TAC]) THEN - Note: for decrypt, because of cipherstealing, there needs to be one extra - block at the end together with the tail to be processed for cipherstealing - *) - ASM_CASES_TAC `val (len:int64) < 96` THENL [CHEAT_TAC; ALL_TAC] THEN + CONV_TAC SYM_CONV THEN + REWRITE_TAC[ARITH_RULE `!a. 0x50 * a = a * 0x50`] THEN + MATCH_MP_TAC (SPECL [`val (num_blocks_adjusted:int64)`; `val (num_5blocks_adjusted:int64)`] DIVISION_BY_80_LEMMA) THEN + REPEAT CONJ_TAC THENL + [ + ASM_SIMP_TAC[]; + ASM_SIMP_TAC[]; - ABBREV_TAC `num_blocks_adjusted = if val (tail_len:int64) = 0 - then num_blocks else word_sub (num_blocks:int64) (word 0x10)` THEN - ABBREV_TAC `num_5blocks_adjusted = (word (val (num_blocks_adjusted:int64) DIV 0x50)):int64` THEN + UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 <= val (num_blocks_adjusted:int64)` THEN + UNDISCH_TAC `~(val (num_5blocks_adjusted:int64) * 0x50 + 0x10 = val (num_blocks_adjusted:int64))` THEN + ARITH_TAC; - (* Prove once and for all the bounds for num_blocks, num_blocks_adjusted - and num_5blocks_adjusted *) - SUBGOAL_THEN `~(val (num_blocks:int64) < 96)` ASSUME_TAC THENL - [ UNDISCH_TAC `~(val (len:int64) < 0x60)` THEN - UNDISCH_TAC `word_and len (word 0xfffffffffffffff0) = (num_blocks:int64)` THEN - MP_TAC (SPECL [`len:int64`; `num_blocks:int64`] NUM_BLOCKS_LO_BOUND_THM) THEN - SIMP_TAC[]; ALL_TAC] THEN - SUBGOAL_THEN `val (num_blocks:int64) <= 2 EXP 24` ASSUME_TAC THENL - [ UNDISCH_TAC `val (len:int64) <= 2 EXP 24` THEN - UNDISCH_TAC `word_and len (word 0xfffffffffffffff0) = (num_blocks:int64)` THEN - MP_TAC (SPECL [`len:int64`; `num_blocks:int64`] NUM_BLOCKS_HI_BOUND_THM) THEN + UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 <= val (num_blocks_adjusted:int64)` THEN + UNDISCH_TAC `~(val (num_5blocks_adjusted:int64) * 0x50 + 0x20 = val (num_blocks_adjusted:int64))` THEN + ARITH_TAC; + + UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 <= val (num_blocks_adjusted:int64)` THEN + UNDISCH_TAC `~(val (num_5blocks_adjusted:int64) * 0x50 + 0x30 = val (num_blocks_adjusted:int64))` THEN + ARITH_TAC; + + UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 <= val (num_blocks_adjusted:int64)` THEN + UNDISCH_TAC `~(val (num_5blocks_adjusted:int64) * 0x50 + 0x40 = val (num_blocks_adjusted:int64))` THEN + ARITH_TAC] + ; ALL_TAC] THEN + ASM_SIMP_TAC[] + ; ALL_TAC] THEN + + (* The cipher stealing branch *) + (* Break the rest of the program into two parts: before byte-swap and after. + This is because byte-swap needs another invariant proof. *) + ABBREV_TAC `curr_len = (acc_len (num_5blocks_adjusted:int64) (num_blocks_adjusted:int64)):num` THEN + ABBREV_TAC `curr_blocks = (acc_blocks (num_5blocks_adjusted:int64) (num_blocks_adjusted:int64) T):num` THEN + + SUBGOAL_THEN `curr_len + 0x10 <= val (len:int64)` ASSUME_TAC THENL + [ EXPAND_TAC "curr_len" THEN + MP_TAC (SPECL [`num_5blocks_adjusted:int64`; `num_blocks_adjusted:int64`] VALUE_OF_ACC_LEN) THEN + REPEAT_N 3 (ANTS_TAC THENL [ASM_ARITH_TAC ORELSE ASM_SIMP_TAC[]; ALL_TAC]) THEN + SIMP_TAC[] THEN DISCH_TAC THEN + EXPAND_TAC "num_blocks_adjusted" THEN + SIMP_TAC[ASSUME `~(val (tail_len:int64) = 0)`] THEN + UNDISCH_TAC `val (num_blocks:int64) <= val (len:int64)` THEN + UNDISCH_TAC `~(val (num_blocks:int64) < 0x60)` THEN + WORD_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `val ((word curr_len):int64) = curr_len` ASSUME_TAC THENL + [ IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN + EXPAND_TAC "curr_len" THEN + MP_TAC (SPECL [`num_5blocks_adjusted:int64`; `num_blocks_adjusted:int64`; `2 EXP 64`] + BOUND_OF_ACC_LEN) THEN + ANTS_TAC THENL [ ASM_ARITH_TAC; ALL_TAC] THEN + ANTS_TAC THENL [ ASM_SIMP_TAC[]; ALL_TAC] THEN + ANTS_TAC THENL [ ASM_SIMP_TAC[]; ALL_TAC] THEN + ANTS_TAC THENL [ ASM_ARITH_TAC; ALL_TAC] THEN + SIMP_TAC[]; ALL_TAC] THEN + + ENSURES_SEQUENCE_TAC `pc + 0xab8` + `\s. + read X0 s = word_add (word_add ct_ptr (word curr_len)) (word 0x10) /\ + read X1 s = word_add pt_ptr (word curr_len) /\ + read X21 s = tail_len /\ + read Q6 s = calculate_tweak curr_blocks iv key2 /\ + read Q16 s = k00 /\ read Q17 s = k01 /\ read Q12 s = k02 /\ read Q13 s = k03 /\ + read Q14 s = k04 /\ read Q15 s = k05 /\ read Q4 s = k06 /\ read Q5 s = k07 /\ + read Q18 s = k08 /\ read Q19 s = k09 /\ read Q20 s = k0a /\ read Q21 s = k0b /\ + read Q22 s = k0c /\ read Q23 s = k0d /\ read Q7 s = k0e /\ + + byte_list_at ct ct_ptr len s /\ + byte_list_at (aes256_xts_decrypt ct curr_len iv key1 key2) pt_ptr (word curr_len) s /\ + read (memory :> bytes128 (word_add pt_ptr (word curr_len))) s = + aes256_xts_decrypt_round + (bytes_to_int128 (SUB_LIST (curr_len,0x10) ct)) + (calculate_tweak (curr_blocks + 0x1) iv key2) + key1` THEN + CONJ_TAC THENL + [ + MATCH_MP_TAC ENSURES_FRAME_SUBSUMED THEN + EXISTS_TAC `MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI ,, + MAYCHANGE [X19; X20; X21; X22],, + MAYCHANGE [Q8; Q9; Q10; Q11; Q12; Q13; Q14; Q15],, + MAYCHANGE [memory :> bytes128 (word_add pt_ptr (word curr_len))]` THEN + REWRITE_TAC[MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI] THEN + CONJ_TAC THENL [ + REPEAT (GEN_REWRITE_TAC ONCE_DEPTH_CONV [GSYM SEQ_ASSOC] THEN + MATCH_MP_TAC SUBSUMED_SEQ THEN REWRITE_TAC[SUBSUMED_REFL]) THEN + ABBREV_TAC `vallen = val (len:int64)` THEN + SUBSUMED_MAYCHANGE_TAC; ALL_TAC] THEN + + REWRITE_TAC[byte_list_at] THEN + UNDISCH_THEN `val ((word curr_len):int64) = curr_len` + (fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th]) THEN REWRITE_TAC[th]) THEN + + ENSURES_INIT_TAC "s0" THEN + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (1--2) THEN + + (* Discharge if condition *) + SUBGOAL_THEN `~(val (word_and (tail_len:int64) (word 0xf)) = 0x0)` MP_TAC THENL + [ UNDISCH_TAC `~(val (tail_len:int64) = 0x0)` THEN + UNDISCH_TAC `val (tail_len:int64) < 16` THEN + MP_TAC (SPEC `tail_len:int64` WORD_AND_MASK16_EQ_0) THEN SIMP_TAC[]; ALL_TAC] THEN - SUBGOAL_THEN `~(val (num_blocks_adjusted:int64) < 80)` ASSUME_TAC THENL - [ UNDISCH_TAC `~(val (num_blocks:int64) < 96)` THEN - UNDISCH_TAC `(if val (tail_len:int64) = 0x0 - then (num_blocks:int64) - else word_sub num_blocks (word 0x10)) = - num_blocks_adjusted` THEN - MP_TAC (SPECL [`num_blocks:int64`;`tail_len:int64`;`num_blocks_adjusted:int64`] - NUM_BLOCKS_ADJUSTED_LO_BOUND_THM) THEN SIMP_TAC[] + ASM_REWRITE_TAC[] THEN DISCH_TAC THEN + POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th])) THEN + + (* Decrypt last block *) + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (3--11) THEN + TWEAK_TAC `Q8:(armstate,int128)component` `(curr_blocks + 1):num` `curr_blocks:num` THEN + MP_TAC (SPECL [`ct_ptr:int64`; `curr_len:num`; `len:int64`; `ct:byte list`; `s11:armstate`] READ_CT_LAST_LEMMA) THEN + ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (12--42) THEN + XTSDEC_TAC `Q26:(armstate,int128)component` `curr_len:num` `(curr_blocks + 1):num` THEN + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (43--43) THEN + + ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] + ; ALL_TAC + ] THEN + + ABBREV_TAC `PP = aes256_xts_decrypt_round + (bytes_to_int128 (SUB_LIST (curr_len,0x10) (ct:byte list))) + (calculate_tweak (curr_blocks + 0x1) (iv:int128) (key2:int128 list)) + (key1:int128 list)` THEN + SUBGOAL_THEN `curr_len + 16 + val (tail_len:int64) = val (len:int64)` ASSUME_TAC THENL + [ REWRITE_TAC[GSYM (ASSUME `acc_len num_5blocks_adjusted num_blocks_adjusted = curr_len`)] THEN + MP_TAC (SPECL [`num_5blocks_adjusted:int64`; `num_blocks_adjusted:int64`] VALUE_OF_ACC_LEN) THEN + ANTS_TAC THENL[ASM_ARITH_TAC; ALL_TAC] THEN + ANTS_TAC THENL[ASM_ARITH_TAC; ALL_TAC] THEN + ANTS_TAC THENL[ASM_SIMP_TAC[]; ALL_TAC] THEN + SIMP_TAC[] THEN DISCH_TAC THEN + EXPAND_TAC "num_blocks_adjusted" THEN + UNDISCH_TAC `~(val (tail_len:int64) = 0)` THEN + SIMP_TAC[] THEN DISCH_TAC THEN + ASM_SIMP_TAC[VAL_WORD_SUB; DIMINDEX_64; VAL_WORD; + ARITH_RULE `16 MOD 2 EXP 64 = 16`] THEN + MP_TAC (SPECL [`val (num_blocks:int64)`; `0x2 EXP 0x40`; `16`] + (ARITH_RULE `!a b c. c <= a ==> c <= b ==> a + b - c = (a - c) + b`)) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN + ANTS_TAC THENL [ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[] THEN DISCH_TAC THEN + MP_TAC (SPECL [`1`; `0x2 EXP 0x40`; `val (num_blocks:int64) - 16`] + (CONJUNCT1 (CONJUNCT2 (CONJUNCT2 MOD_MULT_ADD)))) THEN + SIMP_TAC[ARITH_RULE `!x. 1 * x = x`] THEN DISCH_TAC THEN + IMP_REWRITE_TAC[MOD_LT] THEN + CONJ_TAC THENL [ + SUBGOAL_THEN `val (num_blocks:int64) - 0x10 + 0x10 + val (tail_len:int64) + = val num_blocks + val tail_len` SUBST1_TAC THENL + [ IMP_REWRITE_TAC[ADD_ASSOC; SUB_ADD] THEN ASM_ARITH_TAC; ALL_TAC] THEN + EXPAND_TAC "len" THEN + REWRITE_TAC[VAL_WORD_ADD] THEN + IMP_REWRITE_TAC[MOD_LT; DIMINDEX_64] THEN + CONJ_TAC THENL [ARITH_TAC; ASM_ARITH_TAC]; + ALL_TAC + ] THEN + ASM_ARITH_TAC; ALL_TAC] THEN + (* Invariant proof for .composite_dec_loop *) + (* Invariant: + X0 points to tail of ct + X1 points to starting of last full block of pt + X13 points to tail of pt + X20 points to tail of ct + X21 holds tail_len + Q6 holds second to last tweak + Q16 ... Q7 holds the key schedule for encryption + + Memory: ct_ptr points to the input + Memory: Up to the last block, the output matches the specification + Memory: For the last block, for each byte + [0,i) -- previous decrption result + [i,tail_len) -- equal corresponding ct tail bytes + [tail_len,16] -- previous decryption result + Memory: For the tail, for each byte + [i,tail_len) -- copied over from last pt block + *) + ENSURES_WHILE_PADOWN_TAC + `val (tail_len:int64)` + `0` + `pc + 0xac0` + `pc + 0xad4` + `\i s. + ( read X0 s = word_add (word_add ct_ptr (word curr_len)) (word 0x10) /\ + read X1 s = word_add pt_ptr (word curr_len) /\ + read X13 s = word_add (word_add pt_ptr (word curr_len)) (word 0x10) /\ + read X20 s = word_add (word_add ct_ptr (word curr_len)) (word 0x10) /\ + read X21 s = (word i):int64 /\ + read Q6 s = calculate_tweak curr_blocks iv key2 /\ + read Q16 s = k00 /\ read Q17 s = k01 /\ read Q12 s = k02 /\ read Q13 s = k03 /\ + read Q14 s = k04 /\ read Q15 s = k05 /\ read Q4 s = k06 /\ read Q5 s = k07 /\ + read Q18 s = k08 /\ read Q19 s = k09 /\ read Q20 s = k0a /\ read Q21 s = k0b /\ + read Q22 s = k0c /\ read Q23 s = k0d /\ read Q7 s = k0e /\ + byte_list_at ct ct_ptr len s /\ + byte_list_at (aes256_xts_decrypt ct curr_len iv key1 key2) pt_ptr (word curr_len) s /\ + + read (memory :> bytes128 (word_add pt_ptr (word curr_len))) s = + cipher_stealing_inv i curr_len (val (tail_len:int64)) PP ct /\ + + byte_list_at (SUB_LIST (i, val tail_len - i) (int128_to_bytes PP)) + (word_add pt_ptr (word (curr_len + 0x10 + i))) + (word ((val tail_len) - i)) s) /\ + // loop backedge condition + (read ZF s <=> i = 0) /\ + (read NF s <=> ival ((word i):int64) < &0) /\ + (read VF s <=> ~(ival ((word (i + 1)):int64) - &1 = ival ((word i):int64)))` THEN + ASM_REWRITE_TAC[] THEN REPEAT CONJ_TAC THENL + [ + (* Subgoal1: 0 < val tail_len *) + ASM_ARITH_TAC; + + (* Subgoal2: invariant holds before entering loop *) + REWRITE_TAC[byte_list_at] THEN + UNDISCH_THEN `val ((word curr_len):int64) = curr_len` + (fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th]) THEN REWRITE_TAC[th]) THEN + + ENSURES_INIT_TAC "s0" THEN + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (1--2) THEN + ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN + REPEAT CONJ_TAC THENL + [ + REWRITE_TAC[WORD_VAL]; + + REWRITE_TAC[cipher_stealing_inv; SUB_REFL] THEN + SUBGOAL_THEN `SUB_LIST (val (tail_len:int64),0x0) (SUB_LIST (curr_len + 16,val tail_len) (ct:byte list)) = []` SUBST1_TAC THENL + [ REWRITE_TAC[SUB_LIST_CLAUSES]; ALL_TAC] THEN + REWRITE_TAC[CONJUNCT1 APPEND] THEN + SUBGOAL_THEN `APPEND (SUB_LIST (0x0,val (tail_len:int64)) (int128_to_bytes PP)) + (SUB_LIST (val tail_len,0x10 - val tail_len) (int128_to_bytes PP)) = + (int128_to_bytes PP)` SUBST1_TAC THENL + [ MP_TAC (ISPECL [`int128_to_bytes PP`; `val (tail_len:int64)`; `16 - val (tail_len:int64)`; `0`] (GSYM SUB_LIST_SPLIT)) THEN + IMP_REWRITE_TAC[ADD_CLAUSES; ARITH_RULE `!x. x < 16 ==> x + 16 - x = 16`] THEN + DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES; LENGTH_OF_INT128_TO_BYTES] + ; ALL_TAC] THEN + REWRITE_TAC[BYTES_TO_INT128_OF_INT128_TO_BYTES]; + + REWRITE_TAC[VAL_WORD_0] THEN ARITH_TAC + ]; + + (* Subgoal 3: inductive step *) + REPEAT STRIP_TAC THEN + + (* For non-overlapping and MAYCHANGE address reasoning *) + SUBGOAL_THEN `curr_len + 16 + i < val (len:int64)` ASSUME_TAC THENL + [ REWRITE_TAC[GSYM (ASSUME `acc_len num_5blocks_adjusted num_blocks_adjusted = curr_len`)] THEN + MP_TAC (SPECL [`num_5blocks_adjusted:int64`; `num_blocks_adjusted:int64`] VALUE_OF_ACC_LEN) THEN + REPEAT_N 3 (ANTS_TAC THENL [ASM_ARITH_TAC ORELSE ASM_SIMP_TAC[]; ALL_TAC]) THEN + SIMP_TAC[] THEN DISCH_TAC THEN + EXPAND_TAC "num_blocks_adjusted" THEN + SIMP_TAC[ASSUME `~(val (tail_len:int64) = 0)`] THEN + REWRITE_TAC[VAL_WORD_SUB; DIMINDEX_64] THEN + MP_TAC (SPECL [`val (num_blocks:int64)`; `0x2 EXP 0x40`; `val ((word 0x10):int64)`] + (ARITH_RULE `!a b c. c <= a ==> c <= b ==> a + b - c = (a - c) + b`)) THEN + ANTS_TAC THENL [ + IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN ASM_ARITH_TAC + ; ALL_TAC] THEN + ANTS_TAC THENL [ WORD_ARITH_TAC; ALL_TAC] THEN + SIMP_TAC[] THEN DISCH_TAC THEN + MP_TAC (SPECL [`1`; `0x2 EXP 0x40`; `val (num_blocks:int64) - val ((word 0x10):int64)`] + (CONJUNCT1 (CONJUNCT2 (CONJUNCT2 MOD_MULT_ADD)))) THEN + SIMP_TAC[ARITH_RULE `!x. 1 * x = x`] THEN DISCH_TAC THEN + IMP_REWRITE_TAC[MOD_LT] THEN + IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN + CONV_TAC NUM_REDUCE_CONV THEN + EXPAND_TAC "len" THEN + IMP_REWRITE_TAC[VAL_WORD_ADD; DIMINDEX_64; MOD_LT] THEN + UNDISCH_TAC `val (num_blocks:int64) <= val (len:int64)` THEN + UNDISCH_TAC `~(val (num_blocks:int64) < 0x60)` THEN + UNDISCH_TAC `val (num_blocks:int64) <= 0x2 EXP 0x18` THEN + UNDISCH_TAC `i < val (tail_len:int64)` THEN + UNDISCH_TAC `val (tail_len:int64) < 0x10` THEN + ARITH_TAC ; ALL_TAC] THEN - SUBGOAL_THEN `val (num_blocks_adjusted:int64) <= 2 EXP 24` ASSUME_TAC THENL - [ UNDISCH_TAC `val (num_blocks:int64) <= 2 EXP 24` THEN - UNDISCH_TAC `~(val (num_blocks:int64) < 96)` THEN - UNDISCH_TAC `(if val (tail_len:int64) = 0x0 - then (num_blocks:int64) - else word_sub num_blocks (word 0x10)) = - num_blocks_adjusted` THEN - MP_TAC (SPECL [`num_blocks:int64`;`tail_len:int64`;`num_blocks_adjusted:int64`] - NUM_BLOCKS_ADJUSTED_HI_BOUND_THM) THEN SIMP_TAC[] + + MATCH_MP_TAC ENSURES_FRAME_SUBSUMED THEN + EXISTS_TAC `MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI ,, + MAYCHANGE [X19; X20; X21; X22],, + MAYCHANGE [Q8; Q9; Q10; Q11; Q12; Q13; Q14; Q15],, + MAYCHANGE [memory :> bytes8 (word_add pt_ptr (word (curr_len + 0x10 + i)))],, + MAYCHANGE [memory :> bytes8 (word_add pt_ptr (word (curr_len + i)))]` THEN + REWRITE_TAC[MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI] THEN + CONJ_TAC THENL [ + REPEAT (GEN_REWRITE_TAC ONCE_DEPTH_CONV [GSYM SEQ_ASSOC] THEN + MATCH_MP_TAC SUBSUMED_SEQ THEN REWRITE_TAC[SUBSUMED_REFL]) THEN + ABBREV_TAC `vallen = val (len:int64)` THEN + SUBSUMED_MAYCHANGE_TAC; ALL_TAC] THEN + + REWRITE_TAC[byte_list_at] THEN + UNDISCH_THEN `val ((word curr_len):int64) = curr_len` + (fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th]) THEN REWRITE_TAC[th]) THEN + ENSURES_INIT_TAC "s0" THEN + + SUBGOAL_THEN `val ((word (val (tail_len:int64) - i)):int64) = val tail_len - i` SUBST_ALL_TAC THENL + [ IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN + UNDISCH_TAC `i < val (tail_len:int64)` THEN + UNDISCH_TAC `val (tail_len:int64) < 0x10` THEN + ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `val ((word (val (tail_len:int64) - (i + 0x1))):int64) = val tail_len - (i + 1)` SUBST_ALL_TAC THENL + [ IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN + UNDISCH_TAC `i < val (tail_len:int64)` THEN + UNDISCH_TAC `val (tail_len:int64) < 0x10` THEN + ARITH_TAC; ALL_TAC] THEN + + SUBGOAL_THEN `word_sub ((word (i + 0x1)):int64) (word 0x1) = word i` ASSUME_TAC THENL + [ REWRITE_TAC[GSYM VAL_EQ; VAL_WORD_SUB; DIMINDEX_64] THEN + MP_TAC (SPECL [`val ((word (i + 0x1)):int64)`; `0x2 EXP 0x40`; `val ((word 0x1):int64)`] + (ARITH_RULE `!a b c. c <= a ==> c <= b ==> a + b - c = (a - c) + b`)) THEN + ANTS_TAC THENL [ + IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN ASM_ARITH_TAC + ; ALL_TAC] THEN + ANTS_TAC THENL [ WORD_ARITH_TAC; ALL_TAC] THEN + SIMP_TAC[] THEN DISCH_TAC THEN + MP_TAC (SPECL [`1`; `0x2 EXP 0x40`; `val ((word (i + 0x1)):int64) - val ((word 0x1):int64)`] + (CONJUNCT1 (CONJUNCT2 (CONJUNCT2 MOD_MULT_ADD)))) THEN + SIMP_TAC[ARITH_RULE `!x. 1 * x = x`] THEN DISCH_TAC THEN + IMP_REWRITE_TAC[MOD_LT] THEN + CONJ_TAC THENL + [ SUBGOAL_THEN `i + 1 < 2 EXP 64` MP_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN + IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN + ARITH_TAC; + UNDISCH_TAC `i < val (tail_len:int64)` THEN + UNDISCH_TAC `val (tail_len:int64) < 0x10` THEN + WORD_ARITH_TAC] ; ALL_TAC] THEN - SUBGOAL_THEN `0 < val (num_5blocks_adjusted:int64)` ASSUME_TAC THENL - [ UNDISCH_TAC `word (val (num_blocks_adjusted:int64) DIV 0x50) = (num_5blocks_adjusted:int64)` THEN - UNDISCH_TAC `~(val (num_blocks_adjusted:int64) < 0x50)` THEN - UNDISCH_TAC `val (num_blocks_adjusted:int64) <= 0x2 EXP 0x18` THEN - MP_TAC (SPECL [`num_blocks_adjusted:int64`; `num_5blocks_adjusted:int64`] - NUM_5BLOCKS_ADJUSTED_LO_BOUND_THM) THEN SIMP_TAC[] - ; ALL_TAC] THEN - SUBGOAL_THEN `val (tail_len:int64) < 16` ASSUME_TAC THENL - [ EXPAND_TAC "tail_len" THEN - REWRITE_TAC[ARITH_RULE `0xf = 2 EXP 4 - 1`] THEN - REWRITE_TAC[VAL_WORD_AND_MASK_WORD] THEN - CONV_TAC NUM_REDUCE_CONV THEN - SIMP_TAC[MOD_LT_EQ] THEN - CONV_TAC NUM_REDUCE_CONV + + MP_TAC (SPECL [`(word_add pt_ptr (word curr_len)):int64`; `word i:int64`; `s0:armstate`; + `(cipher_stealing_inv (i + 0x1) curr_len (val (tail_len:int64)) PP ct):int128`] + SELECT_ONE_BYTE_FROM_BLOCK) THEN + + SUBGOAL_THEN `val ((word i):int64) < 0x10` ASSUME_TAC THENL + [ UNDISCH_TAC `i < val (tail_len:int64)` THEN + UNDISCH_TAC `val (tail_len:int64) < 0x10` THEN + WORD_ARITH_TAC; ALL_TAC ] THEN + ASM_SIMP_TAC[] THEN + REPEAT STRIP_TAC THEN + + MP_TAC (SPECL [`ct_ptr:int64`; `len:int64`; + `(word_add (word (curr_len + 0x10)) (word i)):int64`; + `ct:byte list`; `s0:armstate`] SELECT_ONE_BYTE_FROM_FORALL) THEN + SUBGOAL_THEN `val (word_add ((word (curr_len + 0x10)):int64) (word i)) < val (len:int64)` ASSUME_TAC THENL + [ REWRITE_TAC[WORD_RULE `!a b. word_add ((word a):int64) (word b) = word (a + b)`] THEN + IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN + ASM_ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[] THEN + STRIP_TAC THEN + + (* Break the `read (memory :> bytes128 (word_add pt_ptr (word curr_len))) s0 + into bytes using BREAK_ONE_BLOCK_INTO_BYTES *) + MP_TAC (SPECL [`(word_add pt_ptr (word curr_len)):int64`; `s0:armstate`; + `(cipher_stealing_inv (i + 0x1) curr_len (val (tail_len:int64)) PP ct):int128`] + BREAK_ONE_BLOCK_INTO_BYTES) THEN + ASM_SIMP_TAC[] THEN REPEAT STRIP_TAC THEN + + (* For address matching when symbolic simulation *) + SUBGOAL_THEN `word_add (ct_ptr:int64) (word_add (word (curr_len + 0x10)) (word i)) = + word_add ct_ptr (word (curr_len + 16 + i))` SUBST_ALL_TAC THENL + [ REWRITE_TAC[WORD_RULE `!a b. word_add ((word a):int64) (word b) = word (a + b)`; ADD_ASSOC] ; ALL_TAC] THEN - (* relationship between variables *) - SUBGOAL_THEN `val (num_blocks:int64) <= val (len:int64)` ASSUME_TAC THENL - [ EXPAND_TAC "num_blocks" THEN SIMP_TAC[NUM_BLOCKS_LT_LEN_THM]; ALL_TAC] THEN - SUBGOAL_THEN `val (num_blocks_adjusted:int64) <= val (len:int64)` ASSUME_TAC THENL - [ EXPAND_TAC "num_blocks_adjusted" THEN - COND_CASES_TAC THENL - [ ASM_SIMP_TAC[]; - UNDISCH_TAC `~(val (num_blocks:int64) < 0x60)` THEN - UNDISCH_TAC `word_and (len:int64) (word 0xfffffffffffffff0) = (num_blocks:int64)` THEN - MP_TAC (SPECL [`len:int64`; `num_blocks:int64`] NUM_BLOCKS_ADJUSTED_LT_LEN_THM) THEN - SIMP_TAC[]]; ALL_TAC] THEN - SUBGOAL_THEN `val (num_5blocks_adjusted:int64) * 0x50 <= val (num_blocks_adjusted:int64)` ASSUME_TAC THENL - [ EXPAND_TAC "num_5blocks_adjusted" THEN - REWRITE_TAC [VAL_WORD; DIMINDEX_64] THEN - UNDISCH_TAC `val (num_blocks_adjusted:int64) <= 0x2 EXP 0x18` THEN + SUBGOAL_THEN `!x. word_add (word_add (pt_ptr:int64) (word curr_len)) (word x) = + word_add pt_ptr (word (curr_len + x))` ASSUME_TAC THENL + [ GEN_TAC THEN REWRITE_TAC[ + WORD_RULE `!(a:int64) b c. word_add (word_add a b) c = word_add a (word_add b c)`; + WORD_RULE `!a b. word_add ((word a):int64) (word b) = word (a + b)`] + ; ALL_TAC] THEN + POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th])) THEN + + (* case analysis based on i = 0 ... 14, this is unavoidable because symbolic execution + needs to know which byte is being overwritten in pt_ptr to properly update the state. *) + MAP_EVERY (fun i -> TAIL_SWAP_ASM_CASES_TAC (mk_numeral (num i))) (0--14) THEN + UNDISCH_TAC `15 <= i` THEN + UNDISCH_TAC `i < val (tail_len:int64)` THEN + UNDISCH_TAC `val (tail_len:int64) < 16` THEN + ARITH_TAC; + + (* Subgoal 4: *) + REPEAT STRIP_TAC THEN + REWRITE_TAC[byte_list_at] THEN + ENSURES_INIT_TAC "s0" THEN + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (1--1) THEN + SUBGOAL_THEN `ival ((word i):int64) < &0x0 <=> + ~(ival ((word (i + 0x1)):int64) - &0x1 = ival ((word i):int64))` ASSUME_TAC THENL + [ SUBGOAL_THEN `ival ((word i):int64) = &i` ASSUME_TAC THENL + [ MATCH_MP_TAC IVAL_WORD_LT THEN + UNDISCH_TAC `i < val (tail_len:int64)` THEN + UNDISCH_TAC `val (tail_len:int64) < 0x10` THEN + ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `ival ((word (i + 0x1)):int64) = &(i + 1)` ASSUME_TAC THENL + [ MATCH_MP_TAC IVAL_WORD_LT THEN + UNDISCH_TAC `i < val (tail_len:int64)` THEN + UNDISCH_TAC `val (tail_len:int64) < 0x10` THEN + ARITH_TAC; ALL_TAC] THEN + ASM_REWRITE_TAC[] THEN ARITH_TAC; ALL_TAC] THEN - SUBGOAL_THEN `val (num_5blocks_adjusted:int64) * 0x50 <= val (len:int64)` ASSUME_TAC THENL - [ EXPAND_TAC "num_5blocks_adjusted" THEN - REWRITE_TAC [VAL_WORD; DIMINDEX_64] THEN - UNDISCH_TAC `val (num_blocks_adjusted:int64) <= 0x2 EXP 0x18` THEN - UNDISCH_TAC `val (num_blocks_adjusted:int64) <= val (len:int64)` THEN + POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th])) THEN + ENSURES_FINAL_STATE_TAC THEN ASM_SIMP_TAC[]; + + (* Subgoal 5: *) + REPEAT STRIP_TAC THEN + REWRITE_TAC[byte_list_at] THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[cipher_stealing_inv; CONJUNCT1 SUB_LIST; CONJUNCT1 APPEND] THEN + REWRITE_TAC[SUB_0] THEN + ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN `val ((word (val (tail_len:int64))):int64) = val tail_len` SUBST1_TAC THENL + [ IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `(SUB_LIST (0x0,val (tail_len:int64)) (SUB_LIST (curr_len + 16,val tail_len) (ct:byte list))) = + (SUB_LIST (curr_len + 16,val tail_len) ct)` SUBST1_TAC THENL + [ IMP_REWRITE_TAC[SUB_LIST_REFL] THEN + ASM_REWRITE_TAC[LENGTH_SUB_LIST; MIN] THEN + ASM_ARITH_TAC; ALL_TAC] THEN + + MATCH_MP_TAC ENSURES_FRAME_SUBSUMED THEN + EXISTS_TAC `MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI ,, + MAYCHANGE [X19; X20; X21; X22],, + MAYCHANGE [Q8; Q9; Q10; Q11; Q12; Q13; Q14; Q15],, + MAYCHANGE [memory :> bytes128 (word_add pt_ptr (word curr_len))]` THEN + REWRITE_TAC[MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI] THEN + CONJ_TAC THENL [ + REPEAT (GEN_REWRITE_TAC ONCE_DEPTH_CONV [GSYM SEQ_ASSOC] THEN + MATCH_MP_TAC SUBSUMED_SEQ THEN REWRITE_TAC[SUBSUMED_REFL]) THEN + ABBREV_TAC `vallen = val (len:int64)` THEN + SUBSUMED_MAYCHANGE_TAC; ALL_TAC] THEN + + ENSURES_INIT_TAC "s0" THEN + + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (1--32) THEN + ABBREV_TAC `combinedPP = bytes_to_int128 + (APPEND (SUB_LIST (curr_len + 16,val (tail_len:int64)) (ct:byte list)) + (SUB_LIST (val tail_len,0x10 - val tail_len) + (int128_to_bytes (PP:int128))))` THEN + FIRST_X_ASSUM(MP_TAC o SPEC `aes256_xts_decrypt_round combinedPP + (calculate_tweak curr_blocks iv key2) key1` o MATCH_MP (MESON[] + `read (Q26:(armstate,int128)component) (s:armstate) = a ==> !a'. a = a' ==> read Q26 s = a'`)) THEN + ANTS_TAC THENL + [ EXPAND_TAC "key1" THEN + CONV_TAC (RAND_CONV ( + REWRITE_CONV [aes256_xts_decrypt_round] THENC + DEPTH_CONV let_CONV)) THEN + AESDEC_TAC; DISCH_TAC ] THEN + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (33--33) THEN + ENSURES_FINAL_STATE_TAC THEN ASM_SIMP_TAC[] THEN + + UNDISCH_THEN `curr_len + 16 + val (tail_len:int64) = val (len:int64)` + (fun th -> SUBST1_TAC (GSYM th)) THEN + SUBGOAL_THEN `~(curr_len < 16)` ASSUME_TAC THENL + [ REWRITE_TAC[GSYM (ASSUME `acc_len num_5blocks_adjusted num_blocks_adjusted = curr_len`)] THEN + REWRITE_TAC[acc_len] THEN + COND_CASES_TAC THENL [ ARITH_TAC; ALL_TAC] THEN + COND_CASES_TAC THENL [ ARITH_TAC; ALL_TAC] THEN + COND_CASES_TAC THENL [ ARITH_TAC; ALL_TAC] THEN + COND_CASES_TAC THENL [ ARITH_TAC; ALL_TAC] THEN + UNDISCH_TAC `0x0 < val (num_5blocks_adjusted:int64)` THEN + ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `curr_len = 16 * curr_blocks` SUBST_ALL_TAC THENL + [ REWRITE_TAC[GSYM (ASSUME `acc_len num_5blocks_adjusted num_blocks_adjusted = curr_len`)] THEN + EXPAND_TAC "curr_blocks" THEN + REWRITE_TAC[acc_len; acc_blocks] THEN + COND_CASES_TAC THENL [SIMP_TAC[] THEN ARITH_TAC; ALL_TAC] THEN SIMP_TAC[] THEN + COND_CASES_TAC THENL [SIMP_TAC[] THEN ARITH_TAC; ALL_TAC] THEN SIMP_TAC[] THEN + COND_CASES_TAC THENL [SIMP_TAC[] THEN ARITH_TAC; ALL_TAC] THEN SIMP_TAC[] THEN + COND_CASES_TAC THENL [SIMP_TAC[] THEN ARITH_TAC; ALL_TAC] THEN SIMP_TAC[] THEN ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `curr_blocks >= 1` ASSUME_TAC THENL + [ UNDISCH_TAC `~(16 * curr_blocks < 16)` THEN ARITH_TAC; ALL_TAC] THEN - (* Verify properties of the program until the beginning of the loop. + MATCH_MP_TAC BREAK_DATA_INTO_PARTS THEN + REPEAT CONJ_TAC THENL + [ + (* 0. Trivial *) + IMP_REWRITE_TAC[LENGTH_OF_AES256_XTS_DECRYPT] THEN ARITH_TAC; + + (* 1. Result correct up to curr_len *) + UNDISCH_TAC `forall i. + i < 16 * curr_blocks + ==> read (memory :> bytes8 (word_add (pt_ptr:int64) (word i))) s33 = + EL i (aes256_xts_decrypt (ct:byte list) (16 * curr_blocks) (iv:int128) + (key1:int128 list) (key2:int128 list))` THEN + MP_TAC (SPECL [`16 * curr_blocks:num`; `pt_ptr:int64`; + `(aes256_xts_decrypt ct (16 * curr_blocks + 0x10 + val (tail_len:int64)) iv key1 key2):byte list`; + `s33:armstate`] BYTE_LIST_TO_NUM_THM) THEN + ANTS_TAC THENL[ + IMP_REWRITE_TAC[LENGTH_OF_AES256_XTS_DECRYPT] THEN + ARITH_TAC; ALL_TAC] THEN + DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN + MP_TAC (SPECL [`16 * curr_blocks:num`; `pt_ptr:int64`; + `(aes256_xts_decrypt ct (16 * curr_blocks) iv key1 key2):byte list`; + `s33:armstate`] BYTE_LIST_TO_NUM_THM) THEN + ANTS_TAC THENL[ + REWRITE_TAC[LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS] THEN + ARITH_TAC; ALL_TAC] THEN + DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN + + DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN + AP_TERM_TAC THEN + MP_TAC (SPECL [`curr_blocks:num`; `ct:byte list`; `iv:int128`; + `key1:int128 list`; `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN + REWRITE_TAC[ADD_0] THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_OF_AES256_XTS_DECRYPT] THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES]; + + (* 2. Last full block is correct *) + MP_TAC (SPECL [`16:num`; `(word_add pt_ptr (word (0x10 * curr_blocks))):int64`; + `(SUB_LIST (0x10 * curr_blocks,0x10 + val (tail_len:int64)) + (aes256_xts_decrypt ct (0x10 * curr_blocks + 0x10 + val tail_len) + iv key1 key2)):byte list`; + `s33:armstate`] BYTE_LIST_TO_NUM_THM) THEN + ANTS_TAC THENL[ + REWRITE_TAC[LENGTH_SUB_LIST] THEN + IMP_REWRITE_TAC[LENGTH_OF_AES256_XTS_DECRYPT] THEN + ARITH_TAC; ALL_TAC] THEN + DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN + + (* Proving last full block correct *) + REWRITE_TAC[READ_MEMORY_BYTES_BYTES128] THEN + ASM_REWRITE_TAC[] THEN + REWRITE_TAC[SUB_LIST_MIN_RIGHT; MIN] THEN + SIMP_TAC[ARITH_RULE `!x. 0x10 <= 0x10 + x`] THEN + REWRITE_TAC[aes256_xts_decrypt] THEN + SIMP_TAC[ARITH_RULE `!x y. ~(x + 16 + y < 16)`] THEN + REWRITE_TAC[ARITH_RULE `0x10 * curr_blocks + 0x10 + val tail_len = + 0x10 * (curr_blocks + 1) + val tail_len`] THEN + REWRITE_TAC[MOD_MULT_ADD] THEN + ASM_SIMP_TAC[MOD_LT] THEN + REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + REWRITE_TAC[ARITH_RULE + `((0x10 * (curr_blocks + 0x1) + val tail_len) - val tail_len) DIV 0x10 = + (0x10 * (curr_blocks + 0x1)) DIV 0x10`] THEN + IMP_REWRITE_TAC[DIV_MULT; ARITH_RULE `~(16 = 0)`] THEN + IMP_REWRITE_TAC[ARITH_RULE `curr_blocks >= 1 ==> ~(curr_blocks + 1 < 2)`] THEN + IMP_REWRITE_TAC[ADD_SUB; ARITH_RULE `((curr_blocks + 0x1) - 0x2) = curr_blocks - 1`] THEN + + MP_TAC (SPECL [`0:num`; `(curr_blocks - 1):num`; `ct:byte list`; `iv:int128`; + `key1:int128 list`; `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT_REC) THEN + ASM_SIMP_TAC[ARITH_RULE `curr_blocks >= 1 ==> ~(curr_blocks - 1 < 0)`] THEN + IMP_REWRITE_TAC[SUB_0; ARITH_RULE `curr_blocks >= 1 ==> curr_blocks - 1 + 1 = curr_blocks`] THEN + ONCE_REWRITE_TAC[ARITH_RULE `curr_blocks * 16 = 16 * curr_blocks`] THEN + DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_APPEND_RIGHT_LEMMA] THEN + + REWRITE_TAC[aes256_xts_decrypt_tail] THEN + ASM_SIMP_TAC[LET_DEF; LET_END_DEF] THEN + + MP_TAC (SPECL [`(SUB_LIST (curr_blocks * 0x10,0x10) ct):byte list`; + `(SUB_LIST ((curr_blocks + 0x1) * 0x10,val (tail_len:int64)) ct):byte list`; + `val (tail_len:int64)`; `iv:int128`; `curr_blocks:num`; `key1:int128 list`; + `key2:int128 list`] LENGTH_OF_FST_OF_CIPHER_STEALING) THEN + DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_APPEND_LEFT; ARITH_RULE `16 <= 16`] THEN + + REWRITE_TAC[cipher_stealing; LET_DEF; LET_END_DEF] THEN + REWRITE_TAC[SUB_LIST_OF_INT128_TO_BYTES; + NUM_OF_BYTELIST_OF_INT128_TO_BYTES; CALCULATE_TWEAK_EXPAND; + ARITH_RULE `curr_blocks * 16 = 16 * curr_blocks`; + ARITH_RULE `0x10 * (curr_blocks + 0x1) = 16 * curr_blocks + 16`] THEN + EXPAND_TAC "combinedPP" THEN + EXPAND_TAC "PP" THEN + REFL_TAC; + + (* 3. Proving tail is correct *) + UNDISCH_TAC + `forall i. i < val (tail_len:int64) + ==> read (memory :> bytes8 + (word_add (word_add pt_ptr (word (0x10 * curr_blocks + 0x10))) + (word i))) s33 = + EL i (SUB_LIST (0x0,val tail_len) (int128_to_bytes PP))` THEN + MP_TAC (SPECL [`val (tail_len:int64):num`; `(word_add pt_ptr (word (0x10 * curr_blocks + 0x10))):int64`; + `(SUB_LIST (0x0,val (tail_len:int64)) (int128_to_bytes PP)):byte list`; + `s33:armstate`] BYTE_LIST_TO_NUM_THM) THEN + ANTS_TAC THENL[ + REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN + CONV_TAC NUM_REDUCE_CONV THEN + UNDISCH_TAC `val (tail_len:int64) < 0x10` THEN + ARITH_TAC; ALL_TAC] THEN + DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN + MP_TAC (SPECL [`val (tail_len:int64):num`; `(word_add pt_ptr (word (0x10 * curr_blocks + 0x10))):int64`; + `(SUB_LIST (0x10 * curr_blocks + 0x10,val (tail_len:int64)) + (aes256_xts_decrypt ct (0x10 * curr_blocks + 0x10 + val tail_len) iv key1 key2)):byte list`; + `s33:armstate`] BYTE_LIST_TO_NUM_THM) THEN + ANTS_TAC THENL[ + REWRITE_TAC[LENGTH_SUB_LIST] THEN + IMP_REWRITE_TAC[LENGTH_OF_AES256_XTS_DECRYPT] THEN + ARITH_TAC; ALL_TAC] THEN + DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN + + DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN + AP_TERM_TAC THEN + REWRITE_TAC[SUB_LIST_IDEMPOTENT] THEN + REWRITE_TAC[SUB_LIST_MIN_RIGHT; MIN; LE_REFL] THEN + + REWRITE_TAC[aes256_xts_decrypt; + ARITH_RULE `~(0x10 * curr_blocks + 0x10 + val (tail_len:int64) < 0x10)`] THEN + REWRITE_TAC[ARITH_RULE `0x10 * curr_blocks + 0x10 + val tail_len = + 0x10 * (curr_blocks + 1) + val tail_len`] THEN + REWRITE_TAC[MOD_MULT_ADD] THEN + ASM_SIMP_TAC[MOD_LT] THEN + REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + REWRITE_TAC[ARITH_RULE + `((0x10 * (curr_blocks + 0x1) + val tail_len) - val tail_len) DIV 0x10 = + (0x10 * (curr_blocks + 0x1)) DIV 0x10`] THEN + IMP_REWRITE_TAC[DIV_MULT; ARITH_RULE `~(16 = 0)`] THEN + IMP_REWRITE_TAC[ARITH_RULE `curr_blocks >= 1 ==> ~(curr_blocks + 1 < 2)`] THEN + IMP_REWRITE_TAC[ADD_SUB; ARITH_RULE `((curr_blocks + 0x1) - 0x2) = curr_blocks - 1`] THEN + + MP_TAC (ISPECL [`(aes256_xts_decrypt_rec 0x0 (curr_blocks - 0x1) ct iv key1 key2):byte list`; + `(aes256_xts_decrypt_tail curr_blocks (val (tail_len:int64)) ct iv key1 key2):byte list`; + `0x10 * curr_blocks + 0x10:num`; `val (tail_len:int64)`; `0x10 * curr_blocks:num` + ] SUB_LIST_APPEND_RIGHT_GENERAL) THEN + ANTS_TAC THENL + [ REWRITE_TAC[LENGTH_OF_AES256_XTS_DECRYPT_REC] THEN + UNDISCH_TAC `curr_blocks >= 1` THEN + ARITH_TAC; ALL_TAC] THEN + ANTS_TAC THENL [ ARITH_TAC; ALL_TAC] THEN + DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN + + REWRITE_TAC[ARITH_RULE `(0x10 * curr_blocks + 0x10) - 0x10 * curr_blocks = 0x10`] THEN + REWRITE_TAC[aes256_xts_decrypt_tail] THEN + ASM_SIMP_TAC[LET_DEF; LET_END_DEF] THEN + + MP_TAC (SPECL [`(SUB_LIST (curr_blocks * 0x10,0x10) ct):byte list`; + `(SUB_LIST ((curr_blocks + 0x1) * 0x10,val (tail_len:int64)) ct):byte list`; + `val (tail_len:int64)`; `iv:int128`; `curr_blocks:num`; `key1:int128 list`; + `key2:int128 list`] LENGTH_OF_FST_OF_CIPHER_STEALING) THEN + DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_APPEND_RIGHT_LEMMA; ARITH_RULE `16 <= 16`] THEN + + REWRITE_TAC[cipher_stealing; LET_DEF; LET_END_DEF; SUB_LIST_IDEMPOTENT] THEN + EXPAND_TAC "PP" THEN + REWRITE_TAC[ARITH_RULE `curr_blocks * 0x10 = 0x10 * curr_blocks`; + CALCULATE_TWEAK_EXPAND] + ] + ] +);; + + +let AES_XTS_DECRYPT_EQ_1BLOCK_CORRECT = time prove( + `!ct_ptr pt_ptr ct key1_ptr key2_ptr iv_ptr iv len + k00 k01 k02 k03 k04 k05 k06 k07 k08 k09 k0a k0b k0c k0d k0e + k10 k11 k12 k13 k14 k15 k16 k17 k18 k19 k1a k1b k1c k1d k1e + pc. + nonoverlapping (word pc, LENGTH aes_xts_decrypt_mc) (pt_ptr, val len) + /\ nonoverlapping (ct_ptr, val len) (pt_ptr, val len) + /\ nonoverlapping (key1_ptr, 260) (pt_ptr, val len) + /\ val len = 16 /\ LENGTH ct = val len + /\ [k00; k01; k02; k03; k04; k05; k06; k07; k08; k09; k0a; k0b; k0c; k0d; k0e] = key1 + /\ [k10; k11; k12; k13; k14; k15; k16; k17; k18; k19; k1a; k1b; k1c; k1d; k1e] = key2 + ==> ensures arm + (\s. aligned_bytes_loaded s (word pc) aes_xts_decrypt_mc /\ + read PC s = word (pc + 0x1c) /\ + C_ARGUMENTS [ct_ptr; pt_ptr; len; key1_ptr; key2_ptr; iv_ptr] s /\ + byte_list_at ct ct_ptr len s /\ + read(memory :> bytes128 iv_ptr) s = iv /\ + set_key_schedule s key1_ptr k00 k01 k02 k03 k04 k05 k06 k07 k08 k09 k0a k0b k0c k0d k0e /\ + set_key_schedule s key2_ptr k10 k11 k12 k13 k14 k15 k16 k17 k18 k19 k1a k1b k1c k1d k1e) + (\s. read PC s = word (pc + 0xb58) /\ + byte_list_at (aes256_xts_decrypt ct (val len) iv key1 key2) pt_ptr len s + ) + (MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI,, + MAYCHANGE [X19; X20; X21; X22],, + MAYCHANGE [Q8; Q9; Q10; Q11; Q12; Q13; Q14; Q15],, + MAYCHANGE [memory :> bytes(pt_ptr, val len)]) + `, + CHEAT_TAC);; + + +let AES_XTS_DECRYPT_LT_2BLOCK_CORRECT = time prove( + `!ct_ptr pt_ptr ct key1_ptr key2_ptr iv_ptr iv len + k00 k01 k02 k03 k04 k05 k06 k07 k08 k09 k0a k0b k0c k0d k0e + k10 k11 k12 k13 k14 k15 k16 k17 k18 k19 k1a k1b k1c k1d k1e + pc. + nonoverlapping (word pc, LENGTH aes_xts_decrypt_mc) (pt_ptr, val len) + /\ nonoverlapping (ct_ptr, val len) (pt_ptr, val len) + /\ nonoverlapping (key1_ptr, 260) (pt_ptr, val len) + /\ val len >= 16 /\ val len < 0x20 /\ LENGTH ct = val len + /\ [k00; k01; k02; k03; k04; k05; k06; k07; k08; k09; k0a; k0b; k0c; k0d; k0e] = key1 + /\ [k10; k11; k12; k13; k14; k15; k16; k17; k18; k19; k1a; k1b; k1c; k1d; k1e] = key2 + ==> ensures arm + (\s. aligned_bytes_loaded s (word pc) aes_xts_decrypt_mc /\ + read PC s = word (pc + 0x1c) /\ + C_ARGUMENTS [ct_ptr; pt_ptr; len; key1_ptr; key2_ptr; iv_ptr] s /\ + byte_list_at ct ct_ptr len s /\ + read(memory :> bytes128 iv_ptr) s = iv /\ + set_key_schedule s key1_ptr k00 k01 k02 k03 k04 k05 k06 k07 k08 k09 k0a k0b k0c k0d k0e /\ + set_key_schedule s key2_ptr k10 k11 k12 k13 k14 k15 k16 k17 k18 k19 k1a k1b k1c k1d k1e) + (\s. read PC s = word (pc + 0xb58) /\ + byte_list_at (aes256_xts_decrypt ct (val len) iv key1 key2) pt_ptr len s + ) + (MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI,, + MAYCHANGE [X19; X20; X21; X22],, + MAYCHANGE [Q8; Q9; Q10; Q11; Q12; Q13; Q14; Q15],, + MAYCHANGE [memory :> bytes(pt_ptr, val len)]) + `, + CHEAT_TAC);; + + +let AES_XTS_DECRYPT_LT_3BLOCK_CORRECT = time prove( + `!ct_ptr pt_ptr ct key1_ptr key2_ptr iv_ptr iv len + k00 k01 k02 k03 k04 k05 k06 k07 k08 k09 k0a k0b k0c k0d k0e + k10 k11 k12 k13 k14 k15 k16 k17 k18 k19 k1a k1b k1c k1d k1e + pc. + nonoverlapping (word pc, LENGTH aes_xts_decrypt_mc) (pt_ptr, val len) + /\ nonoverlapping (ct_ptr, val len) (pt_ptr, val len) + /\ nonoverlapping (key1_ptr, 260) (pt_ptr, val len) + /\ val len >= 16 /\ val len < 0x30 /\ LENGTH ct = val len + /\ [k00; k01; k02; k03; k04; k05; k06; k07; k08; k09; k0a; k0b; k0c; k0d; k0e] = key1 + /\ [k10; k11; k12; k13; k14; k15; k16; k17; k18; k19; k1a; k1b; k1c; k1d; k1e] = key2 + ==> ensures arm + (\s. aligned_bytes_loaded s (word pc) aes_xts_decrypt_mc /\ + read PC s = word (pc + 0x1c) /\ + C_ARGUMENTS [ct_ptr; pt_ptr; len; key1_ptr; key2_ptr; iv_ptr] s /\ + byte_list_at ct ct_ptr len s /\ + read(memory :> bytes128 iv_ptr) s = iv /\ + set_key_schedule s key1_ptr k00 k01 k02 k03 k04 k05 k06 k07 k08 k09 k0a k0b k0c k0d k0e /\ + set_key_schedule s key2_ptr k10 k11 k12 k13 k14 k15 k16 k17 k18 k19 k1a k1b k1c k1d k1e) + (\s. read PC s = word (pc + 0xb58) /\ + byte_list_at (aes256_xts_decrypt ct (val len) iv key1 key2) pt_ptr len s + ) + (MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI,, + MAYCHANGE [X19; X20; X21; X22],, + MAYCHANGE [Q8; Q9; Q10; Q11; Q12; Q13; Q14; Q15],, + MAYCHANGE [memory :> bytes(pt_ptr, val len)]) + `, + CHEAT_TAC);; + + +let AES_XTS_DECRYPT_LT_4BLOCK_CORRECT = time prove( + `!ct_ptr pt_ptr ct key1_ptr key2_ptr iv_ptr iv len + k00 k01 k02 k03 k04 k05 k06 k07 k08 k09 k0a k0b k0c k0d k0e + k10 k11 k12 k13 k14 k15 k16 k17 k18 k19 k1a k1b k1c k1d k1e + pc. + nonoverlapping (word pc, LENGTH aes_xts_decrypt_mc) (pt_ptr, val len) + /\ nonoverlapping (ct_ptr, val len) (pt_ptr, val len) + /\ nonoverlapping (key1_ptr, 260) (pt_ptr, val len) + /\ val len >= 16 /\ val len < 0x40 /\ LENGTH ct = val len + /\ [k00; k01; k02; k03; k04; k05; k06; k07; k08; k09; k0a; k0b; k0c; k0d; k0e] = key1 + /\ [k10; k11; k12; k13; k14; k15; k16; k17; k18; k19; k1a; k1b; k1c; k1d; k1e] = key2 + ==> ensures arm + (\s. aligned_bytes_loaded s (word pc) aes_xts_decrypt_mc /\ + read PC s = word (pc + 0x1c) /\ + C_ARGUMENTS [ct_ptr; pt_ptr; len; key1_ptr; key2_ptr; iv_ptr] s /\ + byte_list_at ct ct_ptr len s /\ + read(memory :> bytes128 iv_ptr) s = iv /\ + set_key_schedule s key1_ptr k00 k01 k02 k03 k04 k05 k06 k07 k08 k09 k0a k0b k0c k0d k0e /\ + set_key_schedule s key2_ptr k10 k11 k12 k13 k14 k15 k16 k17 k18 k19 k1a k1b k1c k1d k1e) + (\s. read PC s = word (pc + 0xb58) /\ + byte_list_at (aes256_xts_decrypt ct (val len) iv key1 key2) pt_ptr len s + ) + (MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI,, + MAYCHANGE [X19; X20; X21; X22],, + MAYCHANGE [Q8; Q9; Q10; Q11; Q12; Q13; Q14; Q15],, + MAYCHANGE [memory :> bytes(pt_ptr, val len)]) + `, + CHEAT_TAC);; + + +let AES_XTS_DECRYPT_LT_5BLOCK_CORRECT = time prove( + `!ct_ptr pt_ptr ct key1_ptr key2_ptr iv_ptr iv len + k00 k01 k02 k03 k04 k05 k06 k07 k08 k09 k0a k0b k0c k0d k0e + k10 k11 k12 k13 k14 k15 k16 k17 k18 k19 k1a k1b k1c k1d k1e + pc. + nonoverlapping (word pc, LENGTH aes_xts_decrypt_mc) (pt_ptr, val len) + /\ nonoverlapping (ct_ptr, val len) (pt_ptr, val len) + /\ nonoverlapping (key1_ptr, 260) (pt_ptr, val len) + /\ val len >= 16 /\ val len < 0x50 /\ LENGTH ct = val len + /\ [k00; k01; k02; k03; k04; k05; k06; k07; k08; k09; k0a; k0b; k0c; k0d; k0e] = key1 + /\ [k10; k11; k12; k13; k14; k15; k16; k17; k18; k19; k1a; k1b; k1c; k1d; k1e] = key2 + ==> ensures arm + (\s. aligned_bytes_loaded s (word pc) aes_xts_decrypt_mc /\ + read PC s = word (pc + 0x1c) /\ + C_ARGUMENTS [ct_ptr; pt_ptr; len; key1_ptr; key2_ptr; iv_ptr] s /\ + byte_list_at ct ct_ptr len s /\ + read(memory :> bytes128 iv_ptr) s = iv /\ + set_key_schedule s key1_ptr k00 k01 k02 k03 k04 k05 k06 k07 k08 k09 k0a k0b k0c k0d k0e /\ + set_key_schedule s key2_ptr k10 k11 k12 k13 k14 k15 k16 k17 k18 k19 k1a k1b k1c k1d k1e) + (\s. read PC s = word (pc + 0xb58) /\ + byte_list_at (aes256_xts_decrypt ct (val len) iv key1 key2) pt_ptr len s + ) + (MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI,, + MAYCHANGE [X19; X20; X21; X22],, + MAYCHANGE [Q8; Q9; Q10; Q11; Q12; Q13; Q14; Q15],, + MAYCHANGE [memory :> bytes(pt_ptr, val len)]) + `, + CHEAT_TAC);; + + +let AES_XTS_DECRYPT_LT_6BLOCK_CORRECT = time prove( + `!ct_ptr pt_ptr ct key1_ptr key2_ptr iv_ptr iv len + k00 k01 k02 k03 k04 k05 k06 k07 k08 k09 k0a k0b k0c k0d k0e + k10 k11 k12 k13 k14 k15 k16 k17 k18 k19 k1a k1b k1c k1d k1e + pc. + nonoverlapping (word pc, LENGTH aes_xts_decrypt_mc) (pt_ptr, val len) + /\ nonoverlapping (ct_ptr, val len) (pt_ptr, val len) + /\ nonoverlapping (key1_ptr, 260) (pt_ptr, val len) + /\ val len >= 16 /\ val len < 0x60 /\ LENGTH ct = val len + /\ [k00; k01; k02; k03; k04; k05; k06; k07; k08; k09; k0a; k0b; k0c; k0d; k0e] = key1 + /\ [k10; k11; k12; k13; k14; k15; k16; k17; k18; k19; k1a; k1b; k1c; k1d; k1e] = key2 + ==> ensures arm + (\s. aligned_bytes_loaded s (word pc) aes_xts_decrypt_mc /\ + read PC s = word (pc + 0x1c) /\ + C_ARGUMENTS [ct_ptr; pt_ptr; len; key1_ptr; key2_ptr; iv_ptr] s /\ + byte_list_at ct ct_ptr len s /\ + read(memory :> bytes128 iv_ptr) s = iv /\ + set_key_schedule s key1_ptr k00 k01 k02 k03 k04 k05 k06 k07 k08 k09 k0a k0b k0c k0d k0e /\ + set_key_schedule s key2_ptr k10 k11 k12 k13 k14 k15 k16 k17 k18 k19 k1a k1b k1c k1d k1e) + (\s. read PC s = word (pc + 0xb58) /\ + byte_list_at (aes256_xts_decrypt ct (val len) iv key1 key2) pt_ptr len s + ) + (MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI,, + MAYCHANGE [X19; X20; X21; X22],, + MAYCHANGE [Q8; Q9; Q10; Q11; Q12; Q13; Q14; Q15],, + MAYCHANGE [memory :> bytes(pt_ptr, val len)]) + `, + CHEAT_TAC);; + + +let AES_XTS_DECRYPT_CORRECT = time prove( + `!ct_ptr pt_ptr ct key1_ptr key2_ptr iv_ptr iv len + k00 k01 k02 k03 k04 k05 k06 k07 k08 k09 k0a k0b k0c k0d k0e + k10 k11 k12 k13 k14 k15 k16 k17 k18 k19 k1a k1b k1c k1d k1e + pc. + nonoverlapping (word pc, LENGTH aes_xts_decrypt_mc) (pt_ptr, val len) + /\ nonoverlapping (ct_ptr, val len) (pt_ptr, val len) + /\ nonoverlapping (key1_ptr, 260) (pt_ptr, val len) + /\ val len >= 16 /\ val len <= 2 EXP 24 /\ LENGTH ct = val len + ==> ensures arm + (\s. aligned_bytes_loaded s (word pc) aes_xts_decrypt_mc /\ + read PC s = word (pc + 0x1c) /\ + C_ARGUMENTS [ct_ptr; pt_ptr; len; key1_ptr; key2_ptr; iv_ptr] s /\ + byte_list_at ct ct_ptr len s /\ + read(memory :> bytes128 iv_ptr) s = iv /\ + set_key_schedule s key1_ptr k00 k01 k02 k03 k04 k05 k06 k07 k08 k09 k0a k0b k0c k0d k0e /\ + set_key_schedule s key2_ptr k10 k11 k12 k13 k14 k15 k16 k17 k18 k19 k1a k1b k1c k1d k1e) + (\s. read PC s = word (pc + 0xb58) /\ + byte_list_at (aes256_xts_decrypt ct (val len) iv + [k00; k01; k02; k03; k04; k05; k06; k07; k08; k09; k0a; k0b; k0c; k0d; k0e] + [k10; k11; k12; k13; k14; k15; k16; k17; k18; k19; k1a; k1b; k1c; k1d; k1e]) + pt_ptr len s + ) + (MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI,, + MAYCHANGE [X19; X20; X21; X22],, + MAYCHANGE [Q8; Q9; Q10; Q11; Q12; Q13; Q14; Q15],, + MAYCHANGE [memory :> bytes(pt_ptr, val len)]) + `, + REWRITE_TAC [(REWRITE_CONV [aes_xts_decrypt_mc] THENC LENGTH_CONV) `LENGTH aes_xts_decrypt_mc`] THEN + REWRITE_TAC[set_key_schedule; C_ARGUMENTS; SOME_FLAGS; + NONOVERLAPPING_CLAUSES; byte_list_at; + MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI] THEN + REPEAT STRIP_TAC THEN + + (* These are for top-level wrapper function + (* Add values for preserved registers *) + ENSURES_PRESERVED_TAC "x19_init" `X19` THEN + ENSURES_PRESERVED_TAC "x20_init" `X20` THEN + ENSURES_PRESERVED_TAC "x21_init" `X21` THEN + ENSURES_PRESERVED_TAC "x22_init" `X22` THEN + ENSURES_PRESERVED_DREG_TAC "d8_init" `D8` THEN + ENSURES_PRESERVED_DREG_TAC "d9_init" `D9` THEN + ENSURES_PRESERVED_DREG_TAC "d10_init" `D10` THEN + ENSURES_PRESERVED_DREG_TAC "d11_init" `D11` THEN + ENSURES_PRESERVED_DREG_TAC "d12_init" `D12` THEN + ENSURES_PRESERVED_DREG_TAC "d13_init" `D13` THEN + ENSURES_PRESERVED_DREG_TAC "d14_init" `D14` THEN + ENSURES_PRESERVED_DREG_TAC "d15_init" `D15` THEN +*) + + (* Break len into full blocks and tail *) + SUBGOAL_THEN `word_add (word_and len (word 0xf)) + (word_and len (word 0xfffffffffffffff0)) = len:int64` ASSUME_TAC THENL + [REWRITE_TAC[word_split_lemma]; ALL_TAC] THEN + ABBREV_TAC `num_blocks:int64 = word_and len (word 0xfffffffffffffff0)` THEN + ABBREV_TAC `tail_len:int64 = word_and len (word 0xf)` THEN + ABBREV_TAC `key1:int128 list = [k00; k01; k02; k03; k04; k05; k06; k07; k08; k09; k0a; k0b; k0c; k0d; k0e]` THEN + ABBREV_TAC `key2:int128 list = [k10; k11; k12; k13; k14; k15; k16; k17; k18; k19; k1a; k1b; k1c; k1d; k1e]` THEN + + (* Case splits on length: + len < 16 -- error case + len < 32 -- one block, or one block and a tail + len < 48 -- two blocks, or two blocks and a tail + len < 64 -- three blocks, or three blocks and a tail + len < 80 -- four blocks, or four blocks and a tail + len < 96 -- five blocks, or five blocks and a tail + len >= 96 -- six blocks and up + + Note: for decrypt, because of cipherstealing, there needs to be one extra + block at the end together with the tail to be processed for cipherstealing + *) + ASM_CASES_TAC `val (len:int64) < 0x60` THENL [ + ASM_CASES_TAC `val (len:int64) = 16` THENL + [ + MP_TAC AES_XTS_DECRYPT_EQ_1BLOCK_CORRECT THEN + REWRITE_TAC [(REWRITE_CONV [aes_xts_decrypt_mc] THENC LENGTH_CONV) `LENGTH aes_xts_decrypt_mc`] THEN + REWRITE_TAC[set_key_schedule; C_ARGUMENTS; SOME_FLAGS; + NONOVERLAPPING_CLAUSES; byte_list_at; + MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI] THEN + DISCH_THEN MATCH_MP_TAC THEN + ASM_SIMP_TAC[]; + ALL_TAC + ] THEN + + ASM_CASES_TAC `val (len:int64) < 0x20` THENL + [ + MP_TAC AES_XTS_DECRYPT_LT_2BLOCK_CORRECT THEN + REWRITE_TAC [(REWRITE_CONV [aes_xts_decrypt_mc] THENC LENGTH_CONV) `LENGTH aes_xts_decrypt_mc`] THEN + REWRITE_TAC[set_key_schedule; C_ARGUMENTS; SOME_FLAGS; + NONOVERLAPPING_CLAUSES; byte_list_at; + MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI] THEN + DISCH_THEN MATCH_MP_TAC THEN + ASM_SIMP_TAC[]; + ALL_TAC + ] THEN + + ASM_CASES_TAC `val (len:int64) < 0x30` THENL + [ + MP_TAC AES_XTS_DECRYPT_LT_3BLOCK_CORRECT THEN + REWRITE_TAC [(REWRITE_CONV [aes_xts_decrypt_mc] THENC LENGTH_CONV) `LENGTH aes_xts_decrypt_mc`] THEN + REWRITE_TAC[set_key_schedule; C_ARGUMENTS; SOME_FLAGS; + NONOVERLAPPING_CLAUSES; byte_list_at; + MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI] THEN + DISCH_THEN MATCH_MP_TAC THEN + ASM_SIMP_TAC[]; + ALL_TAC + ] THEN + + ASM_CASES_TAC `val (len:int64) < 0x40` THENL + [ + MP_TAC AES_XTS_DECRYPT_LT_4BLOCK_CORRECT THEN + REWRITE_TAC [(REWRITE_CONV [aes_xts_decrypt_mc] THENC LENGTH_CONV) `LENGTH aes_xts_decrypt_mc`] THEN + REWRITE_TAC[set_key_schedule; C_ARGUMENTS; SOME_FLAGS; + NONOVERLAPPING_CLAUSES; byte_list_at; + MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI] THEN + DISCH_THEN MATCH_MP_TAC THEN + ASM_SIMP_TAC[]; + ALL_TAC + ] THEN + + ASM_CASES_TAC `val (len:int64) < 0x50` THENL + [ + MP_TAC AES_XTS_DECRYPT_LT_5BLOCK_CORRECT THEN + REWRITE_TAC [(REWRITE_CONV [aes_xts_decrypt_mc] THENC LENGTH_CONV) `LENGTH aes_xts_decrypt_mc`] THEN + REWRITE_TAC[set_key_schedule; C_ARGUMENTS; SOME_FLAGS; + NONOVERLAPPING_CLAUSES; byte_list_at; + MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI] THEN + DISCH_THEN MATCH_MP_TAC THEN + ASM_SIMP_TAC[]; + ALL_TAC + ] THEN + + ASM_CASES_TAC `val (len:int64) < 0x60` THENL + [ + MP_TAC AES_XTS_DECRYPT_LT_6BLOCK_CORRECT THEN + REWRITE_TAC [(REWRITE_CONV [aes_xts_decrypt_mc] THENC LENGTH_CONV) `LENGTH aes_xts_decrypt_mc`] THEN + REWRITE_TAC[set_key_schedule; C_ARGUMENTS; SOME_FLAGS; + NONOVERLAPPING_CLAUSES; byte_list_at; + MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI] THEN + DISCH_THEN MATCH_MP_TAC THEN + ASM_SIMP_TAC[]; + ALL_TAC + ] THEN + + ASM_ARITH_TAC + ; ALL_TAC] THEN + + ABBREV_TAC `num_blocks_adjusted = if val (tail_len:int64) = 0 + then num_blocks else word_sub (num_blocks:int64) (word 0x10)` THEN + ABBREV_TAC `num_5blocks_adjusted = (word (val (num_blocks_adjusted:int64) DIV 0x50)):int64` THEN + + (* Prove once and for all the bounds for num_blocks, num_blocks_adjusted + and num_5blocks_adjusted *) + SUBGOAL_THEN `~(val (num_blocks:int64) < 96)` ASSUME_TAC THENL + [ UNDISCH_TAC `~(val (len:int64) < 0x60)` THEN + UNDISCH_TAC `word_and len (word 0xfffffffffffffff0) = (num_blocks:int64)` THEN + MP_TAC (SPECL [`len:int64`; `num_blocks:int64`] NUM_BLOCKS_LO_BOUND_THM) THEN + SIMP_TAC[]; ALL_TAC] THEN + SUBGOAL_THEN `val (num_blocks:int64) <= 2 EXP 24` ASSUME_TAC THENL + [ UNDISCH_TAC `val (len:int64) <= 2 EXP 24` THEN + UNDISCH_TAC `word_and len (word 0xfffffffffffffff0) = (num_blocks:int64)` THEN + MP_TAC (SPECL [`len:int64`; `num_blocks:int64`] NUM_BLOCKS_HI_BOUND_THM) THEN + SIMP_TAC[]; ALL_TAC] THEN + SUBGOAL_THEN `~(val (num_blocks_adjusted:int64) < 80)` ASSUME_TAC THENL + [ UNDISCH_TAC `~(val (num_blocks:int64) < 96)` THEN + UNDISCH_TAC `(if val (tail_len:int64) = 0x0 + then (num_blocks:int64) + else word_sub num_blocks (word 0x10)) = + num_blocks_adjusted` THEN + MP_TAC (SPECL [`num_blocks:int64`;`tail_len:int64`;`num_blocks_adjusted:int64`] + NUM_BLOCKS_ADJUSTED_LO_BOUND_THM) THEN SIMP_TAC[] + ; ALL_TAC] THEN + SUBGOAL_THEN `val (num_blocks_adjusted:int64) <= 2 EXP 24` ASSUME_TAC THENL + [ UNDISCH_TAC `val (num_blocks:int64) <= 2 EXP 24` THEN + UNDISCH_TAC `~(val (num_blocks:int64) < 96)` THEN + UNDISCH_TAC `(if val (tail_len:int64) = 0x0 + then (num_blocks:int64) + else word_sub num_blocks (word 0x10)) = + num_blocks_adjusted` THEN + MP_TAC (SPECL [`num_blocks:int64`;`tail_len:int64`;`num_blocks_adjusted:int64`] + NUM_BLOCKS_ADJUSTED_HI_BOUND_THM) THEN SIMP_TAC[] + ; ALL_TAC] THEN + SUBGOAL_THEN `0 < val (num_5blocks_adjusted:int64)` ASSUME_TAC THENL + [ UNDISCH_TAC `word (val (num_blocks_adjusted:int64) DIV 0x50) = (num_5blocks_adjusted:int64)` THEN + UNDISCH_TAC `~(val (num_blocks_adjusted:int64) < 0x50)` THEN + UNDISCH_TAC `val (num_blocks_adjusted:int64) <= 0x2 EXP 0x18` THEN + MP_TAC (SPECL [`num_blocks_adjusted:int64`; `num_5blocks_adjusted:int64`] + NUM_5BLOCKS_ADJUSTED_LO_BOUND_THM) THEN SIMP_TAC[] + ; ALL_TAC] THEN + SUBGOAL_THEN `val (tail_len:int64) < 16` ASSUME_TAC THENL + [ EXPAND_TAC "tail_len" THEN + REWRITE_TAC[ARITH_RULE `0xf = 2 EXP 4 - 1`] THEN + REWRITE_TAC[VAL_WORD_AND_MASK_WORD] THEN + CONV_TAC NUM_REDUCE_CONV THEN + SIMP_TAC[MOD_LT_EQ] THEN + CONV_TAC NUM_REDUCE_CONV + ; ALL_TAC] THEN + (* relationship between variables *) + SUBGOAL_THEN `val (num_blocks:int64) <= val (len:int64)` ASSUME_TAC THENL + [ EXPAND_TAC "num_blocks" THEN SIMP_TAC[NUM_BLOCKS_LT_LEN_THM]; ALL_TAC] THEN + SUBGOAL_THEN `val (num_blocks_adjusted:int64) <= val (len:int64)` ASSUME_TAC THENL + [ EXPAND_TAC "num_blocks_adjusted" THEN + COND_CASES_TAC THENL + [ ASM_SIMP_TAC[]; + UNDISCH_TAC `~(val (num_blocks:int64) < 0x60)` THEN + UNDISCH_TAC `word_and (len:int64) (word 0xfffffffffffffff0) = (num_blocks:int64)` THEN + MP_TAC (SPECL [`len:int64`; `num_blocks:int64`] NUM_BLOCKS_ADJUSTED_LT_LEN_THM) THEN + SIMP_TAC[]]; ALL_TAC] THEN + SUBGOAL_THEN `val (num_5blocks_adjusted:int64) * 0x50 <= val (num_blocks_adjusted:int64)` ASSUME_TAC THENL + [ EXPAND_TAC "num_5blocks_adjusted" THEN + REWRITE_TAC [VAL_WORD; DIMINDEX_64] THEN + UNDISCH_TAC `val (num_blocks_adjusted:int64) <= 0x2 EXP 0x18` THEN + ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `val (num_5blocks_adjusted:int64) * 0x50 <= val (len:int64)` ASSUME_TAC THENL + [ EXPAND_TAC "num_5blocks_adjusted" THEN + REWRITE_TAC [VAL_WORD; DIMINDEX_64] THEN + UNDISCH_TAC `val (num_blocks_adjusted:int64) <= 0x2 EXP 0x18` THEN + UNDISCH_TAC `val (num_blocks_adjusted:int64) <= val (len:int64)` THEN + ARITH_TAC; ALL_TAC] THEN + + (* Verify properties of the program until the beginning of the loop. The properties include the invariant, and a bunch of other initial setup. *) ENSURES_SEQUENCE_TAC `pc + 0x170` @@ -4944,251 +5945,7 @@ let AES_XTS_DECRYPT_CORRECT = time prove( REWRITE_TAC[ARITH_RULE `0x50 * i + 0x20 = (0x50 * i + 0x10) + 0x10`] THEN (* Use SPECL to force IMP_REWRITE_TAC to apply once once *) IMP_REWRITE_TAC[(SPECL [`pt_ptr:int64`; `(0x50 * val (num_5blocks_adjusted:int64) + 0x10):num`; - `x:byte list`; `s108:armstate`] READ_BYTES_AND_BYTE128_SPLIT)] THEN - EXISTS_TAC `(aes256_xts_decrypt ct (0x50 * val (num_5blocks_adjusted:int64) + 0x20) iv key1 key2)` THEN - REPEAT CONJ_TAC THENL [ - MP_TAC (SPECL [`0x5 * val (num_5blocks_adjusted:int64) + 0x2:num`; - `ct:byte list`; `iv:int128`; `key1:int128 list`; - `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN - REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC; GSYM ADD_ASSOC] THEN - CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC THEN - IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN ARITH_TAC; - - MP_TAC (SPECL [`0x5 * val (num_5blocks_adjusted:int64) + 0x2:num`; - `ct:byte list`; `iv:int128`; `key1:int128 list`; - `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN - REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC; GSYM ADD_ASSOC] THEN - CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC THEN - IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN ARITH_TAC; - - (* Establish that one xts decrypt round is the same as - selecting one block of bytes from calling the top-level function. *) - REWRITE_TAC[aes256_xts_decrypt] THEN - SIMP_TAC[ARITH_RULE `~(0x50 * i + 0x20 < 0x10)`] THEN - SUBGOAL_THEN `(0x50 * val (num_5blocks_adjusted:int64) + 0x20) MOD 0x10 = 0` SUBST1_TAC THENL - [ REWRITE_TAC[ARITH_RULE `80 * i + 32 = 16 * (5 * i + 2)`] THEN - REWRITE_TAC[MOD_MULT] - ; ALL_TAC] THEN - CONV_TAC (DEPTH_CONV let_CONV) THEN - REWRITE_TAC[SUB_0; ARITH_RULE `(0x50 * i + 0x20) DIV 0x10 = 0x5 * i + 0x2`] THEN - SIMP_TAC[ARITH_RULE `~(0x5 * i + 0x2 < 0x2)`; - ARITH_RULE `(0x5 * i + 0x2) - 0x2 = 0x5 * i`; - ARITH_RULE `(0x5 * i + 0x2) - 0x1 = 0x5 * i + 0x1`] THEN - - MP_TAC (SPECL [`0`;`5 * val (num_5blocks_adjusted:int64):num`; - `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] - LENGTH_OF_AES256_XTS_DECRYPT_REC) THEN - SIMP_TAC[ARITH_RULE `~(5 * i < 0)`; - ARITH_RULE `(0x5 * i - 0x0 + 0x1) * 0x10 = 0x50 * i + 0x10`] THEN - IMP_REWRITE_TAC[SUB_LIST_APPEND_RIGHT_LEMMA] THEN DISCH_TAC THEN - - MP_TAC (SPECL [`5 * val (num_5blocks_adjusted:int64) + 1:num`; `0x0:num`; - `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] - LENGTH_OF_AES256_XTS_DECRYPT_TAIL) THEN - CONV_TAC NUM_REDUCE_CONV THEN REWRITE_TAC[ADD_0] THEN DISCH_TAC THEN - IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN - - REWRITE_TAC[AES256_XTS_DECRYPT_TAIL_WHEN_1BLOCK] THEN - SIMP_TAC[ARITH_RULE `i * 0x50 + 0x10 = (i * 0x5 + 0x1) * 0x10`; - ARITH_RULE `i * 0x5 = 0x5 * i`]; - - (* Proving that reading previous bytes is the same as the spec *) - REWRITE_TAC[ARITH_RULE `0x50 * i + 0x10 = 0x10 * (5 * i + 1)`; - ARITH_RULE `0x50 * i + 0x20 = 0x10 * (5 * i + 1) + 0x10`] THEN - REWRITE_TAC[SUB_LIST_OF_AES256_XTS_DECRYPT_FULL_BLOCKS] THEN - ASM_REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC] THEN CONV_TAC NUM_REDUCE_CONV - ] THEN - - IMP_REWRITE_TAC[(SPECL [`pt_ptr:int64`; `(0x50 * val (num_5blocks_adjusted:int64)):num`; - `(aes256_xts_decrypt ct (0x50 * val (num_5blocks_adjusted:int64) + 0x10) iv key1 key2):byte list`; - `s108:armstate`] - READ_BYTES_AND_BYTE128_SPLIT)] THEN - EXISTS_TAC `ct:byte list` THEN EXISTS_TAC `iv:int128` THEN - EXISTS_TAC `key1:int128 list` THEN EXISTS_TAC `key2:int128 list` THEN - REPEAT CONJ_TAC THENL [ - MP_TAC (SPECL [`0x5 * val (num_5blocks_adjusted:int64) + 0x1:num`; - `ct:byte list`; `iv:int128`; `key1:int128 list`; - `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN - REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC; GSYM ADD_ASSOC] THEN - CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC THEN - IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN ARITH_TAC; - - MP_TAC (SPECL [`0x5 * val (num_5blocks_adjusted:int64) + 0x1:num`; - `ct:byte list`; `iv:int128`; `key1:int128 list`; - `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN - REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC; GSYM ADD_ASSOC] THEN - CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC THEN - IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN ARITH_TAC; - - (* Establish that one xts decrypt round is the same as - selecting one block of bytes from calling the top-level function. *) - REWRITE_TAC[aes256_xts_decrypt] THEN - SIMP_TAC[ARITH_RULE `~(0x50 * i + 0x10 < 0x10)`] THEN - SUBGOAL_THEN `(0x50 * val (num_5blocks_adjusted:int64) + 0x10) MOD 0x10 = 0` SUBST1_TAC THENL - [ REWRITE_TAC[ARITH_RULE `80 * i + 16 = 16 * (5 * i + 1)`] THEN - REWRITE_TAC[MOD_MULT] - ; ALL_TAC] THEN - CONV_TAC (DEPTH_CONV let_CONV) THEN - REWRITE_TAC[SUB_0; ARITH_RULE `(0x50 * i + 0x10) DIV 0x10 = 0x5 * i + 0x1`] THEN - (* Two cases: i = 0 then execute tail branch, else execute recursion branch *) - COND_CASES_TAC THENL - [ SUBGOAL_THEN `val (num_5blocks_adjusted:int64) = 0` SUBST1_TAC THENL - [ UNDISCH_TAC `5 * val (num_5blocks_adjusted:int64) + 1 < 2` THEN - UNDISCH_TAC `0 < val (num_5blocks_adjusted:int64)` THEN - ARITH_TAC - ; ALL_TAC] THEN CONV_TAC NUM_REDUCE_CONV THEN - - MP_TAC (SPECL [`0x0:num`; `0x0:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] - LENGTH_OF_AES256_XTS_DECRYPT_TAIL) THEN - CONV_TAC NUM_REDUCE_CONV THEN REWRITE_TAC[ADD_0] THEN DISCH_TAC THEN - IMP_REWRITE_TAC[(ISPECL [`(aes256_xts_decrypt_tail 0x0 0x0 ct iv key1 key2):byte list`; - `0x10:num`] SUB_LIST_LENGTH_IMPLIES)] THEN - - REWRITE_TAC[AES256_XTS_DECRYPT_TAIL_WHEN_1BLOCK] THEN - CONV_TAC NUM_REDUCE_CONV; - - SIMP_TAC[ARITH_RULE `(0x5 * i + 0x1) - 0x2 = 0x5 * i - 0x1`; - ARITH_RULE `(0x5 * i + 0x1) - 0x1 = 0x5 * i`] THEN - - MP_TAC (SPECL [`0`;`5 * val (num_5blocks_adjusted:int64) - 1:num`; - `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] - LENGTH_OF_AES256_XTS_DECRYPT_REC) THEN - SUBGOAL_THEN `~(0x5 * val (num_5blocks_adjusted:int64) - 0x1 < 0x0)` ASSUME_TAC THENL - [ UNDISCH_TAC `~(0x5 * val (num_5blocks_adjusted:int64) + 0x1 < 0x2)` THEN ARITH_TAC; ALL_TAC ] THEN - ASM_SIMP_TAC[] THEN - IMP_REWRITE_TAC[ARITH_RULE `~(0x5 * i + 0x1 < 0x2) ==> (0x5 * i - 1 - 0x0 + 0x1) * 0x10 = 0x50 * i`] THEN - IMP_REWRITE_TAC[SUB_LIST_APPEND_RIGHT_LEMMA] THEN DISCH_TAC THEN - - MP_TAC (SPECL [`5 * val (num_5blocks_adjusted:int64):num`; - `0x0:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] - LENGTH_OF_AES256_XTS_DECRYPT_TAIL) THEN - CONV_TAC NUM_REDUCE_CONV THEN REWRITE_TAC[ADD_0] THEN DISCH_TAC THEN - IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN - - REWRITE_TAC[AES256_XTS_DECRYPT_TAIL_WHEN_1BLOCK] THEN - SIMP_TAC[ARITH_RULE `i * 0x50 = (i * 0x5) * 0x10`; - ARITH_RULE `i * 0x5 = 0x5 * i`]]; - - (* Proving that reading previous bytes is the same as the spec *) - REWRITE_TAC[ARITH_RULE `0x50 * i = 0x10 * 5 * i`; - ARITH_RULE `0x50 * i + 0x10 = 0x10 * 5 * i + 0x10`] THEN - REWRITE_TAC[SUB_LIST_OF_AES256_XTS_DECRYPT_FULL_BLOCKS] THEN - IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN - REWRITE_TAC[LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS]] - ] - ; ALL_TAC ] THEN - - DISCH_TAC THEN - ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (6--7) THEN - FIRST_X_ASSUM MP_TAC THEN - COND_CASES_TAC THENL - [ (* Case: len % 0x50 = 0x20 *) - DISCH_TAC THEN - - SUBGOAL_THEN `val (num_5blocks_adjusted:int64) * 0x50 + 0x20 = val (num_blocks_adjusted:int64)` ASSUME_TAC THENL - [ UNDISCH_TAC `val (word_sub - (word_sub (num_blocks_adjusted:int64) - (word_mul (word 0x50) (num_5blocks_adjusted:int64))) - (word 0x20)) = - 0x0` THEN - REWRITE_TAC [VAL_EQ_0; WORD_SUB_EQ_0] THEN - REWRITE_TAC [WORD_RULE `!x:int64. word_mul (word 0x50) x = word(val x * 0x50)`] THEN - REWRITE_TAC[GSYM VAL_EQ] THEN - SUBGOAL_THEN `val (num_5blocks_adjusted:int64) * 0x50 < 2 EXP 64` MP_TAC THENL - [ UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 <= val (num_blocks_adjusted:int64)` THEN - UNDISCH_TAC `val (num_blocks_adjusted:int64) <= 2 EXP 24` THEN - ARITH_TAC; ALL_TAC] THEN - REWRITE_TAC[VAL_WORD_SUB_CASES] THEN - SIMP_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN - UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 <= val (num_blocks_adjusted:int64)` THEN - NUM_REDUCE_TAC THEN ARITH_TAC; ALL_TAC] THEN - - SUBGOAL_THEN `~(val (num_5blocks_adjusted:int64) * 0x50 + 0x40 = val (num_blocks_adjusted:int64))` ASSUME_TAC THENL - [ UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 + 0x20 = val (num_blocks_adjusted:int64)` THEN - ARITH_TAC; ALL_TAC] THEN - SUBGOAL_THEN `~(val (num_5blocks_adjusted:int64) * 0x50 + 0x30 = val (num_blocks_adjusted:int64))` ASSUME_TAC THENL - [ UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 + 0x20 = val (num_blocks_adjusted:int64)` THEN - ARITH_TAC; ALL_TAC] THEN - - SUBGOAL_THEN `val (num_5blocks_adjusted:int64) * 0x50 + 0x20 <= val (len:int64)` ASSUME_TAC THENL - [ UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 + 0x20 = val (num_blocks_adjusted:int64)` THEN - UNDISCH_TAC `val (num_blocks_adjusted:int64) <= val (len:int64)` THEN - ARITH_TAC; ALL_TAC] THEN - MP_TAC (SPECL [`ct_ptr:int64`; `num_5blocks_adjusted:int64`; `len:int64`; `ct:byte list`; `s7:armstate`] READ_CT_TAIL2_LEMMA) THEN - ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN - - (* Assumptions that help with reasoning about nonoverlapping - so that the universally quantified assumption stays. - See: https://hol-light.zulipchat.com/#narrow/channel/474190-s2n-bignum/topic/.E2.9C.94.20Symbolic.20simulation.20removed.20assumption/with/541554894 *) - SUBGOAL_THEN `0x50 * (val (num_5blocks_adjusted:int64)) < 0x2 EXP 0x40` ASSUME_TAC THENL - [ UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 <= val (num_blocks_adjusted:int64)` THEN - UNDISCH_TAC `val (num_blocks_adjusted:int64) <= 0x2 EXP 0x18` THEN - ARITH_TAC; ALL_TAC] THEN - SUBGOAL_THEN `val ((word (0x50 * val (num_5blocks_adjusted:int64))):int64) = 0x50 * val num_5blocks_adjusted` ASSUME_TAC THENL [ - IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN ASM_ARITH_TAC; ALL_TAC] THEN - POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th])) THEN - - ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (8--68) THEN - XTSDEC_TAC `Q0:(armstate,int128)component` - `val (num_5blocks_adjusted:int64) * 0x50` `val (num_5blocks_adjusted:int64) * 0x5` THEN - XTSDEC_TAC `Q1:(armstate,int128)component` - `val (num_5blocks_adjusted:int64) * 0x50 + 0x10` `val (num_5blocks_adjusted:int64) * 0x5 + 0x1` THEN - - (* The following lemmas are for NONSELFMODIFYING_STATE_UPDATE_TAC when store back to pt_ptr *) - RULE_ASSUM_TAC(REWRITE_RULE - [WORD_RULE `word_mul (word 0x50) num_5blocks_adjusted:int64 = word(0x50 * val num_5blocks_adjusted)`]) THEN - - ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (69--77) THEN - TWEAK_TAC `Q6:(armstate,int128)component` `val (num_5blocks_adjusted:int64) * 0x5 + 0x2` `val (num_5blocks_adjusted:int64) * 0x5 + 0x1` THEN - - ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (78--78) THEN - ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN - REPEAT CONJ_TAC THENL - [ - REWRITE_TAC[acc_len] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; - REWRITE_TAC[acc_len] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; - REWRITE_TAC[acc_blocks] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; - REWRITE_TAC[acc_blocks] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; - REWRITE_TAC[acc_blocks] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; - - REWRITE_TAC[acc_len] THEN ASM_SIMP_TAC[LE_REFL] THEN - SUBGOAL_THEN `val ((word (0x50 * val (num_5blocks_adjusted:int64) + 0x20)):int64) = 0x50 * val num_5blocks_adjusted + 0x20` ASSUME_TAC THENL - [ IMP_REWRITE_TAC[VAL_WORD; MOD_LT; DIMINDEX_64] THEN - UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 + 0x20 <= val (len:int64)` THEN - UNDISCH_TAC `val (len:int64) <= 0x2 EXP 0x18` THEN - ARITH_TAC; ALL_TAC] THEN - POP_ASSUM(fun th -> REWRITE_TAC[th]) THEN - - (* Remove quantifier *) - UNDISCH_TAC - `forall i. - i < 0x50 * val (num_5blocks_adjusted:int64) - ==> read (memory :> bytes8 (word_add pt_ptr (word i))) s78 = - EL i (aes256_xts_decrypt ct (0x50 * val num_5blocks_adjusted) iv key1 key2)` THEN - MP_TAC (SPECL [`0x50 * val (num_5blocks_adjusted:int64) + 0x20:num`; `pt_ptr:int64`; - `(aes256_xts_decrypt ct (0x50 * val (num_5blocks_adjusted:int64) + 0x20) iv key1 key2):byte list`; - `s78:armstate`] BYTE_LIST_TO_NUM_THM) THEN - ANTS_TAC THENL[ - REWRITE_TAC[ARITH_RULE `0x50 * i + 0x20 = 0x10 * (5 * i + 2)`; - LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS] THEN - ARITH_TAC - ; ALL_TAC] THEN - DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN - MP_TAC (SPECL [`0x50 * val (num_5blocks_adjusted:int64):num`; `pt_ptr:int64`; - `(aes256_xts_decrypt ct (0x50 * val (num_5blocks_adjusted:int64)) iv key1 key2):byte list`; - `s78:armstate`] BYTE_LIST_TO_NUM_THM) THEN - ANTS_TAC THENL[ - REWRITE_TAC[ARITH_RULE `0x50 * i = 0x10 * 5 * i`; - LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS] THEN - ARITH_TAC - ; ALL_TAC] THEN - DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN - DISCH_TAC THEN - - REWRITE_TAC[ARITH_RULE `0x50 * i + 0x20 = (0x50 * i + 0x10) + 0x10`] THEN - (* Use SPECL to force IMP_REWRITE_TAC to apply once once *) - IMP_REWRITE_TAC[(SPECL [`pt_ptr:int64`; `(0x50 * val (num_5blocks_adjusted:int64) + 0x10):num`; - `x:byte list`; `s78:armstate`] READ_BYTES_AND_BYTE128_SPLIT)] THEN + `x:byte list`; `s108:armstate`] READ_BYTES_AND_BYTE128_SPLIT)] THEN EXISTS_TAC `(aes256_xts_decrypt ct (0x50 * val (num_5blocks_adjusted:int64) + 0x20) iv key1 key2)` THEN REPEAT CONJ_TAC THENL [ MP_TAC (SPECL [`0x5 * val (num_5blocks_adjusted:int64) + 0x2:num`; @@ -5245,7 +6002,7 @@ let AES_XTS_DECRYPT_CORRECT = time prove( IMP_REWRITE_TAC[(SPECL [`pt_ptr:int64`; `(0x50 * val (num_5blocks_adjusted:int64)):num`; `(aes256_xts_decrypt ct (0x50 * val (num_5blocks_adjusted:int64) + 0x10) iv key1 key2):byte list`; - `s78:armstate`] + `s108:armstate`] READ_BYTES_AND_BYTE128_SPLIT)] THEN EXISTS_TAC `ct:byte list` THEN EXISTS_TAC `iv:int128` THEN EXISTS_TAC `key1:int128 list` THEN EXISTS_TAC `key2:int128 list` THEN @@ -5319,20 +6076,21 @@ let AES_XTS_DECRYPT_CORRECT = time prove( REWRITE_TAC[SUB_LIST_OF_AES256_XTS_DECRYPT_FULL_BLOCKS] THEN IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN REWRITE_TAC[LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS]] - ]; ALL_TAC] THEN + ] + ; ALL_TAC ] THEN DISCH_TAC THEN - ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (8--9) THEN + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (6--7) THEN FIRST_X_ASSUM MP_TAC THEN COND_CASES_TAC THENL - [ (* Case: len % 0x50 = 0x10 *) + [ (* Case: len % 0x50 = 0x20 *) DISCH_TAC THEN - SUBGOAL_THEN `val (num_5blocks_adjusted:int64) * 0x50 + 0x10 = val (num_blocks_adjusted:int64)` ASSUME_TAC THENL + SUBGOAL_THEN `val (num_5blocks_adjusted:int64) * 0x50 + 0x20 = val (num_blocks_adjusted:int64)` ASSUME_TAC THENL [ UNDISCH_TAC `val (word_sub (word_sub (num_blocks_adjusted:int64) (word_mul (word 0x50) (num_5blocks_adjusted:int64))) - (word 0x10)) = + (word 0x20)) = 0x0` THEN REWRITE_TAC [VAL_EQ_0; WORD_SUB_EQ_0] THEN REWRITE_TAC [WORD_RULE `!x:int64. word_mul (word 0x50) x = word(val x * 0x50)`] THEN @@ -5347,20 +6105,17 @@ let AES_XTS_DECRYPT_CORRECT = time prove( NUM_REDUCE_TAC THEN ARITH_TAC; ALL_TAC] THEN SUBGOAL_THEN `~(val (num_5blocks_adjusted:int64) * 0x50 + 0x40 = val (num_blocks_adjusted:int64))` ASSUME_TAC THENL - [ UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 + 0x10 = val (num_blocks_adjusted:int64)` THEN + [ UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 + 0x20 = val (num_blocks_adjusted:int64)` THEN ARITH_TAC; ALL_TAC] THEN SUBGOAL_THEN `~(val (num_5blocks_adjusted:int64) * 0x50 + 0x30 = val (num_blocks_adjusted:int64))` ASSUME_TAC THENL - [ UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 + 0x10 = val (num_blocks_adjusted:int64)` THEN - ARITH_TAC; ALL_TAC] THEN - SUBGOAL_THEN `~(val (num_5blocks_adjusted:int64) * 0x50 + 0x20 = val (num_blocks_adjusted:int64))` ASSUME_TAC THENL - [ UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 + 0x10 = val (num_blocks_adjusted:int64)` THEN + [ UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 + 0x20 = val (num_blocks_adjusted:int64)` THEN ARITH_TAC; ALL_TAC] THEN - SUBGOAL_THEN `val (num_5blocks_adjusted:int64) * 0x50 + 0x10 <= val (len:int64)` ASSUME_TAC THENL - [ UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 + 0x10 = val (num_blocks_adjusted:int64)` THEN + SUBGOAL_THEN `val (num_5blocks_adjusted:int64) * 0x50 + 0x20 <= val (len:int64)` ASSUME_TAC THENL + [ UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 + 0x20 = val (num_blocks_adjusted:int64)` THEN UNDISCH_TAC `val (num_blocks_adjusted:int64) <= val (len:int64)` THEN ARITH_TAC; ALL_TAC] THEN - MP_TAC (SPECL [`ct_ptr:int64`; `num_5blocks_adjusted:int64`; `len:int64`; `ct:byte list`; `s9:armstate`] READ_CT_TAIL1_LEMMA) THEN + MP_TAC (SPECL [`ct_ptr:int64`; `num_5blocks_adjusted:int64`; `len:int64`; `ct:byte list`; `s7:armstate`] READ_CT_TAIL2_LEMMA) THEN ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN (* Assumptions that help with reasoning about nonoverlapping @@ -5374,18 +6129,20 @@ let AES_XTS_DECRYPT_CORRECT = time prove( IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN ASM_ARITH_TAC; ALL_TAC] THEN POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th])) THEN - ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (10--40) THEN + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (8--68) THEN XTSDEC_TAC `Q0:(armstate,int128)component` `val (num_5blocks_adjusted:int64) * 0x50` `val (num_5blocks_adjusted:int64) * 0x5` THEN + XTSDEC_TAC `Q1:(armstate,int128)component` + `val (num_5blocks_adjusted:int64) * 0x50 + 0x10` `val (num_5blocks_adjusted:int64) * 0x5 + 0x1` THEN (* The following lemmas are for NONSELFMODIFYING_STATE_UPDATE_TAC when store back to pt_ptr *) RULE_ASSUM_TAC(REWRITE_RULE [WORD_RULE `word_mul (word 0x50) num_5blocks_adjusted:int64 = word(0x50 * val num_5blocks_adjusted)`]) THEN - ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (41--49) THEN - TWEAK_TAC `Q6:(armstate,int128)component` `val (num_5blocks_adjusted:int64) * 0x5 + 0x1` `val (num_5blocks_adjusted:int64) * 0x5` THEN + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (69--77) THEN + TWEAK_TAC `Q6:(armstate,int128)component` `val (num_5blocks_adjusted:int64) * 0x5 + 0x2` `val (num_5blocks_adjusted:int64) * 0x5 + 0x1` THEN - ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (50--50) THEN + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (78--78) THEN ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN REPEAT CONJ_TAC THENL [ @@ -5396,10 +6153,9 @@ let AES_XTS_DECRYPT_CORRECT = time prove( REWRITE_TAC[acc_blocks] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; REWRITE_TAC[acc_len] THEN ASM_SIMP_TAC[LE_REFL] THEN - SUBGOAL_THEN `val ((word (0x50 * val (num_5blocks_adjusted:int64) + 0x10)):int64) = - 0x50 * val num_5blocks_adjusted + 0x10` ASSUME_TAC THENL + SUBGOAL_THEN `val ((word (0x50 * val (num_5blocks_adjusted:int64) + 0x20)):int64) = 0x50 * val num_5blocks_adjusted + 0x20` ASSUME_TAC THENL [ IMP_REWRITE_TAC[VAL_WORD; MOD_LT; DIMINDEX_64] THEN - UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 + 0x10 <= val (len:int64)` THEN + UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 + 0x20 <= val (len:int64)` THEN UNDISCH_TAC `val (len:int64) <= 0x2 EXP 0x18` THEN ARITH_TAC; ALL_TAC] THEN POP_ASSUM(fun th -> REWRITE_TAC[th]) THEN @@ -5408,993 +6164,559 @@ let AES_XTS_DECRYPT_CORRECT = time prove( UNDISCH_TAC `forall i. i < 0x50 * val (num_5blocks_adjusted:int64) - ==> read (memory :> bytes8 (word_add pt_ptr (word i))) s50 = + ==> read (memory :> bytes8 (word_add pt_ptr (word i))) s78 = EL i (aes256_xts_decrypt ct (0x50 * val num_5blocks_adjusted) iv key1 key2)` THEN - MP_TAC (SPECL [`0x50 * val (num_5blocks_adjusted:int64) + 0x10:num`; `pt_ptr:int64`; - `(aes256_xts_decrypt ct (0x50 * val (num_5blocks_adjusted:int64) + 0x10) iv key1 key2):byte list`; - `s50:armstate`] BYTE_LIST_TO_NUM_THM) THEN + MP_TAC (SPECL [`0x50 * val (num_5blocks_adjusted:int64) + 0x20:num`; `pt_ptr:int64`; + `(aes256_xts_decrypt ct (0x50 * val (num_5blocks_adjusted:int64) + 0x20) iv key1 key2):byte list`; + `s78:armstate`] BYTE_LIST_TO_NUM_THM) THEN ANTS_TAC THENL[ - REWRITE_TAC[ARITH_RULE `0x50 * i + 0x10 = 0x10 * (5 * i + 1)`; + REWRITE_TAC[ARITH_RULE `0x50 * i + 0x20 = 0x10 * (5 * i + 2)`; LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS] THEN ARITH_TAC ; ALL_TAC] THEN DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN MP_TAC (SPECL [`0x50 * val (num_5blocks_adjusted:int64):num`; `pt_ptr:int64`; `(aes256_xts_decrypt ct (0x50 * val (num_5blocks_adjusted:int64)) iv key1 key2):byte list`; - `s50:armstate`] BYTE_LIST_TO_NUM_THM) THEN - ANTS_TAC THENL[ - REWRITE_TAC[ARITH_RULE `0x50 * i = 0x10 * 5 * i`; - LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS] THEN - ARITH_TAC - ; ALL_TAC] THEN - DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN - DISCH_TAC THEN - - IMP_REWRITE_TAC[(SPECL [`pt_ptr:int64`; `(0x50 * val (num_5blocks_adjusted:int64)):num`; - `(aes256_xts_decrypt ct (0x50 * val (num_5blocks_adjusted:int64) + 0x10) iv key1 key2):byte list`; - `s50:armstate`] - READ_BYTES_AND_BYTE128_SPLIT)] THEN - EXISTS_TAC `ct:byte list` THEN EXISTS_TAC `iv:int128` THEN - EXISTS_TAC `key1:int128 list` THEN EXISTS_TAC `key2:int128 list` THEN - REPEAT CONJ_TAC THENL [ - MP_TAC (SPECL [`0x5 * val (num_5blocks_adjusted:int64) + 0x1:num`; - `ct:byte list`; `iv:int128`; `key1:int128 list`; - `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN - REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC; GSYM ADD_ASSOC] THEN - CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC THEN - IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN ARITH_TAC; - - MP_TAC (SPECL [`0x5 * val (num_5blocks_adjusted:int64) + 0x1:num`; - `ct:byte list`; `iv:int128`; `key1:int128 list`; - `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN - REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC; GSYM ADD_ASSOC] THEN - CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC THEN - IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN ARITH_TAC; - - (* Establish that one xts decrypt round is the same as - selecting one block of bytes from calling the top-level function. *) - REWRITE_TAC[aes256_xts_decrypt] THEN - SIMP_TAC[ARITH_RULE `~(0x50 * i + 0x10 < 0x10)`] THEN - SUBGOAL_THEN `(0x50 * val (num_5blocks_adjusted:int64) + 0x10) MOD 0x10 = 0` SUBST1_TAC THENL - [ REWRITE_TAC[ARITH_RULE `80 * i + 16 = 16 * (5 * i + 1)`] THEN - REWRITE_TAC[MOD_MULT] - ; ALL_TAC] THEN - CONV_TAC (DEPTH_CONV let_CONV) THEN - REWRITE_TAC[SUB_0; ARITH_RULE `(0x50 * i + 0x10) DIV 0x10 = 0x5 * i + 0x1`] THEN - (* Two cases: i = 0 then execute tail branch, else execute recursion branch *) - COND_CASES_TAC THENL - [ SUBGOAL_THEN `val (num_5blocks_adjusted:int64) = 0` SUBST1_TAC THENL - [ UNDISCH_TAC `5 * val (num_5blocks_adjusted:int64) + 1 < 2` THEN - UNDISCH_TAC `0 < val (num_5blocks_adjusted:int64)` THEN - ARITH_TAC - ; ALL_TAC] THEN CONV_TAC NUM_REDUCE_CONV THEN - - MP_TAC (SPECL [`0x0:num`; `0x0:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] - LENGTH_OF_AES256_XTS_DECRYPT_TAIL) THEN - CONV_TAC NUM_REDUCE_CONV THEN REWRITE_TAC[ADD_0] THEN DISCH_TAC THEN - IMP_REWRITE_TAC[(ISPECL [`(aes256_xts_decrypt_tail 0x0 0x0 ct iv key1 key2):byte list`; - `0x10:num`] SUB_LIST_LENGTH_IMPLIES)] THEN - - REWRITE_TAC[AES256_XTS_DECRYPT_TAIL_WHEN_1BLOCK] THEN - CONV_TAC NUM_REDUCE_CONV; - - SIMP_TAC[ARITH_RULE `(0x5 * i + 0x1) - 0x2 = 0x5 * i - 0x1`; - ARITH_RULE `(0x5 * i + 0x1) - 0x1 = 0x5 * i`] THEN - - MP_TAC (SPECL [`0`;`5 * val (num_5blocks_adjusted:int64) - 1:num`; - `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] - LENGTH_OF_AES256_XTS_DECRYPT_REC) THEN - SUBGOAL_THEN `~(0x5 * val (num_5blocks_adjusted:int64) - 0x1 < 0x0)` ASSUME_TAC THENL - [ UNDISCH_TAC `~(0x5 * val (num_5blocks_adjusted:int64) + 0x1 < 0x2)` THEN ARITH_TAC; ALL_TAC ] THEN - ASM_SIMP_TAC[] THEN - IMP_REWRITE_TAC[ARITH_RULE `~(0x5 * i + 0x1 < 0x2) ==> (0x5 * i - 1 - 0x0 + 0x1) * 0x10 = 0x50 * i`] THEN - IMP_REWRITE_TAC[SUB_LIST_APPEND_RIGHT_LEMMA] THEN DISCH_TAC THEN - - MP_TAC (SPECL [`5 * val (num_5blocks_adjusted:int64):num`; - `0x0:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] - LENGTH_OF_AES256_XTS_DECRYPT_TAIL) THEN - CONV_TAC NUM_REDUCE_CONV THEN REWRITE_TAC[ADD_0] THEN DISCH_TAC THEN - IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN - - REWRITE_TAC[AES256_XTS_DECRYPT_TAIL_WHEN_1BLOCK] THEN - SIMP_TAC[ARITH_RULE `i * 0x50 = (i * 0x5) * 0x10`; - ARITH_RULE `i * 0x5 = 0x5 * i`]]; - - (* Proving that reading previous bytes is the same as the spec *) - REWRITE_TAC[ARITH_RULE `0x50 * i = 0x10 * 5 * i`; - ARITH_RULE `0x50 * i + 0x10 = 0x10 * 5 * i + 0x10`] THEN - REWRITE_TAC[SUB_LIST_OF_AES256_XTS_DECRYPT_FULL_BLOCKS] THEN - IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN - REWRITE_TAC[LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS]] - ] - ; ALL_TAC] THEN - - (* Case: len % 0x50 = 0 *) - DISCH_TAC THEN - SUBGOAL_THEN `val (num_5blocks_adjusted:int64) * 0x50 = val (num_blocks_adjusted:int64)` ASSUME_TAC THENL - [ MATCH_MP_TAC (SPECL [`val (num_blocks_adjusted:int64)`; `val (num_5blocks_adjusted:int64)`] DIVISION_BY_80_LEMMA) THEN - REPEAT CONJ_TAC THENL - [ - EXPAND_TAC "num_5blocks_adjusted" THEN - IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN - UNDISCH_TAC `val (num_blocks_adjusted:int64) <= 0x2 EXP 0x18` THEN - ARITH_TAC; - - EXPAND_TAC "num_blocks_adjusted" THEN - EXPAND_TAC "num_blocks" THEN - COND_CASES_TAC THENL - [ - REWRITE_TAC[NUM_BLOCKS_TO_VAL] THEN - IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT; DIVIDES_RMUL; DIVIDES_REFL] THEN - UNDISCH_TAC `val (len:int64) <= 0x2 EXP 0x18` THEN - ARITH_TAC; - - IMP_REWRITE_TAC[NUM_BLOCKS_MINUS1_TO_VAL] THEN - IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT; DIVIDES_RMUL; DIVIDES_REFL] THEN - UNDISCH_TAC `val (len:int64) <= 0x2 EXP 0x18` THEN - ARITH_TAC]; - - UNDISCH_TAC `~(val (word_sub - (word_sub (num_blocks_adjusted:int64) - (word_mul (word 0x50) (num_5blocks_adjusted:int64))) - (word 0x10)) = 0x0)` THEN - REWRITE_TAC[CONTRAPOS_THM] THEN - REWRITE_TAC[VAL_WORD_SUB_EQ_0; VAL_WORD_MUL; VAL_WORD; DIMINDEX_64; - ARITH_RULE `0x10 MOD 0x2 EXP 0x40 = 0x10`] THEN - REWRITE_TAC[VAL_WORD_SUB; VAL_WORD_MUL; VAL_WORD; DIMINDEX_64; - ARITH_RULE `0x50 MOD 0x2 EXP 0x40 = 0x50`] THEN - - SUBGOAL_THEN `0x50 * val (num_5blocks_adjusted:int64) < 2 EXP 64` ASSUME_TAC THENL - [ UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 <= val (len:int64)` THEN - UNDISCH_TAC `val (len:int64) <= 0x2 EXP 0x18` THEN - ARITH_TAC; ALL_TAC] THEN - MP_TAC (SPECL [`0x50 * val (num_5blocks_adjusted:int64)`; `2 EXP 64`] MOD_LT) THEN - ANTS_TAC THENL [ASM_SIMP_TAC[]; ALL_TAC] THEN - SIMP_TAC[] THEN DISCH_TAC THEN - - MP_TAC (SPECL [`val (num_blocks_adjusted:int64)`; `0x2 EXP 0x40`; - `0x50 * val (num_5blocks_adjusted:int64)`] - (ARITH_RULE `!a b c. c <= a ==> c <= b ==> a + b - c = (a - c) + b`)) THEN - ANTS_TAC THENL [ - UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 <= val (num_blocks_adjusted:int64)` THEN - SIMP_TAC[MULT_SYM]; ALL_TAC] THEN - ANTS_TAC THENL [ - UNDISCH_TAC `0x50 * val (num_5blocks_adjusted:int64) < 2 EXP 64` THEN - ARITH_TAC; ALL_TAC] THEN - ASM_SIMP_TAC[] THEN DISCH_TAC THEN - - MP_TAC (SPECL [`1`; `0x2 EXP 0x40`; - `val (num_blocks_adjusted:int64) - 0x50 * val (num_5blocks_adjusted:int64)`] - (CONJUNCT1 (CONJUNCT2 (CONJUNCT2 MOD_MULT_ADD)))) THEN - REWRITE_TAC[ARITH_RULE `1 * 2 EXP 64 = 2 EXP 64`] THEN - SIMP_TAC[] THEN DISCH_TAC THEN - SIMP_TAC[MULT_SYM] THEN DISCH_TAC THEN - CONV_TAC NUM_REDUCE_CONV; - - UNDISCH_TAC `~(val (word_sub - (word_sub (num_blocks_adjusted:int64) - (word_mul (word 0x50) (num_5blocks_adjusted:int64))) - (word 0x20)) = 0x0)` THEN - REWRITE_TAC[CONTRAPOS_THM] THEN - REWRITE_TAC[VAL_WORD_SUB_EQ_0; VAL_WORD_MUL; VAL_WORD; DIMINDEX_64; - ARITH_RULE `0x20 MOD 0x2 EXP 0x40 = 0x20`] THEN - REWRITE_TAC[VAL_WORD_SUB; VAL_WORD_MUL; VAL_WORD; DIMINDEX_64; - ARITH_RULE `0x50 MOD 0x2 EXP 0x40 = 0x50`] THEN - - SUBGOAL_THEN `0x50 * val (num_5blocks_adjusted:int64) < 2 EXP 64` ASSUME_TAC THENL - [ UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 <= val (len:int64)` THEN - UNDISCH_TAC `val (len:int64) <= 0x2 EXP 0x18` THEN - ARITH_TAC; ALL_TAC] THEN - MP_TAC (SPECL [`0x50 * val (num_5blocks_adjusted:int64)`; `2 EXP 64`] MOD_LT) THEN - ANTS_TAC THENL [ASM_SIMP_TAC[]; ALL_TAC] THEN - SIMP_TAC[] THEN DISCH_TAC THEN - - MP_TAC (SPECL [`val (num_blocks_adjusted:int64)`; `0x2 EXP 0x40`; - `0x50 * val (num_5blocks_adjusted:int64)`] - (ARITH_RULE `!a b c. c <= a ==> c <= b ==> a + b - c = (a - c) + b`)) THEN - ANTS_TAC THENL [ - UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 <= val (num_blocks_adjusted:int64)` THEN - SIMP_TAC[MULT_SYM]; ALL_TAC] THEN - ANTS_TAC THENL [ - UNDISCH_TAC `0x50 * val (num_5blocks_adjusted:int64) < 2 EXP 64` THEN - ARITH_TAC; ALL_TAC] THEN - ASM_SIMP_TAC[] THEN DISCH_TAC THEN - - MP_TAC (SPECL [`1`; `0x2 EXP 0x40`; - `val (num_blocks_adjusted:int64) - 0x50 * val (num_5blocks_adjusted:int64)`] - (CONJUNCT1 (CONJUNCT2 (CONJUNCT2 MOD_MULT_ADD)))) THEN - REWRITE_TAC[ARITH_RULE `1 * 2 EXP 64 = 2 EXP 64`] THEN - SIMP_TAC[] THEN DISCH_TAC THEN - SIMP_TAC[MULT_SYM] THEN DISCH_TAC THEN - CONV_TAC NUM_REDUCE_CONV; - - UNDISCH_TAC `~(val (word_sub - (word_sub (num_blocks_adjusted:int64) - (word_mul (word 0x50) (num_5blocks_adjusted:int64))) - (word 0x30)) = 0x0)` THEN - REWRITE_TAC[CONTRAPOS_THM] THEN - REWRITE_TAC[VAL_WORD_SUB_EQ_0; VAL_WORD_MUL; VAL_WORD; DIMINDEX_64; - ARITH_RULE `0x30 MOD 0x2 EXP 0x40 = 0x30`] THEN - REWRITE_TAC[VAL_WORD_SUB; VAL_WORD_MUL; VAL_WORD; DIMINDEX_64; - ARITH_RULE `0x50 MOD 0x2 EXP 0x40 = 0x50`] THEN - - SUBGOAL_THEN `0x50 * val (num_5blocks_adjusted:int64) < 2 EXP 64` ASSUME_TAC THENL - [ UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 <= val (len:int64)` THEN - UNDISCH_TAC `val (len:int64) <= 0x2 EXP 0x18` THEN - ARITH_TAC; ALL_TAC] THEN - MP_TAC (SPECL [`0x50 * val (num_5blocks_adjusted:int64)`; `2 EXP 64`] MOD_LT) THEN - ANTS_TAC THENL [ASM_SIMP_TAC[]; ALL_TAC] THEN - SIMP_TAC[] THEN DISCH_TAC THEN + `s78:armstate`] BYTE_LIST_TO_NUM_THM) THEN + ANTS_TAC THENL[ + REWRITE_TAC[ARITH_RULE `0x50 * i = 0x10 * 5 * i`; + LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS] THEN + ARITH_TAC + ; ALL_TAC] THEN + DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN + DISCH_TAC THEN - MP_TAC (SPECL [`val (num_blocks_adjusted:int64)`; `0x2 EXP 0x40`; - `0x50 * val (num_5blocks_adjusted:int64)`] - (ARITH_RULE `!a b c. c <= a ==> c <= b ==> a + b - c = (a - c) + b`)) THEN - ANTS_TAC THENL [ - UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 <= val (num_blocks_adjusted:int64)` THEN - SIMP_TAC[MULT_SYM]; ALL_TAC] THEN - ANTS_TAC THENL [ - UNDISCH_TAC `0x50 * val (num_5blocks_adjusted:int64) < 2 EXP 64` THEN - ARITH_TAC; ALL_TAC] THEN - ASM_SIMP_TAC[] THEN DISCH_TAC THEN + REWRITE_TAC[ARITH_RULE `0x50 * i + 0x20 = (0x50 * i + 0x10) + 0x10`] THEN + (* Use SPECL to force IMP_REWRITE_TAC to apply once once *) + IMP_REWRITE_TAC[(SPECL [`pt_ptr:int64`; `(0x50 * val (num_5blocks_adjusted:int64) + 0x10):num`; + `x:byte list`; `s78:armstate`] READ_BYTES_AND_BYTE128_SPLIT)] THEN + EXISTS_TAC `(aes256_xts_decrypt ct (0x50 * val (num_5blocks_adjusted:int64) + 0x20) iv key1 key2)` THEN + REPEAT CONJ_TAC THENL [ + MP_TAC (SPECL [`0x5 * val (num_5blocks_adjusted:int64) + 0x2:num`; + `ct:byte list`; `iv:int128`; `key1:int128 list`; + `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN + REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC; GSYM ADD_ASSOC] THEN + CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN ARITH_TAC; - MP_TAC (SPECL [`1`; `0x2 EXP 0x40`; - `val (num_blocks_adjusted:int64) - 0x50 * val (num_5blocks_adjusted:int64)`] - (CONJUNCT1 (CONJUNCT2 (CONJUNCT2 MOD_MULT_ADD)))) THEN - REWRITE_TAC[ARITH_RULE `1 * 2 EXP 64 = 2 EXP 64`] THEN - SIMP_TAC[] THEN DISCH_TAC THEN - SIMP_TAC[MULT_SYM] THEN DISCH_TAC THEN - CONV_TAC NUM_REDUCE_CONV; + MP_TAC (SPECL [`0x5 * val (num_5blocks_adjusted:int64) + 0x2:num`; + `ct:byte list`; `iv:int128`; `key1:int128 list`; + `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN + REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC; GSYM ADD_ASSOC] THEN + CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN ARITH_TAC; - UNDISCH_TAC `~(val (word_sub - (word_sub (num_blocks_adjusted:int64) - (word_mul (word 0x50) (num_5blocks_adjusted:int64))) - (word 0x40)) = 0x0)` THEN - REWRITE_TAC[CONTRAPOS_THM] THEN - REWRITE_TAC[VAL_WORD_SUB_EQ_0; VAL_WORD_MUL; VAL_WORD; DIMINDEX_64; - ARITH_RULE `0x40 MOD 0x2 EXP 0x40 = 0x40`] THEN - REWRITE_TAC[VAL_WORD_SUB; VAL_WORD_MUL; VAL_WORD; DIMINDEX_64; - ARITH_RULE `0x50 MOD 0x2 EXP 0x40 = 0x50`] THEN + (* Establish that one xts decrypt round is the same as + selecting one block of bytes from calling the top-level function. *) + REWRITE_TAC[aes256_xts_decrypt] THEN + SIMP_TAC[ARITH_RULE `~(0x50 * i + 0x20 < 0x10)`] THEN + SUBGOAL_THEN `(0x50 * val (num_5blocks_adjusted:int64) + 0x20) MOD 0x10 = 0` SUBST1_TAC THENL + [ REWRITE_TAC[ARITH_RULE `80 * i + 32 = 16 * (5 * i + 2)`] THEN + REWRITE_TAC[MOD_MULT] + ; ALL_TAC] THEN + CONV_TAC (DEPTH_CONV let_CONV) THEN + REWRITE_TAC[SUB_0; ARITH_RULE `(0x50 * i + 0x20) DIV 0x10 = 0x5 * i + 0x2`] THEN + SIMP_TAC[ARITH_RULE `~(0x5 * i + 0x2 < 0x2)`; + ARITH_RULE `(0x5 * i + 0x2) - 0x2 = 0x5 * i`; + ARITH_RULE `(0x5 * i + 0x2) - 0x1 = 0x5 * i + 0x1`] THEN - SUBGOAL_THEN `0x50 * val (num_5blocks_adjusted:int64) < 2 EXP 64` ASSUME_TAC THENL - [ UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 <= val (len:int64)` THEN - UNDISCH_TAC `val (len:int64) <= 0x2 EXP 0x18` THEN - ARITH_TAC; ALL_TAC] THEN - MP_TAC (SPECL [`0x50 * val (num_5blocks_adjusted:int64)`; `2 EXP 64`] MOD_LT) THEN - ANTS_TAC THENL [ASM_SIMP_TAC[]; ALL_TAC] THEN - SIMP_TAC[] THEN DISCH_TAC THEN + MP_TAC (SPECL [`0`;`5 * val (num_5blocks_adjusted:int64):num`; + `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + LENGTH_OF_AES256_XTS_DECRYPT_REC) THEN + SIMP_TAC[ARITH_RULE `~(5 * i < 0)`; + ARITH_RULE `(0x5 * i - 0x0 + 0x1) * 0x10 = 0x50 * i + 0x10`] THEN + IMP_REWRITE_TAC[SUB_LIST_APPEND_RIGHT_LEMMA] THEN DISCH_TAC THEN - MP_TAC (SPECL [`val (num_blocks_adjusted:int64)`; `0x2 EXP 0x40`; - `0x50 * val (num_5blocks_adjusted:int64)`] - (ARITH_RULE `!a b c. c <= a ==> c <= b ==> a + b - c = (a - c) + b`)) THEN - ANTS_TAC THENL [ - UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 <= val (num_blocks_adjusted:int64)` THEN - SIMP_TAC[MULT_SYM]; ALL_TAC] THEN - ANTS_TAC THENL [ - UNDISCH_TAC `0x50 * val (num_5blocks_adjusted:int64) < 2 EXP 64` THEN - ARITH_TAC; ALL_TAC] THEN - ASM_SIMP_TAC[] THEN DISCH_TAC THEN + MP_TAC (SPECL [`5 * val (num_5blocks_adjusted:int64) + 1:num`; `0x0:num`; + `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + LENGTH_OF_AES256_XTS_DECRYPT_TAIL) THEN + CONV_TAC NUM_REDUCE_CONV THEN REWRITE_TAC[ADD_0] THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN - MP_TAC (SPECL [`1`; `0x2 EXP 0x40`; - `val (num_blocks_adjusted:int64) - 0x50 * val (num_5blocks_adjusted:int64)`] - (CONJUNCT1 (CONJUNCT2 (CONJUNCT2 MOD_MULT_ADD)))) THEN - REWRITE_TAC[ARITH_RULE `1 * 2 EXP 64 = 2 EXP 64`] THEN - SIMP_TAC[] THEN DISCH_TAC THEN - SIMP_TAC[MULT_SYM] THEN DISCH_TAC THEN - CONV_TAC NUM_REDUCE_CONV - ] - ; ALL_TAC] THEN + REWRITE_TAC[AES256_XTS_DECRYPT_TAIL_WHEN_1BLOCK] THEN + SIMP_TAC[ARITH_RULE `i * 0x50 + 0x10 = (i * 0x5 + 0x1) * 0x10`; + ARITH_RULE `i * 0x5 = 0x5 * i`]; - SUBGOAL_THEN `~(val (num_5blocks_adjusted:int64) * 0x50 + 0x40 = val (num_blocks_adjusted:int64))` ASSUME_TAC THENL - [ UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 = val (num_blocks_adjusted:int64)` THEN - ARITH_TAC; ALL_TAC] THEN - SUBGOAL_THEN `~(val (num_5blocks_adjusted:int64) * 0x50 + 0x30 = val (num_blocks_adjusted:int64))` ASSUME_TAC THENL - [ UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 = val (num_blocks_adjusted:int64)` THEN - ARITH_TAC; ALL_TAC] THEN - SUBGOAL_THEN `~(val (num_5blocks_adjusted:int64) * 0x50 + 0x20 = val (num_blocks_adjusted:int64))` ASSUME_TAC THENL - [ UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 = val (num_blocks_adjusted:int64)` THEN - ARITH_TAC; ALL_TAC] THEN - SUBGOAL_THEN `~(val (num_5blocks_adjusted:int64) * 0x50 + 0x10 = val (num_blocks_adjusted:int64))` ASSUME_TAC THENL - [ UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 = val (num_blocks_adjusted:int64)` THEN - ARITH_TAC; ALL_TAC] THEN + (* Proving that reading previous bytes is the same as the spec *) + REWRITE_TAC[ARITH_RULE `0x50 * i + 0x10 = 0x10 * (5 * i + 1)`; + ARITH_RULE `0x50 * i + 0x20 = 0x10 * (5 * i + 1) + 0x10`] THEN + REWRITE_TAC[SUB_LIST_OF_AES256_XTS_DECRYPT_FULL_BLOCKS] THEN + ASM_REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC] THEN CONV_TAC NUM_REDUCE_CONV + ] THEN - ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (10--10) THEN - ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN - REPEAT CONJ_TAC THENL - [ - REWRITE_TAC[acc_len] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; - REWRITE_TAC[acc_len] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; - REWRITE_TAC[acc_blocks] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; - REWRITE_TAC[acc_blocks] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; - REWRITE_TAC[acc_blocks] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; - REWRITE_TAC[acc_len] THEN ASM_SIMP_TAC[LE_REFL] - ] - ] (* End of loop invariant proof *) - ; ALL_TAC] THEN + IMP_REWRITE_TAC[(SPECL [`pt_ptr:int64`; `(0x50 * val (num_5blocks_adjusted:int64)):num`; + `(aes256_xts_decrypt ct (0x50 * val (num_5blocks_adjusted:int64) + 0x10) iv key1 key2):byte list`; + `s78:armstate`] + READ_BYTES_AND_BYTE128_SPLIT)] THEN + EXISTS_TAC `ct:byte list` THEN EXISTS_TAC `iv:int128` THEN + EXISTS_TAC `key1:int128 list` THEN EXISTS_TAC `key2:int128 list` THEN + REPEAT CONJ_TAC THENL [ + MP_TAC (SPECL [`0x5 * val (num_5blocks_adjusted:int64) + 0x1:num`; + `ct:byte list`; `iv:int128`; `key1:int128 list`; + `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN + REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC; GSYM ADD_ASSOC] THEN + CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN ARITH_TAC; - (* Prove more properties about num_blocks_adjusted and num_5blocks_adjusted *) - SUBGOAL_THEN `val (num_blocks_adjusted:int64) DIV 0x50 = val (num_5blocks_adjusted:int64)` ASSUME_TAC THENL - [ EXPAND_TAC "num_5blocks_adjusted" THEN - IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN - UNDISCH_TAC `val (num_blocks_adjusted:int64) <= 0x2 EXP 0x18` THEN - ARITH_TAC; ALL_TAC] THEN - SUBGOAL_THEN `0x10 divides val (num_blocks_adjusted:int64)` ASSUME_TAC THENL - [ EXPAND_TAC "num_blocks_adjusted" THEN - EXPAND_TAC "num_blocks" THEN - COND_CASES_TAC THENL - [ REWRITE_TAC[NUM_BLOCKS_TO_VAL] THEN - IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT; DIVIDES_RMUL; DIVIDES_REFL] THEN - UNDISCH_TAC `val (len:int64) <= 0x2 EXP 0x18` THEN - ARITH_TAC; + MP_TAC (SPECL [`0x5 * val (num_5blocks_adjusted:int64) + 0x1:num`; + `ct:byte list`; `iv:int128`; `key1:int128 list`; + `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN + REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC; GSYM ADD_ASSOC] THEN + CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN ARITH_TAC; - IMP_REWRITE_TAC[NUM_BLOCKS_MINUS1_TO_VAL] THEN - IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT; DIVIDES_RMUL; DIVIDES_REFL] THEN - UNDISCH_TAC `val (len:int64) <= 0x2 EXP 0x18` THEN - ARITH_TAC]; ALL_TAC] THEN + (* Establish that one xts decrypt round is the same as + selecting one block of bytes from calling the top-level function. *) + REWRITE_TAC[aes256_xts_decrypt] THEN + SIMP_TAC[ARITH_RULE `~(0x50 * i + 0x10 < 0x10)`] THEN + SUBGOAL_THEN `(0x50 * val (num_5blocks_adjusted:int64) + 0x10) MOD 0x10 = 0` SUBST1_TAC THENL + [ REWRITE_TAC[ARITH_RULE `80 * i + 16 = 16 * (5 * i + 1)`] THEN + REWRITE_TAC[MOD_MULT] + ; ALL_TAC] THEN + CONV_TAC (DEPTH_CONV let_CONV) THEN + REWRITE_TAC[SUB_0; ARITH_RULE `(0x50 * i + 0x10) DIV 0x10 = 0x5 * i + 0x1`] THEN + (* Two cases: i = 0 then execute tail branch, else execute recursion branch *) + COND_CASES_TAC THENL + [ SUBGOAL_THEN `val (num_5blocks_adjusted:int64) = 0` SUBST1_TAC THENL + [ UNDISCH_TAC `5 * val (num_5blocks_adjusted:int64) + 1 < 2` THEN + UNDISCH_TAC `0 < val (num_5blocks_adjusted:int64)` THEN + ARITH_TAC + ; ALL_TAC] THEN CONV_TAC NUM_REDUCE_CONV THEN - (* If no tail, execute to the end *) - ASM_CASES_TAC `val (tail_len:int64) = 0` THENL - [ - REWRITE_TAC[byte_list_at] THEN - ENSURES_INIT_TAC "s0" THEN - ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (1--2) THEN - (* Discharge if condition *) - SUBGOAL_THEN `val (word_and (tail_len:int64) (word 0xf)) = 0x0` MP_TAC THENL - [ UNDISCH_TAC `val (tail_len:int64) = 0x0` THEN BITBLAST_TAC; ALL_TAC] THEN - ASM_REWRITE_TAC[] THEN DISCH_TAC THEN - POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th])) THEN + MP_TAC (SPECL [`0x0:num`; `0x0:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + LENGTH_OF_AES256_XTS_DECRYPT_TAIL) THEN + CONV_TAC NUM_REDUCE_CONV THEN REWRITE_TAC[ADD_0] THEN DISCH_TAC THEN + IMP_REWRITE_TAC[(ISPECL [`(aes256_xts_decrypt_tail 0x0 0x0 ct iv key1 key2):byte list`; + `0x10:num`] SUB_LIST_LENGTH_IMPLIES)] THEN - ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[AES256_XTS_DECRYPT_TAIL_WHEN_1BLOCK] THEN + CONV_TAC NUM_REDUCE_CONV; - SUBGOAL_THEN `val (word (acc_len (num_5blocks_adjusted:int64) (num_blocks_adjusted:int64)):int64) = - acc_len num_5blocks_adjusted num_blocks_adjusted` ASSUME_TAC THENL - [ IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN - MP_TAC (SPECL [`num_5blocks_adjusted:int64`; `num_blocks_adjusted:int64`; `2 EXP 64`] - BOUND_OF_ACC_LEN) THEN - ANTS_TAC THENL [ ASM_ARITH_TAC; ALL_TAC] THEN - ANTS_TAC THENL [ ASM_SIMP_TAC[]; ALL_TAC] THEN - ANTS_TAC THENL [ ASM_SIMP_TAC[]; ALL_TAC] THEN - ANTS_TAC THENL [ ASM_ARITH_TAC; ALL_TAC] THEN - SIMP_TAC[]; ALL_TAC] THEN - POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th])) THEN - (* Prove that acc_len is equal to total len because there is no tail *) - SUBGOAL_THEN `val (len:int64) = - acc_len (num_5blocks_adjusted:int64) (num_blocks_adjusted:int64)` SUBST1_TAC THENL - [ SUBGOAL_THEN `len = (num_blocks:int64)` SUBST1_TAC THENL - [ EXPAND_TAC "len" THEN - SUBGOAL_THEN `tail_len:int64 = word 0` ASSUME_TAC THENL - [ REWRITE_TAC[GSYM VAL_EQ_0] THEN ASM_REWRITE_TAC[]; ALL_TAC] THEN - REWRITE_TAC[ASSUME `tail_len:int64 = word 0`; WORD_ADD_0] - ; ALL_TAC] THEN - SUBGOAL_THEN `num_blocks = (num_blocks_adjusted:int64)` SUBST1_TAC THENL - [ EXPAND_TAC "num_blocks_adjusted" THEN - REWRITE_TAC[ASSUME `val (tail_len:int64) = 0`] - ; ALL_TAC] THEN - REWRITE_TAC[acc_len] THEN - REPEAT_N 4 (COND_CASES_TAC THENL[ASM_ARITH_TAC; ALL_TAC]) THEN + SIMP_TAC[ARITH_RULE `(0x5 * i + 0x1) - 0x2 = 0x5 * i - 0x1`; + ARITH_RULE `(0x5 * i + 0x1) - 0x1 = 0x5 * i`] THEN - CONV_TAC SYM_CONV THEN - REWRITE_TAC[ARITH_RULE `!a. 0x50 * a = a * 0x50`] THEN - MATCH_MP_TAC (SPECL [`val (num_blocks_adjusted:int64)`; `val (num_5blocks_adjusted:int64)`] DIVISION_BY_80_LEMMA) THEN - REPEAT CONJ_TAC THENL - [ - ASM_SIMP_TAC[]; - ASM_SIMP_TAC[]; + MP_TAC (SPECL [`0`;`5 * val (num_5blocks_adjusted:int64) - 1:num`; + `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + LENGTH_OF_AES256_XTS_DECRYPT_REC) THEN + SUBGOAL_THEN `~(0x5 * val (num_5blocks_adjusted:int64) - 0x1 < 0x0)` ASSUME_TAC THENL + [ UNDISCH_TAC `~(0x5 * val (num_5blocks_adjusted:int64) + 0x1 < 0x2)` THEN ARITH_TAC; ALL_TAC ] THEN + ASM_SIMP_TAC[] THEN + IMP_REWRITE_TAC[ARITH_RULE `~(0x5 * i + 0x1 < 0x2) ==> (0x5 * i - 1 - 0x0 + 0x1) * 0x10 = 0x50 * i`] THEN + IMP_REWRITE_TAC[SUB_LIST_APPEND_RIGHT_LEMMA] THEN DISCH_TAC THEN - UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 <= val (num_blocks_adjusted:int64)` THEN - UNDISCH_TAC `~(val (num_5blocks_adjusted:int64) * 0x50 + 0x10 = val (num_blocks_adjusted:int64))` THEN - ARITH_TAC; + MP_TAC (SPECL [`5 * val (num_5blocks_adjusted:int64):num`; + `0x0:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + LENGTH_OF_AES256_XTS_DECRYPT_TAIL) THEN + CONV_TAC NUM_REDUCE_CONV THEN REWRITE_TAC[ADD_0] THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN - UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 <= val (num_blocks_adjusted:int64)` THEN - UNDISCH_TAC `~(val (num_5blocks_adjusted:int64) * 0x50 + 0x20 = val (num_blocks_adjusted:int64))` THEN - ARITH_TAC; + REWRITE_TAC[AES256_XTS_DECRYPT_TAIL_WHEN_1BLOCK] THEN + SIMP_TAC[ARITH_RULE `i * 0x50 = (i * 0x5) * 0x10`; + ARITH_RULE `i * 0x5 = 0x5 * i`]]; - UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 <= val (num_blocks_adjusted:int64)` THEN - UNDISCH_TAC `~(val (num_5blocks_adjusted:int64) * 0x50 + 0x30 = val (num_blocks_adjusted:int64))` THEN - ARITH_TAC; + (* Proving that reading previous bytes is the same as the spec *) + REWRITE_TAC[ARITH_RULE `0x50 * i = 0x10 * 5 * i`; + ARITH_RULE `0x50 * i + 0x10 = 0x10 * 5 * i + 0x10`] THEN + REWRITE_TAC[SUB_LIST_OF_AES256_XTS_DECRYPT_FULL_BLOCKS] THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN + REWRITE_TAC[LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS]] + ]; ALL_TAC] THEN - UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 <= val (num_blocks_adjusted:int64)` THEN - UNDISCH_TAC `~(val (num_5blocks_adjusted:int64) * 0x50 + 0x40 = val (num_blocks_adjusted:int64))` THEN - ARITH_TAC] - ; ALL_TAC] THEN - ASM_SIMP_TAC[] - ; ALL_TAC] THEN + DISCH_TAC THEN + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (8--9) THEN + FIRST_X_ASSUM MP_TAC THEN + COND_CASES_TAC THENL + [ (* Case: len % 0x50 = 0x10 *) + DISCH_TAC THEN - (* The cipher stealing branch *) - (* Break the rest of the program into two parts: before byte-swap and after. - This is because byte-swap needs another invariant proof. *) - ABBREV_TAC `curr_len = (acc_len (num_5blocks_adjusted:int64) (num_blocks_adjusted:int64)):num` THEN - ABBREV_TAC `curr_blocks = (acc_blocks (num_5blocks_adjusted:int64) (num_blocks_adjusted:int64) T):num` THEN + SUBGOAL_THEN `val (num_5blocks_adjusted:int64) * 0x50 + 0x10 = val (num_blocks_adjusted:int64)` ASSUME_TAC THENL + [ UNDISCH_TAC `val (word_sub + (word_sub (num_blocks_adjusted:int64) + (word_mul (word 0x50) (num_5blocks_adjusted:int64))) + (word 0x10)) = + 0x0` THEN + REWRITE_TAC [VAL_EQ_0; WORD_SUB_EQ_0] THEN + REWRITE_TAC [WORD_RULE `!x:int64. word_mul (word 0x50) x = word(val x * 0x50)`] THEN + REWRITE_TAC[GSYM VAL_EQ] THEN + SUBGOAL_THEN `val (num_5blocks_adjusted:int64) * 0x50 < 2 EXP 64` MP_TAC THENL + [ UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 <= val (num_blocks_adjusted:int64)` THEN + UNDISCH_TAC `val (num_blocks_adjusted:int64) <= 2 EXP 24` THEN + ARITH_TAC; ALL_TAC] THEN + REWRITE_TAC[VAL_WORD_SUB_CASES] THEN + SIMP_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN + UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 <= val (num_blocks_adjusted:int64)` THEN + NUM_REDUCE_TAC THEN ARITH_TAC; ALL_TAC] THEN - SUBGOAL_THEN `curr_len + 0x10 <= val (len:int64)` ASSUME_TAC THENL - [ EXPAND_TAC "curr_len" THEN - MP_TAC (SPECL [`num_5blocks_adjusted:int64`; `num_blocks_adjusted:int64`] VALUE_OF_ACC_LEN) THEN - REPEAT_N 3 (ANTS_TAC THENL [ASM_ARITH_TAC ORELSE ASM_SIMP_TAC[]; ALL_TAC]) THEN - SIMP_TAC[] THEN DISCH_TAC THEN - EXPAND_TAC "num_blocks_adjusted" THEN - SIMP_TAC[ASSUME `~(val (tail_len:int64) = 0)`] THEN - UNDISCH_TAC `val (num_blocks:int64) <= val (len:int64)` THEN - UNDISCH_TAC `~(val (num_blocks:int64) < 0x60)` THEN - WORD_ARITH_TAC; ALL_TAC] THEN - SUBGOAL_THEN `val ((word curr_len):int64) = curr_len` ASSUME_TAC THENL - [ IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN - EXPAND_TAC "curr_len" THEN - MP_TAC (SPECL [`num_5blocks_adjusted:int64`; `num_blocks_adjusted:int64`; `2 EXP 64`] - BOUND_OF_ACC_LEN) THEN - ANTS_TAC THENL [ ASM_ARITH_TAC; ALL_TAC] THEN - ANTS_TAC THENL [ ASM_SIMP_TAC[]; ALL_TAC] THEN - ANTS_TAC THENL [ ASM_SIMP_TAC[]; ALL_TAC] THEN - ANTS_TAC THENL [ ASM_ARITH_TAC; ALL_TAC] THEN - SIMP_TAC[]; ALL_TAC] THEN + SUBGOAL_THEN `~(val (num_5blocks_adjusted:int64) * 0x50 + 0x40 = val (num_blocks_adjusted:int64))` ASSUME_TAC THENL + [ UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 + 0x10 = val (num_blocks_adjusted:int64)` THEN + ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `~(val (num_5blocks_adjusted:int64) * 0x50 + 0x30 = val (num_blocks_adjusted:int64))` ASSUME_TAC THENL + [ UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 + 0x10 = val (num_blocks_adjusted:int64)` THEN + ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `~(val (num_5blocks_adjusted:int64) * 0x50 + 0x20 = val (num_blocks_adjusted:int64))` ASSUME_TAC THENL + [ UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 + 0x10 = val (num_blocks_adjusted:int64)` THEN + ARITH_TAC; ALL_TAC] THEN - ENSURES_SEQUENCE_TAC `pc + 0xab8` - `\s. - read X0 s = word_add (word_add ct_ptr (word curr_len)) (word 0x10) /\ - read X1 s = word_add pt_ptr (word curr_len) /\ - read X21 s = tail_len /\ - read Q6 s = calculate_tweak curr_blocks iv key2 /\ - read Q16 s = k00 /\ read Q17 s = k01 /\ read Q12 s = k02 /\ read Q13 s = k03 /\ - read Q14 s = k04 /\ read Q15 s = k05 /\ read Q4 s = k06 /\ read Q5 s = k07 /\ - read Q18 s = k08 /\ read Q19 s = k09 /\ read Q20 s = k0a /\ read Q21 s = k0b /\ - read Q22 s = k0c /\ read Q23 s = k0d /\ read Q7 s = k0e /\ + SUBGOAL_THEN `val (num_5blocks_adjusted:int64) * 0x50 + 0x10 <= val (len:int64)` ASSUME_TAC THENL + [ UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 + 0x10 = val (num_blocks_adjusted:int64)` THEN + UNDISCH_TAC `val (num_blocks_adjusted:int64) <= val (len:int64)` THEN + ARITH_TAC; ALL_TAC] THEN + MP_TAC (SPECL [`ct_ptr:int64`; `num_5blocks_adjusted:int64`; `len:int64`; `ct:byte list`; `s9:armstate`] READ_CT_TAIL1_LEMMA) THEN + ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN - byte_list_at ct ct_ptr len s /\ - byte_list_at (aes256_xts_decrypt ct curr_len iv key1 key2) pt_ptr (word curr_len) s /\ - read (memory :> bytes128 (word_add pt_ptr (word curr_len))) s = - aes256_xts_decrypt_round - (bytes_to_int128 (SUB_LIST (curr_len,0x10) ct)) - (calculate_tweak (curr_blocks + 0x1) iv key2) - key1` THEN - CONJ_TAC THENL - [ - MATCH_MP_TAC ENSURES_FRAME_SUBSUMED THEN - EXISTS_TAC `MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI ,, - MAYCHANGE [X19; X20; X21; X22],, - MAYCHANGE [Q8; Q9; Q10; Q11; Q12; Q13; Q14; Q15],, - MAYCHANGE [memory :> bytes128 (word_add pt_ptr (word curr_len))]` THEN - REWRITE_TAC[MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI] THEN - CONJ_TAC THENL [ - REPEAT (GEN_REWRITE_TAC ONCE_DEPTH_CONV [GSYM SEQ_ASSOC] THEN - MATCH_MP_TAC SUBSUMED_SEQ THEN REWRITE_TAC[SUBSUMED_REFL]) THEN - ABBREV_TAC `vallen = val (len:int64)` THEN - SUBSUMED_MAYCHANGE_TAC; ALL_TAC] THEN + (* Assumptions that help with reasoning about nonoverlapping + so that the universally quantified assumption stays. + See: https://hol-light.zulipchat.com/#narrow/channel/474190-s2n-bignum/topic/.E2.9C.94.20Symbolic.20simulation.20removed.20assumption/with/541554894 *) + SUBGOAL_THEN `0x50 * (val (num_5blocks_adjusted:int64)) < 0x2 EXP 0x40` ASSUME_TAC THENL + [ UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 <= val (num_blocks_adjusted:int64)` THEN + UNDISCH_TAC `val (num_blocks_adjusted:int64) <= 0x2 EXP 0x18` THEN + ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `val ((word (0x50 * val (num_5blocks_adjusted:int64))):int64) = 0x50 * val num_5blocks_adjusted` ASSUME_TAC THENL [ + IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN ASM_ARITH_TAC; ALL_TAC] THEN + POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th])) THEN - REWRITE_TAC[byte_list_at] THEN - UNDISCH_THEN `val ((word curr_len):int64) = curr_len` - (fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th]) THEN REWRITE_TAC[th]) THEN + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (10--40) THEN + XTSDEC_TAC `Q0:(armstate,int128)component` + `val (num_5blocks_adjusted:int64) * 0x50` `val (num_5blocks_adjusted:int64) * 0x5` THEN - ENSURES_INIT_TAC "s0" THEN - ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (1--2) THEN + (* The following lemmas are for NONSELFMODIFYING_STATE_UPDATE_TAC when store back to pt_ptr *) + RULE_ASSUM_TAC(REWRITE_RULE + [WORD_RULE `word_mul (word 0x50) num_5blocks_adjusted:int64 = word(0x50 * val num_5blocks_adjusted)`]) THEN - (* Discharge if condition *) - SUBGOAL_THEN `~(val (word_and (tail_len:int64) (word 0xf)) = 0x0)` MP_TAC THENL - [ UNDISCH_TAC `~(val (tail_len:int64) = 0x0)` THEN - UNDISCH_TAC `val (tail_len:int64) < 16` THEN - MP_TAC (SPEC `tail_len:int64` WORD_AND_MASK16_EQ_0) THEN - SIMP_TAC[]; ALL_TAC] THEN - ASM_REWRITE_TAC[] THEN DISCH_TAC THEN - POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th])) THEN + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (41--49) THEN + TWEAK_TAC `Q6:(armstate,int128)component` `val (num_5blocks_adjusted:int64) * 0x5 + 0x1` `val (num_5blocks_adjusted:int64) * 0x5` THEN - (* Decrypt last block *) - ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (3--11) THEN - TWEAK_TAC `Q8:(armstate,int128)component` `(curr_blocks + 1):num` `curr_blocks:num` THEN - MP_TAC (SPECL [`ct_ptr:int64`; `curr_len:num`; `len:int64`; `ct:byte list`; `s11:armstate`] READ_CT_LAST_LEMMA) THEN - ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN - ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (12--42) THEN - XTSDEC_TAC `Q26:(armstate,int128)component` `curr_len:num` `(curr_blocks + 1):num` THEN - ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (43--43) THEN + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (50--50) THEN + ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN + REPEAT CONJ_TAC THENL + [ + REWRITE_TAC[acc_len] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; + REWRITE_TAC[acc_len] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; + REWRITE_TAC[acc_blocks] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; + REWRITE_TAC[acc_blocks] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; + REWRITE_TAC[acc_blocks] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; - ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] - ; ALL_TAC - ] THEN + REWRITE_TAC[acc_len] THEN ASM_SIMP_TAC[LE_REFL] THEN + SUBGOAL_THEN `val ((word (0x50 * val (num_5blocks_adjusted:int64) + 0x10)):int64) = + 0x50 * val num_5blocks_adjusted + 0x10` ASSUME_TAC THENL + [ IMP_REWRITE_TAC[VAL_WORD; MOD_LT; DIMINDEX_64] THEN + UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 + 0x10 <= val (len:int64)` THEN + UNDISCH_TAC `val (len:int64) <= 0x2 EXP 0x18` THEN + ARITH_TAC; ALL_TAC] THEN + POP_ASSUM(fun th -> REWRITE_TAC[th]) THEN - ABBREV_TAC `PP = aes256_xts_decrypt_round - (bytes_to_int128 (SUB_LIST (curr_len,0x10) (ct:byte list))) - (calculate_tweak (curr_blocks + 0x1) (iv:int128) (key2:int128 list)) - (key1:int128 list)` THEN - SUBGOAL_THEN `curr_len + 16 + val (tail_len:int64) = val (len:int64)` ASSUME_TAC THENL - [ REWRITE_TAC[GSYM (ASSUME `acc_len num_5blocks_adjusted num_blocks_adjusted = curr_len`)] THEN - MP_TAC (SPECL [`num_5blocks_adjusted:int64`; `num_blocks_adjusted:int64`] VALUE_OF_ACC_LEN) THEN - ANTS_TAC THENL[ASM_ARITH_TAC; ALL_TAC] THEN - ANTS_TAC THENL[ASM_ARITH_TAC; ALL_TAC] THEN - ANTS_TAC THENL[ASM_SIMP_TAC[]; ALL_TAC] THEN - SIMP_TAC[] THEN DISCH_TAC THEN - EXPAND_TAC "num_blocks_adjusted" THEN - UNDISCH_TAC `~(val (tail_len:int64) = 0)` THEN - SIMP_TAC[] THEN DISCH_TAC THEN - ASM_SIMP_TAC[VAL_WORD_SUB; DIMINDEX_64; VAL_WORD; - ARITH_RULE `16 MOD 2 EXP 64 = 16`] THEN - MP_TAC (SPECL [`val (num_blocks:int64)`; `0x2 EXP 0x40`; `16`] - (ARITH_RULE `!a b c. c <= a ==> c <= b ==> a + b - c = (a - c) + b`)) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN - ANTS_TAC THENL [ARITH_TAC; ALL_TAC] THEN - ASM_SIMP_TAC[] THEN DISCH_TAC THEN - MP_TAC (SPECL [`1`; `0x2 EXP 0x40`; `val (num_blocks:int64) - 16`] - (CONJUNCT1 (CONJUNCT2 (CONJUNCT2 MOD_MULT_ADD)))) THEN - SIMP_TAC[ARITH_RULE `!x. 1 * x = x`] THEN DISCH_TAC THEN - IMP_REWRITE_TAC[MOD_LT] THEN - CONJ_TAC THENL [ - SUBGOAL_THEN `val (num_blocks:int64) - 0x10 + 0x10 + val (tail_len:int64) - = val num_blocks + val tail_len` SUBST1_TAC THENL - [ IMP_REWRITE_TAC[ADD_ASSOC; SUB_ADD] THEN ASM_ARITH_TAC; ALL_TAC] THEN - EXPAND_TAC "len" THEN - REWRITE_TAC[VAL_WORD_ADD] THEN - IMP_REWRITE_TAC[MOD_LT; DIMINDEX_64] THEN - CONJ_TAC THENL [ARITH_TAC; ASM_ARITH_TAC]; - ALL_TAC - ] THEN - ASM_ARITH_TAC; ALL_TAC] THEN - (* Invariant proof for .composite_dec_loop *) - (* Invariant: - X0 points to tail of ct - X1 points to starting of last full block of pt - X13 points to tail of pt - X20 points to tail of ct - X21 holds tail_len - Q6 holds second to last tweak - Q16 ... Q7 holds the key schedule for encryption - - Memory: ct_ptr points to the input - Memory: Up to the last block, the output matches the specification - Memory: For the last block, for each byte - [0,i) -- previous decrption result - [i,tail_len) -- equal corresponding ct tail bytes - [tail_len,16] -- previous decryption result - Memory: For the tail, for each byte - [i,tail_len) -- copied over from last pt block - *) - ENSURES_WHILE_PADOWN_TAC - `val (tail_len:int64)` - `0` - `pc + 0xac0` - `pc + 0xad4` - `\i s. - ( read X0 s = word_add (word_add ct_ptr (word curr_len)) (word 0x10) /\ - read X1 s = word_add pt_ptr (word curr_len) /\ - read X13 s = word_add (word_add pt_ptr (word curr_len)) (word 0x10) /\ - read X20 s = word_add (word_add ct_ptr (word curr_len)) (word 0x10) /\ - read X21 s = (word i):int64 /\ - read Q6 s = calculate_tweak curr_blocks iv key2 /\ - read Q16 s = k00 /\ read Q17 s = k01 /\ read Q12 s = k02 /\ read Q13 s = k03 /\ - read Q14 s = k04 /\ read Q15 s = k05 /\ read Q4 s = k06 /\ read Q5 s = k07 /\ - read Q18 s = k08 /\ read Q19 s = k09 /\ read Q20 s = k0a /\ read Q21 s = k0b /\ - read Q22 s = k0c /\ read Q23 s = k0d /\ read Q7 s = k0e /\ - byte_list_at ct ct_ptr len s /\ - byte_list_at (aes256_xts_decrypt ct curr_len iv key1 key2) pt_ptr (word curr_len) s /\ + (* Remove quantifier *) + UNDISCH_TAC + `forall i. + i < 0x50 * val (num_5blocks_adjusted:int64) + ==> read (memory :> bytes8 (word_add pt_ptr (word i))) s50 = + EL i (aes256_xts_decrypt ct (0x50 * val num_5blocks_adjusted) iv key1 key2)` THEN + MP_TAC (SPECL [`0x50 * val (num_5blocks_adjusted:int64) + 0x10:num`; `pt_ptr:int64`; + `(aes256_xts_decrypt ct (0x50 * val (num_5blocks_adjusted:int64) + 0x10) iv key1 key2):byte list`; + `s50:armstate`] BYTE_LIST_TO_NUM_THM) THEN + ANTS_TAC THENL[ + REWRITE_TAC[ARITH_RULE `0x50 * i + 0x10 = 0x10 * (5 * i + 1)`; + LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS] THEN + ARITH_TAC + ; ALL_TAC] THEN + DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN + MP_TAC (SPECL [`0x50 * val (num_5blocks_adjusted:int64):num`; `pt_ptr:int64`; + `(aes256_xts_decrypt ct (0x50 * val (num_5blocks_adjusted:int64)) iv key1 key2):byte list`; + `s50:armstate`] BYTE_LIST_TO_NUM_THM) THEN + ANTS_TAC THENL[ + REWRITE_TAC[ARITH_RULE `0x50 * i = 0x10 * 5 * i`; + LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS] THEN + ARITH_TAC + ; ALL_TAC] THEN + DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN + DISCH_TAC THEN - read (memory :> bytes128 (word_add pt_ptr (word curr_len))) s = - cipher_stealing_inv i curr_len (val (tail_len:int64)) PP ct /\ + IMP_REWRITE_TAC[(SPECL [`pt_ptr:int64`; `(0x50 * val (num_5blocks_adjusted:int64)):num`; + `(aes256_xts_decrypt ct (0x50 * val (num_5blocks_adjusted:int64) + 0x10) iv key1 key2):byte list`; + `s50:armstate`] + READ_BYTES_AND_BYTE128_SPLIT)] THEN + EXISTS_TAC `ct:byte list` THEN EXISTS_TAC `iv:int128` THEN + EXISTS_TAC `key1:int128 list` THEN EXISTS_TAC `key2:int128 list` THEN + REPEAT CONJ_TAC THENL [ + MP_TAC (SPECL [`0x5 * val (num_5blocks_adjusted:int64) + 0x1:num`; + `ct:byte list`; `iv:int128`; `key1:int128 list`; + `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN + REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC; GSYM ADD_ASSOC] THEN + CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN ARITH_TAC; - byte_list_at (SUB_LIST (i, val tail_len - i) (int128_to_bytes PP)) - (word_add pt_ptr (word (curr_len + 0x10 + i))) - (word ((val tail_len) - i)) s) /\ - // loop backedge condition - (read ZF s <=> i = 0) /\ - (read NF s <=> ival ((word i):int64) < &0) /\ - (read VF s <=> ~(ival ((word (i + 1)):int64) - &1 = ival ((word i):int64)))` THEN - ASM_REWRITE_TAC[] THEN REPEAT CONJ_TAC THENL - [ - (* Subgoal1: 0 < val tail_len *) - ASM_ARITH_TAC; + MP_TAC (SPECL [`0x5 * val (num_5blocks_adjusted:int64) + 0x1:num`; + `ct:byte list`; `iv:int128`; `key1:int128 list`; + `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN + REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC; GSYM ADD_ASSOC] THEN + CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN ARITH_TAC; - (* Subgoal2: invariant holds before entering loop *) - REWRITE_TAC[byte_list_at] THEN - UNDISCH_THEN `val ((word curr_len):int64) = curr_len` - (fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th]) THEN REWRITE_TAC[th]) THEN + (* Establish that one xts decrypt round is the same as + selecting one block of bytes from calling the top-level function. *) + REWRITE_TAC[aes256_xts_decrypt] THEN + SIMP_TAC[ARITH_RULE `~(0x50 * i + 0x10 < 0x10)`] THEN + SUBGOAL_THEN `(0x50 * val (num_5blocks_adjusted:int64) + 0x10) MOD 0x10 = 0` SUBST1_TAC THENL + [ REWRITE_TAC[ARITH_RULE `80 * i + 16 = 16 * (5 * i + 1)`] THEN + REWRITE_TAC[MOD_MULT] + ; ALL_TAC] THEN + CONV_TAC (DEPTH_CONV let_CONV) THEN + REWRITE_TAC[SUB_0; ARITH_RULE `(0x50 * i + 0x10) DIV 0x10 = 0x5 * i + 0x1`] THEN + (* Two cases: i = 0 then execute tail branch, else execute recursion branch *) + COND_CASES_TAC THENL + [ SUBGOAL_THEN `val (num_5blocks_adjusted:int64) = 0` SUBST1_TAC THENL + [ UNDISCH_TAC `5 * val (num_5blocks_adjusted:int64) + 1 < 2` THEN + UNDISCH_TAC `0 < val (num_5blocks_adjusted:int64)` THEN + ARITH_TAC + ; ALL_TAC] THEN CONV_TAC NUM_REDUCE_CONV THEN - ENSURES_INIT_TAC "s0" THEN - ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (1--2) THEN - ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN - REPEAT CONJ_TAC THENL - [ - REWRITE_TAC[WORD_VAL]; - - REWRITE_TAC[cipher_stealing_inv; SUB_REFL] THEN - SUBGOAL_THEN `SUB_LIST (val (tail_len:int64),0x0) (SUB_LIST (curr_len + 16,val tail_len) (ct:byte list)) = []` SUBST1_TAC THENL - [ REWRITE_TAC[SUB_LIST_CLAUSES]; ALL_TAC] THEN - REWRITE_TAC[CONJUNCT1 APPEND] THEN - SUBGOAL_THEN `APPEND (SUB_LIST (0x0,val (tail_len:int64)) (int128_to_bytes PP)) - (SUB_LIST (val tail_len,0x10 - val tail_len) (int128_to_bytes PP)) = - (int128_to_bytes PP)` SUBST1_TAC THENL - [ MP_TAC (ISPECL [`int128_to_bytes PP`; `val (tail_len:int64)`; `16 - val (tail_len:int64)`; `0`] (GSYM SUB_LIST_SPLIT)) THEN - IMP_REWRITE_TAC[ADD_CLAUSES; ARITH_RULE `!x. x < 16 ==> x + 16 - x = 16`] THEN - DISCH_TAC THEN - IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES; LENGTH_OF_INT128_TO_BYTES] - ; ALL_TAC] THEN - REWRITE_TAC[BYTES_TO_INT128_OF_INT128_TO_BYTES]; + MP_TAC (SPECL [`0x0:num`; `0x0:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + LENGTH_OF_AES256_XTS_DECRYPT_TAIL) THEN + CONV_TAC NUM_REDUCE_CONV THEN REWRITE_TAC[ADD_0] THEN DISCH_TAC THEN + IMP_REWRITE_TAC[(ISPECL [`(aes256_xts_decrypt_tail 0x0 0x0 ct iv key1 key2):byte list`; + `0x10:num`] SUB_LIST_LENGTH_IMPLIES)] THEN - REWRITE_TAC[VAL_WORD_0] THEN ARITH_TAC - ]; + REWRITE_TAC[AES256_XTS_DECRYPT_TAIL_WHEN_1BLOCK] THEN + CONV_TAC NUM_REDUCE_CONV; - (* Subgoal 3: inductive step *) - REPEAT STRIP_TAC THEN + SIMP_TAC[ARITH_RULE `(0x5 * i + 0x1) - 0x2 = 0x5 * i - 0x1`; + ARITH_RULE `(0x5 * i + 0x1) - 0x1 = 0x5 * i`] THEN - (* For non-overlapping and MAYCHANGE address reasoning *) - SUBGOAL_THEN `curr_len + 16 + i < val (len:int64)` ASSUME_TAC THENL - [ REWRITE_TAC[GSYM (ASSUME `acc_len num_5blocks_adjusted num_blocks_adjusted = curr_len`)] THEN - MP_TAC (SPECL [`num_5blocks_adjusted:int64`; `num_blocks_adjusted:int64`] VALUE_OF_ACC_LEN) THEN - REPEAT_N 3 (ANTS_TAC THENL [ASM_ARITH_TAC ORELSE ASM_SIMP_TAC[]; ALL_TAC]) THEN - SIMP_TAC[] THEN DISCH_TAC THEN - EXPAND_TAC "num_blocks_adjusted" THEN - SIMP_TAC[ASSUME `~(val (tail_len:int64) = 0)`] THEN - REWRITE_TAC[VAL_WORD_SUB; DIMINDEX_64] THEN - MP_TAC (SPECL [`val (num_blocks:int64)`; `0x2 EXP 0x40`; `val ((word 0x10):int64)`] - (ARITH_RULE `!a b c. c <= a ==> c <= b ==> a + b - c = (a - c) + b`)) THEN - ANTS_TAC THENL [ - IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN ASM_ARITH_TAC - ; ALL_TAC] THEN - ANTS_TAC THENL [ WORD_ARITH_TAC; ALL_TAC] THEN - SIMP_TAC[] THEN DISCH_TAC THEN - MP_TAC (SPECL [`1`; `0x2 EXP 0x40`; `val (num_blocks:int64) - val ((word 0x10):int64)`] - (CONJUNCT1 (CONJUNCT2 (CONJUNCT2 MOD_MULT_ADD)))) THEN - SIMP_TAC[ARITH_RULE `!x. 1 * x = x`] THEN DISCH_TAC THEN - IMP_REWRITE_TAC[MOD_LT] THEN - IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN - CONV_TAC NUM_REDUCE_CONV THEN - EXPAND_TAC "len" THEN - IMP_REWRITE_TAC[VAL_WORD_ADD; DIMINDEX_64; MOD_LT] THEN - UNDISCH_TAC `val (num_blocks:int64) <= val (len:int64)` THEN - UNDISCH_TAC `~(val (num_blocks:int64) < 0x60)` THEN - UNDISCH_TAC `val (num_blocks:int64) <= 0x2 EXP 0x18` THEN - UNDISCH_TAC `i < val (tail_len:int64)` THEN - UNDISCH_TAC `val (tail_len:int64) < 0x10` THEN - ARITH_TAC - ; ALL_TAC] THEN + MP_TAC (SPECL [`0`;`5 * val (num_5blocks_adjusted:int64) - 1:num`; + `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + LENGTH_OF_AES256_XTS_DECRYPT_REC) THEN + SUBGOAL_THEN `~(0x5 * val (num_5blocks_adjusted:int64) - 0x1 < 0x0)` ASSUME_TAC THENL + [ UNDISCH_TAC `~(0x5 * val (num_5blocks_adjusted:int64) + 0x1 < 0x2)` THEN ARITH_TAC; ALL_TAC ] THEN + ASM_SIMP_TAC[] THEN + IMP_REWRITE_TAC[ARITH_RULE `~(0x5 * i + 0x1 < 0x2) ==> (0x5 * i - 1 - 0x0 + 0x1) * 0x10 = 0x50 * i`] THEN + IMP_REWRITE_TAC[SUB_LIST_APPEND_RIGHT_LEMMA] THEN DISCH_TAC THEN - MATCH_MP_TAC ENSURES_FRAME_SUBSUMED THEN - EXISTS_TAC `MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI ,, - MAYCHANGE [X19; X20; X21; X22],, - MAYCHANGE [Q8; Q9; Q10; Q11; Q12; Q13; Q14; Q15],, - MAYCHANGE [memory :> bytes8 (word_add pt_ptr (word (curr_len + 0x10 + i)))],, - MAYCHANGE [memory :> bytes8 (word_add pt_ptr (word (curr_len + i)))]` THEN - REWRITE_TAC[MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI] THEN - CONJ_TAC THENL [ - REPEAT (GEN_REWRITE_TAC ONCE_DEPTH_CONV [GSYM SEQ_ASSOC] THEN - MATCH_MP_TAC SUBSUMED_SEQ THEN REWRITE_TAC[SUBSUMED_REFL]) THEN - ABBREV_TAC `vallen = val (len:int64)` THEN - SUBSUMED_MAYCHANGE_TAC; ALL_TAC] THEN + MP_TAC (SPECL [`5 * val (num_5blocks_adjusted:int64):num`; + `0x0:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + LENGTH_OF_AES256_XTS_DECRYPT_TAIL) THEN + CONV_TAC NUM_REDUCE_CONV THEN REWRITE_TAC[ADD_0] THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN - REWRITE_TAC[byte_list_at] THEN - UNDISCH_THEN `val ((word curr_len):int64) = curr_len` - (fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th]) THEN REWRITE_TAC[th]) THEN - ENSURES_INIT_TAC "s0" THEN + REWRITE_TAC[AES256_XTS_DECRYPT_TAIL_WHEN_1BLOCK] THEN + SIMP_TAC[ARITH_RULE `i * 0x50 = (i * 0x5) * 0x10`; + ARITH_RULE `i * 0x5 = 0x5 * i`]]; - SUBGOAL_THEN `val ((word (val (tail_len:int64) - i)):int64) = val tail_len - i` SUBST_ALL_TAC THENL - [ IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN - UNDISCH_TAC `i < val (tail_len:int64)` THEN - UNDISCH_TAC `val (tail_len:int64) < 0x10` THEN - ARITH_TAC; ALL_TAC] THEN - SUBGOAL_THEN `val ((word (val (tail_len:int64) - (i + 0x1))):int64) = val tail_len - (i + 1)` SUBST_ALL_TAC THENL - [ IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN - UNDISCH_TAC `i < val (tail_len:int64)` THEN - UNDISCH_TAC `val (tail_len:int64) < 0x10` THEN - ARITH_TAC; ALL_TAC] THEN + (* Proving that reading previous bytes is the same as the spec *) + REWRITE_TAC[ARITH_RULE `0x50 * i = 0x10 * 5 * i`; + ARITH_RULE `0x50 * i + 0x10 = 0x10 * 5 * i + 0x10`] THEN + REWRITE_TAC[SUB_LIST_OF_AES256_XTS_DECRYPT_FULL_BLOCKS] THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN + REWRITE_TAC[LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS]] + ] + ; ALL_TAC] THEN - SUBGOAL_THEN `word_sub ((word (i + 0x1)):int64) (word 0x1) = word i` ASSUME_TAC THENL - [ REWRITE_TAC[GSYM VAL_EQ; VAL_WORD_SUB; DIMINDEX_64] THEN - MP_TAC (SPECL [`val ((word (i + 0x1)):int64)`; `0x2 EXP 0x40`; `val ((word 0x1):int64)`] - (ARITH_RULE `!a b c. c <= a ==> c <= b ==> a + b - c = (a - c) + b`)) THEN - ANTS_TAC THENL [ - IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN ASM_ARITH_TAC - ; ALL_TAC] THEN - ANTS_TAC THENL [ WORD_ARITH_TAC; ALL_TAC] THEN - SIMP_TAC[] THEN DISCH_TAC THEN - MP_TAC (SPECL [`1`; `0x2 EXP 0x40`; `val ((word (i + 0x1)):int64) - val ((word 0x1):int64)`] - (CONJUNCT1 (CONJUNCT2 (CONJUNCT2 MOD_MULT_ADD)))) THEN - SIMP_TAC[ARITH_RULE `!x. 1 * x = x`] THEN DISCH_TAC THEN - IMP_REWRITE_TAC[MOD_LT] THEN - CONJ_TAC THENL - [ SUBGOAL_THEN `i + 1 < 2 EXP 64` MP_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN + (* Case: len % 0x50 = 0 *) + DISCH_TAC THEN + SUBGOAL_THEN `val (num_5blocks_adjusted:int64) * 0x50 = val (num_blocks_adjusted:int64)` ASSUME_TAC THENL + [ MATCH_MP_TAC (SPECL [`val (num_blocks_adjusted:int64)`; `val (num_5blocks_adjusted:int64)`] DIVISION_BY_80_LEMMA) THEN + REPEAT CONJ_TAC THENL + [ + EXPAND_TAC "num_5blocks_adjusted" THEN IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN + UNDISCH_TAC `val (num_blocks_adjusted:int64) <= 0x2 EXP 0x18` THEN ARITH_TAC; - UNDISCH_TAC `i < val (tail_len:int64)` THEN - UNDISCH_TAC `val (tail_len:int64) < 0x10` THEN - WORD_ARITH_TAC] - ; ALL_TAC] THEN - MP_TAC (SPECL [`(word_add pt_ptr (word curr_len)):int64`; `word i:int64`; `s0:armstate`; - `(cipher_stealing_inv (i + 0x1) curr_len (val (tail_len:int64)) PP ct):int128`] - SELECT_ONE_BYTE_FROM_BLOCK) THEN + EXPAND_TAC "num_blocks_adjusted" THEN + EXPAND_TAC "num_blocks" THEN + COND_CASES_TAC THENL + [ + REWRITE_TAC[NUM_BLOCKS_TO_VAL] THEN + IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT; DIVIDES_RMUL; DIVIDES_REFL] THEN + UNDISCH_TAC `val (len:int64) <= 0x2 EXP 0x18` THEN + ARITH_TAC; - SUBGOAL_THEN `val ((word i):int64) < 0x10` ASSUME_TAC THENL - [ UNDISCH_TAC `i < val (tail_len:int64)` THEN - UNDISCH_TAC `val (tail_len:int64) < 0x10` THEN - WORD_ARITH_TAC; ALL_TAC ] THEN - ASM_SIMP_TAC[] THEN - REPEAT STRIP_TAC THEN + IMP_REWRITE_TAC[NUM_BLOCKS_MINUS1_TO_VAL] THEN + IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT; DIVIDES_RMUL; DIVIDES_REFL] THEN + UNDISCH_TAC `val (len:int64) <= 0x2 EXP 0x18` THEN + ARITH_TAC]; - MP_TAC (SPECL [`ct_ptr:int64`; `len:int64`; - `(word_add (word (curr_len + 0x10)) (word i)):int64`; - `ct:byte list`; `s0:armstate`] SELECT_ONE_BYTE_FROM_FORALL) THEN - SUBGOAL_THEN `val (word_add ((word (curr_len + 0x10)):int64) (word i)) < val (len:int64)` ASSUME_TAC THENL - [ REWRITE_TAC[WORD_RULE `!a b. word_add ((word a):int64) (word b) = word (a + b)`] THEN - IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN - ASM_ARITH_TAC; ALL_TAC] THEN - ASM_SIMP_TAC[] THEN - STRIP_TAC THEN - - (* Break the `read (memory :> bytes128 (word_add pt_ptr (word curr_len))) s0 - into bytes using BREAK_ONE_BLOCK_INTO_BYTES *) - MP_TAC (SPECL [`(word_add pt_ptr (word curr_len)):int64`; `s0:armstate`; - `(cipher_stealing_inv (i + 0x1) curr_len (val (tail_len:int64)) PP ct):int128`] - BREAK_ONE_BLOCK_INTO_BYTES) THEN - ASM_SIMP_TAC[] THEN REPEAT STRIP_TAC THEN - - (* For address matching when symbolic simulation *) - SUBGOAL_THEN `word_add (ct_ptr:int64) (word_add (word (curr_len + 0x10)) (word i)) = - word_add ct_ptr (word (curr_len + 16 + i))` SUBST_ALL_TAC THENL - [ REWRITE_TAC[WORD_RULE `!a b. word_add ((word a):int64) (word b) = word (a + b)`; ADD_ASSOC] - ; ALL_TAC] THEN - SUBGOAL_THEN `!x. word_add (word_add (pt_ptr:int64) (word curr_len)) (word x) = - word_add pt_ptr (word (curr_len + x))` ASSUME_TAC THENL - [ GEN_TAC THEN REWRITE_TAC[ - WORD_RULE `!(a:int64) b c. word_add (word_add a b) c = word_add a (word_add b c)`; - WORD_RULE `!a b. word_add ((word a):int64) (word b) = word (a + b)`] - ; ALL_TAC] THEN - POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th])) THEN + UNDISCH_TAC `~(val (word_sub + (word_sub (num_blocks_adjusted:int64) + (word_mul (word 0x50) (num_5blocks_adjusted:int64))) + (word 0x10)) = 0x0)` THEN + REWRITE_TAC[CONTRAPOS_THM] THEN + REWRITE_TAC[VAL_WORD_SUB_EQ_0; VAL_WORD_MUL; VAL_WORD; DIMINDEX_64; + ARITH_RULE `0x10 MOD 0x2 EXP 0x40 = 0x10`] THEN + REWRITE_TAC[VAL_WORD_SUB; VAL_WORD_MUL; VAL_WORD; DIMINDEX_64; + ARITH_RULE `0x50 MOD 0x2 EXP 0x40 = 0x50`] THEN - (* case analysis based on i = 0 ... 14, this is unavoidable because symbolic execution - needs to know which byte is being overwritten in pt_ptr to properly update the state. *) - MAP_EVERY (fun i -> TAIL_SWAP_ASM_CASES_TAC (mk_numeral (num i))) (0--14) THEN - UNDISCH_TAC `15 <= i` THEN - UNDISCH_TAC `i < val (tail_len:int64)` THEN - UNDISCH_TAC `val (tail_len:int64) < 16` THEN - ARITH_TAC; + SUBGOAL_THEN `0x50 * val (num_5blocks_adjusted:int64) < 2 EXP 64` ASSUME_TAC THENL + [ UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 <= val (len:int64)` THEN + UNDISCH_TAC `val (len:int64) <= 0x2 EXP 0x18` THEN + ARITH_TAC; ALL_TAC] THEN + MP_TAC (SPECL [`0x50 * val (num_5blocks_adjusted:int64)`; `2 EXP 64`] MOD_LT) THEN + ANTS_TAC THENL [ASM_SIMP_TAC[]; ALL_TAC] THEN + SIMP_TAC[] THEN DISCH_TAC THEN - (* Subgoal 4: *) - REPEAT STRIP_TAC THEN - REWRITE_TAC[byte_list_at] THEN - ENSURES_INIT_TAC "s0" THEN - ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (1--1) THEN - SUBGOAL_THEN `ival ((word i):int64) < &0x0 <=> - ~(ival ((word (i + 0x1)):int64) - &0x1 = ival ((word i):int64))` ASSUME_TAC THENL - [ SUBGOAL_THEN `ival ((word i):int64) = &i` ASSUME_TAC THENL - [ MATCH_MP_TAC IVAL_WORD_LT THEN - UNDISCH_TAC `i < val (tail_len:int64)` THEN - UNDISCH_TAC `val (tail_len:int64) < 0x10` THEN - ARITH_TAC; ALL_TAC] THEN - SUBGOAL_THEN `ival ((word (i + 0x1)):int64) = &(i + 1)` ASSUME_TAC THENL - [ MATCH_MP_TAC IVAL_WORD_LT THEN - UNDISCH_TAC `i < val (tail_len:int64)` THEN - UNDISCH_TAC `val (tail_len:int64) < 0x10` THEN - ARITH_TAC; ALL_TAC] THEN - ASM_REWRITE_TAC[] THEN - ARITH_TAC; ALL_TAC] THEN - POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th])) THEN - ENSURES_FINAL_STATE_TAC THEN ASM_SIMP_TAC[]; + MP_TAC (SPECL [`val (num_blocks_adjusted:int64)`; `0x2 EXP 0x40`; + `0x50 * val (num_5blocks_adjusted:int64)`] + (ARITH_RULE `!a b c. c <= a ==> c <= b ==> a + b - c = (a - c) + b`)) THEN + ANTS_TAC THENL [ + UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 <= val (num_blocks_adjusted:int64)` THEN + SIMP_TAC[MULT_SYM]; ALL_TAC] THEN + ANTS_TAC THENL [ + UNDISCH_TAC `0x50 * val (num_5blocks_adjusted:int64) < 2 EXP 64` THEN + ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[] THEN DISCH_TAC THEN - (* Subgoal 5: *) - REPEAT STRIP_TAC THEN - REWRITE_TAC[byte_list_at] THEN - CONV_TAC NUM_REDUCE_CONV THEN - REWRITE_TAC[cipher_stealing_inv; CONJUNCT1 SUB_LIST; CONJUNCT1 APPEND] THEN - REWRITE_TAC[SUB_0] THEN - ASM_REWRITE_TAC[] THEN - SUBGOAL_THEN `val ((word (val (tail_len:int64))):int64) = val tail_len` SUBST1_TAC THENL - [ IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN ASM_ARITH_TAC; ALL_TAC] THEN - SUBGOAL_THEN `(SUB_LIST (0x0,val (tail_len:int64)) (SUB_LIST (curr_len + 16,val tail_len) (ct:byte list))) = - (SUB_LIST (curr_len + 16,val tail_len) ct)` SUBST1_TAC THENL - [ IMP_REWRITE_TAC[SUB_LIST_REFL] THEN - ASM_REWRITE_TAC[LENGTH_SUB_LIST; MIN] THEN - ASM_ARITH_TAC; ALL_TAC] THEN + MP_TAC (SPECL [`1`; `0x2 EXP 0x40`; + `val (num_blocks_adjusted:int64) - 0x50 * val (num_5blocks_adjusted:int64)`] + (CONJUNCT1 (CONJUNCT2 (CONJUNCT2 MOD_MULT_ADD)))) THEN + REWRITE_TAC[ARITH_RULE `1 * 2 EXP 64 = 2 EXP 64`] THEN + SIMP_TAC[] THEN DISCH_TAC THEN + SIMP_TAC[MULT_SYM] THEN DISCH_TAC THEN + CONV_TAC NUM_REDUCE_CONV; - MATCH_MP_TAC ENSURES_FRAME_SUBSUMED THEN - EXISTS_TAC `MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI ,, - MAYCHANGE [X19; X20; X21; X22],, - MAYCHANGE [Q8; Q9; Q10; Q11; Q12; Q13; Q14; Q15],, - MAYCHANGE [memory :> bytes128 (word_add pt_ptr (word curr_len))]` THEN - REWRITE_TAC[MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI] THEN - CONJ_TAC THENL [ - REPEAT (GEN_REWRITE_TAC ONCE_DEPTH_CONV [GSYM SEQ_ASSOC] THEN - MATCH_MP_TAC SUBSUMED_SEQ THEN REWRITE_TAC[SUBSUMED_REFL]) THEN - ABBREV_TAC `vallen = val (len:int64)` THEN - SUBSUMED_MAYCHANGE_TAC; ALL_TAC] THEN + UNDISCH_TAC `~(val (word_sub + (word_sub (num_blocks_adjusted:int64) + (word_mul (word 0x50) (num_5blocks_adjusted:int64))) + (word 0x20)) = 0x0)` THEN + REWRITE_TAC[CONTRAPOS_THM] THEN + REWRITE_TAC[VAL_WORD_SUB_EQ_0; VAL_WORD_MUL; VAL_WORD; DIMINDEX_64; + ARITH_RULE `0x20 MOD 0x2 EXP 0x40 = 0x20`] THEN + REWRITE_TAC[VAL_WORD_SUB; VAL_WORD_MUL; VAL_WORD; DIMINDEX_64; + ARITH_RULE `0x50 MOD 0x2 EXP 0x40 = 0x50`] THEN - ENSURES_INIT_TAC "s0" THEN + SUBGOAL_THEN `0x50 * val (num_5blocks_adjusted:int64) < 2 EXP 64` ASSUME_TAC THENL + [ UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 <= val (len:int64)` THEN + UNDISCH_TAC `val (len:int64) <= 0x2 EXP 0x18` THEN + ARITH_TAC; ALL_TAC] THEN + MP_TAC (SPECL [`0x50 * val (num_5blocks_adjusted:int64)`; `2 EXP 64`] MOD_LT) THEN + ANTS_TAC THENL [ASM_SIMP_TAC[]; ALL_TAC] THEN + SIMP_TAC[] THEN DISCH_TAC THEN - ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (1--32) THEN - ABBREV_TAC `combinedPP = bytes_to_int128 - (APPEND (SUB_LIST (curr_len + 16,val (tail_len:int64)) (ct:byte list)) - (SUB_LIST (val tail_len,0x10 - val tail_len) - (int128_to_bytes (PP:int128))))` THEN - FIRST_X_ASSUM(MP_TAC o SPEC `aes256_xts_decrypt_round combinedPP - (calculate_tweak curr_blocks iv key2) key1` o MATCH_MP (MESON[] - `read (Q26:(armstate,int128)component) (s:armstate) = a ==> !a'. a = a' ==> read Q26 s = a'`)) THEN - ANTS_TAC THENL - [ EXPAND_TAC "key1" THEN - CONV_TAC (RAND_CONV ( - REWRITE_CONV [aes256_xts_decrypt_round] THENC - DEPTH_CONV let_CONV)) THEN - AESDEC_TAC; DISCH_TAC ] THEN - ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (33--33) THEN - ENSURES_FINAL_STATE_TAC THEN ASM_SIMP_TAC[] THEN - - UNDISCH_THEN `curr_len + 16 + val (tail_len:int64) = val (len:int64)` - (fun th -> SUBST1_TAC (GSYM th)) THEN - SUBGOAL_THEN `~(curr_len < 16)` ASSUME_TAC THENL - [ REWRITE_TAC[GSYM (ASSUME `acc_len num_5blocks_adjusted num_blocks_adjusted = curr_len`)] THEN - REWRITE_TAC[acc_len] THEN - COND_CASES_TAC THENL [ ARITH_TAC; ALL_TAC] THEN - COND_CASES_TAC THENL [ ARITH_TAC; ALL_TAC] THEN - COND_CASES_TAC THENL [ ARITH_TAC; ALL_TAC] THEN - COND_CASES_TAC THENL [ ARITH_TAC; ALL_TAC] THEN - UNDISCH_TAC `0x0 < val (num_5blocks_adjusted:int64)` THEN - ARITH_TAC; ALL_TAC] THEN - SUBGOAL_THEN `curr_len = 16 * curr_blocks` SUBST_ALL_TAC THENL - [ REWRITE_TAC[GSYM (ASSUME `acc_len num_5blocks_adjusted num_blocks_adjusted = curr_len`)] THEN - EXPAND_TAC "curr_blocks" THEN - REWRITE_TAC[acc_len; acc_blocks] THEN - COND_CASES_TAC THENL [SIMP_TAC[] THEN ARITH_TAC; ALL_TAC] THEN SIMP_TAC[] THEN - COND_CASES_TAC THENL [SIMP_TAC[] THEN ARITH_TAC; ALL_TAC] THEN SIMP_TAC[] THEN - COND_CASES_TAC THENL [SIMP_TAC[] THEN ARITH_TAC; ALL_TAC] THEN SIMP_TAC[] THEN - COND_CASES_TAC THENL [SIMP_TAC[] THEN ARITH_TAC; ALL_TAC] THEN SIMP_TAC[] THEN - ARITH_TAC; ALL_TAC] THEN - SUBGOAL_THEN `curr_blocks >= 1` ASSUME_TAC THENL - [ UNDISCH_TAC `~(16 * curr_blocks < 16)` THEN ARITH_TAC; ALL_TAC] THEN + MP_TAC (SPECL [`val (num_blocks_adjusted:int64)`; `0x2 EXP 0x40`; + `0x50 * val (num_5blocks_adjusted:int64)`] + (ARITH_RULE `!a b c. c <= a ==> c <= b ==> a + b - c = (a - c) + b`)) THEN + ANTS_TAC THENL [ + UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 <= val (num_blocks_adjusted:int64)` THEN + SIMP_TAC[MULT_SYM]; ALL_TAC] THEN + ANTS_TAC THENL [ + UNDISCH_TAC `0x50 * val (num_5blocks_adjusted:int64) < 2 EXP 64` THEN + ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[] THEN DISCH_TAC THEN - MATCH_MP_TAC BREAK_DATA_INTO_PARTS THEN - REPEAT CONJ_TAC THENL - [ - (* 0. Trivial *) - IMP_REWRITE_TAC[LENGTH_OF_AES256_XTS_DECRYPT] THEN ARITH_TAC; - - (* 1. Result correct up to curr_len *) - UNDISCH_TAC `forall i. - i < 16 * curr_blocks - ==> read (memory :> bytes8 (word_add (pt_ptr:int64) (word i))) s33 = - EL i (aes256_xts_decrypt (ct:byte list) (16 * curr_blocks) (iv:int128) - (key1:int128 list) (key2:int128 list))` THEN - MP_TAC (SPECL [`16 * curr_blocks:num`; `pt_ptr:int64`; - `(aes256_xts_decrypt ct (16 * curr_blocks + 0x10 + val (tail_len:int64)) iv key1 key2):byte list`; - `s33:armstate`] BYTE_LIST_TO_NUM_THM) THEN - ANTS_TAC THENL[ - IMP_REWRITE_TAC[LENGTH_OF_AES256_XTS_DECRYPT] THEN - ARITH_TAC; ALL_TAC] THEN - DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN - MP_TAC (SPECL [`16 * curr_blocks:num`; `pt_ptr:int64`; - `(aes256_xts_decrypt ct (16 * curr_blocks) iv key1 key2):byte list`; - `s33:armstate`] BYTE_LIST_TO_NUM_THM) THEN - ANTS_TAC THENL[ - REWRITE_TAC[LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS] THEN - ARITH_TAC; ALL_TAC] THEN - DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN + MP_TAC (SPECL [`1`; `0x2 EXP 0x40`; + `val (num_blocks_adjusted:int64) - 0x50 * val (num_5blocks_adjusted:int64)`] + (CONJUNCT1 (CONJUNCT2 (CONJUNCT2 MOD_MULT_ADD)))) THEN + REWRITE_TAC[ARITH_RULE `1 * 2 EXP 64 = 2 EXP 64`] THEN + SIMP_TAC[] THEN DISCH_TAC THEN + SIMP_TAC[MULT_SYM] THEN DISCH_TAC THEN + CONV_TAC NUM_REDUCE_CONV; - DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN - AP_TERM_TAC THEN - MP_TAC (SPECL [`curr_blocks:num`; `ct:byte list`; `iv:int128`; - `key1:int128 list`; `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN - REWRITE_TAC[ADD_0] THEN DISCH_TAC THEN - IMP_REWRITE_TAC[SUB_LIST_OF_AES256_XTS_DECRYPT] THEN - IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES]; - - (* 2. Last full block is correct *) - MP_TAC (SPECL [`16:num`; `(word_add pt_ptr (word (0x10 * curr_blocks))):int64`; - `(SUB_LIST (0x10 * curr_blocks,0x10 + val (tail_len:int64)) - (aes256_xts_decrypt ct (0x10 * curr_blocks + 0x10 + val tail_len) - iv key1 key2)):byte list`; - `s33:armstate`] BYTE_LIST_TO_NUM_THM) THEN - ANTS_TAC THENL[ - REWRITE_TAC[LENGTH_SUB_LIST] THEN - IMP_REWRITE_TAC[LENGTH_OF_AES256_XTS_DECRYPT] THEN - ARITH_TAC; ALL_TAC] THEN - DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN + UNDISCH_TAC `~(val (word_sub + (word_sub (num_blocks_adjusted:int64) + (word_mul (word 0x50) (num_5blocks_adjusted:int64))) + (word 0x30)) = 0x0)` THEN + REWRITE_TAC[CONTRAPOS_THM] THEN + REWRITE_TAC[VAL_WORD_SUB_EQ_0; VAL_WORD_MUL; VAL_WORD; DIMINDEX_64; + ARITH_RULE `0x30 MOD 0x2 EXP 0x40 = 0x30`] THEN + REWRITE_TAC[VAL_WORD_SUB; VAL_WORD_MUL; VAL_WORD; DIMINDEX_64; + ARITH_RULE `0x50 MOD 0x2 EXP 0x40 = 0x50`] THEN - (* Proving last full block correct *) - REWRITE_TAC[READ_MEMORY_BYTES_BYTES128] THEN - ASM_REWRITE_TAC[] THEN - REWRITE_TAC[SUB_LIST_MIN_RIGHT; MIN] THEN - SIMP_TAC[ARITH_RULE `!x. 0x10 <= 0x10 + x`] THEN - REWRITE_TAC[aes256_xts_decrypt] THEN - SIMP_TAC[ARITH_RULE `!x y. ~(x + 16 + y < 16)`] THEN - REWRITE_TAC[ARITH_RULE `0x10 * curr_blocks + 0x10 + val tail_len = - 0x10 * (curr_blocks + 1) + val tail_len`] THEN - REWRITE_TAC[MOD_MULT_ADD] THEN - ASM_SIMP_TAC[MOD_LT] THEN - REWRITE_TAC[LET_DEF; LET_END_DEF] THEN - REWRITE_TAC[ARITH_RULE - `((0x10 * (curr_blocks + 0x1) + val tail_len) - val tail_len) DIV 0x10 = - (0x10 * (curr_blocks + 0x1)) DIV 0x10`] THEN - IMP_REWRITE_TAC[DIV_MULT; ARITH_RULE `~(16 = 0)`] THEN - IMP_REWRITE_TAC[ARITH_RULE `curr_blocks >= 1 ==> ~(curr_blocks + 1 < 2)`] THEN - IMP_REWRITE_TAC[ADD_SUB; ARITH_RULE `((curr_blocks + 0x1) - 0x2) = curr_blocks - 1`] THEN - - MP_TAC (SPECL [`0:num`; `(curr_blocks - 1):num`; `ct:byte list`; `iv:int128`; - `key1:int128 list`; `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT_REC) THEN - ASM_SIMP_TAC[ARITH_RULE `curr_blocks >= 1 ==> ~(curr_blocks - 1 < 0)`] THEN - IMP_REWRITE_TAC[SUB_0; ARITH_RULE `curr_blocks >= 1 ==> curr_blocks - 1 + 1 = curr_blocks`] THEN - ONCE_REWRITE_TAC[ARITH_RULE `curr_blocks * 16 = 16 * curr_blocks`] THEN - DISCH_TAC THEN - IMP_REWRITE_TAC[SUB_LIST_APPEND_RIGHT_LEMMA] THEN + SUBGOAL_THEN `0x50 * val (num_5blocks_adjusted:int64) < 2 EXP 64` ASSUME_TAC THENL + [ UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 <= val (len:int64)` THEN + UNDISCH_TAC `val (len:int64) <= 0x2 EXP 0x18` THEN + ARITH_TAC; ALL_TAC] THEN + MP_TAC (SPECL [`0x50 * val (num_5blocks_adjusted:int64)`; `2 EXP 64`] MOD_LT) THEN + ANTS_TAC THENL [ASM_SIMP_TAC[]; ALL_TAC] THEN + SIMP_TAC[] THEN DISCH_TAC THEN - REWRITE_TAC[aes256_xts_decrypt_tail] THEN - ASM_SIMP_TAC[LET_DEF; LET_END_DEF] THEN + MP_TAC (SPECL [`val (num_blocks_adjusted:int64)`; `0x2 EXP 0x40`; + `0x50 * val (num_5blocks_adjusted:int64)`] + (ARITH_RULE `!a b c. c <= a ==> c <= b ==> a + b - c = (a - c) + b`)) THEN + ANTS_TAC THENL [ + UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 <= val (num_blocks_adjusted:int64)` THEN + SIMP_TAC[MULT_SYM]; ALL_TAC] THEN + ANTS_TAC THENL [ + UNDISCH_TAC `0x50 * val (num_5blocks_adjusted:int64) < 2 EXP 64` THEN + ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[] THEN DISCH_TAC THEN - MP_TAC (SPECL [`(SUB_LIST (curr_blocks * 0x10,0x10) ct):byte list`; - `(SUB_LIST ((curr_blocks + 0x1) * 0x10,val (tail_len:int64)) ct):byte list`; - `val (tail_len:int64)`; `iv:int128`; `curr_blocks:num`; `key1:int128 list`; - `key2:int128 list`] LENGTH_OF_FST_OF_CIPHER_STEALING) THEN - DISCH_TAC THEN - IMP_REWRITE_TAC[SUB_LIST_APPEND_LEFT; ARITH_RULE `16 <= 16`] THEN - - REWRITE_TAC[cipher_stealing; LET_DEF; LET_END_DEF] THEN - REWRITE_TAC[SUB_LIST_OF_INT128_TO_BYTES; - NUM_OF_BYTELIST_OF_INT128_TO_BYTES; CALCULATE_TWEAK_EXPAND; - ARITH_RULE `curr_blocks * 16 = 16 * curr_blocks`; - ARITH_RULE `0x10 * (curr_blocks + 0x1) = 16 * curr_blocks + 16`] THEN - EXPAND_TAC "combinedPP" THEN - EXPAND_TAC "PP" THEN - REFL_TAC; - - (* 3. Proving tail is correct *) - UNDISCH_TAC - `forall i. i < val (tail_len:int64) - ==> read (memory :> bytes8 - (word_add (word_add pt_ptr (word (0x10 * curr_blocks + 0x10))) - (word i))) s33 = - EL i (SUB_LIST (0x0,val tail_len) (int128_to_bytes PP))` THEN - MP_TAC (SPECL [`val (tail_len:int64):num`; `(word_add pt_ptr (word (0x10 * curr_blocks + 0x10))):int64`; - `(SUB_LIST (0x0,val (tail_len:int64)) (int128_to_bytes PP)):byte list`; - `s33:armstate`] BYTE_LIST_TO_NUM_THM) THEN - ANTS_TAC THENL[ - REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN - CONV_TAC NUM_REDUCE_CONV THEN - UNDISCH_TAC `val (tail_len:int64) < 0x10` THEN - ARITH_TAC; ALL_TAC] THEN - DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN - MP_TAC (SPECL [`val (tail_len:int64):num`; `(word_add pt_ptr (word (0x10 * curr_blocks + 0x10))):int64`; - `(SUB_LIST (0x10 * curr_blocks + 0x10,val (tail_len:int64)) - (aes256_xts_decrypt ct (0x10 * curr_blocks + 0x10 + val tail_len) iv key1 key2)):byte list`; - `s33:armstate`] BYTE_LIST_TO_NUM_THM) THEN - ANTS_TAC THENL[ - REWRITE_TAC[LENGTH_SUB_LIST] THEN - IMP_REWRITE_TAC[LENGTH_OF_AES256_XTS_DECRYPT] THEN - ARITH_TAC; ALL_TAC] THEN - DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN + MP_TAC (SPECL [`1`; `0x2 EXP 0x40`; + `val (num_blocks_adjusted:int64) - 0x50 * val (num_5blocks_adjusted:int64)`] + (CONJUNCT1 (CONJUNCT2 (CONJUNCT2 MOD_MULT_ADD)))) THEN + REWRITE_TAC[ARITH_RULE `1 * 2 EXP 64 = 2 EXP 64`] THEN + SIMP_TAC[] THEN DISCH_TAC THEN + SIMP_TAC[MULT_SYM] THEN DISCH_TAC THEN + CONV_TAC NUM_REDUCE_CONV; - DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN - AP_TERM_TAC THEN - REWRITE_TAC[SUB_LIST_IDEMPOTENT] THEN - REWRITE_TAC[SUB_LIST_MIN_RIGHT; MIN; LE_REFL] THEN - - REWRITE_TAC[aes256_xts_decrypt; - ARITH_RULE `~(0x10 * curr_blocks + 0x10 + val (tail_len:int64) < 0x10)`] THEN - REWRITE_TAC[ARITH_RULE `0x10 * curr_blocks + 0x10 + val tail_len = - 0x10 * (curr_blocks + 1) + val tail_len`] THEN - REWRITE_TAC[MOD_MULT_ADD] THEN - ASM_SIMP_TAC[MOD_LT] THEN - REWRITE_TAC[LET_DEF; LET_END_DEF] THEN - REWRITE_TAC[ARITH_RULE - `((0x10 * (curr_blocks + 0x1) + val tail_len) - val tail_len) DIV 0x10 = - (0x10 * (curr_blocks + 0x1)) DIV 0x10`] THEN - IMP_REWRITE_TAC[DIV_MULT; ARITH_RULE `~(16 = 0)`] THEN - IMP_REWRITE_TAC[ARITH_RULE `curr_blocks >= 1 ==> ~(curr_blocks + 1 < 2)`] THEN - IMP_REWRITE_TAC[ADD_SUB; ARITH_RULE `((curr_blocks + 0x1) - 0x2) = curr_blocks - 1`] THEN - - MP_TAC (ISPECL [`(aes256_xts_decrypt_rec 0x0 (curr_blocks - 0x1) ct iv key1 key2):byte list`; - `(aes256_xts_decrypt_tail curr_blocks (val (tail_len:int64)) ct iv key1 key2):byte list`; - `0x10 * curr_blocks + 0x10:num`; `val (tail_len:int64)`; `0x10 * curr_blocks:num` - ] SUB_LIST_APPEND_RIGHT_GENERAL) THEN - ANTS_TAC THENL - [ REWRITE_TAC[LENGTH_OF_AES256_XTS_DECRYPT_REC] THEN - UNDISCH_TAC `curr_blocks >= 1` THEN - ARITH_TAC; ALL_TAC] THEN - ANTS_TAC THENL [ ARITH_TAC; ALL_TAC] THEN - DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN + UNDISCH_TAC `~(val (word_sub + (word_sub (num_blocks_adjusted:int64) + (word_mul (word 0x50) (num_5blocks_adjusted:int64))) + (word 0x40)) = 0x0)` THEN + REWRITE_TAC[CONTRAPOS_THM] THEN + REWRITE_TAC[VAL_WORD_SUB_EQ_0; VAL_WORD_MUL; VAL_WORD; DIMINDEX_64; + ARITH_RULE `0x40 MOD 0x2 EXP 0x40 = 0x40`] THEN + REWRITE_TAC[VAL_WORD_SUB; VAL_WORD_MUL; VAL_WORD; DIMINDEX_64; + ARITH_RULE `0x50 MOD 0x2 EXP 0x40 = 0x50`] THEN - REWRITE_TAC[ARITH_RULE `(0x10 * curr_blocks + 0x10) - 0x10 * curr_blocks = 0x10`] THEN - REWRITE_TAC[aes256_xts_decrypt_tail] THEN - ASM_SIMP_TAC[LET_DEF; LET_END_DEF] THEN + SUBGOAL_THEN `0x50 * val (num_5blocks_adjusted:int64) < 2 EXP 64` ASSUME_TAC THENL + [ UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 <= val (len:int64)` THEN + UNDISCH_TAC `val (len:int64) <= 0x2 EXP 0x18` THEN + ARITH_TAC; ALL_TAC] THEN + MP_TAC (SPECL [`0x50 * val (num_5blocks_adjusted:int64)`; `2 EXP 64`] MOD_LT) THEN + ANTS_TAC THENL [ASM_SIMP_TAC[]; ALL_TAC] THEN + SIMP_TAC[] THEN DISCH_TAC THEN - MP_TAC (SPECL [`(SUB_LIST (curr_blocks * 0x10,0x10) ct):byte list`; - `(SUB_LIST ((curr_blocks + 0x1) * 0x10,val (tail_len:int64)) ct):byte list`; - `val (tail_len:int64)`; `iv:int128`; `curr_blocks:num`; `key1:int128 list`; - `key2:int128 list`] LENGTH_OF_FST_OF_CIPHER_STEALING) THEN - DISCH_TAC THEN - IMP_REWRITE_TAC[SUB_LIST_APPEND_RIGHT_LEMMA; ARITH_RULE `16 <= 16`] THEN + MP_TAC (SPECL [`val (num_blocks_adjusted:int64)`; `0x2 EXP 0x40`; + `0x50 * val (num_5blocks_adjusted:int64)`] + (ARITH_RULE `!a b c. c <= a ==> c <= b ==> a + b - c = (a - c) + b`)) THEN + ANTS_TAC THENL [ + UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 <= val (num_blocks_adjusted:int64)` THEN + SIMP_TAC[MULT_SYM]; ALL_TAC] THEN + ANTS_TAC THENL [ + UNDISCH_TAC `0x50 * val (num_5blocks_adjusted:int64) < 2 EXP 64` THEN + ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[] THEN DISCH_TAC THEN + + MP_TAC (SPECL [`1`; `0x2 EXP 0x40`; + `val (num_blocks_adjusted:int64) - 0x50 * val (num_5blocks_adjusted:int64)`] + (CONJUNCT1 (CONJUNCT2 (CONJUNCT2 MOD_MULT_ADD)))) THEN + REWRITE_TAC[ARITH_RULE `1 * 2 EXP 64 = 2 EXP 64`] THEN + SIMP_TAC[] THEN DISCH_TAC THEN + SIMP_TAC[MULT_SYM] THEN DISCH_TAC THEN + CONV_TAC NUM_REDUCE_CONV + ] + ; ALL_TAC] THEN + + SUBGOAL_THEN `~(val (num_5blocks_adjusted:int64) * 0x50 + 0x40 = val (num_blocks_adjusted:int64))` ASSUME_TAC THENL + [ UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 = val (num_blocks_adjusted:int64)` THEN + ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `~(val (num_5blocks_adjusted:int64) * 0x50 + 0x30 = val (num_blocks_adjusted:int64))` ASSUME_TAC THENL + [ UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 = val (num_blocks_adjusted:int64)` THEN + ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `~(val (num_5blocks_adjusted:int64) * 0x50 + 0x20 = val (num_blocks_adjusted:int64))` ASSUME_TAC THENL + [ UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 = val (num_blocks_adjusted:int64)` THEN + ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `~(val (num_5blocks_adjusted:int64) * 0x50 + 0x10 = val (num_blocks_adjusted:int64))` ASSUME_TAC THENL + [ UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 = val (num_blocks_adjusted:int64)` THEN + ARITH_TAC; ALL_TAC] THEN - REWRITE_TAC[cipher_stealing; LET_DEF; LET_END_DEF; SUB_LIST_IDEMPOTENT] THEN - EXPAND_TAC "PP" THEN - REWRITE_TAC[ARITH_RULE `curr_blocks * 0x10 = 0x10 * curr_blocks`; - CALCULATE_TWEAK_EXPAND] + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (10--10) THEN + ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN + REPEAT CONJ_TAC THENL + [ + REWRITE_TAC[acc_len] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; + REWRITE_TAC[acc_len] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; + REWRITE_TAC[acc_blocks] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; + REWRITE_TAC[acc_blocks] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; + REWRITE_TAC[acc_blocks] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; + REWRITE_TAC[acc_len] THEN ASM_SIMP_TAC[LE_REFL] ] - ] + ] (* End of loop invariant proof *) + ; ALL_TAC] THEN + + MP_TAC CIPHER_STEALING_CORRECT THEN + REWRITE_TAC [(REWRITE_CONV [aes_xts_decrypt_mc] THENC LENGTH_CONV) `LENGTH aes_xts_decrypt_mc`] THEN + REWRITE_TAC[set_key_schedule; C_ARGUMENTS; SOME_FLAGS; + NONOVERLAPPING_CLAUSES; byte_list_at; + MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI] THEN + DISCH_THEN MATCH_MP_TAC THEN + ASM_SIMP_TAC[] );; From cc979524fdb605001d957d33261d5128b61ef692 Mon Sep 17 00:00:00 2001 From: Yan Peng Date: Wed, 22 Oct 2025 14:53:50 -0700 Subject: [PATCH 051/132] Finished: bounded proofs --- arm/proofs/aes_xts_decrypt.ml | 2035 ++++++++++++++++++++++++++++++--- 1 file changed, 1888 insertions(+), 147 deletions(-) diff --git a/arm/proofs/aes_xts_decrypt.ml b/arm/proofs/aes_xts_decrypt.ml index ccdf69689..2e22a9dc0 100644 --- a/arm/proofs/aes_xts_decrypt.ml +++ b/arm/proofs/aes_xts_decrypt.ml @@ -4,8 +4,8 @@ *) use_file_raise_failure := true;; -arm_print_log := true;; -components_print_log := true;; +arm_print_log := false;; +components_print_log := false;; needs "arm/proofs/base.ml";; loadt "arm/proofs/aes_xts_decrypt_spec.ml";; @@ -864,7 +864,7 @@ let XTSDEC_TAC reg ind ind_tweak = AESDEC_TAC; DISCH_TAC ];; (** Proof **) - +(* let AES_XTS_DECRYPT_1BLOCK_CORRECT = prove( `!ct_ptr pt_ptr key0_ptr key1_ptr iv_ptr ib iv (k00:int128) k01 k02 k03 k04 k05 k06 k07 k08 k09 k0a k0b k0c k0d k0e @@ -922,7 +922,7 @@ let AES_XTS_DECRYPT_1BLOCK_CORRECT = prove( ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (127--137) THEN ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC [] );; - +*) (*******************************************) (* Full proof *) @@ -1418,6 +1418,12 @@ let NUM_BLOCKS_LO_BOUND_THM = prove( ==> ~(val num_blocks < 0x60)`, BITBLAST_TAC);; +let NUM_BLOCKS_LO_BOUND_1BLOCK_THM = prove( + `!(len:int64) num_blocks. word_and len (word 0xfffffffffffffff0) = num_blocks + ==> ~(val len < 16) + ==> ~(val num_blocks < 16)`, + BITBLAST_TAC);; + let NUM_BLOCKS_HI_BOUND_THM = prove( `!(len:int64) num_blocks. word_and len (word 0xfffffffffffffff0) = num_blocks ==> val len <= 2 EXP 24 @@ -1437,11 +1443,19 @@ let NUM_BLOCKS_ADJUSTED_LO_BOUND_THM = prove( BITBLAST_TAC );; +let NUM_BLOCKS_ADJUSTED_LO_BOUND_1BLOCK_THM = prove( + `!(num_blocks:int64) (tail_len:int64) num_blocks_adjusted. + (if val tail_len = 0x0 then num_blocks else word_sub num_blocks (word 0x10)) = num_blocks_adjusted + ==> ~(val num_blocks < 16) + ==> ~(val num_blocks_adjusted < 0)`, + BITBLAST_TAC +);; + let NUM_BLOCKS_ADJUSTED_HI_BOUND_THM = prove( `!(num_blocks:int64) (tail_len:int64) num_blocks_adjusted. (if val tail_len = 0x0 then num_blocks else word_sub num_blocks (word 0x10)) = num_blocks_adjusted ==> val num_blocks <= 2 EXP 24 - ==> ~(val num_blocks < 0x60) + ==> ~(val num_blocks < 16) ==> val num_blocks_adjusted <= 2 EXP 24`, BITBLAST_TAC );; @@ -1471,7 +1485,7 @@ let NUM_BLOCKS_LT_LEN_THM = prove( let NUM_BLOCKS_ADJUSTED_LT_LEN_THM = prove( `!(len:int64) num_blocks. word_and len (word 0xfffffffffffffff0) = num_blocks - ==> ~(val num_blocks < 0x60) + ==> ~(val num_blocks < 16) ==> val (word_sub num_blocks (word 0x10)) <= val len`, BITBLAST_TAC );; @@ -3105,7 +3119,6 @@ let BOUND_OF_ACC_LEN = prove( ASM_ARITH_TAC );; -(* For X9 and X10, they stand for i * 0x5 + 4 when number of blocks is divisible by 5 *) let acc_blocks = new_definition `acc_blocks (i:int64) (len:int64) (last:bool) : num = if val i * 0x50 + 0x40 = val len then val i * 0x5 + 4 @@ -3115,8 +3128,7 @@ let acc_blocks = new_definition if val i * 0x50 + 0x20 = val len then val i * 0x5 + 2 else if val i * 0x50 + 0x10 = val len then val i * 0x5 + 1 - else - if last then val i * 0x5 else val i * 0x5 + 4`;; + else val i * 0x5`;; let cipher_stealing_inv = new_definition `cipher_stealing_inv (i:num) (curr_len:num) (tail_len:num) (PP:int128) (ct:byte list): int128 = @@ -3468,13 +3480,14 @@ let BREAK_DATA_INTO_PARTS = prove( ASM_ARITH_TAC );; +(* ************************************** *) (* Assembly proofs *) +(* Proof: Cipher stealing *) let CIPHER_STEALING_CORRECT = time prove( - `!ct_ptr pt_ptr ct key1_ptr iv len + `!ct_ptr pt_ptr ct key1_ptr iv len pc k00 k01 k02 k03 k04 k05 k06 k07 k08 k09 k0a k0b k0c k0d k0e - k10 k11 k12 k13 k14 k15 k16 k17 k18 k19 k1a k1b k1c k1d k1e - pc. + tail_len num_blocks key1 num_blocks_adjusted num_5blocks_adjusted. nonoverlapping (word pc, LENGTH aes_xts_decrypt_mc) (pt_ptr, val len) /\ nonoverlapping (ct_ptr, val len) (pt_ptr, val len) /\ nonoverlapping (key1_ptr, 260) (pt_ptr, val len) @@ -3483,19 +3496,8 @@ let CIPHER_STEALING_CORRECT = time prove( /\ word_and len (word 0xfffffffffffffff0) = num_blocks /\ word_and len (word 0xf) = tail_len /\ [k00; k01; k02; k03; k04; k05; k06; k07; k08; k09; k0a; k0b; k0c; k0d; k0e] = key1 - /\ ~(val len < 0x60) /\ (if val tail_len = 0x0 then num_blocks else word_sub num_blocks (word 0x10)) = num_blocks_adjusted /\ word (val num_blocks_adjusted DIV 0x50) = num_5blocks_adjusted - /\ ~(val num_blocks < 0x60) - /\ val num_blocks <= 0x2 EXP 0x18 - /\ ~(val num_blocks_adjusted < 0x50) - /\ val num_blocks_adjusted <= 0x2 EXP 0x18 - /\ 0x0 < val num_5blocks_adjusted - /\ val tail_len < 0x10 - /\ val num_blocks <= val len - /\ val num_blocks_adjusted <= val len - /\ val num_5blocks_adjusted * 0x50 <= val num_blocks_adjusted - /\ val num_5blocks_adjusted * 0x50 <= val len ==> ensures arm (\s. aligned_bytes_loaded s (word pc) aes_xts_decrypt_mc /\ read PC s = word (pc + 0xa0c) /\ @@ -3505,8 +3507,6 @@ let CIPHER_STEALING_CORRECT = time prove( read X21 s = tail_len /\ read Q6 s = calculate_tweak (acc_blocks num_5blocks_adjusted num_blocks_adjusted T) iv key2 /\ read X19 s = word 0x87 /\ - read X10 s = word_subword (calculate_tweak (acc_blocks num_5blocks_adjusted num_blocks_adjusted F) iv key2) (64,64) /\ - read X9 s = word_zx (calculate_tweak (acc_blocks num_5blocks_adjusted num_blocks_adjusted F) iv key2) /\ read Q16 s = k00 /\ read Q17 s = k01 /\ read Q12 s = k02 /\ read Q13 s = k03 /\ read Q14 s = k04 /\ read Q15 s = k05 /\ read Q4 s = k06 /\ read Q5 s = k07 /\ read Q18 s = k08 /\ read Q19 s = k09 /\ read Q20 s = k0a /\ read Q21 s = k0b /\ @@ -3528,6 +3528,69 @@ let CIPHER_STEALING_CORRECT = time prove( MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI] THEN REPEAT STRIP_TAC THEN + (* Prove once and for all the bounds for num_blocks, num_blocks_adjusted + and num_5blocks_adjusted *) + SUBGOAL_THEN `~(val (num_blocks:int64) < 16)` ASSUME_TAC THENL + [ SUBGOAL_THEN `~(val (len:int64) < 16)` MP_TAC THENL + [ASM_ARITH_TAC; ALL_TAC] THEN + UNDISCH_TAC `word_and len (word 0xfffffffffffffff0) = (num_blocks:int64)` THEN + MP_TAC (SPECL [`len:int64`; `num_blocks:int64`] NUM_BLOCKS_LO_BOUND_1BLOCK_THM) THEN + SIMP_TAC[]; ALL_TAC] THEN + SUBGOAL_THEN `val (num_blocks:int64) <= 2 EXP 24` ASSUME_TAC THENL + [ UNDISCH_TAC `val (len:int64) <= 2 EXP 24` THEN + UNDISCH_TAC `word_and len (word 0xfffffffffffffff0) = (num_blocks:int64)` THEN + MP_TAC (SPECL [`len:int64`; `num_blocks:int64`] NUM_BLOCKS_HI_BOUND_THM) THEN + SIMP_TAC[]; ALL_TAC] THEN + SUBGOAL_THEN `~(val (num_blocks_adjusted:int64) < 0)` ASSUME_TAC THENL + [ UNDISCH_TAC `~(val (num_blocks:int64) < 16)` THEN + UNDISCH_TAC `(if val (tail_len:int64) = 0x0 + then (num_blocks:int64) + else word_sub num_blocks (word 0x10)) = + num_blocks_adjusted` THEN + MP_TAC (SPECL [`num_blocks:int64`;`tail_len:int64`;`num_blocks_adjusted:int64`] + NUM_BLOCKS_ADJUSTED_LO_BOUND_1BLOCK_THM) THEN SIMP_TAC[] + ; ALL_TAC] THEN + SUBGOAL_THEN `val (num_blocks_adjusted:int64) <= 2 EXP 24` ASSUME_TAC THENL + [ UNDISCH_TAC `val (num_blocks:int64) <= 2 EXP 24` THEN + UNDISCH_TAC `~(val (num_blocks:int64) < 16)` THEN + UNDISCH_TAC `(if val (tail_len:int64) = 0x0 + then (num_blocks:int64) + else word_sub num_blocks (word 0x10)) = + num_blocks_adjusted` THEN + MP_TAC (SPECL [`num_blocks:int64`;`tail_len:int64`;`num_blocks_adjusted:int64`] + NUM_BLOCKS_ADJUSTED_HI_BOUND_THM) THEN SIMP_TAC[] + ; ALL_TAC] THEN + SUBGOAL_THEN `val (tail_len:int64) < 16` ASSUME_TAC THENL + [ EXPAND_TAC "tail_len" THEN + REWRITE_TAC[ARITH_RULE `0xf = 2 EXP 4 - 1`] THEN + REWRITE_TAC[VAL_WORD_AND_MASK_WORD] THEN + CONV_TAC NUM_REDUCE_CONV THEN + SIMP_TAC[MOD_LT_EQ] THEN + CONV_TAC NUM_REDUCE_CONV + ; ALL_TAC] THEN + (* relationship between variables *) + SUBGOAL_THEN `val (num_blocks:int64) <= val (len:int64)` ASSUME_TAC THENL + [ EXPAND_TAC "num_blocks" THEN SIMP_TAC[NUM_BLOCKS_LT_LEN_THM]; ALL_TAC] THEN + SUBGOAL_THEN `val (num_blocks_adjusted:int64) <= val (len:int64)` ASSUME_TAC THENL + [ EXPAND_TAC "num_blocks_adjusted" THEN + COND_CASES_TAC THENL + [ ASM_SIMP_TAC[]; + UNDISCH_TAC `~(val (num_blocks:int64) < 16)` THEN + UNDISCH_TAC `word_and (len:int64) (word 0xfffffffffffffff0) = (num_blocks:int64)` THEN + MP_TAC (SPECL [`len:int64`; `num_blocks:int64`] NUM_BLOCKS_ADJUSTED_LT_LEN_THM) THEN + SIMP_TAC[]]; ALL_TAC] THEN + SUBGOAL_THEN `val (num_5blocks_adjusted:int64) * 0x50 <= val (num_blocks_adjusted:int64)` ASSUME_TAC THENL + [ EXPAND_TAC "num_5blocks_adjusted" THEN + REWRITE_TAC [VAL_WORD; DIMINDEX_64] THEN + UNDISCH_TAC `val (num_blocks_adjusted:int64) <= 0x2 EXP 0x18` THEN + ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `val (num_5blocks_adjusted:int64) * 0x50 <= val (len:int64)` ASSUME_TAC THENL + [ EXPAND_TAC "num_5blocks_adjusted" THEN + REWRITE_TAC [VAL_WORD; DIMINDEX_64] THEN + UNDISCH_TAC `val (num_blocks_adjusted:int64) <= 0x2 EXP 0x18` THEN + UNDISCH_TAC `val (num_blocks_adjusted:int64) <= val (len:int64)` THEN + ARITH_TAC; ALL_TAC] THEN + (* Prove more properties about num_blocks_adjusted and num_5blocks_adjusted *) SUBGOAL_THEN `val (num_blocks_adjusted:int64) DIV 0x50 = val (num_5blocks_adjusted:int64)` ASSUME_TAC THENL [ EXPAND_TAC "num_5blocks_adjusted" THEN @@ -3540,12 +3603,12 @@ let CIPHER_STEALING_CORRECT = time prove( COND_CASES_TAC THENL [ REWRITE_TAC[NUM_BLOCKS_TO_VAL] THEN IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT; DIVIDES_RMUL; DIVIDES_REFL] THEN - UNDISCH_TAC `val (len:int64) <= 0x2 EXP 0x18` THEN + MP_TAC (SPEC `len:int64` VAL_BOUND_64) THEN ARITH_TAC; IMP_REWRITE_TAC[NUM_BLOCKS_MINUS1_TO_VAL] THEN IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT; DIVIDES_RMUL; DIVIDES_REFL] THEN - UNDISCH_TAC `val (len:int64) <= 0x2 EXP 0x18` THEN + MP_TAC (SPEC `len:int64` VAL_BOUND_64) THEN ARITH_TAC]; ALL_TAC] THEN (* If no tail, execute to the end *) @@ -3622,15 +3685,16 @@ let CIPHER_STEALING_CORRECT = time prove( ABBREV_TAC `curr_blocks = (acc_blocks (num_5blocks_adjusted:int64) (num_blocks_adjusted:int64) T):num` THEN SUBGOAL_THEN `curr_len + 0x10 <= val (len:int64)` ASSUME_TAC THENL - [ EXPAND_TAC "curr_len" THEN - MP_TAC (SPECL [`num_5blocks_adjusted:int64`; `num_blocks_adjusted:int64`] VALUE_OF_ACC_LEN) THEN - REPEAT_N 3 (ANTS_TAC THENL [ASM_ARITH_TAC ORELSE ASM_SIMP_TAC[]; ALL_TAC]) THEN - SIMP_TAC[] THEN DISCH_TAC THEN - EXPAND_TAC "num_blocks_adjusted" THEN - SIMP_TAC[ASSUME `~(val (tail_len:int64) = 0)`] THEN - UNDISCH_TAC `val (num_blocks:int64) <= val (len:int64)` THEN - UNDISCH_TAC `~(val (num_blocks:int64) < 0x60)` THEN - WORD_ARITH_TAC; ALL_TAC] THEN + [ EXPAND_TAC "curr_len" THEN + MP_TAC (SPECL [`num_5blocks_adjusted:int64`; `num_blocks_adjusted:int64`] VALUE_OF_ACC_LEN) THEN + REPEAT_N 3 (ANTS_TAC THENL [ASM_ARITH_TAC ORELSE ASM_SIMP_TAC[]; ALL_TAC]) THEN + SIMP_TAC[] THEN DISCH_TAC THEN + EXPAND_TAC "num_blocks_adjusted" THEN + SIMP_TAC[ASSUME `~(val (tail_len:int64) = 0)`] THEN + UNDISCH_TAC `val (num_blocks:int64) <= val (len:int64)` THEN + SUBGOAL_THEN `val (num_blocks:int64) >= 16` MP_TAC THENL + [ASM_ARITH_TAC; ALL_TAC] THEN + WORD_ARITH_TAC; ALL_TAC] THEN SUBGOAL_THEN `val ((word curr_len):int64) = curr_len` ASSUME_TAC THENL [ IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN EXPAND_TAC "curr_len" THEN @@ -3849,7 +3913,7 @@ let CIPHER_STEALING_CORRECT = time prove( EXPAND_TAC "len" THEN IMP_REWRITE_TAC[VAL_WORD_ADD; DIMINDEX_64; MOD_LT] THEN UNDISCH_TAC `val (num_blocks:int64) <= val (len:int64)` THEN - UNDISCH_TAC `~(val (num_blocks:int64) < 0x60)` THEN + UNDISCH_TAC `~(val (num_blocks:int64) < 16)` THEN UNDISCH_TAC `val (num_blocks:int64) <= 0x2 EXP 0x18` THEN UNDISCH_TAC `i < val (tail_len:int64)` THEN UNDISCH_TAC `val (tail_len:int64) < 0x10` THEN @@ -4026,15 +4090,6 @@ let CIPHER_STEALING_CORRECT = time prove( UNDISCH_THEN `curr_len + 16 + val (tail_len:int64) = val (len:int64)` (fun th -> SUBST1_TAC (GSYM th)) THEN - SUBGOAL_THEN `~(curr_len < 16)` ASSUME_TAC THENL - [ REWRITE_TAC[GSYM (ASSUME `acc_len num_5blocks_adjusted num_blocks_adjusted = curr_len`)] THEN - REWRITE_TAC[acc_len] THEN - COND_CASES_TAC THENL [ ARITH_TAC; ALL_TAC] THEN - COND_CASES_TAC THENL [ ARITH_TAC; ALL_TAC] THEN - COND_CASES_TAC THENL [ ARITH_TAC; ALL_TAC] THEN - COND_CASES_TAC THENL [ ARITH_TAC; ALL_TAC] THEN - UNDISCH_TAC `0x0 < val (num_5blocks_adjusted:int64)` THEN - ARITH_TAC; ALL_TAC] THEN SUBGOAL_THEN `curr_len = 16 * curr_blocks` SUBST_ALL_TAC THENL [ REWRITE_TAC[GSYM (ASSUME `acc_len num_5blocks_adjusted num_blocks_adjusted = curr_len`)] THEN EXPAND_TAC "curr_blocks" THEN @@ -4044,8 +4099,6 @@ let CIPHER_STEALING_CORRECT = time prove( COND_CASES_TAC THENL [SIMP_TAC[] THEN ARITH_TAC; ALL_TAC] THEN SIMP_TAC[] THEN COND_CASES_TAC THENL [SIMP_TAC[] THEN ARITH_TAC; ALL_TAC] THEN SIMP_TAC[] THEN ARITH_TAC; ALL_TAC] THEN - SUBGOAL_THEN `curr_blocks >= 1` ASSUME_TAC THENL - [ UNDISCH_TAC `~(16 * curr_blocks < 16)` THEN ARITH_TAC; ALL_TAC] THEN MATCH_MP_TAC BREAK_DATA_INTO_PARTS THEN REPEAT CONJ_TAC THENL @@ -4110,7 +4163,33 @@ let CIPHER_STEALING_CORRECT = time prove( `((0x10 * (curr_blocks + 0x1) + val tail_len) - val tail_len) DIV 0x10 = (0x10 * (curr_blocks + 0x1)) DIV 0x10`] THEN IMP_REWRITE_TAC[DIV_MULT; ARITH_RULE `~(16 = 0)`] THEN - IMP_REWRITE_TAC[ARITH_RULE `curr_blocks >= 1 ==> ~(curr_blocks + 1 < 2)`] THEN + COND_CASES_TAC THENL + [ + SUBGOAL_THEN `curr_blocks = 0` SUBST_ALL_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN + EXPAND_TAC "combinedPP" THEN + REWRITE_TAC[aes256_xts_decrypt_tail] THEN + ASM_SIMP_TAC[LET_DEF; LET_END_DEF] THEN + CONV_TAC NUM_REDUCE_CONV THEN + + MP_TAC (SPECL [`(SUB_LIST (0,0x10) ct):byte list`; + `(SUB_LIST (0x10,val (tail_len:int64)) ct):byte list`; + `val (tail_len:int64)`; `iv:int128`; `0:num`; `key1:int128 list`; + `key2:int128 list`] LENGTH_OF_FST_OF_CIPHER_STEALING) THEN + DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_APPEND_LEFT; ARITH_RULE `16 <= 16`] THEN + + REWRITE_TAC[cipher_stealing; LET_DEF; LET_END_DEF] THEN + REWRITE_TAC[SUB_LIST_OF_INT128_TO_BYTES; + NUM_OF_BYTELIST_OF_INT128_TO_BYTES; CALCULATE_TWEAK_EXPAND] THEN + EXPAND_TAC "combinedPP" THEN + EXPAND_TAC "PP" THEN + CONV_TAC NUM_REDUCE_CONV; + ALL_TAC + ] THEN + + SUBGOAL_THEN `curr_blocks >= 1` ASSUME_TAC THENL + [ UNDISCH_TAC `~(curr_blocks + 0x1 < 0x2)` THEN ARITH_TAC; ALL_TAC] THEN + IMP_REWRITE_TAC[ADD_SUB; ARITH_RULE `((curr_blocks + 0x1) - 0x2) = curr_blocks - 1`] THEN MP_TAC (SPECL [`0:num`; `(curr_blocks - 1):num`; `ct:byte list`; `iv:int128`; @@ -4144,8 +4223,8 @@ let CIPHER_STEALING_CORRECT = time prove( UNDISCH_TAC `forall i. i < val (tail_len:int64) ==> read (memory :> bytes8 - (word_add (word_add pt_ptr (word (0x10 * curr_blocks + 0x10))) - (word i))) s33 = + (word_add (word_add pt_ptr (word (0x10 * curr_blocks + 0x10))) + (word i))) s33 = EL i (SUB_LIST (0x0,val tail_len) (int128_to_bytes PP))` THEN MP_TAC (SPECL [`val (tail_len:int64):num`; `(word_add pt_ptr (word (0x10 * curr_blocks + 0x10))):int64`; `(SUB_LIST (0x0,val (tail_len:int64)) (int128_to_bytes PP)):byte list`; @@ -4180,9 +4259,32 @@ let CIPHER_STEALING_CORRECT = time prove( REWRITE_TAC[LET_DEF; LET_END_DEF] THEN REWRITE_TAC[ARITH_RULE `((0x10 * (curr_blocks + 0x1) + val tail_len) - val tail_len) DIV 0x10 = - (0x10 * (curr_blocks + 0x1)) DIV 0x10`] THEN + (0x10 * (curr_blocks + 0x1)) DIV 0x10`] THEN IMP_REWRITE_TAC[DIV_MULT; ARITH_RULE `~(16 = 0)`] THEN - IMP_REWRITE_TAC[ARITH_RULE `curr_blocks >= 1 ==> ~(curr_blocks + 1 < 2)`] THEN + COND_CASES_TAC THENL + [ + SUBGOAL_THEN `curr_blocks = 0` SUBST_ALL_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN + REWRITE_TAC[aes256_xts_decrypt_tail] THEN + ASM_SIMP_TAC[LET_DEF; LET_END_DEF] THEN + CONV_TAC NUM_REDUCE_CONV THEN + + MP_TAC (SPECL [`(SUB_LIST (0,0x10) ct):byte list`; + `(SUB_LIST (0x10,val (tail_len:int64)) ct):byte list`; + `val (tail_len:int64)`; `iv:int128`; `0:num`; `key1:int128 list`; + `key2:int128 list`] LENGTH_OF_FST_OF_CIPHER_STEALING) THEN + DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_APPEND_RIGHT_LEMMA; ARITH_RULE `16 <= 16`] THEN + + REWRITE_TAC[cipher_stealing; LET_DEF; LET_END_DEF; SUB_LIST_IDEMPOTENT] THEN + EXPAND_TAC "PP" THEN + REWRITE_TAC[CALCULATE_TWEAK_EXPAND] THEN + CONV_TAC NUM_REDUCE_CONV; + ALL_TAC + ] THEN + + SUBGOAL_THEN `curr_blocks >= 1` ASSUME_TAC THENL + [ UNDISCH_TAC `~(curr_blocks + 0x1 < 0x2)` THEN ARITH_TAC; ALL_TAC] THEN + IMP_REWRITE_TAC[ADD_SUB; ARITH_RULE `((curr_blocks + 0x1) - 0x2) = curr_blocks - 1`] THEN MP_TAC (ISPECL [`(aes256_xts_decrypt_rec 0x0 (curr_blocks - 0x1) ct iv key1 key2):byte list`; @@ -4211,41 +4313,371 @@ let CIPHER_STEALING_CORRECT = time prove( EXPAND_TAC "PP" THEN REWRITE_TAC[ARITH_RULE `curr_blocks * 0x10 = 0x10 * curr_blocks`; CALCULATE_TWEAK_EXPAND] - ] + ] ] );; +let READ_LT_2BLOCK = prove( + `!(ptr:int64) (len:int64) (bl:byte list) (s:armstate). + LENGTH bl = val len ==> + val len >= 0x10 ==> + val len < 0x20 ==> + (forall i. i < val len + ==> read (memory :> bytes8 (word_add ptr (word i))) s = EL i bl) + ==> read (memory :> bytes128 ptr) s = bytes_to_int128 (SUB_LIST (0, 16) bl)`, + REPEAT STRIP_TAC THEN + MP_TAC (SPECL [`0:num`; `bl:byte list`; `ptr:int64`; + `len:int64`; `s:armstate`] BYTE_LIST_AT_1BLOCKS) THEN + REWRITE_TAC[byte_list_at] THEN + ANTS_TAC THENL[ ASM_SIMP_TAC[]; ALL_TAC] THEN + ANTS_TAC THENL[ ASM_SIMP_TAC[]; ALL_TAC] THEN + ANTS_TAC THENL[ ASM_ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[WORD_ADD_0] +);; -let AES_XTS_DECRYPT_EQ_1BLOCK_CORRECT = time prove( - `!ct_ptr pt_ptr ct key1_ptr key2_ptr iv_ptr iv len - k00 k01 k02 k03 k04 k05 k06 k07 k08 k09 k0a k0b k0c k0d k0e - k10 k11 k12 k13 k14 k15 k16 k17 k18 k19 k1a k1b k1c k1d k1e - pc. - nonoverlapping (word pc, LENGTH aes_xts_decrypt_mc) (pt_ptr, val len) - /\ nonoverlapping (ct_ptr, val len) (pt_ptr, val len) - /\ nonoverlapping (key1_ptr, 260) (pt_ptr, val len) - /\ val len = 16 /\ LENGTH ct = val len - /\ [k00; k01; k02; k03; k04; k05; k06; k07; k08; k09; k0a; k0b; k0c; k0d; k0e] = key1 - /\ [k10; k11; k12; k13; k14; k15; k16; k17; k18; k19; k1a; k1b; k1c; k1d; k1e] = key2 - ==> ensures arm - (\s. aligned_bytes_loaded s (word pc) aes_xts_decrypt_mc /\ - read PC s = word (pc + 0x1c) /\ - C_ARGUMENTS [ct_ptr; pt_ptr; len; key1_ptr; key2_ptr; iv_ptr] s /\ - byte_list_at ct ct_ptr len s /\ - read(memory :> bytes128 iv_ptr) s = iv /\ - set_key_schedule s key1_ptr k00 k01 k02 k03 k04 k05 k06 k07 k08 k09 k0a k0b k0c k0d k0e /\ - set_key_schedule s key2_ptr k10 k11 k12 k13 k14 k15 k16 k17 k18 k19 k1a k1b k1c k1d k1e) - (\s. read PC s = word (pc + 0xb58) /\ - byte_list_at (aes256_xts_decrypt ct (val len) iv key1 key2) pt_ptr len s - ) - (MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI,, - MAYCHANGE [X19; X20; X21; X22],, - MAYCHANGE [Q8; Q9; Q10; Q11; Q12; Q13; Q14; Q15],, - MAYCHANGE [memory :> bytes(pt_ptr, val len)]) - `, - CHEAT_TAC);; +let READ_LT_3BLOCK = prove( + `!(ptr:int64) (len:int64) (bl:byte list) (s:armstate). + LENGTH bl = val len ==> + ~(val len < 0x20) ==> + val len < 0x30 ==> + (forall i. i < val len + ==> read (memory :> bytes8 (word_add ptr (word i))) s = EL i bl) + ==> read (memory :> bytes128 ptr) s = bytes_to_int128 (SUB_LIST (0, 16) bl) /\ + read (memory :> bytes128 (word_add ptr (word 16))) s = + bytes_to_int128 (SUB_LIST (16, 16) bl)`, + REPEAT GEN_TAC THEN REPEAT_N 4 STRIP_TAC THEN + MP_TAC (SPECL [`0:num`; `bl:byte list`; `ptr:int64`; + `len:int64`; `s:armstate`] BYTE_LIST_AT_2BLOCKS) THEN + REWRITE_TAC[byte_list_at] THEN + ANTS_TAC THENL[ ASM_SIMP_TAC[]; ALL_TAC] THEN + ANTS_TAC THENL[ ASM_SIMP_TAC[]; ALL_TAC] THEN + ANTS_TAC THENL[ ASM_ARITH_TAC; ALL_TAC] THEN + CONV_TAC NUM_REDUCE_CONV THEN + ASM_SIMP_TAC[WORD_ADD_0] +);; + +let READ_LT_4BLOCK = prove( + `!(ptr:int64) (len:int64) (bl:byte list) (s:armstate). + LENGTH bl = val len ==> + ~(val len < 0x30) ==> + val len < 0x40 ==> + (forall i. i < val len + ==> read (memory :> bytes8 (word_add ptr (word i))) s = EL i bl) + ==> read (memory :> bytes128 ptr) s = bytes_to_int128 (SUB_LIST (0, 16) bl) /\ + read (memory :> bytes128 (word_add ptr (word 16))) s = + bytes_to_int128 (SUB_LIST (16, 16) bl) /\ + read (memory :> bytes128 (word_add ptr (word 32))) s = + bytes_to_int128 (SUB_LIST (32, 16) bl)`, + REPEAT GEN_TAC THEN REPEAT_N 4 STRIP_TAC THEN + MP_TAC (SPECL [`0:num`; `bl:byte list`; `ptr:int64`; + `len:int64`; `s:armstate`] BYTE_LIST_AT_3BLOCKS) THEN + REWRITE_TAC[byte_list_at] THEN + ANTS_TAC THENL[ ASM_SIMP_TAC[]; ALL_TAC] THEN + ANTS_TAC THENL[ ASM_SIMP_TAC[]; ALL_TAC] THEN + ANTS_TAC THENL[ ASM_ARITH_TAC; ALL_TAC] THEN + CONV_TAC NUM_REDUCE_CONV THEN + ASM_SIMP_TAC[WORD_ADD_0] +);; + +let READ_LT_5BLOCK = prove( + `!(ptr:int64) (len:int64) (bl:byte list) (s:armstate). + LENGTH bl = val len ==> + ~(val len < 0x40) ==> + val len < 0x50 ==> + (forall i. i < val len + ==> read (memory :> bytes8 (word_add ptr (word i))) s = EL i bl) + ==> read (memory :> bytes128 ptr) s = bytes_to_int128 (SUB_LIST (0, 16) bl) /\ + read (memory :> bytes128 (word_add ptr (word 16))) s = + bytes_to_int128 (SUB_LIST (16, 16) bl) /\ + read (memory :> bytes128 (word_add ptr (word 32))) s = + bytes_to_int128 (SUB_LIST (32, 16) bl) /\ + read (memory :> bytes128 (word_add ptr (word 48))) s = + bytes_to_int128 (SUB_LIST (48, 16) bl)`, + REPEAT GEN_TAC THEN REPEAT_N 4 STRIP_TAC THEN + MP_TAC (SPECL [`0:num`; `bl:byte list`; `ptr:int64`; + `len:int64`; `s:armstate`] BYTE_LIST_AT_4BLOCKS) THEN + REWRITE_TAC[byte_list_at] THEN + ANTS_TAC THENL[ ASM_SIMP_TAC[]; ALL_TAC] THEN + ANTS_TAC THENL[ ASM_SIMP_TAC[]; ALL_TAC] THEN + ANTS_TAC THENL[ ASM_ARITH_TAC; ALL_TAC] THEN + CONV_TAC NUM_REDUCE_CONV THEN + ASM_SIMP_TAC[WORD_ADD_0] +);; + +let READ_LT_6BLOCK = prove( + `!(ptr:int64) (len:int64) (bl:byte list) (s:armstate). + LENGTH bl = val len ==> + ~(val len < 0x50) ==> + val len < 0x60 ==> + (forall i. i < val len + ==> read (memory :> bytes8 (word_add ptr (word i))) s = EL i bl) + ==> read (memory :> bytes128 ptr) s = bytes_to_int128 (SUB_LIST (0, 16) bl) /\ + read (memory :> bytes128 (word_add ptr (word 16))) s = + bytes_to_int128 (SUB_LIST (16, 16) bl) /\ + read (memory :> bytes128 (word_add ptr (word 32))) s = + bytes_to_int128 (SUB_LIST (32, 16) bl) /\ + read (memory :> bytes128 (word_add ptr (word 48))) s = + bytes_to_int128 (SUB_LIST (48, 16) bl) /\ + read (memory :> bytes128 (word_add ptr (word 64))) s = + bytes_to_int128 (SUB_LIST (64, 16) bl)`, + REPEAT GEN_TAC THEN REPEAT_N 4 STRIP_TAC THEN + MP_TAC (SPECL [`0:num`; `bl:byte list`; `ptr:int64`; + `len:int64`; `s:armstate`] BYTE_LIST_AT_5BLOCKS) THEN + REWRITE_TAC[byte_list_at] THEN + ANTS_TAC THENL[ ASM_SIMP_TAC[]; ALL_TAC] THEN + ANTS_TAC THENL[ ASM_SIMP_TAC[]; ALL_TAC] THEN + ANTS_TAC THENL[ ASM_ARITH_TAC; ALL_TAC] THEN + CONV_TAC NUM_REDUCE_CONV THEN + ASM_SIMP_TAC[WORD_ADD_0] +);; + +let READ_BYTES_EQ_READ_BYTE128_1BLOCK = prove( + `!(ptr:int64) (ct:byte list) (iv:int128) (key1:int128 list) (key2:int128 list) s. + (read (memory :> bytes128 pt_ptr) s = + aes256_xts_decrypt_round (bytes_to_int128 (SUB_LIST (0x0,0x10) ct)) + (calculate_tweak 0x0 iv key2) + key1) ==> + read (memory :> bytes (pt_ptr,0x10)) s = + num_of_bytelist (SUB_LIST (0x0,0x10) (aes256_xts_decrypt ct 0x10 iv key1 key2))`, + REPEAT STRIP_TAC THEN + REWRITE_TAC[READ_MEMORY_BYTES_BYTES128] THEN + ASM_REWRITE_TAC[] THEN + REWRITE_TAC[aes256_xts_decrypt] THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[aes256_xts_decrypt_tail] THEN + REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[SUB_LIST_OF_INT128_TO_BYTES] THEN + REWRITE_TAC[NUM_OF_BYTELIST_OF_INT128_TO_BYTES] +);; + +let READ_BYTES_EQ_READ_BYTE128_2BLOCKS = prove( + `!(ptr:int64) (ct:byte list) (iv:int128) (key1:int128 list) (key2:int128 list) s. + (read (memory :> bytes128 pt_ptr) s = + aes256_xts_decrypt_round (bytes_to_int128 (SUB_LIST (0x0,0x10) ct)) + (calculate_tweak 0x0 iv key2) + key1) ==> + (read (memory :> bytes128 (word_add pt_ptr (word 0x10))) s = + aes256_xts_decrypt_round (bytes_to_int128 (SUB_LIST (0x10,0x10) ct)) + (calculate_tweak 0x1 iv key2) + key1) ==> + read (memory :> bytes (pt_ptr,0x20)) s = + num_of_bytelist (SUB_LIST (0x0,0x20) (aes256_xts_decrypt ct 0x20 iv key1 key2))`, + REPEAT STRIP_TAC THEN + IMP_REWRITE_TAC[ARITH_RULE `0x20 = 0x10 + 0x10`; READ_BYTES_AND_BYTE128_SPLIT] THEN + EXISTS_TAC `aes256_xts_decrypt ct 0x20 iv key1 key2` THEN + REPEAT CONJ_TAC THENL + [ + CONV_TAC NUM_REDUCE_CONV; + + MP_TAC (SPECL [`2:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN + ARITH_TAC; + + REWRITE_TAC[aes256_xts_decrypt] THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + CONV_TAC NUM_REDUCE_CONV THEN + MP_TAC (SPECL [`ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + LENGTH_OF_AES256_XTS_DECRYPT_REC_TRIVIAL) THEN + IMP_REWRITE_TAC[SUB_LIST_APPEND_RIGHT_LEMMA] THEN DISCH_TAC THEN + REWRITE_TAC[aes256_xts_decrypt_tail] THEN + REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + REWRITE_TAC[SUB_LIST_OF_INT128_TO_BYTES] THEN + REWRITE_TAC[NUM_OF_BYTELIST_OF_INT128_TO_BYTES] THEN + REWRITE_TAC[BYTES_TO_INT128_OF_INT128_TO_BYTES] THEN + CONV_TAC NUM_REDUCE_CONV; + + MP_TAC (SPECL [`1:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + SUB_LIST_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN + CONV_TAC NUM_REDUCE_CONV THEN + SIMP_TAC[] THEN DISCH_TAC THEN + IMP_REWRITE_TAC[READ_BYTES_EQ_READ_BYTE128_1BLOCK] THEN + MP_TAC (SPECL [`1:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN + CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] + ] +);; + +let READ_BYTES_EQ_READ_BYTE128_3BLOCKS = prove( + `!(ptr:int64) (ct:byte list) (iv:int128) (key1:int128 list) (key2:int128 list) s. + (read (memory :> bytes128 pt_ptr) s = + aes256_xts_decrypt_round (bytes_to_int128 (SUB_LIST (0x0,0x10) ct)) + (calculate_tweak 0x0 iv key2) + key1) ==> + (read (memory :> bytes128 (word_add pt_ptr (word 0x10))) s = + aes256_xts_decrypt_round (bytes_to_int128 (SUB_LIST (0x10,0x10) ct)) + (calculate_tweak 0x1 iv key2) + key1) ==> + (read (memory :> bytes128 (word_add pt_ptr (word 0x20))) s = + aes256_xts_decrypt_round (bytes_to_int128 (SUB_LIST (0x20,0x10) ct)) + (calculate_tweak 0x2 iv key2) + key1) ==> + read (memory :> bytes (pt_ptr,0x30)) s = + num_of_bytelist (SUB_LIST (0x0,0x30) (aes256_xts_decrypt ct 0x30 iv key1 key2))`, + REPEAT STRIP_TAC THEN + IMP_REWRITE_TAC[ARITH_RULE `0x30 = 0x20 + 0x10`; READ_BYTES_AND_BYTE128_SPLIT] THEN + EXISTS_TAC `aes256_xts_decrypt ct 0x30 iv key1 key2` THEN + REPEAT CONJ_TAC THENL + [ + CONV_TAC NUM_REDUCE_CONV; + + MP_TAC (SPECL [`3:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN + ARITH_TAC; + + REWRITE_TAC[aes256_xts_decrypt] THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + CONV_TAC NUM_REDUCE_CONV THEN + MP_TAC (SPECL [`0:num`; `1:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + LENGTH_OF_AES256_XTS_DECRYPT_REC) THEN + CONV_TAC NUM_REDUCE_CONV THEN + IMP_REWRITE_TAC[SUB_LIST_APPEND_RIGHT_LEMMA] THEN DISCH_TAC THEN + REWRITE_TAC[aes256_xts_decrypt_tail] THEN + REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + REWRITE_TAC[SUB_LIST_OF_INT128_TO_BYTES] THEN + REWRITE_TAC[NUM_OF_BYTELIST_OF_INT128_TO_BYTES] THEN + REWRITE_TAC[BYTES_TO_INT128_OF_INT128_TO_BYTES] THEN + CONV_TAC NUM_REDUCE_CONV; + ALL_TAC] THEN + + MP_TAC (SPECL [`2:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + SUB_LIST_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN + CONV_TAC NUM_REDUCE_CONV THEN + SIMP_TAC[] THEN DISCH_TAC THEN + IMP_REWRITE_TAC[READ_BYTES_EQ_READ_BYTE128_2BLOCKS] THEN + MP_TAC (SPECL [`2:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN + CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] +);; + +let READ_BYTES_EQ_READ_BYTE128_4BLOCKS = prove( + `!(ptr:int64) (ct:byte list) (iv:int128) (key1:int128 list) (key2:int128 list) s. + (read (memory :> bytes128 pt_ptr) s = + aes256_xts_decrypt_round (bytes_to_int128 (SUB_LIST (0x0,0x10) ct)) + (calculate_tweak 0x0 iv key2) + key1) ==> + (read (memory :> bytes128 (word_add pt_ptr (word 0x10))) s = + aes256_xts_decrypt_round (bytes_to_int128 (SUB_LIST (0x10,0x10) ct)) + (calculate_tweak 0x1 iv key2) + key1) ==> + (read (memory :> bytes128 (word_add pt_ptr (word 0x20))) s = + aes256_xts_decrypt_round (bytes_to_int128 (SUB_LIST (0x20,0x10) ct)) + (calculate_tweak 0x2 iv key2) + key1) ==> + (read (memory :> bytes128 (word_add pt_ptr (word 0x30))) s = + aes256_xts_decrypt_round (bytes_to_int128 (SUB_LIST (0x30,0x10) ct)) + (calculate_tweak 0x3 iv key2) + key1) ==> + read (memory :> bytes (pt_ptr,0x40)) s = + num_of_bytelist (SUB_LIST (0x0,0x40) (aes256_xts_decrypt ct 0x40 iv key1 key2))`, + REPEAT STRIP_TAC THEN + IMP_REWRITE_TAC[ARITH_RULE `0x40 = 0x30 + 0x10`; READ_BYTES_AND_BYTE128_SPLIT] THEN + EXISTS_TAC `aes256_xts_decrypt ct 0x40 iv key1 key2` THEN + REPEAT CONJ_TAC THENL + [ + CONV_TAC NUM_REDUCE_CONV; + + MP_TAC (SPECL [`4:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN + ARITH_TAC; + + REWRITE_TAC[aes256_xts_decrypt] THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + CONV_TAC NUM_REDUCE_CONV THEN + MP_TAC (SPECL [`0:num`; `2:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + LENGTH_OF_AES256_XTS_DECRYPT_REC) THEN + CONV_TAC NUM_REDUCE_CONV THEN + IMP_REWRITE_TAC[SUB_LIST_APPEND_RIGHT_LEMMA] THEN DISCH_TAC THEN + REWRITE_TAC[aes256_xts_decrypt_tail] THEN + REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + REWRITE_TAC[SUB_LIST_OF_INT128_TO_BYTES] THEN + REWRITE_TAC[BYTES_TO_INT128_OF_INT128_TO_BYTES] THEN + CONV_TAC NUM_REDUCE_CONV; + ALL_TAC] THEN + + MP_TAC (SPECL [`3:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + SUB_LIST_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN + CONV_TAC NUM_REDUCE_CONV THEN + SIMP_TAC[] THEN DISCH_TAC THEN + IMP_REWRITE_TAC[READ_BYTES_EQ_READ_BYTE128_3BLOCKS] THEN + MP_TAC (SPECL [`3:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN + CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] +);; + + +let READ_BYTES_EQ_READ_BYTE128_5BLOCKS = prove( + `!(ptr:int64) (ct:byte list) (iv:int128) (key1:int128 list) (key2:int128 list) s. + (read (memory :> bytes128 pt_ptr) s = + aes256_xts_decrypt_round (bytes_to_int128 (SUB_LIST (0x0,0x10) ct)) + (calculate_tweak 0x0 iv key2) + key1) ==> + (read (memory :> bytes128 (word_add pt_ptr (word 0x10))) s = + aes256_xts_decrypt_round (bytes_to_int128 (SUB_LIST (0x10,0x10) ct)) + (calculate_tweak 0x1 iv key2) + key1) ==> + (read (memory :> bytes128 (word_add pt_ptr (word 0x20))) s = + aes256_xts_decrypt_round (bytes_to_int128 (SUB_LIST (0x20,0x10) ct)) + (calculate_tweak 0x2 iv key2) + key1) ==> + (read (memory :> bytes128 (word_add pt_ptr (word 0x30))) s = + aes256_xts_decrypt_round (bytes_to_int128 (SUB_LIST (0x30,0x10) ct)) + (calculate_tweak 0x3 iv key2) + key1) ==> + (read (memory :> bytes128 (word_add pt_ptr (word 0x40))) s = + aes256_xts_decrypt_round (bytes_to_int128 (SUB_LIST (0x40,0x10) ct)) + (calculate_tweak 0x4 iv key2) + key1) ==> + read (memory :> bytes (pt_ptr,0x50)) s = + num_of_bytelist (SUB_LIST (0x0,0x50) (aes256_xts_decrypt ct 0x50 iv key1 key2))`, + REPEAT STRIP_TAC THEN + IMP_REWRITE_TAC[ARITH_RULE `0x50 = 0x40 + 0x10`; READ_BYTES_AND_BYTE128_SPLIT] THEN + EXISTS_TAC `aes256_xts_decrypt ct 0x50 iv key1 key2` THEN + REPEAT CONJ_TAC THENL + [ + CONV_TAC NUM_REDUCE_CONV; + + MP_TAC (SPECL [`5:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN + ARITH_TAC; + + REWRITE_TAC[aes256_xts_decrypt] THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + CONV_TAC NUM_REDUCE_CONV THEN + MP_TAC (SPECL [`0:num`; `3:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + LENGTH_OF_AES256_XTS_DECRYPT_REC) THEN + CONV_TAC NUM_REDUCE_CONV THEN + IMP_REWRITE_TAC[SUB_LIST_APPEND_RIGHT_LEMMA] THEN DISCH_TAC THEN + REWRITE_TAC[aes256_xts_decrypt_tail] THEN + REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + REWRITE_TAC[SUB_LIST_OF_INT128_TO_BYTES] THEN + REWRITE_TAC[BYTES_TO_INT128_OF_INT128_TO_BYTES] THEN + CONV_TAC NUM_REDUCE_CONV; + ALL_TAC] THEN + + MP_TAC (SPECL [`4:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + SUB_LIST_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN + CONV_TAC NUM_REDUCE_CONV THEN + SIMP_TAC[] THEN DISCH_TAC THEN + IMP_REWRITE_TAC[READ_BYTES_EQ_READ_BYTE128_4BLOCKS] THEN + MP_TAC (SPECL [`4:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN + CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] +);; + +(* Proof: Less than 2 blocks *) let AES_XTS_DECRYPT_LT_2BLOCK_CORRECT = time prove( `!ct_ptr pt_ptr ct key1_ptr key2_ptr iv_ptr iv len k00 k01 k02 k03 k04 k05 k06 k07 k08 k09 k0a k0b k0c k0d k0e @@ -4273,48 +4705,542 @@ let AES_XTS_DECRYPT_LT_2BLOCK_CORRECT = time prove( MAYCHANGE [Q8; Q9; Q10; Q11; Q12; Q13; Q14; Q15],, MAYCHANGE [memory :> bytes(pt_ptr, val len)]) `, - CHEAT_TAC);; + REWRITE_TAC [(REWRITE_CONV [aes_xts_decrypt_mc] THENC LENGTH_CONV) `LENGTH aes_xts_decrypt_mc`] THEN + REWRITE_TAC[set_key_schedule; C_ARGUMENTS; SOME_FLAGS; + NONOVERLAPPING_CLAUSES; byte_list_at; + MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI] THEN + REPEAT STRIP_TAC THEN + SUBGOAL_THEN `word_add (word_and len (word 0xf)) + (word_and len (word 0xfffffffffffffff0)) = len:int64` ASSUME_TAC THENL + [REWRITE_TAC[word_split_lemma]; ALL_TAC] THEN + ABBREV_TAC `num_blocks:int64 = word_and len (word 0xfffffffffffffff0)` THEN + ABBREV_TAC `tail_len:int64 = word_and len (word 0xf)` THEN + ABBREV_TAC `num_blocks_adjusted = if val (tail_len:int64) = 0 + then num_blocks else word_sub (num_blocks:int64) (word 0x10)` THEN + ABBREV_TAC `num_5blocks_adjusted = (word (val (num_blocks_adjusted:int64) DIV 0x50)):int64` THEN + + SUBGOAL_THEN `val (num_blocks:int64) = 16` ASSUME_TAC THENL + [ EXPAND_TAC "num_blocks" THEN + REWRITE_TAC[NUM_BLOCKS_TO_VAL] THEN + IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN + CONV_TAC NUM_REDUCE_CONV THEN + SUBGOAL_THEN `val (len:int64) DIV 16 = 1` SUBST1_TAC THENL + [ MATCH_MP_TAC(MESON[LE_ANTISYM] `m <= n /\ n <= m ==> m = n`) THEN + CONJ_TAC THENL [ ASM_ARITH_TAC; ASM_ARITH_TAC]; + ALL_TAC] THEN + ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `val (num_blocks_adjusted:int64) < 0x20` ASSUME_TAC THENL + [ EXPAND_TAC "num_blocks_adjusted" THEN + COND_CASES_TAC THENL[ + ASM_ARITH_TAC; + UNDISCH_TAC `val (num_blocks:int64) = 0x10` THEN + WORD_ARITH_TAC] + ; ALL_TAC] THEN -let AES_XTS_DECRYPT_LT_3BLOCK_CORRECT = time prove( - `!ct_ptr pt_ptr ct key1_ptr key2_ptr iv_ptr iv len - k00 k01 k02 k03 k04 k05 k06 k07 k08 k09 k0a k0b k0c k0d k0e - k10 k11 k12 k13 k14 k15 k16 k17 k18 k19 k1a k1b k1c k1d k1e - pc. - nonoverlapping (word pc, LENGTH aes_xts_decrypt_mc) (pt_ptr, val len) - /\ nonoverlapping (ct_ptr, val len) (pt_ptr, val len) - /\ nonoverlapping (key1_ptr, 260) (pt_ptr, val len) - /\ val len >= 16 /\ val len < 0x30 /\ LENGTH ct = val len - /\ [k00; k01; k02; k03; k04; k05; k06; k07; k08; k09; k0a; k0b; k0c; k0d; k0e] = key1 - /\ [k10; k11; k12; k13; k14; k15; k16; k17; k18; k19; k1a; k1b; k1c; k1d; k1e] = key2 - ==> ensures arm - (\s. aligned_bytes_loaded s (word pc) aes_xts_decrypt_mc /\ - read PC s = word (pc + 0x1c) /\ - C_ARGUMENTS [ct_ptr; pt_ptr; len; key1_ptr; key2_ptr; iv_ptr] s /\ - byte_list_at ct ct_ptr len s /\ - read(memory :> bytes128 iv_ptr) s = iv /\ - set_key_schedule s key1_ptr k00 k01 k02 k03 k04 k05 k06 k07 k08 k09 k0a k0b k0c k0d k0e /\ - set_key_schedule s key2_ptr k10 k11 k12 k13 k14 k15 k16 k17 k18 k19 k1a k1b k1c k1d k1e) - (\s. read PC s = word (pc + 0xb58) /\ - byte_list_at (aes256_xts_decrypt ct (val len) iv key1 key2) pt_ptr len s - ) - (MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI,, - MAYCHANGE [X19; X20; X21; X22],, - MAYCHANGE [Q8; Q9; Q10; Q11; Q12; Q13; Q14; Q15],, - MAYCHANGE [memory :> bytes(pt_ptr, val len)]) - `, - CHEAT_TAC);; + (* Prove property until start of cipher stealing. *) + ENSURES_SEQUENCE_TAC `pc + 0xa0c` + `\s. + read X0 s = word_add ct_ptr (word (acc_len num_5blocks_adjusted num_blocks_adjusted)) /\ + read X1 s = word_add pt_ptr (word (acc_len num_5blocks_adjusted num_blocks_adjusted)) /\ + read X3 s = key1_ptr /\ + read X21 s = tail_len /\ + read Q6 s = calculate_tweak (acc_blocks num_5blocks_adjusted num_blocks_adjusted T) iv key2 /\ + read X19 s = word 0x87 /\ + read Q16 s = k00 /\ read Q17 s = k01 /\ read Q12 s = k02 /\ read Q13 s = k03 /\ + read Q14 s = k04 /\ read Q15 s = k05 /\ read Q4 s = k06 /\ read Q5 s = k07 /\ + read Q18 s = k08 /\ read Q19 s = k09 /\ read Q20 s = k0a /\ read Q21 s = k0b /\ + read Q22 s = k0c /\ read Q23 s = k0d /\ read Q7 s = k0e /\ + byte_list_at ct ct_ptr len s /\ + byte_list_at (aes256_xts_decrypt ct (acc_len num_5blocks_adjusted num_blocks_adjusted) iv key1 key2) + pt_ptr (word (acc_len num_5blocks_adjusted num_blocks_adjusted)) s` THEN + CONJ_TAC THENL + [ + MATCH_MP_TAC ENSURES_FRAME_SUBSUMED THEN + EXISTS_TAC `MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI ,, + MAYCHANGE [X19; X20; X21; X22],, + MAYCHANGE [Q8; Q9; Q10; Q11; Q12; Q13; Q14; Q15],, + MAYCHANGE [memory :> bytes128 pt_ptr]` THEN + REWRITE_TAC[MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI] THEN + CONJ_TAC THENL [ + REPEAT (GEN_REWRITE_TAC ONCE_DEPTH_CONV [GSYM SEQ_ASSOC] THEN + MATCH_MP_TAC SUBSUMED_SEQ THEN REWRITE_TAC[SUBSUMED_REFL]) THEN + ABBREV_TAC `vallen = val (len:int64)` THEN + SUBSUMED_MAYCHANGE_TAC; ALL_TAC] THEN + REWRITE_TAC[byte_list_at] THEN + ENSURES_INIT_TAC "s0" THEN + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (1--2) THEN -let AES_XTS_DECRYPT_LT_4BLOCK_CORRECT = time prove( - `!ct_ptr pt_ptr ct key1_ptr key2_ptr iv_ptr iv len - k00 k01 k02 k03 k04 k05 k06 k07 k08 k09 k0a k0b k0c k0d k0e - k10 k11 k12 k13 k14 k15 k16 k17 k18 k19 k1a k1b k1c k1d k1e + (* Discharge if condition *) + SUBGOAL_THEN + `ival (word_sub (len:int64) (word 0x10)) < &0x0 + <=> ~(ival (len:int64) - &0x10 = ival (word_sub (len:int64) (word 0x10)))` MP_TAC THENL + [ MP_TAC (BITBLAST_RULE + `val (len:int64) >= 0x10 ==> val len < 0x20 ==> + ival (word_sub len (word 0x10)) >= &0x0`) THEN + ASM_REWRITE_TAC[] THEN + MP_TAC (BITBLAST_RULE + `val (len:int64) >= 0x10 ==> val len < 0x20 ==> + ival (len:int64) - &0x10 = ival (word_sub len (word 0x10))`) THEN + ASM_REWRITE_TAC[] THEN + ARITH_TAC; + ALL_TAC] THEN + ASM_REWRITE_TAC[] THEN DISCH_TAC THEN + POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th])) THEN + + MP_TAC (SPECL [`ct_ptr:int64`; `len:int64`; `ct:byte list`; `s2:armstate`] READ_LT_2BLOCK) THEN + ASM_SIMP_TAC[] THEN DISCH_TAC THEN + + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (3--69) THEN + (* Prove Q6 stores initial tweak *) + FIRST_X_ASSUM(MP_TAC o SPEC `(calculate_tweak 0 iv key2)` + o MATCH_MP (MESON[] `read Q6 s = a ==> !a'. a = a' ==> read Q6 s = a'`)) THEN + ANTS_TAC THENL + [ REWRITE_TAC[CONJUNCT1 calculate_tweak; xts_init_tweak] THEN + EXPAND_TAC "key2" THEN AESENC_TAC; DISCH_TAC] THEN + + (* Simulating until branch for num_blocks adjustment *) + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (70--89) THEN + + (* Case split on whether there is a tail *) + FIRST_X_ASSUM MP_TAC THEN + COND_CASES_TAC THENL + [ + DISCH_TAC THEN + + SUBGOAL_THEN `val (tail_len:int64) = 0` SUBST_ALL_TAC THENL + [ UNDISCH_TAC `val (word_and (tail_len:int64) (word 0xf)) = 0x0` THEN + MP_TAC (SPECL [`len:int64`; `tail_len:int64`] TAIL_LEN_BOUND_THM) THEN + ASM_SIMP_TAC[] THEN DISCH_TAC THEN + SUBGOAL_THEN `val (word_and (tail_len:int64) (word 15)) = val tail_len` SUBST1_TAC THENL + [ REWRITE_TAC[VAL_WORD_AND_MASK_WORD; ARITH_RULE `15 = 2 EXP 4 - 1`] THEN + CONV_TAC NUM_REDUCE_CONV THEN ASM_REWRITE_TAC[] THEN + IMP_REWRITE_TAC[MOD_LT]; + ALL_TAC] THEN + SIMP_TAC[]; ALL_TAC] THEN + CONV_TAC NUM_REDUCE_CONV THEN + + SUBGOAL_THEN `val (num_blocks_adjusted:int64) = 16` ASSUME_TAC THENL + [ EXPAND_TAC "num_blocks_adjusted" THEN + CONV_TAC NUM_REDUCE_CONV THEN + ASM_REWRITE_TAC[] + ; ALL_TAC ] THEN + SUBGOAL_THEN `val (num_5blocks_adjusted:int64) = 0` ASSUME_TAC THENL + [ EXPAND_TAC "num_5blocks_adjusted" THEN + UNDISCH_TAC `val (num_blocks_adjusted:int64) = 16` THEN + SIMP_TAC[] THEN DISCH_TAC THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[VAL_WORD_0] + ; ALL_TAC ] THEN + + TWEAK_TAC `Q8:(armstate,int128)component` `1:num` `0:num` THEN + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (90--126) THEN + XTSDEC_TAC `Q0:(armstate,int128)component` `0` `0` THEN + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (127--136) THEN + TWEAK_TAC `Q6:(armstate,int128)component` `1:num` `0:num` THEN + + ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN + REPEAT CONJ_TAC THENL + [ + ASM_REWRITE_TAC[acc_len] THEN CONV_TAC NUM_REDUCE_CONV; + ASM_REWRITE_TAC[acc_len] THEN CONV_TAC NUM_REDUCE_CONV; + ASM_REWRITE_TAC[acc_blocks] THEN CONV_TAC NUM_REDUCE_CONV; + + ASM_REWRITE_TAC[acc_len] THEN + CONV_TAC NUM_REDUCE_CONV THEN + IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN + CONV_TAC NUM_REDUCE_CONV THEN + MP_TAC (SPECL [`16:num`; `pt_ptr:int64`; `(aes256_xts_decrypt ct 16 iv key1 key2):byte list`; `s136:armstate`] BYTE_LIST_TO_NUM_THM) THEN + ANTS_TAC THENL[ + MP_TAC (SPECL [`1`; `ct:byte list`; `iv:int128`; + `key1:int128 list`; `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN + ARITH_TAC; ALL_TAC] THEN + DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN + ASM_REWRITE_TAC[] THEN + IMP_REWRITE_TAC[READ_BYTES_EQ_READ_BYTE128_1BLOCK] + ] + ; ALL_TAC] THEN + + (* There is a tail *) + DISCH_TAC THEN + (* Prove ~ tail_len = 0 *) + SUBGOAL_THEN `~(val (tail_len:int64) = 0)` ASSUME_TAC THENL + [ UNDISCH_TAC `~(val (word_and (tail_len:int64) (word 0xf)) = 0x0)` THEN + MP_TAC (SPECL [`len:int64`; `tail_len:int64`] TAIL_LEN_BOUND_THM) THEN + ASM_REWRITE_TAC[] THEN + SUBST1_TAC(ARITH_RULE `0xf = 2 EXP 4 - 1`) THEN + REWRITE_TAC[VAL_WORD_AND_MASK_WORD] THEN + NUM_REDUCE_TAC THEN IMP_REWRITE_TAC[MOD_LT] + ; ALL_TAC] THEN + (* Prove num_blocks_adjusted = word_sub num_blocks (word 0x10) *) + SUBGOAL_THEN `word_sub num_blocks (word 0x10) = num_blocks_adjusted:int64` ASSUME_TAC THENL + [ UNDISCH_TAC `(if val (tail_len:int64) = 0x0 + then (num_blocks:int64) + else word_sub num_blocks (word 0x10)) = num_blocks_adjusted` THEN + ASM_REWRITE_TAC[]; ALL_TAC] THEN + SUBGOAL_THEN `val (num_blocks_adjusted:int64) = 0` ASSUME_TAC THENL + [ EXPAND_TAC "num_blocks_adjusted" THEN + UNDISCH_TAC `val (num_blocks:int64) = 16` THEN + WORD_ARITH_TAC + ; ALL_TAC ] THEN + SUBGOAL_THEN `val (num_5blocks_adjusted:int64) = 0` ASSUME_TAC THENL + [ EXPAND_TAC "num_5blocks_adjusted" THEN + REWRITE_TAC[ASSUME `val (num_blocks_adjusted:int64) = 0`] THEN + WORD_ARITH_TAC + ; ALL_TAC ] THEN + + TWEAK_TAC `Q8:(armstate,int128)component` `1:num` `0:num` THEN + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (90--92) THEN + (* Discharge if condition *) + SUBGOAL_THEN + `~(ival (word_sub (num_blocks_adjusted:int64) (word 0x10)) < &0x0 <=> + ~(ival (num_blocks_adjusted:int64) - &0x10 = + ival (word_sub (num_blocks_adjusted:int64) (word 0x10))))` MP_TAC THENL + [ SUBGOAL_THEN `num_blocks_adjusted:int64 = (word 0)` SUBST1_TAC THENL + [ UNDISCH_TAC `val (num_blocks_adjusted:int64) = 0` THEN + WORD_ARITH_TAC; ALL_TAC] THEN + WORD_ARITH_TAC + ; ALL_TAC] THEN + DISCH_TAC THEN + POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th])) THEN + + ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN + REPEAT CONJ_TAC THENL + [ + ASM_REWRITE_TAC[acc_len] THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[WORD_ADD_0]; + ASM_REWRITE_TAC[acc_len] THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[WORD_ADD_0]; + ASM_REWRITE_TAC[acc_blocks] THEN CONV_TAC NUM_REDUCE_CONV; + + ASM_REWRITE_TAC[acc_len] THEN + CONV_TAC NUM_REDUCE_CONV THEN + IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN + CONV_TAC NUM_REDUCE_CONV THEN + MESON_TAC[ARITH_RULE `~(i < 0)`] + ] + ; ALL_TAC] THEN + + (* Reuse the cipher stealing proof *) + MP_TAC CIPHER_STEALING_CORRECT THEN + REWRITE_TAC [(REWRITE_CONV [aes_xts_decrypt_mc] THENC LENGTH_CONV) `LENGTH aes_xts_decrypt_mc`] THEN + REWRITE_TAC[set_key_schedule; C_ARGUMENTS; SOME_FLAGS; + NONOVERLAPPING_CLAUSES; byte_list_at; + MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI] THEN + DISCH_THEN MATCH_MP_TAC THEN + EXISTS_TAC `(word 16):int64` THEN + ASM_SIMP_TAC[] THEN + SUBGOAL_THEN `num_blocks:int64 = word 0x10` ASSUME_TAC THENL + [ UNDISCH_TAC `val (num_blocks:int64) = 16` THEN + WORD_ARITH_TAC; ALL_TAC] THEN + REPEAT CONJ_TAC THENL [ + ASM_ARITH_TAC; + EXPAND_TAC "len" THEN AP_TERM_TAC THEN + UNDISCH_TAC `val (num_blocks:int64) = 16` THEN + WORD_ARITH_TAC; + ASM_SIMP_TAC[]; + EXPAND_TAC "num_blocks_adjusted" THEN + REWRITE_TAC[ASSUME `num_blocks:int64 = word 16`] + ] +);; + + +(* Proof: less than 3 blocks *) +let AES_XTS_DECRYPT_LT_3BLOCK_CORRECT = time prove( + `!ct_ptr pt_ptr ct key1_ptr key2_ptr iv_ptr iv len + k00 k01 k02 k03 k04 k05 k06 k07 k08 k09 k0a k0b k0c k0d k0e + k10 k11 k12 k13 k14 k15 k16 k17 k18 k19 k1a k1b k1c k1d k1e + pc. + nonoverlapping (word pc, LENGTH aes_xts_decrypt_mc) (pt_ptr, val len) + /\ nonoverlapping (ct_ptr, val len) (pt_ptr, val len) + /\ nonoverlapping (key1_ptr, 260) (pt_ptr, val len) + /\ ~(val len < 0x20) /\ val len < 0x30 /\ LENGTH ct = val len + /\ [k00; k01; k02; k03; k04; k05; k06; k07; k08; k09; k0a; k0b; k0c; k0d; k0e] = key1 + /\ [k10; k11; k12; k13; k14; k15; k16; k17; k18; k19; k1a; k1b; k1c; k1d; k1e] = key2 + ==> ensures arm + (\s. aligned_bytes_loaded s (word pc) aes_xts_decrypt_mc /\ + read PC s = word (pc + 0x1c) /\ + C_ARGUMENTS [ct_ptr; pt_ptr; len; key1_ptr; key2_ptr; iv_ptr] s /\ + byte_list_at ct ct_ptr len s /\ + read(memory :> bytes128 iv_ptr) s = iv /\ + set_key_schedule s key1_ptr k00 k01 k02 k03 k04 k05 k06 k07 k08 k09 k0a k0b k0c k0d k0e /\ + set_key_schedule s key2_ptr k10 k11 k12 k13 k14 k15 k16 k17 k18 k19 k1a k1b k1c k1d k1e) + (\s. read PC s = word (pc + 0xb58) /\ + byte_list_at (aes256_xts_decrypt ct (val len) iv key1 key2) pt_ptr len s + ) + (MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI,, + MAYCHANGE [X19; X20; X21; X22],, + MAYCHANGE [Q8; Q9; Q10; Q11; Q12; Q13; Q14; Q15],, + MAYCHANGE [memory :> bytes(pt_ptr, val len)]) + `, + REWRITE_TAC [(REWRITE_CONV [aes_xts_decrypt_mc] THENC LENGTH_CONV) `LENGTH aes_xts_decrypt_mc`] THEN + REWRITE_TAC[set_key_schedule; C_ARGUMENTS; SOME_FLAGS; + NONOVERLAPPING_CLAUSES; byte_list_at; + MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI] THEN + REPEAT STRIP_TAC THEN + + SUBGOAL_THEN `word_add (word_and len (word 0xf)) + (word_and len (word 0xfffffffffffffff0)) = len:int64` ASSUME_TAC THENL + [REWRITE_TAC[word_split_lemma]; ALL_TAC] THEN + ABBREV_TAC `num_blocks:int64 = word_and len (word 0xfffffffffffffff0)` THEN + ABBREV_TAC `tail_len:int64 = word_and len (word 0xf)` THEN + ABBREV_TAC `num_blocks_adjusted = if val (tail_len:int64) = 0 + then num_blocks else word_sub (num_blocks:int64) (word 0x10)` THEN + ABBREV_TAC `num_5blocks_adjusted = (word (val (num_blocks_adjusted:int64) DIV 0x50)):int64` THEN + + SUBGOAL_THEN `val (num_blocks:int64) = 32` ASSUME_TAC THENL + [ EXPAND_TAC "num_blocks" THEN + REWRITE_TAC[NUM_BLOCKS_TO_VAL] THEN + IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN + CONV_TAC NUM_REDUCE_CONV THEN + SUBGOAL_THEN `val (len:int64) DIV 16 = 2` SUBST1_TAC THENL + [ MATCH_MP_TAC(MESON[LE_ANTISYM] `m <= n /\ n <= m ==> m = n`) THEN + CONJ_TAC THENL [ ASM_ARITH_TAC; ASM_ARITH_TAC]; + ALL_TAC] THEN + ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `val (num_blocks_adjusted:int64) < 0x30` ASSUME_TAC THENL + [ EXPAND_TAC "num_blocks_adjusted" THEN + COND_CASES_TAC THENL[ + ASM_ARITH_TAC; + UNDISCH_TAC `val (num_blocks:int64) = 0x20` THEN + WORD_ARITH_TAC] + ; ALL_TAC] THEN + + ENSURES_SEQUENCE_TAC `pc + 0xa0c` + `\s. + read X0 s = word_add ct_ptr (word (acc_len num_5blocks_adjusted num_blocks_adjusted)) /\ + read X1 s = word_add pt_ptr (word (acc_len num_5blocks_adjusted num_blocks_adjusted)) /\ + read X3 s = key1_ptr /\ + read X21 s = tail_len /\ + read Q6 s = calculate_tweak (acc_blocks num_5blocks_adjusted num_blocks_adjusted T) iv key2 /\ + read X19 s = word 0x87 /\ + read Q16 s = k00 /\ read Q17 s = k01 /\ read Q12 s = k02 /\ read Q13 s = k03 /\ + read Q14 s = k04 /\ read Q15 s = k05 /\ read Q4 s = k06 /\ read Q5 s = k07 /\ + read Q18 s = k08 /\ read Q19 s = k09 /\ read Q20 s = k0a /\ read Q21 s = k0b /\ + read Q22 s = k0c /\ read Q23 s = k0d /\ read Q7 s = k0e /\ + byte_list_at ct ct_ptr len s /\ + byte_list_at (aes256_xts_decrypt ct (acc_len num_5blocks_adjusted num_blocks_adjusted) iv key1 key2) + pt_ptr (word (acc_len num_5blocks_adjusted num_blocks_adjusted)) s` THEN + CONJ_TAC THENL + [ + MATCH_MP_TAC ENSURES_FRAME_SUBSUMED THEN + EXISTS_TAC `MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI ,, + MAYCHANGE [X19; X20; X21; X22],, + MAYCHANGE [Q8; Q9; Q10; Q11; Q12; Q13; Q14; Q15],, + MAYCHANGE [memory :> bytes128 pt_ptr; memory :> bytes128 (word_add pt_ptr (word 16))]` THEN + REWRITE_TAC[MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI] THEN + CONJ_TAC THENL [ + REPEAT (GEN_REWRITE_TAC ONCE_DEPTH_CONV [GSYM SEQ_ASSOC] THEN + MATCH_MP_TAC SUBSUMED_SEQ THEN REWRITE_TAC[SUBSUMED_REFL]) THEN + ABBREV_TAC `vallen = val (len:int64)` THEN + SUBSUMED_MAYCHANGE_TAC; ALL_TAC] THEN + + REWRITE_TAC[byte_list_at] THEN + ENSURES_INIT_TAC "s0" THEN + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (1--2) THEN + + (* Discharge if condition *) + SUBGOAL_THEN + `ival (word_sub (len:int64) (word 0x10)) < &0x0 + <=> ~(ival (len:int64) - &0x10 = ival (word_sub (len:int64) (word 0x10)))` MP_TAC THENL + [ MP_TAC (BITBLAST_RULE + `~(val (len:int64) < 0x20) ==> val len < 0x30 ==> + ival (word_sub len (word 0x10)) >= &0x0`) THEN + ASM_REWRITE_TAC[] THEN + MP_TAC (BITBLAST_RULE + `~(val (len:int64) < 0x20) ==> val len < 0x30 ==> + ival (len:int64) - &0x10 = ival (word_sub len (word 0x10))`) THEN + ASM_REWRITE_TAC[] THEN + ARITH_TAC; + ALL_TAC] THEN + ASM_REWRITE_TAC[] THEN DISCH_TAC THEN + POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th])) THEN + + MP_TAC (SPECL [`ct_ptr:int64`; `len:int64`; `ct:byte list`; `s2:armstate`] READ_LT_3BLOCK) THEN + ASM_SIMP_TAC[] THEN REPEAT STRIP_TAC THEN + + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (3--69) THEN + (* Prove Q6 stores initial tweak *) + FIRST_X_ASSUM(MP_TAC o SPEC `(calculate_tweak 0 iv key2)` + o MATCH_MP (MESON[] `read Q6 s = a ==> !a'. a = a' ==> read Q6 s = a'`)) THEN + ANTS_TAC THENL + [ REWRITE_TAC[CONJUNCT1 calculate_tweak; xts_init_tweak] THEN + EXPAND_TAC "key2" THEN AESENC_TAC; DISCH_TAC] THEN + + (* Simulating until branch for num_blocks adjustment *) + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (70--89) THEN + + (* Case split on whether there is a tail *) + FIRST_X_ASSUM MP_TAC THEN + COND_CASES_TAC THENL + [ + DISCH_TAC THEN + + SUBGOAL_THEN `val (tail_len:int64) = 0` SUBST_ALL_TAC THENL + [ UNDISCH_TAC `val (word_and (tail_len:int64) (word 0xf)) = 0x0` THEN + MP_TAC (SPECL [`len:int64`; `tail_len:int64`] TAIL_LEN_BOUND_THM) THEN + ASM_SIMP_TAC[] THEN DISCH_TAC THEN + SUBGOAL_THEN `val (word_and (tail_len:int64) (word 15)) = val tail_len` SUBST1_TAC THENL + [ REWRITE_TAC[VAL_WORD_AND_MASK_WORD; ARITH_RULE `15 = 2 EXP 4 - 1`] THEN + CONV_TAC NUM_REDUCE_CONV THEN ASM_REWRITE_TAC[] THEN + IMP_REWRITE_TAC[MOD_LT]; + ALL_TAC] THEN + SIMP_TAC[]; ALL_TAC] THEN + CONV_TAC NUM_REDUCE_CONV THEN + + SUBGOAL_THEN `val (num_blocks_adjusted:int64) = 0x20` ASSUME_TAC THENL + [ EXPAND_TAC "num_blocks_adjusted" THEN + CONV_TAC NUM_REDUCE_CONV THEN + ASM_REWRITE_TAC[] + ; ALL_TAC ] THEN + SUBGOAL_THEN `val (num_5blocks_adjusted:int64) = 0` ASSUME_TAC THENL + [ EXPAND_TAC "num_5blocks_adjusted" THEN + UNDISCH_TAC `val (num_blocks_adjusted:int64) = 0x20` THEN + SIMP_TAC[] THEN DISCH_TAC THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[VAL_WORD_0] + ; ALL_TAC ] THEN + + TWEAK_TAC `Q8:(armstate,int128)component` `1:num` `0:num` THEN + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (90--158) THEN + XTSDEC_TAC `Q0:(armstate,int128)component` `0` `0` THEN + XTSDEC_TAC `Q1:(armstate,int128)component` `0x10` `0x1` THEN + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (159--168) THEN + TWEAK_TAC `Q6:(armstate,int128)component` `2:num` `1:num` THEN + + ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN + REPEAT CONJ_TAC THENL + [ + ASM_REWRITE_TAC[acc_len] THEN CONV_TAC NUM_REDUCE_CONV; + ASM_REWRITE_TAC[acc_len] THEN CONV_TAC NUM_REDUCE_CONV; + ASM_REWRITE_TAC[acc_blocks] THEN CONV_TAC NUM_REDUCE_CONV; + + ASM_REWRITE_TAC[acc_len] THEN + CONV_TAC NUM_REDUCE_CONV THEN + IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN + CONV_TAC NUM_REDUCE_CONV THEN + MP_TAC (SPECL [`0x20:num`; `pt_ptr:int64`; `(aes256_xts_decrypt ct 0x20 iv key1 key2):byte list`; + `s168:armstate`] BYTE_LIST_TO_NUM_THM) THEN + ANTS_TAC THENL[ + MP_TAC (SPECL [`2`; `ct:byte list`; `iv:int128`; + `key1:int128 list`; `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN + ARITH_TAC; ALL_TAC] THEN + DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN + IMP_REWRITE_TAC[READ_BYTES_EQ_READ_BYTE128_2BLOCKS] + ]; ALL_TAC] THEN + + (* There is a tail *) + DISCH_TAC THEN + (* Prove ~ tail_len = 0 *) + SUBGOAL_THEN `~(val (tail_len:int64) = 0)` ASSUME_TAC THENL + [ UNDISCH_TAC `~(val (word_and (tail_len:int64) (word 0xf)) = 0x0)` THEN + MP_TAC (SPECL [`len:int64`; `tail_len:int64`] TAIL_LEN_BOUND_THM) THEN + ASM_REWRITE_TAC[] THEN + SUBST1_TAC(ARITH_RULE `0xf = 2 EXP 4 - 1`) THEN + REWRITE_TAC[VAL_WORD_AND_MASK_WORD] THEN + NUM_REDUCE_TAC THEN IMP_REWRITE_TAC[MOD_LT] + ; ALL_TAC] THEN + (* Prove num_blocks_adjusted = word_sub num_blocks (word 0x10) *) + SUBGOAL_THEN `word_sub num_blocks (word 0x10) = num_blocks_adjusted:int64` ASSUME_TAC THENL + [ UNDISCH_TAC `(if val (tail_len:int64) = 0x0 + then (num_blocks:int64) + else word_sub num_blocks (word 0x10)) = num_blocks_adjusted` THEN + ASM_REWRITE_TAC[]; ALL_TAC] THEN + SUBGOAL_THEN `val (num_blocks_adjusted:int64) = 0x10` ASSUME_TAC THENL + [ EXPAND_TAC "num_blocks_adjusted" THEN + UNDISCH_TAC `val (num_blocks:int64) = 0x20` THEN + WORD_ARITH_TAC + ; ALL_TAC ] THEN + SUBGOAL_THEN `val (num_5blocks_adjusted:int64) = 0` ASSUME_TAC THENL + [ EXPAND_TAC "num_5blocks_adjusted" THEN + REWRITE_TAC[ASSUME `val (num_blocks_adjusted:int64) = 0x10`] THEN + WORD_ARITH_TAC + ; ALL_TAC ] THEN + + TWEAK_TAC `Q8:(armstate,int128)component` `1:num` `0:num` THEN + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (90--92) THEN + (* Discharge if condition *) + SUBGOAL_THEN + `ival (word_sub (num_blocks_adjusted:int64) (word 0x10)) < &0x0 <=> + ~(ival (num_blocks_adjusted:int64) - &0x10 = + ival (word_sub (num_blocks_adjusted:int64) (word 0x10)))` MP_TAC THENL + [ SUBGOAL_THEN `num_blocks_adjusted:int64 = (word 0x10)` SUBST1_TAC THENL + [ UNDISCH_TAC `val (num_blocks_adjusted:int64) = 0x10` THEN + WORD_ARITH_TAC; ALL_TAC] THEN + WORD_ARITH_TAC + ; ALL_TAC] THEN + DISCH_TAC THEN + POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th])) THEN + + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (93--129) THEN + XTSDEC_TAC `Q0:(armstate,int128)component` `0` `0` THEN + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (130--139) THEN + TWEAK_TAC `Q6:(armstate,int128)component` `1:num` `0:num` THEN + + ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN + REPEAT CONJ_TAC THENL + [ + ASM_REWRITE_TAC[acc_len] THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[WORD_ADD_0]; + ASM_REWRITE_TAC[acc_len] THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[WORD_ADD_0]; + ASM_REWRITE_TAC[acc_blocks] THEN CONV_TAC NUM_REDUCE_CONV; + + ASM_REWRITE_TAC[acc_len] THEN + CONV_TAC NUM_REDUCE_CONV THEN + IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN + CONV_TAC NUM_REDUCE_CONV THEN + MP_TAC (SPECL [`16:num`; `pt_ptr:int64`; `(aes256_xts_decrypt ct 16 iv key1 key2):byte list`; + `s139:armstate`] BYTE_LIST_TO_NUM_THM) THEN + ANTS_TAC THENL[ + MP_TAC (SPECL [`1`; `ct:byte list`; `iv:int128`; + `key1:int128 list`; `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN + ARITH_TAC; ALL_TAC] THEN + DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN + IMP_REWRITE_TAC[READ_BYTES_EQ_READ_BYTE128_1BLOCK] + ] + ; ALL_TAC] THEN + + (* Reuse the cipher stealing proof *) + MP_TAC CIPHER_STEALING_CORRECT THEN + REWRITE_TAC [(REWRITE_CONV [aes_xts_decrypt_mc] THENC LENGTH_CONV) `LENGTH aes_xts_decrypt_mc`] THEN + REWRITE_TAC[set_key_schedule; C_ARGUMENTS; SOME_FLAGS; + NONOVERLAPPING_CLAUSES; byte_list_at; + MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI] THEN + DISCH_THEN MATCH_MP_TAC THEN + EXISTS_TAC `(word 0x20):int64` THEN + ASM_SIMP_TAC[] THEN + SUBGOAL_THEN `num_blocks:int64 = word 0x20` ASSUME_TAC THENL + [ UNDISCH_TAC `val (num_blocks:int64) = 0x20` THEN + WORD_ARITH_TAC; ALL_TAC] THEN + REPEAT CONJ_TAC THENL [ + ASM_ARITH_TAC; + ASM_ARITH_TAC; + EXPAND_TAC "len" THEN AP_TERM_TAC THEN + UNDISCH_TAC `val (num_blocks:int64) = 0x20` THEN + WORD_ARITH_TAC; + ASM_SIMP_TAC[]; + EXPAND_TAC "num_blocks_adjusted" THEN + REWRITE_TAC[ASSUME `num_blocks:int64 = word 0x20`] + ] +);; + + +(* Proof: less than 4 blocks *) +let AES_XTS_DECRYPT_LT_4BLOCK_CORRECT = time prove( + `!ct_ptr pt_ptr ct key1_ptr key2_ptr iv_ptr iv len + k00 k01 k02 k03 k04 k05 k06 k07 k08 k09 k0a k0b k0c k0d k0e + k10 k11 k12 k13 k14 k15 k16 k17 k18 k19 k1a k1b k1c k1d k1e pc. nonoverlapping (word pc, LENGTH aes_xts_decrypt_mc) (pt_ptr, val len) /\ nonoverlapping (ct_ptr, val len) (pt_ptr, val len) /\ nonoverlapping (key1_ptr, 260) (pt_ptr, val len) - /\ val len >= 16 /\ val len < 0x40 /\ LENGTH ct = val len + /\ ~(val len < 0x30) /\ val len < 0x40 /\ LENGTH ct = val len /\ [k00; k01; k02; k03; k04; k05; k06; k07; k08; k09; k0a; k0b; k0c; k0d; k0e] = key1 /\ [k10; k11; k12; k13; k14; k15; k16; k17; k18; k19; k1a; k1b; k1c; k1d; k1e] = key2 ==> ensures arm @@ -4333,9 +5259,264 @@ let AES_XTS_DECRYPT_LT_4BLOCK_CORRECT = time prove( MAYCHANGE [Q8; Q9; Q10; Q11; Q12; Q13; Q14; Q15],, MAYCHANGE [memory :> bytes(pt_ptr, val len)]) `, - CHEAT_TAC);; + REWRITE_TAC [(REWRITE_CONV [aes_xts_decrypt_mc] THENC LENGTH_CONV) `LENGTH aes_xts_decrypt_mc`] THEN + REWRITE_TAC[set_key_schedule; C_ARGUMENTS; SOME_FLAGS; + NONOVERLAPPING_CLAUSES; byte_list_at; + MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI] THEN + REPEAT STRIP_TAC THEN + + SUBGOAL_THEN `word_add (word_and len (word 0xf)) + (word_and len (word 0xfffffffffffffff0)) = len:int64` ASSUME_TAC THENL + [REWRITE_TAC[word_split_lemma]; ALL_TAC] THEN + ABBREV_TAC `num_blocks:int64 = word_and len (word 0xfffffffffffffff0)` THEN + ABBREV_TAC `tail_len:int64 = word_and len (word 0xf)` THEN + ABBREV_TAC `num_blocks_adjusted = if val (tail_len:int64) = 0 + then num_blocks else word_sub (num_blocks:int64) (word 0x10)` THEN + ABBREV_TAC `num_5blocks_adjusted = (word (val (num_blocks_adjusted:int64) DIV 0x50)):int64` THEN + + SUBGOAL_THEN `val (num_blocks:int64) = 0x30` ASSUME_TAC THENL + [ EXPAND_TAC "num_blocks" THEN + REWRITE_TAC[NUM_BLOCKS_TO_VAL] THEN + IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN + CONV_TAC NUM_REDUCE_CONV THEN + SUBGOAL_THEN `val (len:int64) DIV 16 = 3` SUBST1_TAC THENL + [ MATCH_MP_TAC(MESON[LE_ANTISYM] `m <= n /\ n <= m ==> m = n`) THEN + CONJ_TAC THENL [ ASM_ARITH_TAC; ASM_ARITH_TAC]; + ALL_TAC] THEN + ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `val (num_blocks_adjusted:int64) < 0x40` ASSUME_TAC THENL + [ EXPAND_TAC "num_blocks_adjusted" THEN + COND_CASES_TAC THENL[ + ASM_ARITH_TAC; + UNDISCH_TAC `val (num_blocks:int64) = 0x30` THEN + WORD_ARITH_TAC] + ; ALL_TAC] THEN + + ENSURES_SEQUENCE_TAC `pc + 0xa0c` + `\s. + read X0 s = word_add ct_ptr (word (acc_len num_5blocks_adjusted num_blocks_adjusted)) /\ + read X1 s = word_add pt_ptr (word (acc_len num_5blocks_adjusted num_blocks_adjusted)) /\ + read X3 s = key1_ptr /\ + read X21 s = tail_len /\ + read Q6 s = calculate_tweak (acc_blocks num_5blocks_adjusted num_blocks_adjusted T) iv key2 /\ + read X19 s = word 0x87 /\ + read Q16 s = k00 /\ read Q17 s = k01 /\ read Q12 s = k02 /\ read Q13 s = k03 /\ + read Q14 s = k04 /\ read Q15 s = k05 /\ read Q4 s = k06 /\ read Q5 s = k07 /\ + read Q18 s = k08 /\ read Q19 s = k09 /\ read Q20 s = k0a /\ read Q21 s = k0b /\ + read Q22 s = k0c /\ read Q23 s = k0d /\ read Q7 s = k0e /\ + byte_list_at ct ct_ptr len s /\ + byte_list_at (aes256_xts_decrypt ct (acc_len num_5blocks_adjusted num_blocks_adjusted) iv key1 key2) + pt_ptr (word (acc_len num_5blocks_adjusted num_blocks_adjusted)) s` THEN + CONJ_TAC THENL + [ + MATCH_MP_TAC ENSURES_FRAME_SUBSUMED THEN + EXISTS_TAC `MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI ,, + MAYCHANGE [X19; X20; X21; X22],, + MAYCHANGE [Q8; Q9; Q10; Q11; Q12; Q13; Q14; Q15],, + MAYCHANGE [ memory :> bytes128 pt_ptr; + memory :> bytes128 (word_add pt_ptr (word 16)); + memory :> bytes128 (word_add pt_ptr (word 32))]` THEN + REWRITE_TAC[MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI] THEN + CONJ_TAC THENL [ + REPEAT (GEN_REWRITE_TAC ONCE_DEPTH_CONV [GSYM SEQ_ASSOC] THEN + MATCH_MP_TAC SUBSUMED_SEQ THEN REWRITE_TAC[SUBSUMED_REFL]) THEN + ABBREV_TAC `vallen = val (len:int64)` THEN + SUBSUMED_MAYCHANGE_TAC; ALL_TAC] THEN + + REWRITE_TAC[byte_list_at] THEN + ENSURES_INIT_TAC "s0" THEN + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (1--2) THEN + + (* Discharge if condition *) + SUBGOAL_THEN + `ival (word_sub (len:int64) (word 0x10)) < &0x0 + <=> ~(ival (len:int64) - &0x10 = ival (word_sub (len:int64) (word 0x10)))` MP_TAC THENL + [ MP_TAC (BITBLAST_RULE + `~(val (len:int64) < 0x30) ==> val len < 0x40 ==> + ival (word_sub len (word 0x10)) >= &0x0`) THEN + ASM_REWRITE_TAC[] THEN + MP_TAC (BITBLAST_RULE + `~(val (len:int64) < 0x30) ==> val len < 0x40 ==> + ival (len:int64) - &0x10 = ival (word_sub len (word 0x10))`) THEN + ASM_REWRITE_TAC[] THEN + ARITH_TAC; + ALL_TAC] THEN + ASM_REWRITE_TAC[] THEN DISCH_TAC THEN + POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th])) THEN + + MP_TAC (SPECL [`ct_ptr:int64`; `len:int64`; `ct:byte list`; `s2:armstate`] READ_LT_4BLOCK) THEN + ASM_SIMP_TAC[] THEN REPEAT STRIP_TAC THEN + + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (3--69) THEN + (* Prove Q6 stores initial tweak *) + FIRST_X_ASSUM(MP_TAC o SPEC `(calculate_tweak 0 iv key2)` + o MATCH_MP (MESON[] `read Q6 s = a ==> !a'. a = a' ==> read Q6 s = a'`)) THEN + ANTS_TAC THENL + [ REWRITE_TAC[CONJUNCT1 calculate_tweak; xts_init_tweak] THEN + EXPAND_TAC "key2" THEN AESENC_TAC; DISCH_TAC] THEN + + (* Simulating until branch for num_blocks adjustment *) + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (70--89) THEN + + (* Case split on whether there is a tail *) + FIRST_X_ASSUM MP_TAC THEN + COND_CASES_TAC THENL + [ + DISCH_TAC THEN + + SUBGOAL_THEN `val (tail_len:int64) = 0` SUBST_ALL_TAC THENL + [ UNDISCH_TAC `val (word_and (tail_len:int64) (word 0xf)) = 0x0` THEN + MP_TAC (SPECL [`len:int64`; `tail_len:int64`] TAIL_LEN_BOUND_THM) THEN + ASM_SIMP_TAC[] THEN DISCH_TAC THEN + SUBGOAL_THEN `val (word_and (tail_len:int64) (word 15)) = val tail_len` SUBST1_TAC THENL + [ REWRITE_TAC[VAL_WORD_AND_MASK_WORD; ARITH_RULE `15 = 2 EXP 4 - 1`] THEN + CONV_TAC NUM_REDUCE_CONV THEN ASM_REWRITE_TAC[] THEN + IMP_REWRITE_TAC[MOD_LT]; + ALL_TAC] THEN + SIMP_TAC[]; ALL_TAC] THEN + CONV_TAC NUM_REDUCE_CONV THEN + + SUBGOAL_THEN `val (num_blocks_adjusted:int64) = 0x30` ASSUME_TAC THENL + [ EXPAND_TAC "num_blocks_adjusted" THEN + CONV_TAC NUM_REDUCE_CONV THEN + ASM_REWRITE_TAC[] + ; ALL_TAC ] THEN + SUBGOAL_THEN `val (num_5blocks_adjusted:int64) = 0` ASSUME_TAC THENL + [ EXPAND_TAC "num_5blocks_adjusted" THEN + UNDISCH_TAC `val (num_blocks_adjusted:int64) = 0x30` THEN + SIMP_TAC[] THEN DISCH_TAC THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[VAL_WORD_0] + ; ALL_TAC ] THEN + + TWEAK_TAC `Q8:(armstate,int128)component` `1:num` `0:num` THEN + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (90--105) THEN + TWEAK_TAC `Q9:(armstate,int128)component` `2:num` `1:num` THEN + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (106--197) THEN + XTSDEC_TAC `Q0:(armstate,int128)component` `0` `0` THEN + XTSDEC_TAC `Q1:(armstate,int128)component` `0x10` `1` THEN + XTSDEC_TAC `Q24:(armstate,int128)component` `0x20` `2` THEN + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (198--208) THEN + TWEAK_TAC `Q6:(armstate,int128)component` `3:num` `2:num` THEN + + ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN + REPEAT CONJ_TAC THENL + [ + ASM_REWRITE_TAC[acc_len] THEN CONV_TAC NUM_REDUCE_CONV; + ASM_REWRITE_TAC[acc_len] THEN CONV_TAC NUM_REDUCE_CONV; + ASM_REWRITE_TAC[acc_blocks] THEN CONV_TAC NUM_REDUCE_CONV; + + ASM_REWRITE_TAC[acc_len] THEN + CONV_TAC NUM_REDUCE_CONV THEN + IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN + CONV_TAC NUM_REDUCE_CONV THEN + MP_TAC (SPECL [`0x30:num`; `pt_ptr:int64`; `(aes256_xts_decrypt ct 0x30 iv key1 key2):byte list`; + `s208:armstate`] BYTE_LIST_TO_NUM_THM) THEN + ANTS_TAC THENL[ + MP_TAC (SPECL [`3`; `ct:byte list`; `iv:int128`; `key1:int128 list`; + `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN + ARITH_TAC; ALL_TAC] THEN + DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN + IMP_REWRITE_TAC[READ_BYTES_EQ_READ_BYTE128_3BLOCKS] + ]; ALL_TAC + ] THEN + + (* There is a tail *) + DISCH_TAC THEN + (* Prove ~ tail_len = 0 *) + SUBGOAL_THEN `~(val (tail_len:int64) = 0)` ASSUME_TAC THENL + [ UNDISCH_TAC `~(val (word_and (tail_len:int64) (word 0xf)) = 0x0)` THEN + MP_TAC (SPECL [`len:int64`; `tail_len:int64`] TAIL_LEN_BOUND_THM) THEN + ASM_REWRITE_TAC[] THEN + SUBST1_TAC(ARITH_RULE `0xf = 2 EXP 4 - 1`) THEN + REWRITE_TAC[VAL_WORD_AND_MASK_WORD] THEN + NUM_REDUCE_TAC THEN IMP_REWRITE_TAC[MOD_LT] + ; ALL_TAC] THEN + (* Prove num_blocks_adjusted = word_sub num_blocks (word 0x10) *) + SUBGOAL_THEN `word_sub num_blocks (word 0x10) = num_blocks_adjusted:int64` ASSUME_TAC THENL + [ UNDISCH_TAC `(if val (tail_len:int64) = 0x0 + then (num_blocks:int64) + else word_sub num_blocks (word 0x10)) = num_blocks_adjusted` THEN + ASM_REWRITE_TAC[]; ALL_TAC] THEN + SUBGOAL_THEN `val (num_blocks_adjusted:int64) = 0x20` ASSUME_TAC THENL + [ EXPAND_TAC "num_blocks_adjusted" THEN + UNDISCH_TAC `val (num_blocks:int64) = 0x30` THEN + WORD_ARITH_TAC + ; ALL_TAC ] THEN + SUBGOAL_THEN `val (num_5blocks_adjusted:int64) = 0` ASSUME_TAC THENL + [ EXPAND_TAC "num_5blocks_adjusted" THEN + REWRITE_TAC[ASSUME `val (num_blocks_adjusted:int64) = 0x20`] THEN + WORD_ARITH_TAC + ; ALL_TAC ] THEN + + TWEAK_TAC `Q8:(armstate,int128)component` `1:num` `0:num` THEN + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (90--92) THEN + (* Discharge if condition *) + SUBGOAL_THEN + `ival (word_sub (num_blocks_adjusted:int64) (word 0x10)) < &0x0 <=> + ~(ival (num_blocks_adjusted:int64) - &0x10 = + ival (word_sub (num_blocks_adjusted:int64) (word 0x10)))` MP_TAC THENL + [ SUBGOAL_THEN `num_blocks_adjusted:int64 = (word 0x20)` SUBST1_TAC THENL + [ UNDISCH_TAC `val (num_blocks_adjusted:int64) = 0x20` THEN + WORD_ARITH_TAC; ALL_TAC] THEN + WORD_ARITH_TAC + ; ALL_TAC] THEN + DISCH_TAC THEN + POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th])) THEN + + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (93--161) THEN + XTSDEC_TAC `Q0:(armstate,int128)component` `0` `0` THEN + XTSDEC_TAC `Q1:(armstate,int128)component` `0x10` `1` THEN + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (162--171) THEN + TWEAK_TAC `Q6:(armstate,int128)component` `2:num` `1:num` THEN + + ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN + REPEAT CONJ_TAC THENL + [ + ASM_REWRITE_TAC[acc_len] THEN CONV_TAC NUM_REDUCE_CONV; + ASM_REWRITE_TAC[acc_len] THEN CONV_TAC NUM_REDUCE_CONV; + ASM_REWRITE_TAC[acc_blocks] THEN CONV_TAC NUM_REDUCE_CONV; + + ASM_REWRITE_TAC[acc_len] THEN + CONV_TAC NUM_REDUCE_CONV THEN + IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN + CONV_TAC NUM_REDUCE_CONV THEN + MP_TAC (SPECL [`0x20:num`; `pt_ptr:int64`; `(aes256_xts_decrypt ct 0x20 iv key1 key2):byte list`; + `s171:armstate`] BYTE_LIST_TO_NUM_THM) THEN + ANTS_TAC THENL[ + MP_TAC (SPECL [`2`; `ct:byte list`; `iv:int128`; + `key1:int128 list`; `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN + ARITH_TAC; ALL_TAC] THEN + DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN + IMP_REWRITE_TAC[READ_BYTES_EQ_READ_BYTE128_2BLOCKS] + ]; ALL_TAC] THEN + + (* Reuse the cipher stealing proof *) + MP_TAC CIPHER_STEALING_CORRECT THEN + REWRITE_TAC [(REWRITE_CONV [aes_xts_decrypt_mc] THENC LENGTH_CONV) `LENGTH aes_xts_decrypt_mc`] THEN + REWRITE_TAC[set_key_schedule; C_ARGUMENTS; SOME_FLAGS; + NONOVERLAPPING_CLAUSES; byte_list_at; + MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI] THEN + DISCH_THEN MATCH_MP_TAC THEN + EXISTS_TAC `(word 0x30):int64` THEN + ASM_SIMP_TAC[] THEN + SUBGOAL_THEN `num_blocks:int64 = word 0x30` ASSUME_TAC THENL + [ UNDISCH_TAC `val (num_blocks:int64) = 0x30` THEN + WORD_ARITH_TAC; ALL_TAC] THEN + REPEAT CONJ_TAC THENL [ + ASM_ARITH_TAC; + ASM_ARITH_TAC; + EXPAND_TAC "len" THEN AP_TERM_TAC THEN + UNDISCH_TAC `val (num_blocks:int64) = 0x30` THEN + WORD_ARITH_TAC; + ASM_SIMP_TAC[]; + EXPAND_TAC "num_blocks_adjusted" THEN + REWRITE_TAC[ASSUME `num_blocks:int64 = word 0x30`] + ] +);; +(* Proof: less than 5 blocks *) let AES_XTS_DECRYPT_LT_5BLOCK_CORRECT = time prove( `!ct_ptr pt_ptr ct key1_ptr key2_ptr iv_ptr iv len k00 k01 k02 k03 k04 k05 k06 k07 k08 k09 k0a k0b k0c k0d k0e @@ -4344,7 +5525,7 @@ let AES_XTS_DECRYPT_LT_5BLOCK_CORRECT = time prove( nonoverlapping (word pc, LENGTH aes_xts_decrypt_mc) (pt_ptr, val len) /\ nonoverlapping (ct_ptr, val len) (pt_ptr, val len) /\ nonoverlapping (key1_ptr, 260) (pt_ptr, val len) - /\ val len >= 16 /\ val len < 0x50 /\ LENGTH ct = val len + /\ ~(val len < 0x40) /\ val len < 0x50 /\ LENGTH ct = val len /\ [k00; k01; k02; k03; k04; k05; k06; k07; k08; k09; k0a; k0b; k0c; k0d; k0e] = key1 /\ [k10; k11; k12; k13; k14; k15; k16; k17; k18; k19; k1a; k1b; k1c; k1d; k1e] = key2 ==> ensures arm @@ -4363,9 +5544,274 @@ let AES_XTS_DECRYPT_LT_5BLOCK_CORRECT = time prove( MAYCHANGE [Q8; Q9; Q10; Q11; Q12; Q13; Q14; Q15],, MAYCHANGE [memory :> bytes(pt_ptr, val len)]) `, - CHEAT_TAC);; + REWRITE_TAC [(REWRITE_CONV [aes_xts_decrypt_mc] THENC LENGTH_CONV) `LENGTH aes_xts_decrypt_mc`] THEN + REWRITE_TAC[set_key_schedule; C_ARGUMENTS; SOME_FLAGS; + NONOVERLAPPING_CLAUSES; byte_list_at; + MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI] THEN + REPEAT STRIP_TAC THEN + + SUBGOAL_THEN `word_add (word_and len (word 0xf)) + (word_and len (word 0xfffffffffffffff0)) = len:int64` ASSUME_TAC THENL + [REWRITE_TAC[word_split_lemma]; ALL_TAC] THEN + ABBREV_TAC `num_blocks:int64 = word_and len (word 0xfffffffffffffff0)` THEN + ABBREV_TAC `tail_len:int64 = word_and len (word 0xf)` THEN + ABBREV_TAC `num_blocks_adjusted = if val (tail_len:int64) = 0 + then num_blocks else word_sub (num_blocks:int64) (word 0x10)` THEN + ABBREV_TAC `num_5blocks_adjusted = (word (val (num_blocks_adjusted:int64) DIV 0x50)):int64` THEN + + SUBGOAL_THEN `val (num_blocks:int64) = 0x40` ASSUME_TAC THENL + [ EXPAND_TAC "num_blocks" THEN + REWRITE_TAC[NUM_BLOCKS_TO_VAL] THEN + IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN + CONV_TAC NUM_REDUCE_CONV THEN + SUBGOAL_THEN `val (len:int64) DIV 16 = 4` SUBST1_TAC THENL + [ MATCH_MP_TAC(MESON[LE_ANTISYM] `m <= n /\ n <= m ==> m = n`) THEN + CONJ_TAC THENL [ ASM_ARITH_TAC; ASM_ARITH_TAC]; + ALL_TAC] THEN + ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `val (num_blocks_adjusted:int64) < 0x50` ASSUME_TAC THENL + [ EXPAND_TAC "num_blocks_adjusted" THEN + COND_CASES_TAC THENL[ + ASM_ARITH_TAC; + UNDISCH_TAC `val (num_blocks:int64) = 0x40` THEN + WORD_ARITH_TAC] + ; ALL_TAC] THEN + + ENSURES_SEQUENCE_TAC `pc + 0xa0c` + `\s. + read X0 s = word_add ct_ptr (word (acc_len num_5blocks_adjusted num_blocks_adjusted)) /\ + read X1 s = word_add pt_ptr (word (acc_len num_5blocks_adjusted num_blocks_adjusted)) /\ + read X3 s = key1_ptr /\ + read X21 s = tail_len /\ + read Q6 s = calculate_tweak (acc_blocks num_5blocks_adjusted num_blocks_adjusted T) iv key2 /\ + read X19 s = word 0x87 /\ + read Q16 s = k00 /\ read Q17 s = k01 /\ read Q12 s = k02 /\ read Q13 s = k03 /\ + read Q14 s = k04 /\ read Q15 s = k05 /\ read Q4 s = k06 /\ read Q5 s = k07 /\ + read Q18 s = k08 /\ read Q19 s = k09 /\ read Q20 s = k0a /\ read Q21 s = k0b /\ + read Q22 s = k0c /\ read Q23 s = k0d /\ read Q7 s = k0e /\ + byte_list_at ct ct_ptr len s /\ + byte_list_at (aes256_xts_decrypt ct (acc_len num_5blocks_adjusted num_blocks_adjusted) iv key1 key2) + pt_ptr (word (acc_len num_5blocks_adjusted num_blocks_adjusted)) s` THEN + CONJ_TAC THENL + [ + MATCH_MP_TAC ENSURES_FRAME_SUBSUMED THEN + EXISTS_TAC `MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI ,, + MAYCHANGE [X19; X20; X21; X22],, + MAYCHANGE [Q8; Q9; Q10; Q11; Q12; Q13; Q14; Q15],, + MAYCHANGE [ memory :> bytes128 pt_ptr; + memory :> bytes128 (word_add pt_ptr (word 16)); + memory :> bytes128 (word_add pt_ptr (word 32)); + memory :> bytes128 (word_add pt_ptr (word 48))]` THEN + REWRITE_TAC[MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI] THEN + CONJ_TAC THENL [ + REPEAT (GEN_REWRITE_TAC ONCE_DEPTH_CONV [GSYM SEQ_ASSOC] THEN + MATCH_MP_TAC SUBSUMED_SEQ THEN REWRITE_TAC[SUBSUMED_REFL]) THEN + ABBREV_TAC `vallen = val (len:int64)` THEN + SUBSUMED_MAYCHANGE_TAC; ALL_TAC] THEN + + REWRITE_TAC[byte_list_at] THEN + ENSURES_INIT_TAC "s0" THEN + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (1--2) THEN + + (* Discharge if condition *) + SUBGOAL_THEN + `ival (word_sub (len:int64) (word 0x10)) < &0x0 + <=> ~(ival (len:int64) - &0x10 = ival (word_sub (len:int64) (word 0x10)))` MP_TAC THENL + [ MP_TAC (BITBLAST_RULE + `~(val (len:int64) < 0x40) ==> val len < 0x50 ==> + ival (word_sub len (word 0x10)) >= &0x0`) THEN + ASM_REWRITE_TAC[] THEN + MP_TAC (BITBLAST_RULE + `~(val (len:int64) < 0x40) ==> val len < 0x50 ==> + ival (len:int64) - &0x10 = ival (word_sub len (word 0x10))`) THEN + ASM_REWRITE_TAC[] THEN + ARITH_TAC; + ALL_TAC] THEN + ASM_REWRITE_TAC[] THEN DISCH_TAC THEN + POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th])) THEN + + MP_TAC (SPECL [`ct_ptr:int64`; `len:int64`; `ct:byte list`; `s2:armstate`] READ_LT_5BLOCK) THEN + ASM_SIMP_TAC[] THEN REPEAT STRIP_TAC THEN + + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (3--69) THEN + (* Prove Q6 stores initial tweak *) + FIRST_X_ASSUM(MP_TAC o SPEC `(calculate_tweak 0 iv key2)` + o MATCH_MP (MESON[] `read Q6 s = a ==> !a'. a = a' ==> read Q6 s = a'`)) THEN + ANTS_TAC THENL + [ REWRITE_TAC[CONJUNCT1 calculate_tweak; xts_init_tweak] THEN + EXPAND_TAC "key2" THEN AESENC_TAC; DISCH_TAC] THEN + + (* Simulating until branch for num_blocks adjustment *) + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (70--89) THEN + + (* Case split on whether there is a tail *) + FIRST_X_ASSUM MP_TAC THEN + COND_CASES_TAC THENL + [ + DISCH_TAC THEN + + SUBGOAL_THEN `val (tail_len:int64) = 0` SUBST_ALL_TAC THENL + [ UNDISCH_TAC `val (word_and (tail_len:int64) (word 0xf)) = 0x0` THEN + MP_TAC (SPECL [`len:int64`; `tail_len:int64`] TAIL_LEN_BOUND_THM) THEN + ASM_SIMP_TAC[] THEN DISCH_TAC THEN + SUBGOAL_THEN `val (word_and (tail_len:int64) (word 15)) = val tail_len` SUBST1_TAC THENL + [ REWRITE_TAC[VAL_WORD_AND_MASK_WORD; ARITH_RULE `15 = 2 EXP 4 - 1`] THEN + CONV_TAC NUM_REDUCE_CONV THEN ASM_REWRITE_TAC[] THEN + IMP_REWRITE_TAC[MOD_LT]; + ALL_TAC] THEN + SIMP_TAC[]; ALL_TAC] THEN + CONV_TAC NUM_REDUCE_CONV THEN + + SUBGOAL_THEN `val (num_blocks_adjusted:int64) = 0x40` ASSUME_TAC THENL + [ EXPAND_TAC "num_blocks_adjusted" THEN + CONV_TAC NUM_REDUCE_CONV THEN + ASM_REWRITE_TAC[] + ; ALL_TAC ] THEN + SUBGOAL_THEN `val (num_5blocks_adjusted:int64) = 0` ASSUME_TAC THENL + [ EXPAND_TAC "num_5blocks_adjusted" THEN + UNDISCH_TAC `val (num_blocks_adjusted:int64) = 0x40` THEN + SIMP_TAC[] THEN DISCH_TAC THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[VAL_WORD_0] + ; ALL_TAC ] THEN + + TWEAK_TAC `Q8:(armstate,int128)component` `1:num` `0:num` THEN + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (90--105) THEN + TWEAK_TAC `Q9:(armstate,int128)component` `2:num` `1:num` THEN + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (106--113) THEN + TWEAK_TAC `Q10:(armstate,int128)component` `3:num` `2:num` THEN + + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (114--235) THEN + XTSDEC_TAC `Q0:(armstate,int128)component` `0` `0` THEN + XTSDEC_TAC `Q1:(armstate,int128)component` `0x10` `1` THEN + XTSDEC_TAC `Q24:(armstate,int128)component` `0x20` `2` THEN + XTSDEC_TAC `Q25:(armstate,int128)component` `0x30` `3` THEN + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (236--246) THEN + TWEAK_TAC `Q6:(armstate,int128)component` `4:num` `3:num` THEN + + ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN + REPEAT CONJ_TAC THENL + [ + ASM_REWRITE_TAC[acc_len] THEN CONV_TAC NUM_REDUCE_CONV; + ASM_REWRITE_TAC[acc_len] THEN CONV_TAC NUM_REDUCE_CONV; + ASM_REWRITE_TAC[acc_blocks] THEN CONV_TAC NUM_REDUCE_CONV; + + ASM_REWRITE_TAC[acc_len] THEN + CONV_TAC NUM_REDUCE_CONV THEN + IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN + CONV_TAC NUM_REDUCE_CONV THEN + MP_TAC (SPECL [`0x40:num`; `pt_ptr:int64`; `(aes256_xts_decrypt ct 0x40 iv key1 key2):byte list`; + `s246:armstate`] BYTE_LIST_TO_NUM_THM) THEN + ANTS_TAC THENL[ + MP_TAC (SPECL [`4`; `ct:byte list`; `iv:int128`; `key1:int128 list`; + `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN + ARITH_TAC; ALL_TAC] THEN + DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN + IMP_REWRITE_TAC[READ_BYTES_EQ_READ_BYTE128_4BLOCKS] ] + ; ALL_TAC + ] THEN + + (* There is a tail *) + DISCH_TAC THEN + (* Prove ~ tail_len = 0 *) + SUBGOAL_THEN `~(val (tail_len:int64) = 0)` ASSUME_TAC THENL + [ UNDISCH_TAC `~(val (word_and (tail_len:int64) (word 0xf)) = 0x0)` THEN + MP_TAC (SPECL [`len:int64`; `tail_len:int64`] TAIL_LEN_BOUND_THM) THEN + ASM_REWRITE_TAC[] THEN + SUBST1_TAC(ARITH_RULE `0xf = 2 EXP 4 - 1`) THEN + REWRITE_TAC[VAL_WORD_AND_MASK_WORD] THEN + NUM_REDUCE_TAC THEN IMP_REWRITE_TAC[MOD_LT] + ; ALL_TAC] THEN + (* Prove num_blocks_adjusted = word_sub num_blocks (word 0x10) *) + SUBGOAL_THEN `word_sub num_blocks (word 0x10) = num_blocks_adjusted:int64` ASSUME_TAC THENL + [ UNDISCH_TAC `(if val (tail_len:int64) = 0x0 + then (num_blocks:int64) + else word_sub num_blocks (word 0x10)) = num_blocks_adjusted` THEN + ASM_REWRITE_TAC[]; ALL_TAC] THEN + SUBGOAL_THEN `val (num_blocks_adjusted:int64) = 0x30` ASSUME_TAC THENL + [ EXPAND_TAC "num_blocks_adjusted" THEN + UNDISCH_TAC `val (num_blocks:int64) = 0x40` THEN + WORD_ARITH_TAC + ; ALL_TAC ] THEN + SUBGOAL_THEN `val (num_5blocks_adjusted:int64) = 0` ASSUME_TAC THENL + [ EXPAND_TAC "num_5blocks_adjusted" THEN + REWRITE_TAC[ASSUME `val (num_blocks_adjusted:int64) = 0x30`] THEN + WORD_ARITH_TAC + ; ALL_TAC ] THEN + + TWEAK_TAC `Q8:(armstate,int128)component` `1:num` `0:num` THEN + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (90--92) THEN + (* Discharge if condition *) + SUBGOAL_THEN + `ival (word_sub (num_blocks_adjusted:int64) (word 0x10)) < &0x0 <=> + ~(ival (num_blocks_adjusted:int64) - &0x10 = + ival (word_sub (num_blocks_adjusted:int64) (word 0x10)))` MP_TAC THENL + [ SUBGOAL_THEN `num_blocks_adjusted:int64 = (word 0x30)` SUBST1_TAC THENL + [ UNDISCH_TAC `val (num_blocks_adjusted:int64) = 0x30` THEN + WORD_ARITH_TAC; ALL_TAC] THEN + WORD_ARITH_TAC + ; ALL_TAC] THEN + DISCH_TAC THEN + POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th])) THEN + + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (93--108) THEN + TWEAK_TAC `Q9:(armstate,int128)component` `2:num` `1:num` THEN + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (109--200) THEN + XTSDEC_TAC `Q0:(armstate,int128)component` `0` `0` THEN + XTSDEC_TAC `Q1:(armstate,int128)component` `0x10` `1` THEN + XTSDEC_TAC `Q24:(armstate,int128)component` `0x20` `2` THEN + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (201--211) THEN + TWEAK_TAC `Q6:(armstate,int128)component` `3:num` `2:num` THEN + + ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN + REPEAT CONJ_TAC THENL + [ + ASM_REWRITE_TAC[acc_len] THEN + CONV_TAC NUM_REDUCE_CONV; + ASM_REWRITE_TAC[acc_len] THEN + CONV_TAC NUM_REDUCE_CONV; + ASM_REWRITE_TAC[acc_blocks] THEN CONV_TAC NUM_REDUCE_CONV; + + ASM_REWRITE_TAC[acc_len] THEN + CONV_TAC NUM_REDUCE_CONV THEN + IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN + CONV_TAC NUM_REDUCE_CONV THEN + MP_TAC (SPECL [`0x30:num`; `pt_ptr:int64`; `(aes256_xts_decrypt ct 0x30 iv key1 key2):byte list`; + `s211:armstate`] BYTE_LIST_TO_NUM_THM) THEN + ANTS_TAC THENL[ + MP_TAC (SPECL [`3`; `ct:byte list`; `iv:int128`; + `key1:int128 list`; `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN + ARITH_TAC; ALL_TAC] THEN + DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN + IMP_REWRITE_TAC[READ_BYTES_EQ_READ_BYTE128_3BLOCKS] + ]; ALL_TAC] THEN + + (* Reuse the cipher stealing proof *) + MP_TAC CIPHER_STEALING_CORRECT THEN + REWRITE_TAC [(REWRITE_CONV [aes_xts_decrypt_mc] THENC LENGTH_CONV) `LENGTH aes_xts_decrypt_mc`] THEN + REWRITE_TAC[set_key_schedule; C_ARGUMENTS; SOME_FLAGS; + NONOVERLAPPING_CLAUSES; byte_list_at; + MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI] THEN + DISCH_THEN MATCH_MP_TAC THEN + EXISTS_TAC `(word 0x40):int64` THEN + ASM_SIMP_TAC[] THEN + SUBGOAL_THEN `num_blocks:int64 = word 0x40` ASSUME_TAC THENL + [ UNDISCH_TAC `val (num_blocks:int64) = 0x40` THEN + WORD_ARITH_TAC; ALL_TAC] THEN + REPEAT CONJ_TAC THENL [ + ASM_ARITH_TAC; + ASM_ARITH_TAC; + EXPAND_TAC "len" THEN AP_TERM_TAC THEN + UNDISCH_TAC `val (num_blocks:int64) = 0x40` THEN + WORD_ARITH_TAC; + ASM_SIMP_TAC[]; + EXPAND_TAC "num_blocks_adjusted" THEN + REWRITE_TAC[ASSUME `num_blocks:int64 = word 0x40`] + ] +);; +(* Proof: less than 6 blocks *) let AES_XTS_DECRYPT_LT_6BLOCK_CORRECT = time prove( `!ct_ptr pt_ptr ct key1_ptr key2_ptr iv_ptr iv len k00 k01 k02 k03 k04 k05 k06 k07 k08 k09 k0a k0b k0c k0d k0e @@ -4374,7 +5820,7 @@ let AES_XTS_DECRYPT_LT_6BLOCK_CORRECT = time prove( nonoverlapping (word pc, LENGTH aes_xts_decrypt_mc) (pt_ptr, val len) /\ nonoverlapping (ct_ptr, val len) (pt_ptr, val len) /\ nonoverlapping (key1_ptr, 260) (pt_ptr, val len) - /\ val len >= 16 /\ val len < 0x60 /\ LENGTH ct = val len + /\ ~(val len < 0x50) /\ val len < 0x60 /\ LENGTH ct = val len /\ [k00; k01; k02; k03; k04; k05; k06; k07; k08; k09; k0a; k0b; k0c; k0d; k0e] = key1 /\ [k10; k11; k12; k13; k14; k15; k16; k17; k18; k19; k1a; k1b; k1c; k1d; k1e] = key2 ==> ensures arm @@ -4393,7 +5839,323 @@ let AES_XTS_DECRYPT_LT_6BLOCK_CORRECT = time prove( MAYCHANGE [Q8; Q9; Q10; Q11; Q12; Q13; Q14; Q15],, MAYCHANGE [memory :> bytes(pt_ptr, val len)]) `, - CHEAT_TAC);; + REWRITE_TAC [(REWRITE_CONV [aes_xts_decrypt_mc] THENC LENGTH_CONV) `LENGTH aes_xts_decrypt_mc`] THEN + REWRITE_TAC[set_key_schedule; C_ARGUMENTS; SOME_FLAGS; + NONOVERLAPPING_CLAUSES; byte_list_at; + MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI] THEN + REPEAT STRIP_TAC THEN + + SUBGOAL_THEN `word_add (word_and len (word 0xf)) + (word_and len (word 0xfffffffffffffff0)) = len:int64` ASSUME_TAC THENL + [REWRITE_TAC[word_split_lemma]; ALL_TAC] THEN + ABBREV_TAC `num_blocks:int64 = word_and len (word 0xfffffffffffffff0)` THEN + ABBREV_TAC `tail_len:int64 = word_and len (word 0xf)` THEN + ABBREV_TAC `num_blocks_adjusted = if val (tail_len:int64) = 0 + then num_blocks else word_sub (num_blocks:int64) (word 0x10)` THEN + ABBREV_TAC `num_5blocks_adjusted = (word (val (num_blocks_adjusted:int64) DIV 0x50)):int64` THEN + + SUBGOAL_THEN `val (num_blocks:int64) = 0x50` ASSUME_TAC THENL + [ EXPAND_TAC "num_blocks" THEN + REWRITE_TAC[NUM_BLOCKS_TO_VAL] THEN + IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN + CONV_TAC NUM_REDUCE_CONV THEN + SUBGOAL_THEN `val (len:int64) DIV 16 = 5` SUBST1_TAC THENL + [ MATCH_MP_TAC(MESON[LE_ANTISYM] `m <= n /\ n <= m ==> m = n`) THEN + CONJ_TAC THENL [ ASM_ARITH_TAC; ASM_ARITH_TAC]; + ALL_TAC] THEN + ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `val (num_blocks_adjusted:int64) < 0x60` ASSUME_TAC THENL + [ EXPAND_TAC "num_blocks_adjusted" THEN + COND_CASES_TAC THENL[ + ASM_ARITH_TAC; + UNDISCH_TAC `val (num_blocks:int64) = 0x50` THEN + WORD_ARITH_TAC] + ; ALL_TAC] THEN + + ENSURES_SEQUENCE_TAC `pc + 0xa0c` + `\s. + read X0 s = word_add ct_ptr (word (acc_len num_5blocks_adjusted num_blocks_adjusted)) /\ + read X1 s = word_add pt_ptr (word (acc_len num_5blocks_adjusted num_blocks_adjusted)) /\ + read X3 s = key1_ptr /\ + read X21 s = tail_len /\ + read Q6 s = calculate_tweak (acc_blocks num_5blocks_adjusted num_blocks_adjusted T) iv key2 /\ + read X19 s = word 0x87 /\ + read Q16 s = k00 /\ read Q17 s = k01 /\ read Q12 s = k02 /\ read Q13 s = k03 /\ + read Q14 s = k04 /\ read Q15 s = k05 /\ read Q4 s = k06 /\ read Q5 s = k07 /\ + read Q18 s = k08 /\ read Q19 s = k09 /\ read Q20 s = k0a /\ read Q21 s = k0b /\ + read Q22 s = k0c /\ read Q23 s = k0d /\ read Q7 s = k0e /\ + byte_list_at ct ct_ptr len s /\ + byte_list_at (aes256_xts_decrypt ct (acc_len num_5blocks_adjusted num_blocks_adjusted) iv key1 key2) + pt_ptr (word (acc_len num_5blocks_adjusted num_blocks_adjusted)) s` THEN + CONJ_TAC THENL + [ + MATCH_MP_TAC ENSURES_FRAME_SUBSUMED THEN + EXISTS_TAC `MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI ,, + MAYCHANGE [X19; X20; X21; X22],, + MAYCHANGE [Q8; Q9; Q10; Q11; Q12; Q13; Q14; Q15],, + MAYCHANGE [ memory :> bytes128 pt_ptr; + memory :> bytes128 (word_add pt_ptr (word 16)); + memory :> bytes128 (word_add pt_ptr (word 32)); + memory :> bytes128 (word_add pt_ptr (word 48)); + memory :> bytes128 (word_add pt_ptr (word 64))]` THEN + REWRITE_TAC[MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI] THEN + CONJ_TAC THENL [ + REPEAT (GEN_REWRITE_TAC ONCE_DEPTH_CONV [GSYM SEQ_ASSOC] THEN + MATCH_MP_TAC SUBSUMED_SEQ THEN REWRITE_TAC[SUBSUMED_REFL]) THEN + ABBREV_TAC `vallen = val (len:int64)` THEN + SUBSUMED_MAYCHANGE_TAC; ALL_TAC] THEN + + REWRITE_TAC[byte_list_at] THEN + ENSURES_INIT_TAC "s0" THEN + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (1--2) THEN + + (* Discharge if condition *) + SUBGOAL_THEN + `ival (word_sub (len:int64) (word 0x10)) < &0x0 + <=> ~(ival (len:int64) - &0x10 = ival (word_sub (len:int64) (word 0x10)))` MP_TAC THENL + [ MP_TAC (BITBLAST_RULE + `~(val (len:int64) < 0x50) ==> val len < 0x60 ==> + ival (word_sub len (word 0x10)) >= &0x0`) THEN + ASM_REWRITE_TAC[] THEN + MP_TAC (BITBLAST_RULE + `~(val (len:int64) < 0x50) ==> val len < 0x60 ==> + ival (len:int64) - &0x10 = ival (word_sub len (word 0x10))`) THEN + ASM_REWRITE_TAC[] THEN + ARITH_TAC; + ALL_TAC] THEN + ASM_REWRITE_TAC[] THEN DISCH_TAC THEN + POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th])) THEN + + MP_TAC (SPECL [`ct_ptr:int64`; `len:int64`; `ct:byte list`; `s2:armstate`] READ_LT_6BLOCK) THEN + ASM_SIMP_TAC[] THEN REPEAT STRIP_TAC THEN + + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (3--69) THEN + (* Prove Q6 stores initial tweak *) + FIRST_X_ASSUM(MP_TAC o SPEC `(calculate_tweak 0 iv key2)` + o MATCH_MP (MESON[] `read Q6 s = a ==> !a'. a = a' ==> read Q6 s = a'`)) THEN + ANTS_TAC THENL + [ REWRITE_TAC[CONJUNCT1 calculate_tweak; xts_init_tweak] THEN + EXPAND_TAC "key2" THEN AESENC_TAC; DISCH_TAC] THEN + + (* Simulating until branch for num_blocks adjustment *) + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (70--89) THEN + + (* Case split on whether there is a tail *) + FIRST_X_ASSUM MP_TAC THEN + COND_CASES_TAC THENL + [ + DISCH_TAC THEN + + SUBGOAL_THEN `val (tail_len:int64) = 0` SUBST_ALL_TAC THENL + [ UNDISCH_TAC `val (word_and (tail_len:int64) (word 0xf)) = 0x0` THEN + MP_TAC (SPECL [`len:int64`; `tail_len:int64`] TAIL_LEN_BOUND_THM) THEN + ASM_SIMP_TAC[] THEN DISCH_TAC THEN + SUBGOAL_THEN `val (word_and (tail_len:int64) (word 15)) = val tail_len` SUBST1_TAC THENL + [ REWRITE_TAC[VAL_WORD_AND_MASK_WORD; ARITH_RULE `15 = 2 EXP 4 - 1`] THEN + CONV_TAC NUM_REDUCE_CONV THEN ASM_REWRITE_TAC[] THEN + IMP_REWRITE_TAC[MOD_LT]; + ALL_TAC] THEN + SIMP_TAC[]; ALL_TAC] THEN + CONV_TAC NUM_REDUCE_CONV THEN + + SUBGOAL_THEN `val (num_blocks_adjusted:int64) = 0x50` ASSUME_TAC THENL + [ EXPAND_TAC "num_blocks_adjusted" THEN + CONV_TAC NUM_REDUCE_CONV THEN + ASM_REWRITE_TAC[] + ; ALL_TAC ] THEN + SUBGOAL_THEN `val (num_5blocks_adjusted:int64) = 1` ASSUME_TAC THENL + [ EXPAND_TAC "num_5blocks_adjusted" THEN + UNDISCH_TAC `val (num_blocks_adjusted:int64) = 0x50` THEN + SIMP_TAC[] THEN DISCH_TAC THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[VAL_WORD_1] + ; ALL_TAC ] THEN + SUBGOAL_THEN `~(val (word_sub (word_sub (num_blocks:int64) (word 0x50)) (word 0x40)) = 0x0)` ASSUME_TAC THENL + [ SUBGOAL_THEN `num_blocks:int64 = word 0x50` ASSUME_TAC THENL + [ UNDISCH_TAC `val (num_blocks:int64) = 0x50` THEN + WORD_ARITH_TAC; ALL_TAC] THEN + ASM_REWRITE_TAC[] THEN + WORD_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `~(val (word_sub (word_sub (num_blocks:int64) (word 0x50)) (word 0x30)) = 0x0)` ASSUME_TAC THENL + [ SUBGOAL_THEN `num_blocks:int64 = word 0x50` ASSUME_TAC THENL + [ UNDISCH_TAC `val (num_blocks:int64) = 0x50` THEN + WORD_ARITH_TAC; ALL_TAC] THEN + ASM_REWRITE_TAC[] THEN + WORD_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `~(val (word_sub (word_sub (num_blocks:int64) (word 0x50)) (word 0x20)) = 0x0)` ASSUME_TAC THENL + [ SUBGOAL_THEN `num_blocks:int64 = word 0x50` ASSUME_TAC THENL + [ UNDISCH_TAC `val (num_blocks:int64) = 0x50` THEN + WORD_ARITH_TAC; ALL_TAC] THEN + ASM_REWRITE_TAC[] THEN + WORD_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `~(val (word_sub (word_sub (num_blocks:int64) (word 0x50)) (word 0x10)) = 0x0)` ASSUME_TAC THENL + [ SUBGOAL_THEN `num_blocks:int64 = word 0x50` ASSUME_TAC THENL + [ UNDISCH_TAC `val (num_blocks:int64) = 0x50` THEN + WORD_ARITH_TAC; ALL_TAC] THEN + ASM_REWRITE_TAC[] THEN + WORD_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `val (word_sub (num_blocks:int64) (word 0x50)) = 0x0` ASSUME_TAC THENL + [ SUBGOAL_THEN `num_blocks:int64 = word 0x50` ASSUME_TAC THENL + [ UNDISCH_TAC `val (num_blocks:int64) = 0x50` THEN + WORD_ARITH_TAC; ALL_TAC] THEN + ASM_REWRITE_TAC[] THEN + WORD_ARITH_TAC; ALL_TAC] THEN + + TWEAK_TAC `Q8:(armstate,int128)component` `1:num` `0:num` THEN + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (90--105) THEN + TWEAK_TAC `Q9:(armstate,int128)component` `2:num` `1:num` THEN + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (106--113) THEN + TWEAK_TAC `Q10:(armstate,int128)component` `3:num` `2:num` THEN + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (114--119) THEN + TWEAK_TAC `Q11:(armstate,int128)component` `4:num` `3:num` THEN + + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (120--273) THEN + XTSDEC_TAC `Q0:(armstate,int128)component` `0` `0` THEN + TWEAK_TAC `Q6:(armstate,int128)component` `5:num` `4:num` THEN + + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (274--281) THEN + XTSDEC_TAC `Q1:(armstate,int128)component` `0x10` `1` THEN + TWEAK_TAC `Q8:(armstate,int128)component` `6:num` `5:num` THEN + + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (282--289) THEN + XTSDEC_TAC `Q24:(armstate,int128)component` `0x20` `2` THEN + TWEAK_TAC `Q9:(armstate,int128)component` `7:num` `6:num` THEN + + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (290--297) THEN + XTSDEC_TAC `Q25:(armstate,int128)component` `0x30` `3` THEN + TWEAK_TAC `Q10:(armstate,int128)component` `8:num` `7:num` THEN + + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (298--305) THEN + XTSDEC_TAC `Q26:(armstate,int128)component` `0x40` `4` THEN + TWEAK_TAC `Q11:(armstate,int128)component` `9:num` `8:num` THEN + + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (306--320) THEN + + ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN + REPEAT CONJ_TAC THENL + [ + ASM_REWRITE_TAC[acc_len] THEN CONV_TAC NUM_REDUCE_CONV; + ASM_REWRITE_TAC[acc_len] THEN CONV_TAC NUM_REDUCE_CONV; + ASM_REWRITE_TAC[acc_blocks] THEN CONV_TAC NUM_REDUCE_CONV; + + ASM_REWRITE_TAC[acc_len] THEN + CONV_TAC NUM_REDUCE_CONV THEN + IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN + CONV_TAC NUM_REDUCE_CONV THEN + MP_TAC (SPECL [`0x50:num`; `pt_ptr:int64`; `(aes256_xts_decrypt ct 0x50 iv key1 key2):byte list`; + `s320:armstate`] BYTE_LIST_TO_NUM_THM) THEN + ANTS_TAC THENL[ + MP_TAC (SPECL [`5`; `ct:byte list`; `iv:int128`; `key1:int128 list`; + `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN + ARITH_TAC; ALL_TAC] THEN + DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN + IMP_REWRITE_TAC[READ_BYTES_EQ_READ_BYTE128_5BLOCKS] ] + ; ALL_TAC + ] THEN + + (* There is a tail *) + DISCH_TAC THEN + (* Prove ~ tail_len = 0 *) + SUBGOAL_THEN `~(val (tail_len:int64) = 0)` ASSUME_TAC THENL + [ UNDISCH_TAC `~(val (word_and (tail_len:int64) (word 0xf)) = 0x0)` THEN + MP_TAC (SPECL [`len:int64`; `tail_len:int64`] TAIL_LEN_BOUND_THM) THEN + ASM_REWRITE_TAC[] THEN + SUBST1_TAC(ARITH_RULE `0xf = 2 EXP 4 - 1`) THEN + REWRITE_TAC[VAL_WORD_AND_MASK_WORD] THEN + NUM_REDUCE_TAC THEN IMP_REWRITE_TAC[MOD_LT] + ; ALL_TAC] THEN + (* Prove num_blocks_adjusted = word_sub num_blocks (word 0x10) *) + SUBGOAL_THEN `word_sub num_blocks (word 0x10) = num_blocks_adjusted:int64` ASSUME_TAC THENL + [ UNDISCH_TAC `(if val (tail_len:int64) = 0x0 + then (num_blocks:int64) + else word_sub num_blocks (word 0x10)) = num_blocks_adjusted` THEN + ASM_REWRITE_TAC[]; ALL_TAC] THEN + SUBGOAL_THEN `val (num_blocks_adjusted:int64) = 0x40` ASSUME_TAC THENL + [ EXPAND_TAC "num_blocks_adjusted" THEN + UNDISCH_TAC `val (num_blocks:int64) = 0x50` THEN + WORD_ARITH_TAC + ; ALL_TAC ] THEN + SUBGOAL_THEN `val (num_5blocks_adjusted:int64) = 0` ASSUME_TAC THENL + [ EXPAND_TAC "num_5blocks_adjusted" THEN + REWRITE_TAC[ASSUME `val (num_blocks_adjusted:int64) = 0x40`] THEN + WORD_ARITH_TAC + ; ALL_TAC ] THEN + + TWEAK_TAC `Q8:(armstate,int128)component` `1:num` `0:num` THEN + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (90--92) THEN + (* Discharge if condition *) + SUBGOAL_THEN + `ival (word_sub (num_blocks_adjusted:int64) (word 0x10)) < &0x0 <=> + ~(ival (num_blocks_adjusted:int64) - &0x10 = + ival (word_sub (num_blocks_adjusted:int64) (word 0x10)))` MP_TAC THENL + [ SUBGOAL_THEN `num_blocks_adjusted:int64 = (word 0x40)` SUBST1_TAC THENL + [ UNDISCH_TAC `val (num_blocks_adjusted:int64) = 0x40` THEN + WORD_ARITH_TAC; ALL_TAC] THEN + WORD_ARITH_TAC + ; ALL_TAC] THEN + DISCH_TAC THEN + POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th])) THEN + + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (93--108) THEN + TWEAK_TAC `Q9:(armstate,int128)component` `2:num` `1:num` THEN + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (109--116) THEN + TWEAK_TAC `Q10:(armstate,int128)component` `3:num` `2:num` THEN + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (117--238) THEN + XTSDEC_TAC `Q0:(armstate,int128)component` `0` `0` THEN + XTSDEC_TAC `Q1:(armstate,int128)component` `0x10` `1` THEN + XTSDEC_TAC `Q24:(armstate,int128)component` `0x20` `2` THEN + XTSDEC_TAC `Q25:(armstate,int128)component` `0x30` `3` THEN + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (239--249) THEN + TWEAK_TAC `Q6:(armstate,int128)component` `4:num` `3:num` THEN + + ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN + REPEAT CONJ_TAC THENL + [ + ASM_REWRITE_TAC[acc_len] THEN + CONV_TAC NUM_REDUCE_CONV; + ASM_REWRITE_TAC[acc_len] THEN + CONV_TAC NUM_REDUCE_CONV; + ASM_REWRITE_TAC[acc_blocks] THEN CONV_TAC NUM_REDUCE_CONV; + + ASM_REWRITE_TAC[acc_len] THEN + CONV_TAC NUM_REDUCE_CONV THEN + IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN + CONV_TAC NUM_REDUCE_CONV THEN + MP_TAC (SPECL [`0x40:num`; `pt_ptr:int64`; `(aes256_xts_decrypt ct 0x40 iv key1 key2):byte list`; + `s249:armstate`] BYTE_LIST_TO_NUM_THM) THEN + ANTS_TAC THENL[ + MP_TAC (SPECL [`4`; `ct:byte list`; `iv:int128`; + `key1:int128 list`; `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN + ARITH_TAC; ALL_TAC] THEN + DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN + IMP_REWRITE_TAC[READ_BYTES_EQ_READ_BYTE128_4BLOCKS] + ]; ALL_TAC + ] THEN + + (* Reuse the cipher stealing proof *) + MP_TAC CIPHER_STEALING_CORRECT THEN + REWRITE_TAC [(REWRITE_CONV [aes_xts_decrypt_mc] THENC LENGTH_CONV) `LENGTH aes_xts_decrypt_mc`] THEN + REWRITE_TAC[set_key_schedule; C_ARGUMENTS; SOME_FLAGS; + NONOVERLAPPING_CLAUSES; byte_list_at; + MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI] THEN + DISCH_THEN MATCH_MP_TAC THEN + EXISTS_TAC `(word 0x50):int64` THEN + ASM_SIMP_TAC[] THEN + SUBGOAL_THEN `num_blocks:int64 = word 0x50` ASSUME_TAC THENL + [ UNDISCH_TAC `val (num_blocks:int64) = 0x50` THEN + WORD_ARITH_TAC; ALL_TAC] THEN + REPEAT CONJ_TAC THENL [ + ASM_ARITH_TAC; + ASM_ARITH_TAC; + EXPAND_TAC "len" THEN AP_TERM_TAC THEN + UNDISCH_TAC `val (num_blocks:int64) = 0x50` THEN + WORD_ARITH_TAC; + ASM_SIMP_TAC[]; + EXPAND_TAC "num_blocks_adjusted" THEN + REWRITE_TAC[ASSUME `num_blocks:int64 = word 0x50`] + ] +);; + let AES_XTS_DECRYPT_CORRECT = time prove( @@ -4468,18 +6230,6 @@ let AES_XTS_DECRYPT_CORRECT = time prove( block at the end together with the tail to be processed for cipherstealing *) ASM_CASES_TAC `val (len:int64) < 0x60` THENL [ - ASM_CASES_TAC `val (len:int64) = 16` THENL - [ - MP_TAC AES_XTS_DECRYPT_EQ_1BLOCK_CORRECT THEN - REWRITE_TAC [(REWRITE_CONV [aes_xts_decrypt_mc] THENC LENGTH_CONV) `LENGTH aes_xts_decrypt_mc`] THEN - REWRITE_TAC[set_key_schedule; C_ARGUMENTS; SOME_FLAGS; - NONOVERLAPPING_CLAUSES; byte_list_at; - MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI] THEN - DISCH_THEN MATCH_MP_TAC THEN - ASM_SIMP_TAC[]; - ALL_TAC - ] THEN - ASM_CASES_TAC `val (len:int64) < 0x20` THENL [ MP_TAC AES_XTS_DECRYPT_LT_2BLOCK_CORRECT THEN @@ -4570,7 +6320,8 @@ let AES_XTS_DECRYPT_CORRECT = time prove( ; ALL_TAC] THEN SUBGOAL_THEN `val (num_blocks_adjusted:int64) <= 2 EXP 24` ASSUME_TAC THENL [ UNDISCH_TAC `val (num_blocks:int64) <= 2 EXP 24` THEN - UNDISCH_TAC `~(val (num_blocks:int64) < 96)` THEN + SUBGOAL_THEN `~(val (num_blocks:int64) < 16)` MP_TAC THENL + [UNDISCH_TAC `~(val (num_blocks:int64) < 96)` THEN ARITH_TAC; ALL_TAC] THEN UNDISCH_TAC `(if val (tail_len:int64) = 0x0 then (num_blocks:int64) else word_sub num_blocks (word 0x10)) = @@ -4600,7 +6351,8 @@ let AES_XTS_DECRYPT_CORRECT = time prove( [ EXPAND_TAC "num_blocks_adjusted" THEN COND_CASES_TAC THENL [ ASM_SIMP_TAC[]; - UNDISCH_TAC `~(val (num_blocks:int64) < 0x60)` THEN + SUBGOAL_THEN `~(val (num_blocks:int64) < 16)` MP_TAC THENL + [UNDISCH_TAC `~(val (num_blocks:int64) < 96)` THEN ARITH_TAC; ALL_TAC] THEN UNDISCH_TAC `word_and (len:int64) (word 0xfffffffffffffff0) = (num_blocks:int64)` THEN MP_TAC (SPECL [`len:int64`; `num_blocks:int64`] NUM_BLOCKS_ADJUSTED_LT_LEN_THM) THEN SIMP_TAC[]]; ALL_TAC] THEN @@ -4839,8 +6591,6 @@ let AES_XTS_DECRYPT_CORRECT = time prove( read X21 s = tail_len /\ read Q6 s = calculate_tweak (acc_blocks num_5blocks_adjusted num_blocks_adjusted T) iv key2 /\ read X19 s = word 0x87 /\ - read X10 s = word_subword (calculate_tweak (acc_blocks num_5blocks_adjusted num_blocks_adjusted F) iv key2) (64,64) /\ - read X9 s = word_zx (calculate_tweak (acc_blocks num_5blocks_adjusted num_blocks_adjusted F) iv key2) /\ read Q16 s = k00 /\ read Q17 s = k01 /\ read Q12 s = k02 /\ read Q13 s = k03 /\ read Q14 s = k04 /\ read Q15 s = k05 /\ read Q4 s = k06 /\ read Q5 s = k07 /\ read Q18 s = k08 /\ read Q19 s = k09 /\ read Q20 s = k0a /\ read Q21 s = k0b /\ @@ -5485,8 +7235,6 @@ let AES_XTS_DECRYPT_CORRECT = time prove( REWRITE_TAC[acc_len] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; REWRITE_TAC[acc_len] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; REWRITE_TAC[acc_blocks] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; - REWRITE_TAC[acc_blocks] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; - REWRITE_TAC[acc_blocks] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; REWRITE_TAC[acc_len] THEN ASM_SIMP_TAC[LE_REFL] THEN SUBGOAL_THEN `val ((word (0x50 * val (num_5blocks_adjusted:int64) + 0x40)):int64) = @@ -5848,8 +7596,6 @@ let AES_XTS_DECRYPT_CORRECT = time prove( REWRITE_TAC[acc_len] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; REWRITE_TAC[acc_len] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; REWRITE_TAC[acc_blocks] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; - REWRITE_TAC[acc_blocks] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; - REWRITE_TAC[acc_blocks] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; REWRITE_TAC[acc_len] THEN ASM_SIMP_TAC[LE_REFL] THEN SUBGOAL_THEN `val ((word (0x50 * val (num_5blocks_adjusted:int64) + 0x30)):int64) = @@ -6149,8 +7895,6 @@ let AES_XTS_DECRYPT_CORRECT = time prove( REWRITE_TAC[acc_len] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; REWRITE_TAC[acc_len] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; REWRITE_TAC[acc_blocks] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; - REWRITE_TAC[acc_blocks] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; - REWRITE_TAC[acc_blocks] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; REWRITE_TAC[acc_len] THEN ASM_SIMP_TAC[LE_REFL] THEN SUBGOAL_THEN `val ((word (0x50 * val (num_5blocks_adjusted:int64) + 0x20)):int64) = 0x50 * val num_5blocks_adjusted + 0x20` ASSUME_TAC THENL @@ -6393,8 +8137,6 @@ let AES_XTS_DECRYPT_CORRECT = time prove( REWRITE_TAC[acc_len] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; REWRITE_TAC[acc_len] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; REWRITE_TAC[acc_blocks] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; - REWRITE_TAC[acc_blocks] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; - REWRITE_TAC[acc_blocks] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; REWRITE_TAC[acc_len] THEN ASM_SIMP_TAC[LE_REFL] THEN SUBGOAL_THEN `val ((word (0x50 * val (num_5blocks_adjusted:int64) + 0x10)):int64) = @@ -6705,8 +8447,6 @@ let AES_XTS_DECRYPT_CORRECT = time prove( REWRITE_TAC[acc_len] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; REWRITE_TAC[acc_len] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; REWRITE_TAC[acc_blocks] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; - REWRITE_TAC[acc_blocks] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; - REWRITE_TAC[acc_blocks] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; REWRITE_TAC[acc_len] THEN ASM_SIMP_TAC[LE_REFL] ] ] (* End of loop invariant proof *) @@ -6718,5 +8458,6 @@ let AES_XTS_DECRYPT_CORRECT = time prove( NONOVERLAPPING_CLAUSES; byte_list_at; MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI] THEN DISCH_THEN MATCH_MP_TAC THEN + EXISTS_TAC `num_blocks:int64` THEN ASM_SIMP_TAC[] );; From d0ee7438a6853611f9e979e94af86cc95b4e3790 Mon Sep 17 00:00:00 2001 From: Yan Peng Date: Fri, 24 Oct 2025 15:17:24 -0700 Subject: [PATCH 052/132] Add the final subroutine theorem --- arm/proofs/aes_xts_decrypt.ml | 78 ++++++++++++++++++++++++----------- 1 file changed, 55 insertions(+), 23 deletions(-) diff --git a/arm/proofs/aes_xts_decrypt.ml b/arm/proofs/aes_xts_decrypt.ml index 2e22a9dc0..5eda1aba4 100644 --- a/arm/proofs/aes_xts_decrypt.ml +++ b/arm/proofs/aes_xts_decrypt.ml @@ -3809,18 +3809,18 @@ let CIPHER_STEALING_CORRECT = time prove( X1 points to starting of last full block of pt X13 points to tail of pt X20 points to tail of ct - X21 holds tail_len + X21 holds decreasing tail_len Q6 holds second to last tweak Q16 ... Q7 holds the key schedule for encryption Memory: ct_ptr points to the input - Memory: Up to the last block, the output matches the specification + Memory: Up to the second to last block, the output matches the specification Memory: For the last block, for each byte - [0,i) -- previous decrption result - [i,tail_len) -- equal corresponding ct tail bytes + [0,i) -- previous decryption result + [i,tail_len) -- equal corresponding ct tail bytes, Cm [tail_len,16] -- previous decryption result Memory: For the tail, for each byte - [i,tail_len) -- copied over from last pt block + [i,tail_len) -- copied over from Pm block *) ENSURES_WHILE_PADOWN_TAC `val (tail_len:int64)` @@ -4012,8 +4012,9 @@ let CIPHER_STEALING_CORRECT = time prove( ; ALL_TAC] THEN POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th])) THEN - (* case analysis based on i = 0 ... 14, this is unavoidable because symbolic execution - needs to know which byte is being overwritten in pt_ptr to properly update the state. *) + (* case analysis based on i = 0 ... 14, because symbolic execution + needs to know which byte is being overwritten in pt_ptr to properly update the state. + TODO: Think about a way to avoid the case split *) MAP_EVERY (fun i -> TAIL_SWAP_ASM_CASES_TAC (mk_numeral (num i))) (0--14) THEN UNDISCH_TAC `15 <= i` THEN UNDISCH_TAC `i < val (tail_len:int64)` THEN @@ -6192,22 +6193,6 @@ let AES_XTS_DECRYPT_CORRECT = time prove( MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI] THEN REPEAT STRIP_TAC THEN - (* These are for top-level wrapper function - (* Add values for preserved registers *) - ENSURES_PRESERVED_TAC "x19_init" `X19` THEN - ENSURES_PRESERVED_TAC "x20_init" `X20` THEN - ENSURES_PRESERVED_TAC "x21_init" `X21` THEN - ENSURES_PRESERVED_TAC "x22_init" `X22` THEN - ENSURES_PRESERVED_DREG_TAC "d8_init" `D8` THEN - ENSURES_PRESERVED_DREG_TAC "d9_init" `D9` THEN - ENSURES_PRESERVED_DREG_TAC "d10_init" `D10` THEN - ENSURES_PRESERVED_DREG_TAC "d11_init" `D11` THEN - ENSURES_PRESERVED_DREG_TAC "d12_init" `D12` THEN - ENSURES_PRESERVED_DREG_TAC "d13_init" `D13` THEN - ENSURES_PRESERVED_DREG_TAC "d14_init" `D14` THEN - ENSURES_PRESERVED_DREG_TAC "d15_init" `D15` THEN -*) - (* Break len into full blocks and tail *) SUBGOAL_THEN `word_add (word_and len (word 0xf)) (word_and len (word 0xfffffffffffffff0)) = len:int64` ASSUME_TAC THENL @@ -8461,3 +8446,50 @@ let AES_XTS_DECRYPT_CORRECT = time prove( EXISTS_TAC `num_blocks:int64` THEN ASM_SIMP_TAC[] );; + + +let AES_XTS_DECRYPT_SUBROUTINE_CORRECT = time prove + (`!ct_ptr pt_ptr ct key1_ptr key2_ptr iv_ptr iv len + k00 k01 k02 k03 k04 k05 k06 k07 k08 k09 k0a k0b k0c k0d k0e + k10 k11 k12 k13 k14 k15 k16 k17 k18 k19 k1a k1b k1c k1d k1e + pc stackpointer returnaddress. + aligned 16 stackpointer + /\ ALL (nonoverlapping (word_sub stackpointer (word 96), 96)) + [ (word pc, LENGTH aes_xts_decrypt_mc); + (ct_ptr, val len); (key1_ptr, 260); + (key2_ptr, 260); (iv_ptr, 16); + (pt_ptr, val len)] + /\ nonoverlapping (word pc, LENGTH aes_xts_decrypt_mc) (pt_ptr, val len) + /\ nonoverlapping (ct_ptr, val len) (pt_ptr, val len) + /\ nonoverlapping (key1_ptr, 260) (pt_ptr, val len) + /\ val len >= 16 /\ val len <= 2 EXP 24 /\ LENGTH ct = val len + ==> ensures arm + (\s. aligned_bytes_loaded s (word pc) aes_xts_decrypt_mc /\ + read PC s = word pc /\ + read SP s = stackpointer /\ + read X30 s = returnaddress /\ + C_ARGUMENTS [ct_ptr; pt_ptr; len; key1_ptr; key2_ptr; iv_ptr] s /\ + byte_list_at ct ct_ptr len s /\ + read(memory :> bytes128 iv_ptr) s = iv /\ + set_key_schedule s key1_ptr k00 k01 k02 k03 k04 k05 k06 k07 k08 k09 k0a k0b k0c k0d k0e /\ + set_key_schedule s key2_ptr k10 k11 k12 k13 k14 k15 k16 k17 k18 k19 k1a k1b k1c k1d k1e) + (\s. read PC s = returnaddress /\ + byte_list_at (aes256_xts_decrypt ct (val len) iv + [k00; k01; k02; k03; k04; k05; k06; k07; k08; k09; k0a; k0b; k0c; k0d; k0e] + [k10; k11; k12; k13; k14; k15; k16; k17; k18; k19; k1a; k1b; k1c; k1d; k1e]) + pt_ptr len s + ) + (MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI,, + MAYCHANGE [memory :> bytes(pt_ptr, val len); + memory :> bytes(word_sub stackpointer (word 96), 96)])`, + REWRITE_TAC[byte_list_at; set_key_schedule; + fst AES_XTS_DECRYPT_EXEC] THEN + (* ~pre_post_nsteps:(7,7): 7 instructions before and after program body + for handling stack. + 96: the byte size occupied on stack for storing preserved registers *) + ARM_ADD_RETURN_STACK_TAC + ~pre_post_nsteps:(7,7) AES_XTS_DECRYPT_EXEC + (REWRITE_RULE[byte_list_at; set_key_schedule; + fst AES_XTS_DECRYPT_EXEC] AES_XTS_DECRYPT_CORRECT) + `[X19; X20; X21; X22; D8; D9; D10; D11; D12; D13; D14; D15]` 96 + );; From 13d85bacae1ee0c05f6d234c9ae1720983cb3601 Mon Sep 17 00:00:00 2001 From: Yan Peng Date: Fri, 31 Oct 2025 10:26:00 -0700 Subject: [PATCH 053/132] Thanks for John Harrison, cleaning up the last CHEAT_TAC --- arm/proofs/aes_encrypt_spec.ml | 2 ++ arm/proofs/aes_xts_decrypt.ml | 32 +++++++++----------------------- 2 files changed, 11 insertions(+), 23 deletions(-) diff --git a/arm/proofs/aes_encrypt_spec.ml b/arm/proofs/aes_encrypt_spec.ml index f1a74c4ad..184d2ba81 100644 --- a/arm/proofs/aes_encrypt_spec.ml +++ b/arm/proofs/aes_encrypt_spec.ml @@ -85,6 +85,7 @@ let AESENC_ROUND_REDUCE_CONV tm = when is_numeral state && is_numeral roundkey -> AESENC_ROUND_HELPER_CONV tm | _ -> failwith "AESENC_ROUND_REDUCE_CONV: inapplicable";; +(* prove(`aes256_encrypt_round (word 0x7b5b54657374566563746f725d53475d) (word 0x48692853686179295b477565726f6e5d) = word 0xa8311c2f9fdba3c58b104b58ded7e595`, @@ -94,6 +95,7 @@ prove(`aes256_encrypt_round (word 0xAB60EEF6E1D04EC228EE8A3BF255FC0B) (word 0xF4DF1409A310982DD708613B072C351F) = word 0x416EAD9670A2C6D71CFE3FCCB03F10D9`, CONV_TAC(LAND_CONV AESENC_ROUND_REDUCE_CONV) THEN REFL_TAC);; +*) (* https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/AES_Core256.pdf diff --git a/arm/proofs/aes_xts_decrypt.ml b/arm/proofs/aes_xts_decrypt.ml index 5eda1aba4..81decffeb 100644 --- a/arm/proofs/aes_xts_decrypt.ml +++ b/arm/proofs/aes_xts_decrypt.ml @@ -4,8 +4,8 @@ *) use_file_raise_failure := true;; -arm_print_log := false;; -components_print_log := false;; +arm_print_log := true;; +components_print_log := true;; needs "arm/proofs/base.ml";; loadt "arm/proofs/aes_xts_decrypt_spec.ml";; @@ -4013,8 +4013,7 @@ let CIPHER_STEALING_CORRECT = time prove( POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th])) THEN (* case analysis based on i = 0 ... 14, because symbolic execution - needs to know which byte is being overwritten in pt_ptr to properly update the state. - TODO: Think about a way to avoid the case split *) + needs to know which byte is being overwritten in pt_ptr to properly update the state. *) MAP_EVERY (fun i -> TAIL_SWAP_ASM_CASES_TAC (mk_numeral (num i))) (0--14) THEN UNDISCH_TAC `15 <= i` THEN UNDISCH_TAC `i < val (tail_len:int64)` THEN @@ -6656,7 +6655,7 @@ let AES_XTS_DECRYPT_CORRECT = time prove( (* Subgoal 3: loop body *) REPEAT STRIP_TAC THEN - (* TODO: add a comment explaining what this bound is for *) + (* An arithmetic rule for discharging subgoal in the following ENSURES_FRAME_SUBSUMED tactic *) SUBGOAL_THEN `i * 0x50 + 0x50 <= val (len:int64)` ASSUME_TAC THENL [ SUBGOAL_THEN `i + 1 <= val (num_5blocks_adjusted:int64)` MP_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN @@ -7212,8 +7211,11 @@ let AES_XTS_DECRYPT_CORRECT = time prove( CHANGED_TAC (RULE_ASSUM_TAC(REWRITE_RULE [WORD_RULE `!base m n. word_add (word_add base (word m)) (word n) = word_add base (word(m + n))`])) THEN - (* TODO: Still have the same problem *) - ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (134--136) THEN + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (134--134) THEN + (* Need to simplify the expression for X1 after the first store instruction *) + CHANGED_TAC (RULE_ASSUM_TAC(REWRITE_RULE + [WORD_RULE `!base m n. word_add (word_add base (word m)) (word n) = word_add base (word(m + n))`])) THEN + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (135--136) THEN ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN REPEAT CONJ_TAC THENL [ @@ -7230,22 +7232,6 @@ let AES_XTS_DECRYPT_CORRECT = time prove( ARITH_TAC; ALL_TAC] THEN POP_ASSUM(fun th -> REWRITE_TAC[th]) THEN - (* TODO: Manually add the assumption as a temporary fix *) - SUBGOAL_THEN `read - (memory :> - bytes128 - (word_add (pt_ptr:int64) (word (0x50 * val (num_5blocks_adjusted:int64) + 0x20)))) - s136 = - aes256_xts_decrypt_round - (bytes_to_int128 - (SUB_LIST (val num_5blocks_adjusted * 0x50 + 0x20,0x10) ct)) - (calculate_tweak (val num_5blocks_adjusted * 0x5 + 0x2) iv key2) - key1` ASSUME_TAC THENL [CHEAT_TAC; ALL_TAC] THEN - (* TODO: ??? *) - RULE_ASSUM_TAC(REWRITE_RULE - [WORD_RULE `(word_add (word_add pt_ptr (word (0x50 * val num_5blocks_adjusted))) - (word 0x30)) = (word_add (pt_ptr:int64) (word (0x50 * val (num_5blocks_adjusted:int64) + 0x30)))`]) THEN - (* Remove quantifier *) UNDISCH_TAC `forall i. From d476108116815b4ea925c41f88b86cd577437442 Mon Sep 17 00:00:00 2001 From: Yan Peng Date: Fri, 14 Feb 2025 01:00:34 +0000 Subject: [PATCH 054/132] More experiments --- arm/proofs/aes-xts.ml | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 arm/proofs/aes-xts.ml diff --git a/arm/proofs/aes-xts.ml b/arm/proofs/aes-xts.ml new file mode 100644 index 000000000..8a245be7a --- /dev/null +++ b/arm/proofs/aes-xts.ml @@ -0,0 +1,8 @@ +(* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT-0 + *) + +needs "arm/proofs/base.ml";; + +print_literal_from_elf "arm/aes-xts/aes-xts-armv8.o";; From 248e996f12a95da8b5e9bee3a0b417c7f389ede2 Mon Sep 17 00:00:00 2001 From: Nevine Ebeid Date: Sun, 6 Jul 2025 19:39:03 -0400 Subject: [PATCH 055/132] One block of AES-256-XTS encrypt: Spec and a test vector (using conversions). --- arm/proofs/aes_encrypt_spec.ml | 4 + arm/proofs/aes_xts_encrypt_spec.ml | 133 +++++++++++++++++++++++++++++ 2 files changed, 137 insertions(+) create mode 100644 arm/proofs/aes_xts_encrypt_spec.ml diff --git a/arm/proofs/aes_encrypt_spec.ml b/arm/proofs/aes_encrypt_spec.ml index 184d2ba81..30bf82d6f 100644 --- a/arm/proofs/aes_encrypt_spec.ml +++ b/arm/proofs/aes_encrypt_spec.ml @@ -7,6 +7,10 @@ let pp_print_num fmt tm = install_user_printer("pp_print_num",pp_print_num);; (* +// NIST FIPS 197 - Advanced Encryption Standard (AES) +// `Nb` = number of columns in the state (4 for AES) +// `Nr` = number of rounds (14 for AES-256) + Cipher(byte in[4*Nb], byte out[4*Nb], word w[Nb*(Nr+1)]) begin diff --git a/arm/proofs/aes_xts_encrypt_spec.ml b/arm/proofs/aes_xts_encrypt_spec.ml new file mode 100644 index 000000000..8abd977bc --- /dev/null +++ b/arm/proofs/aes_xts_encrypt_spec.ml @@ -0,0 +1,133 @@ +needs "arm/proofs/aes_encrypt_spec.ml";; +(* +AES-256-XTS Encryption Algorithm for One Block +Based on IEEE 1619-2007 Standard + +Sec 5.3.1 Encryption of a single block + +Key = Key1 256-bit data key + Key2 256-bit tweak key +P is a block of 128 bits (i.e., the plaintext) +i is the value of the 128-bit tweak (see 5.1) +j is the sequential number of the 128-bit block inside the data unit +C is the block of 128 bits of ciphertext resulting from the operation + +T := AES-enc(Key2 , i) XOR α^j +PP := P XOR T +CC := AES-enc(Key1 , PP) +C := CC XOR T + +j=0 => alpha^j = unity transformation, + i.e. no change to the encrypted tweak for the the first block +*) + +(* XTS encryption function definition *) +let aes256_xts_encrypt_one_block = new_definition + `aes256_xts_encrypt_one_block (plaintext:int128) (data_key_schedule:int128 list) + (tweak_key_schedule:int128 list) (tweak:int128) = + let T = aes256_encrypt tweak tweak_key_schedule in + let pre_encrypt = word_xor plaintext T in + let encrypted = aes256_encrypt pre_encrypt data_key_schedule in + word_xor encrypted T`;; + +(* Test case: Basic XTS encryption *) +(* +Test Vector: +Plaintext: 000102030405060708090a0b0c0d0e0f +Data Key: 2718281828459045235360287471352662497757247093699959574966967627 +Tweak Key: 3141592653589793238462643383279502884197169399375105820974944592 +Tweak: FF000000000000000000000000000000 +Expected: 1C3B3A102F770386E4836C99E370CF9B + +The test vector values appear in reverse byte order to be little endian. +*) +(* Test vectors based on our Python implementation results *) +let data_key_schedule = new_definition `data_key_schedule:int128 list = + [ word 0x26357174286053234590452818281827 + ; word 0x27769666495759996993702457774962 + ; word 0x602147C9461436BD6E74659E2BE420B6 + ; word 0x80385664A74EC002EE19999B878AE9BF + ; word 0x206833EF40497426065D429B68292705 + ; word 0xF9A0259D799873F9DED6B3FB30CF2A60 + ; word 0x50CCC26C70A4F18330ED85A536B0C73E + ; word 0x3D6AEAAFC4CACF32BD52BCCB63840F30 + ; word 0x5F1273FB0FDEB1977F7A40144F97C5B1 + ; word 0xE8BF1969D5D5F3C6111F3CF4AC4D803F + ; word 0x99BA4F0DC6A83CF6C9768D61B60CCD75 + ; word 0x6ECCD2B38673CBDA53A6381C42B904E8 + ; word 0x4DF7787AD44D377712E50B81DB9386E0 + ; word 0x1AC8994774044BF4F277802EA1D1B832 + ; word 0xF06E2AC2BD9952B869D465CF7B316E4E + ]`;; + +let tweak_key_schedule = new_definition `tweak_key_schedule:int128 list = + [ word 0x95278333646284239397585326594131 + ; word 0x92459474098205513799931697418802 + ; word 0xD6C4705143E3F36227817741B4162F12 + ; word 0xCD03DBE05F464F9456C44AC5615DD9D3 + ; word 0xE70DA0DB31C9D08A722A23E855AB54A9 + ; word 0x310BE7DBFC083C3BA34E73AFF58A396A + ; word 0x48822C80AF8F8C5B9E465CD1EC6C7F39 + ; word 0xC9D4E0E8F8DF073304D73B08A79948A7 + ; word 0x0EFACBDA4678E75AE9F76B0177B137D0 + ; word 0x39688B23F0BC6BCB08636CF80CB457F0 + ; word 0xF0D6357CFE2CFEA6B85419FC51A372FD + ; word 0x41F54DF0789DC6D38821AD188042C1E0 + ; word 0x6B8E46189B58736465748DC2DD20943E + ; word 0x4E12BD760FE7F086777A3655FF5B9B4D + ; word 0x70ADE5BA1B23A3A2807BD0C6E50F5D04 + ]`;; +(* +let AES_XTS_ENC_HELPER_CONV = + PRINT_TERM_CONV THENC + REWR_CONV aes256_xts_encrypt_one_block THENC + PRINT_TERM_CONV THENC + REWRITE_CONV [aes256_encrypt; data_key_schedule; tweak_key_schedule] THENC + PRINT_TERM_CONV THENC + REWRITE_CONV EL_15_128_CLAUSES THENC +(* PRINT_TERM_CONV THENC *) + REPEATC let_CONV THENC + DEPTH_CONV (WORD_RED_CONV ORELSEC NUM_RED_CONV) THENC + DEPTH_CONV AESENC_REDUCE_CONV (*THENC + AES_SHIFT_ROWS_CONV THENC + AES_SUB_BYTES_CONV THENC + PRINT_TERM_CONV THENC + DEPTH_CONV (WORD_RED_CONV ORELSEC NUM_RED_CONV) + *) + ;; +*) +let AES_XTS_ENC_HELPER_CONV = +(* PRINT_TERM_CONV THENC *) + REWR_CONV aes256_xts_encrypt_one_block THENC +(* PRINT_TERM_CONV THENC*) + REWRITE_CONV [data_key_schedule; tweak_key_schedule] THENC +(* PRINT_TERM_CONV THENC *) + REPEATC let_CONV THENC + DEPTH_CONV (WORD_RED_CONV ORELSEC NUM_RED_CONV) THENC + DEPTH_CONV AESENC_HELPER_CONV THENC + DEPTH_CONV (WORD_RED_CONV ORELSEC NUM_RED_CONV) + ;; + +(* Takes about a 100 sec on M3 *) +let tmp_xts = AES_XTS_ENC_HELPER_CONV + `aes256_xts_encrypt_one_block + (word 0x0F0E0D0C0B0A09080706050403020100) + data_key_schedule + tweak_key_schedule + (word 0x000000000000000000000000000000FF) + `;; + +prove(list_mk_comb (`(=):((128)word->(128)word->bool)`, + [rand (concl tmp_xts);`(word 0x9BCF70E3996C83E48603772F103A3B1C):(128)word`]), + REFL_TAC);; + +(* Takes about a 100 sec on M3 *) +time prove(`aes256_xts_encrypt_one_block + (word 0x0F0E0D0C0B0A09080706050403020100) + data_key_schedule + tweak_key_schedule + (word 0x000000000000000000000000000000FF) + = word 0x9BCF70E3996C83E48603772F103A3B1C`, (* expected result in little endian *) + CONV_TAC(LAND_CONV AES_XTS_ENC_HELPER_CONV) + THEN REFL_TAC + );; From 2cca201b8998f650880232c334bf0e7558bc07ec Mon Sep 17 00:00:00 2001 From: Nevine Ebeid Date: Mon, 7 Jul 2025 18:22:14 -0400 Subject: [PATCH 056/132] Adding new assembly for AES-XTS: - after merging pennyann's changes to the aws-lc branch https://github.com/nebeid/aws-lc/commits/aes-xts-slothy/ in commit 8a48d97 which have an updated cleaner assembly - and cherry picking pennyann's commit Add LDP/STP pre-index and post-index https://github.com/nebeid/s2n-bignum/commit/182bc754c558805a1ddcb959bb3896d037091dde The assembly was tested on M3 and was disassembled there and added in this commit. --- arm/aes-xts/Makefile | 3 +- arm/aes-xts/aes-xts-armv8.S | 2706 +++++++++------------------------ arm/aes-xts/aes-xts-armv8.txt | 1214 +++++---------- 3 files changed, 1063 insertions(+), 2860 deletions(-) diff --git a/arm/aes-xts/Makefile b/arm/aes-xts/Makefile index 4d41cd311..fd79d8372 100644 --- a/arm/aes-xts/Makefile +++ b/arm/aes-xts/Makefile @@ -30,7 +30,8 @@ endif OBJ = aes256_encrypt.o \ aes256_decrypt.o \ - aes_xts_decrypt_armv8.o + aes_xts_decrypt_armv8.o \ + aes-xts-armv8.o %.o : %.S ; $(CC) -E -I../../include $< | $(GAS) -o $@ - diff --git a/arm/aes-xts/aes-xts-armv8.S b/arm/aes-xts/aes-xts-armv8.S index 25701e691..043337e50 100644 --- a/arm/aes-xts/aes-xts-armv8.S +++ b/arm/aes-xts/aes-xts-armv8.S @@ -1,2031 +1,683 @@ -#include "_internal_s2n_bignum.h" - -# The following xts encrypt is from MacBook M3 build folder -# after moving around some instructions -_aes_hw_xts_encrypt: - # AARCH64_VALID_CALL_TARGET - cmp x2,#16 - // Original input data size bigger than 16, jump to big size processing. - b.ne Lxts_enc_big_size - // Encrypt the iv with key2, as the first XEX iv. - ldr w6,[x4,#240] - ld1 {v0.16b},[x4],#16 - ld1 {v6.16b},[x5] - sub w6,w6,#2 - ld1 {v1.16b},[x4],#16 - -Loop_enc_iv_enc: - aese v6.16b,v0.16b - aesmc v6.16b,v6.16b - ld1 {v0.4s},[x4],#16 - subs w6,w6,#2 - aese v6.16b,v1.16b - aesmc v6.16b,v6.16b - ld1 {v1.4s},[x4],#16 - b.gt Loop_enc_iv_enc - - aese v6.16b,v0.16b - aesmc v6.16b,v6.16b - ld1 {v0.4s},[x4] - aese v6.16b,v1.16b - eor v6.16b,v6.16b,v0.16b - - ld1 {v0.16b},[x0] - eor v0.16b,v6.16b,v0.16b - - ldr w6,[x3,#240] - ld1 {v28.4s,v29.4s},[x3],#32 // load key schedule... - - aese v0.16b,v28.16b - aesmc v0.16b,v0.16b - ld1 {v16.4s,v17.4s},[x3],#32 // load key schedule... - aese v0.16b,v29.16b - aesmc v0.16b,v0.16b - subs w6,w6,#10 //// if rounds==10, jump to aes-128-xts processing -// b.eq .Lxts_128_enc -Lxts_enc_round_loop: - aese v0.16b,v16.16b - aesmc v0.16b,v0.16b - ld1 {v16.4s},[x3],#16 // load key schedule... - aese v0.16b,v17.16b - aesmc v0.16b,v0.16b - ld1 {v17.4s},[x3],#16 // load key schedule... - subs w6,w6,#2 // bias - b.gt Lxts_enc_round_loop -//.Lxts_128_enc: - ld1 {v18.4s,v19.4s},[x3],#32 // load key schedule... - aese v0.16b,v16.16b - aesmc v0.16b,v0.16b - aese v0.16b,v17.16b - aesmc v0.16b,v0.16b - ld1 {v20.4s,v21.4s},[x3],#32 // load key schedule... - aese v0.16b,v18.16b - aesmc v0.16b,v0.16b - aese v0.16b,v19.16b - aesmc v0.16b,v0.16b - ld1 {v22.4s,v23.4s},[x3],#32 // load key schedule... - aese v0.16b,v20.16b - aesmc v0.16b,v0.16b - aese v0.16b,v21.16b - aesmc v0.16b,v0.16b - ld1 {v7.4s},[x3] - aese v0.16b,v22.16b - aesmc v0.16b,v0.16b - aese v0.16b,v23.16b - eor v0.16b,v0.16b,v7.16b - eor v0.16b,v0.16b,v6.16b - st1 {v0.16b},[x1] - b Lxts_enc_final_abort - -.align 4 -Lxts_enc_big_size: - // Encrypt input size > 16 bytes - stp x19,x20,[sp,#-64]! - stp x21,x22,[sp,#48] - stp d8,d9,[sp,#32] - stp d10,d11,[sp,#16] - - // tailcnt store the tail value of length%16. - and x21,x2,#0xf - and x2,x2,#-16 // len &= 0x1..110000, now divisible by 16 - subs x2,x2,#16 - mov x8,#16 - b.lo Lxts_abort // if !(len > 16): error - csel x8,xzr,x8,eq // if (len == 16): step = 0 - - // Firstly, encrypt the iv with key2, as the first iv of XEX. - ldr w6,[x4,#240] - ld1 {v0.4s},[x4],#16 - ld1 {v6.16b},[x5] - sub w6,w6,#2 - ld1 {v1.4s},[x4],#16 - -Loop_iv_enc: - aese v6.16b,v0.16b - aesmc v6.16b,v6.16b - ld1 {v0.4s},[x4],#16 - subs w6,w6,#2 - aese v6.16b,v1.16b - aesmc v6.16b,v6.16b - ld1 {v1.4s},[x4],#16 - b.gt Loop_iv_enc - - aese v6.16b,v0.16b - aesmc v6.16b,v6.16b - ld1 {v0.4s},[x4] - aese v6.16b,v1.16b - eor v6.16b,v6.16b,v0.16b - - // The iv for second block - // x9- iv(low), x10 - iv(high) - // the five ivs stored into, v6.16b,v8.16b,v9.16b,v10.16b,v11.16b - fmov x9,d6 - fmov x10,v6.d[1] - mov w19,#0x87 - extr x22,x10,x10,#32 - extr x10,x10,x9,#63 - and w11,w19,w22,asr#31 - eor x9,x11,x9,lsl#1 - fmov d8,x9 - fmov v8.d[1],x10 - - ldr w5,[x3,#240] // next starting point - ld1 {v0.16b},[x0],x8 - - ld1 {v16.4s,v17.4s},[x3] // load key schedule... - sub w5,w5,#6 - add x7,x3,x5,lsl#4 // pointer to last 7 round keys - ld1 {v18.4s,v19.4s},[x7],#32 - ld1 {v20.4s,v21.4s},[x7],#32 - ld1 {v22.4s,v23.4s},[x7],#32 - ld1 {v7.4s},[x7] - - sub w5,w5,#2 - add x7,x3,#32 - mov w6,w5 - - // Encryption -Lxts_enc: - ld1 {v24.16b},[x0],#16 - subs x2,x2,#32 // bias - add w6,w5,#2 - orr v3.16b,v0.16b,v0.16b - orr v1.16b,v0.16b,v0.16b - orr v28.16b,v0.16b,v0.16b - orr v27.16b,v24.16b,v24.16b - orr v29.16b,v24.16b,v24.16b - b.lo Lxts_inner_enc_tail // when input size % 5 = 1 or 2 - // (with tail or not) - eor v0.16b,v0.16b,v6.16b // before encryption, xor with iv - eor v24.16b,v24.16b,v8.16b - - // The iv for third block - extr x22,x10,x10,#32 - extr x10,x10,x9,#63 - and w11,w19,w22,asr#31 - eor x9,x11,x9,lsl#1 - fmov d9,x9 - fmov v9.d[1],x10 - - - orr v1.16b,v24.16b,v24.16b - ld1 {v24.16b},[x0],#16 - orr v2.16b,v0.16b,v0.16b - orr v3.16b,v1.16b,v1.16b - eor v27.16b,v24.16b,v9.16b // the third block - eor v24.16b,v24.16b,v9.16b - cmp x2,#32 - b.lo Lxts_outer_enc_tail - - // The iv for fourth block - extr x22,x10,x10,#32 - extr x10,x10,x9,#63 - and w11,w19,w22,asr#31 - eor x9,x11,x9,lsl#1 - fmov d10,x9 - fmov v10.d[1],x10 - - ld1 {v25.16b},[x0],#16 - // The iv for fifth block - extr x22,x10,x10,#32 - extr x10,x10,x9,#63 - and w11,w19,w22,asr#31 - eor x9,x11,x9,lsl#1 - fmov d11,x9 - fmov v11.d[1],x10 - - ld1 {v26.16b},[x0],#16 - eor v25.16b,v25.16b,v10.16b // the fourth block - eor v26.16b,v26.16b,v11.16b - sub x2,x2,#32 // bias - mov w6,w5 - // b .Loop5x_xts_enc - -.align 4 -Loop5x_xts_enc: - aese v0.16b,v16.16b - aesmc v0.16b,v0.16b - aese v1.16b,v16.16b - aesmc v1.16b,v1.16b - aese v24.16b,v16.16b - aesmc v24.16b,v24.16b - aese v25.16b,v16.16b - aesmc v25.16b,v25.16b - aese v26.16b,v16.16b - aesmc v26.16b,v26.16b - ld1 {v16.4s},[x7],#16 - subs w6,w6,#2 - aese v0.16b,v17.16b - aesmc v0.16b,v0.16b - aese v1.16b,v17.16b - aesmc v1.16b,v1.16b - aese v24.16b,v17.16b - aesmc v24.16b,v24.16b - aese v25.16b,v17.16b - aesmc v25.16b,v25.16b - aese v26.16b,v17.16b - aesmc v26.16b,v26.16b - ld1 {v17.4s},[x7],#16 - b.gt Loop5x_xts_enc - - aese v0.16b,v16.16b - aesmc v0.16b,v0.16b - aese v1.16b,v16.16b - aesmc v1.16b,v1.16b - aese v24.16b,v16.16b - aesmc v24.16b,v24.16b - aese v25.16b,v16.16b - aesmc v25.16b,v25.16b - aese v26.16b,v16.16b - aesmc v26.16b,v26.16b - subs x2,x2,#0x50 // because Lxts_enc_tail4x - - aese v0.16b,v17.16b - aesmc v0.16b,v0.16b - aese v1.16b,v17.16b - aesmc v1.16b,v1.16b - aese v24.16b,v17.16b - aesmc v24.16b,v24.16b - aese v25.16b,v17.16b - aesmc v25.16b,v25.16b - aese v26.16b,v17.16b - aesmc v26.16b,v26.16b - csel x6,xzr,x2,gt // borrow x6, w6, "gt" is not typo - mov x7,x3 - - aese v0.16b,v18.16b - aesmc v0.16b,v0.16b - aese v1.16b,v18.16b - aesmc v1.16b,v1.16b - aese v24.16b,v18.16b - aesmc v24.16b,v24.16b - aese v25.16b,v18.16b - aesmc v25.16b,v25.16b - aese v26.16b,v18.16b - aesmc v26.16b,v26.16b - add x0,x0,x6 // x0 is adjusted in such way that - // at exit from the loop v1.16b-v26.16b - // are loaded with last "words" - add x6,x2,#0x60 // because Lxts_enc_tail4x - - aese v0.16b,v19.16b - aesmc v0.16b,v0.16b - aese v1.16b,v19.16b - aesmc v1.16b,v1.16b - aese v24.16b,v19.16b - aesmc v24.16b,v24.16b - aese v25.16b,v19.16b - aesmc v25.16b,v25.16b - aese v26.16b,v19.16b - aesmc v26.16b,v26.16b - - aese v0.16b,v20.16b - aesmc v0.16b,v0.16b - aese v1.16b,v20.16b - aesmc v1.16b,v1.16b - aese v24.16b,v20.16b - aesmc v24.16b,v24.16b - aese v25.16b,v20.16b - aesmc v25.16b,v25.16b - aese v26.16b,v20.16b - aesmc v26.16b,v26.16b - - aese v0.16b,v21.16b - aesmc v0.16b,v0.16b - aese v1.16b,v21.16b - aesmc v1.16b,v1.16b - aese v24.16b,v21.16b - aesmc v24.16b,v24.16b - aese v25.16b,v21.16b - aesmc v25.16b,v25.16b - aese v26.16b,v21.16b - aesmc v26.16b,v26.16b - - aese v0.16b,v22.16b - aesmc v0.16b,v0.16b - aese v1.16b,v22.16b - aesmc v1.16b,v1.16b - aese v24.16b,v22.16b - aesmc v24.16b,v24.16b - aese v25.16b,v22.16b - aesmc v25.16b,v25.16b - aese v26.16b,v22.16b - aesmc v26.16b,v26.16b - - aese v0.16b,v23.16b - aese v1.16b,v23.16b - aese v24.16b,v23.16b - aese v25.16b,v23.16b - aese v26.16b,v23.16b - - eor v4.16b,v7.16b,v6.16b - // aese v0.16b,v23.16b - // The iv for first block of one iteration - extr x22,x10,x10,#32 - extr x10,x10,x9,#63 - and w11,w19,w22,asr#31 - eor x9,x11,x9,lsl#1 - fmov d6,x9 - fmov v6.d[1],x10 - eor v5.16b,v7.16b,v8.16b - ld1 {v2.16b},[x0],#16 - // aese v1.16b,v23.16b - // The iv for second block - extr x22,x10,x10,#32 - extr x10,x10,x9,#63 - and w11,w19,w22,asr#31 - eor x9,x11,x9,lsl#1 - fmov d8,x9 - fmov v8.d[1],x10 - eor v17.16b,v7.16b,v9.16b - ld1 {v3.16b},[x0],#16 - // aese v24.16b,v23.16b - // The iv for third block - extr x22,x10,x10,#32 - extr x10,x10,x9,#63 - and w11,w19,w22,asr#31 - eor x9,x11,x9,lsl#1 - fmov d9,x9 - fmov v9.d[1],x10 - eor v30.16b,v7.16b,v10.16b - ld1 {v27.16b},[x0],#16 - // aese v25.16b,v23.16b - // The iv for fourth block - extr x22,x10,x10,#32 - extr x10,x10,x9,#63 - and w11,w19,w22,asr#31 - eor x9,x11,x9,lsl#1 - fmov d10,x9 - fmov v10.d[1],x10 - eor v31.16b,v7.16b,v11.16b - ld1 {v28.16b},[x0],#16 - // aese v26.16b,v23.16b - - // The iv for fifth block - extr x22,x10,x10,#32 - extr x10,x10,x9,#63 - and w11,w19,w22,asr #31 - eor x9,x11,x9,lsl #1 - fmov d11,x9 - fmov v11.d[1],x10 - - ld1 {v29.16b},[x0],#16 - cbz x6,Lxts_enc_tail4x -// vld1 {v16.4s},[x7],#16 // re-pre-load rndkey[0] - eor v4.16b,v4.16b,v0.16b - eor v0.16b,v2.16b,v6.16b - eor v5.16b,v5.16b,v1.16b - eor v1.16b,v3.16b,v8.16b - eor v17.16b,v17.16b,v24.16b - eor v24.16b,v27.16b,v9.16b - eor v30.16b,v30.16b,v25.16b - eor v25.16b,v28.16b,v10.16b - eor v31.16b,v31.16b,v26.16b - //vst1 {v4.16b},[x1],#16 - eor v26.16b,v29.16b,v11.16b - //vst1 {v5.16b},[x1],#16 - mov w6,w5 - st1 {v4.16b,v5.16b},[x1],#32 - st1 {v17.16b},[x1],#16 -// vld1 {v17.4s},[x7],#16 // re-pre-load rndkey[1] -// vst1 {v30.16b},[x1],#16 -// vst1 {v31.16b},[x1],#16 - st1 {v30.16b,v31.16b},[x1],#32 - ld1 {v16.4s},[x7],#16 // re-pre-load rndkey[0] - ld1 {v17.4s},[x7],#16 // re-pre-load rndkey[1] - b.hs Loop5x_xts_enc - - - // If left 4 blocks, borrow the five block's processing. - // This means if (x2 + 1 block) == 0, which is the case - // when input size % 5 = 4, continue processing and do - // another iteration in Loop5x_xts_enc which will exit from - // cbz x6,.Lxts_enc_tail4x. - // Otherwise, this is the end of the loop continue processing - // 0, 1, 2 or 3 blocks (with or without tail) starting at - // Loop5x_enc_after - cmn x2,#0x10 - b.ne Loop5x_enc_after - orr v11.16b,v10.16b,v10.16b - orr v10.16b,v9.16b,v9.16b - orr v9.16b,v8.16b,v8.16b - orr v8.16b,v6.16b,v6.16b - fmov x9,d11 - fmov x10,v11.d[1] - eor v0.16b,v6.16b,v2.16b - eor v1.16b,v8.16b,v3.16b - eor v24.16b,v27.16b,v9.16b - eor v25.16b,v28.16b,v10.16b - eor v26.16b,v29.16b,v11.16b - b.eq Loop5x_xts_enc - -Loop5x_enc_after: - add x2,x2,#0x50 - cbz x2,Lxts_enc_done // no blocks left - - add w6,w5,#2 - subs x2,x2,#0x30 - b.lo Lxts_inner_enc_tail // 1 or 2 blocks left - // (with tail or not) - - eor v0.16b,v6.16b,v27.16b // 3 blocks left - eor v1.16b,v8.16b,v28.16b - eor v24.16b,v29.16b,v9.16b - b Lxts_outer_enc_tail - -.align 4 -Lxts_enc_tail4x: - add x0,x0,#16 - eor v5.16b,v1.16b,v5.16b - st1 {v5.16b},[x1],#16 - eor v17.16b,v24.16b,v17.16b - st1 {v17.16b},[x1],#16 - eor v30.16b,v25.16b,v30.16b - eor v31.16b,v26.16b,v31.16b - st1 {v30.16b,v31.16b},[x1],#32 - b Lxts_enc_done -.align 4 -Lxts_outer_enc_tail: - aese v0.16b,v16.16b - aesmc v0.16b,v0.16b - aese v1.16b,v16.16b - aesmc v1.16b,v1.16b - aese v24.16b,v16.16b - aesmc v24.16b,v24.16b - ld1 {v16.4s},[x7],#16 - subs w6,w6,#2 - aese v0.16b,v17.16b - aesmc v0.16b,v0.16b - aese v1.16b,v17.16b - aesmc v1.16b,v1.16b - aese v24.16b,v17.16b - aesmc v24.16b,v24.16b - ld1 {v17.4s},[x7],#16 - b.gt Lxts_outer_enc_tail - - aese v0.16b,v16.16b - aesmc v0.16b,v0.16b - aese v1.16b,v16.16b - aesmc v1.16b,v1.16b - aese v24.16b,v16.16b - aesmc v24.16b,v24.16b - eor v4.16b,v6.16b,v7.16b - aese v0.16b,v17.16b - aesmc v0.16b,v0.16b - aese v1.16b,v17.16b - aesmc v1.16b,v1.16b - aese v24.16b,v17.16b - aesmc v24.16b,v24.16b - aese v0.16b,v20.16b - aesmc v0.16b,v0.16b - aese v1.16b,v20.16b - aesmc v1.16b,v1.16b - aese v24.16b,v20.16b - aesmc v24.16b,v24.16b - aese v0.16b,v21.16b - aesmc v0.16b,v0.16b - aese v1.16b,v21.16b - aesmc v1.16b,v1.16b - aese v24.16b,v21.16b - aesmc v24.16b,v24.16b - aese v0.16b,v22.16b - aesmc v0.16b,v0.16b - aese v1.16b,v22.16b - aesmc v1.16b,v1.16b - aese v24.16b,v22.16b - aesmc v24.16b,v24.16b - aese v0.16b,v23.16b - aese v1.16b,v23.16b - aese v24.16b,v23.16b - - eor v17.16b,v9.16b,v7.16b - subs x2,x2,#0x30 - // The iv for first block - fmov x9,d9 - fmov x10,v9.d[1] - //mov w19,#0x87 - extr x22,x10,x10,#32 - extr x10,x10,x9,#63 - and w11,w19,w22,asr#31 - eor x9,x11,x9,lsl#1 - fmov d6,x9 - fmov v6.d[1],x10 - eor v5.16b,v8.16b,v7.16b - csel x6,x2,x6,lo // x6, w6, is zero at this point -// aese v0.16b,v17.16b -// aesmc v0.16b,v0.16b -// aese v1.16b,v17.16b -// aesmc v1.16b,v1.16b -// aese v24.16b,v17.16b -// aesmc v24.16b,v24.16b -// veor v17.16b,v9.16b,v7.16b - - add x6,x6,#0x20 - add x0,x0,x6 - mov x7,x3 - -// aese v0.16b,v20.16b -// aesmc v0.16b,v0.16b -// aese v1.16b,v20.16b -// aesmc v1.16b,v1.16b -// aese v24.16b,v20.16b -// aesmc v24.16b,v24.16b -// aese v0.16b,v21.16b -// aesmc v0.16b,v0.16b -// aese v1.16b,v21.16b -// aesmc v1.16b,v1.16b -// aese v24.16b,v21.16b -// aesmc v24.16b,v24.16b -// aese v0.16b,v22.16b -// aesmc v0.16b,v0.16b -// aese v1.16b,v22.16b -// aesmc v1.16b,v1.16b -// aese v24.16b,v22.16b -// aesmc v24.16b,v24.16b -// aese v0.16b,v23.16b -// aese v1.16b,v23.16b -// aese v24.16b,v23.16b - ld1 {v27.16b},[x0],#16 - add w6,w5,#2 -// vld1 {v16.4s},[x7],#16 // re-pre-load rndkey[0] - eor v4.16b,v4.16b,v0.16b - eor v5.16b,v5.16b,v1.16b - eor v24.16b,v24.16b,v17.16b -// vld1 {v17.4s},[x7],#16 // re-pre-load rndkey[1] - ld1 {v16.4s,v17.4s},[x7],#32 -// vst1 {v4.16b},[x1],#16 -// vst1 {v5.16b},[x1],#16 - st1 {v4.16b,v5.16b},[x1],#32 - st1 {v24.16b},[x1],#16 - cmn x2,#0x30 - b.eq Lxts_enc_done -Lxts_encxor_one: - orr v28.16b,v3.16b,v3.16b - orr v29.16b,v27.16b,v27.16b +// Generated by: +// objdump -d -m --symbol-description --symbolize-operands +// --disassembler-options=reg-names-std --no-addresses --no-show-raw-insn +// /crypto/fipsmodule/CMakeFiles/fipsmodule.dir/aes/asm/aes-xts-armv8-enc-slothy.S.o +// > ../aes-xts-armv8-enc-slothy_M3_dissassemble.S + +// crypto/fipsmodule/CMakeFiles/fipsmodule.dir/aes/asm/aes-xts-armv8-enc-slothy.S.o: +// (__TEXT,__text) section +aes_hw_slothy_xts_encrypt: +_aes_hw_slothy_xts_encrypt: + sub sp, sp, #0x60 + stp d8, d9, [sp] + stp d10, d11, [sp, #0x10] + stp d12, d13, [sp, #0x20] + stp d14, d15, [sp, #0x30] + stp x19, x20, [sp, #0x40] + stp x21, x22, [sp, #0x50] + cmp x2, #0x10 + b.lt 0xa60 nop - -Lxts_inner_enc_tail: - cmn x2,#0x10 - eor v1.16b,v28.16b,v6.16b - eor v24.16b,v29.16b,v8.16b - b.eq Lxts_enc_tail_loop - eor v24.16b,v29.16b,v6.16b -Lxts_enc_tail_loop: - aese v1.16b,v16.16b - aesmc v1.16b,v1.16b - aese v24.16b,v16.16b - aesmc v24.16b,v24.16b - ld1 {v16.4s},[x7],#16 - subs w6,w6,#2 - aese v1.16b,v17.16b - aesmc v1.16b,v1.16b - aese v24.16b,v17.16b - aesmc v24.16b,v24.16b - ld1 {v17.4s},[x7],#16 - b.gt Lxts_enc_tail_loop - - aese v1.16b,v16.16b - aesmc v1.16b,v1.16b - aese v24.16b,v16.16b - aesmc v24.16b,v24.16b - aese v1.16b,v17.16b - aesmc v1.16b,v1.16b - aese v24.16b,v17.16b - aesmc v24.16b,v24.16b - aese v1.16b,v20.16b - aesmc v1.16b,v1.16b - aese v24.16b,v20.16b - aesmc v24.16b,v24.16b - cmn x2,#0x20 - aese v1.16b,v21.16b - aesmc v1.16b,v1.16b - aese v24.16b,v21.16b - aesmc v24.16b,v24.16b - eor v5.16b,v6.16b,v7.16b - aese v1.16b,v22.16b - aesmc v1.16b,v1.16b - aese v24.16b,v22.16b - aesmc v24.16b,v24.16b - eor v17.16b,v8.16b,v7.16b - aese v1.16b,v23.16b - aese v24.16b,v23.16b - b.eq Lxts_enc_one - eor v5.16b,v5.16b,v1.16b - st1 {v5.16b},[x1],#16 - eor v17.16b,v17.16b,v24.16b - orr v6.16b,v8.16b,v8.16b - st1 {v17.16b},[x1],#16 - fmov x9,d8 - fmov x10,v8.d[1] - mov w19,#0x87 - extr x22,x10,x10,#32 - extr x10,x10,x9,#63 - and w11,w19,w22,asr #31 - eor x9,x11,x9,lsl #1 - fmov d6,x9 - fmov v6.d[1],x10 - b Lxts_enc_done - -Lxts_enc_one: - eor v5.16b,v5.16b,v24.16b - orr v6.16b,v6.16b,v6.16b - st1 {v5.16b},[x1],#16 - fmov x9,d6 - fmov x10,v6.d[1] - mov w19,#0x87 - extr x22,x10,x10,#32 - extr x10,x10,x9,#63 - and w11,w19,w22,asr #31 - eor x9,x11,x9,lsl #1 - fmov d6,x9 - fmov v6.d[1],x10 - b Lxts_enc_done -.align 5 -Lxts_enc_done: - // Process the tail block with cipher stealing. - tst x21,#0xf - b.eq Lxts_abort - - mov x20,x0 - mov x13,x1 - sub x1,x1,#16 + nop + nop + and x21, x2, #0xf + and x2, x2, #0xfffffffffffffff0 + ldr w6, [x4, #0xf0] + ld1.4s { v0 }, [x4], #16 + ld1.16b { v6 }, [x5] + sub w6, w6, #0x2 + ld1.4s { v1 }, [x4], #16 + aese.16b v6, v0 + aesmc.16b v6, v6 + ld1.4s { v0 }, [x4], #16 + subs w6, w6, #0x2 + aese.16b v6, v1 + aesmc.16b v6, v6 + ld1.4s { v1 }, [x4], #16 + b.gt 0x4c + aese.16b v6, v0 + aesmc.16b v6, v6 + ld1.4s { v0 }, [x4] + aese.16b v6, v1 + eor.16b v6, v6, v0 + fmov x9, d6 + fmov.d x10, v6[1] + mov w19, #0x87 + ror x22, x10, #0x20 + extr x10, x10, x9, #0x3f + and w11, w19, w22, asr #31 + eor x9, x11, x9, lsl #1 + fmov d8, x9 + fmov.d v8[1], x10 + mov x7, x3 + ld1.4s { v16, v17 }, [x7], #32 + ld1.4s { v12, v13 }, [x7], #32 + ld1.4s { v14, v15 }, [x7], #32 + ld1.4s { v4, v5 }, [x7], #32 + ld1.4s { v18, v19 }, [x7], #32 + ld1.4s { v20, v21 }, [x7], #32 + ld1.4s { v22, v23 }, [x7], #32 + ld1.4s { v7 }, [x7] + cmp x2, #0x20 + b.lo 0x928 + cmp x2, #0x30 + b.lo 0x80c + ror x22, x10, #0x20 + extr x10, x10, x9, #0x3f + and w11, w19, w22, asr #31 + eor x9, x11, x9, lsl #1 + fmov d9, x9 + fmov.d v9[1], x10 + cmp x2, #0x40 + b.lo 0x670 + ror x22, x10, #0x20 + extr x10, x10, x9, #0x3f + and w11, w19, w22, asr #31 + eor x9, x11, x9, lsl #1 + fmov d10, x9 + fmov.d v10[1], x10 + cmp x2, #0x50 + b.lo 0x450 + ror x22, x10, #0x20 + extr x10, x10, x9, #0x3f + and w11, w19, w22, asr #31 + eor x9, x11, x9, lsl #1 + fmov d11, x9 + fmov.d v11[1], x10 + ldp q0, q1, [x0], #0x50 + ldp q24, q25, [x0, #-0x30] + ldur q26, [x0, #-0x10] + eor.16b v0, v0, v6 + eor.16b v1, v1, v8 + eor.16b v24, v24, v9 + eor.16b v25, v25, v10 + eor.16b v26, v26, v11 + aese.16b v0, v16 + aesmc.16b v0, v0 + aese.16b v1, v16 + aesmc.16b v1, v1 + aese.16b v24, v16 + aesmc.16b v24, v24 + aese.16b v25, v16 + aesmc.16b v25, v25 + aese.16b v26, v16 + aesmc.16b v26, v26 + aese.16b v0, v17 + aesmc.16b v0, v0 + aese.16b v1, v17 + aesmc.16b v1, v1 + aese.16b v24, v17 + aesmc.16b v24, v24 + aese.16b v25, v17 + aesmc.16b v25, v25 + aese.16b v26, v17 + aesmc.16b v26, v26 + aese.16b v0, v12 + aesmc.16b v0, v0 + aese.16b v1, v12 + aesmc.16b v1, v1 + aese.16b v24, v12 + aesmc.16b v24, v24 + aese.16b v25, v12 + aesmc.16b v25, v25 + aese.16b v26, v12 + aesmc.16b v26, v26 + aese.16b v0, v13 + aesmc.16b v0, v0 + aese.16b v1, v13 + aesmc.16b v1, v1 + aese.16b v24, v13 + aesmc.16b v24, v24 + aese.16b v25, v13 + aesmc.16b v25, v25 + aese.16b v26, v13 + aesmc.16b v26, v26 + aese.16b v0, v14 + aesmc.16b v0, v0 + aese.16b v1, v14 + aesmc.16b v1, v1 + aese.16b v24, v14 + aesmc.16b v24, v24 + aese.16b v25, v14 + aesmc.16b v25, v25 + aese.16b v26, v14 + aesmc.16b v26, v26 + aese.16b v0, v15 + aesmc.16b v0, v0 + aese.16b v1, v15 + aesmc.16b v1, v1 + aese.16b v24, v15 + aesmc.16b v24, v24 + aese.16b v25, v15 + aesmc.16b v25, v25 + aese.16b v26, v15 + aesmc.16b v26, v26 + aese.16b v0, v4 + aesmc.16b v0, v0 + aese.16b v1, v4 + aesmc.16b v1, v1 + aese.16b v24, v4 + aesmc.16b v24, v24 + aese.16b v25, v4 + aesmc.16b v25, v25 + aese.16b v26, v4 + aesmc.16b v26, v26 + aese.16b v0, v5 + aesmc.16b v0, v0 + aese.16b v1, v5 + aesmc.16b v1, v1 + aese.16b v24, v5 + aesmc.16b v24, v24 + aese.16b v25, v5 + aesmc.16b v25, v25 + aese.16b v26, v5 + aesmc.16b v26, v26 + aese.16b v0, v18 + aesmc.16b v0, v0 + aese.16b v1, v18 + aesmc.16b v1, v1 + aese.16b v24, v18 + aesmc.16b v24, v24 + aese.16b v25, v18 + aesmc.16b v25, v25 + aese.16b v26, v18 + aesmc.16b v26, v26 + aese.16b v0, v19 + aesmc.16b v0, v0 + aese.16b v1, v19 + aesmc.16b v1, v1 + aese.16b v24, v19 + aesmc.16b v24, v24 + aese.16b v25, v19 + aesmc.16b v25, v25 + aese.16b v26, v19 + aesmc.16b v26, v26 + aese.16b v0, v20 + aesmc.16b v0, v0 + aese.16b v1, v20 + aesmc.16b v1, v1 + aese.16b v24, v20 + aesmc.16b v24, v24 + aese.16b v25, v20 + aesmc.16b v25, v25 + aese.16b v26, v20 + aesmc.16b v26, v26 + aese.16b v0, v21 + aesmc.16b v0, v0 + aese.16b v1, v21 + aesmc.16b v1, v1 + aese.16b v24, v21 + aesmc.16b v24, v24 + aese.16b v25, v21 + aesmc.16b v25, v25 + aese.16b v26, v21 + aesmc.16b v26, v26 + aese.16b v0, v22 + aesmc.16b v0, v0 + aese.16b v1, v22 + aesmc.16b v1, v1 + aese.16b v24, v22 + aesmc.16b v24, v24 + aese.16b v25, v22 + aesmc.16b v25, v25 + aese.16b v26, v22 + aesmc.16b v26, v26 + aese.16b v0, v23 + aese.16b v1, v23 + aese.16b v24, v23 + aese.16b v25, v23 + aese.16b v26, v23 + eor.16b v0, v0, v7 + eor.16b v0, v0, v6 + ror x22, x10, #0x20 + extr x10, x10, x9, #0x3f + and w11, w19, w22, asr #31 + eor x9, x11, x9, lsl #1 + fmov d6, x9 + fmov.d v6[1], x10 + eor.16b v1, v1, v7 + eor.16b v1, v1, v8 + ror x22, x10, #0x20 + extr x10, x10, x9, #0x3f + and w11, w19, w22, asr #31 + eor x9, x11, x9, lsl #1 + fmov d8, x9 + fmov.d v8[1], x10 + eor.16b v24, v24, v7 + eor.16b v24, v24, v9 + ror x22, x10, #0x20 + extr x10, x10, x9, #0x3f + and w11, w19, w22, asr #31 + eor x9, x11, x9, lsl #1 + fmov d9, x9 + fmov.d v9[1], x10 + eor.16b v25, v25, v7 + eor.16b v25, v25, v10 + ror x22, x10, #0x20 + extr x10, x10, x9, #0x3f + and w11, w19, w22, asr #31 + eor x9, x11, x9, lsl #1 + fmov d10, x9 + fmov.d v10[1], x10 + eor.16b v26, v26, v7 + eor.16b v26, v26, v11 + ror x22, x10, #0x20 + extr x10, x10, x9, #0x3f + and w11, w19, w22, asr #31 + eor x9, x11, x9, lsl #1 + fmov d11, x9 + fmov.d v11[1], x10 + stp q0, q1, [x1], #0x50 + stp q24, q25, [x1, #-0x30] + stur q26, [x1, #-0x10] + subs x2, x2, #0x50 + cmp x2, #0x50 + b.lo 0x428 + b.hs 0x130 + cmp x2, #0x0 + b.eq 0x9e0 + cmp x2, #0x10 + b.eq 0x928 + cmp x2, #0x20 + b.eq 0x80c + cmp x2, #0x30 + b.eq 0x670 + cmp x2, #0x40 + b.eq 0x450 + ld1.16b { v0 }, [x0], #16 + ld1.16b { v1 }, [x0], #16 + ld1.16b { v24 }, [x0], #16 + ld1.16b { v25 }, [x0], #16 + eor.16b v0, v0, v6 + eor.16b v1, v1, v8 + eor.16b v24, v24, v9 + eor.16b v25, v25, v10 + aese.16b v0, v16 + aesmc.16b v0, v0 + aese.16b v1, v16 + aesmc.16b v1, v1 + aese.16b v24, v16 + aesmc.16b v24, v24 + aese.16b v25, v16 + aesmc.16b v25, v25 + aese.16b v0, v17 + aesmc.16b v0, v0 + aese.16b v1, v17 + aesmc.16b v1, v1 + aese.16b v24, v17 + aesmc.16b v24, v24 + aese.16b v25, v17 + aesmc.16b v25, v25 + aese.16b v0, v12 + aesmc.16b v0, v0 + aese.16b v1, v12 + aesmc.16b v1, v1 + aese.16b v24, v12 + aesmc.16b v24, v24 + aese.16b v25, v12 + aesmc.16b v25, v25 + aese.16b v0, v13 + aesmc.16b v0, v0 + aese.16b v1, v13 + aesmc.16b v1, v1 + aese.16b v24, v13 + aesmc.16b v24, v24 + aese.16b v25, v13 + aesmc.16b v25, v25 + aese.16b v0, v14 + aesmc.16b v0, v0 + aese.16b v1, v14 + aesmc.16b v1, v1 + aese.16b v24, v14 + aesmc.16b v24, v24 + aese.16b v25, v14 + aesmc.16b v25, v25 + aese.16b v0, v15 + aesmc.16b v0, v0 + aese.16b v1, v15 + aesmc.16b v1, v1 + aese.16b v24, v15 + aesmc.16b v24, v24 + aese.16b v25, v15 + aesmc.16b v25, v25 + aese.16b v0, v4 + aesmc.16b v0, v0 + aese.16b v1, v4 + aesmc.16b v1, v1 + aese.16b v24, v4 + aesmc.16b v24, v24 + aese.16b v25, v4 + aesmc.16b v25, v25 + aese.16b v0, v5 + aesmc.16b v0, v0 + aese.16b v1, v5 + aesmc.16b v1, v1 + aese.16b v24, v5 + aesmc.16b v24, v24 + aese.16b v25, v5 + aesmc.16b v25, v25 + aese.16b v0, v18 + aesmc.16b v0, v0 + aese.16b v1, v18 + aesmc.16b v1, v1 + aese.16b v24, v18 + aesmc.16b v24, v24 + aese.16b v25, v18 + aesmc.16b v25, v25 + aese.16b v0, v19 + aesmc.16b v0, v0 + aese.16b v1, v19 + aesmc.16b v1, v1 + aese.16b v24, v19 + aesmc.16b v24, v24 + aese.16b v25, v19 + aesmc.16b v25, v25 + aese.16b v0, v20 + aesmc.16b v0, v0 + aese.16b v1, v20 + aesmc.16b v1, v1 + aese.16b v24, v20 + aesmc.16b v24, v24 + aese.16b v25, v20 + aesmc.16b v25, v25 + aese.16b v0, v21 + aesmc.16b v0, v0 + aese.16b v1, v21 + aesmc.16b v1, v1 + aese.16b v24, v21 + aesmc.16b v24, v24 + aese.16b v25, v21 + aesmc.16b v25, v25 + aese.16b v0, v22 + aesmc.16b v0, v0 + aese.16b v1, v22 + aesmc.16b v1, v1 + aese.16b v24, v22 + aesmc.16b v24, v24 + aese.16b v25, v22 + aesmc.16b v25, v25 + aese.16b v0, v23 + aese.16b v1, v23 + aese.16b v24, v23 + aese.16b v25, v23 + eor.16b v0, v0, v7 + eor.16b v0, v0, v6 + eor.16b v1, v1, v7 + eor.16b v1, v1, v8 + eor.16b v24, v24, v7 + eor.16b v24, v24, v9 + eor.16b v25, v25, v7 + eor.16b v25, v25, v10 + st1.16b { v0, v1 }, [x1], #32 + st1.16b { v24, v25 }, [x1], #32 + fmov x9, d10 + fmov.d x10, v10[1] + ror x22, x10, #0x20 + extr x10, x10, x9, #0x3f + and w11, w19, w22, asr #31 + eor x9, x11, x9, lsl #1 + fmov d6, x9 + fmov.d v6[1], x10 + b 0x9e0 + nop + ld1.16b { v0, v1 }, [x0], #32 + ld1.16b { v24 }, [x0], #16 + eor.16b v0, v0, v6 + eor.16b v1, v1, v8 + eor.16b v24, v24, v9 + aese.16b v0, v16 + aesmc.16b v0, v0 + aese.16b v1, v16 + aesmc.16b v1, v1 + aese.16b v24, v16 + aesmc.16b v24, v24 + aese.16b v0, v17 + aesmc.16b v0, v0 + aese.16b v1, v17 + aesmc.16b v1, v1 + aese.16b v24, v17 + aesmc.16b v24, v24 + aese.16b v0, v12 + aesmc.16b v0, v0 + aese.16b v1, v12 + aesmc.16b v1, v1 + aese.16b v24, v12 + aesmc.16b v24, v24 + aese.16b v0, v13 + aesmc.16b v0, v0 + aese.16b v1, v13 + aesmc.16b v1, v1 + aese.16b v24, v13 + aesmc.16b v24, v24 + aese.16b v0, v14 + aesmc.16b v0, v0 + aese.16b v1, v14 + aesmc.16b v1, v1 + aese.16b v24, v14 + aesmc.16b v24, v24 + aese.16b v0, v15 + aesmc.16b v0, v0 + aese.16b v1, v15 + aesmc.16b v1, v1 + aese.16b v24, v15 + aesmc.16b v24, v24 + aese.16b v0, v4 + aesmc.16b v0, v0 + aese.16b v1, v4 + aesmc.16b v1, v1 + aese.16b v24, v4 + aesmc.16b v24, v24 + aese.16b v0, v5 + aesmc.16b v0, v0 + aese.16b v1, v5 + aesmc.16b v1, v1 + aese.16b v24, v5 + aesmc.16b v24, v24 + aese.16b v0, v18 + aesmc.16b v0, v0 + aese.16b v1, v18 + aesmc.16b v1, v1 + aese.16b v24, v18 + aesmc.16b v24, v24 + aese.16b v0, v19 + aesmc.16b v0, v0 + aese.16b v1, v19 + aesmc.16b v1, v1 + aese.16b v24, v19 + aesmc.16b v24, v24 + aese.16b v0, v20 + aesmc.16b v0, v0 + aese.16b v1, v20 + aesmc.16b v1, v1 + aese.16b v24, v20 + aesmc.16b v24, v24 + aese.16b v0, v21 + aesmc.16b v0, v0 + aese.16b v1, v21 + aesmc.16b v1, v1 + aese.16b v24, v21 + aesmc.16b v24, v24 + aese.16b v0, v22 + aesmc.16b v0, v0 + aese.16b v1, v22 + aesmc.16b v1, v1 + aese.16b v24, v22 + aesmc.16b v24, v24 + aese.16b v0, v23 + aese.16b v1, v23 + aese.16b v24, v23 + eor.16b v0, v0, v7 + eor.16b v0, v0, v6 + eor.16b v1, v1, v7 + eor.16b v1, v1, v8 + eor.16b v24, v24, v7 + eor.16b v24, v24, v9 + st1.16b { v0, v1 }, [x1], #32 + st1.16b { v24 }, [x1], #16 + fmov x9, d9 + fmov.d x10, v9[1] + ror x22, x10, #0x20 + extr x10, x10, x9, #0x3f + and w11, w19, w22, asr #31 + eor x9, x11, x9, lsl #1 + fmov d6, x9 + fmov.d v6[1], x10 + b 0x9e0 + ld1.16b { v0, v1 }, [x0], #32 + eor.16b v0, v0, v6 + eor.16b v1, v1, v8 + aese.16b v0, v16 + aesmc.16b v0, v0 + aese.16b v1, v16 + aesmc.16b v1, v1 + aese.16b v0, v17 + aesmc.16b v0, v0 + aese.16b v1, v17 + aesmc.16b v1, v1 + aese.16b v0, v12 + aesmc.16b v0, v0 + aese.16b v1, v12 + aesmc.16b v1, v1 + aese.16b v0, v13 + aesmc.16b v0, v0 + aese.16b v1, v13 + aesmc.16b v1, v1 + aese.16b v0, v14 + aesmc.16b v0, v0 + aese.16b v1, v14 + aesmc.16b v1, v1 + aese.16b v0, v15 + aesmc.16b v0, v0 + aese.16b v1, v15 + aesmc.16b v1, v1 + aese.16b v0, v4 + aesmc.16b v0, v0 + aese.16b v1, v4 + aesmc.16b v1, v1 + aese.16b v0, v5 + aesmc.16b v0, v0 + aese.16b v1, v5 + aesmc.16b v1, v1 + aese.16b v0, v18 + aesmc.16b v0, v0 + aese.16b v1, v18 + aesmc.16b v1, v1 + aese.16b v0, v19 + aesmc.16b v0, v0 + aese.16b v1, v19 + aesmc.16b v1, v1 + aese.16b v0, v20 + aesmc.16b v0, v0 + aese.16b v1, v20 + aesmc.16b v1, v1 + aese.16b v0, v21 + aesmc.16b v0, v0 + aese.16b v1, v21 + aesmc.16b v1, v1 + aese.16b v0, v22 + aesmc.16b v0, v0 + aese.16b v1, v22 + aesmc.16b v1, v1 + aese.16b v0, v23 + aese.16b v1, v23 + eor.16b v0, v0, v7 + eor.16b v0, v0, v6 + eor.16b v1, v1, v7 + eor.16b v1, v1, v8 + st1.16b { v0, v1 }, [x1], #32 + fmov x9, d8 + fmov.d x10, v8[1] + ror x22, x10, #0x20 + extr x10, x10, x9, #0x3f + and w11, w19, w22, asr #31 + eor x9, x11, x9, lsl #1 + fmov d6, x9 + fmov.d v6[1], x10 + b 0x9e0 + ld1.16b { v0 }, [x0], #16 + eor.16b v0, v0, v6 + aese.16b v0, v16 + aesmc.16b v0, v0 + aese.16b v0, v17 + aesmc.16b v0, v0 + aese.16b v0, v12 + aesmc.16b v0, v0 + aese.16b v0, v13 + aesmc.16b v0, v0 + aese.16b v0, v14 + aesmc.16b v0, v0 + aese.16b v0, v15 + aesmc.16b v0, v0 + aese.16b v0, v4 + aesmc.16b v0, v0 + aese.16b v0, v5 + aesmc.16b v0, v0 + aese.16b v0, v18 + aesmc.16b v0, v0 + aese.16b v0, v19 + aesmc.16b v0, v0 + aese.16b v0, v20 + aesmc.16b v0, v0 + aese.16b v0, v21 + aesmc.16b v0, v0 + aese.16b v0, v22 + aesmc.16b v0, v0 + aese.16b v0, v23 + eor.16b v0, v0, v7 + eor.16b v0, v0, v6 + st1.16b { v0 }, [x1], #16 + fmov x9, d6 + fmov.d x10, v6[1] + ror x22, x10, #0x20 + extr x10, x10, x9, #0x3f + and w11, w19, w22, asr #31 + eor x9, x11, x9, lsl #1 + fmov d6, x9 + fmov.d v6[1], x10 + b 0x9e0 + nop + nop + nop + nop + nop + tst x21, #0xf + b.eq 0xa60 + mov x20, x0 + mov x13, x1 + sub x1, x1, #0x10 .composite_enc_loop: - subs x21,x21,#1 - ldrb w15,[x1,x21] - ldrb w14,[x20,x21] - strb w15,[x13,x21] - strb w14,[x1,x21] + subs x21, x21, #0x1 + ldrb w15, [x1, x21] + ldrb w14, [x20, x21] + strb w15, [x13, x21] + strb w14, [x1, x21] b.gt .composite_enc_loop -Lxts_enc_load_done: - ld1 {v26.16b},[x1] - eor v26.16b,v26.16b,v6.16b - - // Encrypt the composite block to get the last second encrypted text block - ldr w6,[x3,#240] // load key schedule... - ld1 {v0.16b},[x3],#16 - sub w6,w6,#2 - ld1 {v1.16b},[x3],#16 // load key schedule... -Loop_final_enc: - aese v26.16b,v0.16b - aesmc v26.16b,v26.16b - ld1 {v0.4s},[x3],#16 - subs w6,w6,#2 - aese v26.16b,v1.16b - aesmc v26.16b,v26.16b - ld1 {v1.4s},[x3],#16 - b.gt Loop_final_enc - - aese v26.16b,v0.16b - aesmc v26.16b,v26.16b - ld1 {v0.4s},[x3] - aese v26.16b,v1.16b - eor v26.16b,v26.16b,v0.16b - eor v26.16b,v26.16b,v6.16b - st1 {v26.16b},[x1] - -Lxts_abort: - ldp x21,x22,[sp,#48] - ldp d8,d9,[sp,#32] - ldp d10,d11,[sp,#16] - ldp x19,x20,[sp],#64 -Lxts_enc_final_abort: - ret - -## aes_hw_xts_encrypt: -## // AARCH64_VALID_CALL_TARGET -## cmp x2,#16 -## // Original input data size bigger than 16, jump to big size processing. -## b.ne .Lxts_enc_big_size -## // Encrypt the iv with key2, as the first XEX iv. -## ldr w6,[x4,#240] -## ld1 {v0.16b},[x4],#16 -## ld1 {v6.16b},[x5] -## sub w6,w6,#2 -## ld1 {v1.16b},[x4],#16 -## -## .Loop_enc_iv_enc: -## aese v6.16b,v0.16b -## aesmc v6.16b,v6.16b -## ld1 {v0.4s},[x4],#16 -## subs w6,w6,#2 -## aese v6.16b,v1.16b -## aesmc v6.16b,v6.16b -## ld1 {v1.4s},[x4],#16 -## b.gt .Loop_enc_iv_enc -## -## aese v6.16b,v0.16b -## aesmc v6.16b,v6.16b -## ld1 {v0.4s},[x4] -## aese v6.16b,v1.16b -## eor v6.16b,v6.16b,v0.16b -## -## ld1 {v0.16b},[x0] -## eor v0.16b,v6.16b,v0.16b -## -## ldr w6,[x3,#240] -## ld1 {v28.4s,v29.4s},[x3],#32 // load key schedule... -## -## aese v0.16b,v28.16b -## aesmc v0.16b,v0.16b -## ld1 {v16.4s,v17.4s},[x3],#32 // load key schedule... -## aese v0.16b,v29.16b -## aesmc v0.16b,v0.16b -## subs w6,w6,#10 // if rounds==10, jump to aes-128-xts processing -## b.eq .Lxts_128_enc -## .Lxts_enc_round_loop: -## aese v0.16b,v16.16b -## aesmc v0.16b,v0.16b -## ld1 {v16.4s},[x3],#16 // load key schedule... -## aese v0.16b,v17.16b -## aesmc v0.16b,v0.16b -## ld1 {v17.4s},[x3],#16 // load key schedule... -## subs w6,w6,#2 // bias -## b.gt .Lxts_enc_round_loop -## .Lxts_128_enc: -## ld1 {v18.4s,v19.4s},[x3],#32 // load key schedule... -## aese v0.16b,v16.16b -## aesmc v0.16b,v0.16b -## aese v0.16b,v17.16b -## aesmc v0.16b,v0.16b -## ld1 {v20.4s,v21.4s},[x3],#32 // load key schedule... -## aese v0.16b,v18.16b -## aesmc v0.16b,v0.16b -## aese v0.16b,v19.16b -## aesmc v0.16b,v0.16b -## ld1 {v22.4s,v23.4s},[x3],#32 // load key schedule... -## aese v0.16b,v20.16b -## aesmc v0.16b,v0.16b -## aese v0.16b,v21.16b -## aesmc v0.16b,v0.16b -## ld1 {v7.4s},[x3] -## aese v0.16b,v22.16b -## aesmc v0.16b,v0.16b -## aese v0.16b,v23.16b -## eor v0.16b,v0.16b,v7.16b -## eor v0.16b,v0.16b,v6.16b -## st1 {v0.16b},[x1] -## b .Lxts_enc_final_abort -## -## .align 4 -## .Lxts_enc_big_size: -## // Encrypt input size > 16 bytes -## stp x19,x20,[sp,#-64]! -## stp x21,x22,[sp,#48] -## stp d8,d9,[sp,#32] -## stp d10,d11,[sp,#16] -## -## // tailcnt store the tail value of length%16. -## and x21,x2,#0xf -## and x2,x2,#-16 // len &= 0x1..110000, now divisible by 16 -## subs x2,x2,#16 -## mov x8,#16 -## b.lo .Lxts_abort // if !(len > 16): error -## csel x8,xzr,x8,eq // if (len == 16): step = 0 -## -## // Firstly, encrypt the iv with key2, as the first iv of XEX. -## ldr w6,[x4,#240] -## ld1 {v0.4s},[x4],#16 -## ld1 {v6.16b},[x5] -## sub w6,w6,#2 -## ld1 {v1.4s},[x4],#16 -## -## .Loop_iv_enc: -## aese v6.16b,v0.16b -## aesmc v6.16b,v6.16b -## ld1 {v0.4s},[x4],#16 -## subs w6,w6,#2 -## aese v6.16b,v1.16b -## aesmc v6.16b,v6.16b -## ld1 {v1.4s},[x4],#16 -## b.gt .Loop_iv_enc -## -## aese v6.16b,v0.16b -## aesmc v6.16b,v6.16b -## ld1 {v0.4s},[x4] -## aese v6.16b,v1.16b -## eor v6.16b,v6.16b,v0.16b -## -## // The iv for second block -## // x9- iv(low), x10 - iv(high) -## // the five ivs stored into, v6.16b,v8.16b,v9.16b,v10.16b,v11.16b -## fmov x9,d6 -## fmov x10,v6.d[1] -## mov w19,#0x87 -## extr x22,x10,x10,#32 -## extr x10,x10,x9,#63 -## and w11,w19,w22,asr#31 -## eor x9,x11,x9,lsl#1 -## fmov d8,x9 -## fmov v8.d[1],x10 -## -## ldr w5,[x3,#240] // next starting point -## ld1 {v0.16b},[x0],x8 -## -## ld1 {v16.4s,v17.4s},[x3] // load key schedule... -## sub w5,w5,#6 -## add x7,x3,x5,lsl#4 // pointer to last 7 round keys -## sub w5,w5,#2 -## ld1 {v18.4s,v19.4s},[x7],#32 -## ld1 {v20.4s,v21.4s},[x7],#32 -## ld1 {v22.4s,v23.4s},[x7],#32 -## ld1 {v7.4s},[x7] -## -## add x7,x3,#32 -## mov w6,w5 -## -## // Encryption -## .Lxts_enc: -## ld1 {v24.16b},[x0],#16 -## subs x2,x2,#32 // bias -## add w6,w5,#2 -## orr v3.16b,v0.16b,v0.16b -## orr v1.16b,v0.16b,v0.16b -## orr v28.16b,v0.16b,v0.16b -## orr v27.16b,v24.16b,v24.16b -## orr v29.16b,v24.16b,v24.16b -## b.lo .Lxts_inner_enc_tail // when input size % 5 = 1 or 2 -## // (with tail or not) -## eor v0.16b,v0.16b,v6.16b // before encryption, xor with iv -## eor v24.16b,v24.16b,v8.16b -## -## // The iv for third block -## extr x22,x10,x10,#32 -## extr x10,x10,x9,#63 -## and w11,w19,w22,asr#31 -## eor x9,x11,x9,lsl#1 -## fmov d9,x9 -## fmov v9.d[1],x10 -## -## -## orr v1.16b,v24.16b,v24.16b -## ld1 {v24.16b},[x0],#16 -## orr v2.16b,v0.16b,v0.16b -## orr v3.16b,v1.16b,v1.16b -## eor v27.16b,v24.16b,v9.16b // the third block -## eor v24.16b,v24.16b,v9.16b -## cmp x2,#32 -## b.lo .Lxts_outer_enc_tail -## -## // The iv for fourth block -## extr x22,x10,x10,#32 -## extr x10,x10,x9,#63 -## and w11,w19,w22,asr#31 -## eor x9,x11,x9,lsl#1 -## fmov d10,x9 -## fmov v10.d[1],x10 -## -## ld1 {v25.16b},[x0],#16 -## // The iv for fifth block -## extr x22,x10,x10,#32 -## extr x10,x10,x9,#63 -## and w11,w19,w22,asr#31 -## eor x9,x11,x9,lsl#1 -## fmov d11,x9 -## fmov v11.d[1],x10 -## -## ld1 {v26.16b},[x0],#16 -## eor v25.16b,v25.16b,v10.16b // the fourth block -## eor v26.16b,v26.16b,v11.16b -## sub x2,x2,#32 // bias -## mov w6,w5 -## b .Loop5x_xts_enc -## -## .align 4 -## .Loop5x_xts_enc: -## aese v0.16b,v16.16b -## aesmc v0.16b,v0.16b -## aese v1.16b,v16.16b -## aesmc v1.16b,v1.16b -## aese v24.16b,v16.16b -## aesmc v24.16b,v24.16b -## aese v25.16b,v16.16b -## aesmc v25.16b,v25.16b -## aese v26.16b,v16.16b -## aesmc v26.16b,v26.16b -## ld1 {v16.4s},[x7],#16 -## subs w6,w6,#2 -## aese v0.16b,v17.16b -## aesmc v0.16b,v0.16b -## aese v1.16b,v17.16b -## aesmc v1.16b,v1.16b -## aese v24.16b,v17.16b -## aesmc v24.16b,v24.16b -## aese v25.16b,v17.16b -## aesmc v25.16b,v25.16b -## aese v26.16b,v17.16b -## aesmc v26.16b,v26.16b -## ld1 {v17.4s},[x7],#16 -## b.gt .Loop5x_xts_enc -## -## aese v0.16b,v16.16b -## aesmc v0.16b,v0.16b -## aese v1.16b,v16.16b -## aesmc v1.16b,v1.16b -## aese v24.16b,v16.16b -## aesmc v24.16b,v24.16b -## aese v25.16b,v16.16b -## aesmc v25.16b,v25.16b -## aese v26.16b,v16.16b -## aesmc v26.16b,v26.16b -## subs x2,x2,#0x50 // because .Lxts_enc_tail4x -## -## aese v0.16b,v17.16b -## aesmc v0.16b,v0.16b -## aese v1.16b,v17.16b -## aesmc v1.16b,v1.16b -## aese v24.16b,v17.16b -## aesmc v24.16b,v24.16b -## aese v25.16b,v17.16b -## aesmc v25.16b,v25.16b -## aese v26.16b,v17.16b -## aesmc v26.16b,v26.16b -## csel x6,xzr,x2,gt // borrow x6, w6, "gt" is not typo -## mov x7,x3 -## -## aese v0.16b,v18.16b -## aesmc v0.16b,v0.16b -## aese v1.16b,v18.16b -## aesmc v1.16b,v1.16b -## aese v24.16b,v18.16b -## aesmc v24.16b,v24.16b -## aese v25.16b,v18.16b -## aesmc v25.16b,v25.16b -## aese v26.16b,v18.16b -## aesmc v26.16b,v26.16b -## add x0,x0,x6 // x0 is adjusted in such way that -## // at exit from the loop v1.16b-v26.16b -## // are loaded with last "words" -## add x6,x2,#0x60 // because .Lxts_enc_tail4x -## -## aese v0.16b,v19.16b -## aesmc v0.16b,v0.16b -## aese v1.16b,v19.16b -## aesmc v1.16b,v1.16b -## aese v24.16b,v19.16b -## aesmc v24.16b,v24.16b -## aese v25.16b,v19.16b -## aesmc v25.16b,v25.16b -## aese v26.16b,v19.16b -## aesmc v26.16b,v26.16b -## -## aese v0.16b,v20.16b -## aesmc v0.16b,v0.16b -## aese v1.16b,v20.16b -## aesmc v1.16b,v1.16b -## aese v24.16b,v20.16b -## aesmc v24.16b,v24.16b -## aese v25.16b,v20.16b -## aesmc v25.16b,v25.16b -## aese v26.16b,v20.16b -## aesmc v26.16b,v26.16b -## -## aese v0.16b,v21.16b -## aesmc v0.16b,v0.16b -## aese v1.16b,v21.16b -## aesmc v1.16b,v1.16b -## aese v24.16b,v21.16b -## aesmc v24.16b,v24.16b -## aese v25.16b,v21.16b -## aesmc v25.16b,v25.16b -## aese v26.16b,v21.16b -## aesmc v26.16b,v26.16b -## -## aese v0.16b,v22.16b -## aesmc v0.16b,v0.16b -## aese v1.16b,v22.16b -## aesmc v1.16b,v1.16b -## aese v24.16b,v22.16b -## aesmc v24.16b,v24.16b -## aese v25.16b,v22.16b -## aesmc v25.16b,v25.16b -## aese v26.16b,v22.16b -## aesmc v26.16b,v26.16b -## -## eor v4.16b,v7.16b,v6.16b -## aese v0.16b,v23.16b -## // The iv for first block of one iteration -## extr x22,x10,x10,#32 -## extr x10,x10,x9,#63 -## and w11,w19,w22,asr#31 -## eor x9,x11,x9,lsl#1 -## fmov d6,x9 -## fmov v6.d[1],x10 -## eor v5.16b,v7.16b,v8.16b -## ld1 {v2.16b},[x0],#16 -## aese v1.16b,v23.16b -## // The iv for second block -## extr x22,x10,x10,#32 -## extr x10,x10,x9,#63 -## and w11,w19,w22,asr#31 -## eor x9,x11,x9,lsl#1 -## fmov d8,x9 -## fmov v8.d[1],x10 -## eor v17.16b,v7.16b,v9.16b -## ld1 {v3.16b},[x0],#16 -## aese v24.16b,v23.16b -## // The iv for third block -## extr x22,x10,x10,#32 -## extr x10,x10,x9,#63 -## and w11,w19,w22,asr#31 -## eor x9,x11,x9,lsl#1 -## fmov d9,x9 -## fmov v9.d[1],x10 -## eor v30.16b,v7.16b,v10.16b -## ld1 {v27.16b},[x0],#16 -## aese v25.16b,v23.16b -## // The iv for fourth block -## extr x22,x10,x10,#32 -## extr x10,x10,x9,#63 -## and w11,w19,w22,asr#31 -## eor x9,x11,x9,lsl#1 -## fmov d10,x9 -## fmov v10.d[1],x10 -## eor v31.16b,v7.16b,v11.16b -## ld1 {v28.16b},[x0],#16 -## aese v26.16b,v23.16b -## -## // The iv for fifth block -## extr x22,x10,x10,#32 -## extr x10,x10,x9,#63 -## and w11,w19,w22,asr #31 -## eor x9,x11,x9,lsl #1 -## fmov d11,x9 -## fmov v11.d[1],x10 -## -## ld1 {v29.16b},[x0],#16 -## cbz x6,.Lxts_enc_tail4x -## ld1 {v16.4s},[x7],#16 // re-pre-load rndkey[0] -## eor v4.16b,v4.16b,v0.16b -## eor v0.16b,v2.16b,v6.16b -## eor v5.16b,v5.16b,v1.16b -## eor v1.16b,v3.16b,v8.16b -## eor v17.16b,v17.16b,v24.16b -## eor v24.16b,v27.16b,v9.16b -## eor v30.16b,v30.16b,v25.16b -## eor v25.16b,v28.16b,v10.16b -## eor v31.16b,v31.16b,v26.16b -## st1 {v4.16b},[x1],#16 -## eor v26.16b,v29.16b,v11.16b -## st1 {v5.16b},[x1],#16 -## mov w6,w5 -## st1 {v17.16b},[x1],#16 -## ld1 {v17.4s},[x7],#16 // re-pre-load rndkey[1] -## st1 {v30.16b},[x1],#16 -## st1 {v31.16b},[x1],#16 -## b.hs .Loop5x_xts_enc -## -## -## // If left 4 blocks, borrow the five block's processing. -## // This means if (x2 + 1 block) == 0, which is the case -## // when input size % 5 = 4, continue processing and do -## // another iteration in Loop5x_xts_enc which will exit from -## // cbz x6,.Lxts_enc_tail4x. -## // Otherwise, this is the end of the loop continue processing -## // 0, 1, 2 or 3 blocks (with or without tail) starting at -## // Loop5x_enc_after -## cmn x2,#0x10 -## b.ne .Loop5x_enc_after -## orr v11.16b,v10.16b,v10.16b -## orr v10.16b,v9.16b,v9.16b -## orr v9.16b,v8.16b,v8.16b -## orr v8.16b,v6.16b,v6.16b -## fmov x9,d11 -## fmov x10,v11.d[1] -## eor v0.16b,v6.16b,v2.16b -## eor v1.16b,v8.16b,v3.16b -## eor v24.16b,v27.16b,v9.16b -## eor v25.16b,v28.16b,v10.16b -## eor v26.16b,v29.16b,v11.16b -## b.eq .Loop5x_xts_enc -## -## .Loop5x_enc_after: -## add x2,x2,#0x50 -## cbz x2,.Lxts_enc_done // no blocks left -## -## add w6,w5,#2 -## subs x2,x2,#0x30 -## b.lo .Lxts_inner_enc_tail // 1 or 2 blocks left -## // (with tail or not) -## -## eor v0.16b,v6.16b,v27.16b // 3 blocks left -## eor v1.16b,v8.16b,v28.16b -## eor v24.16b,v29.16b,v9.16b -## b .Lxts_outer_enc_tail -## -## .align 4 -## .Lxts_enc_tail4x: -## add x0,x0,#16 -## eor v5.16b,v1.16b,v5.16b -## st1 {v5.16b},[x1],#16 -## eor v17.16b,v24.16b,v17.16b -## st1 {v17.16b},[x1],#16 -## eor v30.16b,v25.16b,v30.16b -## eor v31.16b,v26.16b,v31.16b -## st1 {v30.16b,v31.16b},[x1],#32 -## b .Lxts_enc_done -## .align 4 -## .Lxts_outer_enc_tail: -## aese v0.16b,v16.16b -## aesmc v0.16b,v0.16b -## aese v1.16b,v16.16b -## aesmc v1.16b,v1.16b -## aese v24.16b,v16.16b -## aesmc v24.16b,v24.16b -## ld1 {v16.4s},[x7],#16 -## subs w6,w6,#2 -## aese v0.16b,v17.16b -## aesmc v0.16b,v0.16b -## aese v1.16b,v17.16b -## aesmc v1.16b,v1.16b -## aese v24.16b,v17.16b -## aesmc v24.16b,v24.16b -## ld1 {v17.4s},[x7],#16 -## b.gt .Lxts_outer_enc_tail -## -## aese v0.16b,v16.16b -## aesmc v0.16b,v0.16b -## aese v1.16b,v16.16b -## aesmc v1.16b,v1.16b -## aese v24.16b,v16.16b -## aesmc v24.16b,v24.16b -## eor v4.16b,v6.16b,v7.16b -## subs x2,x2,#0x30 -## // The iv for first block -## fmov x9,d9 -## fmov x10,v9.d[1] -## //mov w19,#0x87 -## extr x22,x10,x10,#32 -## extr x10,x10,x9,#63 -## and w11,w19,w22,asr#31 -## eor x9,x11,x9,lsl#1 -## fmov d6,x9 -## fmov v6.d[1],x10 -## eor v5.16b,v8.16b,v7.16b -## csel x6,x2,x6,lo // x6, w6, is zero at this point -## aese v0.16b,v17.16b -## aesmc v0.16b,v0.16b -## aese v1.16b,v17.16b -## aesmc v1.16b,v1.16b -## aese v24.16b,v17.16b -## aesmc v24.16b,v24.16b -## eor v17.16b,v9.16b,v7.16b -## -## add x6,x6,#0x20 -## add x0,x0,x6 -## mov x7,x3 -## -## aese v0.16b,v20.16b -## aesmc v0.16b,v0.16b -## aese v1.16b,v20.16b -## aesmc v1.16b,v1.16b -## aese v24.16b,v20.16b -## aesmc v24.16b,v24.16b -## aese v0.16b,v21.16b -## aesmc v0.16b,v0.16b -## aese v1.16b,v21.16b -## aesmc v1.16b,v1.16b -## aese v24.16b,v21.16b -## aesmc v24.16b,v24.16b -## aese v0.16b,v22.16b -## aesmc v0.16b,v0.16b -## aese v1.16b,v22.16b -## aesmc v1.16b,v1.16b -## aese v24.16b,v22.16b -## aesmc v24.16b,v24.16b -## aese v0.16b,v23.16b -## aese v1.16b,v23.16b -## aese v24.16b,v23.16b -## ld1 {v27.16b},[x0],#16 -## add w6,w5,#2 -## ld1 {v16.4s},[x7],#16 // re-pre-load rndkey[0] -## eor v4.16b,v4.16b,v0.16b -## eor v5.16b,v5.16b,v1.16b -## eor v24.16b,v24.16b,v17.16b -## ld1 {v17.4s},[x7],#16 // re-pre-load rndkey[1] -## st1 {v4.16b},[x1],#16 -## st1 {v5.16b},[x1],#16 -## st1 {v24.16b},[x1],#16 -## cmn x2,#0x30 -## b.eq .Lxts_enc_done -## .Lxts_encxor_one: -## orr v28.16b,v3.16b,v3.16b -## orr v29.16b,v27.16b,v27.16b -## nop -## -## .Lxts_inner_enc_tail: -## cmn x2,#0x10 -## eor v1.16b,v28.16b,v6.16b -## eor v24.16b,v29.16b,v8.16b -## b.eq .Lxts_enc_tail_loop -## eor v24.16b,v29.16b,v6.16b -## .Lxts_enc_tail_loop: -## aese v1.16b,v16.16b -## aesmc v1.16b,v1.16b -## aese v24.16b,v16.16b -## aesmc v24.16b,v24.16b -## ld1 {v16.4s},[x7],#16 -## subs w6,w6,#2 -## aese v1.16b,v17.16b -## aesmc v1.16b,v1.16b -## aese v24.16b,v17.16b -## aesmc v24.16b,v24.16b -## ld1 {v17.4s},[x7],#16 -## b.gt .Lxts_enc_tail_loop -## -## aese v1.16b,v16.16b -## aesmc v1.16b,v1.16b -## aese v24.16b,v16.16b -## aesmc v24.16b,v24.16b -## aese v1.16b,v17.16b -## aesmc v1.16b,v1.16b -## aese v24.16b,v17.16b -## aesmc v24.16b,v24.16b -## aese v1.16b,v20.16b -## aesmc v1.16b,v1.16b -## aese v24.16b,v20.16b -## aesmc v24.16b,v24.16b -## cmn x2,#0x20 -## aese v1.16b,v21.16b -## aesmc v1.16b,v1.16b -## aese v24.16b,v21.16b -## aesmc v24.16b,v24.16b -## eor v5.16b,v6.16b,v7.16b -## aese v1.16b,v22.16b -## aesmc v1.16b,v1.16b -## aese v24.16b,v22.16b -## aesmc v24.16b,v24.16b -## eor v17.16b,v8.16b,v7.16b -## aese v1.16b,v23.16b -## aese v24.16b,v23.16b -## b.eq .Lxts_enc_one -## eor v5.16b,v5.16b,v1.16b -## st1 {v5.16b},[x1],#16 -## eor v17.16b,v17.16b,v24.16b -## orr v6.16b,v8.16b,v8.16b -## st1 {v17.16b},[x1],#16 -## fmov x9,d8 -## fmov x10,v8.d[1] -## mov w19,#0x87 -## extr x22,x10,x10,#32 -## extr x10,x10,x9,#63 -## and w11,w19,w22,asr #31 -## eor x9,x11,x9,lsl #1 -## fmov d6,x9 -## fmov v6.d[1],x10 -## b .Lxts_enc_done -## -## .Lxts_enc_one: -## eor v5.16b,v5.16b,v24.16b -## orr v6.16b,v6.16b,v6.16b -## st1 {v5.16b},[x1],#16 -## fmov x9,d6 -## fmov x10,v6.d[1] -## mov w19,#0x87 -## extr x22,x10,x10,#32 -## extr x10,x10,x9,#63 -## and w11,w19,w22,asr #31 -## eor x9,x11,x9,lsl #1 -## fmov d6,x9 -## fmov v6.d[1],x10 -## b .Lxts_enc_done -## .align 5 -## .Lxts_enc_done: -## // Process the tail block with cipher stealing. -## tst x21,#0xf -## b.eq .Lxts_abort -## -## mov x20,x0 -## mov x13,x1 -## sub x1,x1,#16 -## .composite_enc_loop: -## subs x21,x21,#1 -## ldrb w15,[x1,x21] -## ldrb w14,[x20,x21] -## strb w15,[x13,x21] -## strb w14,[x1,x21] -## b.gt .composite_enc_loop -## .Lxts_enc_load_done: -## ld1 {v26.16b},[x1] -## eor v26.16b,v26.16b,v6.16b -## -## // Encrypt the composite block to get the last second encrypted text block -## ldr w6,[x3,#240] // load key schedule... -## ld1 {v0.16b},[x3],#16 -## sub w6,w6,#2 -## ld1 {v1.16b},[x3],#16 // load key schedule... -## .Loop_final_enc: -## aese v26.16b,v0.16b -## aesmc v26.16b,v26.16b -## ld1 {v0.4s},[x3],#16 -## subs w6,w6,#2 -## aese v26.16b,v1.16b -## aesmc v26.16b,v26.16b -## ld1 {v1.4s},[x3],#16 -## b.gt .Loop_final_enc -## -## aese v26.16b,v0.16b -## aesmc v26.16b,v26.16b -## ld1 {v0.4s},[x3] -## aese v26.16b,v1.16b -## eor v26.16b,v26.16b,v0.16b -## eor v26.16b,v26.16b,v6.16b -## st1 {v26.16b},[x1] -## -## .Lxts_abort: -## ldp x21,x22,[sp,#48] -## ldp d8,d9,[sp,#32] -## ldp d10,d11,[sp,#16] -## ldp x19,x20,[sp],#64 -## .Lxts_enc_final_abort: -## ret -## - -# Decrypt is taken from -# https://github.com/aws/aws-lc/blob/804a11b6f965365156b0a8b6d958233e1372a2e2/generated-src/linux-aarch64/crypto/fipsmodule/aesv8-armx.S#L1475 - -aes_hw_xts_decrypt: - cmp x2,#16 - // Original input data size bigger than 16, jump to big size processing. - b.ne .Lxts_dec_big_size - // Encrypt the iv with key2, as the first XEX iv. - ldr w6,[x4,#240] - ld1 {v0.16b},[x4],#16 - ld1 {v6.16b},[x5] - sub w6,w6,#2 - ld1 {v1.16b},[x4],#16 - -.Loop_dec_small_iv_enc: - aese v6.16b,v0.16b - aesmc v6.16b,v6.16b - ld1 {v0.4s},[x4],#16 - subs w6,w6,#2 - aese v6.16b,v1.16b - aesmc v6.16b,v6.16b - ld1 {v1.4s},[x4],#16 - b.gt .Loop_dec_small_iv_enc - - aese v6.16b,v0.16b - aesmc v6.16b,v6.16b - ld1 {v0.4s},[x4] - aese v6.16b,v1.16b - eor v6.16b,v6.16b,v0.16b - - ld1 {v0.16b},[x0] - eor v0.16b,v6.16b,v0.16b - - ldr w6,[x3,#240] - ld1 {v28.4s,v29.4s},[x3],#32 // load key schedule... - - aesd v0.16b,v28.16b - aesimc v0.16b,v0.16b - ld1 {v16.4s,v17.4s},[x3],#32 // load key schedule... - aesd v0.16b,v29.16b - aesimc v0.16b,v0.16b - subs w6,w6,#10 // bias - b.eq .Lxts_128_dec -.Lxts_dec_round_loop: - aesd v0.16b,v16.16b - aesimc v0.16b,v0.16b - ld1 {v16.4s},[x3],#16 // load key schedule... - aesd v0.16b,v17.16b - aesimc v0.16b,v0.16b - ld1 {v17.4s},[x3],#16 // load key schedule... - subs w6,w6,#2 // bias - b.gt .Lxts_dec_round_loop -.Lxts_128_dec: - ld1 {v18.4s,v19.4s},[x3],#32 // load key schedule... - aesd v0.16b,v16.16b - aesimc v0.16b,v0.16b - aesd v0.16b,v17.16b - aesimc v0.16b,v0.16b - ld1 {v20.4s,v21.4s},[x3],#32 // load key schedule... - aesd v0.16b,v18.16b - aesimc v0.16b,v0.16b - aesd v0.16b,v19.16b - aesimc v0.16b,v0.16b - ld1 {v22.4s,v23.4s},[x3],#32 // load key schedule... - aesd v0.16b,v20.16b - aesimc v0.16b,v0.16b - aesd v0.16b,v21.16b - aesimc v0.16b,v0.16b - ld1 {v7.4s},[x3] - aesd v0.16b,v22.16b - aesimc v0.16b,v0.16b - aesd v0.16b,v23.16b - eor v0.16b,v0.16b,v7.16b - eor v0.16b,v6.16b,v0.16b - st1 {v0.16b},[x1] - b .Lxts_dec_final_abort -.Lxts_dec_big_size: - stp x19,x20,[sp,#-64]! - stp x21,x22,[sp,#48] - stp d8,d9,[sp,#32] - stp d10,d11,[sp,#16] - - and x21,x2,#0xf - and x2,x2,#-16 - subs x2,x2,#16 - mov x8,#16 - b.lo .Lxts_dec_abort - - // Encrypt the iv with key2, as the first XEX iv - ldr w6,[x4,#240] - ld1 {v0.16b},[x4],#16 - ld1 {v6.16b},[x5] - sub w6,w6,#2 - ld1 {v1.16b},[x4],#16 - -.Loop_dec_iv_enc: - aese v6.16b,v0.16b - aesmc v6.16b,v6.16b - ld1 {v0.4s},[x4],#16 - subs w6,w6,#2 - aese v6.16b,v1.16b - aesmc v6.16b,v6.16b - ld1 {v1.4s},[x4],#16 - b.gt .Loop_dec_iv_enc - - aese v6.16b,v0.16b - aesmc v6.16b,v6.16b - ld1 {v0.4s},[x4] - aese v6.16b,v1.16b - eor v6.16b,v6.16b,v0.16b - - // The iv for second block - // x9- iv(low), x10 - iv(high) - // the five ivs stored into, v6.16b,v8.16b,v9.16b,v10.16b,v11.16b - fmov x9,d6 - fmov x10,v6.d[1] - mov w19,#0x87 - extr x22,x10,x10,#32 - extr x10,x10,x9,#63 - and w11,w19,w22,asr #31 - eor x9,x11,x9,lsl #1 - fmov d8,x9 - fmov v8.d[1],x10 - - ldr w5,[x3,#240] // load rounds number - - // The iv for third block - extr x22,x10,x10,#32 - extr x10,x10,x9,#63 - and w11,w19,w22,asr #31 - eor x9,x11,x9,lsl #1 - fmov d9,x9 - fmov v9.d[1],x10 - - ld1 {v16.4s,v17.4s},[x3] // load key schedule... - sub w5,w5,#6 - add x7,x3,x5,lsl#4 // pointer to last 7 round keys - sub w5,w5,#2 - ld1 {v18.4s,v19.4s},[x7],#32 // load key schedule... - ld1 {v20.4s,v21.4s},[x7],#32 - ld1 {v22.4s,v23.4s},[x7],#32 - ld1 {v7.4s},[x7] - - // The iv for fourth block - extr x22,x10,x10,#32 - extr x10,x10,x9,#63 - and w11,w19,w22,asr #31 - eor x9,x11,x9,lsl #1 - fmov d10,x9 - fmov v10.d[1],x10 - - add x7,x3,#32 - mov w6,w5 - b .Lxts_dec - - // Decryption -.align 5 -.Lxts_dec: - tst x21,#0xf - b.eq .Lxts_dec_begin - subs x2,x2,#16 - csel x8,xzr,x8,eq - ld1 {v0.16b},[x0],#16 - b.lo .Lxts_done - sub x0,x0,#16 -.Lxts_dec_begin: - ld1 {v0.16b},[x0],x8 - subs x2,x2,#32 // bias - add w6,w5,#2 - orr v3.16b,v0.16b,v0.16b - orr v1.16b,v0.16b,v0.16b - orr v28.16b,v0.16b,v0.16b - ld1 {v24.16b},[x0],#16 - orr v27.16b,v24.16b,v24.16b - orr v29.16b,v24.16b,v24.16b - b.lo .Lxts_inner_dec_tail - eor v0.16b,v0.16b,v6.16b // before decryt, xor with iv - eor v24.16b,v24.16b,v8.16b - - orr v1.16b,v24.16b,v24.16b - ld1 {v24.16b},[x0],#16 - orr v2.16b,v0.16b,v0.16b - orr v3.16b,v1.16b,v1.16b - eor v27.16b,v24.16b,v9.16b // third block xox with third iv - eor v24.16b,v24.16b,v9.16b - cmp x2,#32 - b.lo .Lxts_outer_dec_tail - - ld1 {v25.16b},[x0],#16 - - // The iv for fifth block - extr x22,x10,x10,#32 - extr x10,x10,x9,#63 - and w11,w19,w22,asr #31 - eor x9,x11,x9,lsl #1 - fmov d11,x9 - fmov v11.d[1],x10 - - ld1 {v26.16b},[x0],#16 - eor v25.16b,v25.16b,v10.16b // the fourth block - eor v26.16b,v26.16b,v11.16b - sub x2,x2,#32 // bias - mov w6,w5 - b .Loop5x_xts_dec - -.align 4 -.Loop5x_xts_dec: - aesd v0.16b,v16.16b - aesimc v0.16b,v0.16b - aesd v1.16b,v16.16b - aesimc v1.16b,v1.16b - aesd v24.16b,v16.16b - aesimc v24.16b,v24.16b - aesd v25.16b,v16.16b - aesimc v25.16b,v25.16b - aesd v26.16b,v16.16b - aesimc v26.16b,v26.16b - ld1 {v16.4s},[x7],#16 // load key schedule... - subs w6,w6,#2 - aesd v0.16b,v17.16b - aesimc v0.16b,v0.16b - aesd v1.16b,v17.16b - aesimc v1.16b,v1.16b - aesd v24.16b,v17.16b - aesimc v24.16b,v24.16b - aesd v25.16b,v17.16b - aesimc v25.16b,v25.16b - aesd v26.16b,v17.16b - aesimc v26.16b,v26.16b - ld1 {v17.4s},[x7],#16 // load key schedule... - b.gt .Loop5x_xts_dec - - aesd v0.16b,v16.16b - aesimc v0.16b,v0.16b - aesd v1.16b,v16.16b - aesimc v1.16b,v1.16b - aesd v24.16b,v16.16b - aesimc v24.16b,v24.16b - aesd v25.16b,v16.16b - aesimc v25.16b,v25.16b - aesd v26.16b,v16.16b - aesimc v26.16b,v26.16b - subs x2,x2,#0x50 // because .Lxts_dec_tail4x - - aesd v0.16b,v17.16b - aesimc v0.16b,v0.16b - aesd v1.16b,v17.16b - aesimc v1.16b,v1.16b - aesd v24.16b,v17.16b - aesimc v24.16b,v24.16b - aesd v25.16b,v17.16b - aesimc v25.16b,v25.16b - aesd v26.16b,v17.16b - aesimc v26.16b,v26.16b - csel x6,xzr,x2,gt // borrow x6, w6, "gt" is not typo - mov x7,x3 - - aesd v0.16b,v18.16b - aesimc v0.16b,v0.16b - aesd v1.16b,v18.16b - aesimc v1.16b,v1.16b - aesd v24.16b,v18.16b - aesimc v24.16b,v24.16b - aesd v25.16b,v18.16b - aesimc v25.16b,v25.16b - aesd v26.16b,v18.16b - aesimc v26.16b,v26.16b - add x0,x0,x6 // x0 is adjusted in such way that - // at exit from the loop v1.16b-v26.16b - // are loaded with last "words" - add x6,x2,#0x60 // because .Lxts_dec_tail4x - - aesd v0.16b,v19.16b - aesimc v0.16b,v0.16b - aesd v1.16b,v19.16b - aesimc v1.16b,v1.16b - aesd v24.16b,v19.16b - aesimc v24.16b,v24.16b - aesd v25.16b,v19.16b - aesimc v25.16b,v25.16b - aesd v26.16b,v19.16b - aesimc v26.16b,v26.16b - - aesd v0.16b,v20.16b - aesimc v0.16b,v0.16b - aesd v1.16b,v20.16b - aesimc v1.16b,v1.16b - aesd v24.16b,v20.16b - aesimc v24.16b,v24.16b - aesd v25.16b,v20.16b - aesimc v25.16b,v25.16b - aesd v26.16b,v20.16b - aesimc v26.16b,v26.16b - - aesd v0.16b,v21.16b - aesimc v0.16b,v0.16b - aesd v1.16b,v21.16b - aesimc v1.16b,v1.16b - aesd v24.16b,v21.16b - aesimc v24.16b,v24.16b - aesd v25.16b,v21.16b - aesimc v25.16b,v25.16b - aesd v26.16b,v21.16b - aesimc v26.16b,v26.16b - - aesd v0.16b,v22.16b - aesimc v0.16b,v0.16b - aesd v1.16b,v22.16b - aesimc v1.16b,v1.16b - aesd v24.16b,v22.16b - aesimc v24.16b,v24.16b - aesd v25.16b,v22.16b - aesimc v25.16b,v25.16b - aesd v26.16b,v22.16b - aesimc v26.16b,v26.16b - - eor v4.16b,v7.16b,v6.16b - aesd v0.16b,v23.16b - // The iv for first block of next iteration. - extr x22,x10,x10,#32 - extr x10,x10,x9,#63 - and w11,w19,w22,asr #31 - eor x9,x11,x9,lsl #1 - fmov d6,x9 - fmov v6.d[1],x10 - eor v5.16b,v7.16b,v8.16b - ld1 {v2.16b},[x0],#16 - aesd v1.16b,v23.16b - // The iv for second block - extr x22,x10,x10,#32 - extr x10,x10,x9,#63 - and w11,w19,w22,asr #31 - eor x9,x11,x9,lsl #1 - fmov d8,x9 - fmov v8.d[1],x10 - eor v17.16b,v7.16b,v9.16b - ld1 {v3.16b},[x0],#16 - aesd v24.16b,v23.16b - // The iv for third block - extr x22,x10,x10,#32 - extr x10,x10,x9,#63 - and w11,w19,w22,asr #31 - eor x9,x11,x9,lsl #1 - fmov d9,x9 - fmov v9.d[1],x10 - eor v30.16b,v7.16b,v10.16b - ld1 {v27.16b},[x0],#16 - aesd v25.16b,v23.16b - // The iv for fourth block - extr x22,x10,x10,#32 - extr x10,x10,x9,#63 - and w11,w19,w22,asr #31 - eor x9,x11,x9,lsl #1 - fmov d10,x9 - fmov v10.d[1],x10 - eor v31.16b,v7.16b,v11.16b - ld1 {v28.16b},[x0],#16 - aesd v26.16b,v23.16b - - // The iv for fifth block - extr x22,x10,x10,#32 - extr x10,x10,x9,#63 - and w11,w19,w22,asr #31 - eor x9,x11,x9,lsl #1 - fmov d11,x9 - fmov v11.d[1],x10 - - ld1 {v29.16b},[x0],#16 - cbz x6,.Lxts_dec_tail4x - ld1 {v16.4s},[x7],#16 // re-pre-load rndkey[0] - eor v4.16b,v4.16b,v0.16b - eor v0.16b,v2.16b,v6.16b - eor v5.16b,v5.16b,v1.16b - eor v1.16b,v3.16b,v8.16b - eor v17.16b,v17.16b,v24.16b - eor v24.16b,v27.16b,v9.16b - eor v30.16b,v30.16b,v25.16b - eor v25.16b,v28.16b,v10.16b - eor v31.16b,v31.16b,v26.16b - st1 {v4.16b},[x1],#16 - eor v26.16b,v29.16b,v11.16b - st1 {v5.16b},[x1],#16 - mov w6,w5 - st1 {v17.16b},[x1],#16 - ld1 {v17.4s},[x7],#16 // re-pre-load rndkey[1] - st1 {v30.16b},[x1],#16 - st1 {v31.16b},[x1],#16 - b.hs .Loop5x_xts_dec - - cmn x2,#0x10 - b.ne .Loop5x_dec_after - // If x2(x2) equal to -0x10, the left blocks is 4. - // After specially processing, utilize the five blocks processing again. - // It will use the following IVs: v6.16b,v6.16b,v8.16b,v9.16b,v10.16b. - orr v11.16b,v10.16b,v10.16b - orr v10.16b,v9.16b,v9.16b - orr v9.16b,v8.16b,v8.16b - orr v8.16b,v6.16b,v6.16b - fmov x9,d11 - fmov x10,v11.d[1] - eor v0.16b,v6.16b,v2.16b - eor v1.16b,v8.16b,v3.16b - eor v24.16b,v27.16b,v9.16b - eor v25.16b,v28.16b,v10.16b - eor v26.16b,v29.16b,v11.16b - b.eq .Loop5x_xts_dec - -.Loop5x_dec_after: - add x2,x2,#0x50 - cbz x2,.Lxts_done - - add w6,w5,#2 - subs x2,x2,#0x30 - b.lo .Lxts_inner_dec_tail - - eor v0.16b,v6.16b,v27.16b - eor v1.16b,v8.16b,v28.16b - eor v24.16b,v29.16b,v9.16b - b .Lxts_outer_dec_tail - -.align 4 -.Lxts_dec_tail4x: - add x0,x0,#16 - tst x21,#0xf - eor v5.16b,v1.16b,v4.16b - st1 {v5.16b},[x1],#16 - eor v17.16b,v24.16b,v17.16b - st1 {v17.16b},[x1],#16 - eor v30.16b,v25.16b,v30.16b - eor v31.16b,v26.16b,v31.16b - st1 {v30.16b,v31.16b},[x1],#32 - - b.eq .Lxts_dec_abort - ld1 {v0.4s},[x0],#16 - b .Lxts_done -.align 4 -.Lxts_outer_dec_tail: - aesd v0.16b,v16.16b - aesimc v0.16b,v0.16b - aesd v1.16b,v16.16b - aesimc v1.16b,v1.16b - aesd v24.16b,v16.16b - aesimc v24.16b,v24.16b - ld1 {v16.4s},[x7],#16 - subs w6,w6,#2 - aesd v0.16b,v17.16b - aesimc v0.16b,v0.16b - aesd v1.16b,v17.16b - aesimc v1.16b,v1.16b - aesd v24.16b,v17.16b - aesimc v24.16b,v24.16b - ld1 {v17.4s},[x7],#16 - b.gt .Lxts_outer_dec_tail - - aesd v0.16b,v16.16b - aesimc v0.16b,v0.16b - aesd v1.16b,v16.16b - aesimc v1.16b,v1.16b - aesd v24.16b,v16.16b - aesimc v24.16b,v24.16b - eor v4.16b,v6.16b,v7.16b - subs x2,x2,#0x30 - // The iv for first block - fmov x9,d9 - fmov x10,v9.d[1] - mov w19,#0x87 - extr x22,x10,x10,#32 - extr x10,x10,x9,#63 - and w11,w19,w22,asr #31 - eor x9,x11,x9,lsl #1 - fmov d6,x9 - fmov v6.d[1],x10 - eor v5.16b,v8.16b,v7.16b - csel x6,x2,x6,lo // x6, w6, is zero at this point - aesd v0.16b,v17.16b - aesimc v0.16b,v0.16b - aesd v1.16b,v17.16b - aesimc v1.16b,v1.16b - aesd v24.16b,v17.16b - aesimc v24.16b,v24.16b - eor v17.16b,v9.16b,v7.16b - // The iv for second block - extr x22,x10,x10,#32 - extr x10,x10,x9,#63 - and w11,w19,w22,asr #31 - eor x9,x11,x9,lsl #1 - fmov d8,x9 - fmov v8.d[1],x10 - - add x6,x6,#0x20 - add x0,x0,x6 // x0 is adjusted to the last data - - mov x7,x3 - - // The iv for third block - extr x22,x10,x10,#32 - extr x10,x10,x9,#63 - and w11,w19,w22,asr #31 - eor x9,x11,x9,lsl #1 - fmov d9,x9 - fmov v9.d[1],x10 - - aesd v0.16b,v20.16b - aesimc v0.16b,v0.16b - aesd v1.16b,v20.16b - aesimc v1.16b,v1.16b - aesd v24.16b,v20.16b - aesimc v24.16b,v24.16b - aesd v0.16b,v21.16b - aesimc v0.16b,v0.16b - aesd v1.16b,v21.16b - aesimc v1.16b,v1.16b - aesd v24.16b,v21.16b - aesimc v24.16b,v24.16b - aesd v0.16b,v22.16b - aesimc v0.16b,v0.16b - aesd v1.16b,v22.16b - aesimc v1.16b,v1.16b - aesd v24.16b,v22.16b - aesimc v24.16b,v24.16b - ld1 {v27.16b},[x0],#16 - aesd v0.16b,v23.16b - aesd v1.16b,v23.16b - aesd v24.16b,v23.16b - ld1 {v16.4s},[x7],#16 // re-pre-load rndkey[0] - add w6,w5,#2 - eor v4.16b,v4.16b,v0.16b - eor v5.16b,v5.16b,v1.16b - eor v24.16b,v24.16b,v17.16b - ld1 {v17.4s},[x7],#16 // re-pre-load rndkey[1] - st1 {v4.16b},[x1],#16 - st1 {v5.16b},[x1],#16 - st1 {v24.16b},[x1],#16 - - cmn x2,#0x30 - add x2,x2,#0x30 - b.eq .Lxts_done - sub x2,x2,#0x30 - orr v28.16b,v3.16b,v3.16b - orr v29.16b,v27.16b,v27.16b - nop - -.Lxts_inner_dec_tail: - // x2 == -0x10 means two blocks left. - cmn x2,#0x10 - eor v1.16b,v28.16b,v6.16b - eor v24.16b,v29.16b,v8.16b - b.eq .Lxts_dec_tail_loop - eor v24.16b,v29.16b,v6.16b -.Lxts_dec_tail_loop: - aesd v1.16b,v16.16b - aesimc v1.16b,v1.16b - aesd v24.16b,v16.16b - aesimc v24.16b,v24.16b - ld1 {v16.4s},[x7],#16 - subs w6,w6,#2 - aesd v1.16b,v17.16b - aesimc v1.16b,v1.16b - aesd v24.16b,v17.16b - aesimc v24.16b,v24.16b - ld1 {v17.4s},[x7],#16 - b.gt .Lxts_dec_tail_loop - - aesd v1.16b,v16.16b - aesimc v1.16b,v1.16b - aesd v24.16b,v16.16b - aesimc v24.16b,v24.16b - aesd v1.16b,v17.16b - aesimc v1.16b,v1.16b - aesd v24.16b,v17.16b - aesimc v24.16b,v24.16b - aesd v1.16b,v20.16b - aesimc v1.16b,v1.16b - aesd v24.16b,v20.16b - aesimc v24.16b,v24.16b - cmn x2,#0x20 - aesd v1.16b,v21.16b - aesimc v1.16b,v1.16b - aesd v24.16b,v21.16b - aesimc v24.16b,v24.16b - eor v5.16b,v6.16b,v7.16b - aesd v1.16b,v22.16b - aesimc v1.16b,v1.16b - aesd v24.16b,v22.16b - aesimc v24.16b,v24.16b - eor v17.16b,v8.16b,v7.16b - aesd v1.16b,v23.16b - aesd v24.16b,v23.16b - b.eq .Lxts_dec_one - eor v5.16b,v5.16b,v1.16b - eor v17.16b,v17.16b,v24.16b - orr v6.16b,v9.16b,v9.16b - orr v8.16b,v10.16b,v10.16b - st1 {v5.16b},[x1],#16 - st1 {v17.16b},[x1],#16 - add x2,x2,#16 - b .Lxts_done - -.Lxts_dec_one: - eor v5.16b,v5.16b,v24.16b - orr v6.16b,v8.16b,v8.16b - orr v8.16b,v9.16b,v9.16b - st1 {v5.16b},[x1],#16 - add x2,x2,#32 - -.Lxts_done: - tst x21,#0xf - b.eq .Lxts_dec_abort - // Processing the last two blocks with cipher stealing. - mov x7,x3 - cbnz x2,.Lxts_dec_1st_done - ld1 {v0.4s},[x0],#16 - - // Decrypt the last secod block to get the last plain text block -.Lxts_dec_1st_done: - eor v26.16b,v0.16b,v8.16b - ldr w6,[x3,#240] - ld1 {v0.4s},[x3],#16 - sub w6,w6,#2 - ld1 {v1.4s},[x3],#16 -.Loop_final_2nd_dec: - aesd v26.16b,v0.16b - aesimc v26.16b,v26.16b - ld1 {v0.4s},[x3],#16 // load key schedule... - subs w6,w6,#2 - aesd v26.16b,v1.16b - aesimc v26.16b,v26.16b - ld1 {v1.4s},[x3],#16 // load key schedule... - b.gt .Loop_final_2nd_dec - - aesd v26.16b,v0.16b - aesimc v26.16b,v26.16b - ld1 {v0.4s},[x3] - aesd v26.16b,v1.16b - eor v26.16b,v26.16b,v0.16b - eor v26.16b,v26.16b,v8.16b - st1 {v26.16b},[x1] - - mov x20,x0 - add x13,x1,#16 - - // Composite the tailcnt "16 byte not aligned block" into the last second plain blocks - // to get the last encrypted block. -.composite_dec_loop: - subs x21,x21,#1 - ldrb w15,[x1,x21] - ldrb w14,[x20,x21] - strb w15,[x13,x21] - strb w14,[x1,x21] - b.gt .composite_dec_loop -.Lxts_dec_load_done: - ld1 {v26.16b},[x1] - eor v26.16b,v26.16b,v6.16b - - // Decrypt the composite block to get the last second plain text block - ldr w6,[x7,#240] - ld1 {v0.16b},[x7],#16 - sub w6,w6,#2 - ld1 {v1.16b},[x7],#16 -.Loop_final_dec: - aesd v26.16b,v0.16b - aesimc v26.16b,v26.16b - ld1 {v0.4s},[x7],#16 // load key schedule... - subs w6,w6,#2 - aesd v26.16b,v1.16b - aesimc v26.16b,v26.16b - ld1 {v1.4s},[x7],#16 // load key schedule... - b.gt .Loop_final_dec - - aesd v26.16b,v0.16b - aesimc v26.16b,v26.16b - ld1 {v0.4s},[x7] - aesd v26.16b,v1.16b - eor v26.16b,v26.16b,v0.16b - eor v26.16b,v26.16b,v6.16b - st1 {v26.16b},[x1] - -.Lxts_dec_abort: - ldp x21,x22,[sp,#48] - ldp d8,d9,[sp,#32] - ldp d10,d11,[sp,#16] - ldp x19,x20,[sp],#64 - -.Lxts_dec_final_abort: + ld1.16b { v26 }, [x1] + eor.16b v26, v26, v6 + ldr w6, [x3, #0xf0] + ld1.16b { v0 }, [x3], #16 + sub w6, w6, #0x2 + ld1.16b { v1 }, [x3], #16 + aese.16b v26, v0 + aesmc.16b v26, v26 + ld1.4s { v0 }, [x3], #16 + subs w6, w6, #0x2 + aese.16b v26, v1 + aesmc.16b v26, v26 + ld1.4s { v1 }, [x3], #16 + b.gt 0xa24 + aese.16b v26, v0 + aesmc.16b v26, v26 + ld1.4s { v0 }, [x3] + aese.16b v26, v1 + eor.16b v26, v26, v0 + eor.16b v26, v26, v6 + st1.16b { v26 }, [x1] + ldp x19, x20, [sp, #0x40] + ldp x21, x22, [sp, #0x50] + ldp d8, d9, [sp] + ldp d10, d11, [sp, #0x10] + ldp d12, d13, [sp, #0x20] + ldp d14, d15, [sp, #0x30] + add sp, sp, #0x60 ret - -#if defined(__linux__) && defined(__ELF__) -.section .note.GNU-stack,"",%progbits -#endif diff --git a/arm/aes-xts/aes-xts-armv8.txt b/arm/aes-xts/aes-xts-armv8.txt index 78438bffb..d750c3852 100644 --- a/arm/aes-xts/aes-xts-armv8.txt +++ b/arm/aes-xts/aes-xts-armv8.txt @@ -1,78 +1,18 @@ [ + 0xd10183ff; (* arm_SUB SP SP (rvalue (word 96)) *) + 0x6d0027e8; (* arm_STP D8 D9 SP (Immediate_Offset (iword (&0))) *) + 0x6d012fea; (* arm_STP D10 D11 SP (Immediate_Offset (iword (&16))) *) + 0x6d0237ec; (* arm_STP D12 D13 SP (Immediate_Offset (iword (&32))) *) + 0x6d033fee; (* arm_STP D14 D15 SP (Immediate_Offset (iword (&48))) *) + 0xa90453f3; (* arm_STP X19 X20 SP (Immediate_Offset (iword (&64))) *) + 0xa9055bf5; (* arm_STP X21 X22 SP (Immediate_Offset (iword (&80))) *) 0xf100405f; (* arm_CMP X2 (rvalue (word 16)) *) - 0x540007e1; (* arm_BNE (word 252) *) - 0xb940f086; (* arm_LDR W6 X4 (Immediate_Offset (word 240)) *) - 0x4cdf7080; (* arm_LDR Q0 X4 (Postimmediate_Offset (word 16)) *) - 0x4c4070a6; (* arm_LDR Q6 X5 No_Offset *) - 0x510008c6; (* arm_SUB W6 W6 (rvalue (word 2)) *) - 0x4cdf7081; (* arm_LDR Q1 X4 (Postimmediate_Offset (word 16)) *) - 0x4e284806; (* arm_AESE Q6 Q0 *) - 0x4e2868c6; (* arm_AESMC Q6 Q6 *) - 0x4cdf7880; (* arm_LDR Q0 X4 (Postimmediate_Offset (word 16)) *) - 0x710008c6; (* arm_SUBS W6 W6 (rvalue (word 2)) *) - 0x4e284826; (* arm_AESE Q6 Q1 *) - 0x4e2868c6; (* arm_AESMC Q6 Q6 *) - 0x4cdf7881; (* arm_LDR Q1 X4 (Postimmediate_Offset (word 16)) *) - 0x54ffff2c; (* arm_BGT (word 2097124) *) - 0x4e284806; (* arm_AESE Q6 Q0 *) - 0x4e2868c6; (* arm_AESMC Q6 Q6 *) - 0x4c407880; (* arm_LDR Q0 X4 No_Offset *) - 0x4e284826; (* arm_AESE Q6 Q1 *) - 0x6e201cc6; (* arm_EOR_VEC Q6 Q6 Q0 128 *) - 0x4c407000; (* arm_LDR Q0 X0 No_Offset *) - 0x6e201cc0; (* arm_EOR_VEC Q0 Q6 Q0 128 *) - 0xb940f066; (* arm_LDR W6 X3 (Immediate_Offset (word 240)) *) - 0x4cdfa87c; (* arm_LDP Q28 Q29 X3 (Postimmediate_Offset (word 32)) *) - 0x4e284b80; (* arm_AESE Q0 Q28 *) - 0x4e286800; (* arm_AESMC Q0 Q0 *) - 0x4cdfa870; (* arm_LDP Q16 Q17 X3 (Postimmediate_Offset (word 32)) *) - 0x4e284ba0; (* arm_AESE Q0 Q29 *) - 0x4e286800; (* arm_AESMC Q0 Q0 *) - 0x710028c6; (* arm_SUBS W6 W6 (rvalue (word 10)) *) - 0x4e284a00; (* arm_AESE Q0 Q16 *) - 0x4e286800; (* arm_AESMC Q0 Q0 *) - 0x4cdf7870; (* arm_LDR Q16 X3 (Postimmediate_Offset (word 16)) *) - 0x4e284a20; (* arm_AESE Q0 Q17 *) - 0x4e286800; (* arm_AESMC Q0 Q0 *) - 0x4cdf7871; (* arm_LDR Q17 X3 (Postimmediate_Offset (word 16)) *) - 0x710008c6; (* arm_SUBS W6 W6 (rvalue (word 2)) *) - 0x54ffff2c; (* arm_BGT (word 2097124) *) - 0x4cdfa872; (* arm_LDP Q18 Q19 X3 (Postimmediate_Offset (word 32)) *) - 0x4e284a00; (* arm_AESE Q0 Q16 *) - 0x4e286800; (* arm_AESMC Q0 Q0 *) - 0x4e284a20; (* arm_AESE Q0 Q17 *) - 0x4e286800; (* arm_AESMC Q0 Q0 *) - 0x4cdfa874; (* arm_LDP Q20 Q21 X3 (Postimmediate_Offset (word 32)) *) - 0x4e284a40; (* arm_AESE Q0 Q18 *) - 0x4e286800; (* arm_AESMC Q0 Q0 *) - 0x4e284a60; (* arm_AESE Q0 Q19 *) - 0x4e286800; (* arm_AESMC Q0 Q0 *) - 0x4cdfa876; (* arm_LDP Q22 Q23 X3 (Postimmediate_Offset (word 32)) *) - 0x4e284a80; (* arm_AESE Q0 Q20 *) - 0x4e286800; (* arm_AESMC Q0 Q0 *) - 0x4e284aa0; (* arm_AESE Q0 Q21 *) - 0x4e286800; (* arm_AESMC Q0 Q0 *) - 0x4c407867; (* arm_LDR Q7 X3 No_Offset *) - 0x4e284ac0; (* arm_AESE Q0 Q22 *) - 0x4e286800; (* arm_AESMC Q0 Q0 *) - 0x4e284ae0; (* arm_AESE Q0 Q23 *) - 0x6e271c00; (* arm_EOR_VEC Q0 Q0 Q7 128 *) - 0x6e261c00; (* arm_EOR_VEC Q0 Q0 Q6 128 *) - 0x4c007020; (* arm_STR Q0 X1 No_Offset *) - 0x140001e8; (* arm_B (word 1952) *) + 0x5400530b; (* arm_BLT (word 2656) *) 0xd503201f; (* arm_NOP *) 0xd503201f; (* arm_NOP *) 0xd503201f; (* arm_NOP *) - 0xa9bc53f3; (* arm_STP X19 X20 SP (Preimmediate_Offset (iword (-- &64))) *) - 0xa9035bf5; (* arm_STP X21 X22 SP (Immediate_Offset (iword (&48))) *) - 0x6d0227e8; (* arm_STP D8 D9 SP (Immediate_Offset (iword (&32))) *) - 0x6d012fea; (* arm_STP D10 D11 SP (Immediate_Offset (iword (&16))) *) 0x92400c55; (* arm_AND X21 X2 (rvalue (word 15)) *) 0x927cec42; (* arm_AND X2 X2 (rvalue (word 18446744073709551600)) *) - 0xf1004042; (* arm_SUBS X2 X2 (rvalue (word 16)) *) - 0xd2800208; (* arm_MOV X8 (rvalue (word 16)) *) - 0x54003b03; (* arm_BCC (word 1888) *) - 0x9a8803e8; (* arm_CSEL X8 XZR X8 Condition_EQ *) 0xb940f086; (* arm_LDR W6 X4 (Immediate_Offset (word 240)) *) 0x4cdf7880; (* arm_LDR Q0 X4 (Postimmediate_Offset (word 16)) *) 0x4c4070a6; (* arm_LDR Q6 X5 No_Offset *) @@ -85,14 +25,14 @@ 0x4e284826; (* arm_AESE Q6 Q1 *) 0x4e2868c6; (* arm_AESMC Q6 Q6 *) 0x4cdf7881; (* arm_LDR Q1 X4 (Postimmediate_Offset (word 16)) *) - 0x54ffff2c; (* arm_BGT (word 2097124) *) + 0x5400026c; (* arm_BGT (word 76) *) 0x4e284806; (* arm_AESE Q6 Q0 *) 0x4e2868c6; (* arm_AESMC Q6 Q6 *) 0x4c407880; (* arm_LDR Q0 X4 No_Offset *) 0x4e284826; (* arm_AESE Q6 Q1 *) 0x6e201cc6; (* arm_EOR_VEC Q6 Q6 Q0 128 *) - 0x9e6600c9; (* arm_FMOV_FtoI X9 Q6 0 *) - 0x9eae00ca; (* arm_FMOV_FtoI X10 Q6 1 *) + 0x9e6600c9; (* arm_FMOV_FtoI X9 Q6 0 64 *) + 0x9eae00ca; (* arm_FMOV_FtoI X10 Q6 1 64 *) 0x528010f3; (* arm_MOV W19 (rvalue (word 135)) *) 0x93ca8156; (* arm_ROR X22 X10 32 *) 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) @@ -100,61 +40,49 @@ 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 1) *) 0x9e670128; (* arm_FMOV_ItoF Q8 X9 0 *) 0x9eaf0148; (* arm_FMOV_ItoF Q8 X10 1 *) - 0xb940f065; (* arm_LDR W5 X3 (Immediate_Offset (word 240)) *) - 0x4cc87000; (* arm_LDR Q0 X0 (Postreg_Offset X8) *) - 0x4c40a870; (* arm_LDP Q16 Q17 X3 No_Offset *) - 0x510018a5; (* arm_SUB W5 W5 (rvalue (word 6)) *) - 0x8b051067; (* arm_ADD X7 X3 (Shiftedreg X5 LSL 4) *) + 0xaa0303e7; (* arm_MOV X7 X3 *) + 0x4cdfa8f0; (* arm_LDP Q16 Q17 X7 (Postimmediate_Offset (word 32)) *) + 0x4cdfa8ec; (* arm_LDP Q12 Q13 X7 (Postimmediate_Offset (word 32)) *) + 0x4cdfa8ee; (* arm_LDP Q14 Q15 X7 (Postimmediate_Offset (word 32)) *) + 0x4cdfa8e4; (* arm_LDP Q4 Q5 X7 (Postimmediate_Offset (word 32)) *) 0x4cdfa8f2; (* arm_LDP Q18 Q19 X7 (Postimmediate_Offset (word 32)) *) 0x4cdfa8f4; (* arm_LDP Q20 Q21 X7 (Postimmediate_Offset (word 32)) *) 0x4cdfa8f6; (* arm_LDP Q22 Q23 X7 (Postimmediate_Offset (word 32)) *) 0x4c4078e7; (* arm_LDR Q7 X7 No_Offset *) - 0x510008a5; (* arm_SUB W5 W5 (rvalue (word 2)) *) - 0x91008067; (* arm_ADD X7 X3 (rvalue (word 32)) *) - 0x2a0503e6; (* arm_MOV W6 W5 *) - 0x4cdf7018; (* arm_LDR Q24 X0 (Postimmediate_Offset (word 16)) *) - 0xf1008042; (* arm_SUBS X2 X2 (rvalue (word 32)) *) - 0x110008a6; (* arm_ADD W6 W5 (rvalue (word 2)) *) - 0x4ea01c03; (* arm_MOV_VEC Q3 Q0 128 *) - 0x4ea01c01; (* arm_MOV_VEC Q1 Q0 128 *) - 0x4ea01c1c; (* arm_MOV_VEC Q28 Q0 128 *) - 0x4eb81f1b; (* arm_MOV_VEC Q27 Q24 128 *) - 0x4eb81f1d; (* arm_MOV_VEC Q29 Q24 128 *) - 0x54002723; (* arm_BCC (word 1252) *) - 0x6e261c00; (* arm_EOR_VEC Q0 Q0 Q6 128 *) - 0x6e281f18; (* arm_EOR_VEC Q24 Q24 Q8 128 *) + 0xf100805f; (* arm_CMP X2 (rvalue (word 32)) *) + 0x54004943; (* arm_BCC (word 2344) *) + 0xf100c05f; (* arm_CMP X2 (rvalue (word 48)) *) + 0x54004063; (* arm_BCC (word 2060) *) 0x93ca8156; (* arm_ROR X22 X10 32 *) 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 31) *) 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 1) *) 0x9e670129; (* arm_FMOV_ItoF Q9 X9 0 *) 0x9eaf0149; (* arm_FMOV_ItoF Q9 X10 1 *) - 0x4eb81f01; (* arm_MOV_VEC Q1 Q24 128 *) - 0x4cdf7018; (* arm_LDR Q24 X0 (Postimmediate_Offset (word 16)) *) - 0x4ea01c02; (* arm_MOV_VEC Q2 Q0 128 *) - 0x4ea11c23; (* arm_MOV_VEC Q3 Q1 128 *) - 0x6e291f1b; (* arm_EOR_VEC Q27 Q24 Q9 128 *) - 0x6e291f18; (* arm_EOR_VEC Q24 Q24 Q9 128 *) - 0xf100805f; (* arm_CMP X2 (rvalue (word 32)) *) - 0x54001b63; (* arm_BCC (word 876) *) + 0xf101005f; (* arm_CMP X2 (rvalue (word 64)) *) + 0x54003383; (* arm_BCC (word 1648) *) 0x93ca8156; (* arm_ROR X22 X10 32 *) 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 31) *) 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 1) *) 0x9e67012a; (* arm_FMOV_ItoF Q10 X9 0 *) 0x9eaf014a; (* arm_FMOV_ItoF Q10 X10 1 *) - 0x4cdf7019; (* arm_LDR Q25 X0 (Postimmediate_Offset (word 16)) *) + 0xf101405f; (* arm_CMP X2 (rvalue (word 80)) *) + 0x54002283; (* arm_BCC (word 1104) *) 0x93ca8156; (* arm_ROR X22 X10 32 *) 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 31) *) 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 1) *) 0x9e67012b; (* arm_FMOV_ItoF Q11 X9 0 *) 0x9eaf014b; (* arm_FMOV_ItoF Q11 X10 1 *) - 0x4cdf701a; (* arm_LDR Q26 X0 (Postimmediate_Offset (word 16)) *) + 0xacc28400; (* arm_LDP Q0 Q1 X0 (Postimmediate_Offset (iword (&80))) *) + 0xad7ee418; (* arm_LDP Q24 Q25 X0 (Immediate_Offset (iword (-- &48))) *) + 0x3cdf001a; (* arm_LDR Q26 X0 (Immediate_Offset (word 18446744073709551600)) *) + 0x6e261c00; (* arm_EOR_VEC Q0 Q0 Q6 128 *) + 0x6e281c21; (* arm_EOR_VEC Q1 Q1 Q8 128 *) + 0x6e291f18; (* arm_EOR_VEC Q24 Q24 Q9 128 *) 0x6e2a1f39; (* arm_EOR_VEC Q25 Q25 Q10 128 *) 0x6e2b1f5a; (* arm_EOR_VEC Q26 Q26 Q11 128 *) - 0xd1008042; (* arm_SUB X2 X2 (rvalue (word 32)) *) - 0x2a0503e6; (* arm_MOV W6 W5 *) 0x4e284a00; (* arm_AESE Q0 Q16 *) 0x4e286800; (* arm_AESMC Q0 Q0 *) 0x4e284a01; (* arm_AESE Q1 Q16 *) @@ -165,8 +93,6 @@ 0x4e286b39; (* arm_AESMC Q25 Q25 *) 0x4e284a1a; (* arm_AESE Q26 Q16 *) 0x4e286b5a; (* arm_AESMC Q26 Q26 *) - 0x4cdf78f0; (* arm_LDR Q16 X7 (Postimmediate_Offset (word 16)) *) - 0x710008c6; (* arm_SUBS W6 W6 (rvalue (word 2)) *) 0x4e284a20; (* arm_AESE Q0 Q17 *) 0x4e286800; (* arm_AESMC Q0 Q0 *) 0x4e284a21; (* arm_AESE Q1 Q17 *) @@ -177,31 +103,66 @@ 0x4e286b39; (* arm_AESMC Q25 Q25 *) 0x4e284a3a; (* arm_AESE Q26 Q17 *) 0x4e286b5a; (* arm_AESMC Q26 Q26 *) - 0x4cdf78f1; (* arm_LDR Q17 X7 (Postimmediate_Offset (word 16)) *) - 0x54fffd2c; (* arm_BGT (word 2097060) *) - 0x4e284a00; (* arm_AESE Q0 Q16 *) + 0x4e284980; (* arm_AESE Q0 Q12 *) 0x4e286800; (* arm_AESMC Q0 Q0 *) - 0x4e284a01; (* arm_AESE Q1 Q16 *) + 0x4e284981; (* arm_AESE Q1 Q12 *) 0x4e286821; (* arm_AESMC Q1 Q1 *) - 0x4e284a18; (* arm_AESE Q24 Q16 *) + 0x4e284998; (* arm_AESE Q24 Q12 *) 0x4e286b18; (* arm_AESMC Q24 Q24 *) - 0x4e284a19; (* arm_AESE Q25 Q16 *) + 0x4e284999; (* arm_AESE Q25 Q12 *) 0x4e286b39; (* arm_AESMC Q25 Q25 *) - 0x4e284a1a; (* arm_AESE Q26 Q16 *) + 0x4e28499a; (* arm_AESE Q26 Q12 *) 0x4e286b5a; (* arm_AESMC Q26 Q26 *) - 0xf1014042; (* arm_SUBS X2 X2 (rvalue (word 80)) *) - 0x4e284a20; (* arm_AESE Q0 Q17 *) + 0x4e2849a0; (* arm_AESE Q0 Q13 *) 0x4e286800; (* arm_AESMC Q0 Q0 *) - 0x4e284a21; (* arm_AESE Q1 Q17 *) + 0x4e2849a1; (* arm_AESE Q1 Q13 *) 0x4e286821; (* arm_AESMC Q1 Q1 *) - 0x4e284a38; (* arm_AESE Q24 Q17 *) + 0x4e2849b8; (* arm_AESE Q24 Q13 *) 0x4e286b18; (* arm_AESMC Q24 Q24 *) - 0x4e284a39; (* arm_AESE Q25 Q17 *) + 0x4e2849b9; (* arm_AESE Q25 Q13 *) 0x4e286b39; (* arm_AESMC Q25 Q25 *) - 0x4e284a3a; (* arm_AESE Q26 Q17 *) + 0x4e2849ba; (* arm_AESE Q26 Q13 *) + 0x4e286b5a; (* arm_AESMC Q26 Q26 *) + 0x4e2849c0; (* arm_AESE Q0 Q14 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e2849c1; (* arm_AESE Q1 Q14 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e2849d8; (* arm_AESE Q24 Q14 *) + 0x4e286b18; (* arm_AESMC Q24 Q24 *) + 0x4e2849d9; (* arm_AESE Q25 Q14 *) + 0x4e286b39; (* arm_AESMC Q25 Q25 *) + 0x4e2849da; (* arm_AESE Q26 Q14 *) + 0x4e286b5a; (* arm_AESMC Q26 Q26 *) + 0x4e2849e0; (* arm_AESE Q0 Q15 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e2849e1; (* arm_AESE Q1 Q15 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e2849f8; (* arm_AESE Q24 Q15 *) + 0x4e286b18; (* arm_AESMC Q24 Q24 *) + 0x4e2849f9; (* arm_AESE Q25 Q15 *) + 0x4e286b39; (* arm_AESMC Q25 Q25 *) + 0x4e2849fa; (* arm_AESE Q26 Q15 *) + 0x4e286b5a; (* arm_AESMC Q26 Q26 *) + 0x4e284880; (* arm_AESE Q0 Q4 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e284881; (* arm_AESE Q1 Q4 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e284898; (* arm_AESE Q24 Q4 *) + 0x4e286b18; (* arm_AESMC Q24 Q24 *) + 0x4e284899; (* arm_AESE Q25 Q4 *) + 0x4e286b39; (* arm_AESMC Q25 Q25 *) + 0x4e28489a; (* arm_AESE Q26 Q4 *) + 0x4e286b5a; (* arm_AESMC Q26 Q26 *) + 0x4e2848a0; (* arm_AESE Q0 Q5 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e2848a1; (* arm_AESE Q1 Q5 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e2848b8; (* arm_AESE Q24 Q5 *) + 0x4e286b18; (* arm_AESMC Q24 Q24 *) + 0x4e2848b9; (* arm_AESE Q25 Q5 *) + 0x4e286b39; (* arm_AESMC Q25 Q25 *) + 0x4e2848ba; (* arm_AESE Q26 Q5 *) 0x4e286b5a; (* arm_AESMC Q26 Q26 *) - 0x9a82c3e6; (* arm_CSEL X6 XZR X2 Condition_GT *) - 0xaa0303e7; (* arm_MOV X7 X3 *) 0x4e284a40; (* arm_AESE Q0 Q18 *) 0x4e286800; (* arm_AESMC Q0 Q0 *) 0x4e284a41; (* arm_AESE Q1 Q18 *) @@ -212,8 +173,6 @@ 0x4e286b39; (* arm_AESMC Q25 Q25 *) 0x4e284a5a; (* arm_AESE Q26 Q18 *) 0x4e286b5a; (* arm_AESMC Q26 Q26 *) - 0x8b060000; (* arm_ADD X0 X0 X6 *) - 0x91018046; (* arm_ADD X6 X2 (rvalue (word 96)) *) 0x4e284a60; (* arm_AESE Q0 Q19 *) 0x4e286800; (* arm_AESMC Q0 Q0 *) 0x4e284a61; (* arm_AESE Q1 Q19 *) @@ -259,260 +218,421 @@ 0x4e284af8; (* arm_AESE Q24 Q23 *) 0x4e284af9; (* arm_AESE Q25 Q23 *) 0x4e284afa; (* arm_AESE Q26 Q23 *) - 0x6e261ce4; (* arm_EOR_VEC Q4 Q7 Q6 128 *) + 0x6e271c00; (* arm_EOR_VEC Q0 Q0 Q7 128 *) + 0x6e261c00; (* arm_EOR_VEC Q0 Q0 Q6 128 *) 0x93ca8156; (* arm_ROR X22 X10 32 *) 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 31) *) 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 1) *) 0x9e670126; (* arm_FMOV_ItoF Q6 X9 0 *) 0x9eaf0146; (* arm_FMOV_ItoF Q6 X10 1 *) - 0x6e281ce5; (* arm_EOR_VEC Q5 Q7 Q8 128 *) - 0x4cdf7002; (* arm_LDR Q2 X0 (Postimmediate_Offset (word 16)) *) + 0x6e271c21; (* arm_EOR_VEC Q1 Q1 Q7 128 *) + 0x6e281c21; (* arm_EOR_VEC Q1 Q1 Q8 128 *) 0x93ca8156; (* arm_ROR X22 X10 32 *) 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 31) *) 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 1) *) 0x9e670128; (* arm_FMOV_ItoF Q8 X9 0 *) 0x9eaf0148; (* arm_FMOV_ItoF Q8 X10 1 *) - 0x6e291cf1; (* arm_EOR_VEC Q17 Q7 Q9 128 *) - 0x4cdf7003; (* arm_LDR Q3 X0 (Postimmediate_Offset (word 16)) *) + 0x6e271f18; (* arm_EOR_VEC Q24 Q24 Q7 128 *) + 0x6e291f18; (* arm_EOR_VEC Q24 Q24 Q9 128 *) 0x93ca8156; (* arm_ROR X22 X10 32 *) 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 31) *) 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 1) *) 0x9e670129; (* arm_FMOV_ItoF Q9 X9 0 *) 0x9eaf0149; (* arm_FMOV_ItoF Q9 X10 1 *) - 0x6e2a1cfe; (* arm_EOR_VEC Q30 Q7 Q10 128 *) - 0x4cdf701b; (* arm_LDR Q27 X0 (Postimmediate_Offset (word 16)) *) + 0x6e271f39; (* arm_EOR_VEC Q25 Q25 Q7 128 *) + 0x6e2a1f39; (* arm_EOR_VEC Q25 Q25 Q10 128 *) 0x93ca8156; (* arm_ROR X22 X10 32 *) 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 31) *) 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 1) *) 0x9e67012a; (* arm_FMOV_ItoF Q10 X9 0 *) 0x9eaf014a; (* arm_FMOV_ItoF Q10 X10 1 *) - 0x6e2b1cff; (* arm_EOR_VEC Q31 Q7 Q11 128 *) - 0x4cdf701c; (* arm_LDR Q28 X0 (Postimmediate_Offset (word 16)) *) + 0x6e271f5a; (* arm_EOR_VEC Q26 Q26 Q7 128 *) + 0x6e2b1f5a; (* arm_EOR_VEC Q26 Q26 Q11 128 *) 0x93ca8156; (* arm_ROR X22 X10 32 *) 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 31) *) 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 1) *) 0x9e67012b; (* arm_FMOV_ItoF Q11 X9 0 *) 0x9eaf014b; (* arm_FMOV_ItoF Q11 X10 1 *) - 0x4cdf701d; (* arm_LDR Q29 X0 (Postimmediate_Offset (word 16)) *) - 0xb4000586; (* arm_CBZ X6 (word 176) *) - 0x6e201c84; (* arm_EOR_VEC Q4 Q4 Q0 128 *) - 0x6e261c40; (* arm_EOR_VEC Q0 Q2 Q6 128 *) - 0x6e211ca5; (* arm_EOR_VEC Q5 Q5 Q1 128 *) - 0x6e281c61; (* arm_EOR_VEC Q1 Q3 Q8 128 *) - 0x6e381e31; (* arm_EOR_VEC Q17 Q17 Q24 128 *) - 0x6e291f78; (* arm_EOR_VEC Q24 Q27 Q9 128 *) - 0x6e391fde; (* arm_EOR_VEC Q30 Q30 Q25 128 *) - 0x6e2a1f99; (* arm_EOR_VEC Q25 Q28 Q10 128 *) - 0x6e3a1fff; (* arm_EOR_VEC Q31 Q31 Q26 128 *) - 0x6e2b1fba; (* arm_EOR_VEC Q26 Q29 Q11 128 *) - 0x2a0503e6; (* arm_MOV W6 W5 *) - 0x4c9fa024; (* arm_STP Q4 Q5 X1 (Postimmediate_Offset (word 32)) *) - 0x4c9f7031; (* arm_STR Q17 X1 (Postimmediate_Offset (word 16)) *) - 0x4c9fa03e; (* arm_STP Q30 Q31 X1 (Postimmediate_Offset (word 32)) *) - 0x4cdf78f0; (* arm_LDR Q16 X7 (Postimmediate_Offset (word 16)) *) - 0x4cdf78f1; (* arm_LDR Q17 X7 (Postimmediate_Offset (word 16)) *) - 0x54ffebe2; (* arm_BCS (word 2096508) *) - 0xb100405f; (* arm_CMN X2 (rvalue (word 16)) *) - 0x540001a1; (* arm_BNE (word 52) *) - 0x4eaa1d4b; (* arm_MOV_VEC Q11 Q10 128 *) - 0x4ea91d2a; (* arm_MOV_VEC Q10 Q9 128 *) - 0x4ea81d09; (* arm_MOV_VEC Q9 Q8 128 *) - 0x4ea61cc8; (* arm_MOV_VEC Q8 Q6 128 *) - 0x9e660169; (* arm_FMOV_FtoI X9 Q11 0 *) - 0x9eae016a; (* arm_FMOV_FtoI X10 Q11 1 *) - 0x6e221cc0; (* arm_EOR_VEC Q0 Q6 Q2 128 *) - 0x6e231d01; (* arm_EOR_VEC Q1 Q8 Q3 128 *) - 0x6e291f78; (* arm_EOR_VEC Q24 Q27 Q9 128 *) - 0x6e2a1f99; (* arm_EOR_VEC Q25 Q28 Q10 128 *) - 0x6e2b1fba; (* arm_EOR_VEC Q26 Q29 Q11 128 *) - 0x54ffea20; (* arm_BEQ (word 2096452) *) - 0x91014042; (* arm_ADD X2 X2 (rvalue (word 80)) *) - 0xb4001662; (* arm_CBZ X2 (word 716) *) - 0x110008a6; (* arm_ADD W6 W5 (rvalue (word 2)) *) - 0xf100c042; (* arm_SUBS X2 X2 (rvalue (word 48)) *) - 0x54000c43; (* arm_BCC (word 392) *) - 0x6e3b1cc0; (* arm_EOR_VEC Q0 Q6 Q27 128 *) - 0x6e3c1d01; (* arm_EOR_VEC Q1 Q8 Q28 128 *) - 0x6e291fb8; (* arm_EOR_VEC Q24 Q29 Q9 128 *) - 0x14000010; (* arm_B (word 64) *) - 0xd503201f; (* arm_NOP *) - 0xd503201f; (* arm_NOP *) - 0xd503201f; (* arm_NOP *) - 0x91004000; (* arm_ADD X0 X0 (rvalue (word 16)) *) - 0x6e251c25; (* arm_EOR_VEC Q5 Q1 Q5 128 *) - 0x4c9f7025; (* arm_STR Q5 X1 (Postimmediate_Offset (word 16)) *) - 0x6e311f11; (* arm_EOR_VEC Q17 Q24 Q17 128 *) - 0x4c9f7031; (* arm_STR Q17 X1 (Postimmediate_Offset (word 16)) *) - 0x6e3e1f3e; (* arm_EOR_VEC Q30 Q25 Q30 128 *) - 0x6e3f1f5f; (* arm_EOR_VEC Q31 Q26 Q31 128 *) - 0x4c9fa03e; (* arm_STP Q30 Q31 X1 (Postimmediate_Offset (word 32)) *) - 0x140000a0; (* arm_B (word 640) *) - 0xd503201f; (* arm_NOP *) - 0xd503201f; (* arm_NOP *) - 0xd503201f; (* arm_NOP *) + 0xac828420; (* arm_STP Q0 Q1 X1 (Postimmediate_Offset (iword (&80))) *) + 0xad3ee438; (* arm_STP Q24 Q25 X1 (Immediate_Offset (iword (-- &48))) *) + 0x3c9f003a; (* arm_STR Q26 X1 (Immediate_Offset (word 18446744073709551600)) *) + 0xf1014042; (* arm_SUBS X2 X2 (rvalue (word 80)) *) + 0xf101405f; (* arm_CMP X2 (rvalue (word 80)) *) + 0x54002143; (* arm_BCC (word 1064) *) + 0x54000982; (* arm_BCS (word 304) *) + 0xf100005f; (* arm_CMP X2 (rvalue (word 0)) *) + 0x54004f00; (* arm_BEQ (word 2528) *) + 0xf100405f; (* arm_CMP X2 (rvalue (word 16)) *) + 0x54004940; (* arm_BEQ (word 2344) *) + 0xf100805f; (* arm_CMP X2 (rvalue (word 32)) *) + 0x54004060; (* arm_BEQ (word 2060) *) + 0xf100c05f; (* arm_CMP X2 (rvalue (word 48)) *) + 0x54003380; (* arm_BEQ (word 1648) *) + 0xf101005f; (* arm_CMP X2 (rvalue (word 64)) *) + 0x54002280; (* arm_BEQ (word 1104) *) + 0x4cdf7000; (* arm_LDR Q0 X0 (Postimmediate_Offset (word 16)) *) + 0x4cdf7001; (* arm_LDR Q1 X0 (Postimmediate_Offset (word 16)) *) + 0x4cdf7018; (* arm_LDR Q24 X0 (Postimmediate_Offset (word 16)) *) + 0x4cdf7019; (* arm_LDR Q25 X0 (Postimmediate_Offset (word 16)) *) + 0x6e261c00; (* arm_EOR_VEC Q0 Q0 Q6 128 *) + 0x6e281c21; (* arm_EOR_VEC Q1 Q1 Q8 128 *) + 0x6e291f18; (* arm_EOR_VEC Q24 Q24 Q9 128 *) + 0x6e2a1f39; (* arm_EOR_VEC Q25 Q25 Q10 128 *) 0x4e284a00; (* arm_AESE Q0 Q16 *) 0x4e286800; (* arm_AESMC Q0 Q0 *) 0x4e284a01; (* arm_AESE Q1 Q16 *) 0x4e286821; (* arm_AESMC Q1 Q1 *) 0x4e284a18; (* arm_AESE Q24 Q16 *) 0x4e286b18; (* arm_AESMC Q24 Q24 *) - 0x4cdf78f0; (* arm_LDR Q16 X7 (Postimmediate_Offset (word 16)) *) - 0x710008c6; (* arm_SUBS W6 W6 (rvalue (word 2)) *) + 0x4e284a19; (* arm_AESE Q25 Q16 *) + 0x4e286b39; (* arm_AESMC Q25 Q25 *) 0x4e284a20; (* arm_AESE Q0 Q17 *) 0x4e286800; (* arm_AESMC Q0 Q0 *) 0x4e284a21; (* arm_AESE Q1 Q17 *) 0x4e286821; (* arm_AESMC Q1 Q1 *) 0x4e284a38; (* arm_AESE Q24 Q17 *) 0x4e286b18; (* arm_AESMC Q24 Q24 *) - 0x4cdf78f1; (* arm_LDR Q17 X7 (Postimmediate_Offset (word 16)) *) - 0x54fffe2c; (* arm_BGT (word 2097092) *) - 0x4e284a00; (* arm_AESE Q0 Q16 *) + 0x4e284a39; (* arm_AESE Q25 Q17 *) + 0x4e286b39; (* arm_AESMC Q25 Q25 *) + 0x4e284980; (* arm_AESE Q0 Q12 *) 0x4e286800; (* arm_AESMC Q0 Q0 *) - 0x4e284a01; (* arm_AESE Q1 Q16 *) + 0x4e284981; (* arm_AESE Q1 Q12 *) 0x4e286821; (* arm_AESMC Q1 Q1 *) - 0x4e284a18; (* arm_AESE Q24 Q16 *) + 0x4e284998; (* arm_AESE Q24 Q12 *) 0x4e286b18; (* arm_AESMC Q24 Q24 *) - 0x6e271cc4; (* arm_EOR_VEC Q4 Q6 Q7 128 *) - 0x4e284a20; (* arm_AESE Q0 Q17 *) + 0x4e284999; (* arm_AESE Q25 Q12 *) + 0x4e286b39; (* arm_AESMC Q25 Q25 *) + 0x4e2849a0; (* arm_AESE Q0 Q13 *) 0x4e286800; (* arm_AESMC Q0 Q0 *) - 0x4e284a21; (* arm_AESE Q1 Q17 *) + 0x4e2849a1; (* arm_AESE Q1 Q13 *) 0x4e286821; (* arm_AESMC Q1 Q1 *) - 0x4e284a38; (* arm_AESE Q24 Q17 *) + 0x4e2849b8; (* arm_AESE Q24 Q13 *) + 0x4e286b18; (* arm_AESMC Q24 Q24 *) + 0x4e2849b9; (* arm_AESE Q25 Q13 *) + 0x4e286b39; (* arm_AESMC Q25 Q25 *) + 0x4e2849c0; (* arm_AESE Q0 Q14 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e2849c1; (* arm_AESE Q1 Q14 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e2849d8; (* arm_AESE Q24 Q14 *) + 0x4e286b18; (* arm_AESMC Q24 Q24 *) + 0x4e2849d9; (* arm_AESE Q25 Q14 *) + 0x4e286b39; (* arm_AESMC Q25 Q25 *) + 0x4e2849e0; (* arm_AESE Q0 Q15 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e2849e1; (* arm_AESE Q1 Q15 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e2849f8; (* arm_AESE Q24 Q15 *) + 0x4e286b18; (* arm_AESMC Q24 Q24 *) + 0x4e2849f9; (* arm_AESE Q25 Q15 *) + 0x4e286b39; (* arm_AESMC Q25 Q25 *) + 0x4e284880; (* arm_AESE Q0 Q4 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e284881; (* arm_AESE Q1 Q4 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e284898; (* arm_AESE Q24 Q4 *) 0x4e286b18; (* arm_AESMC Q24 Q24 *) + 0x4e284899; (* arm_AESE Q25 Q4 *) + 0x4e286b39; (* arm_AESMC Q25 Q25 *) + 0x4e2848a0; (* arm_AESE Q0 Q5 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e2848a1; (* arm_AESE Q1 Q5 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e2848b8; (* arm_AESE Q24 Q5 *) + 0x4e286b18; (* arm_AESMC Q24 Q24 *) + 0x4e2848b9; (* arm_AESE Q25 Q5 *) + 0x4e286b39; (* arm_AESMC Q25 Q25 *) + 0x4e284a40; (* arm_AESE Q0 Q18 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e284a41; (* arm_AESE Q1 Q18 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e284a58; (* arm_AESE Q24 Q18 *) + 0x4e286b18; (* arm_AESMC Q24 Q24 *) + 0x4e284a59; (* arm_AESE Q25 Q18 *) + 0x4e286b39; (* arm_AESMC Q25 Q25 *) + 0x4e284a60; (* arm_AESE Q0 Q19 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e284a61; (* arm_AESE Q1 Q19 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e284a78; (* arm_AESE Q24 Q19 *) + 0x4e286b18; (* arm_AESMC Q24 Q24 *) + 0x4e284a79; (* arm_AESE Q25 Q19 *) + 0x4e286b39; (* arm_AESMC Q25 Q25 *) 0x4e284a80; (* arm_AESE Q0 Q20 *) 0x4e286800; (* arm_AESMC Q0 Q0 *) 0x4e284a81; (* arm_AESE Q1 Q20 *) 0x4e286821; (* arm_AESMC Q1 Q1 *) 0x4e284a98; (* arm_AESE Q24 Q20 *) 0x4e286b18; (* arm_AESMC Q24 Q24 *) + 0x4e284a99; (* arm_AESE Q25 Q20 *) + 0x4e286b39; (* arm_AESMC Q25 Q25 *) 0x4e284aa0; (* arm_AESE Q0 Q21 *) 0x4e286800; (* arm_AESMC Q0 Q0 *) 0x4e284aa1; (* arm_AESE Q1 Q21 *) 0x4e286821; (* arm_AESMC Q1 Q1 *) 0x4e284ab8; (* arm_AESE Q24 Q21 *) 0x4e286b18; (* arm_AESMC Q24 Q24 *) + 0x4e284ab9; (* arm_AESE Q25 Q21 *) + 0x4e286b39; (* arm_AESMC Q25 Q25 *) 0x4e284ac0; (* arm_AESE Q0 Q22 *) 0x4e286800; (* arm_AESMC Q0 Q0 *) 0x4e284ac1; (* arm_AESE Q1 Q22 *) 0x4e286821; (* arm_AESMC Q1 Q1 *) 0x4e284ad8; (* arm_AESE Q24 Q22 *) 0x4e286b18; (* arm_AESMC Q24 Q24 *) + 0x4e284ad9; (* arm_AESE Q25 Q22 *) + 0x4e286b39; (* arm_AESMC Q25 Q25 *) 0x4e284ae0; (* arm_AESE Q0 Q23 *) 0x4e284ae1; (* arm_AESE Q1 Q23 *) 0x4e284af8; (* arm_AESE Q24 Q23 *) - 0x6e271d31; (* arm_EOR_VEC Q17 Q9 Q7 128 *) - 0xf100c042; (* arm_SUBS X2 X2 (rvalue (word 48)) *) - 0x9e660129; (* arm_FMOV_FtoI X9 Q9 0 *) - 0x9eae012a; (* arm_FMOV_FtoI X10 Q9 1 *) + 0x4e284af9; (* arm_AESE Q25 Q23 *) + 0x6e271c00; (* arm_EOR_VEC Q0 Q0 Q7 128 *) + 0x6e261c00; (* arm_EOR_VEC Q0 Q0 Q6 128 *) + 0x6e271c21; (* arm_EOR_VEC Q1 Q1 Q7 128 *) + 0x6e281c21; (* arm_EOR_VEC Q1 Q1 Q8 128 *) + 0x6e271f18; (* arm_EOR_VEC Q24 Q24 Q7 128 *) + 0x6e291f18; (* arm_EOR_VEC Q24 Q24 Q9 128 *) + 0x6e271f39; (* arm_EOR_VEC Q25 Q25 Q7 128 *) + 0x6e2a1f39; (* arm_EOR_VEC Q25 Q25 Q10 128 *) + 0x4c9fa020; (* arm_STP Q0 Q1 X1 (Postimmediate_Offset (word 32)) *) + 0x4c9fa038; (* arm_STP Q24 Q25 X1 (Postimmediate_Offset (word 32)) *) + 0x9e660149; (* arm_FMOV_FtoI X9 Q10 0 64 *) + 0x9eae014a; (* arm_FMOV_FtoI X10 Q10 1 64 *) 0x93ca8156; (* arm_ROR X22 X10 32 *) 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 31) *) 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 1) *) 0x9e670126; (* arm_FMOV_ItoF Q6 X9 0 *) 0x9eaf0146; (* arm_FMOV_ItoF Q6 X10 1 *) - 0x6e271d05; (* arm_EOR_VEC Q5 Q8 Q7 128 *) - 0x9a863046; (* arm_CSEL X6 X2 X6 Condition_CC *) - 0x910080c6; (* arm_ADD X6 X6 (rvalue (word 32)) *) - 0x8b060000; (* arm_ADD X0 X0 X6 *) - 0xaa0303e7; (* arm_MOV X7 X3 *) - 0x4cdf701b; (* arm_LDR Q27 X0 (Postimmediate_Offset (word 16)) *) - 0x110008a6; (* arm_ADD W6 W5 (rvalue (word 2)) *) - 0x6e201c84; (* arm_EOR_VEC Q4 Q4 Q0 128 *) - 0x6e211ca5; (* arm_EOR_VEC Q5 Q5 Q1 128 *) - 0x6e311f18; (* arm_EOR_VEC Q24 Q24 Q17 128 *) - 0x4cdfa8f0; (* arm_LDP Q16 Q17 X7 (Postimmediate_Offset (word 32)) *) - 0x4c9fa024; (* arm_STP Q4 Q5 X1 (Postimmediate_Offset (word 32)) *) - 0x4c9f7038; (* arm_STR Q24 X1 (Postimmediate_Offset (word 16)) *) - 0xb100c05f; (* arm_CMN X2 (rvalue (word 48)) *) - 0x54000a40; (* arm_BEQ (word 328) *) - 0x4ea31c7c; (* arm_MOV_VEC Q28 Q3 128 *) - 0x4ebb1f7d; (* arm_MOV_VEC Q29 Q27 128 *) + 0x14000278; (* arm_B (word 2528) *) 0xd503201f; (* arm_NOP *) - 0xb100405f; (* arm_CMN X2 (rvalue (word 16)) *) - 0x6e261f81; (* arm_EOR_VEC Q1 Q28 Q6 128 *) - 0x6e281fb8; (* arm_EOR_VEC Q24 Q29 Q8 128 *) - 0x54000040; (* arm_BEQ (word 8) *) - 0x6e261fb8; (* arm_EOR_VEC Q24 Q29 Q6 128 *) + 0x4cdfa000; (* arm_LDP Q0 Q1 X0 (Postimmediate_Offset (word 32)) *) + 0x4cdf7018; (* arm_LDR Q24 X0 (Postimmediate_Offset (word 16)) *) + 0x6e261c00; (* arm_EOR_VEC Q0 Q0 Q6 128 *) + 0x6e281c21; (* arm_EOR_VEC Q1 Q1 Q8 128 *) + 0x6e291f18; (* arm_EOR_VEC Q24 Q24 Q9 128 *) + 0x4e284a00; (* arm_AESE Q0 Q16 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) 0x4e284a01; (* arm_AESE Q1 Q16 *) 0x4e286821; (* arm_AESMC Q1 Q1 *) 0x4e284a18; (* arm_AESE Q24 Q16 *) 0x4e286b18; (* arm_AESMC Q24 Q24 *) - 0x4cdf78f0; (* arm_LDR Q16 X7 (Postimmediate_Offset (word 16)) *) - 0x710008c6; (* arm_SUBS W6 W6 (rvalue (word 2)) *) + 0x4e284a20; (* arm_AESE Q0 Q17 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) 0x4e284a21; (* arm_AESE Q1 Q17 *) 0x4e286821; (* arm_AESMC Q1 Q1 *) 0x4e284a38; (* arm_AESE Q24 Q17 *) 0x4e286b18; (* arm_AESMC Q24 Q24 *) - 0x4cdf78f1; (* arm_LDR Q17 X7 (Postimmediate_Offset (word 16)) *) - 0x54fffeac; (* arm_BGT (word 2097108) *) - 0x4e284a01; (* arm_AESE Q1 Q16 *) + 0x4e284980; (* arm_AESE Q0 Q12 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e284981; (* arm_AESE Q1 Q12 *) 0x4e286821; (* arm_AESMC Q1 Q1 *) - 0x4e284a18; (* arm_AESE Q24 Q16 *) + 0x4e284998; (* arm_AESE Q24 Q12 *) 0x4e286b18; (* arm_AESMC Q24 Q24 *) - 0x4e284a21; (* arm_AESE Q1 Q17 *) + 0x4e2849a0; (* arm_AESE Q0 Q13 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e2849a1; (* arm_AESE Q1 Q13 *) 0x4e286821; (* arm_AESMC Q1 Q1 *) - 0x4e284a38; (* arm_AESE Q24 Q17 *) + 0x4e2849b8; (* arm_AESE Q24 Q13 *) 0x4e286b18; (* arm_AESMC Q24 Q24 *) + 0x4e2849c0; (* arm_AESE Q0 Q14 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e2849c1; (* arm_AESE Q1 Q14 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e2849d8; (* arm_AESE Q24 Q14 *) + 0x4e286b18; (* arm_AESMC Q24 Q24 *) + 0x4e2849e0; (* arm_AESE Q0 Q15 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e2849e1; (* arm_AESE Q1 Q15 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e2849f8; (* arm_AESE Q24 Q15 *) + 0x4e286b18; (* arm_AESMC Q24 Q24 *) + 0x4e284880; (* arm_AESE Q0 Q4 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e284881; (* arm_AESE Q1 Q4 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e284898; (* arm_AESE Q24 Q4 *) + 0x4e286b18; (* arm_AESMC Q24 Q24 *) + 0x4e2848a0; (* arm_AESE Q0 Q5 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e2848a1; (* arm_AESE Q1 Q5 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e2848b8; (* arm_AESE Q24 Q5 *) + 0x4e286b18; (* arm_AESMC Q24 Q24 *) + 0x4e284a40; (* arm_AESE Q0 Q18 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e284a41; (* arm_AESE Q1 Q18 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e284a58; (* arm_AESE Q24 Q18 *) + 0x4e286b18; (* arm_AESMC Q24 Q24 *) + 0x4e284a60; (* arm_AESE Q0 Q19 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e284a61; (* arm_AESE Q1 Q19 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e284a78; (* arm_AESE Q24 Q19 *) + 0x4e286b18; (* arm_AESMC Q24 Q24 *) + 0x4e284a80; (* arm_AESE Q0 Q20 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) 0x4e284a81; (* arm_AESE Q1 Q20 *) 0x4e286821; (* arm_AESMC Q1 Q1 *) 0x4e284a98; (* arm_AESE Q24 Q20 *) 0x4e286b18; (* arm_AESMC Q24 Q24 *) - 0xb100805f; (* arm_CMN X2 (rvalue (word 32)) *) + 0x4e284aa0; (* arm_AESE Q0 Q21 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) 0x4e284aa1; (* arm_AESE Q1 Q21 *) 0x4e286821; (* arm_AESMC Q1 Q1 *) 0x4e284ab8; (* arm_AESE Q24 Q21 *) 0x4e286b18; (* arm_AESMC Q24 Q24 *) - 0x6e271cc5; (* arm_EOR_VEC Q5 Q6 Q7 128 *) + 0x4e284ac0; (* arm_AESE Q0 Q22 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) 0x4e284ac1; (* arm_AESE Q1 Q22 *) 0x4e286821; (* arm_AESMC Q1 Q1 *) 0x4e284ad8; (* arm_AESE Q24 Q22 *) 0x4e286b18; (* arm_AESMC Q24 Q24 *) - 0x6e271d11; (* arm_EOR_VEC Q17 Q8 Q7 128 *) + 0x4e284ae0; (* arm_AESE Q0 Q23 *) 0x4e284ae1; (* arm_AESE Q1 Q23 *) 0x4e284af8; (* arm_AESE Q24 Q23 *) - 0x54000200; (* arm_BEQ (word 64) *) - 0x6e211ca5; (* arm_EOR_VEC Q5 Q5 Q1 128 *) - 0x4c9f7025; (* arm_STR Q5 X1 (Postimmediate_Offset (word 16)) *) - 0x6e381e31; (* arm_EOR_VEC Q17 Q17 Q24 128 *) - 0x4ea81d06; (* arm_MOV_VEC Q6 Q8 128 *) - 0x4c9f7031; (* arm_STR Q17 X1 (Postimmediate_Offset (word 16)) *) - 0x9e660109; (* arm_FMOV_FtoI X9 Q8 0 *) - 0x9eae010a; (* arm_FMOV_FtoI X10 Q8 1 *) - 0x528010f3; (* arm_MOV W19 (rvalue (word 135)) *) + 0x6e271c00; (* arm_EOR_VEC Q0 Q0 Q7 128 *) + 0x6e261c00; (* arm_EOR_VEC Q0 Q0 Q6 128 *) + 0x6e271c21; (* arm_EOR_VEC Q1 Q1 Q7 128 *) + 0x6e281c21; (* arm_EOR_VEC Q1 Q1 Q8 128 *) + 0x6e271f18; (* arm_EOR_VEC Q24 Q24 Q7 128 *) + 0x6e291f18; (* arm_EOR_VEC Q24 Q24 Q9 128 *) + 0x4c9fa020; (* arm_STP Q0 Q1 X1 (Postimmediate_Offset (word 32)) *) + 0x4c9f7038; (* arm_STR Q24 X1 (Postimmediate_Offset (word 16)) *) + 0x9e660129; (* arm_FMOV_FtoI X9 Q9 0 64 *) + 0x9eae012a; (* arm_FMOV_FtoI X10 Q9 1 64 *) 0x93ca8156; (* arm_ROR X22 X10 32 *) 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 31) *) 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 1) *) 0x9e670126; (* arm_FMOV_ItoF Q6 X9 0 *) 0x9eaf0146; (* arm_FMOV_ItoF Q6 X10 1 *) - 0x14000015; (* arm_B (word 84) *) - 0x6e381ca5; (* arm_EOR_VEC Q5 Q5 Q24 128 *) - 0x4ea61cc6; (* arm_MOV_VEC Q6 Q6 128 *) - 0x4c9f7025; (* arm_STR Q5 X1 (Postimmediate_Offset (word 16)) *) - 0x9e6600c9; (* arm_FMOV_FtoI X9 Q6 0 *) - 0x9eae00ca; (* arm_FMOV_FtoI X10 Q6 1 *) - 0x528010f3; (* arm_MOV W19 (rvalue (word 135)) *) + 0x14000278; (* arm_B (word 2528) *) + 0x4cdfa000; (* arm_LDP Q0 Q1 X0 (Postimmediate_Offset (word 32)) *) + 0x6e261c00; (* arm_EOR_VEC Q0 Q0 Q6 128 *) + 0x6e281c21; (* arm_EOR_VEC Q1 Q1 Q8 128 *) + 0x4e284a00; (* arm_AESE Q0 Q16 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e284a01; (* arm_AESE Q1 Q16 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e284a20; (* arm_AESE Q0 Q17 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e284a21; (* arm_AESE Q1 Q17 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e284980; (* arm_AESE Q0 Q12 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e284981; (* arm_AESE Q1 Q12 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e2849a0; (* arm_AESE Q0 Q13 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e2849a1; (* arm_AESE Q1 Q13 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e2849c0; (* arm_AESE Q0 Q14 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e2849c1; (* arm_AESE Q1 Q14 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e2849e0; (* arm_AESE Q0 Q15 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e2849e1; (* arm_AESE Q1 Q15 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e284880; (* arm_AESE Q0 Q4 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e284881; (* arm_AESE Q1 Q4 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e2848a0; (* arm_AESE Q0 Q5 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e2848a1; (* arm_AESE Q1 Q5 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e284a40; (* arm_AESE Q0 Q18 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e284a41; (* arm_AESE Q1 Q18 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e284a60; (* arm_AESE Q0 Q19 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e284a61; (* arm_AESE Q1 Q19 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e284a80; (* arm_AESE Q0 Q20 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e284a81; (* arm_AESE Q1 Q20 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e284aa0; (* arm_AESE Q0 Q21 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e284aa1; (* arm_AESE Q1 Q21 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e284ac0; (* arm_AESE Q0 Q22 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e284ac1; (* arm_AESE Q1 Q22 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e284ae0; (* arm_AESE Q0 Q23 *) + 0x4e284ae1; (* arm_AESE Q1 Q23 *) + 0x6e271c00; (* arm_EOR_VEC Q0 Q0 Q7 128 *) + 0x6e261c00; (* arm_EOR_VEC Q0 Q0 Q6 128 *) + 0x6e271c21; (* arm_EOR_VEC Q1 Q1 Q7 128 *) + 0x6e281c21; (* arm_EOR_VEC Q1 Q1 Q8 128 *) + 0x4c9fa020; (* arm_STP Q0 Q1 X1 (Postimmediate_Offset (word 32)) *) + 0x9e660109; (* arm_FMOV_FtoI X9 Q8 0 64 *) + 0x9eae010a; (* arm_FMOV_FtoI X10 Q8 1 64 *) 0x93ca8156; (* arm_ROR X22 X10 32 *) 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 31) *) 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 1) *) 0x9e670126; (* arm_FMOV_ItoF Q6 X9 0 *) 0x9eaf0146; (* arm_FMOV_ItoF Q6 X10 1 *) - 0x14000008; (* arm_B (word 32) *) - 0xd503201f; (* arm_NOP *) - 0xd503201f; (* arm_NOP *) + 0x14000278; (* arm_B (word 2528) *) + 0x4cdf7000; (* arm_LDR Q0 X0 (Postimmediate_Offset (word 16)) *) + 0x6e261c00; (* arm_EOR_VEC Q0 Q0 Q6 128 *) + 0x4e284a00; (* arm_AESE Q0 Q16 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e284a20; (* arm_AESE Q0 Q17 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e284980; (* arm_AESE Q0 Q12 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e2849a0; (* arm_AESE Q0 Q13 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e2849c0; (* arm_AESE Q0 Q14 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e2849e0; (* arm_AESE Q0 Q15 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e284880; (* arm_AESE Q0 Q4 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e2848a0; (* arm_AESE Q0 Q5 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e284a40; (* arm_AESE Q0 Q18 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e284a60; (* arm_AESE Q0 Q19 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e284a80; (* arm_AESE Q0 Q20 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e284aa0; (* arm_AESE Q0 Q21 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e284ac0; (* arm_AESE Q0 Q22 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e284ae0; (* arm_AESE Q0 Q23 *) + 0x6e271c00; (* arm_EOR_VEC Q0 Q0 Q7 128 *) + 0x6e261c00; (* arm_EOR_VEC Q0 Q0 Q6 128 *) + 0x4c9f7020; (* arm_STR Q0 X1 (Postimmediate_Offset (word 16)) *) + 0x9e6600c9; (* arm_FMOV_FtoI X9 Q6 0 64 *) + 0x9eae00ca; (* arm_FMOV_FtoI X10 Q6 1 64 *) + 0x93ca8156; (* arm_ROR X22 X10 32 *) + 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) + 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 31) *) + 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 1) *) + 0x9e670126; (* arm_FMOV_ItoF Q6 X9 0 *) + 0x9eaf0146; (* arm_FMOV_ItoF Q6 X10 1 *) + 0x14000278; (* arm_B (word 2528) *) 0xd503201f; (* arm_NOP *) 0xd503201f; (* arm_NOP *) 0xd503201f; (* arm_NOP *) 0xd503201f; (* arm_NOP *) 0xd503201f; (* arm_NOP *) 0xf2400ebf; (* arm_TST X21 (rvalue (word 15)) *) - 0x540003e0; (* arm_BEQ (word 124) *) + 0x54005300; (* arm_BEQ (word 2656) *) 0xaa0003f4; (* arm_MOV X20 X0 *) 0xaa0103ed; (* arm_MOV X13 X1 *) 0xd1004021; (* arm_SUB X1 X1 (rvalue (word 16)) *) @@ -535,7 +655,7 @@ 0x4e28483a; (* arm_AESE Q26 Q1 *) 0x4e286b5a; (* arm_AESMC Q26 Q26 *) 0x4cdf7861; (* arm_LDR Q1 X3 (Postimmediate_Offset (word 16)) *) - 0x54ffff2c; (* arm_BGT (word 2097124) *) + 0x5400512c; (* arm_BGT (word 2596) *) 0x4e28481a; (* arm_AESE Q26 Q0 *) 0x4e286b5a; (* arm_AESMC Q26 Q26 *) 0x4c407860; (* arm_LDR Q0 X3 No_Offset *) @@ -543,582 +663,12 @@ 0x6e201f5a; (* arm_EOR_VEC Q26 Q26 Q0 128 *) 0x6e261f5a; (* arm_EOR_VEC Q26 Q26 Q6 128 *) 0x4c00703a; (* arm_STR Q26 X1 No_Offset *) - 0xa9435bf5; (* arm_LDP X21 X22 SP (Immediate_Offset (iword (&48))) *) - 0x6d4227e8; (* arm_LDP D8 D9 SP (Immediate_Offset (iword (&32))) *) - 0x6d412fea; (* arm_LDP D10 D11 SP (Immediate_Offset (iword (&16))) *) - 0xa8c453f3; (* arm_LDP X19 X20 SP (Postimmediate_Offset (iword (&64))) *) - 0xd65f03c0; (* arm_RET X30 *) - 0xf100405f; (* arm_CMP X2 (rvalue (word 16)) *) - 0x540007a1; (* arm_BNE (word 244) *) - 0xb940f086; (* arm_LDR W6 X4 (Immediate_Offset (word 240)) *) - 0x4cdf7080; (* arm_LDR Q0 X4 (Postimmediate_Offset (word 16)) *) - 0x4c4070a6; (* arm_LDR Q6 X5 No_Offset *) - 0x510008c6; (* arm_SUB W6 W6 (rvalue (word 2)) *) - 0x4cdf7081; (* arm_LDR Q1 X4 (Postimmediate_Offset (word 16)) *) - 0x4e284806; (* arm_AESE Q6 Q0 *) - 0x4e2868c6; (* arm_AESMC Q6 Q6 *) - 0x4cdf7880; (* arm_LDR Q0 X4 (Postimmediate_Offset (word 16)) *) - 0x710008c6; (* arm_SUBS W6 W6 (rvalue (word 2)) *) - 0x4e284826; (* arm_AESE Q6 Q1 *) - 0x4e2868c6; (* arm_AESMC Q6 Q6 *) - 0x4cdf7881; (* arm_LDR Q1 X4 (Postimmediate_Offset (word 16)) *) - 0x54ffff2c; (* arm_BGT (word 2097124) *) - 0x4e284806; (* arm_AESE Q6 Q0 *) - 0x4e2868c6; (* arm_AESMC Q6 Q6 *) - 0x4c407880; (* arm_LDR Q0 X4 No_Offset *) - 0x4e284826; (* arm_AESE Q6 Q1 *) - 0x6e201cc6; (* arm_EOR_VEC Q6 Q6 Q0 128 *) - 0x4c407000; (* arm_LDR Q0 X0 No_Offset *) - 0x6e201cc0; (* arm_EOR_VEC Q0 Q6 Q0 128 *) - 0xb940f066; (* arm_LDR W6 X3 (Immediate_Offset (word 240)) *) - 0x4cdfa87c; (* arm_LDP Q28 Q29 X3 (Postimmediate_Offset (word 32)) *) - 0x4e285b80; (* arm_AESD Q0 Q28 *) - 0x4e287800; (* arm_AESIMC Q0 Q0 *) - 0x4cdfa870; (* arm_LDP Q16 Q17 X3 (Postimmediate_Offset (word 32)) *) - 0x4e285ba0; (* arm_AESD Q0 Q29 *) - 0x4e287800; (* arm_AESIMC Q0 Q0 *) - 0x710028c6; (* arm_SUBS W6 W6 (rvalue (word 10)) *) - 0x54000120; (* arm_BEQ (word 36) *) - 0x4e285a00; (* arm_AESD Q0 Q16 *) - 0x4e287800; (* arm_AESIMC Q0 Q0 *) - 0x4cdf7870; (* arm_LDR Q16 X3 (Postimmediate_Offset (word 16)) *) - 0x4e285a20; (* arm_AESD Q0 Q17 *) - 0x4e287800; (* arm_AESIMC Q0 Q0 *) - 0x4cdf7871; (* arm_LDR Q17 X3 (Postimmediate_Offset (word 16)) *) - 0x710008c6; (* arm_SUBS W6 W6 (rvalue (word 2)) *) - 0x54ffff2c; (* arm_BGT (word 2097124) *) - 0x4cdfa872; (* arm_LDP Q18 Q19 X3 (Postimmediate_Offset (word 32)) *) - 0x4e285a00; (* arm_AESD Q0 Q16 *) - 0x4e287800; (* arm_AESIMC Q0 Q0 *) - 0x4e285a20; (* arm_AESD Q0 Q17 *) - 0x4e287800; (* arm_AESIMC Q0 Q0 *) - 0x4cdfa874; (* arm_LDP Q20 Q21 X3 (Postimmediate_Offset (word 32)) *) - 0x4e285a40; (* arm_AESD Q0 Q18 *) - 0x4e287800; (* arm_AESIMC Q0 Q0 *) - 0x4e285a60; (* arm_AESD Q0 Q19 *) - 0x4e287800; (* arm_AESIMC Q0 Q0 *) - 0x4cdfa876; (* arm_LDP Q22 Q23 X3 (Postimmediate_Offset (word 32)) *) - 0x4e285a80; (* arm_AESD Q0 Q20 *) - 0x4e287800; (* arm_AESIMC Q0 Q0 *) - 0x4e285aa0; (* arm_AESD Q0 Q21 *) - 0x4e287800; (* arm_AESIMC Q0 Q0 *) - 0x4c407867; (* arm_LDR Q7 X3 No_Offset *) - 0x4e285ac0; (* arm_AESD Q0 Q22 *) - 0x4e287800; (* arm_AESIMC Q0 Q0 *) - 0x4e285ae0; (* arm_AESD Q0 Q23 *) - 0x6e271c00; (* arm_EOR_VEC Q0 Q0 Q7 128 *) - 0x6e201cc0; (* arm_EOR_VEC Q0 Q6 Q0 128 *) - 0x4c007020; (* arm_STR Q0 X1 No_Offset *) - 0x140001ff; (* arm_B (word 2044) *) - 0xa9bc53f3; (* arm_STP X19 X20 SP (Preimmediate_Offset (iword (-- &64))) *) - 0xa9035bf5; (* arm_STP X21 X22 SP (Immediate_Offset (iword (&48))) *) - 0x6d0227e8; (* arm_STP D8 D9 SP (Immediate_Offset (iword (&32))) *) - 0x6d012fea; (* arm_STP D10 D11 SP (Immediate_Offset (iword (&16))) *) - 0x92400c55; (* arm_AND X21 X2 (rvalue (word 15)) *) - 0x927cec42; (* arm_AND X2 X2 (rvalue (word 18446744073709551600)) *) - 0xf1004042; (* arm_SUBS X2 X2 (rvalue (word 16)) *) - 0xd2800208; (* arm_MOV X8 (rvalue (word 16)) *) - 0x54003e43; (* arm_BCC (word 1992) *) - 0xb940f086; (* arm_LDR W6 X4 (Immediate_Offset (word 240)) *) - 0x4cdf7080; (* arm_LDR Q0 X4 (Postimmediate_Offset (word 16)) *) - 0x4c4070a6; (* arm_LDR Q6 X5 No_Offset *) - 0x510008c6; (* arm_SUB W6 W6 (rvalue (word 2)) *) - 0x4cdf7081; (* arm_LDR Q1 X4 (Postimmediate_Offset (word 16)) *) - 0x4e284806; (* arm_AESE Q6 Q0 *) - 0x4e2868c6; (* arm_AESMC Q6 Q6 *) - 0x4cdf7880; (* arm_LDR Q0 X4 (Postimmediate_Offset (word 16)) *) - 0x710008c6; (* arm_SUBS W6 W6 (rvalue (word 2)) *) - 0x4e284826; (* arm_AESE Q6 Q1 *) - 0x4e2868c6; (* arm_AESMC Q6 Q6 *) - 0x4cdf7881; (* arm_LDR Q1 X4 (Postimmediate_Offset (word 16)) *) - 0x54ffff2c; (* arm_BGT (word 2097124) *) - 0x4e284806; (* arm_AESE Q6 Q0 *) - 0x4e2868c6; (* arm_AESMC Q6 Q6 *) - 0x4c407880; (* arm_LDR Q0 X4 No_Offset *) - 0x4e284826; (* arm_AESE Q6 Q1 *) - 0x6e201cc6; (* arm_EOR_VEC Q6 Q6 Q0 128 *) - 0x9e6600c9; (* arm_FMOV_FtoI X9 Q6 0 *) - 0x9eae00ca; (* arm_FMOV_FtoI X10 Q6 1 *) - 0x528010f3; (* arm_MOV W19 (rvalue (word 135)) *) - 0x93ca8156; (* arm_ROR X22 X10 32 *) - 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) - 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 31) *) - 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 1) *) - 0x9e670128; (* arm_FMOV_ItoF Q8 X9 0 *) - 0x9eaf0148; (* arm_FMOV_ItoF Q8 X10 1 *) - 0xb940f065; (* arm_LDR W5 X3 (Immediate_Offset (word 240)) *) - 0x93ca8156; (* arm_ROR X22 X10 32 *) - 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) - 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 31) *) - 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 1) *) - 0x9e670129; (* arm_FMOV_ItoF Q9 X9 0 *) - 0x9eaf0149; (* arm_FMOV_ItoF Q9 X10 1 *) - 0x4c40a870; (* arm_LDP Q16 Q17 X3 No_Offset *) - 0x510018a5; (* arm_SUB W5 W5 (rvalue (word 6)) *) - 0x8b051067; (* arm_ADD X7 X3 (Shiftedreg X5 LSL 4) *) - 0x510008a5; (* arm_SUB W5 W5 (rvalue (word 2)) *) - 0x4cdfa8f2; (* arm_LDP Q18 Q19 X7 (Postimmediate_Offset (word 32)) *) - 0x4cdfa8f4; (* arm_LDP Q20 Q21 X7 (Postimmediate_Offset (word 32)) *) - 0x4cdfa8f6; (* arm_LDP Q22 Q23 X7 (Postimmediate_Offset (word 32)) *) - 0x4c4078e7; (* arm_LDR Q7 X7 No_Offset *) - 0x93ca8156; (* arm_ROR X22 X10 32 *) - 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) - 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 31) *) - 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 1) *) - 0x9e67012a; (* arm_FMOV_ItoF Q10 X9 0 *) - 0x9eaf014a; (* arm_FMOV_ItoF Q10 X10 1 *) - 0x91008067; (* arm_ADD X7 X3 (rvalue (word 32)) *) - 0x2a0503e6; (* arm_MOV W6 W5 *) - 0x14000002; (* arm_B (word 8) *) - 0xd503201f; (* arm_NOP *) - 0xf2400ebf; (* arm_TST X21 (rvalue (word 15)) *) - 0x540000c0; (* arm_BEQ (word 24) *) - 0xf1004042; (* arm_SUBS X2 X2 (rvalue (word 16)) *) - 0x9a8803e8; (* arm_CSEL X8 XZR X8 Condition_EQ *) - 0x4cdf7000; (* arm_LDR Q0 X0 (Postimmediate_Offset (word 16)) *) - 0x54003043; (* arm_BCC (word 1544) *) - 0xd1004000; (* arm_SUB X0 X0 (rvalue (word 16)) *) - 0x4cc87000; (* arm_LDR Q0 X0 (Postreg_Offset X8) *) - 0xf1008042; (* arm_SUBS X2 X2 (rvalue (word 32)) *) - 0x110008a6; (* arm_ADD W6 W5 (rvalue (word 2)) *) - 0x4ea01c03; (* arm_MOV_VEC Q3 Q0 128 *) - 0x4ea01c01; (* arm_MOV_VEC Q1 Q0 128 *) - 0x4ea01c1c; (* arm_MOV_VEC Q28 Q0 128 *) - 0x4cdf7018; (* arm_LDR Q24 X0 (Postimmediate_Offset (word 16)) *) - 0x4eb81f1b; (* arm_MOV_VEC Q27 Q24 128 *) - 0x4eb81f1d; (* arm_MOV_VEC Q29 Q24 128 *) - 0x540027e3; (* arm_BCC (word 1276) *) - 0x6e261c00; (* arm_EOR_VEC Q0 Q0 Q6 128 *) - 0x6e281f18; (* arm_EOR_VEC Q24 Q24 Q8 128 *) - 0x4eb81f01; (* arm_MOV_VEC Q1 Q24 128 *) - 0x4cdf7018; (* arm_LDR Q24 X0 (Postimmediate_Offset (word 16)) *) - 0x4ea01c02; (* arm_MOV_VEC Q2 Q0 128 *) - 0x4ea11c23; (* arm_MOV_VEC Q3 Q1 128 *) - 0x6e291f1b; (* arm_EOR_VEC Q27 Q24 Q9 128 *) - 0x6e291f18; (* arm_EOR_VEC Q24 Q24 Q9 128 *) - 0xf100805f; (* arm_CMP X2 (rvalue (word 32)) *) - 0x54001ac3; (* arm_BCC (word 856) *) - 0x4cdf7019; (* arm_LDR Q25 X0 (Postimmediate_Offset (word 16)) *) - 0x93ca8156; (* arm_ROR X22 X10 32 *) - 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) - 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 31) *) - 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 1) *) - 0x9e67012b; (* arm_FMOV_ItoF Q11 X9 0 *) - 0x9eaf014b; (* arm_FMOV_ItoF Q11 X10 1 *) - 0x4cdf701a; (* arm_LDR Q26 X0 (Postimmediate_Offset (word 16)) *) - 0x6e2a1f39; (* arm_EOR_VEC Q25 Q25 Q10 128 *) - 0x6e2b1f5a; (* arm_EOR_VEC Q26 Q26 Q11 128 *) - 0xd1008042; (* arm_SUB X2 X2 (rvalue (word 32)) *) - 0x2a0503e6; (* arm_MOV W6 W5 *) - 0x14000001; (* arm_B (word 4) *) - 0x4e285a00; (* arm_AESD Q0 Q16 *) - 0x4e287800; (* arm_AESIMC Q0 Q0 *) - 0x4e285a01; (* arm_AESD Q1 Q16 *) - 0x4e287821; (* arm_AESIMC Q1 Q1 *) - 0x4e285a18; (* arm_AESD Q24 Q16 *) - 0x4e287b18; (* arm_AESIMC Q24 Q24 *) - 0x4e285a19; (* arm_AESD Q25 Q16 *) - 0x4e287b39; (* arm_AESIMC Q25 Q25 *) - 0x4e285a1a; (* arm_AESD Q26 Q16 *) - 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) - 0x4cdf78f0; (* arm_LDR Q16 X7 (Postimmediate_Offset (word 16)) *) - 0x710008c6; (* arm_SUBS W6 W6 (rvalue (word 2)) *) - 0x4e285a20; (* arm_AESD Q0 Q17 *) - 0x4e287800; (* arm_AESIMC Q0 Q0 *) - 0x4e285a21; (* arm_AESD Q1 Q17 *) - 0x4e287821; (* arm_AESIMC Q1 Q1 *) - 0x4e285a38; (* arm_AESD Q24 Q17 *) - 0x4e287b18; (* arm_AESIMC Q24 Q24 *) - 0x4e285a39; (* arm_AESD Q25 Q17 *) - 0x4e287b39; (* arm_AESIMC Q25 Q25 *) - 0x4e285a3a; (* arm_AESD Q26 Q17 *) - 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) - 0x4cdf78f1; (* arm_LDR Q17 X7 (Postimmediate_Offset (word 16)) *) - 0x54fffd2c; (* arm_BGT (word 2097060) *) - 0x4e285a00; (* arm_AESD Q0 Q16 *) - 0x4e287800; (* arm_AESIMC Q0 Q0 *) - 0x4e285a01; (* arm_AESD Q1 Q16 *) - 0x4e287821; (* arm_AESIMC Q1 Q1 *) - 0x4e285a18; (* arm_AESD Q24 Q16 *) - 0x4e287b18; (* arm_AESIMC Q24 Q24 *) - 0x4e285a19; (* arm_AESD Q25 Q16 *) - 0x4e287b39; (* arm_AESIMC Q25 Q25 *) - 0x4e285a1a; (* arm_AESD Q26 Q16 *) - 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) - 0xf1014042; (* arm_SUBS X2 X2 (rvalue (word 80)) *) - 0x4e285a20; (* arm_AESD Q0 Q17 *) - 0x4e287800; (* arm_AESIMC Q0 Q0 *) - 0x4e285a21; (* arm_AESD Q1 Q17 *) - 0x4e287821; (* arm_AESIMC Q1 Q1 *) - 0x4e285a38; (* arm_AESD Q24 Q17 *) - 0x4e287b18; (* arm_AESIMC Q24 Q24 *) - 0x4e285a39; (* arm_AESD Q25 Q17 *) - 0x4e287b39; (* arm_AESIMC Q25 Q25 *) - 0x4e285a3a; (* arm_AESD Q26 Q17 *) - 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) - 0x9a82c3e6; (* arm_CSEL X6 XZR X2 Condition_GT *) - 0xaa0303e7; (* arm_MOV X7 X3 *) - 0x4e285a40; (* arm_AESD Q0 Q18 *) - 0x4e287800; (* arm_AESIMC Q0 Q0 *) - 0x4e285a41; (* arm_AESD Q1 Q18 *) - 0x4e287821; (* arm_AESIMC Q1 Q1 *) - 0x4e285a58; (* arm_AESD Q24 Q18 *) - 0x4e287b18; (* arm_AESIMC Q24 Q24 *) - 0x4e285a59; (* arm_AESD Q25 Q18 *) - 0x4e287b39; (* arm_AESIMC Q25 Q25 *) - 0x4e285a5a; (* arm_AESD Q26 Q18 *) - 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) - 0x8b060000; (* arm_ADD X0 X0 X6 *) - 0x91018046; (* arm_ADD X6 X2 (rvalue (word 96)) *) - 0x4e285a60; (* arm_AESD Q0 Q19 *) - 0x4e287800; (* arm_AESIMC Q0 Q0 *) - 0x4e285a61; (* arm_AESD Q1 Q19 *) - 0x4e287821; (* arm_AESIMC Q1 Q1 *) - 0x4e285a78; (* arm_AESD Q24 Q19 *) - 0x4e287b18; (* arm_AESIMC Q24 Q24 *) - 0x4e285a79; (* arm_AESD Q25 Q19 *) - 0x4e287b39; (* arm_AESIMC Q25 Q25 *) - 0x4e285a7a; (* arm_AESD Q26 Q19 *) - 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) - 0x4e285a80; (* arm_AESD Q0 Q20 *) - 0x4e287800; (* arm_AESIMC Q0 Q0 *) - 0x4e285a81; (* arm_AESD Q1 Q20 *) - 0x4e287821; (* arm_AESIMC Q1 Q1 *) - 0x4e285a98; (* arm_AESD Q24 Q20 *) - 0x4e287b18; (* arm_AESIMC Q24 Q24 *) - 0x4e285a99; (* arm_AESD Q25 Q20 *) - 0x4e287b39; (* arm_AESIMC Q25 Q25 *) - 0x4e285a9a; (* arm_AESD Q26 Q20 *) - 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) - 0x4e285aa0; (* arm_AESD Q0 Q21 *) - 0x4e287800; (* arm_AESIMC Q0 Q0 *) - 0x4e285aa1; (* arm_AESD Q1 Q21 *) - 0x4e287821; (* arm_AESIMC Q1 Q1 *) - 0x4e285ab8; (* arm_AESD Q24 Q21 *) - 0x4e287b18; (* arm_AESIMC Q24 Q24 *) - 0x4e285ab9; (* arm_AESD Q25 Q21 *) - 0x4e287b39; (* arm_AESIMC Q25 Q25 *) - 0x4e285aba; (* arm_AESD Q26 Q21 *) - 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) - 0x4e285ac0; (* arm_AESD Q0 Q22 *) - 0x4e287800; (* arm_AESIMC Q0 Q0 *) - 0x4e285ac1; (* arm_AESD Q1 Q22 *) - 0x4e287821; (* arm_AESIMC Q1 Q1 *) - 0x4e285ad8; (* arm_AESD Q24 Q22 *) - 0x4e287b18; (* arm_AESIMC Q24 Q24 *) - 0x4e285ad9; (* arm_AESD Q25 Q22 *) - 0x4e287b39; (* arm_AESIMC Q25 Q25 *) - 0x4e285ada; (* arm_AESD Q26 Q22 *) - 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) - 0x6e261ce4; (* arm_EOR_VEC Q4 Q7 Q6 128 *) - 0x4e285ae0; (* arm_AESD Q0 Q23 *) - 0x93ca8156; (* arm_ROR X22 X10 32 *) - 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) - 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 31) *) - 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 1) *) - 0x9e670126; (* arm_FMOV_ItoF Q6 X9 0 *) - 0x9eaf0146; (* arm_FMOV_ItoF Q6 X10 1 *) - 0x6e281ce5; (* arm_EOR_VEC Q5 Q7 Q8 128 *) - 0x4cdf7002; (* arm_LDR Q2 X0 (Postimmediate_Offset (word 16)) *) - 0x4e285ae1; (* arm_AESD Q1 Q23 *) - 0x93ca8156; (* arm_ROR X22 X10 32 *) - 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) - 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 31) *) - 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 1) *) - 0x9e670128; (* arm_FMOV_ItoF Q8 X9 0 *) - 0x9eaf0148; (* arm_FMOV_ItoF Q8 X10 1 *) - 0x6e291cf1; (* arm_EOR_VEC Q17 Q7 Q9 128 *) - 0x4cdf7003; (* arm_LDR Q3 X0 (Postimmediate_Offset (word 16)) *) - 0x4e285af8; (* arm_AESD Q24 Q23 *) - 0x93ca8156; (* arm_ROR X22 X10 32 *) - 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) - 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 31) *) - 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 1) *) - 0x9e670129; (* arm_FMOV_ItoF Q9 X9 0 *) - 0x9eaf0149; (* arm_FMOV_ItoF Q9 X10 1 *) - 0x6e2a1cfe; (* arm_EOR_VEC Q30 Q7 Q10 128 *) - 0x4cdf701b; (* arm_LDR Q27 X0 (Postimmediate_Offset (word 16)) *) - 0x4e285af9; (* arm_AESD Q25 Q23 *) - 0x93ca8156; (* arm_ROR X22 X10 32 *) - 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) - 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 31) *) - 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 1) *) - 0x9e67012a; (* arm_FMOV_ItoF Q10 X9 0 *) - 0x9eaf014a; (* arm_FMOV_ItoF Q10 X10 1 *) - 0x6e2b1cff; (* arm_EOR_VEC Q31 Q7 Q11 128 *) - 0x4cdf701c; (* arm_LDR Q28 X0 (Postimmediate_Offset (word 16)) *) - 0x4e285afa; (* arm_AESD Q26 Q23 *) - 0x93ca8156; (* arm_ROR X22 X10 32 *) - 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) - 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 31) *) - 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 1) *) - 0x9e67012b; (* arm_FMOV_ItoF Q11 X9 0 *) - 0x9eaf014b; (* arm_FMOV_ItoF Q11 X10 1 *) - 0x4cdf701d; (* arm_LDR Q29 X0 (Postimmediate_Offset (word 16)) *) - 0xb4000586; (* arm_CBZ X6 (word 176) *) - 0x4cdf78f0; (* arm_LDR Q16 X7 (Postimmediate_Offset (word 16)) *) - 0x6e201c84; (* arm_EOR_VEC Q4 Q4 Q0 128 *) - 0x6e261c40; (* arm_EOR_VEC Q0 Q2 Q6 128 *) - 0x6e211ca5; (* arm_EOR_VEC Q5 Q5 Q1 128 *) - 0x6e281c61; (* arm_EOR_VEC Q1 Q3 Q8 128 *) - 0x6e381e31; (* arm_EOR_VEC Q17 Q17 Q24 128 *) - 0x6e291f78; (* arm_EOR_VEC Q24 Q27 Q9 128 *) - 0x6e391fde; (* arm_EOR_VEC Q30 Q30 Q25 128 *) - 0x6e2a1f99; (* arm_EOR_VEC Q25 Q28 Q10 128 *) - 0x6e3a1fff; (* arm_EOR_VEC Q31 Q31 Q26 128 *) - 0x4c9f7024; (* arm_STR Q4 X1 (Postimmediate_Offset (word 16)) *) - 0x6e2b1fba; (* arm_EOR_VEC Q26 Q29 Q11 128 *) - 0x4c9f7025; (* arm_STR Q5 X1 (Postimmediate_Offset (word 16)) *) - 0x2a0503e6; (* arm_MOV W6 W5 *) - 0x4c9f7031; (* arm_STR Q17 X1 (Postimmediate_Offset (word 16)) *) - 0x4cdf78f1; (* arm_LDR Q17 X7 (Postimmediate_Offset (word 16)) *) - 0x4c9f703e; (* arm_STR Q30 X1 (Postimmediate_Offset (word 16)) *) - 0x4c9f703f; (* arm_STR Q31 X1 (Postimmediate_Offset (word 16)) *) - 0x54ffeba2; (* arm_BCS (word 2096500) *) - 0xb100405f; (* arm_CMN X2 (rvalue (word 16)) *) - 0x540001a1; (* arm_BNE (word 52) *) - 0x4eaa1d4b; (* arm_MOV_VEC Q11 Q10 128 *) - 0x4ea91d2a; (* arm_MOV_VEC Q10 Q9 128 *) - 0x4ea81d09; (* arm_MOV_VEC Q9 Q8 128 *) - 0x4ea61cc8; (* arm_MOV_VEC Q8 Q6 128 *) - 0x9e660169; (* arm_FMOV_FtoI X9 Q11 0 *) - 0x9eae016a; (* arm_FMOV_FtoI X10 Q11 1 *) - 0x6e221cc0; (* arm_EOR_VEC Q0 Q6 Q2 128 *) - 0x6e231d01; (* arm_EOR_VEC Q1 Q8 Q3 128 *) - 0x6e291f78; (* arm_EOR_VEC Q24 Q27 Q9 128 *) - 0x6e2a1f99; (* arm_EOR_VEC Q25 Q28 Q10 128 *) - 0x6e2b1fba; (* arm_EOR_VEC Q26 Q29 Q11 128 *) - 0x54ffe9e0; (* arm_BEQ (word 2096444) *) - 0x91014042; (* arm_ADD X2 X2 (rvalue (word 80)) *) - 0xb4001582; (* arm_CBZ X2 (word 688) *) - 0x110008a6; (* arm_ADD W6 W5 (rvalue (word 2)) *) - 0xf100c042; (* arm_SUBS X2 X2 (rvalue (word 48)) *) - 0x54000e23; (* arm_BCC (word 452) *) - 0x6e3b1cc0; (* arm_EOR_VEC Q0 Q6 Q27 128 *) - 0x6e3c1d01; (* arm_EOR_VEC Q1 Q8 Q28 128 *) - 0x6e291fb8; (* arm_EOR_VEC Q24 Q29 Q9 128 *) - 0x1400000e; (* arm_B (word 56) *) - 0xd503201f; (* arm_NOP *) - 0x91004000; (* arm_ADD X0 X0 (rvalue (word 16)) *) - 0xf2400ebf; (* arm_TST X21 (rvalue (word 15)) *) - 0x6e241c25; (* arm_EOR_VEC Q5 Q1 Q4 128 *) - 0x4c9f7025; (* arm_STR Q5 X1 (Postimmediate_Offset (word 16)) *) - 0x6e311f11; (* arm_EOR_VEC Q17 Q24 Q17 128 *) - 0x4c9f7031; (* arm_STR Q17 X1 (Postimmediate_Offset (word 16)) *) - 0x6e3e1f3e; (* arm_EOR_VEC Q30 Q25 Q30 128 *) - 0x6e3f1f5f; (* arm_EOR_VEC Q31 Q26 Q31 128 *) - 0x4c9fa03e; (* arm_STP Q30 Q31 X1 (Postimmediate_Offset (word 32)) *) - 0x54001a00; (* arm_BEQ (word 832) *) - 0x4cdf7800; (* arm_LDR Q0 X0 (Postimmediate_Offset (word 16)) *) - 0x14000098; (* arm_B (word 608) *) - 0x4e285a00; (* arm_AESD Q0 Q16 *) - 0x4e287800; (* arm_AESIMC Q0 Q0 *) - 0x4e285a01; (* arm_AESD Q1 Q16 *) - 0x4e287821; (* arm_AESIMC Q1 Q1 *) - 0x4e285a18; (* arm_AESD Q24 Q16 *) - 0x4e287b18; (* arm_AESIMC Q24 Q24 *) - 0x4cdf78f0; (* arm_LDR Q16 X7 (Postimmediate_Offset (word 16)) *) - 0x710008c6; (* arm_SUBS W6 W6 (rvalue (word 2)) *) - 0x4e285a20; (* arm_AESD Q0 Q17 *) - 0x4e287800; (* arm_AESIMC Q0 Q0 *) - 0x4e285a21; (* arm_AESD Q1 Q17 *) - 0x4e287821; (* arm_AESIMC Q1 Q1 *) - 0x4e285a38; (* arm_AESD Q24 Q17 *) - 0x4e287b18; (* arm_AESIMC Q24 Q24 *) - 0x4cdf78f1; (* arm_LDR Q17 X7 (Postimmediate_Offset (word 16)) *) - 0x54fffe2c; (* arm_BGT (word 2097092) *) - 0x4e285a00; (* arm_AESD Q0 Q16 *) - 0x4e287800; (* arm_AESIMC Q0 Q0 *) - 0x4e285a01; (* arm_AESD Q1 Q16 *) - 0x4e287821; (* arm_AESIMC Q1 Q1 *) - 0x4e285a18; (* arm_AESD Q24 Q16 *) - 0x4e287b18; (* arm_AESIMC Q24 Q24 *) - 0x6e271cc4; (* arm_EOR_VEC Q4 Q6 Q7 128 *) - 0xf100c042; (* arm_SUBS X2 X2 (rvalue (word 48)) *) - 0x9e660129; (* arm_FMOV_FtoI X9 Q9 0 *) - 0x9eae012a; (* arm_FMOV_FtoI X10 Q9 1 *) - 0x528010f3; (* arm_MOV W19 (rvalue (word 135)) *) - 0x93ca8156; (* arm_ROR X22 X10 32 *) - 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) - 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 31) *) - 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 1) *) - 0x9e670126; (* arm_FMOV_ItoF Q6 X9 0 *) - 0x9eaf0146; (* arm_FMOV_ItoF Q6 X10 1 *) - 0x6e271d05; (* arm_EOR_VEC Q5 Q8 Q7 128 *) - 0x9a863046; (* arm_CSEL X6 X2 X6 Condition_CC *) - 0x4e285a20; (* arm_AESD Q0 Q17 *) - 0x4e287800; (* arm_AESIMC Q0 Q0 *) - 0x4e285a21; (* arm_AESD Q1 Q17 *) - 0x4e287821; (* arm_AESIMC Q1 Q1 *) - 0x4e285a38; (* arm_AESD Q24 Q17 *) - 0x4e287b18; (* arm_AESIMC Q24 Q24 *) - 0x6e271d31; (* arm_EOR_VEC Q17 Q9 Q7 128 *) - 0x93ca8156; (* arm_ROR X22 X10 32 *) - 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) - 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 31) *) - 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 1) *) - 0x9e670128; (* arm_FMOV_ItoF Q8 X9 0 *) - 0x9eaf0148; (* arm_FMOV_ItoF Q8 X10 1 *) - 0x910080c6; (* arm_ADD X6 X6 (rvalue (word 32)) *) - 0x8b060000; (* arm_ADD X0 X0 X6 *) - 0xaa0303e7; (* arm_MOV X7 X3 *) - 0x93ca8156; (* arm_ROR X22 X10 32 *) - 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) - 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 31) *) - 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 1) *) - 0x9e670129; (* arm_FMOV_ItoF Q9 X9 0 *) - 0x9eaf0149; (* arm_FMOV_ItoF Q9 X10 1 *) - 0x4e285a80; (* arm_AESD Q0 Q20 *) - 0x4e287800; (* arm_AESIMC Q0 Q0 *) - 0x4e285a81; (* arm_AESD Q1 Q20 *) - 0x4e287821; (* arm_AESIMC Q1 Q1 *) - 0x4e285a98; (* arm_AESD Q24 Q20 *) - 0x4e287b18; (* arm_AESIMC Q24 Q24 *) - 0x4e285aa0; (* arm_AESD Q0 Q21 *) - 0x4e287800; (* arm_AESIMC Q0 Q0 *) - 0x4e285aa1; (* arm_AESD Q1 Q21 *) - 0x4e287821; (* arm_AESIMC Q1 Q1 *) - 0x4e285ab8; (* arm_AESD Q24 Q21 *) - 0x4e287b18; (* arm_AESIMC Q24 Q24 *) - 0x4e285ac0; (* arm_AESD Q0 Q22 *) - 0x4e287800; (* arm_AESIMC Q0 Q0 *) - 0x4e285ac1; (* arm_AESD Q1 Q22 *) - 0x4e287821; (* arm_AESIMC Q1 Q1 *) - 0x4e285ad8; (* arm_AESD Q24 Q22 *) - 0x4e287b18; (* arm_AESIMC Q24 Q24 *) - 0x4cdf701b; (* arm_LDR Q27 X0 (Postimmediate_Offset (word 16)) *) - 0x4e285ae0; (* arm_AESD Q0 Q23 *) - 0x4e285ae1; (* arm_AESD Q1 Q23 *) - 0x4e285af8; (* arm_AESD Q24 Q23 *) - 0x4cdf78f0; (* arm_LDR Q16 X7 (Postimmediate_Offset (word 16)) *) - 0x110008a6; (* arm_ADD W6 W5 (rvalue (word 2)) *) - 0x6e201c84; (* arm_EOR_VEC Q4 Q4 Q0 128 *) - 0x6e211ca5; (* arm_EOR_VEC Q5 Q5 Q1 128 *) - 0x6e311f18; (* arm_EOR_VEC Q24 Q24 Q17 128 *) - 0x4cdf78f1; (* arm_LDR Q17 X7 (Postimmediate_Offset (word 16)) *) - 0x4c9f7024; (* arm_STR Q4 X1 (Postimmediate_Offset (word 16)) *) - 0x4c9f7025; (* arm_STR Q5 X1 (Postimmediate_Offset (word 16)) *) - 0x4c9f7038; (* arm_STR Q24 X1 (Postimmediate_Offset (word 16)) *) - 0xb100c05f; (* arm_CMN X2 (rvalue (word 48)) *) - 0x9100c042; (* arm_ADD X2 X2 (rvalue (word 48)) *) - 0x540007a0; (* arm_BEQ (word 244) *) - 0xd100c042; (* arm_SUB X2 X2 (rvalue (word 48)) *) - 0x4ea31c7c; (* arm_MOV_VEC Q28 Q3 128 *) - 0x4ebb1f7d; (* arm_MOV_VEC Q29 Q27 128 *) - 0xd503201f; (* arm_NOP *) - 0xb100405f; (* arm_CMN X2 (rvalue (word 16)) *) - 0x6e261f81; (* arm_EOR_VEC Q1 Q28 Q6 128 *) - 0x6e281fb8; (* arm_EOR_VEC Q24 Q29 Q8 128 *) - 0x54000040; (* arm_BEQ (word 8) *) - 0x6e261fb8; (* arm_EOR_VEC Q24 Q29 Q6 128 *) - 0x4e285a01; (* arm_AESD Q1 Q16 *) - 0x4e287821; (* arm_AESIMC Q1 Q1 *) - 0x4e285a18; (* arm_AESD Q24 Q16 *) - 0x4e287b18; (* arm_AESIMC Q24 Q24 *) - 0x4cdf78f0; (* arm_LDR Q16 X7 (Postimmediate_Offset (word 16)) *) - 0x710008c6; (* arm_SUBS W6 W6 (rvalue (word 2)) *) - 0x4e285a21; (* arm_AESD Q1 Q17 *) - 0x4e287821; (* arm_AESIMC Q1 Q1 *) - 0x4e285a38; (* arm_AESD Q24 Q17 *) - 0x4e287b18; (* arm_AESIMC Q24 Q24 *) - 0x4cdf78f1; (* arm_LDR Q17 X7 (Postimmediate_Offset (word 16)) *) - 0x54fffeac; (* arm_BGT (word 2097108) *) - 0x4e285a01; (* arm_AESD Q1 Q16 *) - 0x4e287821; (* arm_AESIMC Q1 Q1 *) - 0x4e285a18; (* arm_AESD Q24 Q16 *) - 0x4e287b18; (* arm_AESIMC Q24 Q24 *) - 0x4e285a21; (* arm_AESD Q1 Q17 *) - 0x4e287821; (* arm_AESIMC Q1 Q1 *) - 0x4e285a38; (* arm_AESD Q24 Q17 *) - 0x4e287b18; (* arm_AESIMC Q24 Q24 *) - 0x4e285a81; (* arm_AESD Q1 Q20 *) - 0x4e287821; (* arm_AESIMC Q1 Q1 *) - 0x4e285a98; (* arm_AESD Q24 Q20 *) - 0x4e287b18; (* arm_AESIMC Q24 Q24 *) - 0xb100805f; (* arm_CMN X2 (rvalue (word 32)) *) - 0x4e285aa1; (* arm_AESD Q1 Q21 *) - 0x4e287821; (* arm_AESIMC Q1 Q1 *) - 0x4e285ab8; (* arm_AESD Q24 Q21 *) - 0x4e287b18; (* arm_AESIMC Q24 Q24 *) - 0x6e271cc5; (* arm_EOR_VEC Q5 Q6 Q7 128 *) - 0x4e285ac1; (* arm_AESD Q1 Q22 *) - 0x4e287821; (* arm_AESIMC Q1 Q1 *) - 0x4e285ad8; (* arm_AESD Q24 Q22 *) - 0x4e287b18; (* arm_AESIMC Q24 Q24 *) - 0x6e271d11; (* arm_EOR_VEC Q17 Q8 Q7 128 *) - 0x4e285ae1; (* arm_AESD Q1 Q23 *) - 0x4e285af8; (* arm_AESD Q24 Q23 *) - 0x54000120; (* arm_BEQ (word 36) *) - 0x6e211ca5; (* arm_EOR_VEC Q5 Q5 Q1 128 *) - 0x6e381e31; (* arm_EOR_VEC Q17 Q17 Q24 128 *) - 0x4ea91d26; (* arm_MOV_VEC Q6 Q9 128 *) - 0x4eaa1d48; (* arm_MOV_VEC Q8 Q10 128 *) - 0x4c9f7025; (* arm_STR Q5 X1 (Postimmediate_Offset (word 16)) *) - 0x4c9f7031; (* arm_STR Q17 X1 (Postimmediate_Offset (word 16)) *) - 0x91004042; (* arm_ADD X2 X2 (rvalue (word 16)) *) - 0x14000006; (* arm_B (word 24) *) - 0x6e381ca5; (* arm_EOR_VEC Q5 Q5 Q24 128 *) - 0x4ea81d06; (* arm_MOV_VEC Q6 Q8 128 *) - 0x4ea91d28; (* arm_MOV_VEC Q8 Q9 128 *) - 0x4c9f7025; (* arm_STR Q5 X1 (Postimmediate_Offset (word 16)) *) - 0x91008042; (* arm_ADD X2 X2 (rvalue (word 32)) *) - 0xf2400ebf; (* arm_TST X21 (rvalue (word 15)) *) - 0x540006a0; (* arm_BEQ (word 212) *) - 0xaa0303e7; (* arm_MOV X7 X3 *) - 0xb5000042; (* arm_CBNZ X2 (word 8) *) - 0x4cdf7800; (* arm_LDR Q0 X0 (Postimmediate_Offset (word 16)) *) - 0x6e281c1a; (* arm_EOR_VEC Q26 Q0 Q8 128 *) - 0xb940f066; (* arm_LDR W6 X3 (Immediate_Offset (word 240)) *) - 0x4cdf7860; (* arm_LDR Q0 X3 (Postimmediate_Offset (word 16)) *) - 0x510008c6; (* arm_SUB W6 W6 (rvalue (word 2)) *) - 0x4cdf7861; (* arm_LDR Q1 X3 (Postimmediate_Offset (word 16)) *) - 0x4e28581a; (* arm_AESD Q26 Q0 *) - 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) - 0x4cdf7860; (* arm_LDR Q0 X3 (Postimmediate_Offset (word 16)) *) - 0x710008c6; (* arm_SUBS W6 W6 (rvalue (word 2)) *) - 0x4e28583a; (* arm_AESD Q26 Q1 *) - 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) - 0x4cdf7861; (* arm_LDR Q1 X3 (Postimmediate_Offset (word 16)) *) - 0x54ffff2c; (* arm_BGT (word 2097124) *) - 0x4e28581a; (* arm_AESD Q26 Q0 *) - 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) - 0x4c407860; (* arm_LDR Q0 X3 No_Offset *) - 0x4e28583a; (* arm_AESD Q26 Q1 *) - 0x6e201f5a; (* arm_EOR_VEC Q26 Q26 Q0 128 *) - 0x6e281f5a; (* arm_EOR_VEC Q26 Q26 Q8 128 *) - 0x4c00703a; (* arm_STR Q26 X1 No_Offset *) - 0xaa0003f4; (* arm_MOV X20 X0 *) - 0x9100402d; (* arm_ADD X13 X1 (rvalue (word 16)) *) - 0xf10006b5; (* arm_SUBS X21 X21 (rvalue (word 1)) *) - 0x3875682f; (* arm_LDRB W15 X1 (Register_Offset X21) *) - 0x38756a8e; (* arm_LDRB W14 X20 (Register_Offset X21) *) - 0x383569af; (* arm_STRB W15 X13 (Register_Offset X21) *) - 0x3835682e; (* arm_STRB W14 X1 (Register_Offset X21) *) - 0x54ffff6c; (* arm_BGT (word 2097132) *) - 0x4c40703a; (* arm_LDR Q26 X1 No_Offset *) - 0x6e261f5a; (* arm_EOR_VEC Q26 Q26 Q6 128 *) - 0xb940f0e6; (* arm_LDR W6 X7 (Immediate_Offset (word 240)) *) - 0x4cdf70e0; (* arm_LDR Q0 X7 (Postimmediate_Offset (word 16)) *) - 0x510008c6; (* arm_SUB W6 W6 (rvalue (word 2)) *) - 0x4cdf70e1; (* arm_LDR Q1 X7 (Postimmediate_Offset (word 16)) *) - 0x4e28581a; (* arm_AESD Q26 Q0 *) - 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) - 0x4cdf78e0; (* arm_LDR Q0 X7 (Postimmediate_Offset (word 16)) *) - 0x710008c6; (* arm_SUBS W6 W6 (rvalue (word 2)) *) - 0x4e28583a; (* arm_AESD Q26 Q1 *) - 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) - 0x4cdf78e1; (* arm_LDR Q1 X7 (Postimmediate_Offset (word 16)) *) - 0x54ffff2c; (* arm_BGT (word 2097124) *) - 0x4e28581a; (* arm_AESD Q26 Q0 *) - 0x4e287b5a; (* arm_AESIMC Q26 Q26 *) - 0x4c4078e0; (* arm_LDR Q0 X7 No_Offset *) - 0x4e28583a; (* arm_AESD Q26 Q1 *) - 0x6e201f5a; (* arm_EOR_VEC Q26 Q26 Q0 128 *) - 0x6e261f5a; (* arm_EOR_VEC Q26 Q26 Q6 128 *) - 0x4c00703a; (* arm_STR Q26 X1 No_Offset *) - 0xa9435bf5; (* arm_LDP X21 X22 SP (Immediate_Offset (iword (&48))) *) - 0x6d4227e8; (* arm_LDP D8 D9 SP (Immediate_Offset (iword (&32))) *) + 0xa94453f3; (* arm_LDP X19 X20 SP (Immediate_Offset (iword (&64))) *) + 0xa9455bf5; (* arm_LDP X21 X22 SP (Immediate_Offset (iword (&80))) *) + 0x6d4027e8; (* arm_LDP D8 D9 SP (Immediate_Offset (iword (&0))) *) 0x6d412fea; (* arm_LDP D10 D11 SP (Immediate_Offset (iword (&16))) *) - 0xa8c453f3; (* arm_LDP X19 X20 SP (Postimmediate_Offset (iword (&64))) *) + 0x6d4237ec; (* arm_LDP D12 D13 SP (Immediate_Offset (iword (&32))) *) + 0x6d433fee; (* arm_LDP D14 D15 SP (Immediate_Offset (iword (&48))) *) + 0x910183ff; (* arm_ADD SP SP (rvalue (word 96)) *) 0xd65f03c0 (* arm_RET X30 *) ];; From 25279ee4a2bfcda62902cd0804ca50ab67aa6542 Mon Sep 17 00:00:00 2001 From: Nevine Ebeid Date: Fri, 18 Jul 2025 17:42:43 -0400 Subject: [PATCH 057/132] Proof of one-block AES-XTS encrypt. --- arm/aes-xts/aes-xts-armv8.S | 1326 ++++++++++++++-------------- arm/aes-xts/aes-xts-armv8.txt | 460 +++++----- arm/proofs/aes-xts-armv8.ml | 1027 ++++++++++++++++++++- arm/proofs/aes_encrypt.ml | 4 +- arm/proofs/aes_xts_encrypt_spec.ml | 4 + 5 files changed, 1905 insertions(+), 916 deletions(-) diff --git a/arm/aes-xts/aes-xts-armv8.S b/arm/aes-xts/aes-xts-armv8.S index 043337e50..9b8eb8c7a 100644 --- a/arm/aes-xts/aes-xts-armv8.S +++ b/arm/aes-xts/aes-xts-armv8.S @@ -1,683 +1,647 @@ -// Generated by: -// objdump -d -m --symbol-description --symbolize-operands -// --disassembler-options=reg-names-std --no-addresses --no-show-raw-insn -// /crypto/fipsmodule/CMakeFiles/fipsmodule.dir/aes/asm/aes-xts-armv8-enc-slothy.S.o -// > ../aes-xts-armv8-enc-slothy_M3_dissassemble.S - -// crypto/fipsmodule/CMakeFiles/fipsmodule.dir/aes/asm/aes-xts-armv8-enc-slothy.S.o: -// (__TEXT,__text) section -aes_hw_slothy_xts_encrypt: +#include "_internal_s2n_bignum.h" + +// copied from https://github.com/nebeid/aws-lc/blob/8a48d976c7e2018dc44a736f1b74435f4eeb7b99/crypto/fipsmodule/aes/asm/slothy/clean/enc/aes-xts-armv8-enc-base_x5_basic.S#L1-L677 + +.align 4 + +#define STACK_SIZE_GPRS (2*16) +#define STACK_SIZE_VREGS (4*16) +#define STACK_SIZE (STACK_SIZE_GPRS + STACK_SIZE_VREGS) + +#define STACK_BASE_GPRS (0) +#define STACK_BASE_VREGS (STACK_SIZE_GPRS) + +.macro save_regs + stp x19, x20, [sp, #(STACK_BASE_GPRS + 16*0)] + stp x21, x22, [sp, #(STACK_BASE_GPRS + 16*1)] +.endm + +.macro restore_regs + ldp x19, x20, [sp, #(STACK_BASE_GPRS + 16*0)] + ldp x21, x22, [sp, #(STACK_BASE_GPRS + 16*1)] +.endm + +.macro save_vregs + stp d8, d9, [sp, #(STACK_BASE_VREGS + 16*0)] + stp d10, d11, [sp, #(STACK_BASE_VREGS + 16*1)] + stp d12, d13, [sp, #(STACK_BASE_VREGS + 16*2)] + stp d14, d15, [sp, #(STACK_BASE_VREGS + 16*3)] +.endm + +.macro restore_vregs + ldp d8, d9, [sp, #(STACK_BASE_VREGS + 16*0)] + ldp d10, d11, [sp, #(STACK_BASE_VREGS + 16*1)] + ldp d12, d13, [sp, #(STACK_BASE_VREGS + 16*2)] + ldp d14, d15, [sp, #(STACK_BASE_VREGS + 16*3)] +.endm + +// A single AES round +// Prevent SLOTHY from unfolding because uArchs tend to fuse AESMC+AESE +.macro aesr data, key // @slothy:no-unfold + aese \data, \key + aesmc \data, \data +.endm + +.macro tweak lo, hi + extr x22, x10, x10, #32 + extr x10, x10, x9, #63 + and w11, w19, w22, asr#31 + eor x9, x11, x9, lsl#1 + fmov \lo, x9 + fmov \hi, x10 +.endm + _aes_hw_slothy_xts_encrypt: - sub sp, sp, #0x60 - stp d8, d9, [sp] - stp d10, d11, [sp, #0x10] - stp d12, d13, [sp, #0x20] - stp d14, d15, [sp, #0x30] - stp x19, x20, [sp, #0x40] - stp x21, x22, [sp, #0x50] - cmp x2, #0x10 - b.lt 0xa60 - nop - nop - nop - and x21, x2, #0xf - and x2, x2, #0xfffffffffffffff0 - ldr w6, [x4, #0xf0] - ld1.4s { v0 }, [x4], #16 - ld1.16b { v6 }, [x5] - sub w6, w6, #0x2 - ld1.4s { v1 }, [x4], #16 - aese.16b v6, v0 - aesmc.16b v6, v6 - ld1.4s { v0 }, [x4], #16 - subs w6, w6, #0x2 - aese.16b v6, v1 - aesmc.16b v6, v6 - ld1.4s { v1 }, [x4], #16 - b.gt 0x4c - aese.16b v6, v0 - aesmc.16b v6, v6 - ld1.4s { v0 }, [x4] - aese.16b v6, v1 - eor.16b v6, v6, v0 - fmov x9, d6 - fmov.d x10, v6[1] - mov w19, #0x87 - ror x22, x10, #0x20 - extr x10, x10, x9, #0x3f - and w11, w19, w22, asr #31 - eor x9, x11, x9, lsl #1 - fmov d8, x9 - fmov.d v8[1], x10 - mov x7, x3 - ld1.4s { v16, v17 }, [x7], #32 - ld1.4s { v12, v13 }, [x7], #32 - ld1.4s { v14, v15 }, [x7], #32 - ld1.4s { v4, v5 }, [x7], #32 - ld1.4s { v18, v19 }, [x7], #32 - ld1.4s { v20, v21 }, [x7], #32 - ld1.4s { v22, v23 }, [x7], #32 - ld1.4s { v7 }, [x7] - cmp x2, #0x20 - b.lo 0x928 - cmp x2, #0x30 - b.lo 0x80c - ror x22, x10, #0x20 - extr x10, x10, x9, #0x3f - and w11, w19, w22, asr #31 - eor x9, x11, x9, lsl #1 - fmov d9, x9 - fmov.d v9[1], x10 - cmp x2, #0x40 - b.lo 0x670 - ror x22, x10, #0x20 - extr x10, x10, x9, #0x3f - and w11, w19, w22, asr #31 - eor x9, x11, x9, lsl #1 - fmov d10, x9 - fmov.d v10[1], x10 - cmp x2, #0x50 - b.lo 0x450 - ror x22, x10, #0x20 - extr x10, x10, x9, #0x3f - and w11, w19, w22, asr #31 - eor x9, x11, x9, lsl #1 - fmov d11, x9 - fmov.d v11[1], x10 - ldp q0, q1, [x0], #0x50 - ldp q24, q25, [x0, #-0x30] - ldur q26, [x0, #-0x10] - eor.16b v0, v0, v6 - eor.16b v1, v1, v8 - eor.16b v24, v24, v9 - eor.16b v25, v25, v10 - eor.16b v26, v26, v11 - aese.16b v0, v16 - aesmc.16b v0, v0 - aese.16b v1, v16 - aesmc.16b v1, v1 - aese.16b v24, v16 - aesmc.16b v24, v24 - aese.16b v25, v16 - aesmc.16b v25, v25 - aese.16b v26, v16 - aesmc.16b v26, v26 - aese.16b v0, v17 - aesmc.16b v0, v0 - aese.16b v1, v17 - aesmc.16b v1, v1 - aese.16b v24, v17 - aesmc.16b v24, v24 - aese.16b v25, v17 - aesmc.16b v25, v25 - aese.16b v26, v17 - aesmc.16b v26, v26 - aese.16b v0, v12 - aesmc.16b v0, v0 - aese.16b v1, v12 - aesmc.16b v1, v1 - aese.16b v24, v12 - aesmc.16b v24, v24 - aese.16b v25, v12 - aesmc.16b v25, v25 - aese.16b v26, v12 - aesmc.16b v26, v26 - aese.16b v0, v13 - aesmc.16b v0, v0 - aese.16b v1, v13 - aesmc.16b v1, v1 - aese.16b v24, v13 - aesmc.16b v24, v24 - aese.16b v25, v13 - aesmc.16b v25, v25 - aese.16b v26, v13 - aesmc.16b v26, v26 - aese.16b v0, v14 - aesmc.16b v0, v0 - aese.16b v1, v14 - aesmc.16b v1, v1 - aese.16b v24, v14 - aesmc.16b v24, v24 - aese.16b v25, v14 - aesmc.16b v25, v25 - aese.16b v26, v14 - aesmc.16b v26, v26 - aese.16b v0, v15 - aesmc.16b v0, v0 - aese.16b v1, v15 - aesmc.16b v1, v1 - aese.16b v24, v15 - aesmc.16b v24, v24 - aese.16b v25, v15 - aesmc.16b v25, v25 - aese.16b v26, v15 - aesmc.16b v26, v26 - aese.16b v0, v4 - aesmc.16b v0, v0 - aese.16b v1, v4 - aesmc.16b v1, v1 - aese.16b v24, v4 - aesmc.16b v24, v24 - aese.16b v25, v4 - aesmc.16b v25, v25 - aese.16b v26, v4 - aesmc.16b v26, v26 - aese.16b v0, v5 - aesmc.16b v0, v0 - aese.16b v1, v5 - aesmc.16b v1, v1 - aese.16b v24, v5 - aesmc.16b v24, v24 - aese.16b v25, v5 - aesmc.16b v25, v25 - aese.16b v26, v5 - aesmc.16b v26, v26 - aese.16b v0, v18 - aesmc.16b v0, v0 - aese.16b v1, v18 - aesmc.16b v1, v1 - aese.16b v24, v18 - aesmc.16b v24, v24 - aese.16b v25, v18 - aesmc.16b v25, v25 - aese.16b v26, v18 - aesmc.16b v26, v26 - aese.16b v0, v19 - aesmc.16b v0, v0 - aese.16b v1, v19 - aesmc.16b v1, v1 - aese.16b v24, v19 - aesmc.16b v24, v24 - aese.16b v25, v19 - aesmc.16b v25, v25 - aese.16b v26, v19 - aesmc.16b v26, v26 - aese.16b v0, v20 - aesmc.16b v0, v0 - aese.16b v1, v20 - aesmc.16b v1, v1 - aese.16b v24, v20 - aesmc.16b v24, v24 - aese.16b v25, v20 - aesmc.16b v25, v25 - aese.16b v26, v20 - aesmc.16b v26, v26 - aese.16b v0, v21 - aesmc.16b v0, v0 - aese.16b v1, v21 - aesmc.16b v1, v1 - aese.16b v24, v21 - aesmc.16b v24, v24 - aese.16b v25, v21 - aesmc.16b v25, v25 - aese.16b v26, v21 - aesmc.16b v26, v26 - aese.16b v0, v22 - aesmc.16b v0, v0 - aese.16b v1, v22 - aesmc.16b v1, v1 - aese.16b v24, v22 - aesmc.16b v24, v24 - aese.16b v25, v22 - aesmc.16b v25, v25 - aese.16b v26, v22 - aesmc.16b v26, v26 - aese.16b v0, v23 - aese.16b v1, v23 - aese.16b v24, v23 - aese.16b v25, v23 - aese.16b v26, v23 - eor.16b v0, v0, v7 - eor.16b v0, v0, v6 - ror x22, x10, #0x20 - extr x10, x10, x9, #0x3f - and w11, w19, w22, asr #31 - eor x9, x11, x9, lsl #1 - fmov d6, x9 - fmov.d v6[1], x10 - eor.16b v1, v1, v7 - eor.16b v1, v1, v8 - ror x22, x10, #0x20 - extr x10, x10, x9, #0x3f - and w11, w19, w22, asr #31 - eor x9, x11, x9, lsl #1 - fmov d8, x9 - fmov.d v8[1], x10 - eor.16b v24, v24, v7 - eor.16b v24, v24, v9 - ror x22, x10, #0x20 - extr x10, x10, x9, #0x3f - and w11, w19, w22, asr #31 - eor x9, x11, x9, lsl #1 - fmov d9, x9 - fmov.d v9[1], x10 - eor.16b v25, v25, v7 - eor.16b v25, v25, v10 - ror x22, x10, #0x20 - extr x10, x10, x9, #0x3f - and w11, w19, w22, asr #31 - eor x9, x11, x9, lsl #1 - fmov d10, x9 - fmov.d v10[1], x10 - eor.16b v26, v26, v7 - eor.16b v26, v26, v11 - ror x22, x10, #0x20 - extr x10, x10, x9, #0x3f - and w11, w19, w22, asr #31 - eor x9, x11, x9, lsl #1 - fmov d11, x9 - fmov.d v11[1], x10 - stp q0, q1, [x1], #0x50 - stp q24, q25, [x1, #-0x30] - stur q26, [x1, #-0x10] - subs x2, x2, #0x50 - cmp x2, #0x50 - b.lo 0x428 - b.hs 0x130 - cmp x2, #0x0 - b.eq 0x9e0 - cmp x2, #0x10 - b.eq 0x928 - cmp x2, #0x20 - b.eq 0x80c - cmp x2, #0x30 - b.eq 0x670 - cmp x2, #0x40 - b.eq 0x450 - ld1.16b { v0 }, [x0], #16 - ld1.16b { v1 }, [x0], #16 - ld1.16b { v24 }, [x0], #16 - ld1.16b { v25 }, [x0], #16 - eor.16b v0, v0, v6 - eor.16b v1, v1, v8 - eor.16b v24, v24, v9 - eor.16b v25, v25, v10 - aese.16b v0, v16 - aesmc.16b v0, v0 - aese.16b v1, v16 - aesmc.16b v1, v1 - aese.16b v24, v16 - aesmc.16b v24, v24 - aese.16b v25, v16 - aesmc.16b v25, v25 - aese.16b v0, v17 - aesmc.16b v0, v0 - aese.16b v1, v17 - aesmc.16b v1, v1 - aese.16b v24, v17 - aesmc.16b v24, v24 - aese.16b v25, v17 - aesmc.16b v25, v25 - aese.16b v0, v12 - aesmc.16b v0, v0 - aese.16b v1, v12 - aesmc.16b v1, v1 - aese.16b v24, v12 - aesmc.16b v24, v24 - aese.16b v25, v12 - aesmc.16b v25, v25 - aese.16b v0, v13 - aesmc.16b v0, v0 - aese.16b v1, v13 - aesmc.16b v1, v1 - aese.16b v24, v13 - aesmc.16b v24, v24 - aese.16b v25, v13 - aesmc.16b v25, v25 - aese.16b v0, v14 - aesmc.16b v0, v0 - aese.16b v1, v14 - aesmc.16b v1, v1 - aese.16b v24, v14 - aesmc.16b v24, v24 - aese.16b v25, v14 - aesmc.16b v25, v25 - aese.16b v0, v15 - aesmc.16b v0, v0 - aese.16b v1, v15 - aesmc.16b v1, v1 - aese.16b v24, v15 - aesmc.16b v24, v24 - aese.16b v25, v15 - aesmc.16b v25, v25 - aese.16b v0, v4 - aesmc.16b v0, v0 - aese.16b v1, v4 - aesmc.16b v1, v1 - aese.16b v24, v4 - aesmc.16b v24, v24 - aese.16b v25, v4 - aesmc.16b v25, v25 - aese.16b v0, v5 - aesmc.16b v0, v0 - aese.16b v1, v5 - aesmc.16b v1, v1 - aese.16b v24, v5 - aesmc.16b v24, v24 - aese.16b v25, v5 - aesmc.16b v25, v25 - aese.16b v0, v18 - aesmc.16b v0, v0 - aese.16b v1, v18 - aesmc.16b v1, v1 - aese.16b v24, v18 - aesmc.16b v24, v24 - aese.16b v25, v18 - aesmc.16b v25, v25 - aese.16b v0, v19 - aesmc.16b v0, v0 - aese.16b v1, v19 - aesmc.16b v1, v1 - aese.16b v24, v19 - aesmc.16b v24, v24 - aese.16b v25, v19 - aesmc.16b v25, v25 - aese.16b v0, v20 - aesmc.16b v0, v0 - aese.16b v1, v20 - aesmc.16b v1, v1 - aese.16b v24, v20 - aesmc.16b v24, v24 - aese.16b v25, v20 - aesmc.16b v25, v25 - aese.16b v0, v21 - aesmc.16b v0, v0 - aese.16b v1, v21 - aesmc.16b v1, v1 - aese.16b v24, v21 - aesmc.16b v24, v24 - aese.16b v25, v21 - aesmc.16b v25, v25 - aese.16b v0, v22 - aesmc.16b v0, v0 - aese.16b v1, v22 - aesmc.16b v1, v1 - aese.16b v24, v22 - aesmc.16b v24, v24 - aese.16b v25, v22 - aesmc.16b v25, v25 - aese.16b v0, v23 - aese.16b v1, v23 - aese.16b v24, v23 - aese.16b v25, v23 - eor.16b v0, v0, v7 - eor.16b v0, v0, v6 - eor.16b v1, v1, v7 - eor.16b v1, v1, v8 - eor.16b v24, v24, v7 - eor.16b v24, v24, v9 - eor.16b v25, v25, v7 - eor.16b v25, v25, v10 - st1.16b { v0, v1 }, [x1], #32 - st1.16b { v24, v25 }, [x1], #32 - fmov x9, d10 - fmov.d x10, v10[1] - ror x22, x10, #0x20 - extr x10, x10, x9, #0x3f - and w11, w19, w22, asr #31 - eor x9, x11, x9, lsl #1 - fmov d6, x9 - fmov.d v6[1], x10 - b 0x9e0 - nop - ld1.16b { v0, v1 }, [x0], #32 - ld1.16b { v24 }, [x0], #16 - eor.16b v0, v0, v6 - eor.16b v1, v1, v8 - eor.16b v24, v24, v9 - aese.16b v0, v16 - aesmc.16b v0, v0 - aese.16b v1, v16 - aesmc.16b v1, v1 - aese.16b v24, v16 - aesmc.16b v24, v24 - aese.16b v0, v17 - aesmc.16b v0, v0 - aese.16b v1, v17 - aesmc.16b v1, v1 - aese.16b v24, v17 - aesmc.16b v24, v24 - aese.16b v0, v12 - aesmc.16b v0, v0 - aese.16b v1, v12 - aesmc.16b v1, v1 - aese.16b v24, v12 - aesmc.16b v24, v24 - aese.16b v0, v13 - aesmc.16b v0, v0 - aese.16b v1, v13 - aesmc.16b v1, v1 - aese.16b v24, v13 - aesmc.16b v24, v24 - aese.16b v0, v14 - aesmc.16b v0, v0 - aese.16b v1, v14 - aesmc.16b v1, v1 - aese.16b v24, v14 - aesmc.16b v24, v24 - aese.16b v0, v15 - aesmc.16b v0, v0 - aese.16b v1, v15 - aesmc.16b v1, v1 - aese.16b v24, v15 - aesmc.16b v24, v24 - aese.16b v0, v4 - aesmc.16b v0, v0 - aese.16b v1, v4 - aesmc.16b v1, v1 - aese.16b v24, v4 - aesmc.16b v24, v24 - aese.16b v0, v5 - aesmc.16b v0, v0 - aese.16b v1, v5 - aesmc.16b v1, v1 - aese.16b v24, v5 - aesmc.16b v24, v24 - aese.16b v0, v18 - aesmc.16b v0, v0 - aese.16b v1, v18 - aesmc.16b v1, v1 - aese.16b v24, v18 - aesmc.16b v24, v24 - aese.16b v0, v19 - aesmc.16b v0, v0 - aese.16b v1, v19 - aesmc.16b v1, v1 - aese.16b v24, v19 - aesmc.16b v24, v24 - aese.16b v0, v20 - aesmc.16b v0, v0 - aese.16b v1, v20 - aesmc.16b v1, v1 - aese.16b v24, v20 - aesmc.16b v24, v24 - aese.16b v0, v21 - aesmc.16b v0, v0 - aese.16b v1, v21 - aesmc.16b v1, v1 - aese.16b v24, v21 - aesmc.16b v24, v24 - aese.16b v0, v22 - aesmc.16b v0, v0 - aese.16b v1, v22 - aesmc.16b v1, v1 - aese.16b v24, v22 - aesmc.16b v24, v24 - aese.16b v0, v23 - aese.16b v1, v23 - aese.16b v24, v23 - eor.16b v0, v0, v7 - eor.16b v0, v0, v6 - eor.16b v1, v1, v7 - eor.16b v1, v1, v8 - eor.16b v24, v24, v7 - eor.16b v24, v24, v9 - st1.16b { v0, v1 }, [x1], #32 - st1.16b { v24 }, [x1], #16 - fmov x9, d9 - fmov.d x10, v9[1] - ror x22, x10, #0x20 - extr x10, x10, x9, #0x3f - and w11, w19, w22, asr #31 - eor x9, x11, x9, lsl #1 - fmov d6, x9 - fmov.d v6[1], x10 - b 0x9e0 - ld1.16b { v0, v1 }, [x0], #32 - eor.16b v0, v0, v6 - eor.16b v1, v1, v8 - aese.16b v0, v16 - aesmc.16b v0, v0 - aese.16b v1, v16 - aesmc.16b v1, v1 - aese.16b v0, v17 - aesmc.16b v0, v0 - aese.16b v1, v17 - aesmc.16b v1, v1 - aese.16b v0, v12 - aesmc.16b v0, v0 - aese.16b v1, v12 - aesmc.16b v1, v1 - aese.16b v0, v13 - aesmc.16b v0, v0 - aese.16b v1, v13 - aesmc.16b v1, v1 - aese.16b v0, v14 - aesmc.16b v0, v0 - aese.16b v1, v14 - aesmc.16b v1, v1 - aese.16b v0, v15 - aesmc.16b v0, v0 - aese.16b v1, v15 - aesmc.16b v1, v1 - aese.16b v0, v4 - aesmc.16b v0, v0 - aese.16b v1, v4 - aesmc.16b v1, v1 - aese.16b v0, v5 - aesmc.16b v0, v0 - aese.16b v1, v5 - aesmc.16b v1, v1 - aese.16b v0, v18 - aesmc.16b v0, v0 - aese.16b v1, v18 - aesmc.16b v1, v1 - aese.16b v0, v19 - aesmc.16b v0, v0 - aese.16b v1, v19 - aesmc.16b v1, v1 - aese.16b v0, v20 - aesmc.16b v0, v0 - aese.16b v1, v20 - aesmc.16b v1, v1 - aese.16b v0, v21 - aesmc.16b v0, v0 - aese.16b v1, v21 - aesmc.16b v1, v1 - aese.16b v0, v22 - aesmc.16b v0, v0 - aese.16b v1, v22 - aesmc.16b v1, v1 - aese.16b v0, v23 - aese.16b v1, v23 - eor.16b v0, v0, v7 - eor.16b v0, v0, v6 - eor.16b v1, v1, v7 - eor.16b v1, v1, v8 - st1.16b { v0, v1 }, [x1], #32 - fmov x9, d8 - fmov.d x10, v8[1] - ror x22, x10, #0x20 - extr x10, x10, x9, #0x3f - and w11, w19, w22, asr #31 - eor x9, x11, x9, lsl #1 - fmov d6, x9 - fmov.d v6[1], x10 - b 0x9e0 - ld1.16b { v0 }, [x0], #16 - eor.16b v0, v0, v6 - aese.16b v0, v16 - aesmc.16b v0, v0 - aese.16b v0, v17 - aesmc.16b v0, v0 - aese.16b v0, v12 - aesmc.16b v0, v0 - aese.16b v0, v13 - aesmc.16b v0, v0 - aese.16b v0, v14 - aesmc.16b v0, v0 - aese.16b v0, v15 - aesmc.16b v0, v0 - aese.16b v0, v4 - aesmc.16b v0, v0 - aese.16b v0, v5 - aesmc.16b v0, v0 - aese.16b v0, v18 - aesmc.16b v0, v0 - aese.16b v0, v19 - aesmc.16b v0, v0 - aese.16b v0, v20 - aesmc.16b v0, v0 - aese.16b v0, v21 - aesmc.16b v0, v0 - aese.16b v0, v22 - aesmc.16b v0, v0 - aese.16b v0, v23 - eor.16b v0, v0, v7 - eor.16b v0, v0, v6 - st1.16b { v0 }, [x1], #16 - fmov x9, d6 - fmov.d x10, v6[1] - ror x22, x10, #0x20 - extr x10, x10, x9, #0x3f - and w11, w19, w22, asr #31 - eor x9, x11, x9, lsl #1 - fmov d6, x9 - fmov.d v6[1], x10 - b 0x9e0 - nop - nop - nop - nop - nop - tst x21, #0xf - b.eq 0xa60 - mov x20, x0 - mov x13, x1 - sub x1, x1, #0x10 +aes_hw_slothy_xts_encrypt: + # AARCH64_VALID_CALL_TARGET + + sub sp, sp, #STACK_SIZE + save_vregs + save_regs + + cmp x2, #16 // AES-XTS needs at least one block + b.lt Lxts_abort +.align 4 +Lxts_enc_big_size: // Encrypt input size >= 16 bytes + and x21, x2, #0xf // store the tail value of length%16 + and x2, x2, #-16 // len &= 0x1..110000, now divisible by 16 + // subs x2, x2, #16 + + // Firstly, encrypt the iv with key2, as the first iv of XEX. + ldr w6, [x4,#240] + ld1 {v0.4s}, [x4], #16 + ld1 {v6.16b}, [x5] + sub w6, w6, #2 + ld1 {v1.4s}, [x4], #16 + +Loop_iv_enc: + aesr v6.16b, v0.16b + ld1 {v0.4s}, [x4], #16 + subs w6, w6, #2 + aesr v6.16b, v1.16b + ld1 {v1.4s}, [x4], #16 + b.gt Loop_iv_enc + + aesr v6.16b, v0.16b + ld1 {v0.4s}, [x4] + aese v6.16b, v1.16b + eor v6.16b, v6.16b, v0.16b + + // The iv for second block + // x9- iv(low), x10 - iv(high) + // the five ivs stored into, v6.16b,v8.16b,v9.16b,v10.16b,v11.16b + fmov x9, d6 + fmov x10, v6.d[1] + mov w19, #0x87 + tweak d8, v8.d[1] + + mov x7, x3 + ld1 {v16.4s,v17.4s},[x7], #32 // load key schedule + ld1 {v12.4s,v13.4s},[x7], #32 + ld1 {v14.4s,v15.4s},[x7], #32 + ld1 {v4.4s,v5.4s}, [x7], #32 + ld1 {v18.4s,v19.4s},[x7], #32 + ld1 {v20.4s,v21.4s},[x7], #32 + ld1 {v22.4s,v23.4s},[x7], #32 + ld1 {v7.4s}, [x7] + +// Encryption +Lxts_enc: + cmp x2,#32 + b.lo Lxts_enc_tail1x // when input = 1 with tail + + cmp x2,#48 + b.lo Lxts_enc_tail2x // when input size = 2 + + // The iv for third block + tweak d9,v9.d[1] + + cmp x2,#64 + b.lo Lxts_enc_tail3x + + // The iv for fourth block + tweak d10,v10.d[1] + + cmp x2,#80 + b.lo Lxts_enc_tail4x + + // The iv for fifth block + tweak d11,v11.d[1] + +.align 4 +Loop5x_xts_enc: + ldp q0, q1, [x0], #0x50 + ldp q24, q25, [x0, #-0x30] + ldr q26, [x0, #-0x10] + + eor v0.16b,v0.16b,v6.16b // before encryption, xor with iv + eor v1.16b,v1.16b,v8.16b + eor v24.16b,v24.16b,v9.16b + eor v25.16b,v25.16b,v10.16b + eor v26.16b,v26.16b,v11.16b + + aesr v0.16b, v16.16b + aesr v1.16b, v16.16b + aesr v24.16b, v16.16b + aesr v25.16b, v16.16b + aesr v26.16b, v16.16b + + aesr v0.16b, v17.16b + aesr v1.16b, v17.16b + aesr v24.16b, v17.16b + aesr v25.16b, v17.16b + aesr v26.16b, v17.16b + + aesr v0.16b, v12.16b + aesr v1.16b, v12.16b + aesr v24.16b, v12.16b + aesr v25.16b, v12.16b + aesr v26.16b, v12.16b + + aesr v0.16b, v13.16b + aesr v1.16b, v13.16b + aesr v24.16b, v13.16b + aesr v25.16b, v13.16b + aesr v26.16b, v13.16b + + aesr v0.16b, v14.16b + aesr v1.16b, v14.16b + aesr v24.16b, v14.16b + aesr v25.16b, v14.16b + aesr v26.16b, v14.16b + + aesr v0.16b, v15.16b + aesr v1.16b, v15.16b + aesr v24.16b, v15.16b + aesr v25.16b, v15.16b + aesr v26.16b, v15.16b + + aesr v0.16b, v4.16b + aesr v1.16b, v4.16b + aesr v24.16b, v4.16b + aesr v25.16b, v4.16b + aesr v26.16b, v4.16b + + aesr v0.16b, v5.16b + aesr v1.16b, v5.16b + aesr v24.16b, v5.16b + aesr v25.16b, v5.16b + aesr v26.16b, v5.16b + + aesr v0.16b, v18.16b + aesr v1.16b, v18.16b + aesr v24.16b, v18.16b + aesr v25.16b, v18.16b + aesr v26.16b, v18.16b + + aesr v0.16b, v19.16b + aesr v1.16b, v19.16b + aesr v24.16b, v19.16b + aesr v25.16b, v19.16b + aesr v26.16b, v19.16b + + aesr v0.16b, v20.16b + aesr v1.16b, v20.16b + aesr v24.16b, v20.16b + aesr v25.16b, v20.16b + aesr v26.16b, v20.16b + + aesr v0.16b, v21.16b + aesr v1.16b, v21.16b + aesr v24.16b, v21.16b + aesr v25.16b, v21.16b + aesr v26.16b, v21.16b + + aesr v0.16b, v22.16b + aesr v1.16b, v22.16b + aesr v24.16b, v22.16b + aesr v25.16b, v22.16b + aesr v26.16b, v22.16b + + aese v0.16b,v23.16b + aese v1.16b,v23.16b + aese v24.16b,v23.16b + aese v25.16b,v23.16b + aese v26.16b,v23.16b + + eor v0.16b,v0.16b,v7.16b + eor v0.16b,v0.16b,v6.16b + // The iv for first block of one iteration + tweak d6,v6.d[1] + eor v1.16b,v1.16b,v7.16b + eor v1.16b,v1.16b,v8.16b + + // The iv for second block + tweak d8,v8.d[1] + eor v24.16b,v24.16b,v7.16b + eor v24.16b,v24.16b,v9.16b + + // The iv for third block + tweak d9,v9.d[1] + eor v25.16b,v25.16b,v7.16b + eor v25.16b,v25.16b,v10.16b + + // The iv for fourth block + tweak d10,v10.d[1] + eor v26.16b,v26.16b,v7.16b + eor v26.16b,v26.16b,v11.16b + + // The iv for fifth block + tweak d11,v11.d[1] + + stp q0, q1, [x1], #0x50 + stp q24, q25, [x1, #-0x30] + str q26, [x1, #-0x10] + + subs x2,x2,#0x50 // @slothy:core + + cmp x2,#0x50 + b.lo Loop5x_enc_after + + b.hs Loop5x_xts_enc + +Loop5x_enc_after: + cmp x2,#0x0 + b.eq Lxts_enc_done + + cmp x2,#0x10 + b.eq Lxts_enc_tail1x + + cmp x2,#0x20 + b.eq Lxts_enc_tail2x + + cmp x2,#0x30 + b.eq Lxts_enc_tail3x + + cmp x2,#0x40 + b.eq Lxts_enc_tail4x + +.align 4 +Lxts_enc_tail4x: + ld1 {v0.16b}, [x0],#16 // the first block + ld1 {v1.16b}, [x0],#16 // the second block + ld1 {v24.16b},[x0],#16 // the third block + ld1 {v25.16b},[x0],#16 // the fourth block + + eor v0.16b,v0.16b,v6.16b + eor v1.16b,v1.16b,v8.16b + eor v24.16b,v24.16b,v9.16b + eor v25.16b,v25.16b,v10.16b + + aesr v0.16b, v16.16b + aesr v1.16b, v16.16b + aesr v24.16b, v16.16b + aesr v25.16b, v16.16b + + aesr v0.16b, v17.16b + aesr v1.16b, v17.16b + aesr v24.16b, v17.16b + aesr v25.16b, v17.16b + + aesr v0.16b, v12.16b + aesr v1.16b, v12.16b + aesr v24.16b, v12.16b + aesr v25.16b, v12.16b + + aesr v0.16b, v13.16b + aesr v1.16b, v13.16b + aesr v24.16b, v13.16b + aesr v25.16b, v13.16b + + aesr v0.16b, v14.16b + aesr v1.16b, v14.16b + aesr v24.16b, v14.16b + aesr v25.16b, v14.16b + + aesr v0.16b, v15.16b + aesr v1.16b, v15.16b + aesr v24.16b, v15.16b + aesr v25.16b, v15.16b + + aesr v0.16b, v4.16b + aesr v1.16b, v4.16b + aesr v24.16b, v4.16b + aesr v25.16b, v4.16b + + aesr v0.16b, v5.16b + aesr v1.16b, v5.16b + aesr v24.16b, v5.16b + aesr v25.16b, v5.16b + + aesr v0.16b, v18.16b + aesr v1.16b, v18.16b + aesr v24.16b, v18.16b + aesr v25.16b, v18.16b + + aesr v0.16b, v19.16b + aesr v1.16b, v19.16b + aesr v24.16b, v19.16b + aesr v25.16b, v19.16b + + aesr v0.16b, v20.16b + aesr v1.16b, v20.16b + aesr v24.16b, v20.16b + aesr v25.16b, v20.16b + + aesr v0.16b, v21.16b + aesr v1.16b, v21.16b + aesr v24.16b, v21.16b + aesr v25.16b, v21.16b + + aesr v0.16b, v22.16b + aesr v1.16b, v22.16b + aesr v24.16b, v22.16b + aesr v25.16b, v22.16b + + aese v0.16b,v23.16b + aese v1.16b,v23.16b + aese v24.16b,v23.16b + aese v25.16b,v23.16b + + eor v0.16b,v0.16b,v7.16b + eor v0.16b,v0.16b,v6.16b + + eor v1.16b,v1.16b,v7.16b + eor v1.16b,v1.16b,v8.16b + + eor v24.16b,v24.16b,v7.16b + eor v24.16b,v24.16b,v9.16b + + eor v25.16b,v25.16b,v7.16b + eor v25.16b,v25.16b,v10.16b + + st1 {v0.16b,v1.16b},[x1],#32 + st1 {v24.16b,v25.16b},[x1],#32 + + // The iv for tail + fmov x9,d10 + fmov x10,v10.d[1] + tweak d6,v6.d[1] + + b Lxts_enc_done + +.align 4 +Lxts_enc_tail3x: + ld1 {v0.16b,v1.16b}, [x0],#32 + ld1 {v24.16b}, [x0],#16 + + eor v0.16b,v0.16b,v6.16b + eor v1.16b,v1.16b,v8.16b + eor v24.16b,v24.16b,v9.16b + + // First round with v16 + aesr v0.16b, v16.16b + aesr v1.16b, v16.16b + aesr v24.16b, v16.16b + + // Second round with v17 + aesr v0.16b, v17.16b + aesr v1.16b, v17.16b + aesr v24.16b, v17.16b + + // Third round with v12 + aesr v0.16b, v12.16b + aesr v1.16b, v12.16b + aesr v24.16b, v12.16b + + // Fourth round with v13 + aesr v0.16b, v13.16b + aesr v1.16b, v13.16b + aesr v24.16b, v13.16b + + // Fifth round with v14 + aesr v0.16b, v14.16b + aesr v1.16b, v14.16b + aesr v24.16b, v14.16b + + // Sixth round with v15 + aesr v0.16b, v15.16b + aesr v1.16b, v15.16b + aesr v24.16b, v15.16b + + // Seventh round with v4 + aesr v0.16b, v4.16b + aesr v1.16b, v4.16b + aesr v24.16b, v4.16b + + // Eighth round with v5 + aesr v0.16b, v5.16b + aesr v1.16b, v5.16b + aesr v24.16b, v5.16b + + // 9th round with v18 + aesr v0.16b, v18.16b + aesr v1.16b, v18.16b + aesr v24.16b, v18.16b + + // 10th round with v19 + aesr v0.16b, v19.16b + aesr v1.16b, v19.16b + aesr v24.16b, v19.16b + + aesr v0.16b, v20.16b + aesr v1.16b, v20.16b + aesr v24.16b, v20.16b + + aesr v0.16b, v21.16b + aesr v1.16b, v21.16b + aesr v24.16b, v21.16b + + aesr v0.16b, v22.16b + aesr v1.16b, v22.16b + aesr v24.16b, v22.16b + + aese v0.16b,v23.16b + aese v1.16b,v23.16b + aese v24.16b,v23.16b + + eor v0.16b,v0.16b,v7.16b + eor v0.16b,v0.16b,v6.16b + eor v1.16b,v1.16b,v7.16b + eor v1.16b,v1.16b,v8.16b + eor v24.16b,v24.16b,v7.16b + eor v24.16b,v24.16b,v9.16b + + st1 {v0.16b,v1.16b},[x1],#32 + st1 {v24.16b},[x1],#16 + + // The iv for tail + fmov x9,d9 + fmov x10,v9.d[1] + tweak d6,v6.d[1] + + b Lxts_enc_done // done processing three blocks + +Lxts_enc_tail2x: + ld1 {v0.16b,v1.16b},[x0],#32 // the first block + + eor v0.16b,v0.16b,v6.16b + eor v1.16b,v1.16b,v8.16b + + // First round with v16 + aesr v0.16b, v16.16b + aesr v1.16b, v16.16b + + // Second round with v17 + aesr v0.16b, v17.16b + aesr v1.16b, v17.16b + + // Third round with v12 + aesr v0.16b, v12.16b + aesr v1.16b, v12.16b + + // Fourth round with v13 + aesr v0.16b, v13.16b + aesr v1.16b, v13.16b + + // Fifth round with v14 + aesr v0.16b, v14.16b + aesr v1.16b, v14.16b + + // Sixth round with v15 + aesr v0.16b, v15.16b + aesr v1.16b, v15.16b + + // Seventh round with v4 + aesr v0.16b, v4.16b + aesr v1.16b, v4.16b + + // Eighth round with v5 + aesr v0.16b, v5.16b + aesr v1.16b, v5.16b + + // 9th round with v18 + aesr v0.16b, v18.16b + aesr v1.16b, v18.16b + + // 10th round with v19 + aesr v0.16b, v19.16b + aesr v1.16b, v19.16b + + aesr v0.16b, v20.16b + aesr v1.16b, v20.16b + + aesr v0.16b, v21.16b + aesr v1.16b, v21.16b + + aesr v0.16b, v22.16b + aesr v1.16b, v22.16b + + aese v0.16b,v23.16b + aese v1.16b,v23.16b + + eor v0.16b,v0.16b,v7.16b + eor v0.16b,v0.16b,v6.16b + eor v1.16b,v1.16b,v7.16b + eor v1.16b,v1.16b,v8.16b + + st1 {v0.16b,v1.16b},[x1],#32 + + // The iv for tail + fmov x9,d8 + fmov x10,v8.d[1] + tweak d6,v6.d[1] + b Lxts_enc_done + +Lxts_enc_tail1x: + ld1 {v0.16b}, [x0],#16 // the first block + + eor v0.16b,v0.16b,v6.16b + + // First round with v16 + aesr v0.16b, v16.16b + + // Second round with v17 + aesr v0.16b, v17.16b + + // Third round with v12 + aesr v0.16b, v12.16b + + // Fourth round with v13 + aesr v0.16b, v13.16b + + // Fifth round with v14 + aesr v0.16b, v14.16b + + // Sixth round with v15 + aesr v0.16b, v15.16b + + // Seventh round with v4 + aesr v0.16b, v4.16b + + // Eighth round with v5 + aesr v0.16b, v5.16b + + // 9th round with v18 + aesr v0.16b, v18.16b + + // 10th round with v19 + aesr v0.16b, v19.16b + + aesr v0.16b, v20.16b + aesr v0.16b, v21.16b + aesr v0.16b, v22.16b + aese v0.16b,v23.16b + + eor v0.16b,v0.16b,v7.16b + eor v0.16b,v0.16b,v6.16b + st1 {v0.16b},[x1],#16 + + // tweak for tail + fmov x9,d6 + fmov x10,v6.d[1] + tweak d6,v6.d[1] + b Lxts_enc_done + +.align 5 +Lxts_enc_done: + // Process the tail block with cipher stealing. + tst x21,#0xf + b.eq Lxts_abort + + mov x20,x0 + mov x13,x1 + sub x1,x1,#16 .composite_enc_loop: - subs x21, x21, #0x1 - ldrb w15, [x1, x21] - ldrb w14, [x20, x21] - strb w15, [x13, x21] - strb w14, [x1, x21] - b.gt .composite_enc_loop - ld1.16b { v26 }, [x1] - eor.16b v26, v26, v6 - ldr w6, [x3, #0xf0] - ld1.16b { v0 }, [x3], #16 - sub w6, w6, #0x2 - ld1.16b { v1 }, [x3], #16 - aese.16b v26, v0 - aesmc.16b v26, v26 - ld1.4s { v0 }, [x3], #16 - subs w6, w6, #0x2 - aese.16b v26, v1 - aesmc.16b v26, v26 - ld1.4s { v1 }, [x3], #16 - b.gt 0xa24 - aese.16b v26, v0 - aesmc.16b v26, v26 - ld1.4s { v0 }, [x3] - aese.16b v26, v1 - eor.16b v26, v26, v0 - eor.16b v26, v26, v6 - st1.16b { v26 }, [x1] - ldp x19, x20, [sp, #0x40] - ldp x21, x22, [sp, #0x50] - ldp d8, d9, [sp] - ldp d10, d11, [sp, #0x10] - ldp d12, d13, [sp, #0x20] - ldp d14, d15, [sp, #0x30] - add sp, sp, #0x60 - ret + subs x21,x21,#1 + ldrb w15,[x1,x21] + ldrb w14,[x20,x21] + strb w15,[x13,x21] + strb w14,[x1,x21] + b.gt .composite_enc_loop +Lxts_enc_load_done: + ld1 {v26.16b},[x1] + eor v26.16b,v26.16b,v6.16b + + // Encrypt the composite block to get the last second encrypted text block + ldr w6,[x3,#240] // load key schedule... + ld1 {v0.16b},[x3],#16 + sub w6,w6,#2 + ld1 {v1.16b},[x3],#16 // load key schedule... +Loop_final_enc: + aesr v26.16b, v0.16b + ld1 {v0.4s},[x3],#16 + subs w6,w6,#2 + aesr v26.16b, v1.16b + ld1 {v1.4s},[x3],#16 + b.gt Loop_final_enc + + aesr v26.16b, v0.16b + ld1 {v0.4s},[x3] + aese v26.16b,v1.16b + eor v26.16b,v26.16b,v0.16b + eor v26.16b,v26.16b,v6.16b + st1 {v26.16b},[x1] + +Lxts_abort: + restore_regs + +Lxts_enc_final_abort: + restore_vregs + add sp, sp, #STACK_SIZE + ret + +#if defined(__ELF__) +// See https://www.airs.com/blog/archives/518. +.section .note.GNU-stack,"",%progbits +#endif diff --git a/arm/aes-xts/aes-xts-armv8.txt b/arm/aes-xts/aes-xts-armv8.txt index d750c3852..1cd8643a5 100644 --- a/arm/aes-xts/aes-xts-armv8.txt +++ b/arm/aes-xts/aes-xts-armv8.txt @@ -1,88 +1,88 @@ [ - 0xd10183ff; (* arm_SUB SP SP (rvalue (word 96)) *) - 0x6d0027e8; (* arm_STP D8 D9 SP (Immediate_Offset (iword (&0))) *) - 0x6d012fea; (* arm_STP D10 D11 SP (Immediate_Offset (iword (&16))) *) - 0x6d0237ec; (* arm_STP D12 D13 SP (Immediate_Offset (iword (&32))) *) - 0x6d033fee; (* arm_STP D14 D15 SP (Immediate_Offset (iword (&48))) *) - 0xa90453f3; (* arm_STP X19 X20 SP (Immediate_Offset (iword (&64))) *) - 0xa9055bf5; (* arm_STP X21 X22 SP (Immediate_Offset (iword (&80))) *) - 0xf100405f; (* arm_CMP X2 (rvalue (word 16)) *) - 0x5400530b; (* arm_BLT (word 2656) *) + 0xd10183ff; (* arm_SUB SP SP (rvalue (word 0x60)) *) + 0x6d0227e8; (* arm_STP D8 D9 SP (Immediate_Offset (iword (&0x20))) *) + 0x6d032fea; (* arm_STP D10 D11 SP (Immediate_Offset (iword (&0x30))) *) + 0x6d0437ec; (* arm_STP D12 D13 SP (Immediate_Offset (iword (&0x40))) *) + 0x6d053fee; (* arm_STP D14 D15 SP (Immediate_Offset (iword (&0x50))) *) + 0xa90053f3; (* arm_STP X19 X20 SP (Immediate_Offset (iword (&0x0))) *) + 0xa9015bf5; (* arm_STP X21 X22 SP (Immediate_Offset (iword (&0x10))) *) + 0xf100405f; (* arm_CMP X2 (rvalue (word 0x10)) *) + 0x5400520b; (* arm_BLT (word 0xa40) *) 0xd503201f; (* arm_NOP *) 0xd503201f; (* arm_NOP *) 0xd503201f; (* arm_NOP *) - 0x92400c55; (* arm_AND X21 X2 (rvalue (word 15)) *) - 0x927cec42; (* arm_AND X2 X2 (rvalue (word 18446744073709551600)) *) - 0xb940f086; (* arm_LDR W6 X4 (Immediate_Offset (word 240)) *) - 0x4cdf7880; (* arm_LDR Q0 X4 (Postimmediate_Offset (word 16)) *) + 0x92400c55; (* arm_AND X21 X2 (rvalue (word 0xf)) *) + 0x927cec42; (* arm_AND X2 X2 (rvalue (word 0xfffffffffffffff0)) *) + 0xb940f086; (* arm_LDR W6 X4 (Immediate_Offset (word 0xf0)) *) + 0x4cdf7880; (* arm_LDR Q0 X4 (Postimmediate_Offset (word 0x10)) *) 0x4c4070a6; (* arm_LDR Q6 X5 No_Offset *) - 0x510008c6; (* arm_SUB W6 W6 (rvalue (word 2)) *) - 0x4cdf7881; (* arm_LDR Q1 X4 (Postimmediate_Offset (word 16)) *) + 0x510008c6; (* arm_SUB W6 W6 (rvalue (word 0x2)) *) + 0x4cdf7881; (* arm_LDR Q1 X4 (Postimmediate_Offset (word 0x10)) *) 0x4e284806; (* arm_AESE Q6 Q0 *) 0x4e2868c6; (* arm_AESMC Q6 Q6 *) - 0x4cdf7880; (* arm_LDR Q0 X4 (Postimmediate_Offset (word 16)) *) - 0x710008c6; (* arm_SUBS W6 W6 (rvalue (word 2)) *) + 0x4cdf7880; (* arm_LDR Q0 X4 (Postimmediate_Offset (word 0x10)) *) + 0x710008c6; (* arm_SUBS W6 W6 (rvalue (word 0x2)) *) 0x4e284826; (* arm_AESE Q6 Q1 *) 0x4e2868c6; (* arm_AESMC Q6 Q6 *) - 0x4cdf7881; (* arm_LDR Q1 X4 (Postimmediate_Offset (word 16)) *) - 0x5400026c; (* arm_BGT (word 76) *) + 0x4cdf7881; (* arm_LDR Q1 X4 (Postimmediate_Offset (word 0x10)) *) + 0x54ffff2c; (* arm_BGT (word 0x1fffe4) *) 0x4e284806; (* arm_AESE Q6 Q0 *) 0x4e2868c6; (* arm_AESMC Q6 Q6 *) 0x4c407880; (* arm_LDR Q0 X4 No_Offset *) 0x4e284826; (* arm_AESE Q6 Q1 *) - 0x6e201cc6; (* arm_EOR_VEC Q6 Q6 Q0 128 *) - 0x9e6600c9; (* arm_FMOV_FtoI X9 Q6 0 64 *) - 0x9eae00ca; (* arm_FMOV_FtoI X10 Q6 1 64 *) - 0x528010f3; (* arm_MOV W19 (rvalue (word 135)) *) - 0x93ca8156; (* arm_ROR X22 X10 32 *) - 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) - 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 31) *) - 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 1) *) - 0x9e670128; (* arm_FMOV_ItoF Q8 X9 0 *) - 0x9eaf0148; (* arm_FMOV_ItoF Q8 X10 1 *) + 0x6e201cc6; (* arm_EOR_VEC Q6 Q6 Q0 0x80 *) + 0x9e6600c9; (* arm_FMOV_FtoI X9 Q6 0x0 0x40 *) + 0x9eae00ca; (* arm_FMOV_FtoI X10 Q6 0x1 0x40 *) + 0x528010f3; (* arm_MOV W19 (rvalue (word 0x87)) *) + 0x93ca8156; (* arm_ROR X22 X10 0x20 *) + 0x93c9fd4a; (* arm_EXTR X10 X10 X9 0x3f *) + 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 0x1f) *) + 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 0x1) *) + 0x9e670128; (* arm_FMOV_ItoF Q8 X9 0x0 *) + 0x9eaf0148; (* arm_FMOV_ItoF Q8 X10 0x1 *) 0xaa0303e7; (* arm_MOV X7 X3 *) - 0x4cdfa8f0; (* arm_LDP Q16 Q17 X7 (Postimmediate_Offset (word 32)) *) - 0x4cdfa8ec; (* arm_LDP Q12 Q13 X7 (Postimmediate_Offset (word 32)) *) - 0x4cdfa8ee; (* arm_LDP Q14 Q15 X7 (Postimmediate_Offset (word 32)) *) - 0x4cdfa8e4; (* arm_LDP Q4 Q5 X7 (Postimmediate_Offset (word 32)) *) - 0x4cdfa8f2; (* arm_LDP Q18 Q19 X7 (Postimmediate_Offset (word 32)) *) - 0x4cdfa8f4; (* arm_LDP Q20 Q21 X7 (Postimmediate_Offset (word 32)) *) - 0x4cdfa8f6; (* arm_LDP Q22 Q23 X7 (Postimmediate_Offset (word 32)) *) + 0x4cdfa8f0; (* arm_LDP Q16 Q17 X7 (Postimmediate_Offset (word 0x20)) *) + 0x4cdfa8ec; (* arm_LDP Q12 Q13 X7 (Postimmediate_Offset (word 0x20)) *) + 0x4cdfa8ee; (* arm_LDP Q14 Q15 X7 (Postimmediate_Offset (word 0x20)) *) + 0x4cdfa8e4; (* arm_LDP Q4 Q5 X7 (Postimmediate_Offset (word 0x20)) *) + 0x4cdfa8f2; (* arm_LDP Q18 Q19 X7 (Postimmediate_Offset (word 0x20)) *) + 0x4cdfa8f4; (* arm_LDP Q20 Q21 X7 (Postimmediate_Offset (word 0x20)) *) + 0x4cdfa8f6; (* arm_LDP Q22 Q23 X7 (Postimmediate_Offset (word 0x20)) *) 0x4c4078e7; (* arm_LDR Q7 X7 No_Offset *) - 0xf100805f; (* arm_CMP X2 (rvalue (word 32)) *) - 0x54004943; (* arm_BCC (word 2344) *) - 0xf100c05f; (* arm_CMP X2 (rvalue (word 48)) *) - 0x54004063; (* arm_BCC (word 2060) *) - 0x93ca8156; (* arm_ROR X22 X10 32 *) - 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) - 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 31) *) - 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 1) *) - 0x9e670129; (* arm_FMOV_ItoF Q9 X9 0 *) - 0x9eaf0149; (* arm_FMOV_ItoF Q9 X10 1 *) - 0xf101005f; (* arm_CMP X2 (rvalue (word 64)) *) - 0x54003383; (* arm_BCC (word 1648) *) - 0x93ca8156; (* arm_ROR X22 X10 32 *) - 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) - 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 31) *) - 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 1) *) - 0x9e67012a; (* arm_FMOV_ItoF Q10 X9 0 *) - 0x9eaf014a; (* arm_FMOV_ItoF Q10 X10 1 *) - 0xf101405f; (* arm_CMP X2 (rvalue (word 80)) *) - 0x54002283; (* arm_BCC (word 1104) *) - 0x93ca8156; (* arm_ROR X22 X10 32 *) - 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) - 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 31) *) - 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 1) *) - 0x9e67012b; (* arm_FMOV_ItoF Q11 X9 0 *) - 0x9eaf014b; (* arm_FMOV_ItoF Q11 X10 1 *) - 0xacc28400; (* arm_LDP Q0 Q1 X0 (Postimmediate_Offset (iword (&80))) *) - 0xad7ee418; (* arm_LDP Q24 Q25 X0 (Immediate_Offset (iword (-- &48))) *) - 0x3cdf001a; (* arm_LDR Q26 X0 (Immediate_Offset (word 18446744073709551600)) *) - 0x6e261c00; (* arm_EOR_VEC Q0 Q0 Q6 128 *) - 0x6e281c21; (* arm_EOR_VEC Q1 Q1 Q8 128 *) - 0x6e291f18; (* arm_EOR_VEC Q24 Q24 Q9 128 *) - 0x6e2a1f39; (* arm_EOR_VEC Q25 Q25 Q10 128 *) - 0x6e2b1f5a; (* arm_EOR_VEC Q26 Q26 Q11 128 *) + 0xf100805f; (* arm_CMP X2 (rvalue (word 0x20)) *) + 0x540042e3; (* arm_BCC (word 0x85c) *) + 0xf100c05f; (* arm_CMP X2 (rvalue (word 0x30)) *) + 0x540039c3; (* arm_BCC (word 0x738) *) + 0x93ca8156; (* arm_ROR X22 X10 0x20 *) + 0x93c9fd4a; (* arm_EXTR X10 X10 X9 0x3f *) + 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 0x1f) *) + 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 0x1) *) + 0x9e670129; (* arm_FMOV_ItoF Q9 X9 0x0 *) + 0x9eaf0149; (* arm_FMOV_ItoF Q9 X10 0x1 *) + 0xf101005f; (* arm_CMP X2 (rvalue (word 0x40)) *) + 0x54002be3; (* arm_BCC (word 0x57c) *) + 0x93ca8156; (* arm_ROR X22 X10 0x20 *) + 0x93c9fd4a; (* arm_EXTR X10 X10 X9 0x3f *) + 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 0x1f) *) + 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 0x1) *) + 0x9e67012a; (* arm_FMOV_ItoF Q10 X9 0x0 *) + 0x9eaf014a; (* arm_FMOV_ItoF Q10 X10 0x1 *) + 0xf101405f; (* arm_CMP X2 (rvalue (word 0x50)) *) + 0x540019e3; (* arm_BCC (word 0x33c) *) + 0x93ca8156; (* arm_ROR X22 X10 0x20 *) + 0x93c9fd4a; (* arm_EXTR X10 X10 X9 0x3f *) + 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 0x1f) *) + 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 0x1) *) + 0x9e67012b; (* arm_FMOV_ItoF Q11 X9 0x0 *) + 0x9eaf014b; (* arm_FMOV_ItoF Q11 X10 0x1 *) + 0xacc28400; (* arm_LDP Q0 Q1 X0 (Postimmediate_Offset (iword (&0x50))) *) + 0xad7ee418; (* arm_LDP Q24 Q25 X0 (Immediate_Offset (iword (-- &0x30))) *) + 0x3cdf001a; (* arm_LDR Q26 X0 (Immediate_Offset (word 0xfffffffffffffff0)) *) + 0x6e261c00; (* arm_EOR_VEC Q0 Q0 Q6 0x80 *) + 0x6e281c21; (* arm_EOR_VEC Q1 Q1 Q8 0x80 *) + 0x6e291f18; (* arm_EOR_VEC Q24 Q24 Q9 0x80 *) + 0x6e2a1f39; (* arm_EOR_VEC Q25 Q25 Q10 0x80 *) + 0x6e2b1f5a; (* arm_EOR_VEC Q26 Q26 Q11 0x80 *) 0x4e284a00; (* arm_AESE Q0 Q16 *) 0x4e286800; (* arm_AESMC Q0 Q0 *) 0x4e284a01; (* arm_AESE Q1 Q16 *) @@ -218,71 +218,71 @@ 0x4e284af8; (* arm_AESE Q24 Q23 *) 0x4e284af9; (* arm_AESE Q25 Q23 *) 0x4e284afa; (* arm_AESE Q26 Q23 *) - 0x6e271c00; (* arm_EOR_VEC Q0 Q0 Q7 128 *) - 0x6e261c00; (* arm_EOR_VEC Q0 Q0 Q6 128 *) - 0x93ca8156; (* arm_ROR X22 X10 32 *) - 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) - 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 31) *) - 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 1) *) - 0x9e670126; (* arm_FMOV_ItoF Q6 X9 0 *) - 0x9eaf0146; (* arm_FMOV_ItoF Q6 X10 1 *) - 0x6e271c21; (* arm_EOR_VEC Q1 Q1 Q7 128 *) - 0x6e281c21; (* arm_EOR_VEC Q1 Q1 Q8 128 *) - 0x93ca8156; (* arm_ROR X22 X10 32 *) - 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) - 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 31) *) - 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 1) *) - 0x9e670128; (* arm_FMOV_ItoF Q8 X9 0 *) - 0x9eaf0148; (* arm_FMOV_ItoF Q8 X10 1 *) - 0x6e271f18; (* arm_EOR_VEC Q24 Q24 Q7 128 *) - 0x6e291f18; (* arm_EOR_VEC Q24 Q24 Q9 128 *) - 0x93ca8156; (* arm_ROR X22 X10 32 *) - 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) - 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 31) *) - 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 1) *) - 0x9e670129; (* arm_FMOV_ItoF Q9 X9 0 *) - 0x9eaf0149; (* arm_FMOV_ItoF Q9 X10 1 *) - 0x6e271f39; (* arm_EOR_VEC Q25 Q25 Q7 128 *) - 0x6e2a1f39; (* arm_EOR_VEC Q25 Q25 Q10 128 *) - 0x93ca8156; (* arm_ROR X22 X10 32 *) - 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) - 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 31) *) - 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 1) *) - 0x9e67012a; (* arm_FMOV_ItoF Q10 X9 0 *) - 0x9eaf014a; (* arm_FMOV_ItoF Q10 X10 1 *) - 0x6e271f5a; (* arm_EOR_VEC Q26 Q26 Q7 128 *) - 0x6e2b1f5a; (* arm_EOR_VEC Q26 Q26 Q11 128 *) - 0x93ca8156; (* arm_ROR X22 X10 32 *) - 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) - 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 31) *) - 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 1) *) - 0x9e67012b; (* arm_FMOV_ItoF Q11 X9 0 *) - 0x9eaf014b; (* arm_FMOV_ItoF Q11 X10 1 *) - 0xac828420; (* arm_STP Q0 Q1 X1 (Postimmediate_Offset (iword (&80))) *) - 0xad3ee438; (* arm_STP Q24 Q25 X1 (Immediate_Offset (iword (-- &48))) *) - 0x3c9f003a; (* arm_STR Q26 X1 (Immediate_Offset (word 18446744073709551600)) *) - 0xf1014042; (* arm_SUBS X2 X2 (rvalue (word 80)) *) - 0xf101405f; (* arm_CMP X2 (rvalue (word 80)) *) - 0x54002143; (* arm_BCC (word 1064) *) - 0x54000982; (* arm_BCS (word 304) *) - 0xf100005f; (* arm_CMP X2 (rvalue (word 0)) *) - 0x54004f00; (* arm_BEQ (word 2528) *) - 0xf100405f; (* arm_CMP X2 (rvalue (word 16)) *) - 0x54004940; (* arm_BEQ (word 2344) *) - 0xf100805f; (* arm_CMP X2 (rvalue (word 32)) *) - 0x54004060; (* arm_BEQ (word 2060) *) - 0xf100c05f; (* arm_CMP X2 (rvalue (word 48)) *) - 0x54003380; (* arm_BEQ (word 1648) *) - 0xf101005f; (* arm_CMP X2 (rvalue (word 64)) *) - 0x54002280; (* arm_BEQ (word 1104) *) - 0x4cdf7000; (* arm_LDR Q0 X0 (Postimmediate_Offset (word 16)) *) - 0x4cdf7001; (* arm_LDR Q1 X0 (Postimmediate_Offset (word 16)) *) - 0x4cdf7018; (* arm_LDR Q24 X0 (Postimmediate_Offset (word 16)) *) - 0x4cdf7019; (* arm_LDR Q25 X0 (Postimmediate_Offset (word 16)) *) - 0x6e261c00; (* arm_EOR_VEC Q0 Q0 Q6 128 *) - 0x6e281c21; (* arm_EOR_VEC Q1 Q1 Q8 128 *) - 0x6e291f18; (* arm_EOR_VEC Q24 Q24 Q9 128 *) - 0x6e2a1f39; (* arm_EOR_VEC Q25 Q25 Q10 128 *) + 0x6e271c00; (* arm_EOR_VEC Q0 Q0 Q7 0x80 *) + 0x6e261c00; (* arm_EOR_VEC Q0 Q0 Q6 0x80 *) + 0x93ca8156; (* arm_ROR X22 X10 0x20 *) + 0x93c9fd4a; (* arm_EXTR X10 X10 X9 0x3f *) + 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 0x1f) *) + 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 0x1) *) + 0x9e670126; (* arm_FMOV_ItoF Q6 X9 0x0 *) + 0x9eaf0146; (* arm_FMOV_ItoF Q6 X10 0x1 *) + 0x6e271c21; (* arm_EOR_VEC Q1 Q1 Q7 0x80 *) + 0x6e281c21; (* arm_EOR_VEC Q1 Q1 Q8 0x80 *) + 0x93ca8156; (* arm_ROR X22 X10 0x20 *) + 0x93c9fd4a; (* arm_EXTR X10 X10 X9 0x3f *) + 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 0x1f) *) + 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 0x1) *) + 0x9e670128; (* arm_FMOV_ItoF Q8 X9 0x0 *) + 0x9eaf0148; (* arm_FMOV_ItoF Q8 X10 0x1 *) + 0x6e271f18; (* arm_EOR_VEC Q24 Q24 Q7 0x80 *) + 0x6e291f18; (* arm_EOR_VEC Q24 Q24 Q9 0x80 *) + 0x93ca8156; (* arm_ROR X22 X10 0x20 *) + 0x93c9fd4a; (* arm_EXTR X10 X10 X9 0x3f *) + 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 0x1f) *) + 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 0x1) *) + 0x9e670129; (* arm_FMOV_ItoF Q9 X9 0x0 *) + 0x9eaf0149; (* arm_FMOV_ItoF Q9 X10 0x1 *) + 0x6e271f39; (* arm_EOR_VEC Q25 Q25 Q7 0x80 *) + 0x6e2a1f39; (* arm_EOR_VEC Q25 Q25 Q10 0x80 *) + 0x93ca8156; (* arm_ROR X22 X10 0x20 *) + 0x93c9fd4a; (* arm_EXTR X10 X10 X9 0x3f *) + 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 0x1f) *) + 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 0x1) *) + 0x9e67012a; (* arm_FMOV_ItoF Q10 X9 0x0 *) + 0x9eaf014a; (* arm_FMOV_ItoF Q10 X10 0x1 *) + 0x6e271f5a; (* arm_EOR_VEC Q26 Q26 Q7 0x80 *) + 0x6e2b1f5a; (* arm_EOR_VEC Q26 Q26 Q11 0x80 *) + 0x93ca8156; (* arm_ROR X22 X10 0x20 *) + 0x93c9fd4a; (* arm_EXTR X10 X10 X9 0x3f *) + 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 0x1f) *) + 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 0x1) *) + 0x9e67012b; (* arm_FMOV_ItoF Q11 X9 0x0 *) + 0x9eaf014b; (* arm_FMOV_ItoF Q11 X10 0x1 *) + 0xac828420; (* arm_STP Q0 Q1 X1 (Postimmediate_Offset (iword (&0x50))) *) + 0xad3ee438; (* arm_STP Q24 Q25 X1 (Immediate_Offset (iword (-- &0x30))) *) + 0x3c9f003a; (* arm_STR Q26 X1 (Immediate_Offset (word 0xfffffffffffffff0)) *) + 0xf1014042; (* arm_SUBS X2 X2 (rvalue (word 0x50)) *) + 0xf101405f; (* arm_CMP X2 (rvalue (word 0x50)) *) + 0x54000043; (* arm_BCC (word 0x8) *) + 0x54ffe862; (* arm_BCS (word 0x1ffd0c) *) + 0xf100005f; (* arm_CMP X2 (rvalue (word 0x0)) *) + 0x54002da0; (* arm_BEQ (word 0x5b4) *) + 0xf100405f; (* arm_CMP X2 (rvalue (word 0x10)) *) + 0x540027a0; (* arm_BEQ (word 0x4f4) *) + 0xf100805f; (* arm_CMP X2 (rvalue (word 0x20)) *) + 0x54001e80; (* arm_BEQ (word 0x3d0) *) + 0xf100c05f; (* arm_CMP X2 (rvalue (word 0x30)) *) + 0x54001160; (* arm_BEQ (word 0x22c) *) + 0xf101005f; (* arm_CMP X2 (rvalue (word 0x40)) *) + 0x54000020; (* arm_BEQ (word 0x4) *) + 0x4cdf7000; (* arm_LDR Q0 X0 (Postimmediate_Offset (word 0x10)) *) + 0x4cdf7001; (* arm_LDR Q1 X0 (Postimmediate_Offset (word 0x10)) *) + 0x4cdf7018; (* arm_LDR Q24 X0 (Postimmediate_Offset (word 0x10)) *) + 0x4cdf7019; (* arm_LDR Q25 X0 (Postimmediate_Offset (word 0x10)) *) + 0x6e261c00; (* arm_EOR_VEC Q0 Q0 Q6 0x80 *) + 0x6e281c21; (* arm_EOR_VEC Q1 Q1 Q8 0x80 *) + 0x6e291f18; (* arm_EOR_VEC Q24 Q24 Q9 0x80 *) + 0x6e2a1f39; (* arm_EOR_VEC Q25 Q25 Q10 0x80 *) 0x4e284a00; (* arm_AESE Q0 Q16 *) 0x4e286800; (* arm_AESMC Q0 Q0 *) 0x4e284a01; (* arm_AESE Q1 Q16 *) @@ -391,31 +391,31 @@ 0x4e284ae1; (* arm_AESE Q1 Q23 *) 0x4e284af8; (* arm_AESE Q24 Q23 *) 0x4e284af9; (* arm_AESE Q25 Q23 *) - 0x6e271c00; (* arm_EOR_VEC Q0 Q0 Q7 128 *) - 0x6e261c00; (* arm_EOR_VEC Q0 Q0 Q6 128 *) - 0x6e271c21; (* arm_EOR_VEC Q1 Q1 Q7 128 *) - 0x6e281c21; (* arm_EOR_VEC Q1 Q1 Q8 128 *) - 0x6e271f18; (* arm_EOR_VEC Q24 Q24 Q7 128 *) - 0x6e291f18; (* arm_EOR_VEC Q24 Q24 Q9 128 *) - 0x6e271f39; (* arm_EOR_VEC Q25 Q25 Q7 128 *) - 0x6e2a1f39; (* arm_EOR_VEC Q25 Q25 Q10 128 *) - 0x4c9fa020; (* arm_STP Q0 Q1 X1 (Postimmediate_Offset (word 32)) *) - 0x4c9fa038; (* arm_STP Q24 Q25 X1 (Postimmediate_Offset (word 32)) *) - 0x9e660149; (* arm_FMOV_FtoI X9 Q10 0 64 *) - 0x9eae014a; (* arm_FMOV_FtoI X10 Q10 1 64 *) - 0x93ca8156; (* arm_ROR X22 X10 32 *) - 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) - 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 31) *) - 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 1) *) - 0x9e670126; (* arm_FMOV_ItoF Q6 X9 0 *) - 0x9eaf0146; (* arm_FMOV_ItoF Q6 X10 1 *) - 0x14000278; (* arm_B (word 2528) *) + 0x6e271c00; (* arm_EOR_VEC Q0 Q0 Q7 0x80 *) + 0x6e261c00; (* arm_EOR_VEC Q0 Q0 Q6 0x80 *) + 0x6e271c21; (* arm_EOR_VEC Q1 Q1 Q7 0x80 *) + 0x6e281c21; (* arm_EOR_VEC Q1 Q1 Q8 0x80 *) + 0x6e271f18; (* arm_EOR_VEC Q24 Q24 Q7 0x80 *) + 0x6e291f18; (* arm_EOR_VEC Q24 Q24 Q9 0x80 *) + 0x6e271f39; (* arm_EOR_VEC Q25 Q25 Q7 0x80 *) + 0x6e2a1f39; (* arm_EOR_VEC Q25 Q25 Q10 0x80 *) + 0x4c9fa020; (* arm_STP Q0 Q1 X1 (Postimmediate_Offset (word 0x20)) *) + 0x4c9fa038; (* arm_STP Q24 Q25 X1 (Postimmediate_Offset (word 0x20)) *) + 0x9e660149; (* arm_FMOV_FtoI X9 Q10 0x0 0x40 *) + 0x9eae014a; (* arm_FMOV_FtoI X10 Q10 0x1 0x40 *) + 0x93ca8156; (* arm_ROR X22 X10 0x20 *) + 0x93c9fd4a; (* arm_EXTR X10 X10 X9 0x3f *) + 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 0x1f) *) + 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 0x1) *) + 0x9e670126; (* arm_FMOV_ItoF Q6 X9 0x0 *) + 0x9eaf0146; (* arm_FMOV_ItoF Q6 X10 0x1 *) + 0x140000de; (* arm_B (word 0x378) *) 0xd503201f; (* arm_NOP *) - 0x4cdfa000; (* arm_LDP Q0 Q1 X0 (Postimmediate_Offset (word 32)) *) - 0x4cdf7018; (* arm_LDR Q24 X0 (Postimmediate_Offset (word 16)) *) - 0x6e261c00; (* arm_EOR_VEC Q0 Q0 Q6 128 *) - 0x6e281c21; (* arm_EOR_VEC Q1 Q1 Q8 128 *) - 0x6e291f18; (* arm_EOR_VEC Q24 Q24 Q9 128 *) + 0x4cdfa000; (* arm_LDP Q0 Q1 X0 (Postimmediate_Offset (word 0x20)) *) + 0x4cdf7018; (* arm_LDR Q24 X0 (Postimmediate_Offset (word 0x10)) *) + 0x6e261c00; (* arm_EOR_VEC Q0 Q0 Q6 0x80 *) + 0x6e281c21; (* arm_EOR_VEC Q1 Q1 Q8 0x80 *) + 0x6e291f18; (* arm_EOR_VEC Q24 Q24 Q9 0x80 *) 0x4e284a00; (* arm_AESE Q0 Q16 *) 0x4e286800; (* arm_AESMC Q0 Q0 *) 0x4e284a01; (* arm_AESE Q1 Q16 *) @@ -497,26 +497,26 @@ 0x4e284ae0; (* arm_AESE Q0 Q23 *) 0x4e284ae1; (* arm_AESE Q1 Q23 *) 0x4e284af8; (* arm_AESE Q24 Q23 *) - 0x6e271c00; (* arm_EOR_VEC Q0 Q0 Q7 128 *) - 0x6e261c00; (* arm_EOR_VEC Q0 Q0 Q6 128 *) - 0x6e271c21; (* arm_EOR_VEC Q1 Q1 Q7 128 *) - 0x6e281c21; (* arm_EOR_VEC Q1 Q1 Q8 128 *) - 0x6e271f18; (* arm_EOR_VEC Q24 Q24 Q7 128 *) - 0x6e291f18; (* arm_EOR_VEC Q24 Q24 Q9 128 *) - 0x4c9fa020; (* arm_STP Q0 Q1 X1 (Postimmediate_Offset (word 32)) *) - 0x4c9f7038; (* arm_STR Q24 X1 (Postimmediate_Offset (word 16)) *) - 0x9e660129; (* arm_FMOV_FtoI X9 Q9 0 64 *) - 0x9eae012a; (* arm_FMOV_FtoI X10 Q9 1 64 *) - 0x93ca8156; (* arm_ROR X22 X10 32 *) - 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) - 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 31) *) - 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 1) *) - 0x9e670126; (* arm_FMOV_ItoF Q6 X9 0 *) - 0x9eaf0146; (* arm_FMOV_ItoF Q6 X10 1 *) - 0x14000278; (* arm_B (word 2528) *) - 0x4cdfa000; (* arm_LDP Q0 Q1 X0 (Postimmediate_Offset (word 32)) *) - 0x6e261c00; (* arm_EOR_VEC Q0 Q0 Q6 128 *) - 0x6e281c21; (* arm_EOR_VEC Q1 Q1 Q8 128 *) + 0x6e271c00; (* arm_EOR_VEC Q0 Q0 Q7 0x80 *) + 0x6e261c00; (* arm_EOR_VEC Q0 Q0 Q6 0x80 *) + 0x6e271c21; (* arm_EOR_VEC Q1 Q1 Q7 0x80 *) + 0x6e281c21; (* arm_EOR_VEC Q1 Q1 Q8 0x80 *) + 0x6e271f18; (* arm_EOR_VEC Q24 Q24 Q7 0x80 *) + 0x6e291f18; (* arm_EOR_VEC Q24 Q24 Q9 0x80 *) + 0x4c9fa020; (* arm_STP Q0 Q1 X1 (Postimmediate_Offset (word 0x20)) *) + 0x4c9f7038; (* arm_STR Q24 X1 (Postimmediate_Offset (word 0x10)) *) + 0x9e660129; (* arm_FMOV_FtoI X9 Q9 0x0 0x40 *) + 0x9eae012a; (* arm_FMOV_FtoI X10 Q9 0x1 0x40 *) + 0x93ca8156; (* arm_ROR X22 X10 0x20 *) + 0x93c9fd4a; (* arm_EXTR X10 X10 X9 0x3f *) + 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 0x1f) *) + 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 0x1) *) + 0x9e670126; (* arm_FMOV_ItoF Q6 X9 0x0 *) + 0x9eaf0146; (* arm_FMOV_ItoF Q6 X10 0x1 *) + 0x14000076; (* arm_B (word 0x1d8) *) + 0x4cdfa000; (* arm_LDP Q0 Q1 X0 (Postimmediate_Offset (word 0x20)) *) + 0x6e261c00; (* arm_EOR_VEC Q0 Q0 Q6 0x80 *) + 0x6e281c21; (* arm_EOR_VEC Q1 Q1 Q8 0x80 *) 0x4e284a00; (* arm_AESE Q0 Q16 *) 0x4e286800; (* arm_AESMC Q0 Q0 *) 0x4e284a01; (* arm_AESE Q1 Q16 *) @@ -571,22 +571,22 @@ 0x4e286821; (* arm_AESMC Q1 Q1 *) 0x4e284ae0; (* arm_AESE Q0 Q23 *) 0x4e284ae1; (* arm_AESE Q1 Q23 *) - 0x6e271c00; (* arm_EOR_VEC Q0 Q0 Q7 128 *) - 0x6e261c00; (* arm_EOR_VEC Q0 Q0 Q6 128 *) - 0x6e271c21; (* arm_EOR_VEC Q1 Q1 Q7 128 *) - 0x6e281c21; (* arm_EOR_VEC Q1 Q1 Q8 128 *) - 0x4c9fa020; (* arm_STP Q0 Q1 X1 (Postimmediate_Offset (word 32)) *) - 0x9e660109; (* arm_FMOV_FtoI X9 Q8 0 64 *) - 0x9eae010a; (* arm_FMOV_FtoI X10 Q8 1 64 *) - 0x93ca8156; (* arm_ROR X22 X10 32 *) - 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) - 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 31) *) - 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 1) *) - 0x9e670126; (* arm_FMOV_ItoF Q6 X9 0 *) - 0x9eaf0146; (* arm_FMOV_ItoF Q6 X10 1 *) - 0x14000278; (* arm_B (word 2528) *) - 0x4cdf7000; (* arm_LDR Q0 X0 (Postimmediate_Offset (word 16)) *) - 0x6e261c00; (* arm_EOR_VEC Q0 Q0 Q6 128 *) + 0x6e271c00; (* arm_EOR_VEC Q0 Q0 Q7 0x80 *) + 0x6e261c00; (* arm_EOR_VEC Q0 Q0 Q6 0x80 *) + 0x6e271c21; (* arm_EOR_VEC Q1 Q1 Q7 0x80 *) + 0x6e281c21; (* arm_EOR_VEC Q1 Q1 Q8 0x80 *) + 0x4c9fa020; (* arm_STP Q0 Q1 X1 (Postimmediate_Offset (word 0x20)) *) + 0x9e660109; (* arm_FMOV_FtoI X9 Q8 0x0 0x40 *) + 0x9eae010a; (* arm_FMOV_FtoI X10 Q8 0x1 0x40 *) + 0x93ca8156; (* arm_ROR X22 X10 0x20 *) + 0x93c9fd4a; (* arm_EXTR X10 X10 X9 0x3f *) + 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 0x1f) *) + 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 0x1) *) + 0x9e670126; (* arm_FMOV_ItoF Q6 X9 0x0 *) + 0x9eaf0146; (* arm_FMOV_ItoF Q6 X10 0x1 *) + 0x1400002f; (* arm_B (word 0xbc) *) + 0x4cdf7000; (* arm_LDR Q0 X0 (Postimmediate_Offset (word 0x10)) *) + 0x6e261c00; (* arm_EOR_VEC Q0 Q0 Q6 0x80 *) 0x4e284a00; (* arm_AESE Q0 Q16 *) 0x4e286800; (* arm_AESMC Q0 Q0 *) 0x4e284a20; (* arm_AESE Q0 Q17 *) @@ -614,61 +614,61 @@ 0x4e284ac0; (* arm_AESE Q0 Q22 *) 0x4e286800; (* arm_AESMC Q0 Q0 *) 0x4e284ae0; (* arm_AESE Q0 Q23 *) - 0x6e271c00; (* arm_EOR_VEC Q0 Q0 Q7 128 *) - 0x6e261c00; (* arm_EOR_VEC Q0 Q0 Q6 128 *) - 0x4c9f7020; (* arm_STR Q0 X1 (Postimmediate_Offset (word 16)) *) - 0x9e6600c9; (* arm_FMOV_FtoI X9 Q6 0 64 *) - 0x9eae00ca; (* arm_FMOV_FtoI X10 Q6 1 64 *) - 0x93ca8156; (* arm_ROR X22 X10 32 *) - 0x93c9fd4a; (* arm_EXTR X10 X10 X9 63 *) - 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 31) *) - 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 1) *) - 0x9e670126; (* arm_FMOV_ItoF Q6 X9 0 *) - 0x9eaf0146; (* arm_FMOV_ItoF Q6 X10 1 *) - 0x14000278; (* arm_B (word 2528) *) + 0x6e271c00; (* arm_EOR_VEC Q0 Q0 Q7 0x80 *) + 0x6e261c00; (* arm_EOR_VEC Q0 Q0 Q6 0x80 *) + 0x4c9f7020; (* arm_STR Q0 X1 (Postimmediate_Offset (word 0x10)) *) + 0x9e6600c9; (* arm_FMOV_FtoI X9 Q6 0x0 0x40 *) + 0x9eae00ca; (* arm_FMOV_FtoI X10 Q6 0x1 0x40 *) + 0x93ca8156; (* arm_ROR X22 X10 0x20 *) + 0x93c9fd4a; (* arm_EXTR X10 X10 X9 0x3f *) + 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 0x1f) *) + 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 0x1) *) + 0x9e670126; (* arm_FMOV_ItoF Q6 X9 0x0 *) + 0x9eaf0146; (* arm_FMOV_ItoF Q6 X10 0x1 *) + 0x14000006; (* arm_B (word 0x18) *) 0xd503201f; (* arm_NOP *) 0xd503201f; (* arm_NOP *) 0xd503201f; (* arm_NOP *) 0xd503201f; (* arm_NOP *) 0xd503201f; (* arm_NOP *) - 0xf2400ebf; (* arm_TST X21 (rvalue (word 15)) *) - 0x54005300; (* arm_BEQ (word 2656) *) + 0xf2400ebf; (* arm_TST X21 (rvalue (word 0xf)) *) + 0x540003e0; (* arm_BEQ (word 0x7c) *) 0xaa0003f4; (* arm_MOV X20 X0 *) 0xaa0103ed; (* arm_MOV X13 X1 *) - 0xd1004021; (* arm_SUB X1 X1 (rvalue (word 16)) *) - 0xf10006b5; (* arm_SUBS X21 X21 (rvalue (word 1)) *) + 0xd1004021; (* arm_SUB X1 X1 (rvalue (word 0x10)) *) + 0xf10006b5; (* arm_SUBS X21 X21 (rvalue (word 0x1)) *) 0x3875682f; (* arm_LDRB W15 X1 (Register_Offset X21) *) 0x38756a8e; (* arm_LDRB W14 X20 (Register_Offset X21) *) 0x383569af; (* arm_STRB W15 X13 (Register_Offset X21) *) 0x3835682e; (* arm_STRB W14 X1 (Register_Offset X21) *) - 0x54ffff6c; (* arm_BGT (word 2097132) *) + 0x54ffff6c; (* arm_BGT (word 0x1fffec) *) 0x4c40703a; (* arm_LDR Q26 X1 No_Offset *) - 0x6e261f5a; (* arm_EOR_VEC Q26 Q26 Q6 128 *) - 0xb940f066; (* arm_LDR W6 X3 (Immediate_Offset (word 240)) *) - 0x4cdf7060; (* arm_LDR Q0 X3 (Postimmediate_Offset (word 16)) *) - 0x510008c6; (* arm_SUB W6 W6 (rvalue (word 2)) *) - 0x4cdf7061; (* arm_LDR Q1 X3 (Postimmediate_Offset (word 16)) *) + 0x6e261f5a; (* arm_EOR_VEC Q26 Q26 Q6 0x80 *) + 0xb940f066; (* arm_LDR W6 X3 (Immediate_Offset (word 0xf0)) *) + 0x4cdf7060; (* arm_LDR Q0 X3 (Postimmediate_Offset (word 0x10)) *) + 0x510008c6; (* arm_SUB W6 W6 (rvalue (word 0x2)) *) + 0x4cdf7061; (* arm_LDR Q1 X3 (Postimmediate_Offset (word 0x10)) *) 0x4e28481a; (* arm_AESE Q26 Q0 *) 0x4e286b5a; (* arm_AESMC Q26 Q26 *) - 0x4cdf7860; (* arm_LDR Q0 X3 (Postimmediate_Offset (word 16)) *) - 0x710008c6; (* arm_SUBS W6 W6 (rvalue (word 2)) *) + 0x4cdf7860; (* arm_LDR Q0 X3 (Postimmediate_Offset (word 0x10)) *) + 0x710008c6; (* arm_SUBS W6 W6 (rvalue (word 0x2)) *) 0x4e28483a; (* arm_AESE Q26 Q1 *) 0x4e286b5a; (* arm_AESMC Q26 Q26 *) - 0x4cdf7861; (* arm_LDR Q1 X3 (Postimmediate_Offset (word 16)) *) - 0x5400512c; (* arm_BGT (word 2596) *) + 0x4cdf7861; (* arm_LDR Q1 X3 (Postimmediate_Offset (word 0x10)) *) + 0x54ffff2c; (* arm_BGT (word 0x1fffe4) *) 0x4e28481a; (* arm_AESE Q26 Q0 *) 0x4e286b5a; (* arm_AESMC Q26 Q26 *) 0x4c407860; (* arm_LDR Q0 X3 No_Offset *) 0x4e28483a; (* arm_AESE Q26 Q1 *) - 0x6e201f5a; (* arm_EOR_VEC Q26 Q26 Q0 128 *) - 0x6e261f5a; (* arm_EOR_VEC Q26 Q26 Q6 128 *) + 0x6e201f5a; (* arm_EOR_VEC Q26 Q26 Q0 0x80 *) + 0x6e261f5a; (* arm_EOR_VEC Q26 Q26 Q6 0x80 *) 0x4c00703a; (* arm_STR Q26 X1 No_Offset *) - 0xa94453f3; (* arm_LDP X19 X20 SP (Immediate_Offset (iword (&64))) *) - 0xa9455bf5; (* arm_LDP X21 X22 SP (Immediate_Offset (iword (&80))) *) - 0x6d4027e8; (* arm_LDP D8 D9 SP (Immediate_Offset (iword (&0))) *) - 0x6d412fea; (* arm_LDP D10 D11 SP (Immediate_Offset (iword (&16))) *) - 0x6d4237ec; (* arm_LDP D12 D13 SP (Immediate_Offset (iword (&32))) *) - 0x6d433fee; (* arm_LDP D14 D15 SP (Immediate_Offset (iword (&48))) *) - 0x910183ff; (* arm_ADD SP SP (rvalue (word 96)) *) + 0xa94053f3; (* arm_LDP X19 X20 SP (Immediate_Offset (iword (&0x0))) *) + 0xa9415bf5; (* arm_LDP X21 X22 SP (Immediate_Offset (iword (&0x10))) *) + 0x6d4227e8; (* arm_LDP D8 D9 SP (Immediate_Offset (iword (&0x20))) *) + 0x6d432fea; (* arm_LDP D10 D11 SP (Immediate_Offset (iword (&0x30))) *) + 0x6d4437ec; (* arm_LDP D12 D13 SP (Immediate_Offset (iword (&0x40))) *) + 0x6d453fee; (* arm_LDP D14 D15 SP (Immediate_Offset (iword (&0x50))) *) + 0x910183ff; (* arm_ADD SP SP (rvalue (word 0x60)) *) 0xd65f03c0 (* arm_RET X30 *) ];; diff --git a/arm/proofs/aes-xts-armv8.ml b/arm/proofs/aes-xts-armv8.ml index cbba0da7d..82a760258 100644 --- a/arm/proofs/aes-xts-armv8.ml +++ b/arm/proofs/aes-xts-armv8.ml @@ -6,9 +6,11 @@ use_file_raise_failure := true;; needs "arm/proofs/base.ml";; +needs "arm/proofs/aes_encrypt_spec.ml";; +needs "arm/proofs/aes_xts_encrypt_spec.ml";; (* print_literal_from_elf "arm/aes-xts/aes-xts-armv8.o";; *) -save_literal_from_elf "arm/aes-xts/aes-xts-armv8.txt" "arm/aes-xts/aes-xts-armv8.o";; +(* save_literal_from_elf "arm/aes-xts/aes-xts-armv8.txt" "arm/aes-xts/aes-xts-armv8.o";;*) (* let aes_xts_armv8 = define_assert_from_elf "aes_xts_armv8" "arm/aes-xts/aes-xts-armv8.o" ..*) @@ -19,4 +21,1025 @@ d503201f f8: d503201f nop 4cc87000 198: 4cc87000 ld1.16b { v0 }, [x0], x8 4c40a870 19c: 4c40a870 ld1.4s { v16, v17 }, [x3] 3875682f 818: 3875682f ldrb w15, [x1, x21] -*) \ No newline at end of file +Also LDP/STP pre-index and post-index +*) + +let aes256_xts_encrypt_mc = define_assert_from_elf "aes256_xts_encrypt_mc" "arm/aes-xts/aes-xts-armv8.o" +[ + 0xd10183ff; (* arm_SUB SP SP (rvalue (word 0x60)) *) + 0x6d0227e8; (* arm_STP D8 D9 SP (Immediate_Offset (iword (&0x20))) *) + 0x6d032fea; (* arm_STP D10 D11 SP (Immediate_Offset (iword (&0x30))) *) + 0x6d0437ec; (* arm_STP D12 D13 SP (Immediate_Offset (iword (&0x40))) *) + 0x6d053fee; (* arm_STP D14 D15 SP (Immediate_Offset (iword (&0x50))) *) + 0xa90053f3; (* arm_STP X19 X20 SP (Immediate_Offset (iword (&0x0))) *) + 0xa9015bf5; (* arm_STP X21 X22 SP (Immediate_Offset (iword (&0x10))) *) + 0xf100405f; (* arm_CMP X2 (rvalue (word 0x10)) *) + 0x5400520b; (* arm_BLT (word 0xa40) *) + 0xd503201f; (* arm_NOP *) + 0xd503201f; (* arm_NOP *) + 0xd503201f; (* arm_NOP *) + + (* // Lxts_enc_big_size: *) + 0x92400c55; (* arm_AND X21 X2 (rvalue (word 0xf)) *) + 0x927cec42; (* arm_AND X2 X2 (rvalue (word 0xfffffffffffffff0)) *) + + (* // Firstly, encrypt the iv with key2 *) + 0xb940f086; (* arm_LDR W6 X4 (Immediate_Offset (word 0xf0)) *) + 0x4cdf7880; (* arm_LDR Q0 X4 (Postimmediate_Offset (word 0x10)) *) + 0x4c4070a6; (* arm_LDR Q6 X5 No_Offset *) + 0x510008c6; (* arm_SUB W6 W6 (rvalue (word 0x2)) *) + 0x4cdf7881; (* arm_LDR Q1 X4 (Postimmediate_Offset (word 0x10)) *) + 0x4e284806; (* arm_AESE Q6 Q0 *) + 0x4e2868c6; (* arm_AESMC Q6 Q6 *) + 0x4cdf7880; (* arm_LDR Q0 X4 (Postimmediate_Offset (word 0x10)) *) + 0x710008c6; (* arm_SUBS W6 W6 (rvalue (word 0x2)) *) + 0x4e284826; (* arm_AESE Q6 Q1 *) + 0x4e2868c6; (* arm_AESMC Q6 Q6 *) + 0x4cdf7881; (* arm_LDR Q1 X4 (Postimmediate_Offset (word 0x10)) *) + 0x54ffff2c; (* arm_BGT (word 0x1fffe4) *) + 0x4e284806; (* arm_AESE Q6 Q0 *) + 0x4e2868c6; (* arm_AESMC Q6 Q6 *) + 0x4c407880; (* arm_LDR Q0 X4 No_Offset *) + 0x4e284826; (* arm_AESE Q6 Q1 *) + 0x6e201cc6; (* arm_EOR_VEC Q6 Q6 Q0 0x80 *) + + (* iv for second block *) + (* pc + 0x80 *) + 0x9e6600c9; (* arm_FMOV_FtoI X9 Q6 0x0 0x40 *) + 0x9eae00ca; (* arm_FMOV_FtoI X10 Q6 0x1 0x40 *) + 0x528010f3; (* arm_MOV W19 (rvalue (word 0x87)) *) + 0x93ca8156; (* arm_ROR X22 X10 0x20 *) + 0x93c9fd4a; (* arm_EXTR X10 X10 X9 0x3f *) + 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 0x1f) *) + 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 0x1) *) + 0x9e670128; (* arm_FMOV_ItoF Q8 X9 0x0 *) + 0x9eaf0148; (* arm_FMOV_ItoF Q8 X10 0x1 *) + + (* Load key schedule *) + (* pc + 0xa4 *) + 0xaa0303e7; (* arm_MOV X7 X3 *) + 0x4cdfa8f0; (* arm_LDP Q16 Q17 X7 (Postimmediate_Offset (word 0x20)) *) + 0x4cdfa8ec; (* arm_LDP Q12 Q13 X7 (Postimmediate_Offset (word 0x20)) *) + 0x4cdfa8ee; (* arm_LDP Q14 Q15 X7 (Postimmediate_Offset (word 0x20)) *) + 0x4cdfa8e4; (* arm_LDP Q4 Q5 X7 (Postimmediate_Offset (word 0x20)) *) + 0x4cdfa8f2; (* arm_LDP Q18 Q19 X7 (Postimmediate_Offset (word 0x20)) *) + 0x4cdfa8f4; (* arm_LDP Q20 Q21 X7 (Postimmediate_Offset (word 0x20)) *) + 0x4cdfa8f6; (* arm_LDP Q22 Q23 X7 (Postimmediate_Offset (word 0x20)) *) + 0x4c4078e7; (* arm_LDR Q7 X7 No_Offset *) + + (* Lxts_enc: *) + (* pc + 0xc8 *) + 0xf100805f; (* arm_CMP X2 (rvalue (word 0x20)) *) + 0x540042e3; (* arm_BCC (word 0x85c) *) (* b.lo Lxts_enc_tail1x // when input = 1 with tail *) + + 0xf100c05f; (* arm_CMP X2 (rvalue (word 0x30)) *) + 0x540039c3; (* arm_BCC (word 0x738) *) + 0x93ca8156; (* arm_ROR X22 X10 0x20 *) + 0x93c9fd4a; (* arm_EXTR X10 X10 X9 0x3f *) + 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 0x1f) *) + 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 0x1) *) + 0x9e670129; (* arm_FMOV_ItoF Q9 X9 0x0 *) + 0x9eaf0149; (* arm_FMOV_ItoF Q9 X10 0x1 *) + 0xf101005f; (* arm_CMP X2 (rvalue (word 0x40)) *) + 0x54002be3; (* arm_BCC (word 0x57c) *) + 0x93ca8156; (* arm_ROR X22 X10 0x20 *) + 0x93c9fd4a; (* arm_EXTR X10 X10 X9 0x3f *) + 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 0x1f) *) + 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 0x1) *) + 0x9e67012a; (* arm_FMOV_ItoF Q10 X9 0x0 *) + 0x9eaf014a; (* arm_FMOV_ItoF Q10 X10 0x1 *) + 0xf101405f; (* arm_CMP X2 (rvalue (word 0x50)) *) + 0x540019e3; (* arm_BCC (word 0x33c) *) + 0x93ca8156; (* arm_ROR X22 X10 0x20 *) + 0x93c9fd4a; (* arm_EXTR X10 X10 X9 0x3f *) + 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 0x1f) *) + 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 0x1) *) + 0x9e67012b; (* arm_FMOV_ItoF Q11 X9 0x0 *) + 0x9eaf014b; (* arm_FMOV_ItoF Q11 X10 0x1 *) + 0xacc28400; (* arm_LDP Q0 Q1 X0 (Postimmediate_Offset (iword (&0x50))) *) + 0xad7ee418; (* arm_LDP Q24 Q25 X0 (Immediate_Offset (iword (-- &0x30))) *) + 0x3cdf001a; (* arm_LDR Q26 X0 (Immediate_Offset (word 0xfffffffffffffff0)) *) + 0x6e261c00; (* arm_EOR_VEC Q0 Q0 Q6 0x80 *) + 0x6e281c21; (* arm_EOR_VEC Q1 Q1 Q8 0x80 *) + 0x6e291f18; (* arm_EOR_VEC Q24 Q24 Q9 0x80 *) + 0x6e2a1f39; (* arm_EOR_VEC Q25 Q25 Q10 0x80 *) + 0x6e2b1f5a; (* arm_EOR_VEC Q26 Q26 Q11 0x80 *) + 0x4e284a00; (* arm_AESE Q0 Q16 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e284a01; (* arm_AESE Q1 Q16 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e284a18; (* arm_AESE Q24 Q16 *) + 0x4e286b18; (* arm_AESMC Q24 Q24 *) + 0x4e284a19; (* arm_AESE Q25 Q16 *) + 0x4e286b39; (* arm_AESMC Q25 Q25 *) + 0x4e284a1a; (* arm_AESE Q26 Q16 *) + 0x4e286b5a; (* arm_AESMC Q26 Q26 *) + 0x4e284a20; (* arm_AESE Q0 Q17 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e284a21; (* arm_AESE Q1 Q17 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e284a38; (* arm_AESE Q24 Q17 *) + 0x4e286b18; (* arm_AESMC Q24 Q24 *) + 0x4e284a39; (* arm_AESE Q25 Q17 *) + 0x4e286b39; (* arm_AESMC Q25 Q25 *) + 0x4e284a3a; (* arm_AESE Q26 Q17 *) + 0x4e286b5a; (* arm_AESMC Q26 Q26 *) + 0x4e284980; (* arm_AESE Q0 Q12 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e284981; (* arm_AESE Q1 Q12 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e284998; (* arm_AESE Q24 Q12 *) + 0x4e286b18; (* arm_AESMC Q24 Q24 *) + 0x4e284999; (* arm_AESE Q25 Q12 *) + 0x4e286b39; (* arm_AESMC Q25 Q25 *) + 0x4e28499a; (* arm_AESE Q26 Q12 *) + 0x4e286b5a; (* arm_AESMC Q26 Q26 *) + 0x4e2849a0; (* arm_AESE Q0 Q13 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e2849a1; (* arm_AESE Q1 Q13 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e2849b8; (* arm_AESE Q24 Q13 *) + 0x4e286b18; (* arm_AESMC Q24 Q24 *) + 0x4e2849b9; (* arm_AESE Q25 Q13 *) + 0x4e286b39; (* arm_AESMC Q25 Q25 *) + 0x4e2849ba; (* arm_AESE Q26 Q13 *) + 0x4e286b5a; (* arm_AESMC Q26 Q26 *) + 0x4e2849c0; (* arm_AESE Q0 Q14 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e2849c1; (* arm_AESE Q1 Q14 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e2849d8; (* arm_AESE Q24 Q14 *) + 0x4e286b18; (* arm_AESMC Q24 Q24 *) + 0x4e2849d9; (* arm_AESE Q25 Q14 *) + 0x4e286b39; (* arm_AESMC Q25 Q25 *) + 0x4e2849da; (* arm_AESE Q26 Q14 *) + 0x4e286b5a; (* arm_AESMC Q26 Q26 *) + 0x4e2849e0; (* arm_AESE Q0 Q15 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e2849e1; (* arm_AESE Q1 Q15 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e2849f8; (* arm_AESE Q24 Q15 *) + 0x4e286b18; (* arm_AESMC Q24 Q24 *) + 0x4e2849f9; (* arm_AESE Q25 Q15 *) + 0x4e286b39; (* arm_AESMC Q25 Q25 *) + 0x4e2849fa; (* arm_AESE Q26 Q15 *) + 0x4e286b5a; (* arm_AESMC Q26 Q26 *) + 0x4e284880; (* arm_AESE Q0 Q4 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e284881; (* arm_AESE Q1 Q4 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e284898; (* arm_AESE Q24 Q4 *) + 0x4e286b18; (* arm_AESMC Q24 Q24 *) + 0x4e284899; (* arm_AESE Q25 Q4 *) + 0x4e286b39; (* arm_AESMC Q25 Q25 *) + 0x4e28489a; (* arm_AESE Q26 Q4 *) + 0x4e286b5a; (* arm_AESMC Q26 Q26 *) + 0x4e2848a0; (* arm_AESE Q0 Q5 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e2848a1; (* arm_AESE Q1 Q5 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e2848b8; (* arm_AESE Q24 Q5 *) + 0x4e286b18; (* arm_AESMC Q24 Q24 *) + 0x4e2848b9; (* arm_AESE Q25 Q5 *) + 0x4e286b39; (* arm_AESMC Q25 Q25 *) + 0x4e2848ba; (* arm_AESE Q26 Q5 *) + 0x4e286b5a; (* arm_AESMC Q26 Q26 *) + 0x4e284a40; (* arm_AESE Q0 Q18 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e284a41; (* arm_AESE Q1 Q18 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e284a58; (* arm_AESE Q24 Q18 *) + 0x4e286b18; (* arm_AESMC Q24 Q24 *) + 0x4e284a59; (* arm_AESE Q25 Q18 *) + 0x4e286b39; (* arm_AESMC Q25 Q25 *) + 0x4e284a5a; (* arm_AESE Q26 Q18 *) + 0x4e286b5a; (* arm_AESMC Q26 Q26 *) + 0x4e284a60; (* arm_AESE Q0 Q19 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e284a61; (* arm_AESE Q1 Q19 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e284a78; (* arm_AESE Q24 Q19 *) + 0x4e286b18; (* arm_AESMC Q24 Q24 *) + 0x4e284a79; (* arm_AESE Q25 Q19 *) + 0x4e286b39; (* arm_AESMC Q25 Q25 *) + 0x4e284a7a; (* arm_AESE Q26 Q19 *) + 0x4e286b5a; (* arm_AESMC Q26 Q26 *) + 0x4e284a80; (* arm_AESE Q0 Q20 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e284a81; (* arm_AESE Q1 Q20 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e284a98; (* arm_AESE Q24 Q20 *) + 0x4e286b18; (* arm_AESMC Q24 Q24 *) + 0x4e284a99; (* arm_AESE Q25 Q20 *) + 0x4e286b39; (* arm_AESMC Q25 Q25 *) + 0x4e284a9a; (* arm_AESE Q26 Q20 *) + 0x4e286b5a; (* arm_AESMC Q26 Q26 *) + 0x4e284aa0; (* arm_AESE Q0 Q21 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e284aa1; (* arm_AESE Q1 Q21 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e284ab8; (* arm_AESE Q24 Q21 *) + 0x4e286b18; (* arm_AESMC Q24 Q24 *) + 0x4e284ab9; (* arm_AESE Q25 Q21 *) + 0x4e286b39; (* arm_AESMC Q25 Q25 *) + 0x4e284aba; (* arm_AESE Q26 Q21 *) + 0x4e286b5a; (* arm_AESMC Q26 Q26 *) + 0x4e284ac0; (* arm_AESE Q0 Q22 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e284ac1; (* arm_AESE Q1 Q22 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e284ad8; (* arm_AESE Q24 Q22 *) + 0x4e286b18; (* arm_AESMC Q24 Q24 *) + 0x4e284ad9; (* arm_AESE Q25 Q22 *) + 0x4e286b39; (* arm_AESMC Q25 Q25 *) + 0x4e284ada; (* arm_AESE Q26 Q22 *) + 0x4e286b5a; (* arm_AESMC Q26 Q26 *) + 0x4e284ae0; (* arm_AESE Q0 Q23 *) + 0x4e284ae1; (* arm_AESE Q1 Q23 *) + 0x4e284af8; (* arm_AESE Q24 Q23 *) + 0x4e284af9; (* arm_AESE Q25 Q23 *) + 0x4e284afa; (* arm_AESE Q26 Q23 *) + 0x6e271c00; (* arm_EOR_VEC Q0 Q0 Q7 0x80 *) + 0x6e261c00; (* arm_EOR_VEC Q0 Q0 Q6 0x80 *) + 0x93ca8156; (* arm_ROR X22 X10 0x20 *) + 0x93c9fd4a; (* arm_EXTR X10 X10 X9 0x3f *) + 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 0x1f) *) + 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 0x1) *) + 0x9e670126; (* arm_FMOV_ItoF Q6 X9 0x0 *) + 0x9eaf0146; (* arm_FMOV_ItoF Q6 X10 0x1 *) + 0x6e271c21; (* arm_EOR_VEC Q1 Q1 Q7 0x80 *) + 0x6e281c21; (* arm_EOR_VEC Q1 Q1 Q8 0x80 *) + 0x93ca8156; (* arm_ROR X22 X10 0x20 *) + 0x93c9fd4a; (* arm_EXTR X10 X10 X9 0x3f *) + 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 0x1f) *) + 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 0x1) *) + 0x9e670128; (* arm_FMOV_ItoF Q8 X9 0x0 *) + 0x9eaf0148; (* arm_FMOV_ItoF Q8 X10 0x1 *) + 0x6e271f18; (* arm_EOR_VEC Q24 Q24 Q7 0x80 *) + 0x6e291f18; (* arm_EOR_VEC Q24 Q24 Q9 0x80 *) + 0x93ca8156; (* arm_ROR X22 X10 0x20 *) + 0x93c9fd4a; (* arm_EXTR X10 X10 X9 0x3f *) + 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 0x1f) *) + 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 0x1) *) + 0x9e670129; (* arm_FMOV_ItoF Q9 X9 0x0 *) + 0x9eaf0149; (* arm_FMOV_ItoF Q9 X10 0x1 *) + 0x6e271f39; (* arm_EOR_VEC Q25 Q25 Q7 0x80 *) + 0x6e2a1f39; (* arm_EOR_VEC Q25 Q25 Q10 0x80 *) + 0x93ca8156; (* arm_ROR X22 X10 0x20 *) + 0x93c9fd4a; (* arm_EXTR X10 X10 X9 0x3f *) + 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 0x1f) *) + 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 0x1) *) + 0x9e67012a; (* arm_FMOV_ItoF Q10 X9 0x0 *) + 0x9eaf014a; (* arm_FMOV_ItoF Q10 X10 0x1 *) + 0x6e271f5a; (* arm_EOR_VEC Q26 Q26 Q7 0x80 *) + 0x6e2b1f5a; (* arm_EOR_VEC Q26 Q26 Q11 0x80 *) + 0x93ca8156; (* arm_ROR X22 X10 0x20 *) + 0x93c9fd4a; (* arm_EXTR X10 X10 X9 0x3f *) + 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 0x1f) *) + 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 0x1) *) + 0x9e67012b; (* arm_FMOV_ItoF Q11 X9 0x0 *) + 0x9eaf014b; (* arm_FMOV_ItoF Q11 X10 0x1 *) + 0xac828420; (* arm_STP Q0 Q1 X1 (Postimmediate_Offset (iword (&0x50))) *) + 0xad3ee438; (* arm_STP Q24 Q25 X1 (Immediate_Offset (iword (-- &0x30))) *) + 0x3c9f003a; (* arm_STR Q26 X1 (Immediate_Offset (word 0xfffffffffffffff0)) *) + 0xf1014042; (* arm_SUBS X2 X2 (rvalue (word 0x50)) *) + 0xf101405f; (* arm_CMP X2 (rvalue (word 0x50)) *) + 0x54000043; (* arm_BCC (word 0x8) *) + 0x54ffe862; (* arm_BCS (word 0x1ffd0c) *) + 0xf100005f; (* arm_CMP X2 (rvalue (word 0x0)) *) + 0x54002da0; (* arm_BEQ (word 0x5b4) *) + 0xf100405f; (* arm_CMP X2 (rvalue (word 0x10)) *) + 0x540027a0; (* arm_BEQ (word 0x4f4) *) + 0xf100805f; (* arm_CMP X2 (rvalue (word 0x20)) *) + 0x54001e80; (* arm_BEQ (word 0x3d0) *) + 0xf100c05f; (* arm_CMP X2 (rvalue (word 0x30)) *) + 0x54001160; (* arm_BEQ (word 0x22c) *) + 0xf101005f; (* arm_CMP X2 (rvalue (word 0x40)) *) + 0x54000020; (* arm_BEQ (word 0x4) *) + 0x4cdf7000; (* arm_LDR Q0 X0 (Postimmediate_Offset (word 0x10)) *) + 0x4cdf7001; (* arm_LDR Q1 X0 (Postimmediate_Offset (word 0x10)) *) + 0x4cdf7018; (* arm_LDR Q24 X0 (Postimmediate_Offset (word 0x10)) *) + 0x4cdf7019; (* arm_LDR Q25 X0 (Postimmediate_Offset (word 0x10)) *) + 0x6e261c00; (* arm_EOR_VEC Q0 Q0 Q6 0x80 *) + 0x6e281c21; (* arm_EOR_VEC Q1 Q1 Q8 0x80 *) + 0x6e291f18; (* arm_EOR_VEC Q24 Q24 Q9 0x80 *) + 0x6e2a1f39; (* arm_EOR_VEC Q25 Q25 Q10 0x80 *) + 0x4e284a00; (* arm_AESE Q0 Q16 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e284a01; (* arm_AESE Q1 Q16 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e284a18; (* arm_AESE Q24 Q16 *) + 0x4e286b18; (* arm_AESMC Q24 Q24 *) + 0x4e284a19; (* arm_AESE Q25 Q16 *) + 0x4e286b39; (* arm_AESMC Q25 Q25 *) + 0x4e284a20; (* arm_AESE Q0 Q17 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e284a21; (* arm_AESE Q1 Q17 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e284a38; (* arm_AESE Q24 Q17 *) + 0x4e286b18; (* arm_AESMC Q24 Q24 *) + 0x4e284a39; (* arm_AESE Q25 Q17 *) + 0x4e286b39; (* arm_AESMC Q25 Q25 *) + 0x4e284980; (* arm_AESE Q0 Q12 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e284981; (* arm_AESE Q1 Q12 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e284998; (* arm_AESE Q24 Q12 *) + 0x4e286b18; (* arm_AESMC Q24 Q24 *) + 0x4e284999; (* arm_AESE Q25 Q12 *) + 0x4e286b39; (* arm_AESMC Q25 Q25 *) + 0x4e2849a0; (* arm_AESE Q0 Q13 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e2849a1; (* arm_AESE Q1 Q13 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e2849b8; (* arm_AESE Q24 Q13 *) + 0x4e286b18; (* arm_AESMC Q24 Q24 *) + 0x4e2849b9; (* arm_AESE Q25 Q13 *) + 0x4e286b39; (* arm_AESMC Q25 Q25 *) + 0x4e2849c0; (* arm_AESE Q0 Q14 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e2849c1; (* arm_AESE Q1 Q14 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e2849d8; (* arm_AESE Q24 Q14 *) + 0x4e286b18; (* arm_AESMC Q24 Q24 *) + 0x4e2849d9; (* arm_AESE Q25 Q14 *) + 0x4e286b39; (* arm_AESMC Q25 Q25 *) + 0x4e2849e0; (* arm_AESE Q0 Q15 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e2849e1; (* arm_AESE Q1 Q15 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e2849f8; (* arm_AESE Q24 Q15 *) + 0x4e286b18; (* arm_AESMC Q24 Q24 *) + 0x4e2849f9; (* arm_AESE Q25 Q15 *) + 0x4e286b39; (* arm_AESMC Q25 Q25 *) + 0x4e284880; (* arm_AESE Q0 Q4 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e284881; (* arm_AESE Q1 Q4 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e284898; (* arm_AESE Q24 Q4 *) + 0x4e286b18; (* arm_AESMC Q24 Q24 *) + 0x4e284899; (* arm_AESE Q25 Q4 *) + 0x4e286b39; (* arm_AESMC Q25 Q25 *) + 0x4e2848a0; (* arm_AESE Q0 Q5 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e2848a1; (* arm_AESE Q1 Q5 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e2848b8; (* arm_AESE Q24 Q5 *) + 0x4e286b18; (* arm_AESMC Q24 Q24 *) + 0x4e2848b9; (* arm_AESE Q25 Q5 *) + 0x4e286b39; (* arm_AESMC Q25 Q25 *) + 0x4e284a40; (* arm_AESE Q0 Q18 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e284a41; (* arm_AESE Q1 Q18 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e284a58; (* arm_AESE Q24 Q18 *) + 0x4e286b18; (* arm_AESMC Q24 Q24 *) + 0x4e284a59; (* arm_AESE Q25 Q18 *) + 0x4e286b39; (* arm_AESMC Q25 Q25 *) + 0x4e284a60; (* arm_AESE Q0 Q19 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e284a61; (* arm_AESE Q1 Q19 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e284a78; (* arm_AESE Q24 Q19 *) + 0x4e286b18; (* arm_AESMC Q24 Q24 *) + 0x4e284a79; (* arm_AESE Q25 Q19 *) + 0x4e286b39; (* arm_AESMC Q25 Q25 *) + 0x4e284a80; (* arm_AESE Q0 Q20 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e284a81; (* arm_AESE Q1 Q20 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e284a98; (* arm_AESE Q24 Q20 *) + 0x4e286b18; (* arm_AESMC Q24 Q24 *) + 0x4e284a99; (* arm_AESE Q25 Q20 *) + 0x4e286b39; (* arm_AESMC Q25 Q25 *) + 0x4e284aa0; (* arm_AESE Q0 Q21 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e284aa1; (* arm_AESE Q1 Q21 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e284ab8; (* arm_AESE Q24 Q21 *) + 0x4e286b18; (* arm_AESMC Q24 Q24 *) + 0x4e284ab9; (* arm_AESE Q25 Q21 *) + 0x4e286b39; (* arm_AESMC Q25 Q25 *) + 0x4e284ac0; (* arm_AESE Q0 Q22 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e284ac1; (* arm_AESE Q1 Q22 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e284ad8; (* arm_AESE Q24 Q22 *) + 0x4e286b18; (* arm_AESMC Q24 Q24 *) + 0x4e284ad9; (* arm_AESE Q25 Q22 *) + 0x4e286b39; (* arm_AESMC Q25 Q25 *) + 0x4e284ae0; (* arm_AESE Q0 Q23 *) + 0x4e284ae1; (* arm_AESE Q1 Q23 *) + 0x4e284af8; (* arm_AESE Q24 Q23 *) + 0x4e284af9; (* arm_AESE Q25 Q23 *) + 0x6e271c00; (* arm_EOR_VEC Q0 Q0 Q7 0x80 *) + 0x6e261c00; (* arm_EOR_VEC Q0 Q0 Q6 0x80 *) + 0x6e271c21; (* arm_EOR_VEC Q1 Q1 Q7 0x80 *) + 0x6e281c21; (* arm_EOR_VEC Q1 Q1 Q8 0x80 *) + 0x6e271f18; (* arm_EOR_VEC Q24 Q24 Q7 0x80 *) + 0x6e291f18; (* arm_EOR_VEC Q24 Q24 Q9 0x80 *) + 0x6e271f39; (* arm_EOR_VEC Q25 Q25 Q7 0x80 *) + 0x6e2a1f39; (* arm_EOR_VEC Q25 Q25 Q10 0x80 *) + 0x4c9fa020; (* arm_STP Q0 Q1 X1 (Postimmediate_Offset (word 0x20)) *) + 0x4c9fa038; (* arm_STP Q24 Q25 X1 (Postimmediate_Offset (word 0x20)) *) + 0x9e660149; (* arm_FMOV_FtoI X9 Q10 0x0 0x40 *) + 0x9eae014a; (* arm_FMOV_FtoI X10 Q10 0x1 0x40 *) + 0x93ca8156; (* arm_ROR X22 X10 0x20 *) + 0x93c9fd4a; (* arm_EXTR X10 X10 X9 0x3f *) + 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 0x1f) *) + 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 0x1) *) + 0x9e670126; (* arm_FMOV_ItoF Q6 X9 0x0 *) + 0x9eaf0146; (* arm_FMOV_ItoF Q6 X10 0x1 *) + 0x140000de; (* arm_B (word 0x378) *) + 0xd503201f; (* arm_NOP *) + 0x4cdfa000; (* arm_LDP Q0 Q1 X0 (Postimmediate_Offset (word 0x20)) *) + 0x4cdf7018; (* arm_LDR Q24 X0 (Postimmediate_Offset (word 0x10)) *) + 0x6e261c00; (* arm_EOR_VEC Q0 Q0 Q6 0x80 *) + 0x6e281c21; (* arm_EOR_VEC Q1 Q1 Q8 0x80 *) + 0x6e291f18; (* arm_EOR_VEC Q24 Q24 Q9 0x80 *) + 0x4e284a00; (* arm_AESE Q0 Q16 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e284a01; (* arm_AESE Q1 Q16 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e284a18; (* arm_AESE Q24 Q16 *) + 0x4e286b18; (* arm_AESMC Q24 Q24 *) + 0x4e284a20; (* arm_AESE Q0 Q17 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e284a21; (* arm_AESE Q1 Q17 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e284a38; (* arm_AESE Q24 Q17 *) + 0x4e286b18; (* arm_AESMC Q24 Q24 *) + 0x4e284980; (* arm_AESE Q0 Q12 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e284981; (* arm_AESE Q1 Q12 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e284998; (* arm_AESE Q24 Q12 *) + 0x4e286b18; (* arm_AESMC Q24 Q24 *) + 0x4e2849a0; (* arm_AESE Q0 Q13 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e2849a1; (* arm_AESE Q1 Q13 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e2849b8; (* arm_AESE Q24 Q13 *) + 0x4e286b18; (* arm_AESMC Q24 Q24 *) + 0x4e2849c0; (* arm_AESE Q0 Q14 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e2849c1; (* arm_AESE Q1 Q14 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e2849d8; (* arm_AESE Q24 Q14 *) + 0x4e286b18; (* arm_AESMC Q24 Q24 *) + 0x4e2849e0; (* arm_AESE Q0 Q15 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e2849e1; (* arm_AESE Q1 Q15 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e2849f8; (* arm_AESE Q24 Q15 *) + 0x4e286b18; (* arm_AESMC Q24 Q24 *) + 0x4e284880; (* arm_AESE Q0 Q4 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e284881; (* arm_AESE Q1 Q4 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e284898; (* arm_AESE Q24 Q4 *) + 0x4e286b18; (* arm_AESMC Q24 Q24 *) + 0x4e2848a0; (* arm_AESE Q0 Q5 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e2848a1; (* arm_AESE Q1 Q5 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e2848b8; (* arm_AESE Q24 Q5 *) + 0x4e286b18; (* arm_AESMC Q24 Q24 *) + 0x4e284a40; (* arm_AESE Q0 Q18 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e284a41; (* arm_AESE Q1 Q18 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e284a58; (* arm_AESE Q24 Q18 *) + 0x4e286b18; (* arm_AESMC Q24 Q24 *) + 0x4e284a60; (* arm_AESE Q0 Q19 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e284a61; (* arm_AESE Q1 Q19 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e284a78; (* arm_AESE Q24 Q19 *) + 0x4e286b18; (* arm_AESMC Q24 Q24 *) + 0x4e284a80; (* arm_AESE Q0 Q20 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e284a81; (* arm_AESE Q1 Q20 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e284a98; (* arm_AESE Q24 Q20 *) + 0x4e286b18; (* arm_AESMC Q24 Q24 *) + 0x4e284aa0; (* arm_AESE Q0 Q21 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e284aa1; (* arm_AESE Q1 Q21 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e284ab8; (* arm_AESE Q24 Q21 *) + 0x4e286b18; (* arm_AESMC Q24 Q24 *) + 0x4e284ac0; (* arm_AESE Q0 Q22 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e284ac1; (* arm_AESE Q1 Q22 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e284ad8; (* arm_AESE Q24 Q22 *) + 0x4e286b18; (* arm_AESMC Q24 Q24 *) + 0x4e284ae0; (* arm_AESE Q0 Q23 *) + 0x4e284ae1; (* arm_AESE Q1 Q23 *) + 0x4e284af8; (* arm_AESE Q24 Q23 *) + 0x6e271c00; (* arm_EOR_VEC Q0 Q0 Q7 0x80 *) + 0x6e261c00; (* arm_EOR_VEC Q0 Q0 Q6 0x80 *) + 0x6e271c21; (* arm_EOR_VEC Q1 Q1 Q7 0x80 *) + 0x6e281c21; (* arm_EOR_VEC Q1 Q1 Q8 0x80 *) + 0x6e271f18; (* arm_EOR_VEC Q24 Q24 Q7 0x80 *) + 0x6e291f18; (* arm_EOR_VEC Q24 Q24 Q9 0x80 *) + 0x4c9fa020; (* arm_STP Q0 Q1 X1 (Postimmediate_Offset (word 0x20)) *) + 0x4c9f7038; (* arm_STR Q24 X1 (Postimmediate_Offset (word 0x10)) *) + 0x9e660129; (* arm_FMOV_FtoI X9 Q9 0x0 0x40 *) + 0x9eae012a; (* arm_FMOV_FtoI X10 Q9 0x1 0x40 *) + 0x93ca8156; (* arm_ROR X22 X10 0x20 *) + 0x93c9fd4a; (* arm_EXTR X10 X10 X9 0x3f *) + 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 0x1f) *) + 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 0x1) *) + 0x9e670126; (* arm_FMOV_ItoF Q6 X9 0x0 *) + 0x9eaf0146; (* arm_FMOV_ItoF Q6 X10 0x1 *) + 0x14000076; (* arm_B (word 0x1d8) *) + 0x4cdfa000; (* arm_LDP Q0 Q1 X0 (Postimmediate_Offset (word 0x20)) *) + 0x6e261c00; (* arm_EOR_VEC Q0 Q0 Q6 0x80 *) + 0x6e281c21; (* arm_EOR_VEC Q1 Q1 Q8 0x80 *) + 0x4e284a00; (* arm_AESE Q0 Q16 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e284a01; (* arm_AESE Q1 Q16 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e284a20; (* arm_AESE Q0 Q17 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e284a21; (* arm_AESE Q1 Q17 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e284980; (* arm_AESE Q0 Q12 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e284981; (* arm_AESE Q1 Q12 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e2849a0; (* arm_AESE Q0 Q13 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e2849a1; (* arm_AESE Q1 Q13 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e2849c0; (* arm_AESE Q0 Q14 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e2849c1; (* arm_AESE Q1 Q14 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e2849e0; (* arm_AESE Q0 Q15 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e2849e1; (* arm_AESE Q1 Q15 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e284880; (* arm_AESE Q0 Q4 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e284881; (* arm_AESE Q1 Q4 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e2848a0; (* arm_AESE Q0 Q5 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e2848a1; (* arm_AESE Q1 Q5 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e284a40; (* arm_AESE Q0 Q18 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e284a41; (* arm_AESE Q1 Q18 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e284a60; (* arm_AESE Q0 Q19 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e284a61; (* arm_AESE Q1 Q19 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e284a80; (* arm_AESE Q0 Q20 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e284a81; (* arm_AESE Q1 Q20 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e284aa0; (* arm_AESE Q0 Q21 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e284aa1; (* arm_AESE Q1 Q21 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e284ac0; (* arm_AESE Q0 Q22 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e284ac1; (* arm_AESE Q1 Q22 *) + 0x4e286821; (* arm_AESMC Q1 Q1 *) + 0x4e284ae0; (* arm_AESE Q0 Q23 *) + 0x4e284ae1; (* arm_AESE Q1 Q23 *) + 0x6e271c00; (* arm_EOR_VEC Q0 Q0 Q7 0x80 *) + 0x6e261c00; (* arm_EOR_VEC Q0 Q0 Q6 0x80 *) + 0x6e271c21; (* arm_EOR_VEC Q1 Q1 Q7 0x80 *) + 0x6e281c21; (* arm_EOR_VEC Q1 Q1 Q8 0x80 *) + 0x4c9fa020; (* arm_STP Q0 Q1 X1 (Postimmediate_Offset (word 0x20)) *) + 0x9e660109; (* arm_FMOV_FtoI X9 Q8 0x0 0x40 *) + 0x9eae010a; (* arm_FMOV_FtoI X10 Q8 0x1 0x40 *) + 0x93ca8156; (* arm_ROR X22 X10 0x20 *) + 0x93c9fd4a; (* arm_EXTR X10 X10 X9 0x3f *) + 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 0x1f) *) + 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 0x1) *) + 0x9e670126; (* arm_FMOV_ItoF Q6 X9 0x0 *) + 0x9eaf0146; (* arm_FMOV_ItoF Q6 X10 0x1 *) + 0x1400002f; (* arm_B (word 0xbc) *) + + (* Lxts_enc_tail1x: *) + 0x4cdf7000; (* arm_LDR Q0 X0 (Postimmediate_Offset (word 0x10)) *) + 0x6e261c00; (* arm_EOR_VEC Q0 Q0 Q6 0x80 *) + 0x4e284a00; (* arm_AESE Q0 Q16 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e284a20; (* arm_AESE Q0 Q17 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e284980; (* arm_AESE Q0 Q12 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e2849a0; (* arm_AESE Q0 Q13 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e2849c0; (* arm_AESE Q0 Q14 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e2849e0; (* arm_AESE Q0 Q15 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e284880; (* arm_AESE Q0 Q4 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e2848a0; (* arm_AESE Q0 Q5 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e284a40; (* arm_AESE Q0 Q18 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e284a60; (* arm_AESE Q0 Q19 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e284a80; (* arm_AESE Q0 Q20 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e284aa0; (* arm_AESE Q0 Q21 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e284ac0; (* arm_AESE Q0 Q22 *) + 0x4e286800; (* arm_AESMC Q0 Q0 *) + 0x4e284ae0; (* arm_AESE Q0 Q23 *) + 0x6e271c00; (* arm_EOR_VEC Q0 Q0 Q7 0x80 *) + 0x6e261c00; (* arm_EOR_VEC Q0 Q0 Q6 0x80 *) + 0x4c9f7020; (* arm_STR Q0 X1 (Postimmediate_Offset (word 0x10)) *) + 0x9e6600c9; (* arm_FMOV_FtoI X9 Q6 0x0 0x40 *) + 0x9eae00ca; (* arm_FMOV_FtoI X10 Q6 0x1 0x40 *) + 0x93ca8156; (* arm_ROR X22 X10 0x20 *) + 0x93c9fd4a; (* arm_EXTR X10 X10 X9 0x3f *) + 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 0x1f) *) + 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 0x1) *) + 0x9e670126; (* arm_FMOV_ItoF Q6 X9 0x0 *) + 0x9eaf0146; (* arm_FMOV_ItoF Q6 X10 0x1 *) + 0x14000006; (* arm_B (word 0x18) *) + 0xd503201f; (* arm_NOP *) + 0xd503201f; (* arm_NOP *) + 0xd503201f; (* arm_NOP *) + 0xd503201f; (* arm_NOP *) + 0xd503201f; (* arm_NOP *) + + (* Lxts_enc_done: *) + 0xf2400ebf; (* arm_TST X21 (rvalue (word 0xf)) *) + 0x540003e0; (* arm_BEQ (word 0x7c) *) + 0xaa0003f4; (* arm_MOV X20 X0 *) + 0xaa0103ed; (* arm_MOV X13 X1 *) + 0xd1004021; (* arm_SUB X1 X1 (rvalue (word 0x10)) *) + 0xf10006b5; (* arm_SUBS X21 X21 (rvalue (word 0x1)) *) + 0x3875682f; (* arm_LDRB W15 X1 (Register_Offset X21) *) + 0x38756a8e; (* arm_LDRB W14 X20 (Register_Offset X21) *) + 0x383569af; (* arm_STRB W15 X13 (Register_Offset X21) *) + 0x3835682e; (* arm_STRB W14 X1 (Register_Offset X21) *) + 0x54ffff6c; (* arm_BGT (word 0x1fffec) *) + 0x4c40703a; (* arm_LDR Q26 X1 No_Offset *) + 0x6e261f5a; (* arm_EOR_VEC Q26 Q26 Q6 0x80 *) + 0xb940f066; (* arm_LDR W6 X3 (Immediate_Offset (word 0xf0)) *) + 0x4cdf7060; (* arm_LDR Q0 X3 (Postimmediate_Offset (word 0x10)) *) + 0x510008c6; (* arm_SUB W6 W6 (rvalue (word 0x2)) *) + 0x4cdf7061; (* arm_LDR Q1 X3 (Postimmediate_Offset (word 0x10)) *) + 0x4e28481a; (* arm_AESE Q26 Q0 *) + 0x4e286b5a; (* arm_AESMC Q26 Q26 *) + 0x4cdf7860; (* arm_LDR Q0 X3 (Postimmediate_Offset (word 0x10)) *) + 0x710008c6; (* arm_SUBS W6 W6 (rvalue (word 0x2)) *) + 0x4e28483a; (* arm_AESE Q26 Q1 *) + 0x4e286b5a; (* arm_AESMC Q26 Q26 *) + 0x4cdf7861; (* arm_LDR Q1 X3 (Postimmediate_Offset (word 0x10)) *) + 0x54ffff2c; (* arm_BGT (word 0x1fffe4) *) + 0x4e28481a; (* arm_AESE Q26 Q0 *) + 0x4e286b5a; (* arm_AESMC Q26 Q26 *) + 0x4c407860; (* arm_LDR Q0 X3 No_Offset *) + 0x4e28483a; (* arm_AESE Q26 Q1 *) + 0x6e201f5a; (* arm_EOR_VEC Q26 Q26 Q0 0x80 *) + 0x6e261f5a; (* arm_EOR_VEC Q26 Q26 Q6 0x80 *) + 0x4c00703a; (* arm_STR Q26 X1 No_Offset *) + 0xa94053f3; (* arm_LDP X19 X20 SP (Immediate_Offset (iword (&0x0))) *) + 0xa9415bf5; (* arm_LDP X21 X22 SP (Immediate_Offset (iword (&0x10))) *) + 0x6d4227e8; (* arm_LDP D8 D9 SP (Immediate_Offset (iword (&0x20))) *) + 0x6d432fea; (* arm_LDP D10 D11 SP (Immediate_Offset (iword (&0x30))) *) + 0x6d4437ec; (* arm_LDP D12 D13 SP (Immediate_Offset (iword (&0x40))) *) + 0x6d453fee; (* arm_LDP D14 D15 SP (Immediate_Offset (iword (&0x50))) *) + 0x910183ff; (* arm_ADD SP SP (rvalue (word 0x60)) *) + 0xd65f03c0 (* arm_RET X30 *) +];; + + +let AES256_XTS_ENCRYPT_EXEC = ARM_MK_EXEC_RULE aes256_xts_encrypt_mc;; + +let AESENC_TAC = + REWRITE_TAC [aes256_encrypt] THEN + REWRITE_TAC EL_15_128_CLAUSES THEN + REWRITE_TAC [aes256_encrypt_round; aese; aesmc] THEN + CONV_TAC (TOP_DEPTH_CONV let_CONV) THEN + BITBLAST_TAC;; + +let AESXTS_ENC_ONE_BLOCK_TAC = + REWRITE_TAC [aes256_xts_encrypt_one_block] THEN + CONV_TAC (TOP_DEPTH_CONV let_CONV) THEN + GEN_REWRITE_TAC LAND_CONV [WORD_XOR_SYM] THEN + REPEAT (AP_THM_TAC THEN AP_TERM_TAC) THEN + BITBLAST_TAC;; + +(* +void aes_hw_xts_encrypt(const uint8_t *in, uint8_t *out, size_t length, + const AES_KEY *key1, const AES_KEY *key2, + const uint8_t iv[16]) +*) +(* for stack pointer alignment and nonoverlapping examples, I looked at shigoel's sha512_block_data_order_hw.ml + and bignum_invsqrt_p25519_alt.ml *) +let AES256_ENCRYPT_ONE_BLOCK_CORRECT = prove( + `! plaintext ciphertext key1 key2 iv + in_pt tweak + k1_0 k1_1 k1_2 k1_3 k1_4 k1_5 k1_6 k1_7 k1_8 k1_9 k1_10 k1_11 k1_12 k1_13 k1_14 + k2_0 k2_1 k2_2 k2_3 k2_4 k2_5 k2_6 k2_7 k2_8 k2_9 k2_10 k2_11 k2_12 k2_13 k2_14 + pc stackpointer. + aligned 16 stackpointer /\ + PAIRWISE nonoverlapping + [(stackpointer, 6*16); + (word pc, LENGTH aes256_xts_encrypt_mc); + (ciphertext, 16); + (key1, 244); + (key2, 244)] + ==> ensures arm + // precondition + (\s. aligned_bytes_loaded s (word pc) aes256_xts_encrypt_mc /\ + read PC s = word (pc + 28) /\ + read SP s = stackpointer /\ + C_ARGUMENTS [plaintext; ciphertext; word 16; key1; key2; iv] s /\ + read(memory :> bytes128 plaintext) s = in_pt /\ + read(memory :> bytes128 iv) s = tweak /\ + read(memory :> bytes32 (word_add key1 (word 240))) s = word 14 /\ + read(memory :> bytes128 key1) s = k1_0 /\ + read(memory :> bytes128 (word_add key1 (word 16))) s = k1_1 /\ + read(memory :> bytes128 (word_add key1 (word 32))) s = k1_2 /\ + read(memory :> bytes128 (word_add key1 (word 48))) s = k1_3 /\ + read(memory :> bytes128 (word_add key1 (word 64))) s = k1_4 /\ + read(memory :> bytes128 (word_add key1 (word 80))) s = k1_5 /\ + read(memory :> bytes128 (word_add key1 (word 96))) s = k1_6 /\ + read(memory :> bytes128 (word_add key1 (word 112))) s = k1_7 /\ + read(memory :> bytes128 (word_add key1 (word 128))) s = k1_8 /\ + read(memory :> bytes128 (word_add key1 (word 144))) s = k1_9 /\ + read(memory :> bytes128 (word_add key1 (word 160))) s = k1_10 /\ + read(memory :> bytes128 (word_add key1 (word 176))) s = k1_11 /\ + read(memory :> bytes128 (word_add key1 (word 192))) s = k1_12 /\ + read(memory :> bytes128 (word_add key1 (word 208))) s = k1_13 /\ + read(memory :> bytes128 (word_add key1 (word 224))) s = k1_14 /\ + read(memory :> bytes32 (word_add key2 (word 240))) s = word 14 /\ + read(memory :> bytes128 key2) s = k2_0 /\ + read(memory :> bytes128 (word_add key2 (word 16))) s = k2_1 /\ + read(memory :> bytes128 (word_add key2 (word 32))) s = k2_2 /\ + read(memory :> bytes128 (word_add key2 (word 48))) s = k2_3 /\ + read(memory :> bytes128 (word_add key2 (word 64))) s = k2_4 /\ + read(memory :> bytes128 (word_add key2 (word 80))) s = k2_5 /\ + read(memory :> bytes128 (word_add key2 (word 96))) s = k2_6 /\ + read(memory :> bytes128 (word_add key2 (word 112))) s = k2_7 /\ + read(memory :> bytes128 (word_add key2 (word 128))) s = k2_8 /\ + read(memory :> bytes128 (word_add key2 (word 144))) s = k2_9 /\ + read(memory :> bytes128 (word_add key2 (word 160))) s = k2_10 /\ + read(memory :> bytes128 (word_add key2 (word 176))) s = k2_11 /\ + read(memory :> bytes128 (word_add key2 (word 192))) s = k2_12 /\ + read(memory :> bytes128 (word_add key2 (word 208))) s = k2_13 /\ + read(memory :> bytes128 (word_add key2 (word 224))) s = k2_14 + ) + // postcondition + (\s. read PC s = word (pc + LENGTH aes256_xts_encrypt_mc - 8*4) /\ + read(memory :> bytes128 ciphertext) s = + aes256_xts_encrypt_one_block in_pt + [k1_0; k1_1; k1_2; k1_3; k1_4; k1_5; k1_6; k1_7; k1_8; k1_9; k1_10; k1_11; k1_12; k1_13; k1_14] + [k2_0; k2_1; k2_2; k2_3; k2_4; k2_5; k2_6; k2_7; k2_8; k2_9; k2_10; k2_11; k2_12; k2_13; k2_14] + tweak + ) + (MAYCHANGE [PC;X0;X1;X2;X4;X6;X7;X9;X10;X11;X19;X20;X21;X22],, + MAYCHANGE [Q0;Q1;Q4;Q5;Q6;Q7;Q8;Q9;Q10;Q11;Q12;Q13;Q14;Q15;Q16;Q17;Q18;Q19;Q20;Q21;Q22;Q23;Q24;Q25;Q26],, + MAYCHANGE SOME_FLAGS,, MAYCHANGE [memory :> bytes128 ciphertext],, + MAYCHANGE [events])` + (* ,, + MAYCHANGE [memory :> bytes(stackpointer, 160) *), + REWRITE_TAC[NONOVERLAPPING_CLAUSES; C_ARGUMENTS; SOME_FLAGS; PAIRWISE; ALL] THEN + REWRITE_TAC [(REWRITE_CONV [aes256_xts_encrypt_mc] THENC LENGTH_CONV) `LENGTH aes256_xts_encrypt_mc`] THEN + REPEAT STRIP_TAC THEN + ENSURES_INIT_TAC "s0" THEN + + ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (1--1) THEN + ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (2--2) THEN + ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (3--3) THEN + ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (4--4) THEN + ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (5--6) THEN + ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (7--25) THEN + + ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (26--56) THEN + ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (57--65) THEN + +(* FIRST_X_ASSUM(MP_TAC o MATCH_MP (MESON[] `read Q6 s = a ==> !a'. a = a' ==> read Q6 s = a'`)) THEN *) + FIRST_X_ASSUM(MP_TAC o SPEC + `(aes256_encrypt (tweak:int128) [k2_0:int128; k2_1; k2_2; k2_3; k2_4; k2_5; k2_6; k2_7; k2_8; k2_9; k2_10; k2_11; k2_12; k2_13; k2_14]):int128` + o MATCH_MP (MESON[] `read Q6 s = a ==> !a'. a = a' ==> read Q6 s = a'`)) THEN + ANTS_TAC THENL [ASM_REWRITE_TAC[] THEN AESENC_TAC; DISCH_TAC] THEN + + ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (66--74) THEN + ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (75--83) THEN + ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (84--85) THEN + + ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (86--86) THEN + ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (87--87) THEN + ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (88--115) THEN + + (* FIRST_X_ASSUM(MP_TAC o MATCH_MP (MESON[] `read Q0 s = a ==> !a'. a = a' ==> read Q0 s = a'`)) THEN *) + FIRST_X_ASSUM(MP_TAC o SPEC + `(aes256_encrypt + (word_xor + (aes256_encrypt + tweak + [k2_0; k2_1; k2_2; k2_3; k2_4; k2_5; k2_6; k2_7; k2_8; + k2_9; k2_10; k2_11; k2_12; k2_13; k2_14]) + in_pt:int128) + [k1_0:int128; k1_1; k1_2; k1_3; k1_4; k1_5; k1_6; k1_7; k1_8; k1_9; k1_10; k1_11; k1_12; k1_13; k1_14]):int128` + o MATCH_MP (MESON[] `read Q0 s = a ==> !a'. a = a' ==> read Q0 s = a'`)) THEN + ANTS_TAC THENL [ASM_REWRITE_TAC[] THEN AESENC_TAC; DISCH_TAC] THEN + + ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (116--116) THEN + +(* + FIRST_X_ASSUM(MP_TAC o SPEC + `(aes256_xts_encrypt_one_block + (in_pt:int128) + [k1_0:int128; k1_1; k1_2; k1_3; k1_4; k1_5; k1_6; k1_7; k1_8; k1_9; k1_10; + k1_11; k1_12; k1_13; k1_14] + [k2_0:int128; k2_1; k2_2; k2_3; k2_4; k2_5; k2_6; k2_7; k2_8; k2_9; k2_10; + k2_11; k2_12; k2_13; k2_14] + (tweak:int128)):int128` + o MATCH_MP (MESON[] `read Q0 s = a ==> !a'. a = a' ==> read Q0 s = a'`)) THEN + ANTS_TAC THENL [ASM_REWRITE_TAC[] THEN AESXTS_ENC_ONE_BLOCK_TAC; DISCH_TAC] THEN +*) + + ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (117--117) THEN + FIRST_X_ASSUM(MP_TAC o SPEC + `(aes256_xts_encrypt_one_block + (in_pt:int128) + [k1_0:int128; k1_1; k1_2; k1_3; k1_4; k1_5; k1_6; k1_7; k1_8; k1_9; k1_10; + k1_11; k1_12; k1_13; k1_14] + [k2_0:int128; k2_1; k2_2; k2_3; k2_4; k2_5; k2_6; k2_7; k2_8; k2_9; k2_10; + k2_11; k2_12; k2_13; k2_14] + (tweak:int128)):int128` + o MATCH_MP (MESON[] `read (memory :> bytes128 ciphertext) s = a ==> !a'. a = a' + ==> read (memory :> bytes128 ciphertext) s = a'`)) THEN + ANTS_TAC THENL [ASM_REWRITE_TAC[] THEN AESXTS_ENC_ONE_BLOCK_TAC; DISCH_TAC] THEN + + ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (118--122) THEN + ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (123--128) THEN + (* ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (128--136) THEN *) + + ENSURES_FINAL_STATE_TAC THEN + ASM_REWRITE_TAC[] THEN + ARITH_TAC +);; + + (* + `word_xor + (aes256_encrypt + (word_xor + (aes256_encrypt tweak + [k2_0; k2_1; k2_2; k2_3; k2_4; k2_5; k2_6; k2_7; k2_8; k2_9; k2_10; k2_11; + k2_12; k2_13; k2_14]) + in_pt) + [k1_0; k1_1; k1_2; k1_3; k1_4; k1_5; k1_6; k1_7; k1_8; k1_9; k1_10; k1_11; + k1_12; k1_13; k1_14]) + (aes256_encrypt tweak + [k2_0; k2_1; k2_2; k2_3; k2_4; k2_5; k2_6; k2_7; k2_8; k2_9; k2_10; k2_11; + k2_12; k2_13; k2_14]) = + word_xor + (aes256_encrypt + (word_xor in_pt + (aes256_encrypt tweak + [k2_0; k2_1; k2_2; k2_3; k2_4; k2_5; k2_6; k2_7; k2_8; k2_9; k2_10; k2_11; + k2_12; k2_13; k2_14])) + [k1_0; k1_1; k1_2; k1_3; k1_4; k1_5; k1_6; k1_7; k1_8; k1_9; k1_10; k1_11; + k1_12; k1_13; k1_14]) + (aes256_encrypt tweak + [k2_0; k2_1; k2_2; k2_3; k2_4; k2_5; k2_6; k2_7; k2_8; k2_9; k2_10; k2_11; + k2_12; k2_13; k2_14])` + +# e(AP_THM_TAC);; + + `word_xor + (aes256_encrypt + (word_xor + (aes256_encrypt tweak + [k2_0; k2_1; k2_2; k2_3; k2_4; k2_5; k2_6; k2_7; k2_8; k2_9; k2_10; k2_11; + k2_12; k2_13; k2_14]) + in_pt) + [k1_0; k1_1; k1_2; k1_3; k1_4; k1_5; k1_6; k1_7; k1_8; k1_9; k1_10; k1_11; + k1_12; k1_13; k1_14]) = + word_xor + (aes256_encrypt + (word_xor in_pt + (aes256_encrypt tweak + [k2_0; k2_1; k2_2; k2_3; k2_4; k2_5; k2_6; k2_7; k2_8; k2_9; k2_10; k2_11; + k2_12; k2_13; k2_14])) + [k1_0; k1_1; k1_2; k1_3; k1_4; k1_5; k1_6; k1_7; k1_8; k1_9; k1_10; k1_11; + k1_12; k1_13; k1_14])` + +# e(AP_TERM_TAC);; + +`aes256_encrypt + (word_xor + (aes256_encrypt tweak + [k2_0; k2_1; k2_2; k2_3; k2_4; k2_5; k2_6; k2_7; k2_8; k2_9; k2_10; k2_11; + k2_12; k2_13; k2_14]) + in_pt) + [k1_0; k1_1; k1_2; k1_3; k1_4; k1_5; k1_6; k1_7; k1_8; k1_9; k1_10; k1_11; + k1_12; k1_13; k1_14] = + aes256_encrypt + (word_xor in_pt + (aes256_encrypt tweak + [k2_0; k2_1; k2_2; k2_3; k2_4; k2_5; k2_6; k2_7; k2_8; k2_9; k2_10; k2_11; + k2_12; k2_13; k2_14])) + [k1_0; k1_1; k1_2; k1_3; k1_4; k1_5; k1_6; k1_7; k1_8; k1_9; k1_10; k1_11; + k1_12; k1_13; k1_14]` + +# e(AP_THM_TAC);; + `aes256_encrypt + (word_xor + (aes256_encrypt tweak + [k2_0; k2_1; k2_2; k2_3; k2_4; k2_5; k2_6; k2_7; k2_8; k2_9; k2_10; k2_11; + k2_12; k2_13; k2_14]) + in_pt) = + aes256_encrypt + (word_xor in_pt + (aes256_encrypt tweak + [k2_0; k2_1; k2_2; k2_3; k2_4; k2_5; k2_6; k2_7; k2_8; k2_9; k2_10; k2_11; + k2_12; k2_13; k2_14]))` + +# e(AP_TERM_TAC);; +`word_xor + (aes256_encrypt tweak + [k2_0; k2_1; k2_2; k2_3; k2_4; k2_5; k2_6; k2_7; k2_8; k2_9; k2_10; k2_11; + k2_12; k2_13; k2_14]) + in_pt = + word_xor in_pt + (aes256_encrypt tweak + [k2_0; k2_1; k2_2; k2_3; k2_4; k2_5; k2_6; k2_7; k2_8; k2_9; k2_10; k2_11; + k2_12; k2_13; k2_14])` +*) + + +(* +If I don't make the second FIRST_X_ASSUM before XORING with the tweak, +How can I go within this term to do it later in the second argument of the +first xor to make it aes256_encrypt? + + 83 [`read (memory :> bytes128 ciphertext) s117 = + word_xor + (aes256_encrypt tweak + [k2_0; k2_1; k2_2; k2_3; k2_4; k2_5; k2_6; k2_7; k2_8; k2_9; k2_10; + k2_11; k2_12; k2_13; k2_14]) + (word_xor k1_14 + (aese + (aesmc + (aese + (aesmc + (aese + (aesmc + (aese + (aesmc + (aese + (aesmc + (aese + (aesmc + (aese + (aesmc + (aese + (aesmc + (aese + (aesmc + (aese + (aesmc + (aese + (aesmc + (aese + (aesmc + (aese + (aesmc + (aese + (word_xor + (aes256_encrypt tweak + [k2_0; k2_1; k2_2; k2_3; k2_4; k2_5; k2_6; k2_7; k2_8; + k2_9; k2_10; k2_11; k2_12; k2_13; k2_14]) + in_pt) + k1_0)) + k1_1)) + k1_2)) + k1_3)) + k1_4)) + k1_5)) + k1_6)) + k1_7)) + k1_8)) + k1_9)) + k1_10)) + k1_11)) + k1_12)) + k1_13))`] + +Why the REPEAT line in the following doesn't return back? +let AESXTS_ENC_ONE_BLOCK_TAC = + REWRITE_TAC [aes256_xts_encrypt_one_block] THEN + CONV_TAC (TOP_DEPTH_CONV let_CONV) THEN + REPEAT (GEN_REWRITE_TAC LAND_CONV [WORD_XOR_SYM] ORELSE AP_THM_TAC ORELSE AP_TERM_TAC) THEN + BITBLAST_TAC;; +*) diff --git a/arm/proofs/aes_encrypt.ml b/arm/proofs/aes_encrypt.ml index 25c278ab8..8b961859d 100644 --- a/arm/proofs/aes_encrypt.ml +++ b/arm/proofs/aes_encrypt.ml @@ -57,8 +57,6 @@ let AES256_ENCRYPT_CORRECT = prove( read(memory :> bytes128 (word_add key (word 224))) s = k14 ) // postcondition - // TODO: Nevine will figure out the post condition for output - // hint: use the aes256_encrypt from aes_encrypt_spec (\s. read PC s = word (pc + LENGTH aes256_encrypt_mc) /\ read(memory :> bytes128 ciphertext) s = aes256_encrypt ib @@ -82,7 +80,7 @@ let AES256_ENCRYPT_CORRECT = prove( ASM_REWRITE_TAC[] THEN REWRITE_TAC [aes256_encrypt] THEN REWRITE_TAC EL_15_128_CLAUSES THEN - REWRITE_TAC [aes256_encrypt_round; aese; aesmc] + REWRITE_TAC [aes256_encrypt_round; aese; aesmc] THEN CONV_TAC (TOP_DEPTH_CONV let_CONV) THEN BITBLAST_TAC (* Alternatively, use the XOR symmetry diff --git a/arm/proofs/aes_xts_encrypt_spec.ml b/arm/proofs/aes_xts_encrypt_spec.ml index 8abd977bc..9f3b2a154 100644 --- a/arm/proofs/aes_xts_encrypt_spec.ml +++ b/arm/proofs/aes_xts_encrypt_spec.ml @@ -108,6 +108,7 @@ let AES_XTS_ENC_HELPER_CONV = DEPTH_CONV (WORD_RED_CONV ORELSEC NUM_RED_CONV) ;; +(* (* Takes about a 100 sec on M3 *) let tmp_xts = AES_XTS_ENC_HELPER_CONV `aes256_xts_encrypt_one_block @@ -120,7 +121,9 @@ let tmp_xts = AES_XTS_ENC_HELPER_CONV prove(list_mk_comb (`(=):((128)word->(128)word->bool)`, [rand (concl tmp_xts);`(word 0x9BCF70E3996C83E48603772F103A3B1C):(128)word`]), REFL_TAC);; +*) +(* (* Takes about a 100 sec on M3 *) time prove(`aes256_xts_encrypt_one_block (word 0x0F0E0D0C0B0A09080706050403020100) @@ -131,3 +134,4 @@ time prove(`aes256_xts_encrypt_one_block CONV_TAC(LAND_CONV AES_XTS_ENC_HELPER_CONV) THEN REFL_TAC );; +*) \ No newline at end of file From 75c991ab7bd90079a7af4aa529bd4b07098fb610 Mon Sep 17 00:00:00 2001 From: Nevine Ebeid Date: Mon, 18 Aug 2025 17:37:27 -0400 Subject: [PATCH 058/132] AES-XTS encrypt (any input length) spec. To be tested --- arm/proofs/aes-xts-armv8.ml | 6 + arm/proofs/aes_xts_encrypt_spec.ml | 361 ++++++++++++++++++++++++++--- 2 files changed, 330 insertions(+), 37 deletions(-) diff --git a/arm/proofs/aes-xts-armv8.ml b/arm/proofs/aes-xts-armv8.ml index 82a760258..cea3c4011 100644 --- a/arm/proofs/aes-xts-armv8.ml +++ b/arm/proofs/aes-xts-armv8.ml @@ -1036,10 +1036,16 @@ first xor to make it aes256_encrypt? k1_12)) k1_13))`] + +RULE_ASSUM_TAC(REWRITE_RULE[GSYM specth]) + Why the REPEAT line in the following doesn't return back? let AESXTS_ENC_ONE_BLOCK_TAC = REWRITE_TAC [aes256_xts_encrypt_one_block] THEN CONV_TAC (TOP_DEPTH_CONV let_CONV) THEN REPEAT (GEN_REWRITE_TAC LAND_CONV [WORD_XOR_SYM] ORELSE AP_THM_TAC ORELSE AP_TERM_TAC) THEN BITBLAST_TAC;; + + REWRITE_TAC may just repeat (without REPEAT) would arrive at a canonical form + June: TARGET_REWRITE_TAC *) diff --git a/arm/proofs/aes_xts_encrypt_spec.ml b/arm/proofs/aes_xts_encrypt_spec.ml index 9f3b2a154..31b02692a 100644 --- a/arm/proofs/aes_xts_encrypt_spec.ml +++ b/arm/proofs/aes_xts_encrypt_spec.ml @@ -1,3 +1,4 @@ +needs "arm/proofs/base.ml";; needs "arm/proofs/aes_encrypt_spec.ml";; (* AES-256-XTS Encryption Algorithm for One Block @@ -12,7 +13,7 @@ i is the value of the 128-bit tweak (see 5.1) j is the sequential number of the 128-bit block inside the data unit C is the block of 128 bits of ciphertext resulting from the operation -T := AES-enc(Key2 , i) XOR α^j +T := AES-enc(Key2 , i) MUL α^j PP := P XOR T CC := AES-enc(Key1 , PP) C := CC XOR T @@ -77,31 +78,195 @@ let tweak_key_schedule = new_definition `tweak_key_schedule:int128 list = ; word 0x4E12BD760FE7F086777A3655FF5B9B4D ; word 0x70ADE5BA1B23A3A2807BD0C6E50F5D04 ]`;; + (* -let AES_XTS_ENC_HELPER_CONV = - PRINT_TERM_CONV THENC - REWR_CONV aes256_xts_encrypt_one_block THENC - PRINT_TERM_CONV THENC - REWRITE_CONV [aes256_encrypt; data_key_schedule; tweak_key_schedule] THENC - PRINT_TERM_CONV THENC - REWRITE_CONV EL_15_128_CLAUSES THENC -(* PRINT_TERM_CONV THENC *) - REPEATC let_CONV THENC - DEPTH_CONV (WORD_RED_CONV ORELSEC NUM_RED_CONV) THENC - DEPTH_CONV AESENC_REDUCE_CONV (*THENC - AES_SHIFT_ROWS_CONV THENC - AES_SUB_BYTES_CONV THENC - PRINT_TERM_CONV THENC - DEPTH_CONV (WORD_RED_CONV ORELSEC NUM_RED_CONV) - *) - ;; +AES-256-XTS Encryption Algorithm for Any Input Length +Based on IEEE 1619-2007 Standard + +This specification implements the complete AES-XTS encryption algorithm +as described in IEEE 1619-2007, Section 5.3, supporting arbitrary input lengths. + +Key components: +- Key = Key1 (256-bit data key) || Key2 (256-bit tweak key) +- P is the plaintext of arbitrary length (≥ 128 bits) +- i is the value of the 128-bit tweak +- C is the resulting ciphertext + +The algorithm processes data in 128-bit blocks with special handling for +the final partial block (if any) using ciphertext stealing. + +For each complete block j: + T_j := AES-enc(Key2, i) MUL α^j + PP_j := P_j XOR T_j + CC_j := AES-enc(Key1, PP_j) + C_j := CC_j XOR T_j + +Where α is the primitive element in GF(2^128) and MUL denotes multiplication +in the Galois field. + +For partial final blocks, ciphertext stealing is used as per Section 5.3.2. *) -let AES_XTS_ENC_HELPER_CONV = + +(*****************************************) +(* AES-XTS encryption full *) + +(* Note: the implementation sequences the calculation of the tweak for each block, + however, the specification will calculate the tweak from the very beginning for each block. + We write the specification in the sequenced version for proof simplicity. *) + +(* Helper functions derived from Amanda's code: + https://github.com/amanda-zx/s2n-bignum/blob/sha512/arm/sha512/sha512_specs.ml#L360 *) + +(* XTS tweak initialization - encrypt the IV with key2 *) +(* TODO: put it in a common place to be used with decrypt + Start *) +let xts_init_tweak = new_definition + `xts_init_tweak (iv:int128) (key_schedule:int128 list) = + aes256_encrypt iv key_schedule`;; + +let bytes_to_int128 = define + `bytes_to_int128 (bs : byte list) : int128 = + word_join + (word_join + (word_join + (word_join (EL 15 bs) (EL 14 bs) : int16) + (word_join (EL 13 bs) (EL 12 bs) : int16) : int32) + (word_join + (word_join (EL 11 bs) (EL 10 bs) : int16) + (word_join (EL 9 bs) (EL 8 bs) : int16) : int32) : int64) + (word_join + (word_join + (word_join (EL 7 bs) (EL 6 bs) : int16) + (word_join (EL 5 bs) (EL 4 bs) : int16) : int32) + (word_join + (word_join (EL 3 bs) (EL 2 bs) : int16) + (word_join (EL 1 bs) (EL 0 bs) : int16) : int32) : int64)`;; + +let int128_to_bytes = define + `int128_to_bytes (w : int128) : byte list = + [word_subword w (0, 8); word_subword w (8, 8); word_subword w (16, 8); word_subword w (24, 8); + word_subword w (32, 8); word_subword w (40, 8); word_subword w (48, 8); word_subword w (56, 8); + word_subword w (64, 8); word_subword w (72, 8); word_subword w (80, 8); word_subword w (88, 8); + word_subword w (96, 8); word_subword w (104, 8); word_subword w (112, 8); word_subword w (120, 8)]`;; + +(* Multiplication by the primitive element \alpha in GF(2^128) *) +let GF_128_mult_by_primitive = new_definition + `GF_128_mult_by_primitive (tweak:(128)word) = + let shifted = word_shl tweak 1 in + let mask = word_ishr tweak 127 in + word_xor (word_and mask (word 0x87)) shifted`;; + +let FST3 = define `FST3 (x:a#b#c) = FST x`;; +let SND3 = define `SND3 (x:a#b#c) = FST (SND x)`;; +let THD3 = define `THD3 (x:a#b#c) = SND (SND x)`;; + +(* TODO: put it in a common place to be used with decrypt + End *) + +(* AES-XTS encryption round function *) +let aes256_xts_encrypt_round = new_definition + `aes256_xts_encrypt_round (P:int128) (tk:int128) (key_schedule:int128 list) = + let PP = word_xor P tk in + let CC = aes256_encrypt PP key_schedule in + word_xor CC tk`;; + +(* Single block AES-XTS encryption *) +let aes256_xts_encrypt_1block = new_definition + `aes256_xts_encrypt_1block (P:int128) (iv:int128) (key1:int128 list) (key2:int128 list) = + let tk = xts_init_tweak iv key2 in + aes256_xts_encrypt_round P tk key1`;; + +(* Recursive encryption function for multiple blocks *) +let eth = prove_general_recursive_function_exists + `?aes256_xts_encrypt_rec. + ! (i:num) (m:num) (P:byte list) (iv:int128) (key1:int128 list) (key2:int128 list). + aes256_xts_encrypt_rec i m P iv key1 key2 : (byte list)#int128#num = + if m < i then ([], iv, i) + else + let current_block = bytes_to_int128 (SUB_LIST (i * 16, 16) P) in + let curr = int128_to_bytes (aes256_xts_encrypt_round current_block iv key1) in + let iv = GF_128_mult_by_primitive iv in + let res = aes256_xts_encrypt_rec (i + 1) m P iv key1 key2 in + (APPEND curr (FST3 res), SND3 res, THD3 res)`;; + +let wfth = prove(hd(hyp eth), + EXISTS_TAC `MEASURE (\(i:num,m:num,P:byte list,iv:int128,key1:int128 list,key2:int128 list). (m + 1) - i)` THEN + REWRITE_TAC[WF_MEASURE; MEASURE] THEN ARITH_TAC);; + +let exists_lemma = PROVE_HYP wfth eth;; + +(* Note: results are stored in LSByte to MSByte *) +let aes256_xts_encrypt_rec = new_specification ["aes256_xts_encrypt_rec"] exists_lemma;; + +(* Cipher stealing for encryption (note: encryption cipher stealing is different from decryption) *) +let cipher_stealing_encrypt = new_definition + `cipher_stealing_encrypt (block:int128) (tail:int128) (tail_len:num) (iv:int128) (key1:int128 list) : int128#int128 = + let CC = aes256_xts_encrypt_round block iv key1 in + let Cm = word_subword CC (0, tail_len * 8) in + let CP = word_subword CC (tail_len * 8, (16 - tail_len) * 8) in + let PP = word_join (word_subword tail (0, tail_len * 8)) CP in + let iv_last = GF_128_mult_by_primitive iv in + let Cm1 = aes256_xts_encrypt_round PP iv_last key1 in + (Cm1, (word_zx Cm))`;; + +(* Encryption tail handling - either single block or cipher stealing *) +let aes256_xts_encrypt_tail = new_definition + `aes256_xts_encrypt_tail (i:num) (m:num) (tail:num) (P:byte list) (iv:int128) (key1:int128 list) (key2:int128 list) : byte list = + let Pm1 = bytes_to_int128 (SUB_LIST (i * 16, 16) P) in + if tail = 0 then + int128_to_bytes (aes256_xts_encrypt_round Pm1 iv key1) + else + let padded_tail = APPEND (SUB_LIST ((i + 1) * 16, tail) P) (REPLICATE (16 - tail) (word 0)) in + let Ptail = bytes_to_int128 padded_tail in + let res_cs = cipher_stealing_encrypt Pm1 Ptail tail iv key1 in + let Cm1 = int128_to_bytes (FST res_cs) in + let Ctail = SUB_LIST (0, tail) (int128_to_bytes (SND res_cs)) in + APPEND Cm1 Ctail`;; + +(* The main encryption function *) +(* Note: the specification does not handle the case of len < 16, which is + handled in the implementation. *) +(* AES256-XTS assumes there is at least one block in input *) +(* + P: Input plaintext represented as a byte list + len: Byte length of P + iv: Initialization vector (tweak) as an int128 + key1: Key schedule for AES-256 encryption + key2: Key schedule for AES-256 encryption for the tweak + C_error: Error output ciphertext in case of invalid input length + return: Output ciphertext as a byte list + When input len < 16, the function returns C_error, + which will be the initial value stored in output address. +*) +(* TODO: Challenge lemma: proving that the output is of same length as input *) +(* TODO: Double check if NIST spec talks about the error case len < 16 *) +(* TODO: Double check the pseudo code in the spec for tweak calculation in ANEX c *) +let aes256_xts_encrypt = new_definition + `aes256_xts_encrypt + (P:byte list) (len:num) (iv:int128) (key1:int128 list) (key2:int128 list) (C_error:byte list) : byte list = + if len < 16 then + C_error + else + let tail = len MOD 16 in + let m = (len - tail) DIV 16 in + let i = 0 in + let iv = xts_init_tweak iv key2 in + if m < 2 then + aes256_xts_encrypt_tail i m tail P iv key1 key2 + else + let res = aes256_xts_encrypt_rec 0 (m - 2) P iv key1 key2 in + let Ctail = aes256_xts_encrypt_tail (THD3 res) m tail P (SND3 res) key1 key2 in + APPEND (FST3 res) Ctail`;; + +(****) +(* Conversions and test vectors *) +let AES_XTS_ENC_1BLK_HELPER_CONV = (* PRINT_TERM_CONV THENC *) - REWR_CONV aes256_xts_encrypt_one_block THENC -(* PRINT_TERM_CONV THENC*) + REWR_CONV aes256_xts_encrypt_1block THENC + PRINT_TERM_CONV THENC REWRITE_CONV [data_key_schedule; tweak_key_schedule] THENC -(* PRINT_TERM_CONV THENC *) + (* PRINT_TERM_CONV THENC *) + REWRITE_CONV [xts_init_tweak; aes256_xts_encrypt_round] THENC REPEATC let_CONV THENC DEPTH_CONV (WORD_RED_CONV ORELSEC NUM_RED_CONV) THENC DEPTH_CONV AESENC_HELPER_CONV THENC @@ -109,13 +274,24 @@ let AES_XTS_ENC_HELPER_CONV = ;; (* -(* Takes about a 100 sec on M3 *) -let tmp_xts = AES_XTS_ENC_HELPER_CONV - `aes256_xts_encrypt_one_block +(* Proven in about 100 sec on M3 *) +time prove(`aes256_xts_encrypt_1block + (word 0x0F0E0D0C0B0A09080706050403020100) + (word 0x000000000000000000000000000000FF) + data_key_schedule + tweak_key_schedule + = word 0x9BCF70E3996C83E48603772F103A3B1C`, (* expected result in little endian *) + CONV_TAC(LAND_CONV AES_XTS_ENC_1BLK_HELPER_CONV) + THEN REFL_TAC + );; +*) +(* +let tmp_xts = AES_XTS_ENC_1BLK_HELPER_CONV + `aes256_xts_encrypt_1block (word 0x0F0E0D0C0B0A09080706050403020100) + (word 0x000000000000000000000000000000FF) data_key_schedule tweak_key_schedule - (word 0x000000000000000000000000000000FF) `;; prove(list_mk_comb (`(=):((128)word->(128)word->bool)`, @@ -124,14 +300,125 @@ prove(list_mk_comb (`(=):((128)word->(128)word->bool)`, *) (* -(* Takes about a 100 sec on M3 *) -time prove(`aes256_xts_encrypt_one_block - (word 0x0F0E0D0C0B0A09080706050403020100) - data_key_schedule - tweak_key_schedule - (word 0x000000000000000000000000000000FF) - = word 0x9BCF70E3996C83E48603772F103A3B1C`, (* expected result in little endian *) - CONV_TAC(LAND_CONV AES_XTS_ENC_HELPER_CONV) - THEN REFL_TAC - );; -*) \ No newline at end of file + Two-block test vector (same key and tweak as single block) + Plaintext: 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f + Data Key: 2718281828459045235360287471352662497757247093699959574966967627 + Tweak Key: 3141592653589793238462643383279502884197169399375105820974944592 + Tweak: FF000000000000000000000000000000 + Ciphertext: 1C3B3A102F770386E4836C99E370CF9BEA00803F5E482357A4AE12D414A3E63B + Plaintext (reversed): 1F1E1D1C1B1A191817161514131211100F0E0D0C0B0A09080706050403020100 + Ciphertext (reversed): 3BE6A314D412AEA45723485E3F8000EA9BCF70E3996C83E48603772F103A3B1C +*) + +(* Convert reversed plaintext and ciphertext to byte lists using int128_to_bytes *) +let plaintext = new_definition + `plaintext = + int128_to_bytes (word 0x1F1E1D1C1B1A191817161514131211100F0E0D0C0B0A09080706050403020100)`;; + +let ciphertext = new_definition + `ciphertext = + int128_to_bytes (word 0x3BE6A314D412AEA45723485E3F8000EA9BCF70E3996C83E48603772F103A3B1C)`;; + +let cerr = new_definition + `cerr = + int128_to_bytes (word 0x0)`;; + +(* Generated by Cline but not needed +(* Two-block plaintext for testing *) +let two_block_plaintext = new_definition + `two_block_plaintext = + APPEND (int128_to_bytes (word 0x0F0E0D0C0B0A09080706050403020100)) + (int128_to_bytes (word 0x1F1E1D1C1B1A19181716151413121110))`;; +*) + +(* This was generated by Cline, to review *) +(* Conversion for aes256_xts_encrypt using the byte lists *) +let AES_XTS_ENC_HELPER_CONV = +(* PRINT_TERM_CONV THENC *) + REWR_CONV aes256_xts_encrypt THENC + PRINT_TERM_CONV THENC + REWRITE_CONV [data_key_schedule; tweak_key_schedule; plaintext; ciphertext; C_err] THENC + (* PRINT_TERM_CONV THENC *) + REWRITE_CONV [xts_init_tweak; aes256_xts_encrypt_round; aes256_xts_encrypt_tail; + aes256_xts_encrypt_rec; cipher_stealing_encrypt] THENC + REWRITE_CONV [int128_to_bytes; bytes_to_int128; SUB_LIST; APPEND; EL] THENC + REPEATC let_CONV THENC + DEPTH_CONV (WORD_RED_CONV ORELSEC NUM_RED_CONV) THENC + DEPTH_CONV AESENC_HELPER_CONV THENC + DEPTH_CONV (WORD_RED_CONV ORELSEC NUM_RED_CONV) + ;; + + let tmp_xts_enc = AES_XTS_ENC_HELPER_CONV + `aes256_xts_encrypt plaintext 32 (word 0x000000000000000000000000000000FF) + data_key_schedule + tweak_key_schedule C_error + `;; +(*****************************************) +(* Test key schedules from the decryption spec *) + +let KEY1 = new_definition `KEY1:int128 list = + [ word 0xc70a951e84370d1836bdd387607e94e5 + ; word 0x7ead95d6f74bf6b3103340cce21b473d + ; word 0x298c296cdf3241d53d0757ddbebda060 + ; word 0x89e66365e778b67ff22807f1cdc91c8f + ; word 0xf6be68b9e235160883baf7bd2340b902 + ; word 0x6e9ed51a1550b18e3fe11b7e185c513e + ; word 0x148b7eb1618fe1b5a0fa4ebf336ae76e + ; word 0x7bce64942ab1aaf027bd4a40982968cd + ; word 0x75049f04c175af0a9390a9d1d91a6526 + ; word 0x517fce640d0ce0b0bf94228de7e3085d + ; word 0xb471300e52e506db4a8accf7a81afe26 + ; word 0x5c732ed4b298c23d58772ad0be94ce31 + ; word 0xe69436d5186fca2ce29032d11463c620 + ; word 0xeeebece9eaefe8ede6e3e4e1e2e7e0e5 + ; word 0xf0f1f2f3f4f5f6f7f8f9fafbfcfdfeff + ]`;; + +let KEY2 = new_definition `KEY2:int128 list = + [ word 0xb0b1b2b3b4b5b6b7b8b9babbbcbdbebf + ; word 0xa0a1a2a3a4a5a6a7a8a9aaabacadaeaf + ; word 0x0ae0323bba5180880ee4363fb65d8c84 + ; word 0x67e123e2c740814163e527e6cb4c8d4d + ; word 0x908df02c9a6dc217203c429f2ed874a0 + ; word 0x685584790fb4a79bc8f426daab11013c + ; word 0xb241f85f22cc0873b8a1ca64989d88fb + ; word 0x338745cb5bd2c1b2546666299c9240f3 + ; word 0xaf72a5d51d335d8a3fff55f9875e9f9d + ; word 0xd9e1a4a0ea66e16bb1b420d9e5d246f0 + ; word 0xead5ca6245a76fb75894323d676b67c4 + ; word 0xe0e257483903f3e8d365128362d1325a + ; word 0xc26c685728b9a2356d1ecd82358affbf + ; word 0x4d05c122ade7966a94e4658247817701 + ; word 0x21a29367e3cefb30cb775905a6699487 + ]`;; + +(*****************************************) +(* Conversions *) + +let plaintext = new_definition + `[word 0x0f; word 0x0e; word 0x0d; word 0x0c + ; word 0x0b; word 0x0a; word 0x09; word 0x08 + ; word 0x07; word 0x06; word 0x05; word 0x04 + ; word 0x03; word 0x02; word 0x01; word 0x00] : byte list`;; + +let iv = new_definition + `(word 0x0000000000000000000000123456789a) : int128`;; + +let C_error = new_definition + `[ word 0; word 0; word 0; word 0 + ; word 0; word 0; word 0; word 0 + ; word 0; word 0; word 0; word 0 + ; word 0; word 0; word 0; word 0] : byte list`;; + +let ciphertext = new_definition + `[word 0xc3; word 0x0c; word 0xa8; word 0xf2 + ; word 0xed; word 0x57; word 0x30; word 0x7e + ; word 0xdc; word 0x87; word 0xe5; word 0x44 + ; word 0x86; word 0x7a; word 0xc8; word 0x88] : byte list`;; + +let rw = Compute.bool_compset();; +word_compute_add_convs rw;; +num_compute_add_convs rw;; +Compute.add_thms [aes256_xts_encrypt;KEY1;KEY2;plaintext;iv;C_error;ciphertext] rw;; +let my_conv = Compute.WEAK_CBV_CONV rw;; +my_conv `aes256_xts_encrypt P 16 iv KEY1 KEY2 C_error`;; From 19ae854b86e2a4bc1070211cb776ee83ad52bae0 Mon Sep 17 00:00:00 2001 From: Nevine Ebeid Date: Wed, 3 Sep 2025 15:37:21 -0400 Subject: [PATCH 059/132] Make encrypt_spec match decrypt_spec. --- arm/proofs/aes_xts_encrypt_spec.ml | 75 ++++++++++++++++-------------- 1 file changed, 39 insertions(+), 36 deletions(-) diff --git a/arm/proofs/aes_xts_encrypt_spec.ml b/arm/proofs/aes_xts_encrypt_spec.ml index 31b02692a..0e6a9756c 100644 --- a/arm/proofs/aes_xts_encrypt_spec.ml +++ b/arm/proofs/aes_xts_encrypt_spec.ml @@ -156,12 +156,12 @@ let GF_128_mult_by_primitive = new_definition let mask = word_ishr tweak 127 in word_xor (word_and mask (word 0x87)) shifted`;; -let FST3 = define `FST3 (x:a#b#c) = FST x`;; -let SND3 = define `SND3 (x:a#b#c) = FST (SND x)`;; -let THD3 = define `THD3 (x:a#b#c) = SND (SND x)`;; - (* TODO: put it in a common place to be used with decrypt End *) +let calculate_tweak = new_recursive_definition num_RECURSION + `calculate_tweak 0 (iv:(128)word) (key2:int128 list) = xts_init_tweak iv key2 /\ + calculate_tweak (SUC n) (iv:(128)word) (key2:int128 list) = + GF_128_mult_by_primitive (calculate_tweak n iv key2)`;; (* AES-XTS encryption round function *) let aes256_xts_encrypt_round = new_definition @@ -180,14 +180,14 @@ let aes256_xts_encrypt_1block = new_definition let eth = prove_general_recursive_function_exists `?aes256_xts_encrypt_rec. ! (i:num) (m:num) (P:byte list) (iv:int128) (key1:int128 list) (key2:int128 list). - aes256_xts_encrypt_rec i m P iv key1 key2 : (byte list)#int128#num = - if m < i then ([], iv, i) + aes256_xts_encrypt_rec i m P iv key1 key2 : (byte list)#num = + if m < i then ([], i) else let current_block = bytes_to_int128 (SUB_LIST (i * 16, 16) P) in - let curr = int128_to_bytes (aes256_xts_encrypt_round current_block iv key1) in - let iv = GF_128_mult_by_primitive iv in + let twk = calculate_tweak i iv key2 in + let curr = int128_to_bytes (aes256_xts_encrypt_round current_block twk key1) in let res = aes256_xts_encrypt_rec (i + 1) m P iv key1 key2 in - (APPEND curr (FST3 res), SND3 res, THD3 res)`;; + (APPEND curr (FST res), SND res)`;; let wfth = prove(hd(hyp eth), EXISTS_TAC `MEASURE (\(i:num,m:num,P:byte list,iv:int128,key1:int128 list,key2:int128 list). (m + 1) - i)` THEN @@ -198,30 +198,35 @@ let exists_lemma = PROVE_HYP wfth eth;; (* Note: results are stored in LSByte to MSByte *) let aes256_xts_encrypt_rec = new_specification ["aes256_xts_encrypt_rec"] exists_lemma;; -(* Cipher stealing for encryption (note: encryption cipher stealing is different from decryption) *) +(* Cipher stealing for encryption (note: encryption cipher stealing is different from decryption) + Pm1 : last full block; P_{m-1} in the standard + Pm : tail; P_m +*) let cipher_stealing_encrypt = new_definition - `cipher_stealing_encrypt (block:int128) (tail:int128) (tail_len:num) (iv:int128) (key1:int128 list) : int128#int128 = - let CC = aes256_xts_encrypt_round block iv key1 in - let Cm = word_subword CC (0, tail_len * 8) in - let CP = word_subword CC (tail_len * 8, (16 - tail_len) * 8) in - let PP = word_join (word_subword tail (0, tail_len * 8)) CP in + `cipher_stealing_encrypt (Pm1:byte list) (Pm:byte list) (tail_len:num) + (iv:int128) (i:num) (key1:int128 list) (key2:int128 list): (byte list)#(byte list) = + let twk = calculate_tweak i iv key2 in + let CC = int128_to_bytes (aes256_xts_encrypt_round (bytes_to_int128 Pm1) twk key1) in + let Cm = SUB_LIST (0, tail_len) CC in + let CP = SUB_LIST (tail_len, 16 - tail_len) CC in + let PP = bytes_to_int128 (APPEND Pm CP) in let iv_last = GF_128_mult_by_primitive iv in - let Cm1 = aes256_xts_encrypt_round PP iv_last key1 in - (Cm1, (word_zx Cm))`;; + let Cm1 = int128_to_bytes (aes256_xts_encrypt_round PP iv_last key1) in + (Cm1, Cm)`;; (* Encryption tail handling - either single block or cipher stealing *) let aes256_xts_encrypt_tail = new_definition - `aes256_xts_encrypt_tail (i:num) (m:num) (tail:num) (P:byte list) (iv:int128) (key1:int128 list) (key2:int128 list) : byte list = - let Pm1 = bytes_to_int128 (SUB_LIST (i * 16, 16) P) in - if tail = 0 then - int128_to_bytes (aes256_xts_encrypt_round Pm1 iv key1) + `aes256_xts_encrypt_tail (i:num) (tail_len:num) (P:byte list) (iv:int128) + (key1:int128 list) (key2:int128 list) : byte list = + if tail_len = 0 then + let Pm1 = bytes_to_int128 (SUB_LIST (i * 16, 16) P) in + let twk = calculate_tweak i iv key2 in + int128_to_bytes (aes256_xts_encrypt_round Pm1 twk key1) else - let padded_tail = APPEND (SUB_LIST ((i + 1) * 16, tail) P) (REPLICATE (16 - tail) (word 0)) in - let Ptail = bytes_to_int128 padded_tail in - let res_cs = cipher_stealing_encrypt Pm1 Ptail tail iv key1 in - let Cm1 = int128_to_bytes (FST res_cs) in - let Ctail = SUB_LIST (0, tail) (int128_to_bytes (SND res_cs)) in - APPEND Cm1 Ctail`;; + let Pm1 = SUB_LIST (i * 16, 16) P in + let Pm = SUB_LIST ((i + 1) * 16, tail_len) P in + let res_cs = cipher_stealing_encrypt Pm1 Pm tail_len iv i key1 key2 in + APPEND (FST res_cs) (SND res_cs)`;; (* The main encryption function *) (* Note: the specification does not handle the case of len < 16, which is @@ -243,20 +248,18 @@ let aes256_xts_encrypt_tail = new_definition (* TODO: Double check the pseudo code in the spec for tweak calculation in ANEX c *) let aes256_xts_encrypt = new_definition `aes256_xts_encrypt - (P:byte list) (len:num) (iv:int128) (key1:int128 list) (key2:int128 list) (C_error:byte list) : byte list = + (P:byte list) (len:num) (iv:int128) (key1:int128 list) (key2:int128 list) (err:byte list) : byte list = if len < 16 then - C_error + err else - let tail = len MOD 16 in - let m = (len - tail) DIV 16 in - let i = 0 in - let iv = xts_init_tweak iv key2 in + let tail_len = len MOD 16 in + let m = (len - tail_len) DIV 16 in if m < 2 then - aes256_xts_encrypt_tail i m tail P iv key1 key2 + aes256_xts_encrypt_tail 0 tail_len P iv key1 key2 else let res = aes256_xts_encrypt_rec 0 (m - 2) P iv key1 key2 in - let Ctail = aes256_xts_encrypt_tail (THD3 res) m tail P (SND3 res) key1 key2 in - APPEND (FST3 res) Ctail`;; + let Ctail = aes256_xts_encrypt_tail (SND res) tail_len P iv key1 key2 in + APPEND (FST res) Ctail`;; (****) (* Conversions and test vectors *) From 014bd1ae3e044d8a7d5b7c098ba4e93b3f454bbc Mon Sep 17 00:00:00 2001 From: Nevine Ebeid Date: Fri, 5 Sep 2025 18:18:53 -0400 Subject: [PATCH 060/132] Working through the conversions for AES-XTS encrypt test vector. --- arm/proofs/aes_xts_encrypt_spec.ml | 382 +++++++++++++++++++++-------- 1 file changed, 280 insertions(+), 102 deletions(-) diff --git a/arm/proofs/aes_xts_encrypt_spec.ml b/arm/proofs/aes_xts_encrypt_spec.ml index 0e6a9756c..72ef7acd6 100644 --- a/arm/proofs/aes_xts_encrypt_spec.ml +++ b/arm/proofs/aes_xts_encrypt_spec.ml @@ -31,53 +31,6 @@ let aes256_xts_encrypt_one_block = new_definition let encrypted = aes256_encrypt pre_encrypt data_key_schedule in word_xor encrypted T`;; -(* Test case: Basic XTS encryption *) -(* -Test Vector: -Plaintext: 000102030405060708090a0b0c0d0e0f -Data Key: 2718281828459045235360287471352662497757247093699959574966967627 -Tweak Key: 3141592653589793238462643383279502884197169399375105820974944592 -Tweak: FF000000000000000000000000000000 -Expected: 1C3B3A102F770386E4836C99E370CF9B - -The test vector values appear in reverse byte order to be little endian. -*) -(* Test vectors based on our Python implementation results *) -let data_key_schedule = new_definition `data_key_schedule:int128 list = - [ word 0x26357174286053234590452818281827 - ; word 0x27769666495759996993702457774962 - ; word 0x602147C9461436BD6E74659E2BE420B6 - ; word 0x80385664A74EC002EE19999B878AE9BF - ; word 0x206833EF40497426065D429B68292705 - ; word 0xF9A0259D799873F9DED6B3FB30CF2A60 - ; word 0x50CCC26C70A4F18330ED85A536B0C73E - ; word 0x3D6AEAAFC4CACF32BD52BCCB63840F30 - ; word 0x5F1273FB0FDEB1977F7A40144F97C5B1 - ; word 0xE8BF1969D5D5F3C6111F3CF4AC4D803F - ; word 0x99BA4F0DC6A83CF6C9768D61B60CCD75 - ; word 0x6ECCD2B38673CBDA53A6381C42B904E8 - ; word 0x4DF7787AD44D377712E50B81DB9386E0 - ; word 0x1AC8994774044BF4F277802EA1D1B832 - ; word 0xF06E2AC2BD9952B869D465CF7B316E4E - ]`;; - -let tweak_key_schedule = new_definition `tweak_key_schedule:int128 list = - [ word 0x95278333646284239397585326594131 - ; word 0x92459474098205513799931697418802 - ; word 0xD6C4705143E3F36227817741B4162F12 - ; word 0xCD03DBE05F464F9456C44AC5615DD9D3 - ; word 0xE70DA0DB31C9D08A722A23E855AB54A9 - ; word 0x310BE7DBFC083C3BA34E73AFF58A396A - ; word 0x48822C80AF8F8C5B9E465CD1EC6C7F39 - ; word 0xC9D4E0E8F8DF073304D73B08A79948A7 - ; word 0x0EFACBDA4678E75AE9F76B0177B137D0 - ; word 0x39688B23F0BC6BCB08636CF80CB457F0 - ; word 0xF0D6357CFE2CFEA6B85419FC51A372FD - ; word 0x41F54DF0789DC6D38821AD188042C1E0 - ; word 0x6B8E46189B58736465748DC2DD20943E - ; word 0x4E12BD760FE7F086777A3655FF5B9B4D - ; word 0x70ADE5BA1B23A3A2807BD0C6E50F5D04 - ]`;; (* AES-256-XTS Encryption Algorithm for Any Input Length @@ -121,8 +74,8 @@ For partial final blocks, ciphertext stealing is used as per Section 5.3.2. (* TODO: put it in a common place to be used with decrypt Start *) let xts_init_tweak = new_definition - `xts_init_tweak (iv:int128) (key_schedule:int128 list) = - aes256_encrypt iv key_schedule`;; + `xts_init_tweak (iv:int128) (key2:int128 list) = + aes256_encrypt iv key2`;; let bytes_to_int128 = define `bytes_to_int128 (bs : byte list) : int128 = @@ -165,9 +118,9 @@ let calculate_tweak = new_recursive_definition num_RECURSION (* AES-XTS encryption round function *) let aes256_xts_encrypt_round = new_definition - `aes256_xts_encrypt_round (P:int128) (tk:int128) (key_schedule:int128 list) = + `aes256_xts_encrypt_round (P:int128) (tk:int128) (key1:int128 list) = let PP = word_xor P tk in - let CC = aes256_encrypt PP key_schedule in + let CC = aes256_encrypt PP key1 in word_xor CC tk`;; (* Single block AES-XTS encryption *) @@ -261,8 +214,115 @@ let aes256_xts_encrypt = new_definition let Ctail = aes256_xts_encrypt_tail (SND res) tail_len P iv key1 key2 in APPEND (FST res) Ctail`;; -(****) +(***********************************************) (* Conversions and test vectors *) +(* Test case: Basic XTS encryption *) +(* +Test Vector: +Plaintext: 000102030405060708090a0b0c0d0e0f +Data Key: 2718281828459045235360287471352662497757247093699959574966967627 +Tweak Key: 3141592653589793238462643383279502884197169399375105820974944592 +Tweak: FF000000000000000000000000000000 +Expected: 1C3B3A102F770386E4836C99E370CF9B + +The test vector values appear in reverse byte order to be little endian. +*) +(* Test vectors based on our Python implementation results *) +let data_key_schedule = new_definition `data_key_schedule:int128 list = + [ word 0x26357174286053234590452818281827 + ; word 0x27769666495759996993702457774962 + ; word 0x602147C9461436BD6E74659E2BE420B6 + ; word 0x80385664A74EC002EE19999B878AE9BF + ; word 0x206833EF40497426065D429B68292705 + ; word 0xF9A0259D799873F9DED6B3FB30CF2A60 + ; word 0x50CCC26C70A4F18330ED85A536B0C73E + ; word 0x3D6AEAAFC4CACF32BD52BCCB63840F30 + ; word 0x5F1273FB0FDEB1977F7A40144F97C5B1 + ; word 0xE8BF1969D5D5F3C6111F3CF4AC4D803F + ; word 0x99BA4F0DC6A83CF6C9768D61B60CCD75 + ; word 0x6ECCD2B38673CBDA53A6381C42B904E8 + ; word 0x4DF7787AD44D377712E50B81DB9386E0 + ; word 0x1AC8994774044BF4F277802EA1D1B832 + ; word 0xF06E2AC2BD9952B869D465CF7B316E4E + ]`;; + +let tweak_key_schedule = new_definition `tweak_key_schedule:int128 list = + [ word 0x95278333646284239397585326594131 + ; word 0x92459474098205513799931697418802 + ; word 0xD6C4705143E3F36227817741B4162F12 + ; word 0xCD03DBE05F464F9456C44AC5615DD9D3 + ; word 0xE70DA0DB31C9D08A722A23E855AB54A9 + ; word 0x310BE7DBFC083C3BA34E73AFF58A396A + ; word 0x48822C80AF8F8C5B9E465CD1EC6C7F39 + ; word 0xC9D4E0E8F8DF073304D73B08A79948A7 + ; word 0x0EFACBDA4678E75AE9F76B0177B137D0 + ; word 0x39688B23F0BC6BCB08636CF80CB457F0 + ; word 0xF0D6357CFE2CFEA6B85419FC51A372FD + ; word 0x41F54DF0789DC6D38821AD188042C1E0 + ; word 0x6B8E46189B58736465748DC2DD20943E + ; word 0x4E12BD760FE7F086777A3655FF5B9B4D + ; word 0x70ADE5BA1B23A3A2807BD0C6E50F5D04 + ]`;; + +(* + Two-block test vector (same key and tweak as single block) + Plaintext: 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f + Data Key: 2718281828459045235360287471352662497757247093699959574966967627 + Tweak Key: 3141592653589793238462643383279502884197169399375105820974944592 + Tweak: FF000000000000000000000000000000 + Ciphertext: 1C3B3A102F770386E4836C99E370CF9BEA00803F5E482357A4AE12D414A3E63B + Plaintext (reversed): 1F1E1D1C1B1A191817161514131211100F0E0D0C0B0A09080706050403020100 + Ciphertext (reversed): 3BE6A314D412AEA45723485E3F8000EA9BCF70E3996C83E48603772F103A3B1C +*) + +(* Convert reversed plaintext and ciphertext to byte lists using int128_to_bytes *) +let plaintext = new_definition + `plaintext = + int128_to_bytes (word 0x0F0E0D0C0B0A09080706050403020100 : int128)`;; + +let ciphertext = new_definition + `ciphertext = + int128_to_bytes (word 0x9BCF70E3996C83E48603772F103A3B1C : int128 )`;; + +let cerr = new_definition + `cerr = + int128_to_bytes (word 0x0)`;; + +let iv = new_definition + `iv = (word 0x000000000000000000000000000000FF) : int128`;; + +let plaintext2 = new_definition + `plaintext2 = + APPEND (int128_to_bytes (word 0x0F0E0D0C0B0A09080706050403020100)) + (int128_to_bytes (word 0x1F1E1D1C1B1A19181716151413121110))`;; + +(REWR_CONV plaintext2 THENC + RAND_CONV INT128_TO_BYTES_CONV THENC + RATOR_CONV(RAND_CONV INT128_TO_BYTES_CONV) THENC + REWRITE_CONV [APPEND]) `plaintext2`;; + + (REWR_CONV plaintext2 THENC + DEPTH_CONV INT128_TO_BYTES_CONV THENC + (*RATOR_CONV(RAND_CONV INT128_TO_BYTES_CONV) THENC*) + REWRITE_CONV [APPEND]) `plaintext2`;; + + +(* Common with decrypt *) +let XTS_INIT_TWEAK_CONV = + REWR_CONV xts_init_tweak THENC AESENC_HELPER_CONV;; +(* +let tmp_xts_tweak = (REWRITE_CONV [iv; tweak_key_schedule] THENC XTS_INIT_TWEAK_CONV) + `xts_init_tweak iv + tweak_key_schedule`;; +(* Or the following: 33 sec *) +time prove(`xts_init_tweak iv + tweak_key_schedule + = word 0x8b2b4a71228e98aed6aa0ca97775261a`, + CONV_TAC(REWRITE_CONV [iv; tweak_key_schedule] THENC LAND_CONV XTS_INIT_TWEAK_CONV) + THEN REFL_TAC + );; +*) + let AES_XTS_ENC_1BLK_HELPER_CONV = (* PRINT_TERM_CONV THENC *) REWR_CONV aes256_xts_encrypt_1block THENC @@ -275,7 +335,6 @@ let AES_XTS_ENC_1BLK_HELPER_CONV = DEPTH_CONV AESENC_HELPER_CONV THENC DEPTH_CONV (WORD_RED_CONV ORELSEC NUM_RED_CONV) ;; - (* (* Proven in about 100 sec on M3 *) time prove(`aes256_xts_encrypt_1block @@ -302,60 +361,179 @@ prove(list_mk_comb (`(=):((128)word->(128)word->bool)`, REFL_TAC);; *) +let AES256_XTS_ENCRYPT_ROUND_CONV = + REWR_CONV aes256_xts_encrypt_round THENC + REPEATC let_CONV THENC + DEPTH_CONV (WORD_RED_CONV ORELSEC NUM_RED_CONV) THENC + DEPTH_CONV AESENC_HELPER_CONV THENC + DEPTH_CONV (WORD_RED_CONV ORELSEC NUM_RED_CONV);; +(*(* 32 sec *) +time prove(`aes256_xts_encrypt_round + (word 0x0F0E0D0C0B0A09080706050403020100) + (word 0x8b2b4a71228e98aed6aa0ca97775261a) + data_key_schedule + = word 0x9BCF70E3996C83E48603772F103A3B1C`, + CONV_TAC(REWRITE_CONV[data_key_schedule] THENC LAND_CONV AES256_XTS_ENCRYPT_ROUND_CONV) THEN + REFL_TAC + );; *) + +(* Common with decrypt *) +let EL_16_8_CLAUSES = + let pat = `EL n [x0;x1;x2;x3;x4;x5;x6;x7;x8;x9;x10;x11;x12;x13;x14;x15]:byte` in + map (fun n -> EL_CONV(subst [mk_small_numeral n,`n:num`] pat)) (0--15);; + +let BYTES_TO_INT128_CONV = + REWR_CONV bytes_to_int128 THENC + REWRITE_CONV EL_16_8_CLAUSES THENC + DEPTH_CONV WORD_RED_CONV;; (* - Two-block test vector (same key and tweak as single block) - Plaintext: 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f - Data Key: 2718281828459045235360287471352662497757247093699959574966967627 - Tweak Key: 3141592653589793238462643383279502884197169399375105820974944592 - Tweak: FF000000000000000000000000000000 - Ciphertext: 1C3B3A102F770386E4836C99E370CF9BEA00803F5E482357A4AE12D414A3E63B - Plaintext (reversed): 1F1E1D1C1B1A191817161514131211100F0E0D0C0B0A09080706050403020100 - Ciphertext (reversed): 3BE6A314D412AEA45723485E3F8000EA9BCF70E3996C83E48603772F103A3B1C +time prove(`bytes_to_int128 plaintext + = (word 0x0f0e0d0c0b0a09080706050403020100 :int128)`, + CONV_TAC(REWRITE_CONV [plaintext;int128_to_bytes] THENC + LAND_CONV BYTES_TO_INT128_CONV) THEN + REFL_TAC + );; *) -(* Convert reversed plaintext and ciphertext to byte lists using int128_to_bytes *) -let plaintext = new_definition - `plaintext = - int128_to_bytes (word 0x1F1E1D1C1B1A191817161514131211100F0E0D0C0B0A09080706050403020100)`;; +(* Common with decrypt *) +let INT128_TO_BYTES_CONV = + REWRITE_CONV [int128_to_bytes] THENC + DEPTH_CONV WORD_RED_CONV;; +(* INT128_TO_BYTES_CONV `int128_to_bytes (word 0x0102030405060708090a0b0c0d0e0f)`;; *) -let ciphertext = new_definition - `ciphertext = - int128_to_bytes (word 0x3BE6A314D412AEA45723485E3F8000EA9BCF70E3996C83E48603772F103A3B1C)`;; - -let cerr = new_definition - `cerr = - int128_to_bytes (word 0x0)`;; - -(* Generated by Cline but not needed -(* Two-block plaintext for testing *) -let two_block_plaintext = new_definition - `two_block_plaintext = - APPEND (int128_to_bytes (word 0x0F0E0D0C0B0A09080706050403020100)) - (int128_to_bytes (word 0x1F1E1D1C1B1A19181716151413121110))`;; -*) - -(* This was generated by Cline, to review *) -(* Conversion for aes256_xts_encrypt using the byte lists *) -let AES_XTS_ENC_HELPER_CONV = -(* PRINT_TERM_CONV THENC *) - REWR_CONV aes256_xts_encrypt THENC - PRINT_TERM_CONV THENC - REWRITE_CONV [data_key_schedule; tweak_key_schedule; plaintext; ciphertext; C_err] THENC - (* PRINT_TERM_CONV THENC *) - REWRITE_CONV [xts_init_tweak; aes256_xts_encrypt_round; aes256_xts_encrypt_tail; - aes256_xts_encrypt_rec; cipher_stealing_encrypt] THENC - REWRITE_CONV [int128_to_bytes; bytes_to_int128; SUB_LIST; APPEND; EL] THENC +(* Common with decrypt *) +let GF_128_MULT_BY_PRIMITIVE_CONV = + REWRITE_CONV [GF_128_mult_by_primitive] THENC REPEATC let_CONV THENC - DEPTH_CONV (WORD_RED_CONV ORELSEC NUM_RED_CONV) THENC - DEPTH_CONV AESENC_HELPER_CONV THENC - DEPTH_CONV (WORD_RED_CONV ORELSEC NUM_RED_CONV) - ;; - - let tmp_xts_enc = AES_XTS_ENC_HELPER_CONV - `aes256_xts_encrypt plaintext 32 (word 0x000000000000000000000000000000FF) - data_key_schedule - tweak_key_schedule C_error - `;; + DEPTH_CONV WORD_RED_CONV;; +(* GF_128_MULT_BY_PRIMITIVE_CONV + `GF_128_mult_by_primitive (word 0x8b2b4a71228e98aed6aa0ca97775261a)`;; *) +time prove(`GF_128_mult_by_primitive (word 0x8b2b4a71228e98aed6aa0ca97775261a) + = (word 0x165694e2451d315dad541952eeea4cb3 : int128)`, + CONV_TAC(LAND_CONV GF_128_MULT_BY_PRIMITIVE_CONV) THEN REFL_TAC + );; + +let rec CALCULATE_TWEAK_CONV tm = + let BASE_CONV = + ONCE_REWRITE_CONV [calculate_tweak] THENC + XTS_INIT_TWEAK_CONV in + let INDUCT_CONV = + RATOR_CONV(LAND_CONV num_CONV) THENC (* ((calculate_tweak 1) iv_tweak) KEY2 *) + (* PRINT_TERM_CONV THENC*) + ONCE_REWRITE_CONV [CONJUNCT2 calculate_tweak] THENC + RAND_CONV CALCULATE_TWEAK_CONV THENC + GF_128_MULT_BY_PRIMITIVE_CONV in + match tm with + | Comb + (Comb + (Comb + (Const ("calculate_tweak",_), n), + _), + _) -> + if dest_numeral n =/ num 0 + then BASE_CONV tm + else INDUCT_CONV tm + | _ -> failwith "CALCULATE_TWEAK_CONV: inapplicable";; + +(REWRITE_CONV [iv;tweak_key_schedule] THENC CALCULATE_TWEAK_CONV) `calculate_tweak 0 iv tweak_key_schedule`;; + +(REWRITE_CONV [iv;tweak_key_schedule] THENC CALCULATE_TWEAK_CONV) `calculate_tweak 1 iv tweak_key_schedule`;; + +let rec AES256_XTS_ENCRYPT_REC_CONV tm = + let BASE_CONV = + REWR_CONV aes256_xts_encrypt_rec THENC + DEPTH_CONV NUM_RED_CONV in + let INDUCT_CONV = + REWR_CONV aes256_xts_encrypt_rec THENC + DEPTH_CONV NUM_RED_CONV THENC + ONCE_DEPTH_CONV SUB_LIST_CONV THENC + ONCE_DEPTH_CONV BYTES_TO_INT128_CONV THENC let_CONV THENC + SUBLET_CONV CALCULATE_TWEAK_CONV THENC let_CONV THENC + SUBLET_CONV (RAND_CONV AES256_XTS_ENCRYPT_ROUND_CONV) THENC + SUBLET_CONV INT128_TO_BYTES_CONV THENC let_CONV THENC + SUBLET_CONV AES256_XTS_ENCRYPT_REC_CONV THENC let_CONV THENC + REWRITE_CONV [FST;SND;APPEND] in + match tm with + | Comb + (Comb + (Comb + (Comb + (Comb + (Comb (Const ("aes256_xts_encrypt_rec", _), i), m), + _), + _), + _), + _) -> + if dest_numeral m failwith "AES256_XTS_ENCRYPT_REC_CONV: inapplicable";; + +(REWRITE_CONV [iv; data_key_schedule; tweak_key_schedule; plaintext; int128_to_bytes] THENC + AES256_XTS_ENCRYPT_REC_CONV) + `aes256_xts_encrypt_rec 0 0 plaintext iv data_key_schedule tweak_key_schedule`;; + +let CIPHER_STEALING_ENCRYPT_CONV = + REWRITE_CONV [cipher_stealing_encrypt] THENC + SUBLET_CONV CALCULATE_TWEAK_CONV THENC let_CONV THENC + SUBLET_CONV (ONCE_DEPTH_CONV BYTES_TO_INT128_CONV) THENC + SUBLET_CONV (RAND_CONV AES256_XTS_ENCRYPT_ROUND_CONV) THENC + SUBLET_CONV INT128_TO_BYTES_CONV THENC let_CONV THENC + SUBLET_CONV SUB_LIST_CONV THENC let_CONV THENC + SUBLET_CONV (DEPTH_CONV NUM_RED_CONV) THENC (* For evaluating 16 - tail_len *) + SUBLET_CONV SUB_LIST_CONV THENC let_CONV THENC + SUBLET_CONV (ONCE_DEPTH_CONV (REWRITE_CONV [APPEND])) THENC + SUBLET_CONV BYTES_TO_INT128_CONV THENC let_CONV THENC + SUBLET_CONV GF_128_MULT_BY_PRIMITIVE_CONV THENC let_CONV THENC + SUBLET_CONV (RAND_CONV AES256_XTS_ENCRYPT_ROUND_CONV) THENC + SUBLET_CONV INT128_TO_BYTES_CONV THENC let_CONV;; + +(REWRITE_CONV [plaintext; int128_to_bytes; iv; data_key_schedule; tweak_key_schedule] THENC CIPHER_STEALING_ENCRYPT_CONV) + `cipher_stealing_encrypt plaintext [(word 0x0)] 1 iv 0 data_key_schedule tweak_key_schedule`;; + +let AES256_XTS_ENCRYPT_TAIL_CONV tm = + let ONE_BLOCK_CONV = + REWR_CONV aes256_xts_encrypt_tail THENC + DEPTH_CONV NUM_RED_CONV THENC + SUBLET_CONV (RAND_CONV SUB_LIST_CONV) THENC + SUBLET_CONV BYTES_TO_INT128_CONV THENC let_CONV THENC + SUBLET_CONV CALCULATE_TWEAK_CONV THENC let_CONV THENC + RAND_CONV AES256_XTS_ENCRYPT_ROUND_CONV THENC + INT128_TO_BYTES_CONV in + let ONE_BLOCK_AND_TAIL_CONV = + REWR_CONV aes256_xts_encrypt_tail THENC + DEPTH_CONV NUM_RED_CONV THENC + SUBLET_CONV SUB_LIST_CONV THENC let_CONV THENC + SUBLET_CONV SUB_LIST_CONV THENC let_CONV THENC + SUBLET_CONV CIPHER_STEALING_ENCRYPT_CONV THENC let_CONV THENC + REWRITE_CONV [FST;SND] THENC REWRITE_CONV [APPEND] in + match tm with + | Comb + (Comb + (Comb + (Comb + (Comb + (Comb + (Const ("aes256_xts_encrypt_tail", _), _), tail_len), + _), + _), + _), + _) -> + if dest_numeral tail_len =/ num 0 + then ONE_BLOCK_CONV tm + else ONE_BLOCK_AND_TAIL_CONV tm + | _ -> failwith "AES256_XTS_ENCRYPT_TAIL_CONV: inapplicable";; + + +(REWRITE_CONV [plaintext; int128_to_bytes; iv; data_key_schedule; tweak_key_schedule] THENC AES256_XTS_ENCRYPT_TAIL_CONV) + `aes256_xts_encrypt_tail 0 0 plaintext iv data_key_schedule tweak_key_schedule`;; + +(* The following values were sent to the REPL from aes_xts_decrypt_spec.ml *) +(REWRITE_CONV [p1;iv_tweak;KEY1;KEY2] THENC AES256_XTS_ENCRYPT_TAIL_CONV) + `aes256_xts_encrypt_tail 0 6 p1 iv_tweak KEY1 KEY2`;; + +(REWRITE_CONV [p0;iv_tweak;KEY1;KEY2] THENC AES256_XTS_ENCRYPT_TAIL_CONV) + `aes256_xts_encrypt_tail 0 0 p0 iv_tweak KEY1 KEY2`;; (*****************************************) (* Test key schedules from the decryption spec *) From 2ea0b4dc11b22f58ee7d329ca226e9398a928c7c Mon Sep 17 00:00:00 2001 From: Nevine Ebeid Date: Mon, 8 Sep 2025 18:28:39 -0400 Subject: [PATCH 061/132] Fixed a bug in cipher_stealing_encrypt in the computation of the last tweak. It was using the input iv value, while it should be using the tweak that was calculated in the step before using calculate_tweak. Used the test vectors used in aes_xts_decrypt_spec.ml after modifying the key schedule of the data key to be as should be used in encryption. The one used in decryption is different so as to accommodate EQINVCIPHER; a more efficient decryption algorithm defined in FIPS 197 and used in AWS-LC. --- arm/proofs/aes_xts_encrypt_spec.ml | 304 +++++++++++++++++++---------- 1 file changed, 201 insertions(+), 103 deletions(-) diff --git a/arm/proofs/aes_xts_encrypt_spec.ml b/arm/proofs/aes_xts_encrypt_spec.ml index 72ef7acd6..e3060949e 100644 --- a/arm/proofs/aes_xts_encrypt_spec.ml +++ b/arm/proofs/aes_xts_encrypt_spec.ml @@ -159,12 +159,12 @@ let cipher_stealing_encrypt = new_definition `cipher_stealing_encrypt (Pm1:byte list) (Pm:byte list) (tail_len:num) (iv:int128) (i:num) (key1:int128 list) (key2:int128 list): (byte list)#(byte list) = let twk = calculate_tweak i iv key2 in + let twk_last = GF_128_mult_by_primitive twk in let CC = int128_to_bytes (aes256_xts_encrypt_round (bytes_to_int128 Pm1) twk key1) in let Cm = SUB_LIST (0, tail_len) CC in let CP = SUB_LIST (tail_len, 16 - tail_len) CC in let PP = bytes_to_int128 (APPEND Pm CP) in - let iv_last = GF_128_mult_by_primitive iv in - let Cm1 = int128_to_bytes (aes256_xts_encrypt_round PP iv_last key1) in + let Cm1 = int128_to_bytes (aes256_xts_encrypt_round PP twk_last key1) in (Cm1, Cm)`;; (* Encryption tail handling - either single block or cipher stealing *) @@ -224,6 +224,8 @@ Data Key: 2718281828459045235360287471352662497757247093699959574966967627 Tweak Key: 3141592653589793238462643383279502884197169399375105820974944592 Tweak: FF000000000000000000000000000000 Expected: 1C3B3A102F770386E4836C99E370CF9B + Plaintext (reversed): 0F0E0D0C0B0A09080706050403020100 + Ciphertext (reversed): 9BCF70E3996C83E48603772F103A3B1C The test vector values appear in reverse byte order to be little endian. *) @@ -266,13 +268,13 @@ let tweak_key_schedule = new_definition `tweak_key_schedule:int128 list = (* Two-block test vector (same key and tweak as single block) - Plaintext: 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f + Plaintext: 000102030405060708090a0b0c0d0e0f 101112131415161718191a1b1c1d1e1f Data Key: 2718281828459045235360287471352662497757247093699959574966967627 Tweak Key: 3141592653589793238462643383279502884197169399375105820974944592 Tweak: FF000000000000000000000000000000 - Ciphertext: 1C3B3A102F770386E4836C99E370CF9BEA00803F5E482357A4AE12D414A3E63B - Plaintext (reversed): 1F1E1D1C1B1A191817161514131211100F0E0D0C0B0A09080706050403020100 - Ciphertext (reversed): 3BE6A314D412AEA45723485E3F8000EA9BCF70E3996C83E48603772F103A3B1C + Ciphertext: 1C3B3A102F770386E4836C99E370CF9B EA00803F5E482357A4AE12D414A3E63B + Plaintext (reversed): 0F0E0D0C0B0A09080706050403020100 1F1E1D1C1B1A19181716151413121110 + Ciphertext (reversed): 9BCF70E3996C83E48603772F103A3B1C 3BE6A314D412AEA45723485E3F8000EA *) (* Convert reversed plaintext and ciphertext to byte lists using int128_to_bytes *) @@ -301,10 +303,107 @@ let plaintext2 = new_definition RATOR_CONV(RAND_CONV INT128_TO_BYTES_CONV) THENC REWRITE_CONV [APPEND]) `plaintext2`;; + (* loops indefinitely (REWR_CONV plaintext2 THENC DEPTH_CONV INT128_TO_BYTES_CONV THENC (*RATOR_CONV(RAND_CONV INT128_TO_BYTES_CONV) THENC*) REWRITE_CONV [APPEND]) `plaintext2`;; +*) + +(* Test values from aes_xts_decrypt_spec.ml *) + let iv_tweak = new_definition + `iv_tweak = (word 0x0000000000000000000000123456789a) : int128`;; + +let pm1 = new_definition + `pm1 = [word 0x0; word 0x1; word 0x2; word 0x3; + word 0x4; word 0x5; word 0x6; word 0x7; + word 0x8; word 0x9; word 0xa; word 0xb; + word 0xc; word 0xd; word 0xe; word 0xf] : byte list`;; +let pm = new_definition + `pm = [word 0x10; word 0x11; word 0x12; word 0x13; + word 0x14; word 0x15] : byte list`;; + +let cm1 = new_definition + `cm1 = [word 0x75; word 0xe8; word 0x18; word 0x8b; word 0xcc; word 0xe5; + word 0x9a; word 0xda; word 0x93; word 0x9f; word 0x57; word 0xde; + word 0x2c; word 0xb9; word 0xa4; word 0x89] : byte list`;; +let cm = new_definition + `cm = [word 0xc3; word 0xc; word 0xa8; word 0xf2; word 0xed; word 0x57] : byte list`;; + +let p1 = new_definition + `p1 = [word 0x0; word 0x1; word 0x2; word 0x3; + word 0x4; word 0x5; word 0x6; word 0x7; + word 0x8; word 0x9; word 0xa; word 0xb; + word 0xc; word 0xd; word 0xe; word 0xf; + word 0x10; word 0x11; word 0x12; word 0x13; + word 0x14; word 0x15] : byte list`;; + +let c1 = new_definition + `c1 = [ word 0x75; word 0xe8; word 0x18; word 0x8b; + word 0xcc; word 0xe5; word 0x9a; word 0xda; + word 0x93; word 0x9f; word 0x57; word 0xde; + word 0x2c; word 0xb9; word 0xa4; word 0x89; + word 0xc3; word 0x0c; word 0xa8; word 0xf2; + word 0xed; word 0x57 ] : byte list`;; +(* +(* This key schedule is from aes_xts_decrypt_spec.ml + It is used in EQINVCIPHER found in Sec 5.3.5 of + https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.197-upd1.pdf + which is implemented in AWS-LC as the AES decryption algorithm. + It's different from the encryption key scheduling. *) +let key_1 = new_definition `key_1:int128 list = + [ word 0xc70a951e84370d1836bdd387607e94e5 + ; word 0x7ead95d6f74bf6b3103340cce21b473d + ; word 0x298c296cdf3241d53d0757ddbebda060 + ; word 0x89e66365e778b67ff22807f1cdc91c8f + ; word 0xf6be68b9e235160883baf7bd2340b902 + ; word 0x6e9ed51a1550b18e3fe11b7e185c513e + ; word 0x148b7eb1618fe1b5a0fa4ebf336ae76e + ; word 0x7bce64942ab1aaf027bd4a40982968cd + ; word 0x75049f04c175af0a9390a9d1d91a6526 + ; word 0x517fce640d0ce0b0bf94228de7e3085d + ; word 0xb471300e52e506db4a8accf7a81afe26 + ; word 0x5c732ed4b298c23d58772ad0be94ce31 + ; word 0xe69436d5186fca2ce29032d11463c620 + ; word 0xeeebece9eaefe8ede6e3e4e1e2e7e0e5 + ; word 0xf0f1f2f3f4f5f6f7f8f9fafbfcfdfeff + ]`;; +*) +let key_1 = new_definition `key_1:int128 list = + [ word 0xF0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF + ; word 0xE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEF + ; word 0x11E1F899E1100A6A15E5FC9DED1C0666 + ; word 0x82F841EE6219A30D86FC45EA6E15AF01 + ; word 0x201B498931FAB110D0EABB7AC50F47E7 + ; word 0xBFA733AF3D5F72415F46D14CD9BA94A6 + ; word 0x7D0C58C35D17114A6CEDA05ABC071B20 + ; word 0xFBFA6E2A445D5D8579022FC42644FE88 + ; word 0x15FEDF6468F287A735E596ED590836B7 + ; word 0xB95A7CA042A0128A06FD4F0F7FFF60CB + ; word 0xF1B74699E44999FD8CBB1E5AB95E88B7 + ; word 0x23511B009A0B67A0D8AB752ADE563A25 + ; word 0x433D9806B28ADE9F56C34762DA785938 + ; word 0xA58075C086D16EC01CDA0960C4717C4A + ; word 0xC70A951E84370D1836BDD387607E94E5 + ]`;; + +let key_2 = new_definition `key_2:int128 list = + [ word 0xb0b1b2b3b4b5b6b7b8b9babbbcbdbebf + ; word 0xa0a1a2a3a4a5a6a7a8a9aaabacadaeaf + ; word 0x0ae0323bba5180880ee4363fb65d8c84 + ; word 0x67e123e2c740814163e527e6cb4c8d4d + ; word 0x908df02c9a6dc217203c429f2ed874a0 + ; word 0x685584790fb4a79bc8f426daab11013c + ; word 0xb241f85f22cc0873b8a1ca64989d88fb + ; word 0x338745cb5bd2c1b2546666299c9240f3 + ; word 0xaf72a5d51d335d8a3fff55f9875e9f9d + ; word 0xd9e1a4a0ea66e16bb1b420d9e5d246f0 + ; word 0xead5ca6245a76fb75894323d676b67c4 + ; word 0xe0e257483903f3e8d365128362d1325a + ; word 0xc26c685728b9a2356d1ecd82358affbf + ; word 0x4d05c122ade7966a94e4658247817701 + ; word 0x21a29367e3cefb30cb775905a6699487 + ]`;; (* Common with decrypt *) @@ -323,6 +422,7 @@ time prove(`xts_init_tweak iv );; *) +(* let AES_XTS_ENC_1BLK_HELPER_CONV = (* PRINT_TERM_CONV THENC *) REWR_CONV aes256_xts_encrypt_1block THENC @@ -335,18 +435,53 @@ let AES_XTS_ENC_1BLK_HELPER_CONV = DEPTH_CONV AESENC_HELPER_CONV THENC DEPTH_CONV (WORD_RED_CONV ORELSEC NUM_RED_CONV) ;; +*) +let AES256_XTS_ENCRYPT_ROUND_CONV = + REWR_CONV aes256_xts_encrypt_round THENC + REPEATC let_CONV THENC + DEPTH_CONV (WORD_RED_CONV ORELSEC NUM_RED_CONV) THENC + DEPTH_CONV AESENC_HELPER_CONV THENC + DEPTH_CONV (WORD_RED_CONV ORELSEC NUM_RED_CONV);; +(* +(* 32 sec *) +time prove(`aes256_xts_encrypt_round + (word 0x0F0E0D0C0B0A09080706050403020100) + (word 0x8b2b4a71228e98aed6aa0ca97775261a) + data_key_schedule + = word 0x9BCF70E3996C83E48603772F103A3B1C`, + CONV_TAC(REWRITE_CONV[data_key_schedule] THENC LAND_CONV AES256_XTS_ENCRYPT_ROUND_CONV) THEN + REFL_TAC + );; +*) (* -(* Proven in about 100 sec on M3 *) +time prove(`aes256_xts_encrypt_round + (word 0x1F1E1D1C1B1A19181716151413121110) + (word 0x165694e2451d315dad541952eeea4cb3) + data_key_schedule + = word 0x3BE6A314D412AEA45723485E3F8000EA`, + CONV_TAC(REWRITE_CONV[data_key_schedule] THENC LAND_CONV AES256_XTS_ENCRYPT_ROUND_CONV) THEN + REFL_TAC + );; +*) + +let AES_XTS_ENC_1BLK_HELPER_CONV = + REWR_CONV aes256_xts_encrypt_1block THENC + REWRITE_CONV [xts_init_tweak] THENC + SUBLET_CONV AESENC_HELPER_CONV THENC + let_CONV THENC + AES256_XTS_ENCRYPT_ROUND_CONV;; + ;; +(* Proven in about 73 sec on M3 *) time prove(`aes256_xts_encrypt_1block (word 0x0F0E0D0C0B0A09080706050403020100) (word 0x000000000000000000000000000000FF) data_key_schedule tweak_key_schedule = word 0x9BCF70E3996C83E48603772F103A3B1C`, (* expected result in little endian *) - CONV_TAC(LAND_CONV AES_XTS_ENC_1BLK_HELPER_CONV) + CONV_TAC(REWRITE_CONV [data_key_schedule; tweak_key_schedule] THENC LAND_CONV AES_XTS_ENC_1BLK_HELPER_CONV) THEN REFL_TAC );; -*) + (* let tmp_xts = AES_XTS_ENC_1BLK_HELPER_CONV `aes256_xts_encrypt_1block @@ -360,22 +495,17 @@ prove(list_mk_comb (`(=):((128)word->(128)word->bool)`, [rand (concl tmp_xts);`(word 0x9BCF70E3996C83E48603772F103A3B1C):(128)word`]), REFL_TAC);; *) +time prove(`aes256_xts_encrypt_1block + (word 0x0F0E0D0C0B0A09080706050403020100) + (word 0x0000000000000000000000123456789a) + key_1 + key_2 + = word 0x88c87a8644e587dc7e3057edf2a80cc3`, (* expected result in little endian *) + CONV_TAC(REWRITE_CONV [key_1; key_2] THENC LAND_CONV AES_XTS_ENC_1BLK_HELPER_CONV) + THEN REFL_TAC + );; -let AES256_XTS_ENCRYPT_ROUND_CONV = - REWR_CONV aes256_xts_encrypt_round THENC - REPEATC let_CONV THENC - DEPTH_CONV (WORD_RED_CONV ORELSEC NUM_RED_CONV) THENC - DEPTH_CONV AESENC_HELPER_CONV THENC - DEPTH_CONV (WORD_RED_CONV ORELSEC NUM_RED_CONV);; -(*(* 32 sec *) -time prove(`aes256_xts_encrypt_round - (word 0x0F0E0D0C0B0A09080706050403020100) - (word 0x8b2b4a71228e98aed6aa0ca97775261a) - data_key_schedule - = word 0x9BCF70E3996C83E48603772F103A3B1C`, - CONV_TAC(REWRITE_CONV[data_key_schedule] THENC LAND_CONV AES256_XTS_ENCRYPT_ROUND_CONV) THEN - REFL_TAC - );; *) +(* answer with the old key_1: word 0x494ba756143b3d88b6f8a44fba9d2228 *) (* Common with decrypt *) let EL_16_8_CLAUSES = @@ -418,7 +548,7 @@ let rec CALCULATE_TWEAK_CONV tm = ONCE_REWRITE_CONV [calculate_tweak] THENC XTS_INIT_TWEAK_CONV in let INDUCT_CONV = - RATOR_CONV(LAND_CONV num_CONV) THENC (* ((calculate_tweak 1) iv_tweak) KEY2 *) + RATOR_CONV(LAND_CONV num_CONV) THENC (* ((calculate_tweak 1) iv_tweak) key_2 *) (* PRINT_TERM_CONV THENC*) ONCE_REWRITE_CONV [CONJUNCT2 calculate_tweak] THENC RAND_CONV CALCULATE_TWEAK_CONV THENC @@ -434,10 +564,13 @@ let rec CALCULATE_TWEAK_CONV tm = then BASE_CONV tm else INDUCT_CONV tm | _ -> failwith "CALCULATE_TWEAK_CONV: inapplicable";; - +(* +(* result: word 0x8b2b4a71228e98aed6aa0ca97775261a, confirmed by input to first encrypt_round above *) (REWRITE_CONV [iv;tweak_key_schedule] THENC CALCULATE_TWEAK_CONV) `calculate_tweak 0 iv tweak_key_schedule`;; - +*)(* +(* result: word 0x165694e2451d315dad541952eeea4cb3, confirmed by input to second encrypt_round above *) (REWRITE_CONV [iv;tweak_key_schedule] THENC CALCULATE_TWEAK_CONV) `calculate_tweak 1 iv tweak_key_schedule`;; +*) let rec AES256_XTS_ENCRYPT_REC_CONV tm = let BASE_CONV = @@ -469,10 +602,22 @@ let rec AES256_XTS_ENCRYPT_REC_CONV tm = else INDUCT_CONV tm | _ -> failwith "AES256_XTS_ENCRYPT_REC_CONV: inapplicable";; +(* (REWRITE_CONV [iv; data_key_schedule; tweak_key_schedule; plaintext; int128_to_bytes] THENC AES256_XTS_ENCRYPT_REC_CONV) `aes256_xts_encrypt_rec 0 0 plaintext iv data_key_schedule tweak_key_schedule`;; +*) (* +(REWRITE_CONV [iv_tweak; pm1; key_1; key_2] THENC + AES256_XTS_ENCRYPT_REC_CONV) + `aes256_xts_encrypt_rec 0 0 pm1 iv_tweak key_1 key_2`;; +*) +(* +(REWRITE_CONV [iv; data_key_schedule; tweak_key_schedule; plaintext2; int128_to_bytes; APPEND] THENC + AES256_XTS_ENCRYPT_REC_CONV) + `aes256_xts_encrypt_rec 0 1 plaintext2 iv data_key_schedule tweak_key_schedule`;; +*) +(* let CIPHER_STEALING_ENCRYPT_CONV = REWRITE_CONV [cipher_stealing_encrypt] THENC SUBLET_CONV CALCULATE_TWEAK_CONV THENC let_CONV THENC @@ -487,9 +632,28 @@ let CIPHER_STEALING_ENCRYPT_CONV = SUBLET_CONV GF_128_MULT_BY_PRIMITIVE_CONV THENC let_CONV THENC SUBLET_CONV (RAND_CONV AES256_XTS_ENCRYPT_ROUND_CONV) THENC SUBLET_CONV INT128_TO_BYTES_CONV THENC let_CONV;; +*) +let CIPHER_STEALING_ENCRYPT_CONV = + REWR_CONV cipher_stealing_encrypt THENC + SUBLET_CONV CALCULATE_TWEAK_CONV THENC let_CONV THENC + SUBLET_CONV GF_128_MULT_BY_PRIMITIVE_CONV THENC let_CONV THENC + SUBLET_CONV (ONCE_DEPTH_CONV BYTES_TO_INT128_CONV) THENC + SUBLET_CONV (RAND_CONV AES256_XTS_ENCRYPT_ROUND_CONV) THENC + SUBLET_CONV INT128_TO_BYTES_CONV THENC let_CONV THENC + SUBLET_CONV SUB_LIST_CONV THENC let_CONV THENC + SUBLET_CONV (DEPTH_CONV NUM_RED_CONV) THENC (* For evaluating 16 - tail_len *) + SUBLET_CONV SUB_LIST_CONV THENC let_CONV THENC + SUBLET_CONV (ONCE_DEPTH_CONV (REWRITE_CONV [APPEND])) THENC + SUBLET_CONV BYTES_TO_INT128_CONV THENC let_CONV THENC + SUBLET_CONV (RAND_CONV AES256_XTS_ENCRYPT_ROUND_CONV) THENC + SUBLET_CONV INT128_TO_BYTES_CONV THENC let_CONV;; -(REWRITE_CONV [plaintext; int128_to_bytes; iv; data_key_schedule; tweak_key_schedule] THENC CIPHER_STEALING_ENCRYPT_CONV) - `cipher_stealing_encrypt plaintext [(word 0x0)] 1 iv 0 data_key_schedule tweak_key_schedule`;; +(* (REWRITE_CONV [plaintext; int128_to_bytes; iv; data_key_schedule; tweak_key_schedule] THENC CIPHER_STEALING_ENCRYPT_CONV) + `cipher_stealing_encrypt plaintext [(word 0x0)] 1 iv 0 data_key_schedule tweak_key_schedule`;;*) +(* +(REWRITE_CONV [pm1; pm; iv_tweak; key_1; key_2] THENC CIPHER_STEALING_ENCRYPT_CONV) + `cipher_stealing_encrypt pm1 pm 6 iv_tweak 0 key_1 key_2`;; +*) let AES256_XTS_ENCRYPT_TAIL_CONV tm = let ONE_BLOCK_CONV = @@ -523,83 +687,17 @@ let AES256_XTS_ENCRYPT_TAIL_CONV tm = then ONE_BLOCK_CONV tm else ONE_BLOCK_AND_TAIL_CONV tm | _ -> failwith "AES256_XTS_ENCRYPT_TAIL_CONV: inapplicable";; - - +(* (REWRITE_CONV [plaintext; int128_to_bytes; iv; data_key_schedule; tweak_key_schedule] THENC AES256_XTS_ENCRYPT_TAIL_CONV) `aes256_xts_encrypt_tail 0 0 plaintext iv data_key_schedule tweak_key_schedule`;; - -(* The following values were sent to the REPL from aes_xts_decrypt_spec.ml *) -(REWRITE_CONV [p1;iv_tweak;KEY1;KEY2] THENC AES256_XTS_ENCRYPT_TAIL_CONV) - `aes256_xts_encrypt_tail 0 6 p1 iv_tweak KEY1 KEY2`;; - -(REWRITE_CONV [p0;iv_tweak;KEY1;KEY2] THENC AES256_XTS_ENCRYPT_TAIL_CONV) - `aes256_xts_encrypt_tail 0 0 p0 iv_tweak KEY1 KEY2`;; -(*****************************************) -(* Test key schedules from the decryption spec *) - -let KEY1 = new_definition `KEY1:int128 list = - [ word 0xc70a951e84370d1836bdd387607e94e5 - ; word 0x7ead95d6f74bf6b3103340cce21b473d - ; word 0x298c296cdf3241d53d0757ddbebda060 - ; word 0x89e66365e778b67ff22807f1cdc91c8f - ; word 0xf6be68b9e235160883baf7bd2340b902 - ; word 0x6e9ed51a1550b18e3fe11b7e185c513e - ; word 0x148b7eb1618fe1b5a0fa4ebf336ae76e - ; word 0x7bce64942ab1aaf027bd4a40982968cd - ; word 0x75049f04c175af0a9390a9d1d91a6526 - ; word 0x517fce640d0ce0b0bf94228de7e3085d - ; word 0xb471300e52e506db4a8accf7a81afe26 - ; word 0x5c732ed4b298c23d58772ad0be94ce31 - ; word 0xe69436d5186fca2ce29032d11463c620 - ; word 0xeeebece9eaefe8ede6e3e4e1e2e7e0e5 - ; word 0xf0f1f2f3f4f5f6f7f8f9fafbfcfdfeff - ]`;; - -let KEY2 = new_definition `KEY2:int128 list = - [ word 0xb0b1b2b3b4b5b6b7b8b9babbbcbdbebf - ; word 0xa0a1a2a3a4a5a6a7a8a9aaabacadaeaf - ; word 0x0ae0323bba5180880ee4363fb65d8c84 - ; word 0x67e123e2c740814163e527e6cb4c8d4d - ; word 0x908df02c9a6dc217203c429f2ed874a0 - ; word 0x685584790fb4a79bc8f426daab11013c - ; word 0xb241f85f22cc0873b8a1ca64989d88fb - ; word 0x338745cb5bd2c1b2546666299c9240f3 - ; word 0xaf72a5d51d335d8a3fff55f9875e9f9d - ; word 0xd9e1a4a0ea66e16bb1b420d9e5d246f0 - ; word 0xead5ca6245a76fb75894323d676b67c4 - ; word 0xe0e257483903f3e8d365128362d1325a - ; word 0xc26c685728b9a2356d1ecd82358affbf - ; word 0x4d05c122ade7966a94e4658247817701 - ; word 0x21a29367e3cefb30cb775905a6699487 - ]`;; - +*)(* +(REWRITE_CONV [p1;iv_tweak;key_1;key_2] THENC AES256_XTS_ENCRYPT_TAIL_CONV) + `aes256_xts_encrypt_tail 0 6 p1 iv_tweak key_1 key_2`;; +*)(* +(REWRITE_CONV [p0;iv_tweak;key_1;key_2] THENC AES256_XTS_ENCRYPT_TAIL_CONV) + `aes256_xts_encrypt_tail 0 0 p0 iv_tweak key_1 key_2`;; +*) (*****************************************) -(* Conversions *) -let plaintext = new_definition - `[word 0x0f; word 0x0e; word 0x0d; word 0x0c - ; word 0x0b; word 0x0a; word 0x09; word 0x08 - ; word 0x07; word 0x06; word 0x05; word 0x04 - ; word 0x03; word 0x02; word 0x01; word 0x00] : byte list`;; - -let iv = new_definition - `(word 0x0000000000000000000000123456789a) : int128`;; -let C_error = new_definition - `[ word 0; word 0; word 0; word 0 - ; word 0; word 0; word 0; word 0 - ; word 0; word 0; word 0; word 0 - ; word 0; word 0; word 0; word 0] : byte list`;; -let ciphertext = new_definition - `[word 0xc3; word 0x0c; word 0xa8; word 0xf2 - ; word 0xed; word 0x57; word 0x30; word 0x7e - ; word 0xdc; word 0x87; word 0xe5; word 0x44 - ; word 0x86; word 0x7a; word 0xc8; word 0x88] : byte list`;; - -let rw = Compute.bool_compset();; -word_compute_add_convs rw;; -num_compute_add_convs rw;; -Compute.add_thms [aes256_xts_encrypt;KEY1;KEY2;plaintext;iv;C_error;ciphertext] rw;; -let my_conv = Compute.WEAK_CBV_CONV rw;; -my_conv `aes256_xts_encrypt P 16 iv KEY1 KEY2 C_error`;; From b655c7a958620e791d789500fc9703b4c559182f Mon Sep 17 00:00:00 2001 From: Nevine Ebeid Date: Tue, 9 Sep 2025 11:07:31 -0400 Subject: [PATCH 062/132] Completed AES-XTS Encrypt specs and their tests. --- arm/proofs/aes_xts_encrypt_spec.ml | 107 +++++++++++++++++++++++++++-- 1 file changed, 102 insertions(+), 5 deletions(-) diff --git a/arm/proofs/aes_xts_encrypt_spec.ml b/arm/proofs/aes_xts_encrypt_spec.ml index e3060949e..05269274f 100644 --- a/arm/proofs/aes_xts_encrypt_spec.ml +++ b/arm/proofs/aes_xts_encrypt_spec.ml @@ -159,11 +159,11 @@ let cipher_stealing_encrypt = new_definition `cipher_stealing_encrypt (Pm1:byte list) (Pm:byte list) (tail_len:num) (iv:int128) (i:num) (key1:int128 list) (key2:int128 list): (byte list)#(byte list) = let twk = calculate_tweak i iv key2 in - let twk_last = GF_128_mult_by_primitive twk in let CC = int128_to_bytes (aes256_xts_encrypt_round (bytes_to_int128 Pm1) twk key1) in let Cm = SUB_LIST (0, tail_len) CC in let CP = SUB_LIST (tail_len, 16 - tail_len) CC in let PP = bytes_to_int128 (APPEND Pm CP) in + let twk_last = GF_128_mult_by_primitive twk in let Cm1 = int128_to_bytes (aes256_xts_encrypt_round PP twk_last key1) in (Cm1, Cm)`;; @@ -314,6 +314,7 @@ let plaintext2 = new_definition let iv_tweak = new_definition `iv_tweak = (word 0x0000000000000000000000123456789a) : int128`;; +(* p0 = pm1 = plaintext *) let pm1 = new_definition `pm1 = [word 0x0; word 0x1; word 0x2; word 0x3; word 0x4; word 0x5; word 0x6; word 0x7; @@ -330,6 +331,12 @@ let cm1 = new_definition let cm = new_definition `cm = [word 0xc3; word 0xc; word 0xa8; word 0xf2; word 0xed; word 0x57] : byte list`;; +let c0 = new_definition + `c0 = [word 0xc3; word 0x0c; word 0xa8; word 0xf2 + ; word 0xed; word 0x57; word 0x30; word 0x7e + ; word 0xdc; word 0x87; word 0xe5; word 0x44 + ; word 0x86; word 0x7a; word 0xc8; word 0x88] : byte list`;; + let p1 = new_definition `p1 = [word 0x0; word 0x1; word 0x2; word 0x3; word 0x4; word 0x5; word 0x6; word 0x7; @@ -337,7 +344,6 @@ let p1 = new_definition word 0xc; word 0xd; word 0xe; word 0xf; word 0x10; word 0x11; word 0x12; word 0x13; word 0x14; word 0x15] : byte list`;; - let c1 = new_definition `c1 = [ word 0x75; word 0xe8; word 0x18; word 0x8b; word 0xcc; word 0xe5; word 0x9a; word 0xda; @@ -345,6 +351,36 @@ let c1 = new_definition word 0x2c; word 0xb9; word 0xa4; word 0x89; word 0xc3; word 0x0c; word 0xa8; word 0xf2; word 0xed; word 0x57 ] : byte list`;; + +let p2 = new_definition + `p2 = [word 0x0; word 0x1; word 0x2; word 0x3; + word 0x4; word 0x5; word 0x6; word 0x7; + word 0x8; word 0x9; word 0xa; word 0xb; + word 0xc; word 0xd; word 0xe; word 0xf; + word 0x10; word 0x11; word 0x12; word 0x13; + word 0x14; word 0x15; word 0x16; word 0x17; + word 0x18; word 0x19; word 0x1a; word 0x1b; + word 0x1c; word 0x1d; word 0x1e; word 0x1f; + word 0x20; word 0x21; word 0x22; word 0x23; + word 0x24; word 0x25; word 0x26; word 0x27; + word 0x28; word 0x29; word 0x2a; word 0x2b; + word 0x2c; word 0x2d; word 0x2e; word 0x2f; + word 0x30; word 0x31; word 0x32] : byte list`;; +let c2 = new_definition + `c2 = [ word 0xc3; word 0x0c; word 0xa8; word 0xf2; + word 0xed; word 0x57; word 0x30; word 0x7e; + word 0xdc; word 0x87; word 0xe5; word 0x44; + word 0x86; word 0x7a; word 0xc8; word 0x88; + word 0x34; word 0x8c; word 0x20; word 0x89; + word 0x28; word 0xd7; word 0x40; word 0x62; + word 0x69; word 0x95; word 0x45; word 0x51; + word 0xcb; word 0x62; word 0x7b; word 0x5b; + word 0xbe; word 0xa4; word 0x77; word 0x68; + word 0xaa; word 0x25; word 0x37; word 0x6e; + word 0x92; word 0x4c; word 0xce; word 0x6a; + word 0x10; word 0x2c; word 0xa2; word 0xe4; + word 0xe1; word 0xc2; word 0x41 ] : byte list`;; + (* (* This key schedule is from aes_xts_decrypt_spec.ml It is used in EQINVCIPHER found in Sec 5.3.5 of @@ -471,6 +507,7 @@ let AES_XTS_ENC_1BLK_HELPER_CONV = let_CONV THENC AES256_XTS_ENCRYPT_ROUND_CONV;; ;; +(* (* Proven in about 73 sec on M3 *) time prove(`aes256_xts_encrypt_1block (word 0x0F0E0D0C0B0A09080706050403020100) @@ -481,6 +518,7 @@ time prove(`aes256_xts_encrypt_1block CONV_TAC(REWRITE_CONV [data_key_schedule; tweak_key_schedule] THENC LAND_CONV AES_XTS_ENC_1BLK_HELPER_CONV) THEN REFL_TAC );; +*) (* let tmp_xts = AES_XTS_ENC_1BLK_HELPER_CONV @@ -495,6 +533,8 @@ prove(list_mk_comb (`(=):((128)word->(128)word->bool)`, [rand (concl tmp_xts);`(word 0x9BCF70E3996C83E48603772F103A3B1C):(128)word`]), REFL_TAC);; *) +(* + (* 67 sec on M3 *) time prove(`aes256_xts_encrypt_1block (word 0x0F0E0D0C0B0A09080706050403020100) (word 0x0000000000000000000000123456789a) @@ -504,8 +544,7 @@ time prove(`aes256_xts_encrypt_1block CONV_TAC(REWRITE_CONV [key_1; key_2] THENC LAND_CONV AES_XTS_ENC_1BLK_HELPER_CONV) THEN REFL_TAC );; - -(* answer with the old key_1: word 0x494ba756143b3d88b6f8a44fba9d2228 *) +*) (* Common with decrypt *) let EL_16_8_CLAUSES = @@ -636,7 +675,6 @@ let CIPHER_STEALING_ENCRYPT_CONV = let CIPHER_STEALING_ENCRYPT_CONV = REWR_CONV cipher_stealing_encrypt THENC SUBLET_CONV CALCULATE_TWEAK_CONV THENC let_CONV THENC - SUBLET_CONV GF_128_MULT_BY_PRIMITIVE_CONV THENC let_CONV THENC SUBLET_CONV (ONCE_DEPTH_CONV BYTES_TO_INT128_CONV) THENC SUBLET_CONV (RAND_CONV AES256_XTS_ENCRYPT_ROUND_CONV) THENC SUBLET_CONV INT128_TO_BYTES_CONV THENC let_CONV THENC @@ -645,6 +683,7 @@ let CIPHER_STEALING_ENCRYPT_CONV = SUBLET_CONV SUB_LIST_CONV THENC let_CONV THENC SUBLET_CONV (ONCE_DEPTH_CONV (REWRITE_CONV [APPEND])) THENC SUBLET_CONV BYTES_TO_INT128_CONV THENC let_CONV THENC + SUBLET_CONV GF_128_MULT_BY_PRIMITIVE_CONV THENC let_CONV THENC SUBLET_CONV (RAND_CONV AES256_XTS_ENCRYPT_ROUND_CONV) THENC SUBLET_CONV INT128_TO_BYTES_CONV THENC let_CONV;; @@ -697,6 +736,64 @@ let AES256_XTS_ENCRYPT_TAIL_CONV tm = (REWRITE_CONV [p0;iv_tweak;key_1;key_2] THENC AES256_XTS_ENCRYPT_TAIL_CONV) `aes256_xts_encrypt_tail 0 0 p0 iv_tweak key_1 key_2`;; *) + +let AES256_XTS_ENCRYPT_CONV tm = + let ERROR_CONV = + REWR_CONV aes256_xts_encrypt THENC + DEPTH_CONV NUM_RED_CONV in + let MORE_THAN_2_CONV = + SUBLET_CONV AES256_XTS_ENCRYPT_REC_CONV THENC let_CONV THENC + REWRITE_CONV [FST;SND] THENC + SUBLET_CONV AES256_XTS_ENCRYPT_TAIL_CONV THENC let_CONV THENC + REWRITE_CONV [APPEND] in + let BODY_CONV = + REWR_CONV aes256_xts_encrypt THENC + DEPTH_CONV NUM_RED_CONV THENC let_CONV THENC + DEPTH_CONV NUM_RED_CONV THENC let_CONV THENC + DEPTH_CONV NUM_RED_CONV THENC + (AES256_XTS_ENCRYPT_TAIL_CONV ORELSEC MORE_THAN_2_CONV) in + match tm with + | Comb + (Comb + (Comb + (Comb + (Comb + (Comb + (Const ("aes256_xts_encrypt", _), _), len), + _), + _), + _), + _) -> + if dest_numeral len failwith "AES256_XTS_ENCRYPT_CONV: inapplicable";; + +(* +(REWRITE_CONV [cerr; int128_to_bytes] THENC AES256_XTS_ENCRYPT_CONV) + `aes256_xts_encrypt p0 5 iv_tweak key_1 key_2 cerr`;; + +(*(REWRITE_CONV [plaintext; cerr; int128_to_bytes; iv_tweak; key_1; key_2] THENC AES256_XTS_ENCRYPT_CONV) + `aes256_xts_encrypt plaintext 16 iv_tweak key_1 key_2 cerr`;;*) + +(* 1 block : 68 sec on M3 *) +time prove (`aes256_xts_encrypt plaintext 16 iv_tweak key_1 key_2 cerr = c0`, + CONV_TAC(LAND_CONV (REWRITE_CONV [plaintext; cerr; int128_to_bytes; iv_tweak; key_1; key_2] + THENC AES256_XTS_ENCRYPT_CONV)) THEN + REWRITE_TAC [c0] THEN REFL_TAC);; + +(* 1 block + 6 bytes : 102 sec on M3 *) +time prove (`aes256_xts_encrypt p1 22 iv_tweak key_1 key_2 cerr = c1`, + CONV_TAC(LAND_CONV (REWRITE_CONV [p1; cerr; int128_to_bytes; iv_tweak; key_1; key_2] + THENC AES256_XTS_ENCRYPT_CONV)) THEN + REWRITE_TAC [c1] THEN REFL_TAC);; + +(* 3 blocks + 3 bytes : 240 sec on M3 *) +time prove (`aes256_xts_encrypt p2 51 iv_tweak key_1 key_2 cerr = c2`, + CONV_TAC(LAND_CONV (REWRITE_CONV [p2; cerr; int128_to_bytes; iv_tweak; key_1; key_2] + THENC AES256_XTS_ENCRYPT_CONV)) THEN + REWRITE_TAC [c2] THEN REFL_TAC);; +*) (*****************************************) From 92ad994ad05460df506e74cddc070b7cc708db33 Mon Sep 17 00:00:00 2001 From: Nevine Ebeid Date: Fri, 19 Sep 2025 10:47:16 -0400 Subject: [PATCH 063/132] Use the asm code integrated in AWS-LC and redo the 1-block proof based on the new specs 1-block function. --- arm/aes-xts/aes-xts-armv8.S | 723 ++++++++++++++--------------- arm/aes-xts/aes-xts-armv8.txt | 44 +- arm/proofs/aes-xts-armv8.ml | 127 +++-- arm/proofs/aes_xts_encrypt_spec.ml | 108 ++--- 4 files changed, 460 insertions(+), 542 deletions(-) diff --git a/arm/aes-xts/aes-xts-armv8.S b/arm/aes-xts/aes-xts-armv8.S index 9b8eb8c7a..69159a790 100644 --- a/arm/aes-xts/aes-xts-armv8.S +++ b/arm/aes-xts/aes-xts-armv8.S @@ -1,71 +1,77 @@ -#include "_internal_s2n_bignum.h" +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT-0 -// copied from https://github.com/nebeid/aws-lc/blob/8a48d976c7e2018dc44a736f1b74435f4eeb7b99/crypto/fipsmodule/aes/asm/slothy/clean/enc/aes-xts-armv8-enc-base_x5_basic.S#L1-L677 +// Auto-added during import for AWS-LC symbol prefixing support +#include "_internal_s2n_bignum.h" -.align 4 + .arch armv8-a+crypto + S2N_BN_SYM_VISIBILITY_DIRECTIVE(aes_hw_xts_encrypt) + S2N_BN_SYM_PRIVACY_DIRECTIVE(aes_hw_xts_encrypt) + .text + .balign 4 -#define STACK_SIZE_GPRS (2*16) -#define STACK_SIZE_VREGS (4*16) +#define STACK_SIZE_GPRS 32 //2*16 +#define STACK_SIZE_VREGS 64 //4*16 #define STACK_SIZE (STACK_SIZE_GPRS + STACK_SIZE_VREGS) -#define STACK_BASE_GPRS (0) -#define STACK_BASE_VREGS (STACK_SIZE_GPRS) +#define STACK_BASE_GPRS 0 +#define STACK_BASE_VREGS STACK_SIZE_GPRS -.macro save_regs - stp x19, x20, [sp, #(STACK_BASE_GPRS + 16*0)] +#define save_regs \ + stp x19, x20, [sp, #(STACK_BASE_GPRS + 16*0)] __LF \ stp x21, x22, [sp, #(STACK_BASE_GPRS + 16*1)] -.endm -.macro restore_regs - ldp x19, x20, [sp, #(STACK_BASE_GPRS + 16*0)] +#define restore_regs \ + ldp x19, x20, [sp, #(STACK_BASE_GPRS + 16*0)] __LF \ ldp x21, x22, [sp, #(STACK_BASE_GPRS + 16*1)] -.endm -.macro save_vregs - stp d8, d9, [sp, #(STACK_BASE_VREGS + 16*0)] - stp d10, d11, [sp, #(STACK_BASE_VREGS + 16*1)] - stp d12, d13, [sp, #(STACK_BASE_VREGS + 16*2)] +#define save_vregs \ + stp d8, d9, [sp, #(STACK_BASE_VREGS + 16*0)] __LF \ + stp d10, d11, [sp, #(STACK_BASE_VREGS + 16*1)] __LF \ + stp d12, d13, [sp, #(STACK_BASE_VREGS + 16*2)] __LF \ stp d14, d15, [sp, #(STACK_BASE_VREGS + 16*3)] -.endm -.macro restore_vregs - ldp d8, d9, [sp, #(STACK_BASE_VREGS + 16*0)] - ldp d10, d11, [sp, #(STACK_BASE_VREGS + 16*1)] - ldp d12, d13, [sp, #(STACK_BASE_VREGS + 16*2)] +#define restore_vregs \ + ldp d8, d9, [sp, #(STACK_BASE_VREGS + 16*0)] __LF \ + ldp d10, d11, [sp, #(STACK_BASE_VREGS + 16*1)] __LF \ + ldp d12, d13, [sp, #(STACK_BASE_VREGS + 16*2)] __LF \ ldp d14, d15, [sp, #(STACK_BASE_VREGS + 16*3)] -.endm // A single AES round // Prevent SLOTHY from unfolding because uArchs tend to fuse AESMC+AESE -.macro aesr data, key // @slothy:no-unfold - aese \data, \key - aesmc \data, \data -.endm - -.macro tweak lo, hi - extr x22, x10, x10, #32 - extr x10, x10, x9, #63 - and w11, w19, w22, asr#31 - eor x9, x11, x9, lsl#1 - fmov \lo, x9 - fmov \hi, x10 -.endm - -_aes_hw_slothy_xts_encrypt: -aes_hw_slothy_xts_encrypt: - # AARCH64_VALID_CALL_TARGET +#define aesr(data, key) \ + aese data, key __LF \ + aesmc data, data + +#define tweak(lo, hi) \ + extr x22, x10, x10, #32 __LF \ + extr x10, x10, x9, #63 __LF \ + and w11, w19, w22, asr#31 __LF \ + eor x9, x11, x9, lsl#1 __LF \ + fmov lo, x9 __LF \ + fmov hi, x10 + +#define udiv_by_80(src, dst) \ + mov dst, #-0x3333333333333334 __LF \ + movk dst, #0xcccd __LF \ + umulh dst, src, dst __LF \ + lsr dst, dst, #6 + +S2N_BN_SYMBOL(aes_hw_xts_encrypt): + # AARCH64_VALID_CALL_TARGET sub sp, sp, #STACK_SIZE save_vregs save_regs + udiv_by_80(x2, x8) // Number of 5x-unrolled iterations + cmp x2, #16 // AES-XTS needs at least one block - b.lt Lxts_abort + b.lt .Lxts_enc_abort .align 4 -Lxts_enc_big_size: // Encrypt input size >= 16 bytes +.Lxts_enc_big_size: // Encrypt input size >= 16 bytes and x21, x2, #0xf // store the tail value of length%16 and x2, x2, #-16 // len &= 0x1..110000, now divisible by 16 - // subs x2, x2, #16 // Firstly, encrypt the iv with key2, as the first iv of XEX. ldr w6, [x4,#240] @@ -74,15 +80,15 @@ Lxts_enc_big_size: // Encrypt input size >= 16 bytes sub w6, w6, #2 ld1 {v1.4s}, [x4], #16 -Loop_iv_enc: - aesr v6.16b, v0.16b +.Loop_iv_enc: + aesr(v6.16b, v0.16b) ld1 {v0.4s}, [x4], #16 subs w6, w6, #2 - aesr v6.16b, v1.16b + aesr(v6.16b, v1.16b) ld1 {v1.4s}, [x4], #16 - b.gt Loop_iv_enc + b.gt .Loop_iv_enc - aesr v6.16b, v0.16b + aesr(v6.16b, v0.16b) ld1 {v0.4s}, [x4] aese v6.16b, v1.16b eor v6.16b, v6.16b, v0.16b @@ -93,7 +99,7 @@ Loop_iv_enc: fmov x9, d6 fmov x10, v6.d[1] mov w19, #0x87 - tweak d8, v8.d[1] + tweak(d8, v8.d[1]) mov x7, x3 ld1 {v16.4s,v17.4s},[x7], #32 // load key schedule @@ -106,30 +112,30 @@ Loop_iv_enc: ld1 {v7.4s}, [x7] // Encryption -Lxts_enc: - cmp x2,#32 - b.lo Lxts_enc_tail1x // when input = 1 with tail +.Lxts_enc: + cmp x2, #0x20 + b.lo .Lxts_enc_tail1x // when input = 1 with tail - cmp x2,#48 - b.lo Lxts_enc_tail2x // when input size = 2 + cmp x2, #0x30 + b.lo .Lxts_enc_tail2x // when input size = 2 // The iv for third block - tweak d9,v9.d[1] + tweak(d9,v9.d[1]) - cmp x2,#64 - b.lo Lxts_enc_tail3x + cmp x2,#0x40 + b.lo .Lxts_enc_tail3x // The iv for fourth block - tweak d10,v10.d[1] + tweak(d10,v10.d[1]) - cmp x2,#80 - b.lo Lxts_enc_tail4x + cmp x2,#0x50 + b.lo .Lxts_enc_tail4x // The iv for fifth block - tweak d11,v11.d[1] + tweak(d11,v11.d[1]) .align 4 -Loop5x_xts_enc: +.Loop5x_xts_enc: ldp q0, q1, [x0], #0x50 ldp q24, q25, [x0, #-0x30] ldr q26, [x0, #-0x10] @@ -140,83 +146,83 @@ Loop5x_xts_enc: eor v25.16b,v25.16b,v10.16b eor v26.16b,v26.16b,v11.16b - aesr v0.16b, v16.16b - aesr v1.16b, v16.16b - aesr v24.16b, v16.16b - aesr v25.16b, v16.16b - aesr v26.16b, v16.16b - - aesr v0.16b, v17.16b - aesr v1.16b, v17.16b - aesr v24.16b, v17.16b - aesr v25.16b, v17.16b - aesr v26.16b, v17.16b - - aesr v0.16b, v12.16b - aesr v1.16b, v12.16b - aesr v24.16b, v12.16b - aesr v25.16b, v12.16b - aesr v26.16b, v12.16b - - aesr v0.16b, v13.16b - aesr v1.16b, v13.16b - aesr v24.16b, v13.16b - aesr v25.16b, v13.16b - aesr v26.16b, v13.16b - - aesr v0.16b, v14.16b - aesr v1.16b, v14.16b - aesr v24.16b, v14.16b - aesr v25.16b, v14.16b - aesr v26.16b, v14.16b - - aesr v0.16b, v15.16b - aesr v1.16b, v15.16b - aesr v24.16b, v15.16b - aesr v25.16b, v15.16b - aesr v26.16b, v15.16b - - aesr v0.16b, v4.16b - aesr v1.16b, v4.16b - aesr v24.16b, v4.16b - aesr v25.16b, v4.16b - aesr v26.16b, v4.16b - - aesr v0.16b, v5.16b - aesr v1.16b, v5.16b - aesr v24.16b, v5.16b - aesr v25.16b, v5.16b - aesr v26.16b, v5.16b - - aesr v0.16b, v18.16b - aesr v1.16b, v18.16b - aesr v24.16b, v18.16b - aesr v25.16b, v18.16b - aesr v26.16b, v18.16b - - aesr v0.16b, v19.16b - aesr v1.16b, v19.16b - aesr v24.16b, v19.16b - aesr v25.16b, v19.16b - aesr v26.16b, v19.16b - - aesr v0.16b, v20.16b - aesr v1.16b, v20.16b - aesr v24.16b, v20.16b - aesr v25.16b, v20.16b - aesr v26.16b, v20.16b - - aesr v0.16b, v21.16b - aesr v1.16b, v21.16b - aesr v24.16b, v21.16b - aesr v25.16b, v21.16b - aesr v26.16b, v21.16b - - aesr v0.16b, v22.16b - aesr v1.16b, v22.16b - aesr v24.16b, v22.16b - aesr v25.16b, v22.16b - aesr v26.16b, v22.16b + aesr(v0.16b, v16.16b) + aesr(v1.16b, v16.16b) + aesr(v24.16b, v16.16b) + aesr(v25.16b, v16.16b) + aesr(v26.16b, v16.16b) + + aesr(v0.16b, v17.16b) + aesr(v1.16b, v17.16b) + aesr(v24.16b, v17.16b) + aesr(v25.16b, v17.16b) + aesr(v26.16b, v17.16b) + + aesr(v0.16b, v12.16b) + aesr(v1.16b, v12.16b) + aesr(v24.16b, v12.16b) + aesr(v25.16b, v12.16b) + aesr(v26.16b, v12.16b) + + aesr(v0.16b, v13.16b) + aesr(v1.16b, v13.16b) + aesr(v24.16b, v13.16b) + aesr(v25.16b, v13.16b) + aesr(v26.16b, v13.16b) + + aesr(v0.16b, v14.16b) + aesr(v1.16b, v14.16b) + aesr(v24.16b, v14.16b) + aesr(v25.16b, v14.16b) + aesr(v26.16b, v14.16b) + + aesr(v0.16b, v15.16b) + aesr(v1.16b, v15.16b) + aesr(v24.16b, v15.16b) + aesr(v25.16b, v15.16b) + aesr(v26.16b, v15.16b) + + aesr(v0.16b, v4.16b) + aesr(v1.16b, v4.16b) + aesr(v24.16b, v4.16b) + aesr(v25.16b, v4.16b) + aesr(v26.16b, v4.16b) + + aesr(v0.16b, v5.16b) + aesr(v1.16b, v5.16b) + aesr(v24.16b, v5.16b) + aesr(v25.16b, v5.16b) + aesr(v26.16b, v5.16b) + + aesr(v0.16b, v18.16b) + aesr(v1.16b, v18.16b) + aesr(v24.16b, v18.16b) + aesr(v25.16b, v18.16b) + aesr(v26.16b, v18.16b) + + aesr(v0.16b, v19.16b) + aesr(v1.16b, v19.16b) + aesr(v24.16b, v19.16b) + aesr(v25.16b, v19.16b) + aesr(v26.16b, v19.16b) + + aesr(v0.16b, v20.16b) + aesr(v1.16b, v20.16b) + aesr(v24.16b, v20.16b) + aesr(v25.16b, v20.16b) + aesr(v26.16b, v20.16b) + + aesr(v0.16b, v21.16b) + aesr(v1.16b, v21.16b) + aesr(v24.16b, v21.16b) + aesr(v25.16b, v21.16b) + aesr(v26.16b, v21.16b) + + aesr(v0.16b, v22.16b) + aesr(v1.16b, v22.16b) + aesr(v24.16b, v22.16b) + aesr(v25.16b, v22.16b) + aesr(v26.16b, v22.16b) aese v0.16b,v23.16b aese v1.16b,v23.16b @@ -227,60 +233,56 @@ Loop5x_xts_enc: eor v0.16b,v0.16b,v7.16b eor v0.16b,v0.16b,v6.16b // The iv for first block of one iteration - tweak d6,v6.d[1] + tweak(d6, v6.d[1]) eor v1.16b,v1.16b,v7.16b eor v1.16b,v1.16b,v8.16b // The iv for second block - tweak d8,v8.d[1] + tweak(d8, v8.d[1]) eor v24.16b,v24.16b,v7.16b eor v24.16b,v24.16b,v9.16b // The iv for third block - tweak d9,v9.d[1] + tweak(d9, v9.d[1]) eor v25.16b,v25.16b,v7.16b eor v25.16b,v25.16b,v10.16b // The iv for fourth block - tweak d10,v10.d[1] + tweak(d10, v10.d[1]) eor v26.16b,v26.16b,v7.16b eor v26.16b,v26.16b,v11.16b // The iv for fifth block - tweak d11,v11.d[1] + tweak(d11, v11.d[1]) stp q0, q1, [x1], #0x50 stp q24, q25, [x1, #-0x30] str q26, [x1, #-0x10] - subs x2,x2,#0x50 // @slothy:core + sub x2, x2, #0x50 + subs x8,x8,#1 + cbnz x8, .Loop5x_xts_enc - cmp x2,#0x50 - b.lo Loop5x_enc_after - - b.hs Loop5x_xts_enc +.Loop5x_enc_after: + cmp x2,#0x40 + b.eq .Lxts_enc_tail4x // 4 blocks left -Loop5x_enc_after: - cmp x2,#0x0 - b.eq Lxts_enc_done - - cmp x2,#0x10 - b.eq Lxts_enc_tail1x + cmp x2,#0x30 + b.eq .Lxts_enc_tail3x cmp x2,#0x20 - b.eq Lxts_enc_tail2x + b.eq .Lxts_enc_tail2x - cmp x2,#0x30 - b.eq Lxts_enc_tail3x + cmp x2,#0x10 + b.eq .Lxts_enc_tail1x - cmp x2,#0x40 - b.eq Lxts_enc_tail4x + b .Lxts_enc_done // no blocks left .align 4 -Lxts_enc_tail4x: - ld1 {v0.16b}, [x0],#16 // the first block +.Lxts_enc_tail4x: + ld1 {v0.16b}, [x0],#16 // the first block ld1 {v1.16b}, [x0],#16 // the second block - ld1 {v24.16b},[x0],#16 // the third block + ld1 {v24.16b},[x0],#16 // the third block ld1 {v25.16b},[x0],#16 // the fourth block eor v0.16b,v0.16b,v6.16b @@ -288,70 +290,70 @@ Lxts_enc_tail4x: eor v24.16b,v24.16b,v9.16b eor v25.16b,v25.16b,v10.16b - aesr v0.16b, v16.16b - aesr v1.16b, v16.16b - aesr v24.16b, v16.16b - aesr v25.16b, v16.16b - - aesr v0.16b, v17.16b - aesr v1.16b, v17.16b - aesr v24.16b, v17.16b - aesr v25.16b, v17.16b - - aesr v0.16b, v12.16b - aesr v1.16b, v12.16b - aesr v24.16b, v12.16b - aesr v25.16b, v12.16b - - aesr v0.16b, v13.16b - aesr v1.16b, v13.16b - aesr v24.16b, v13.16b - aesr v25.16b, v13.16b - - aesr v0.16b, v14.16b - aesr v1.16b, v14.16b - aesr v24.16b, v14.16b - aesr v25.16b, v14.16b - - aesr v0.16b, v15.16b - aesr v1.16b, v15.16b - aesr v24.16b, v15.16b - aesr v25.16b, v15.16b - - aesr v0.16b, v4.16b - aesr v1.16b, v4.16b - aesr v24.16b, v4.16b - aesr v25.16b, v4.16b - - aesr v0.16b, v5.16b - aesr v1.16b, v5.16b - aesr v24.16b, v5.16b - aesr v25.16b, v5.16b - - aesr v0.16b, v18.16b - aesr v1.16b, v18.16b - aesr v24.16b, v18.16b - aesr v25.16b, v18.16b - - aesr v0.16b, v19.16b - aesr v1.16b, v19.16b - aesr v24.16b, v19.16b - aesr v25.16b, v19.16b - - aesr v0.16b, v20.16b - aesr v1.16b, v20.16b - aesr v24.16b, v20.16b - aesr v25.16b, v20.16b - - aesr v0.16b, v21.16b - aesr v1.16b, v21.16b - aesr v24.16b, v21.16b - aesr v25.16b, v21.16b - - aesr v0.16b, v22.16b - aesr v1.16b, v22.16b - aesr v24.16b, v22.16b - aesr v25.16b, v22.16b + aesr(v0.16b, v16.16b) + aesr(v1.16b, v16.16b) + aesr(v24.16b, v16.16b) + aesr(v25.16b, v16.16b) + + aesr(v0.16b, v17.16b) + aesr(v1.16b, v17.16b) + aesr(v24.16b, v17.16b) + aesr(v25.16b, v17.16b) + + aesr(v0.16b, v12.16b) + aesr(v1.16b, v12.16b) + aesr(v24.16b, v12.16b) + aesr(v25.16b, v12.16b) + + aesr(v0.16b, v13.16b) + aesr(v1.16b, v13.16b) + aesr(v24.16b, v13.16b) + aesr(v25.16b, v13.16b) + + aesr(v0.16b, v14.16b) + aesr(v1.16b, v14.16b) + aesr(v24.16b, v14.16b) + aesr(v25.16b, v14.16b) + + aesr(v0.16b, v15.16b) + aesr(v1.16b, v15.16b) + aesr(v24.16b, v15.16b) + aesr(v25.16b, v15.16b) + + aesr(v0.16b, v4.16b) + aesr(v1.16b, v4.16b) + aesr(v24.16b, v4.16b) + aesr(v25.16b, v4.16b) + + aesr(v0.16b, v5.16b) + aesr(v1.16b, v5.16b) + aesr(v24.16b, v5.16b) + aesr(v25.16b, v5.16b) + + aesr(v0.16b, v18.16b) + aesr(v1.16b, v18.16b) + aesr(v24.16b, v18.16b) + aesr(v25.16b, v18.16b) + + aesr(v0.16b, v19.16b) + aesr(v1.16b, v19.16b) + aesr(v24.16b, v19.16b) + aesr(v25.16b, v19.16b) + + aesr(v0.16b, v20.16b) + aesr(v1.16b, v20.16b) + aesr(v24.16b, v20.16b) + aesr(v25.16b, v20.16b) + + aesr(v0.16b, v21.16b) + aesr(v1.16b, v21.16b) + aesr(v24.16b, v21.16b) + aesr(v25.16b, v21.16b) + + aesr(v0.16b, v22.16b) + aesr(v1.16b, v22.16b) + aesr(v24.16b, v22.16b) + aesr(v25.16b, v22.16b) aese v0.16b,v23.16b aese v1.16b,v23.16b @@ -376,12 +378,12 @@ Lxts_enc_tail4x: // The iv for tail fmov x9,d10 fmov x10,v10.d[1] - tweak d6,v6.d[1] + tweak(d6, v6.d[1]) - b Lxts_enc_done + b .Lxts_enc_done .align 4 -Lxts_enc_tail3x: +.Lxts_enc_tail3x: ld1 {v0.16b,v1.16b}, [x0],#32 ld1 {v24.16b}, [x0],#16 @@ -389,67 +391,57 @@ Lxts_enc_tail3x: eor v1.16b,v1.16b,v8.16b eor v24.16b,v24.16b,v9.16b - // First round with v16 - aesr v0.16b, v16.16b - aesr v1.16b, v16.16b - aesr v24.16b, v16.16b - - // Second round with v17 - aesr v0.16b, v17.16b - aesr v1.16b, v17.16b - aesr v24.16b, v17.16b - - // Third round with v12 - aesr v0.16b, v12.16b - aesr v1.16b, v12.16b - aesr v24.16b, v12.16b - - // Fourth round with v13 - aesr v0.16b, v13.16b - aesr v1.16b, v13.16b - aesr v24.16b, v13.16b - - // Fifth round with v14 - aesr v0.16b, v14.16b - aesr v1.16b, v14.16b - aesr v24.16b, v14.16b - - // Sixth round with v15 - aesr v0.16b, v15.16b - aesr v1.16b, v15.16b - aesr v24.16b, v15.16b - - // Seventh round with v4 - aesr v0.16b, v4.16b - aesr v1.16b, v4.16b - aesr v24.16b, v4.16b - - // Eighth round with v5 - aesr v0.16b, v5.16b - aesr v1.16b, v5.16b - aesr v24.16b, v5.16b - - // 9th round with v18 - aesr v0.16b, v18.16b - aesr v1.16b, v18.16b - aesr v24.16b, v18.16b - - // 10th round with v19 - aesr v0.16b, v19.16b - aesr v1.16b, v19.16b - aesr v24.16b, v19.16b - - aesr v0.16b, v20.16b - aesr v1.16b, v20.16b - aesr v24.16b, v20.16b - - aesr v0.16b, v21.16b - aesr v1.16b, v21.16b - aesr v24.16b, v21.16b - - aesr v0.16b, v22.16b - aesr v1.16b, v22.16b - aesr v24.16b, v22.16b + aesr(v0.16b, v16.16b) + aesr(v1.16b, v16.16b) + aesr(v24.16b, v16.16b) + + aesr(v0.16b, v17.16b) + aesr(v1.16b, v17.16b) + aesr(v24.16b, v17.16b) + + aesr(v0.16b, v12.16b) + aesr(v1.16b, v12.16b) + aesr(v24.16b, v12.16b) + + aesr(v0.16b, v13.16b) + aesr(v1.16b, v13.16b) + aesr(v24.16b, v13.16b) + + aesr(v0.16b, v14.16b) + aesr(v1.16b, v14.16b) + aesr(v24.16b, v14.16b) + + aesr(v0.16b, v15.16b) + aesr(v1.16b, v15.16b) + aesr(v24.16b, v15.16b) + + aesr(v0.16b, v4.16b) + aesr(v1.16b, v4.16b) + aesr(v24.16b, v4.16b) + + aesr(v0.16b, v5.16b) + aesr(v1.16b, v5.16b) + aesr(v24.16b, v5.16b) + + aesr(v0.16b, v18.16b) + aesr(v1.16b, v18.16b) + aesr(v24.16b, v18.16b) + + aesr(v0.16b, v19.16b) + aesr(v1.16b, v19.16b) + aesr(v24.16b, v19.16b) + + aesr(v0.16b, v20.16b) + aesr(v1.16b, v20.16b) + aesr(v24.16b, v20.16b) + + aesr(v0.16b, v21.16b) + aesr(v1.16b, v21.16b) + aesr(v24.16b, v21.16b) + + aesr(v0.16b, v22.16b) + aesr(v1.16b, v22.16b) + aesr(v24.16b, v22.16b) aese v0.16b,v23.16b aese v1.16b,v23.16b @@ -468,64 +460,54 @@ Lxts_enc_tail3x: // The iv for tail fmov x9,d9 fmov x10,v9.d[1] - tweak d6,v6.d[1] + tweak(d6, v6.d[1]) - b Lxts_enc_done // done processing three blocks + b .Lxts_enc_done // done processing three blocks -Lxts_enc_tail2x: +.Lxts_enc_tail2x: ld1 {v0.16b,v1.16b},[x0],#32 // the first block eor v0.16b,v0.16b,v6.16b eor v1.16b,v1.16b,v8.16b - // First round with v16 - aesr v0.16b, v16.16b - aesr v1.16b, v16.16b + aesr(v0.16b, v16.16b) + aesr(v1.16b, v16.16b) - // Second round with v17 - aesr v0.16b, v17.16b - aesr v1.16b, v17.16b + aesr(v0.16b, v17.16b) + aesr(v1.16b, v17.16b) - // Third round with v12 - aesr v0.16b, v12.16b - aesr v1.16b, v12.16b + aesr(v0.16b, v12.16b) + aesr(v1.16b, v12.16b) - // Fourth round with v13 - aesr v0.16b, v13.16b - aesr v1.16b, v13.16b + aesr(v0.16b, v13.16b) + aesr(v1.16b, v13.16b) - // Fifth round with v14 - aesr v0.16b, v14.16b - aesr v1.16b, v14.16b + aesr(v0.16b, v14.16b) + aesr(v1.16b, v14.16b) - // Sixth round with v15 - aesr v0.16b, v15.16b - aesr v1.16b, v15.16b + aesr(v0.16b, v15.16b) + aesr(v1.16b, v15.16b) - // Seventh round with v4 - aesr v0.16b, v4.16b - aesr v1.16b, v4.16b + aesr(v0.16b, v4.16b) + aesr(v1.16b, v4.16b) - // Eighth round with v5 - aesr v0.16b, v5.16b - aesr v1.16b, v5.16b + aesr(v0.16b, v5.16b) + aesr(v1.16b, v5.16b) - // 9th round with v18 - aesr v0.16b, v18.16b - aesr v1.16b, v18.16b + aesr(v0.16b, v18.16b) + aesr(v1.16b, v18.16b) - // 10th round with v19 - aesr v0.16b, v19.16b - aesr v1.16b, v19.16b + aesr(v0.16b, v19.16b) + aesr(v1.16b, v19.16b) - aesr v0.16b, v20.16b - aesr v1.16b, v20.16b + aesr(v0.16b, v20.16b) + aesr(v1.16b, v20.16b) - aesr v0.16b, v21.16b - aesr v1.16b, v21.16b + aesr(v0.16b, v21.16b) + aesr(v1.16b, v21.16b) - aesr v0.16b, v22.16b - aesr v1.16b, v22.16b + aesr(v0.16b, v22.16b) + aesr(v1.16b, v22.16b) aese v0.16b,v23.16b aese v1.16b,v23.16b @@ -540,47 +522,27 @@ Lxts_enc_tail2x: // The iv for tail fmov x9,d8 fmov x10,v8.d[1] - tweak d6,v6.d[1] - b Lxts_enc_done + tweak(d6, v6.d[1]) + b .Lxts_enc_done -Lxts_enc_tail1x: +.Lxts_enc_tail1x: ld1 {v0.16b}, [x0],#16 // the first block eor v0.16b,v0.16b,v6.16b - // First round with v16 - aesr v0.16b, v16.16b - - // Second round with v17 - aesr v0.16b, v17.16b - - // Third round with v12 - aesr v0.16b, v12.16b - - // Fourth round with v13 - aesr v0.16b, v13.16b - - // Fifth round with v14 - aesr v0.16b, v14.16b - - // Sixth round with v15 - aesr v0.16b, v15.16b - - // Seventh round with v4 - aesr v0.16b, v4.16b - - // Eighth round with v5 - aesr v0.16b, v5.16b - - // 9th round with v18 - aesr v0.16b, v18.16b - - // 10th round with v19 - aesr v0.16b, v19.16b - - aesr v0.16b, v20.16b - aesr v0.16b, v21.16b - aesr v0.16b, v22.16b + aesr(v0.16b, v16.16b) + aesr(v0.16b, v17.16b) + aesr(v0.16b, v12.16b) + aesr(v0.16b, v13.16b) + aesr(v0.16b, v14.16b) + aesr(v0.16b, v15.16b) + aesr(v0.16b, v4.16b) + aesr(v0.16b, v5.16b) + aesr(v0.16b, v18.16b) + aesr(v0.16b, v19.16b) + aesr(v0.16b, v20.16b) + aesr(v0.16b, v21.16b) + aesr(v0.16b, v22.16b) aese v0.16b,v23.16b eor v0.16b,v0.16b,v7.16b @@ -590,14 +552,14 @@ Lxts_enc_tail1x: // tweak for tail fmov x9,d6 fmov x10,v6.d[1] - tweak d6,v6.d[1] - b Lxts_enc_done + tweak(d6, v6.d[1]) + b .Lxts_enc_done .align 5 -Lxts_enc_done: +.Lxts_enc_done: // Process the tail block with cipher stealing. tst x21,#0xf - b.eq Lxts_abort + b.eq .Lxts_enc_abort mov x20,x0 mov x13,x1 @@ -609,7 +571,7 @@ Lxts_enc_done: strb w15,[x13,x21] strb w14,[x1,x21] b.gt .composite_enc_loop -Lxts_enc_load_done: +.Lxts_enc_load_done: ld1 {v26.16b},[x1] eor v26.16b,v26.16b,v6.16b @@ -618,30 +580,27 @@ Lxts_enc_load_done: ld1 {v0.16b},[x3],#16 sub w6,w6,#2 ld1 {v1.16b},[x3],#16 // load key schedule... -Loop_final_enc: - aesr v26.16b, v0.16b +.Loop_final_enc: + aesr(v26.16b, v0.16b) ld1 {v0.4s},[x3],#16 subs w6,w6,#2 - aesr v26.16b, v1.16b + aesr(v26.16b, v1.16b) ld1 {v1.4s},[x3],#16 - b.gt Loop_final_enc + b.gt .Loop_final_enc - aesr v26.16b, v0.16b + aesr(v26.16b, v0.16b) ld1 {v0.4s},[x3] aese v26.16b,v1.16b eor v26.16b,v26.16b,v0.16b eor v26.16b,v26.16b,v6.16b st1 {v26.16b},[x1] -Lxts_abort: +.Lxts_enc_abort: restore_regs - -Lxts_enc_final_abort: restore_vregs add sp, sp, #STACK_SIZE ret -#if defined(__ELF__) -// See https://www.airs.com/blog/archives/518. -.section .note.GNU-stack,"",%progbits +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack, "", %progbits #endif diff --git a/arm/aes-xts/aes-xts-armv8.txt b/arm/aes-xts/aes-xts-armv8.txt index 1cd8643a5..3567ee4fa 100644 --- a/arm/aes-xts/aes-xts-armv8.txt +++ b/arm/aes-xts/aes-xts-armv8.txt @@ -6,8 +6,12 @@ 0x6d053fee; (* arm_STP D14 D15 SP (Immediate_Offset (iword (&0x50))) *) 0xa90053f3; (* arm_STP X19 X20 SP (Immediate_Offset (iword (&0x0))) *) 0xa9015bf5; (* arm_STP X21 X22 SP (Immediate_Offset (iword (&0x10))) *) + 0xb202e7e8; (* arm_MOV X8 (rvalue (word 0xcccccccccccccccc)) *) + 0xf29999a8; (* arm_MOVK X8 (word 0xcccd) 0x0 *) + 0x9bc87c48; (* arm_UMULH X8 X2 X8 *) + 0xd346fd08; (* arm_LSR X8 X8 0x6 *) 0xf100405f; (* arm_CMP X2 (rvalue (word 0x10)) *) - 0x5400520b; (* arm_BLT (word 0xa40) *) + 0x5400518b; (* arm_BLT (word 0xa30) *) 0xd503201f; (* arm_NOP *) 0xd503201f; (* arm_NOP *) 0xd503201f; (* arm_NOP *) @@ -261,20 +265,20 @@ 0xac828420; (* arm_STP Q0 Q1 X1 (Postimmediate_Offset (iword (&0x50))) *) 0xad3ee438; (* arm_STP Q24 Q25 X1 (Immediate_Offset (iword (-- &0x30))) *) 0x3c9f003a; (* arm_STR Q26 X1 (Immediate_Offset (word 0xfffffffffffffff0)) *) - 0xf1014042; (* arm_SUBS X2 X2 (rvalue (word 0x50)) *) - 0xf101405f; (* arm_CMP X2 (rvalue (word 0x50)) *) - 0x54000043; (* arm_BCC (word 0x8) *) - 0x54ffe862; (* arm_BCS (word 0x1ffd0c) *) - 0xf100005f; (* arm_CMP X2 (rvalue (word 0x0)) *) - 0x54002da0; (* arm_BEQ (word 0x5b4) *) - 0xf100405f; (* arm_CMP X2 (rvalue (word 0x10)) *) - 0x540027a0; (* arm_BEQ (word 0x4f4) *) - 0xf100805f; (* arm_CMP X2 (rvalue (word 0x20)) *) - 0x54001e80; (* arm_BEQ (word 0x3d0) *) - 0xf100c05f; (* arm_CMP X2 (rvalue (word 0x30)) *) - 0x54001160; (* arm_BEQ (word 0x22c) *) + 0xd1014042; (* arm_SUB X2 X2 (rvalue (word 0x50)) *) + 0xf1000508; (* arm_SUBS X8 X8 (rvalue (word 0x1)) *) + 0xb5ffe888; (* arm_CBNZ X8 (word 0x1ffd10) *) 0xf101005f; (* arm_CMP X2 (rvalue (word 0x40)) *) - 0x54000020; (* arm_BEQ (word 0x4) *) + 0x54000140; (* arm_BEQ (word 0x28) *) + 0xf100c05f; (* arm_CMP X2 (rvalue (word 0x30)) *) + 0x54001200; (* arm_BEQ (word 0x240) *) + 0xf100805f; (* arm_CMP X2 (rvalue (word 0x20)) *) + 0x54001ea0; (* arm_BEQ (word 0x3d4) *) + 0xf100405f; (* arm_CMP X2 (rvalue (word 0x10)) *) + 0x54002740; (* arm_BEQ (word 0x4e8) *) + 0x14000163; (* arm_B (word 0x58c) *) + 0xd503201f; (* arm_NOP *) + 0xd503201f; (* arm_NOP *) 0x4cdf7000; (* arm_LDR Q0 X0 (Postimmediate_Offset (word 0x10)) *) 0x4cdf7001; (* arm_LDR Q1 X0 (Postimmediate_Offset (word 0x10)) *) 0x4cdf7018; (* arm_LDR Q24 X0 (Postimmediate_Offset (word 0x10)) *) @@ -409,7 +413,7 @@ 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 0x1) *) 0x9e670126; (* arm_FMOV_ItoF Q6 X9 0x0 *) 0x9eaf0146; (* arm_FMOV_ItoF Q6 X10 0x1 *) - 0x140000de; (* arm_B (word 0x378) *) + 0x140000da; (* arm_B (word 0x368) *) 0xd503201f; (* arm_NOP *) 0x4cdfa000; (* arm_LDP Q0 Q1 X0 (Postimmediate_Offset (word 0x20)) *) 0x4cdf7018; (* arm_LDR Q24 X0 (Postimmediate_Offset (word 0x10)) *) @@ -513,7 +517,7 @@ 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 0x1) *) 0x9e670126; (* arm_FMOV_ItoF Q6 X9 0x0 *) 0x9eaf0146; (* arm_FMOV_ItoF Q6 X10 0x1 *) - 0x14000076; (* arm_B (word 0x1d8) *) + 0x14000072; (* arm_B (word 0x1c8) *) 0x4cdfa000; (* arm_LDP Q0 Q1 X0 (Postimmediate_Offset (word 0x20)) *) 0x6e261c00; (* arm_EOR_VEC Q0 Q0 Q6 0x80 *) 0x6e281c21; (* arm_EOR_VEC Q1 Q1 Q8 0x80 *) @@ -584,7 +588,7 @@ 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 0x1) *) 0x9e670126; (* arm_FMOV_ItoF Q6 X9 0x0 *) 0x9eaf0146; (* arm_FMOV_ItoF Q6 X10 0x1 *) - 0x1400002f; (* arm_B (word 0xbc) *) + 0x1400002b; (* arm_B (word 0xac) *) 0x4cdf7000; (* arm_LDR Q0 X0 (Postimmediate_Offset (word 0x10)) *) 0x6e261c00; (* arm_EOR_VEC Q0 Q0 Q6 0x80 *) 0x4e284a00; (* arm_AESE Q0 Q16 *) @@ -625,11 +629,7 @@ 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 0x1) *) 0x9e670126; (* arm_FMOV_ItoF Q6 X9 0x0 *) 0x9eaf0146; (* arm_FMOV_ItoF Q6 X10 0x1 *) - 0x14000006; (* arm_B (word 0x18) *) - 0xd503201f; (* arm_NOP *) - 0xd503201f; (* arm_NOP *) - 0xd503201f; (* arm_NOP *) - 0xd503201f; (* arm_NOP *) + 0x14000002; (* arm_B (word 0x8) *) 0xd503201f; (* arm_NOP *) 0xf2400ebf; (* arm_TST X21 (rvalue (word 0xf)) *) 0x540003e0; (* arm_BEQ (word 0x7c) *) diff --git a/arm/proofs/aes-xts-armv8.ml b/arm/proofs/aes-xts-armv8.ml index cea3c4011..70ee7856b 100644 --- a/arm/proofs/aes-xts-armv8.ml +++ b/arm/proofs/aes-xts-armv8.ml @@ -10,7 +10,7 @@ needs "arm/proofs/aes_encrypt_spec.ml";; needs "arm/proofs/aes_xts_encrypt_spec.ml";; (* print_literal_from_elf "arm/aes-xts/aes-xts-armv8.o";; *) -(* save_literal_from_elf "arm/aes-xts/aes-xts-armv8.txt" "arm/aes-xts/aes-xts-armv8.o";;*) +(* save_literal_from_elf "arm/aes-xts/aes-xts-armv8.txt" "arm/aes-xts/aes-xts-armv8.o";; *) (* let aes_xts_armv8 = define_assert_from_elf "aes_xts_armv8" "arm/aes-xts/aes-xts-armv8.o" ..*) @@ -33,13 +33,17 @@ let aes256_xts_encrypt_mc = define_assert_from_elf "aes256_xts_encrypt_mc" "arm/ 0x6d053fee; (* arm_STP D14 D15 SP (Immediate_Offset (iword (&0x50))) *) 0xa90053f3; (* arm_STP X19 X20 SP (Immediate_Offset (iword (&0x0))) *) 0xa9015bf5; (* arm_STP X21 X22 SP (Immediate_Offset (iword (&0x10))) *) + 0xb202e7e8; (* arm_MOV X8 (rvalue (word 0xcccccccccccccccc)) *) + 0xf29999a8; (* arm_MOVK X8 (word 0xcccd) 0x0 *) + 0x9bc87c48; (* arm_UMULH X8 X2 X8 *) + 0xd346fd08; (* arm_LSR X8 X8 0x6 *) 0xf100405f; (* arm_CMP X2 (rvalue (word 0x10)) *) - 0x5400520b; (* arm_BLT (word 0xa40) *) + 0x5400518b; (* arm_BLT (word 0xa30) *) 0xd503201f; (* arm_NOP *) 0xd503201f; (* arm_NOP *) 0xd503201f; (* arm_NOP *) - (* // Lxts_enc_big_size: *) +(* // Lxts_enc_big_size: *) 0x92400c55; (* arm_AND X21 X2 (rvalue (word 0xf)) *) 0x927cec42; (* arm_AND X2 X2 (rvalue (word 0xfffffffffffffff0)) *) @@ -64,7 +68,7 @@ let aes256_xts_encrypt_mc = define_assert_from_elf "aes256_xts_encrypt_mc" "arm/ 0x6e201cc6; (* arm_EOR_VEC Q6 Q6 Q0 0x80 *) (* iv for second block *) - (* pc + 0x80 *) + (* pc + 0x90 *) 0x9e6600c9; (* arm_FMOV_FtoI X9 Q6 0x0 0x40 *) 0x9eae00ca; (* arm_FMOV_FtoI X10 Q6 0x1 0x40 *) 0x528010f3; (* arm_MOV W19 (rvalue (word 0x87)) *) @@ -76,7 +80,7 @@ let aes256_xts_encrypt_mc = define_assert_from_elf "aes256_xts_encrypt_mc" "arm/ 0x9eaf0148; (* arm_FMOV_ItoF Q8 X10 0x1 *) (* Load key schedule *) - (* pc + 0xa4 *) + (* pc + 0xb4 *) 0xaa0303e7; (* arm_MOV X7 X3 *) 0x4cdfa8f0; (* arm_LDP Q16 Q17 X7 (Postimmediate_Offset (word 0x20)) *) 0x4cdfa8ec; (* arm_LDP Q12 Q13 X7 (Postimmediate_Offset (word 0x20)) *) @@ -88,7 +92,7 @@ let aes256_xts_encrypt_mc = define_assert_from_elf "aes256_xts_encrypt_mc" "arm/ 0x4c4078e7; (* arm_LDR Q7 X7 No_Offset *) (* Lxts_enc: *) - (* pc + 0xc8 *) + (* pc + 0xd8 *) 0xf100805f; (* arm_CMP X2 (rvalue (word 0x20)) *) 0x540042e3; (* arm_BCC (word 0x85c) *) (* b.lo Lxts_enc_tail1x // when input = 1 with tail *) @@ -302,20 +306,20 @@ let aes256_xts_encrypt_mc = define_assert_from_elf "aes256_xts_encrypt_mc" "arm/ 0xac828420; (* arm_STP Q0 Q1 X1 (Postimmediate_Offset (iword (&0x50))) *) 0xad3ee438; (* arm_STP Q24 Q25 X1 (Immediate_Offset (iword (-- &0x30))) *) 0x3c9f003a; (* arm_STR Q26 X1 (Immediate_Offset (word 0xfffffffffffffff0)) *) - 0xf1014042; (* arm_SUBS X2 X2 (rvalue (word 0x50)) *) - 0xf101405f; (* arm_CMP X2 (rvalue (word 0x50)) *) - 0x54000043; (* arm_BCC (word 0x8) *) - 0x54ffe862; (* arm_BCS (word 0x1ffd0c) *) - 0xf100005f; (* arm_CMP X2 (rvalue (word 0x0)) *) - 0x54002da0; (* arm_BEQ (word 0x5b4) *) - 0xf100405f; (* arm_CMP X2 (rvalue (word 0x10)) *) - 0x540027a0; (* arm_BEQ (word 0x4f4) *) - 0xf100805f; (* arm_CMP X2 (rvalue (word 0x20)) *) - 0x54001e80; (* arm_BEQ (word 0x3d0) *) - 0xf100c05f; (* arm_CMP X2 (rvalue (word 0x30)) *) - 0x54001160; (* arm_BEQ (word 0x22c) *) + 0xd1014042; (* arm_SUB X2 X2 (rvalue (word 0x50)) *) + 0xf1000508; (* arm_SUBS X8 X8 (rvalue (word 0x1)) *) + 0xb5ffe888; (* arm_CBNZ X8 (word 0x1ffd10) *) 0xf101005f; (* arm_CMP X2 (rvalue (word 0x40)) *) - 0x54000020; (* arm_BEQ (word 0x4) *) + 0x54000140; (* arm_BEQ (word 0x28) *) + 0xf100c05f; (* arm_CMP X2 (rvalue (word 0x30)) *) + 0x54001200; (* arm_BEQ (word 0x240) *) + 0xf100805f; (* arm_CMP X2 (rvalue (word 0x20)) *) + 0x54001ea0; (* arm_BEQ (word 0x3d4) *) + 0xf100405f; (* arm_CMP X2 (rvalue (word 0x10)) *) + 0x54002740; (* arm_BEQ (word 0x4e8) *) + 0x14000163; (* arm_B (word 0x58c) *) + 0xd503201f; (* arm_NOP *) + 0xd503201f; (* arm_NOP *) 0x4cdf7000; (* arm_LDR Q0 X0 (Postimmediate_Offset (word 0x10)) *) 0x4cdf7001; (* arm_LDR Q1 X0 (Postimmediate_Offset (word 0x10)) *) 0x4cdf7018; (* arm_LDR Q24 X0 (Postimmediate_Offset (word 0x10)) *) @@ -450,7 +454,7 @@ let aes256_xts_encrypt_mc = define_assert_from_elf "aes256_xts_encrypt_mc" "arm/ 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 0x1) *) 0x9e670126; (* arm_FMOV_ItoF Q6 X9 0x0 *) 0x9eaf0146; (* arm_FMOV_ItoF Q6 X10 0x1 *) - 0x140000de; (* arm_B (word 0x378) *) + 0x140000da; (* arm_B (word 0x368) *) 0xd503201f; (* arm_NOP *) 0x4cdfa000; (* arm_LDP Q0 Q1 X0 (Postimmediate_Offset (word 0x20)) *) 0x4cdf7018; (* arm_LDR Q24 X0 (Postimmediate_Offset (word 0x10)) *) @@ -554,7 +558,7 @@ let aes256_xts_encrypt_mc = define_assert_from_elf "aes256_xts_encrypt_mc" "arm/ 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 0x1) *) 0x9e670126; (* arm_FMOV_ItoF Q6 X9 0x0 *) 0x9eaf0146; (* arm_FMOV_ItoF Q6 X10 0x1 *) - 0x14000076; (* arm_B (word 0x1d8) *) + 0x14000072; (* arm_B (word 0x1c8) *) 0x4cdfa000; (* arm_LDP Q0 Q1 X0 (Postimmediate_Offset (word 0x20)) *) 0x6e261c00; (* arm_EOR_VEC Q0 Q0 Q6 0x80 *) 0x6e281c21; (* arm_EOR_VEC Q1 Q1 Q8 0x80 *) @@ -625,9 +629,10 @@ let aes256_xts_encrypt_mc = define_assert_from_elf "aes256_xts_encrypt_mc" "arm/ 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 0x1) *) 0x9e670126; (* arm_FMOV_ItoF Q6 X9 0x0 *) 0x9eaf0146; (* arm_FMOV_ItoF Q6 X10 0x1 *) - 0x1400002f; (* arm_B (word 0xbc) *) + 0x1400002b; (* arm_B (word 0xac) *) (* Lxts_enc_tail1x: *) + (* pc + 0x938 *) 0x4cdf7000; (* arm_LDR Q0 X0 (Postimmediate_Offset (word 0x10)) *) 0x6e261c00; (* arm_EOR_VEC Q0 Q0 Q6 0x80 *) 0x4e284a00; (* arm_AESE Q0 Q16 *) @@ -668,11 +673,7 @@ let aes256_xts_encrypt_mc = define_assert_from_elf "aes256_xts_encrypt_mc" "arm/ 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 0x1) *) 0x9e670126; (* arm_FMOV_ItoF Q6 X9 0x0 *) 0x9eaf0146; (* arm_FMOV_ItoF Q6 X10 0x1 *) - 0x14000006; (* arm_B (word 0x18) *) - 0xd503201f; (* arm_NOP *) - 0xd503201f; (* arm_NOP *) - 0xd503201f; (* arm_NOP *) - 0xd503201f; (* arm_NOP *) + 0x14000002; (* arm_B (word 0x8) *) 0xd503201f; (* arm_NOP *) (* Lxts_enc_done: *) @@ -729,7 +730,8 @@ let AESENC_TAC = BITBLAST_TAC;; let AESXTS_ENC_ONE_BLOCK_TAC = - REWRITE_TAC [aes256_xts_encrypt_one_block] THEN + REWRITE_TAC [aes256_xts_encrypt_1block] THEN + REWRITE_TAC [xts_init_tweak; aes256_xts_encrypt_round] THEN CONV_TAC (TOP_DEPTH_CONV let_CONV) THEN GEN_REWRITE_TAC LAND_CONV [WORD_XOR_SYM] THEN REPEAT (AP_THM_TAC THEN AP_TERM_TAC) THEN @@ -743,7 +745,7 @@ void aes_hw_xts_encrypt(const uint8_t *in, uint8_t *out, size_t length, (* for stack pointer alignment and nonoverlapping examples, I looked at shigoel's sha512_block_data_order_hw.ml and bignum_invsqrt_p25519_alt.ml *) let AES256_ENCRYPT_ONE_BLOCK_CORRECT = prove( - `! plaintext ciphertext key1 key2 iv + `! ptxt ctxt key1 key2 iv in_pt tweak k1_0 k1_1 k1_2 k1_3 k1_4 k1_5 k1_6 k1_7 k1_8 k1_9 k1_10 k1_11 k1_12 k1_13 k1_14 k2_0 k2_1 k2_2 k2_3 k2_4 k2_5 k2_6 k2_7 k2_8 k2_9 k2_10 k2_11 k2_12 k2_13 k2_14 @@ -752,7 +754,7 @@ let AES256_ENCRYPT_ONE_BLOCK_CORRECT = prove( PAIRWISE nonoverlapping [(stackpointer, 6*16); (word pc, LENGTH aes256_xts_encrypt_mc); - (ciphertext, 16); + (ctxt, 16); (key1, 244); (key2, 244)] ==> ensures arm @@ -760,8 +762,8 @@ let AES256_ENCRYPT_ONE_BLOCK_CORRECT = prove( (\s. aligned_bytes_loaded s (word pc) aes256_xts_encrypt_mc /\ read PC s = word (pc + 28) /\ read SP s = stackpointer /\ - C_ARGUMENTS [plaintext; ciphertext; word 16; key1; key2; iv] s /\ - read(memory :> bytes128 plaintext) s = in_pt /\ + C_ARGUMENTS [ptxt; ctxt; word 16; key1; key2; iv] s /\ + read(memory :> bytes128 ptxt) s = in_pt /\ read(memory :> bytes128 iv) s = tweak /\ read(memory :> bytes32 (word_add key1 (word 240))) s = word 14 /\ read(memory :> bytes128 key1) s = k1_0 /\ @@ -798,15 +800,14 @@ let AES256_ENCRYPT_ONE_BLOCK_CORRECT = prove( ) // postcondition (\s. read PC s = word (pc + LENGTH aes256_xts_encrypt_mc - 8*4) /\ - read(memory :> bytes128 ciphertext) s = - aes256_xts_encrypt_one_block in_pt + read(memory :> bytes128 ctxt) s = + aes256_xts_encrypt_1block in_pt tweak [k1_0; k1_1; k1_2; k1_3; k1_4; k1_5; k1_6; k1_7; k1_8; k1_9; k1_10; k1_11; k1_12; k1_13; k1_14] [k2_0; k2_1; k2_2; k2_3; k2_4; k2_5; k2_6; k2_7; k2_8; k2_9; k2_10; k2_11; k2_12; k2_13; k2_14] - tweak ) - (MAYCHANGE [PC;X0;X1;X2;X4;X6;X7;X9;X10;X11;X19;X20;X21;X22],, + (MAYCHANGE [PC;X0;X1;X2;X4;X6;X7;X8;X9;X10;X11;X19;X20;X21;X22],, MAYCHANGE [Q0;Q1;Q4;Q5;Q6;Q7;Q8;Q9;Q10;Q11;Q12;Q13;Q14;Q15;Q16;Q17;Q18;Q19;Q20;Q21;Q22;Q23;Q24;Q25;Q26],, - MAYCHANGE SOME_FLAGS,, MAYCHANGE [memory :> bytes128 ciphertext],, + MAYCHANGE SOME_FLAGS,, MAYCHANGE [memory :> bytes128 ctxt],, MAYCHANGE [events])` (* ,, MAYCHANGE [memory :> bytes(stackpointer, 160) *), @@ -823,7 +824,7 @@ let AES256_ENCRYPT_ONE_BLOCK_CORRECT = prove( ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (7--25) THEN ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (26--56) THEN - ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (57--65) THEN + ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (57--69) THEN (* FIRST_X_ASSUM(MP_TAC o MATCH_MP (MESON[] `read Q6 s = a ==> !a'. a = a' ==> read Q6 s = a'`)) THEN *) FIRST_X_ASSUM(MP_TAC o SPEC @@ -831,15 +832,15 @@ let AES256_ENCRYPT_ONE_BLOCK_CORRECT = prove( o MATCH_MP (MESON[] `read Q6 s = a ==> !a'. a = a' ==> read Q6 s = a'`)) THEN ANTS_TAC THENL [ASM_REWRITE_TAC[] THEN AESENC_TAC; DISCH_TAC] THEN - ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (66--74) THEN - ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (75--83) THEN - ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (84--85) THEN + ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (70--70) THEN + ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (71--78) THEN + ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (79--87) THEN + ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (88--89) THEN - ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (86--86) THEN - ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (87--87) THEN - ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (88--115) THEN + ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (90--90) THEN + ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (91--119) THEN - (* FIRST_X_ASSUM(MP_TAC o MATCH_MP (MESON[] `read Q0 s = a ==> !a'. a = a' ==> read Q0 s = a'`)) THEN *) +(* FIRST_X_ASSUM(MP_TAC o MATCH_MP (MESON[] `read Q0 s = a ==> !a'. a = a' ==> read Q0 s = a'`)) THEN *) FIRST_X_ASSUM(MP_TAC o SPEC `(aes256_encrypt (word_xor @@ -852,43 +853,31 @@ let AES256_ENCRYPT_ONE_BLOCK_CORRECT = prove( o MATCH_MP (MESON[] `read Q0 s = a ==> !a'. a = a' ==> read Q0 s = a'`)) THEN ANTS_TAC THENL [ASM_REWRITE_TAC[] THEN AESENC_TAC; DISCH_TAC] THEN - ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (116--116) THEN - -(* - FIRST_X_ASSUM(MP_TAC o SPEC - `(aes256_xts_encrypt_one_block - (in_pt:int128) - [k1_0:int128; k1_1; k1_2; k1_3; k1_4; k1_5; k1_6; k1_7; k1_8; k1_9; k1_10; - k1_11; k1_12; k1_13; k1_14] - [k2_0:int128; k2_1; k2_2; k2_3; k2_4; k2_5; k2_6; k2_7; k2_8; k2_9; k2_10; - k2_11; k2_12; k2_13; k2_14] - (tweak:int128)):int128` - o MATCH_MP (MESON[] `read Q0 s = a ==> !a'. a = a' ==> read Q0 s = a'`)) THEN - ANTS_TAC THENL [ASM_REWRITE_TAC[] THEN AESXTS_ENC_ONE_BLOCK_TAC; DISCH_TAC] THEN -*) + ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (120--120) THEN - ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (117--117) THEN + ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (121--121) THEN FIRST_X_ASSUM(MP_TAC o SPEC - `(aes256_xts_encrypt_one_block + `(aes256_xts_encrypt_1block (in_pt:int128) + (tweak:int128) [k1_0:int128; k1_1; k1_2; k1_3; k1_4; k1_5; k1_6; k1_7; k1_8; k1_9; k1_10; k1_11; k1_12; k1_13; k1_14] [k2_0:int128; k2_1; k2_2; k2_3; k2_4; k2_5; k2_6; k2_7; k2_8; k2_9; k2_10; - k2_11; k2_12; k2_13; k2_14] - (tweak:int128)):int128` - o MATCH_MP (MESON[] `read (memory :> bytes128 ciphertext) s = a ==> !a'. a = a' - ==> read (memory :> bytes128 ciphertext) s = a'`)) THEN + k2_11; k2_12; k2_13; k2_14]):int128` + o MATCH_MP (MESON[] `read (memory :> bytes128 ctxt) s = a ==> !a'. a = a' + ==> read (memory :> bytes128 ctxt) s = a'`)) THEN ANTS_TAC THENL [ASM_REWRITE_TAC[] THEN AESXTS_ENC_ONE_BLOCK_TAC; DISCH_TAC] THEN - ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (118--122) THEN - ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (123--128) THEN - (* ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (128--136) THEN *) + ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (122--126) THEN + ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (127--132) THEN ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN ARITH_TAC );; + + (* `word_xor (aes256_encrypt @@ -983,7 +972,7 @@ If I don't make the second FIRST_X_ASSUM before XORING with the tweak, How can I go within this term to do it later in the second argument of the first xor to make it aes256_encrypt? - 83 [`read (memory :> bytes128 ciphertext) s117 = + 83 [`read (memory :> bytes128 ctxt) s117 = word_xor (aes256_encrypt tweak [k2_0; k2_1; k2_2; k2_3; k2_4; k2_5; k2_6; k2_7; k2_8; k2_9; k2_10; diff --git a/arm/proofs/aes_xts_encrypt_spec.ml b/arm/proofs/aes_xts_encrypt_spec.ml index 05269274f..c33cafabb 100644 --- a/arm/proofs/aes_xts_encrypt_spec.ml +++ b/arm/proofs/aes_xts_encrypt_spec.ml @@ -1,36 +1,5 @@ needs "arm/proofs/base.ml";; needs "arm/proofs/aes_encrypt_spec.ml";; -(* -AES-256-XTS Encryption Algorithm for One Block -Based on IEEE 1619-2007 Standard - -Sec 5.3.1 Encryption of a single block - -Key = Key1 256-bit data key - Key2 256-bit tweak key -P is a block of 128 bits (i.e., the plaintext) -i is the value of the 128-bit tweak (see 5.1) -j is the sequential number of the 128-bit block inside the data unit -C is the block of 128 bits of ciphertext resulting from the operation - -T := AES-enc(Key2 , i) MUL α^j -PP := P XOR T -CC := AES-enc(Key1 , PP) -C := CC XOR T - -j=0 => alpha^j = unity transformation, - i.e. no change to the encrypted tweak for the the first block -*) - -(* XTS encryption function definition *) -let aes256_xts_encrypt_one_block = new_definition - `aes256_xts_encrypt_one_block (plaintext:int128) (data_key_schedule:int128 list) - (tweak_key_schedule:int128 list) (tweak:int128) = - let T = aes256_encrypt tweak tweak_key_schedule in - let pre_encrypt = word_xor plaintext T in - let encrypted = aes256_encrypt pre_encrypt data_key_schedule in - word_xor encrypted T`;; - (* AES-256-XTS Encryption Algorithm for Any Input Length @@ -41,7 +10,7 @@ as described in IEEE 1619-2007, Section 5.3, supporting arbitrary input lengths. Key components: - Key = Key1 (256-bit data key) || Key2 (256-bit tweak key) -- P is the plaintext of arbitrary length (≥ 128 bits) +- P is the plaintext of arbitrary length (>= 128 bits) - i is the value of the 128-bit tweak - C is the resulting ciphertext @@ -49,12 +18,12 @@ The algorithm processes data in 128-bit blocks with special handling for the final partial block (if any) using ciphertext stealing. For each complete block j: - T_j := AES-enc(Key2, i) MUL α^j + T_j := AES-enc(Key2, i) MUL alpha^j PP_j := P_j XOR T_j CC_j := AES-enc(Key1, PP_j) C_j := CC_j XOR T_j -Where α is the primitive element in GF(2^128) and MUL denotes multiplication +Where alpha is the primitive element in GF(2^128) and MUL denotes multiplication in the Galois field. For partial final blocks, ciphertext stealing is used as per Section 5.3.2. @@ -278,43 +247,44 @@ let tweak_key_schedule = new_definition `tweak_key_schedule:int128 list = *) (* Convert reversed plaintext and ciphertext to byte lists using int128_to_bytes *) -let plaintext = new_definition - `plaintext = +let ptext = new_definition + `ptext = int128_to_bytes (word 0x0F0E0D0C0B0A09080706050403020100 : int128)`;; -let ciphertext = new_definition - `ciphertext = +let ctext = new_definition + `ctext = int128_to_bytes (word 0x9BCF70E3996C83E48603772F103A3B1C : int128 )`;; let cerr = new_definition `cerr = int128_to_bytes (word 0x0)`;; -let iv = new_definition - `iv = (word 0x000000000000000000000000000000FF) : int128`;; +let iv1 = new_definition + `iv1 = (word 0x000000000000000000000000000000FF) : int128`;; -let plaintext2 = new_definition - `plaintext2 = +let ptext2 = new_definition + `ptext2 = APPEND (int128_to_bytes (word 0x0F0E0D0C0B0A09080706050403020100)) (int128_to_bytes (word 0x1F1E1D1C1B1A19181716151413121110))`;; -(REWR_CONV plaintext2 THENC +(* +(REWR_CONV ptext2 THENC RAND_CONV INT128_TO_BYTES_CONV THENC RATOR_CONV(RAND_CONV INT128_TO_BYTES_CONV) THENC - REWRITE_CONV [APPEND]) `plaintext2`;; - + REWRITE_CONV [APPEND]) `ptext2`;; +*) (* loops indefinitely - (REWR_CONV plaintext2 THENC + (REWR_CONV ptext2 THENC DEPTH_CONV INT128_TO_BYTES_CONV THENC (*RATOR_CONV(RAND_CONV INT128_TO_BYTES_CONV) THENC*) - REWRITE_CONV [APPEND]) `plaintext2`;; + REWRITE_CONV [APPEND]) `ptext2`;; *) (* Test values from aes_xts_decrypt_spec.ml *) let iv_tweak = new_definition `iv_tweak = (word 0x0000000000000000000000123456789a) : int128`;; -(* p0 = pm1 = plaintext *) +(* p0 = pm1 = ptext *) let pm1 = new_definition `pm1 = [word 0x0; word 0x1; word 0x2; word 0x3; word 0x4; word 0x5; word 0x6; word 0x7; @@ -446,14 +416,14 @@ let key_2 = new_definition `key_2:int128 list = let XTS_INIT_TWEAK_CONV = REWR_CONV xts_init_tweak THENC AESENC_HELPER_CONV;; (* -let tmp_xts_tweak = (REWRITE_CONV [iv; tweak_key_schedule] THENC XTS_INIT_TWEAK_CONV) - `xts_init_tweak iv +let tmp_xts_tweak = (REWRITE_CONV [iv1; tweak_key_schedule] THENC XTS_INIT_TWEAK_CONV) + `xts_init_tweak iv1 tweak_key_schedule`;; (* Or the following: 33 sec *) -time prove(`xts_init_tweak iv +time prove(`xts_init_tweak iv1 tweak_key_schedule = word 0x8b2b4a71228e98aed6aa0ca97775261a`, - CONV_TAC(REWRITE_CONV [iv; tweak_key_schedule] THENC LAND_CONV XTS_INIT_TWEAK_CONV) + CONV_TAC(REWRITE_CONV [iv1; tweak_key_schedule] THENC LAND_CONV XTS_INIT_TWEAK_CONV) THEN REFL_TAC );; *) @@ -506,7 +476,7 @@ let AES_XTS_ENC_1BLK_HELPER_CONV = SUBLET_CONV AESENC_HELPER_CONV THENC let_CONV THENC AES256_XTS_ENCRYPT_ROUND_CONV;; - ;; + (* (* Proven in about 73 sec on M3 *) time prove(`aes256_xts_encrypt_1block @@ -556,9 +526,9 @@ let BYTES_TO_INT128_CONV = REWRITE_CONV EL_16_8_CLAUSES THENC DEPTH_CONV WORD_RED_CONV;; (* -time prove(`bytes_to_int128 plaintext +time prove(`bytes_to_int128 ptext = (word 0x0f0e0d0c0b0a09080706050403020100 :int128)`, - CONV_TAC(REWRITE_CONV [plaintext;int128_to_bytes] THENC + CONV_TAC(REWRITE_CONV [ptext;int128_to_bytes] THENC LAND_CONV BYTES_TO_INT128_CONV) THEN REFL_TAC );; @@ -605,10 +575,10 @@ let rec CALCULATE_TWEAK_CONV tm = | _ -> failwith "CALCULATE_TWEAK_CONV: inapplicable";; (* (* result: word 0x8b2b4a71228e98aed6aa0ca97775261a, confirmed by input to first encrypt_round above *) -(REWRITE_CONV [iv;tweak_key_schedule] THENC CALCULATE_TWEAK_CONV) `calculate_tweak 0 iv tweak_key_schedule`;; +(REWRITE_CONV [iv1;tweak_key_schedule] THENC CALCULATE_TWEAK_CONV) `calculate_tweak 0 iv1 tweak_key_schedule`;; *)(* (* result: word 0x165694e2451d315dad541952eeea4cb3, confirmed by input to second encrypt_round above *) -(REWRITE_CONV [iv;tweak_key_schedule] THENC CALCULATE_TWEAK_CONV) `calculate_tweak 1 iv tweak_key_schedule`;; +(REWRITE_CONV [iv1;tweak_key_schedule] THENC CALCULATE_TWEAK_CONV) `calculate_tweak 1 iv1 tweak_key_schedule`;; *) let rec AES256_XTS_ENCRYPT_REC_CONV tm = @@ -642,18 +612,18 @@ let rec AES256_XTS_ENCRYPT_REC_CONV tm = | _ -> failwith "AES256_XTS_ENCRYPT_REC_CONV: inapplicable";; (* -(REWRITE_CONV [iv; data_key_schedule; tweak_key_schedule; plaintext; int128_to_bytes] THENC +(REWRITE_CONV [iv1; data_key_schedule; tweak_key_schedule; ptext; int128_to_bytes] THENC AES256_XTS_ENCRYPT_REC_CONV) - `aes256_xts_encrypt_rec 0 0 plaintext iv data_key_schedule tweak_key_schedule`;; + `aes256_xts_encrypt_rec 0 0 ptext iv1 data_key_schedule tweak_key_schedule`;; *) (* (REWRITE_CONV [iv_tweak; pm1; key_1; key_2] THENC AES256_XTS_ENCRYPT_REC_CONV) `aes256_xts_encrypt_rec 0 0 pm1 iv_tweak key_1 key_2`;; *) (* -(REWRITE_CONV [iv; data_key_schedule; tweak_key_schedule; plaintext2; int128_to_bytes; APPEND] THENC +(REWRITE_CONV [iv1; data_key_schedule; tweak_key_schedule; ptext2; int128_to_bytes; APPEND] THENC AES256_XTS_ENCRYPT_REC_CONV) - `aes256_xts_encrypt_rec 0 1 plaintext2 iv data_key_schedule tweak_key_schedule`;; + `aes256_xts_encrypt_rec 0 1 ptext2 iv1 data_key_schedule tweak_key_schedule`;; *) (* @@ -687,8 +657,8 @@ let CIPHER_STEALING_ENCRYPT_CONV = SUBLET_CONV (RAND_CONV AES256_XTS_ENCRYPT_ROUND_CONV) THENC SUBLET_CONV INT128_TO_BYTES_CONV THENC let_CONV;; -(* (REWRITE_CONV [plaintext; int128_to_bytes; iv; data_key_schedule; tweak_key_schedule] THENC CIPHER_STEALING_ENCRYPT_CONV) - `cipher_stealing_encrypt plaintext [(word 0x0)] 1 iv 0 data_key_schedule tweak_key_schedule`;;*) +(* (REWRITE_CONV [ptext; int128_to_bytes; iv1; data_key_schedule; tweak_key_schedule] THENC CIPHER_STEALING_ENCRYPT_CONV) + `cipher_stealing_encrypt ptext [(word 0x0)] 1 iv1 0 data_key_schedule tweak_key_schedule`;;*) (* (REWRITE_CONV [pm1; pm; iv_tweak; key_1; key_2] THENC CIPHER_STEALING_ENCRYPT_CONV) `cipher_stealing_encrypt pm1 pm 6 iv_tweak 0 key_1 key_2`;; @@ -727,8 +697,8 @@ let AES256_XTS_ENCRYPT_TAIL_CONV tm = else ONE_BLOCK_AND_TAIL_CONV tm | _ -> failwith "AES256_XTS_ENCRYPT_TAIL_CONV: inapplicable";; (* -(REWRITE_CONV [plaintext; int128_to_bytes; iv; data_key_schedule; tweak_key_schedule] THENC AES256_XTS_ENCRYPT_TAIL_CONV) - `aes256_xts_encrypt_tail 0 0 plaintext iv data_key_schedule tweak_key_schedule`;; +(REWRITE_CONV [ptext; int128_to_bytes; iv1; data_key_schedule; tweak_key_schedule] THENC AES256_XTS_ENCRYPT_TAIL_CONV) + `aes256_xts_encrypt_tail 0 0 ptext iv1 data_key_schedule tweak_key_schedule`;; *)(* (REWRITE_CONV [p1;iv_tweak;key_1;key_2] THENC AES256_XTS_ENCRYPT_TAIL_CONV) `aes256_xts_encrypt_tail 0 6 p1 iv_tweak key_1 key_2`;; @@ -773,12 +743,12 @@ let AES256_XTS_ENCRYPT_CONV tm = (REWRITE_CONV [cerr; int128_to_bytes] THENC AES256_XTS_ENCRYPT_CONV) `aes256_xts_encrypt p0 5 iv_tweak key_1 key_2 cerr`;; -(*(REWRITE_CONV [plaintext; cerr; int128_to_bytes; iv_tweak; key_1; key_2] THENC AES256_XTS_ENCRYPT_CONV) - `aes256_xts_encrypt plaintext 16 iv_tweak key_1 key_2 cerr`;;*) +(*(REWRITE_CONV [ptext; cerr; int128_to_bytes; iv_tweak; key_1; key_2] THENC AES256_XTS_ENCRYPT_CONV) + `aes256_xts_encrypt ptext 16 iv_tweak key_1 key_2 cerr`;;*) (* 1 block : 68 sec on M3 *) -time prove (`aes256_xts_encrypt plaintext 16 iv_tweak key_1 key_2 cerr = c0`, - CONV_TAC(LAND_CONV (REWRITE_CONV [plaintext; cerr; int128_to_bytes; iv_tweak; key_1; key_2] +time prove (`aes256_xts_encrypt ptext 16 iv_tweak key_1 key_2 cerr = c0`, + CONV_TAC(LAND_CONV (REWRITE_CONV [ptext; cerr; int128_to_bytes; iv_tweak; key_1; key_2] THENC AES256_XTS_ENCRYPT_CONV)) THEN REWRITE_TAC [c0] THEN REFL_TAC);; From fbeca3bc4a0b1a489d30dca61173a312d0a8b76c Mon Sep 17 00:00:00 2001 From: Nevine Ebeid Date: Thu, 25 Sep 2025 10:10:32 -0400 Subject: [PATCH 064/132] WIP: full proof: - loop invariant, one subgoal proven. - proof of code before the loop started. --- arm/proofs/aes-xts-armv8.ml | 654 +++++++++++++++++++++++++++++++----- 1 file changed, 563 insertions(+), 91 deletions(-) diff --git a/arm/proofs/aes-xts-armv8.ml b/arm/proofs/aes-xts-armv8.ml index 70ee7856b..ad1dc79a1 100644 --- a/arm/proofs/aes-xts-armv8.ml +++ b/arm/proofs/aes-xts-armv8.ml @@ -120,6 +120,9 @@ let aes256_xts_encrypt_mc = define_assert_from_elf "aes256_xts_encrypt_mc" "arm/ 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 0x1) *) 0x9e67012b; (* arm_FMOV_ItoF Q11 X9 0x0 *) 0x9eaf014b; (* arm_FMOV_ItoF Q11 X10 0x1 *) + + (* .Loop5x_xts_enc *) + (* pc + 0x140 *) 0xacc28400; (* arm_LDP Q0 Q1 X0 (Postimmediate_Offset (iword (&0x50))) *) 0xad7ee418; (* arm_LDP Q24 Q25 X0 (Immediate_Offset (iword (-- &0x30))) *) 0x3cdf001a; (* arm_LDR Q26 X0 (Immediate_Offset (word 0xfffffffffffffff0)) *) @@ -309,6 +312,9 @@ let aes256_xts_encrypt_mc = define_assert_from_elf "aes256_xts_encrypt_mc" "arm/ 0xd1014042; (* arm_SUB X2 X2 (rvalue (word 0x50)) *) 0xf1000508; (* arm_SUBS X8 X8 (rvalue (word 0x1)) *) 0xb5ffe888; (* arm_CBNZ X8 (word 0x1ffd10) *) + + (* .Loop5x_enc_after: *) + (* pc + 0x434 *) 0xf101005f; (* arm_CMP X2 (rvalue (word 0x40)) *) 0x54000140; (* arm_BEQ (word 0x28) *) 0xf100c05f; (* arm_CMP X2 (rvalue (word 0x30)) *) @@ -719,6 +725,31 @@ let aes256_xts_encrypt_mc = define_assert_from_elf "aes256_xts_encrypt_mc" "arm/ 0xd65f03c0 (* arm_RET X30 *) ];; +(** Definitions **) + +(* same as in aes_xts_decrypt.ml *) +let set_key_schedule = new_definition + `set_key_schedule (s:armstate) (key_ptr:int64) (k0:int128) + (k1:int128) (k2:int128) (k3:int128) (k4:int128) (k5:int128) + (k6:int128) (k7:int128) (k8:int128) (k9:int128) (ka:int128) + (kb:int128) (kc:int128) (kd:int128) (ke:int128) : bool = + (read(memory :> bytes128 key_ptr) s = k0 /\ + read(memory :> bytes128 (word_add key_ptr (word 16))) s = k1 /\ + read(memory :> bytes128 (word_add key_ptr (word 32))) s = k2 /\ + read(memory :> bytes128 (word_add key_ptr (word 48))) s = k3 /\ + read(memory :> bytes128 (word_add key_ptr (word 64))) s = k4 /\ + read(memory :> bytes128 (word_add key_ptr (word 80))) s = k5 /\ + read(memory :> bytes128 (word_add key_ptr (word 96))) s = k6 /\ + read(memory :> bytes128 (word_add key_ptr (word 112))) s = k7 /\ + read(memory :> bytes128 (word_add key_ptr (word 128))) s = k8 /\ + read(memory :> bytes128 (word_add key_ptr (word 144))) s = k9 /\ + read(memory :> bytes128 (word_add key_ptr (word 160))) s = ka /\ + read(memory :> bytes128 (word_add key_ptr (word 176))) s = kb /\ + read(memory :> bytes128 (word_add key_ptr (word 192))) s = kc /\ + read(memory :> bytes128 (word_add key_ptr (word 208))) s = kd /\ + read(memory :> bytes128 (word_add key_ptr (word 224))) s = ke /\ + read(memory :> bytes32 (word_add key_ptr (word 240))) s = word 14)`;; + let AES256_XTS_ENCRYPT_EXEC = ARM_MK_EXEC_RULE aes256_xts_encrypt_mc;; @@ -745,98 +776,61 @@ void aes_hw_xts_encrypt(const uint8_t *in, uint8_t *out, size_t length, (* for stack pointer alignment and nonoverlapping examples, I looked at shigoel's sha512_block_data_order_hw.ml and bignum_invsqrt_p25519_alt.ml *) let AES256_ENCRYPT_ONE_BLOCK_CORRECT = prove( - `! ptxt ctxt key1 key2 iv - in_pt tweak - k1_0 k1_1 k1_2 k1_3 k1_4 k1_5 k1_6 k1_7 k1_8 k1_9 k1_10 k1_11 k1_12 k1_13 k1_14 + `! ptxt_p ctxt_p key1_p key2_p iv_p + pt_in iv + (k1_0:int128) k1_1 k1_2 k1_3 k1_4 k1_5 k1_6 k1_7 k1_8 k1_9 k1_10 k1_11 k1_12 k1_13 k1_14 k2_0 k2_1 k2_2 k2_3 k2_4 k2_5 k2_6 k2_7 k2_8 k2_9 k2_10 k2_11 k2_12 k2_13 k2_14 pc stackpointer. aligned 16 stackpointer /\ PAIRWISE nonoverlapping [(stackpointer, 6*16); (word pc, LENGTH aes256_xts_encrypt_mc); - (ctxt, 16); - (key1, 244); - (key2, 244)] + (ctxt_p, 16); + (key1_p, 244); + (key2_p, 244)] ==> ensures arm // precondition (\s. aligned_bytes_loaded s (word pc) aes256_xts_encrypt_mc /\ read PC s = word (pc + 28) /\ read SP s = stackpointer /\ - C_ARGUMENTS [ptxt; ctxt; word 16; key1; key2; iv] s /\ - read(memory :> bytes128 ptxt) s = in_pt /\ - read(memory :> bytes128 iv) s = tweak /\ - read(memory :> bytes32 (word_add key1 (word 240))) s = word 14 /\ - read(memory :> bytes128 key1) s = k1_0 /\ - read(memory :> bytes128 (word_add key1 (word 16))) s = k1_1 /\ - read(memory :> bytes128 (word_add key1 (word 32))) s = k1_2 /\ - read(memory :> bytes128 (word_add key1 (word 48))) s = k1_3 /\ - read(memory :> bytes128 (word_add key1 (word 64))) s = k1_4 /\ - read(memory :> bytes128 (word_add key1 (word 80))) s = k1_5 /\ - read(memory :> bytes128 (word_add key1 (word 96))) s = k1_6 /\ - read(memory :> bytes128 (word_add key1 (word 112))) s = k1_7 /\ - read(memory :> bytes128 (word_add key1 (word 128))) s = k1_8 /\ - read(memory :> bytes128 (word_add key1 (word 144))) s = k1_9 /\ - read(memory :> bytes128 (word_add key1 (word 160))) s = k1_10 /\ - read(memory :> bytes128 (word_add key1 (word 176))) s = k1_11 /\ - read(memory :> bytes128 (word_add key1 (word 192))) s = k1_12 /\ - read(memory :> bytes128 (word_add key1 (word 208))) s = k1_13 /\ - read(memory :> bytes128 (word_add key1 (word 224))) s = k1_14 /\ - read(memory :> bytes32 (word_add key2 (word 240))) s = word 14 /\ - read(memory :> bytes128 key2) s = k2_0 /\ - read(memory :> bytes128 (word_add key2 (word 16))) s = k2_1 /\ - read(memory :> bytes128 (word_add key2 (word 32))) s = k2_2 /\ - read(memory :> bytes128 (word_add key2 (word 48))) s = k2_3 /\ - read(memory :> bytes128 (word_add key2 (word 64))) s = k2_4 /\ - read(memory :> bytes128 (word_add key2 (word 80))) s = k2_5 /\ - read(memory :> bytes128 (word_add key2 (word 96))) s = k2_6 /\ - read(memory :> bytes128 (word_add key2 (word 112))) s = k2_7 /\ - read(memory :> bytes128 (word_add key2 (word 128))) s = k2_8 /\ - read(memory :> bytes128 (word_add key2 (word 144))) s = k2_9 /\ - read(memory :> bytes128 (word_add key2 (word 160))) s = k2_10 /\ - read(memory :> bytes128 (word_add key2 (word 176))) s = k2_11 /\ - read(memory :> bytes128 (word_add key2 (word 192))) s = k2_12 /\ - read(memory :> bytes128 (word_add key2 (word 208))) s = k2_13 /\ - read(memory :> bytes128 (word_add key2 (word 224))) s = k2_14 + C_ARGUMENTS [ptxt_p; ctxt_p; word 16; key1_p; key2_p; iv_p] s /\ + read(memory :> bytes128 ptxt_p) s = pt_in /\ + read(memory :> bytes128 iv_p) s = iv /\ + set_key_schedule s key1_p k1_0 k1_1 k1_2 k1_3 k1_4 k1_5 k1_6 k1_7 k1_8 k1_9 k1_10 k1_11 k1_12 k1_13 k1_14 /\ + set_key_schedule s key2_p k2_0 k2_1 k2_2 k2_3 k2_4 k2_5 k2_6 k2_7 k2_8 k2_9 k2_10 k2_11 k2_12 k2_13 k2_14 ) // postcondition (\s. read PC s = word (pc + LENGTH aes256_xts_encrypt_mc - 8*4) /\ - read(memory :> bytes128 ctxt) s = - aes256_xts_encrypt_1block in_pt tweak + read(memory :> bytes128 ctxt_p) s = + aes256_xts_encrypt_1block pt_in iv [k1_0; k1_1; k1_2; k1_3; k1_4; k1_5; k1_6; k1_7; k1_8; k1_9; k1_10; k1_11; k1_12; k1_13; k1_14] [k2_0; k2_1; k2_2; k2_3; k2_4; k2_5; k2_6; k2_7; k2_8; k2_9; k2_10; k2_11; k2_12; k2_13; k2_14] ) (MAYCHANGE [PC;X0;X1;X2;X4;X6;X7;X8;X9;X10;X11;X19;X20;X21;X22],, MAYCHANGE [Q0;Q1;Q4;Q5;Q6;Q7;Q8;Q9;Q10;Q11;Q12;Q13;Q14;Q15;Q16;Q17;Q18;Q19;Q20;Q21;Q22;Q23;Q24;Q25;Q26],, - MAYCHANGE SOME_FLAGS,, MAYCHANGE [memory :> bytes128 ctxt],, - MAYCHANGE [events])` - (* ,, - MAYCHANGE [memory :> bytes(stackpointer, 160) *), - REWRITE_TAC[NONOVERLAPPING_CLAUSES; C_ARGUMENTS; SOME_FLAGS; PAIRWISE; ALL] THEN + MAYCHANGE SOME_FLAGS,, MAYCHANGE [memory :> bytes128 ctxt_p],, + MAYCHANGE [events])`, REWRITE_TAC [(REWRITE_CONV [aes256_xts_encrypt_mc] THENC LENGTH_CONV) `LENGTH aes256_xts_encrypt_mc`] THEN + REWRITE_TAC[set_key_schedule; NONOVERLAPPING_CLAUSES; C_ARGUMENTS; SOME_FLAGS; PAIRWISE; ALL] THEN REPEAT STRIP_TAC THEN + (* Start symbolic simulation *) ENSURES_INIT_TAC "s0" THEN - ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (1--1) THEN - ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (2--2) THEN - ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (3--3) THEN - ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (4--4) THEN - ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (5--6) THEN + (* Simulate until the iv encryption and verify it against AES encryption spec *) + ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (1--6) THEN ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (7--25) THEN - ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (26--56) THEN ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (57--69) THEN (* FIRST_X_ASSUM(MP_TAC o MATCH_MP (MESON[] `read Q6 s = a ==> !a'. a = a' ==> read Q6 s = a'`)) THEN *) FIRST_X_ASSUM(MP_TAC o SPEC - `(aes256_encrypt (tweak:int128) [k2_0:int128; k2_1; k2_2; k2_3; k2_4; k2_5; k2_6; k2_7; k2_8; k2_9; k2_10; k2_11; k2_12; k2_13; k2_14]):int128` + `(aes256_encrypt (iv:int128) [k2_0:int128; k2_1; k2_2; k2_3; k2_4; k2_5; k2_6; k2_7; k2_8; k2_9; k2_10; k2_11; k2_12; k2_13; k2_14]):int128` o MATCH_MP (MESON[] `read Q6 s = a ==> !a'. a = a' ==> read Q6 s = a'`)) THEN ANTS_TAC THENL [ASM_REWRITE_TAC[] THEN AESENC_TAC; DISCH_TAC] THEN - ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (70--70) THEN - ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (71--78) THEN - ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (79--87) THEN - ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (88--89) THEN - + (* Simulate until the one-block input encryption until before XORing the iv with the output. *) + ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (70--78) THEN + ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (79--89) THEN ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (90--90) THEN ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (91--119) THEN @@ -845,27 +839,29 @@ let AES256_ENCRYPT_ONE_BLOCK_CORRECT = prove( `(aes256_encrypt (word_xor (aes256_encrypt - tweak + iv [k2_0; k2_1; k2_2; k2_3; k2_4; k2_5; k2_6; k2_7; k2_8; k2_9; k2_10; k2_11; k2_12; k2_13; k2_14]) - in_pt:int128) + pt_in:int128) [k1_0:int128; k1_1; k1_2; k1_3; k1_4; k1_5; k1_6; k1_7; k1_8; k1_9; k1_10; k1_11; k1_12; k1_13; k1_14]):int128` o MATCH_MP (MESON[] `read Q0 s = a ==> !a'. a = a' ==> read Q0 s = a'`)) THEN ANTS_TAC THENL [ASM_REWRITE_TAC[] THEN AESENC_TAC; DISCH_TAC] THEN + (* XOR the tweak with the output in Q0 *) ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (120--120) THEN + (* Write it to the ciphertext output *) ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (121--121) THEN FIRST_X_ASSUM(MP_TAC o SPEC `(aes256_xts_encrypt_1block - (in_pt:int128) - (tweak:int128) + (pt_in:int128) + (iv:int128) [k1_0:int128; k1_1; k1_2; k1_3; k1_4; k1_5; k1_6; k1_7; k1_8; k1_9; k1_10; k1_11; k1_12; k1_13; k1_14] [k2_0:int128; k2_1; k2_2; k2_3; k2_4; k2_5; k2_6; k2_7; k2_8; k2_9; k2_10; k2_11; k2_12; k2_13; k2_14]):int128` - o MATCH_MP (MESON[] `read (memory :> bytes128 ctxt) s = a ==> !a'. a = a' - ==> read (memory :> bytes128 ctxt) s = a'`)) THEN + o MATCH_MP (MESON[] `read (memory :> bytes128 ctxt_p) s = a ==> !a'. a = a' + ==> read (memory :> bytes128 ctxt_p) s = a'`)) THEN ANTS_TAC THENL [ASM_REWRITE_TAC[] THEN AESXTS_ENC_ONE_BLOCK_TAC; DISCH_TAC] THEN ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (122--126) THEN @@ -876,30 +872,506 @@ let AES256_ENCRYPT_ONE_BLOCK_CORRECT = prove( ARITH_TAC );; +(*******************************************) +(* Full proof *) + +let byte_list_l_at = define + `byte_list_l_at (m : byte list) (l:num) (m_p : int64) s = + ! i. i < l ==> read (memory :> bytes8(word_add m_p (word i))) s = EL i m`;; +let word_split_lemma = prove( + `!len:int64. word_add (word_and len (word 0xf)) + (word_and len (word 0xfffffffffffffff0)) = len`, + BITBLAST_TAC);; + +let LEN_FULL_BLOCKS_LO_BOUND_THM = prove( + `!(len:int64) len_full_blocks. word_and len (word 0xfffffffffffffff0) = len_full_blocks + ==> ~(val len < 0x50) + ==> ~(val len_full_blocks < 0x50)`, + BITBLAST_TAC);; + +let LEN_FULL_BLOCKS_HI_BOUND_THM = prove( + `!(len:int64) len_full_blocks. word_and len (word 0xfffffffffffffff0) = len_full_blocks + ==> val len <= 2 EXP 24 + ==> val len_full_blocks <= 2 EXP 24`, + BITBLAST_TAC);; + + let TAIL_LEN_BOUND_THM = prove( + `!(len:int64) tail_len. word_and len (word 0xf) = tail_len + ==> val tail_len < 0x10`, + BITBLAST_TAC);; + +let NUM_5BLOCKS_LO_BOUND_THM = prove( + `!(len_full_blocks:int64) (num_5blocks:int64). + val len_full_blocks <= 2 EXP 24 + ==> ~(val len_full_blocks < 0x50) + ==> word (val len_full_blocks DIV 0x50) = num_5blocks + ==> 0x0 < val num_5blocks`, + REPEAT STRIP_TAC THEN + EXPAND_TAC "num_5blocks" THEN + REWRITE_TAC[VAL_WORD; DIMINDEX_64] THEN + UNDISCH_TAC `~(val (len_full_blocks:int64) < 0x50)` THEN + ABBREV_TAC `n = val (len_full_blocks:int64)` THEN + SUBGOAL_THEN `n DIV 0x50 < 2 EXP 64` ASSUME_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[MOD_LT] THEN + ARITH_TAC +);; +(* +void aes_hw_xts_encrypt(const uint8_t *in, uint8_t *out, size_t length, + const AES_KEY *key1, const AES_KEY *key2, + const uint8_t iv[16]) +*) + +let AES256_XTS_ENCRYPT_CORRECT = prove( + `!ptxt_p ctxt_p len key1_p key2_p iv_p ct_org + pt_in iv + k1_0 k1_1 k1_2 k1_3 k1_4 k1_5 k1_6 k1_7 k1_8 k1_9 k1_10 k1_11 k1_12 k1_13 k1_14 + k2_0 k2_1 k2_2 k2_3 k2_4 k2_5 k2_6 k2_7 k2_8 k2_9 k2_10 k2_11 k2_12 k2_13 k2_14 + pc stackpointer. + aligned 16 stackpointer /\ + PAIRWISE nonoverlapping + [(stackpointer, 6*16); + (word pc, LENGTH aes256_xts_encrypt_mc); + (ctxt_p, val len); + (key1_p, 244); + (key2_p, 244)] /\ + val len >= 16 /\ val len <= 2 EXP 24 /\ LENGTH pt_in = val len + ==> ensures arm + // precondition + (\s. aligned_bytes_loaded s (word pc) aes256_xts_encrypt_mc /\ + read PC s = word (pc + 28) /\ + read SP s = stackpointer /\ + C_ARGUMENTS [ptxt_p; ctxt_p; len; key1_p; key2_p; iv_p] s /\ + byte_list_l_at pt_in (val len) ptxt_p s /\ + byte_list_l_at ct_err 15 ct_org s /\ + read(memory :> bytes128 ctxt_p) s = err /\ + read(memory :> bytes128 iv_p) s = iv /\ + set_key_schedule s key1_p k1_0 k1_1 k1_2 k1_3 k1_4 k1_5 k1_6 k1_7 k1_8 k1_9 k1_10 k1_11 k1_12 k1_13 k1_14 /\ + set_key_schedule s key2_p k2_0 k2_1 k2_2 k2_3 k2_4 k2_5 k2_6 k2_7 k2_8 k2_9 k2_10 k2_11 k2_12 k2_13 k2_14 + ) + // postcondition + (\s. read PC s = word (pc + LENGTH aes256_xts_encrypt_mc - 8*4) /\ + byte_list_l_at (aes256_xts_encrypt pt_in (val len) iv + [k1_0; k1_1; k1_2; k1_3; k1_4; k1_5; k1_6; k1_7; k1_8; k1_9; k1_10; k1_11; k1_12; k1_13; k1_14] + [k2_0; k2_1; k2_2; k2_3; k2_4; k2_5; k2_6; k2_7; k2_8; k2_9; k2_10; k2_11; k2_12; k2_13; k2_14] ct_err) + (val len) ctxt_p s + ) + (MAYCHANGE [PC;X0;X1;X2;X4;X6;X7;X8;X9;X10;X11;X19;X20;X21;X22],, + MAYCHANGE [Q0;Q1;Q4;Q5;Q6;Q7;Q8;Q9;Q10;Q11;Q12;Q13;Q14;Q15;Q16;Q17;Q18;Q19;Q20;Q21;Q22;Q23;Q24;Q25;Q26],, + MAYCHANGE SOME_FLAGS,, MAYCHANGE [memory :> bytes128 ctxt_p],, + MAYCHANGE [events])`, + + REWRITE_TAC [(REWRITE_CONV [aes256_xts_encrypt_mc] THENC LENGTH_CONV) `LENGTH aes256_xts_encrypt_mc`] THEN + REWRITE_TAC[byte_list_l_at; set_key_schedule; NONOVERLAPPING_CLAUSES; C_ARGUMENTS; SOME_FLAGS; PAIRWISE; ALL] THEN + REPEAT STRIP_TAC THEN + + (* Break len into full blocks and tail *) + SUBGOAL_THEN `word_add (word_and len (word 0xf)) + (word_and len (word 0xfffffffffffffff0)) = len:int64` ASSUME_TAC THENL + [REWRITE_TAC[word_split_lemma]; ALL_TAC] THEN + ABBREV_TAC `len_full_blocks:int64 = word_and len (word 0xfffffffffffffff0)` THEN + ABBREV_TAC `tail_len:int64 = word_and len (word 0xf)` THEN + + ABBREV_TAC `key1_lst:int128 list = [k1_0; k1_1; k1_2; k1_3; k1_4; k1_5; k1_6; k1_7; k1_8; k1_9; k1_10; k1_11; k1_12; k1_13; k1_14]` THEN + ABBREV_TAC `key2_lst:int128 list = [k2_0; k2_1; k2_2; k2_3; k2_4; k2_5; k2_6; k2_7; k2_8; k2_9; k2_10; k2_11; k2_12; k2_13; k2_14]` THEN + + (* Case splits on length: + len < 16 -- error case + len < 32 -- one block, or one block and a tail + len < 48 -- two blocks, or two blocks and a tail + len < 64 -- three blocks, or three blocks and a tail + len < 80 -- four blocks, or four blocks and a tail + len >= 80 -- five blocks and up => at least one big loop iteration + + Note: for encrypt, in cipherstealing, the tail is directly processed since the last + tweak is available from prior calculations. The order of the tweaks is not flipped, + as in the case of decrypt, between the last block and the tail. + *) + ASM_CASES_TAC `val (len:int64) < 0x50` THENL [CHEAT_TAC; ALL_TAC] THEN + + ABBREV_TAC `num_5blocks = (word (val (len_full_blocks:int64) DIV 0x50)):int64` THEN + + SUBGOAL_THEN `~(val (len_full_blocks:int64) < 0x50)` ASSUME_TAC THENL + [ UNDISCH_TAC `~(val (len:int64) < 0x50)` THEN + UNDISCH_TAC `word_and len (word 0xfffffffffffffff0) = (len_full_blocks:int64)` THEN + MP_TAC (SPECL [`len:int64`; `len_full_blocks:int64`] LEN_FULL_BLOCKS_LO_BOUND_THM) THEN + SIMP_TAC[]; ALL_TAC] THEN + SUBGOAL_THEN `val (len_full_blocks:int64) <= 0x2 EXP 24` ASSUME_TAC THENL + [ UNDISCH_TAC `val (len:int64) <= 0x2 EXP 24` THEN + UNDISCH_TAC `word_and len (word 0xfffffffffffffff0) = (len_full_blocks:int64)` THEN + MP_TAC (SPECL [`len:int64`; `len_full_blocks:int64`] LEN_FULL_BLOCKS_HI_BOUND_THM) THEN + SIMP_TAC[]; ALL_TAC] THEN + SUBGOAL_THEN `0 < val (num_5blocks:int64)` ASSUME_TAC THENL + [ UNDISCH_TAC `word (val (len_full_blocks:int64) DIV 0x50) = (num_5blocks:int64)` THEN + UNDISCH_TAC `~(val (len_full_blocks:int64) < 0x50)` THEN + UNDISCH_TAC `val (len_full_blocks:int64) <= 0x2 EXP 24` THEN + MP_TAC (SPECL [`len_full_blocks:int64`; `num_5blocks:int64`] + NUM_5BLOCKS_LO_BOUND_THM) THEN SIMP_TAC[] + ; ALL_TAC] THEN + + (* Verify properties of the program until the beginning of the loop. + This saves work in the second subgoal of the loop invariant and brings it here. + Up to the loop: + - First 5 tweaks are calculated from the iv + - X2 contains len_full_blocks + - X8 contains num_5_blocks + - key1 schedule is loaded in Q registers *) + ENSURES_SEQUENCE_TAC + `pc + 0x140` + `\s. + read X0 s = ptxt_p /\ + read X1 s = ctxt_p /\ + read X2 s = len_full_blocks /\ + read X8 s = num_5blocks /\ + read X21 s = tail_len /\ + read Q6 s = calculate_tweak 0 iv key2 /\ + read Q8 s = calculate_tweak 1 iv key2 /\ + read Q9 s = calculate_tweak 2 iv key2 /\ + read Q10 s = calculate_tweak 3 iv key2 /\ + read Q11 s = calculate_tweak 4 iv key2 /\ + read X19 s = word 0x87 /\ + ` THEN + + (* Loop invariant *) + ENSURES_WHILE_PAUP_TAC + `0` (* counter begin number *) + `val (num_5blocks:int64)` (* counter end number *) + `pc + 0x140` (* loop body start PC *) + `pc + 0x430` (* loop backedge branch PC *) + `\i s. + // loop invariant at the end of the loop + (read X8 s = word_sub num_5blocks (word i) /\ + read X0 s = word_add ptxt_p (word_mul (word 0x50) (word i)) /\ + read X1 s = word_add ctxt_p (word_mul (word 0x50) (word i)) /\ + byte_list_l_at (aes256_xts_encrypt pt_in (i * 0x50) iv key1_lst key2_lst ct_err) + (i * 0x50) ptxt_p s) /\ + // loop backedge condition + (read ZF s <=> i = val (num_5blocks:int64))` THEN + ASM_REWRITE_TAC[] THEN REPEAT CONJ_TAC THENL + [ + (* Subgoal 1. + 0 < `val (num_5blocks:int64)`` + automatically discharged by asm *) + + (* Subgoal 2. *) + REWRITE_TAC[byte_list_l_at] THEN + ENSURES_INIT_TAC "s0" THEN + ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN + REPEAT CONJ_TAC THENL + (* + `aligned_bytes_loaded s0 (word pc) aes256_xts_encrypt_mc /\ + read PC s0 = word (pc + 0x140) /\ + read X8 s0 = word_sub num_5blocks (word 0x0) /\ + read X0 s0 = word_add ptxt_p (word_mul (word 0x50) (word 0x0)) /\ + read X1 s0 = word_add ctxt_p (word_mul (word 0x50) (word 0x0)) /\ + (forall i. + i < 0x0 * 0x50 + ==> read (memory :> bytes8 (word_add ptxt_p (word i))) s0 = + EL i + (aes256_xts_encrypt pt_in (0x0 * 0x50) iv key1_lst key2_lst ct_err))` + +`eventually arm + (\s'. + (aligned_bytes_loaded s' (word pc) aes256_xts_encrypt_mc /\ + read PC s' = word (pc + 0x140) /\ + read X8 s' = word_sub num_5blocks (word 0x0) /\ + read X0 s' = word_add ptxt_p (word_mul (word 0x50) (word 0x0)) /\ + read X1 s' = word_add ctxt_p (word_mul (word 0x50) (word 0x0)) /\ + (forall i. + i < 0x0 * 0x50 + ==> read (memory :> bytes8 (word_add ptxt_p (word i))) s' = + EL i + (aes256_xts_encrypt pt_in (0x0 * 0x50) iv key1_lst key2_lst + ct_err))) /\ + (MAYCHANGE + [PC; X0; X1; X2; X4; X6; X7; X8; X9; X10; X11; X19; X20; X21; X22] ,, + MAYCHANGE + [Q0; Q1; Q4; Q5; Q6; Q7; Q8; Q9; Q10; Q11; Q12; Q13; Q14; Q15; Q16; + Q17; Q18; Q19; Q20; Q21; Q22; Q23; Q24; Q25; Q26] ,, + MAYCHANGE [NF; ZF; CF; VF] ,, + MAYCHANGE [memory :> bytes128 ctxt_p] ,, + MAYCHANGE [events]) + s0 + s') + s0` + + + 0 [`aligned 0x10 stackpointer`] + 1 [`nonoverlapping_modulo (0x2 EXP 0x40) (val stackpointer,0x6 * 0x10) + (pc,0xa80)`] + 2 [`nonoverlapping_modulo (0x2 EXP 0x40) (val stackpointer,0x6 * 0x10) + (val ctxt_p,val len)`] + 3 [`nonoverlapping_modulo (0x2 EXP 0x40) (val stackpointer,0x6 * 0x10) + (val key1_p,0xf4)`] + 4 [`nonoverlapping_modulo (0x2 EXP 0x40) (val stackpointer,0x6 * 0x10) + (val key2_p,0xf4)`] + 5 [`nonoverlapping_modulo (0x2 EXP 0x40) (pc,0xa80) (val ctxt_p,val len)`] + 6 [`nonoverlapping_modulo (0x2 EXP 0x40) (pc,0xa80) (val key1_p,0xf4)`] + 7 [`nonoverlapping_modulo (0x2 EXP 0x40) (pc,0xa80) (val key2_p,0xf4)`] + 8 [`nonoverlapping_modulo (0x2 EXP 0x40) (val ctxt_p,val len) + (val key1_p,0xf4)`] + 9 [`nonoverlapping_modulo (0x2 EXP 0x40) (val ctxt_p,val len) + (val key2_p,0xf4)`] + 10 [`nonoverlapping_modulo (0x2 EXP 0x40) (val key1_p,0xf4) + (val key2_p,0xf4)`] + 11 [`val len >= 0x10`] + 12 [`val len <= 0x2 EXP 0x18`] + 13 [`LENGTH pt_in = val len`] + 14 [`word_add tail_len len_full_blocks = len`] + 15 [`word_and len (word 0xfffffffffffffff0) = len_full_blocks`] + 16 [`word_and len (word 0xf) = tail_len`] + 17 [`[k1_0; k1_1; k1_2; k1_3; k1_4; k1_5; k1_6; k1_7; k1_8; k1_9; k1_10; + k1_11; k1_12; k1_13; k1_14] = + key1_lst`] + 18 [`[k2_0; k2_1; k2_2; k2_3; k2_4; k2_5; k2_6; k2_7; k2_8; k2_9; k2_10; + k2_11; k2_12; k2_13; k2_14] = + key2_lst`] + 19 [`~(val len < 0x50)`] + 20 [`word (val len_full_blocks DIV 0x50) = num_5blocks`] + 21 [`~(val len_full_blocks < 0x50)`] + 22 [`val len_full_blocks <= 0x2 EXP 0x18`] + 23 [`0x0 < val num_5blocks`] + +`ensures arm + (\s. + aligned_bytes_loaded s (word pc) aes256_xts_encrypt_mc /\ + read PC s = word (pc + 0x1c) /\ + read SP s = stackpointer /\ + (read X0 s = ptxt_p /\ + read X1 s = ctxt_p /\ + read X2 s = len /\ + read X3 s = key1_p /\ + read X4 s = key2_p /\ + read X5 s = iv_p) /\ + (forall i. + i < val len + ==> read (memory :> bytes8 (word_add ptxt_p (word i))) s = + EL i pt_in) /\ + (forall i. + i < 0xf + ==> read (memory :> bytes8 (word_add ct_org (word i))) s = + EL i ct_err) /\ + read (memory :> bytes128 ctxt_p) s = err /\ + read (memory :> bytes128 iv_p) s = iv /\ + (read (memory :> bytes128 key1_p) s = k1_0 /\ + read (memory :> bytes128 (word_add key1_p (word 0x10))) s = k1_1 /\ + read (memory :> bytes128 (word_add key1_p (word 0x20))) s = k1_2 /\ + read (memory :> bytes128 (word_add key1_p (word 0x30))) s = k1_3 /\ + read (memory :> bytes128 (word_add key1_p (word 0x40))) s = k1_4 /\ + read (memory :> bytes128 (word_add key1_p (word 0x50))) s = k1_5 /\ + read (memory :> bytes128 (word_add key1_p (word 0x60))) s = k1_6 /\ + read (memory :> bytes128 (word_add key1_p (word 0x70))) s = k1_7 /\ + read (memory :> bytes128 (word_add key1_p (word 0x80))) s = k1_8 /\ + read (memory :> bytes128 (word_add key1_p (word 0x90))) s = k1_9 /\ + read (memory :> bytes128 (word_add key1_p (word 0xa0))) s = k1_10 /\ + read (memory :> bytes128 (word_add key1_p (word 0xb0))) s = k1_11 /\ + read (memory :> bytes128 (word_add key1_p (word 0xc0))) s = k1_12 /\ + read (memory :> bytes128 (word_add key1_p (word 0xd0))) s = k1_13 /\ + read (memory :> bytes128 (word_add key1_p (word 0xe0))) s = k1_14 /\ + read (memory :> bytes32 (word_add key1_p (word 0xf0))) s = word 0xe) /\ + read (memory :> bytes128 key2_p) s = k2_0 /\ + read (memory :> bytes128 (word_add key2_p (word 0x10))) s = k2_1 /\ + read (memory :> bytes128 (word_add key2_p (word 0x20))) s = k2_2 /\ + read (memory :> bytes128 (word_add key2_p (word 0x30))) s = k2_3 /\ + read (memory :> bytes128 (word_add key2_p (word 0x40))) s = k2_4 /\ + read (memory :> bytes128 (word_add key2_p (word 0x50))) s = k2_5 /\ + read (memory :> bytes128 (word_add key2_p (word 0x60))) s = k2_6 /\ + read (memory :> bytes128 (word_add key2_p (word 0x70))) s = k2_7 /\ + read (memory :> bytes128 (word_add key2_p (word 0x80))) s = k2_8 /\ + read (memory :> bytes128 (word_add key2_p (word 0x90))) s = k2_9 /\ + read (memory :> bytes128 (word_add key2_p (word 0xa0))) s = k2_10 /\ + read (memory :> bytes128 (word_add key2_p (word 0xb0))) s = k2_11 /\ + read (memory :> bytes128 (word_add key2_p (word 0xc0))) s = k2_12 /\ + read (memory :> bytes128 (word_add key2_p (word 0xd0))) s = k2_13 /\ + read (memory :> bytes128 (word_add key2_p (word 0xe0))) s = k2_14 /\ + read (memory :> bytes32 (word_add key2_p (word 0xf0))) s = word 0xe) + (\s. + aligned_bytes_loaded s (word pc) aes256_xts_encrypt_mc /\ + read PC s = word (pc + 0x140) /\ + read X8 s = word_sub num_5blocks (word 0x0) /\ + read X0 s = word_add ptxt_p (word_mul (word 0x50) (word 0x0)) /\ + read X1 s = word_add ctxt_p (word_mul (word 0x50) (word 0x0)) /\ + byte_list_l_at + (aes256_xts_encrypt pt_in (0x0 * 0x50) iv key1_lst key2_lst ct_err) + (0x0 * 0x50) + ptxt_p + s) + (MAYCHANGE + [PC; X0; X1; X2; X4; X6; X7; X8; X9; X10; X11; X19; X20; X21; X22] ,, + MAYCHANGE + [Q0; Q1; Q4; Q5; Q6; Q7; Q8; Q9; Q10; Q11; Q12; Q13; Q14; Q15; Q16; Q17; + Q18; Q19; Q20; Q21; Q22; Q23; Q24; Q25; Q26] ,, + MAYCHANGE [NF; ZF; CF; VF] ,, + MAYCHANGE [memory :> bytes128 ctxt_p] ,, + MAYCHANGE [events])` + + +(* + Decrypt Subgoal 2 without the ENSURES_SEQUENCE_TAC before the loop invariant + + 0 [`nonoverlapping_modulo (0x2 EXP 0x40) (pc,0xb20) (val pt_ptr,val len)`] + 1 [`nonoverlapping_modulo (0x2 EXP 0x40) (val ct_ptr,val len) + (val pt_ptr,val len)`] + 2 [`val len >= 0x10`] + 3 [`val len <= 0x2 EXP 0x18`] + 4 [`LENGTH ct = val len`] + 5 [`word_add tail_len num_blocks = len`] + 6 [`word_and len (word 0xfffffffffffffff0) = num_blocks`] + 7 [`word_and len (word 0xf) = tail_len`] + 8 [`[k00; k01; k02; k03; k04; k05; k06; k07; k08; k09; k0a; k0b; k0c; k0d; + k0e] = + key1`] + 9 [`[k10; k11; k12; k13; k14; k15; k16; k17; k18; k19; k1a; k1b; k1c; k1d; + k1e] = + key2`] + 10 [`~(val len < 0x60)`] + 11 [`(if val tail_len = 0x0 + then num_blocks + else word_sub num_blocks (word 0x10)) = + num_blocks_adjusted`] + 12 [`word (val num_blocks_adjusted DIV 0x50) = num_5blocks_adjusted`] + 13 [`~(val num_blocks < 0x60)`] + 14 [`val num_blocks <= 0x2 EXP 0x18`] + 15 [`~(val num_blocks_adjusted < 0x50)`] + 16 [`val num_blocks_adjusted <= 0x2 EXP 0x18`] + 17 [`0x0 < val num_5blocks_adjusted`] + +`ensures arm + (\s. + aligned_bytes_loaded s (word pc) aes_xts_decrypt_mc /\ + read PC s = word (pc + 0x1c) /\ + (read X0 s = ct_ptr /\ + read X1 s = pt_ptr /\ + read X2 s = len /\ + read X3 s = key1_ptr /\ + read X4 s = key2_ptr /\ + read X5 s = iv_ptr) /\ + (forall i. + i < val len + ==> read (memory :> bytes8 (word_add ct_ptr (word i))) s = EL i ct) /\ + (forall i. + i < LENGTH pt_init + ==> read (memory :> bytes8 (word_add pt_ptr (word i))) s = + EL i pt_init) /\ + read (memory :> bytes128 iv_ptr) s = iv /\ + (read (memory :> bytes128 key1_ptr) s = k00 /\ + read (memory :> bytes128 (word_add key1_ptr (word 0x10))) s = k01 /\ + read (memory :> bytes128 (word_add key1_ptr (word 0x20))) s = k02 /\ + read (memory :> bytes128 (word_add key1_ptr (word 0x30))) s = k03 /\ + read (memory :> bytes128 (word_add key1_ptr (word 0x40))) s = k04 /\ + read (memory :> bytes128 (word_add key1_ptr (word 0x50))) s = k05 /\ + read (memory :> bytes128 (word_add key1_ptr (word 0x60))) s = k06 /\ + read (memory :> bytes128 (word_add key1_ptr (word 0x70))) s = k07 /\ + read (memory :> bytes128 (word_add key1_ptr (word 0x80))) s = k08 /\ + read (memory :> bytes128 (word_add key1_ptr (word 0x90))) s = k09 /\ + read (memory :> bytes128 (word_add key1_ptr (word 0xa0))) s = k0a /\ + read (memory :> bytes128 (word_add key1_ptr (word 0xb0))) s = k0b /\ + read (memory :> bytes128 (word_add key1_ptr (word 0xc0))) s = k0c /\ + read (memory :> bytes128 (word_add key1_ptr (word 0xd0))) s = k0d /\ + read (memory :> bytes128 (word_add key1_ptr (word 0xe0))) s = k0e /\ + read (memory :> bytes32 (word_add key1_ptr (word 0xf0))) s = word 0xe) /\ + read (memory :> bytes128 key2_ptr) s = k10 /\ + read (memory :> bytes128 (word_add key2_ptr (word 0x10))) s = k11 /\ + read (memory :> bytes128 (word_add key2_ptr (word 0x20))) s = k12 /\ + read (memory :> bytes128 (word_add key2_ptr (word 0x30))) s = k13 /\ + read (memory :> bytes128 (word_add key2_ptr (word 0x40))) s = k14 /\ + read (memory :> bytes128 (word_add key2_ptr (word 0x50))) s = k15 /\ + read (memory :> bytes128 (word_add key2_ptr (word 0x60))) s = k16 /\ + read (memory :> bytes128 (word_add key2_ptr (word 0x70))) s = k17 /\ + read (memory :> bytes128 (word_add key2_ptr (word 0x80))) s = k18 /\ + read (memory :> bytes128 (word_add key2_ptr (word 0x90))) s = k19 /\ + read (memory :> bytes128 (word_add key2_ptr (word 0xa0))) s = k1a /\ + read (memory :> bytes128 (word_add key2_ptr (word 0xb0))) s = k1b /\ + read (memory :> bytes128 (word_add key2_ptr (word 0xc0))) s = k1c /\ + read (memory :> bytes128 (word_add key2_ptr (word 0xd0))) s = k1d /\ + read (memory :> bytes128 (word_add key2_ptr (word 0xe0))) s = k1e /\ + read (memory :> bytes32 (word_add key2_ptr (word 0xf0))) s = word 0xe) + (\s. + aligned_bytes_loaded s (word pc) aes_xts_decrypt_mc /\ + read PC s = word (pc + 0x170) /\ + read X0 s = word_add ct_ptr (word_mul (word 0x50) (word 0x0)) /\ + read X1 s = word_add pt_ptr (word_mul (word 0x50) (word 0x0)) /\ + read X3 s = key1_ptr /\ + read X21 s = tail_len /\ + read X2 s = + word_sub num_blocks_adjusted (word_mul (word 0x50) (word 0x0)) /\ + read X8 s = word_sub num_5blocks_adjusted (word 0x0) /\ + read Q6 s = calculate_tweak (0x0 * 0x5) iv key2 /\ + read Q8 s = calculate_tweak (0x0 * 0x5 + 0x1) iv key2 /\ + read Q9 s = calculate_tweak (0x0 * 0x5 + 0x2) iv key2 /\ + read Q10 s = calculate_tweak (0x0 * 0x5 + 0x3) iv key2 /\ + read Q11 s = calculate_tweak (0x0 * 0x5 + 0x4) iv key2 /\ + read X19 s = word 0x87 /\ + read X10 s = + word_subword (calculate_tweak (0x0 * 0x5 + 0x4) iv key2) (0x40,0x40) /\ + read X9 s = word_zx (calculate_tweak (0x0 * 0x5 + 0x4) iv key2) /\ + read Q16 s = k00 /\ + read Q17 s = k01 /\ + read Q12 s = k02 /\ + read Q13 s = k03 /\ + read Q14 s = k04 /\ + read Q15 s = k05 /\ + read Q4 s = k06 /\ + read Q5 s = k07 /\ + read Q18 s = k08 /\ + read Q19 s = k09 /\ + read Q20 s = k0a /\ + read Q21 s = k0b /\ + read Q22 s = k0c /\ + read Q23 s = k0d /\ + read Q7 s = k0e /\ + byte_list_at ct ct_ptr s /\ + byte_list_at + (aes256_xts_decrypt ct (0x0 * 0x5 * 0x10) iv key1 key2 pt_init) + pt_ptr + s) + (MAYCHANGE [PC] ,, + MAYCHANGE [events] ,, + MAYCHANGE [X21; X2; X6; X4; X9; X10; X19; X22; X11; X7; X0; X1; X8] ,, + MAYCHANGE + [Q6; Q1; Q0; Q8; Q9; Q10; Q11; Q16; Q17; Q12; Q13; Q14; Q15; Q4; Q5; Q18; + Q19; Q20; Q21; Q22; Q23; Q7; Q29; Q24; Q25; Q26] ,, + MAYCHANGE [NF; ZF; CF; VF] ,, + MAYCHANGE [memory :> bytes (pt_ptr,val len)])` +*) +(* loop.ml subgoal 2 *) +`ensures arm + (\s. + aligned_bytes_loaded s (word pc) loop_mc /\ + read PC s = word pc /\ + read X30 s = word retpc) + (\s. + aligned_bytes_loaded s (word pc) loop_mc /\ + read PC s = word (pc + 0x8) /\ + read X1 s = word 0x0 /\ + read X0 s = word (0x0 * 0x2) /\ + read X30 s = word retpc) + (MAYCHANGE [PC; X0; X1] ,, MAYCHANGE [NF; ZF; CF; VF] ,, MAYCHANGE [events])` + *) (* `word_xor (aes256_encrypt (word_xor - (aes256_encrypt tweak + (aes256_encrypt iv [k2_0; k2_1; k2_2; k2_3; k2_4; k2_5; k2_6; k2_7; k2_8; k2_9; k2_10; k2_11; k2_12; k2_13; k2_14]) - in_pt) + pt_in) [k1_0; k1_1; k1_2; k1_3; k1_4; k1_5; k1_6; k1_7; k1_8; k1_9; k1_10; k1_11; k1_12; k1_13; k1_14]) - (aes256_encrypt tweak + (aes256_encrypt iv [k2_0; k2_1; k2_2; k2_3; k2_4; k2_5; k2_6; k2_7; k2_8; k2_9; k2_10; k2_11; k2_12; k2_13; k2_14]) = word_xor (aes256_encrypt - (word_xor in_pt - (aes256_encrypt tweak + (word_xor pt_in + (aes256_encrypt iv [k2_0; k2_1; k2_2; k2_3; k2_4; k2_5; k2_6; k2_7; k2_8; k2_9; k2_10; k2_11; k2_12; k2_13; k2_14])) [k1_0; k1_1; k1_2; k1_3; k1_4; k1_5; k1_6; k1_7; k1_8; k1_9; k1_10; k1_11; k1_12; k1_13; k1_14]) - (aes256_encrypt tweak + (aes256_encrypt iv [k2_0; k2_1; k2_2; k2_3; k2_4; k2_5; k2_6; k2_7; k2_8; k2_9; k2_10; k2_11; k2_12; k2_13; k2_14])` @@ -908,16 +1380,16 @@ let AES256_ENCRYPT_ONE_BLOCK_CORRECT = prove( `word_xor (aes256_encrypt (word_xor - (aes256_encrypt tweak + (aes256_encrypt iv [k2_0; k2_1; k2_2; k2_3; k2_4; k2_5; k2_6; k2_7; k2_8; k2_9; k2_10; k2_11; k2_12; k2_13; k2_14]) - in_pt) + pt_in) [k1_0; k1_1; k1_2; k1_3; k1_4; k1_5; k1_6; k1_7; k1_8; k1_9; k1_10; k1_11; k1_12; k1_13; k1_14]) = word_xor (aes256_encrypt - (word_xor in_pt - (aes256_encrypt tweak + (word_xor pt_in + (aes256_encrypt iv [k2_0; k2_1; k2_2; k2_3; k2_4; k2_5; k2_6; k2_7; k2_8; k2_9; k2_10; k2_11; k2_12; k2_13; k2_14])) [k1_0; k1_1; k1_2; k1_3; k1_4; k1_5; k1_6; k1_7; k1_8; k1_9; k1_10; k1_11; @@ -927,15 +1399,15 @@ let AES256_ENCRYPT_ONE_BLOCK_CORRECT = prove( `aes256_encrypt (word_xor - (aes256_encrypt tweak + (aes256_encrypt iv [k2_0; k2_1; k2_2; k2_3; k2_4; k2_5; k2_6; k2_7; k2_8; k2_9; k2_10; k2_11; k2_12; k2_13; k2_14]) - in_pt) + pt_in) [k1_0; k1_1; k1_2; k1_3; k1_4; k1_5; k1_6; k1_7; k1_8; k1_9; k1_10; k1_11; k1_12; k1_13; k1_14] = aes256_encrypt - (word_xor in_pt - (aes256_encrypt tweak + (word_xor pt_in + (aes256_encrypt iv [k2_0; k2_1; k2_2; k2_3; k2_4; k2_5; k2_6; k2_7; k2_8; k2_9; k2_10; k2_11; k2_12; k2_13; k2_14])) [k1_0; k1_1; k1_2; k1_3; k1_4; k1_5; k1_6; k1_7; k1_8; k1_9; k1_10; k1_11; @@ -944,24 +1416,24 @@ let AES256_ENCRYPT_ONE_BLOCK_CORRECT = prove( # e(AP_THM_TAC);; `aes256_encrypt (word_xor - (aes256_encrypt tweak + (aes256_encrypt iv [k2_0; k2_1; k2_2; k2_3; k2_4; k2_5; k2_6; k2_7; k2_8; k2_9; k2_10; k2_11; k2_12; k2_13; k2_14]) - in_pt) = + pt_in) = aes256_encrypt - (word_xor in_pt - (aes256_encrypt tweak + (word_xor pt_in + (aes256_encrypt iv [k2_0; k2_1; k2_2; k2_3; k2_4; k2_5; k2_6; k2_7; k2_8; k2_9; k2_10; k2_11; k2_12; k2_13; k2_14]))` # e(AP_TERM_TAC);; `word_xor - (aes256_encrypt tweak + (aes256_encrypt iv [k2_0; k2_1; k2_2; k2_3; k2_4; k2_5; k2_6; k2_7; k2_8; k2_9; k2_10; k2_11; k2_12; k2_13; k2_14]) - in_pt = - word_xor in_pt - (aes256_encrypt tweak + pt_in = + word_xor pt_in + (aes256_encrypt iv [k2_0; k2_1; k2_2; k2_3; k2_4; k2_5; k2_6; k2_7; k2_8; k2_9; k2_10; k2_11; k2_12; k2_13; k2_14])` *) @@ -974,7 +1446,7 @@ first xor to make it aes256_encrypt? 83 [`read (memory :> bytes128 ctxt) s117 = word_xor - (aes256_encrypt tweak + (aes256_encrypt iv [k2_0; k2_1; k2_2; k2_3; k2_4; k2_5; k2_6; k2_7; k2_8; k2_9; k2_10; k2_11; k2_12; k2_13; k2_14]) (word_xor k1_14 @@ -1006,10 +1478,10 @@ first xor to make it aes256_encrypt? (aesmc (aese (word_xor - (aes256_encrypt tweak + (aes256_encrypt iv [k2_0; k2_1; k2_2; k2_3; k2_4; k2_5; k2_6; k2_7; k2_8; k2_9; k2_10; k2_11; k2_12; k2_13; k2_14]) - in_pt) + pt_in) k1_0)) k1_1)) k1_2)) From 8b644e9ad19c29968e96bde3fb48039aad4fef58 Mon Sep 17 00:00:00 2001 From: Nevine Ebeid Date: Fri, 3 Oct 2025 09:24:53 -0400 Subject: [PATCH 065/132] Moved udiv and second tweak operations to later, WIP: full proof; code before the loop proven See corresponding https://github.com/aws/aws-lc/pull/2726 Diff of assembly files in both repos: diff third_party/s2n-bignum/s2n-bignum-to-be-imported/arm/aes/aes-xts-enc.S ../s2n-bignum/arm/aes-xts/aes-xts-armv8.S [25/10/2 | 5:02PM] 4d3 < #include 62c61 < AARCH64_VALID_CALL_TARGET --- > # AARCH64_VALID_CALL_TARGET 67a67 > 136a137 --- arm/aes-xts/aes-xts-armv8.S | 19 +-- arm/aes-xts/aes-xts-armv8.txt | 36 ++--- arm/proofs/aes-xts-armv8.ml | 255 ++++++++++++++++++++++++++-------- 3 files changed, 226 insertions(+), 84 deletions(-) diff --git a/arm/aes-xts/aes-xts-armv8.S b/arm/aes-xts/aes-xts-armv8.S index 69159a790..7d7d2d394 100644 --- a/arm/aes-xts/aes-xts-armv8.S +++ b/arm/aes-xts/aes-xts-armv8.S @@ -64,7 +64,6 @@ S2N_BN_SYMBOL(aes_hw_xts_encrypt): save_vregs save_regs - udiv_by_80(x2, x8) // Number of 5x-unrolled iterations cmp x2, #16 // AES-XTS needs at least one block b.lt .Lxts_enc_abort @@ -93,14 +92,6 @@ S2N_BN_SYMBOL(aes_hw_xts_encrypt): aese v6.16b, v1.16b eor v6.16b, v6.16b, v0.16b - // The iv for second block - // x9- iv(low), x10 - iv(high) - // the five ivs stored into, v6.16b,v8.16b,v9.16b,v10.16b,v11.16b - fmov x9, d6 - fmov x10, v6.d[1] - mov w19, #0x87 - tweak(d8, v8.d[1]) - mov x7, x3 ld1 {v16.4s,v17.4s},[x7], #32 // load key schedule ld1 {v12.4s,v13.4s},[x7], #32 @@ -116,6 +107,14 @@ S2N_BN_SYMBOL(aes_hw_xts_encrypt): cmp x2, #0x20 b.lo .Lxts_enc_tail1x // when input = 1 with tail + // The iv for second block + // x9- iv(low), x10 - iv(high) + // the five ivs stored into, v6.16b,v8.16b,v9.16b,v10.16b,v11.16b + fmov x9, d6 + fmov x10, v6.d[1] + mov w19, #0x87 + tweak(d8, v8.d[1]) + cmp x2, #0x30 b.lo .Lxts_enc_tail2x // when input size = 2 @@ -134,6 +133,8 @@ S2N_BN_SYMBOL(aes_hw_xts_encrypt): // The iv for fifth block tweak(d11,v11.d[1]) + udiv_by_80(x2, x8) // Number of 5x-unrolled iterations + .align 4 .Loop5x_xts_enc: ldp q0, q1, [x0], #0x50 diff --git a/arm/aes-xts/aes-xts-armv8.txt b/arm/aes-xts/aes-xts-armv8.txt index 3567ee4fa..ad2f00663 100644 --- a/arm/aes-xts/aes-xts-armv8.txt +++ b/arm/aes-xts/aes-xts-armv8.txt @@ -6,12 +6,8 @@ 0x6d053fee; (* arm_STP D14 D15 SP (Immediate_Offset (iword (&0x50))) *) 0xa90053f3; (* arm_STP X19 X20 SP (Immediate_Offset (iword (&0x0))) *) 0xa9015bf5; (* arm_STP X21 X22 SP (Immediate_Offset (iword (&0x10))) *) - 0xb202e7e8; (* arm_MOV X8 (rvalue (word 0xcccccccccccccccc)) *) - 0xf29999a8; (* arm_MOVK X8 (word 0xcccd) 0x0 *) - 0x9bc87c48; (* arm_UMULH X8 X2 X8 *) - 0xd346fd08; (* arm_LSR X8 X8 0x6 *) 0xf100405f; (* arm_CMP X2 (rvalue (word 0x10)) *) - 0x5400518b; (* arm_BLT (word 0xa30) *) + 0x5400520b; (* arm_BLT (word 0xa40) *) 0xd503201f; (* arm_NOP *) 0xd503201f; (* arm_NOP *) 0xd503201f; (* arm_NOP *) @@ -35,15 +31,6 @@ 0x4c407880; (* arm_LDR Q0 X4 No_Offset *) 0x4e284826; (* arm_AESE Q6 Q1 *) 0x6e201cc6; (* arm_EOR_VEC Q6 Q6 Q0 0x80 *) - 0x9e6600c9; (* arm_FMOV_FtoI X9 Q6 0x0 0x40 *) - 0x9eae00ca; (* arm_FMOV_FtoI X10 Q6 0x1 0x40 *) - 0x528010f3; (* arm_MOV W19 (rvalue (word 0x87)) *) - 0x93ca8156; (* arm_ROR X22 X10 0x20 *) - 0x93c9fd4a; (* arm_EXTR X10 X10 X9 0x3f *) - 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 0x1f) *) - 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 0x1) *) - 0x9e670128; (* arm_FMOV_ItoF Q8 X9 0x0 *) - 0x9eaf0148; (* arm_FMOV_ItoF Q8 X10 0x1 *) 0xaa0303e7; (* arm_MOV X7 X3 *) 0x4cdfa8f0; (* arm_LDP Q16 Q17 X7 (Postimmediate_Offset (word 0x20)) *) 0x4cdfa8ec; (* arm_LDP Q12 Q13 X7 (Postimmediate_Offset (word 0x20)) *) @@ -54,9 +41,18 @@ 0x4cdfa8f6; (* arm_LDP Q22 Q23 X7 (Postimmediate_Offset (word 0x20)) *) 0x4c4078e7; (* arm_LDR Q7 X7 No_Offset *) 0xf100805f; (* arm_CMP X2 (rvalue (word 0x20)) *) - 0x540042e3; (* arm_BCC (word 0x85c) *) + 0x54004483; (* arm_BCC (word 0x890) *) + 0x9e6600c9; (* arm_FMOV_FtoI X9 Q6 0x0 0x40 *) + 0x9eae00ca; (* arm_FMOV_FtoI X10 Q6 0x1 0x40 *) + 0x528010f3; (* arm_MOV W19 (rvalue (word 0x87)) *) + 0x93ca8156; (* arm_ROR X22 X10 0x20 *) + 0x93c9fd4a; (* arm_EXTR X10 X10 X9 0x3f *) + 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 0x1f) *) + 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 0x1) *) + 0x9e670128; (* arm_FMOV_ItoF Q8 X9 0x0 *) + 0x9eaf0148; (* arm_FMOV_ItoF Q8 X10 0x1 *) 0xf100c05f; (* arm_CMP X2 (rvalue (word 0x30)) *) - 0x540039c3; (* arm_BCC (word 0x738) *) + 0x54003a43; (* arm_BCC (word 0x748) *) 0x93ca8156; (* arm_ROR X22 X10 0x20 *) 0x93c9fd4a; (* arm_EXTR X10 X10 X9 0x3f *) 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 0x1f) *) @@ -64,7 +60,7 @@ 0x9e670129; (* arm_FMOV_ItoF Q9 X9 0x0 *) 0x9eaf0149; (* arm_FMOV_ItoF Q9 X10 0x1 *) 0xf101005f; (* arm_CMP X2 (rvalue (word 0x40)) *) - 0x54002be3; (* arm_BCC (word 0x57c) *) + 0x54002c63; (* arm_BCC (word 0x58c) *) 0x93ca8156; (* arm_ROR X22 X10 0x20 *) 0x93c9fd4a; (* arm_EXTR X10 X10 X9 0x3f *) 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 0x1f) *) @@ -72,13 +68,17 @@ 0x9e67012a; (* arm_FMOV_ItoF Q10 X9 0x0 *) 0x9eaf014a; (* arm_FMOV_ItoF Q10 X10 0x1 *) 0xf101405f; (* arm_CMP X2 (rvalue (word 0x50)) *) - 0x540019e3; (* arm_BCC (word 0x33c) *) + 0x54001a63; (* arm_BCC (word 0x34c) *) 0x93ca8156; (* arm_ROR X22 X10 0x20 *) 0x93c9fd4a; (* arm_EXTR X10 X10 X9 0x3f *) 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 0x1f) *) 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 0x1) *) 0x9e67012b; (* arm_FMOV_ItoF Q11 X9 0x0 *) 0x9eaf014b; (* arm_FMOV_ItoF Q11 X10 0x1 *) + 0xb202e7e8; (* arm_MOV X8 (rvalue (word 0xcccccccccccccccc)) *) + 0xf29999a8; (* arm_MOVK X8 (word 0xcccd) 0x0 *) + 0x9bc87c48; (* arm_UMULH X8 X2 X8 *) + 0xd346fd08; (* arm_LSR X8 X8 0x6 *) 0xacc28400; (* arm_LDP Q0 Q1 X0 (Postimmediate_Offset (iword (&0x50))) *) 0xad7ee418; (* arm_LDP Q24 Q25 X0 (Immediate_Offset (iword (-- &0x30))) *) 0x3cdf001a; (* arm_LDR Q26 X0 (Immediate_Offset (word 0xfffffffffffffff0)) *) diff --git a/arm/proofs/aes-xts-armv8.ml b/arm/proofs/aes-xts-armv8.ml index ad1dc79a1..914d77eeb 100644 --- a/arm/proofs/aes-xts-armv8.ml +++ b/arm/proofs/aes-xts-armv8.ml @@ -33,17 +33,13 @@ let aes256_xts_encrypt_mc = define_assert_from_elf "aes256_xts_encrypt_mc" "arm/ 0x6d053fee; (* arm_STP D14 D15 SP (Immediate_Offset (iword (&0x50))) *) 0xa90053f3; (* arm_STP X19 X20 SP (Immediate_Offset (iword (&0x0))) *) 0xa9015bf5; (* arm_STP X21 X22 SP (Immediate_Offset (iword (&0x10))) *) - 0xb202e7e8; (* arm_MOV X8 (rvalue (word 0xcccccccccccccccc)) *) - 0xf29999a8; (* arm_MOVK X8 (word 0xcccd) 0x0 *) - 0x9bc87c48; (* arm_UMULH X8 X2 X8 *) - 0xd346fd08; (* arm_LSR X8 X8 0x6 *) 0xf100405f; (* arm_CMP X2 (rvalue (word 0x10)) *) - 0x5400518b; (* arm_BLT (word 0xa30) *) + 0x5400520b; (* arm_BLT (word 0xa40) *) 0xd503201f; (* arm_NOP *) 0xd503201f; (* arm_NOP *) 0xd503201f; (* arm_NOP *) -(* // Lxts_enc_big_size: *) + (* // Lxts_enc_big_size: *) 0x92400c55; (* arm_AND X21 X2 (rvalue (word 0xf)) *) 0x927cec42; (* arm_AND X2 X2 (rvalue (word 0xfffffffffffffff0)) *) @@ -67,20 +63,8 @@ let aes256_xts_encrypt_mc = define_assert_from_elf "aes256_xts_encrypt_mc" "arm/ 0x4e284826; (* arm_AESE Q6 Q1 *) 0x6e201cc6; (* arm_EOR_VEC Q6 Q6 Q0 0x80 *) - (* iv for second block *) - (* pc + 0x90 *) - 0x9e6600c9; (* arm_FMOV_FtoI X9 Q6 0x0 0x40 *) - 0x9eae00ca; (* arm_FMOV_FtoI X10 Q6 0x1 0x40 *) - 0x528010f3; (* arm_MOV W19 (rvalue (word 0x87)) *) - 0x93ca8156; (* arm_ROR X22 X10 0x20 *) - 0x93c9fd4a; (* arm_EXTR X10 X10 X9 0x3f *) - 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 0x1f) *) - 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 0x1) *) - 0x9e670128; (* arm_FMOV_ItoF Q8 X9 0x0 *) - 0x9eaf0148; (* arm_FMOV_ItoF Q8 X10 0x1 *) - (* Load key schedule *) - (* pc + 0xb4 *) + (* pc + 0x80 *) 0xaa0303e7; (* arm_MOV X7 X3 *) 0x4cdfa8f0; (* arm_LDP Q16 Q17 X7 (Postimmediate_Offset (word 0x20)) *) 0x4cdfa8ec; (* arm_LDP Q12 Q13 X7 (Postimmediate_Offset (word 0x20)) *) @@ -92,12 +76,20 @@ let aes256_xts_encrypt_mc = define_assert_from_elf "aes256_xts_encrypt_mc" "arm/ 0x4c4078e7; (* arm_LDR Q7 X7 No_Offset *) (* Lxts_enc: *) - (* pc + 0xd8 *) + (* pc + 0xa4 *) 0xf100805f; (* arm_CMP X2 (rvalue (word 0x20)) *) - 0x540042e3; (* arm_BCC (word 0x85c) *) (* b.lo Lxts_enc_tail1x // when input = 1 with tail *) - + 0x54004483; (* arm_BCC (word 0x890) *) + 0x9e6600c9; (* arm_FMOV_FtoI X9 Q6 0x0 0x40 *) + 0x9eae00ca; (* arm_FMOV_FtoI X10 Q6 0x1 0x40 *) + 0x528010f3; (* arm_MOV W19 (rvalue (word 0x87)) *) + 0x93ca8156; (* arm_ROR X22 X10 0x20 *) + 0x93c9fd4a; (* arm_EXTR X10 X10 X9 0x3f *) + 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 0x1f) *) + 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 0x1) *) + 0x9e670128; (* arm_FMOV_ItoF Q8 X9 0x0 *) + 0x9eaf0148; (* arm_FMOV_ItoF Q8 X10 0x1 *) 0xf100c05f; (* arm_CMP X2 (rvalue (word 0x30)) *) - 0x540039c3; (* arm_BCC (word 0x738) *) + 0x54003a43; (* arm_BCC (word 0x748) *) 0x93ca8156; (* arm_ROR X22 X10 0x20 *) 0x93c9fd4a; (* arm_EXTR X10 X10 X9 0x3f *) 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 0x1f) *) @@ -105,7 +97,7 @@ let aes256_xts_encrypt_mc = define_assert_from_elf "aes256_xts_encrypt_mc" "arm/ 0x9e670129; (* arm_FMOV_ItoF Q9 X9 0x0 *) 0x9eaf0149; (* arm_FMOV_ItoF Q9 X10 0x1 *) 0xf101005f; (* arm_CMP X2 (rvalue (word 0x40)) *) - 0x54002be3; (* arm_BCC (word 0x57c) *) + 0x54002c63; (* arm_BCC (word 0x58c) *) 0x93ca8156; (* arm_ROR X22 X10 0x20 *) 0x93c9fd4a; (* arm_EXTR X10 X10 X9 0x3f *) 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 0x1f) *) @@ -113,16 +105,17 @@ let aes256_xts_encrypt_mc = define_assert_from_elf "aes256_xts_encrypt_mc" "arm/ 0x9e67012a; (* arm_FMOV_ItoF Q10 X9 0x0 *) 0x9eaf014a; (* arm_FMOV_ItoF Q10 X10 0x1 *) 0xf101405f; (* arm_CMP X2 (rvalue (word 0x50)) *) - 0x540019e3; (* arm_BCC (word 0x33c) *) + 0x54001a63; (* arm_BCC (word 0x34c) *) 0x93ca8156; (* arm_ROR X22 X10 0x20 *) 0x93c9fd4a; (* arm_EXTR X10 X10 X9 0x3f *) 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 0x1f) *) 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 0x1) *) 0x9e67012b; (* arm_FMOV_ItoF Q11 X9 0x0 *) 0x9eaf014b; (* arm_FMOV_ItoF Q11 X10 0x1 *) - - (* .Loop5x_xts_enc *) - (* pc + 0x140 *) + 0xb202e7e8; (* arm_MOV X8 (rvalue (word 0xcccccccccccccccc)) *) + 0xf29999a8; (* arm_MOVK X8 (word 0xcccd) 0x0 *) + 0x9bc87c48; (* arm_UMULH X8 X2 X8 *) + 0xd346fd08; (* arm_LSR X8 X8 0x6 *) 0xacc28400; (* arm_LDP Q0 Q1 X0 (Postimmediate_Offset (iword (&0x50))) *) 0xad7ee418; (* arm_LDP Q24 Q25 X0 (Immediate_Offset (iword (-- &0x30))) *) 0x3cdf001a; (* arm_LDR Q26 X0 (Immediate_Offset (word 0xfffffffffffffff0)) *) @@ -312,9 +305,6 @@ let aes256_xts_encrypt_mc = define_assert_from_elf "aes256_xts_encrypt_mc" "arm/ 0xd1014042; (* arm_SUB X2 X2 (rvalue (word 0x50)) *) 0xf1000508; (* arm_SUBS X8 X8 (rvalue (word 0x1)) *) 0xb5ffe888; (* arm_CBNZ X8 (word 0x1ffd10) *) - - (* .Loop5x_enc_after: *) - (* pc + 0x434 *) 0xf101005f; (* arm_CMP X2 (rvalue (word 0x40)) *) 0x54000140; (* arm_BEQ (word 0x28) *) 0xf100c05f; (* arm_CMP X2 (rvalue (word 0x30)) *) @@ -638,7 +628,6 @@ let aes256_xts_encrypt_mc = define_assert_from_elf "aes256_xts_encrypt_mc" "arm/ 0x1400002b; (* arm_B (word 0xac) *) (* Lxts_enc_tail1x: *) - (* pc + 0x938 *) 0x4cdf7000; (* arm_LDR Q0 X0 (Postimmediate_Offset (word 0x10)) *) 0x6e261c00; (* arm_EOR_VEC Q0 Q0 Q6 0x80 *) 0x4e284a00; (* arm_AESE Q0 Q16 *) @@ -725,6 +714,8 @@ let aes256_xts_encrypt_mc = define_assert_from_elf "aes256_xts_encrypt_mc" "arm/ 0xd65f03c0 (* arm_RET X30 *) ];; +let AES256_XTS_ENCRYPT_EXEC = ARM_MK_EXEC_RULE aes256_xts_encrypt_mc;; + (** Definitions **) (* same as in aes_xts_decrypt.ml *) @@ -750,9 +741,6 @@ let set_key_schedule = new_definition read(memory :> bytes128 (word_add key_ptr (word 224))) s = ke /\ read(memory :> bytes32 (word_add key_ptr (word 240))) s = word 14)`;; - -let AES256_XTS_ENCRYPT_EXEC = ARM_MK_EXEC_RULE aes256_xts_encrypt_mc;; - let AESENC_TAC = REWRITE_TAC [aes256_encrypt] THEN REWRITE_TAC EL_15_128_CLAUSES THEN @@ -817,10 +805,7 @@ let AES256_ENCRYPT_ONE_BLOCK_CORRECT = prove( ENSURES_INIT_TAC "s0" THEN (* Simulate until the iv encryption and verify it against AES encryption spec *) - ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (1--6) THEN - ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (7--25) THEN - ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (26--56) THEN - ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (57--69) THEN + ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (1--65) THEN (* FIRST_X_ASSUM(MP_TAC o MATCH_MP (MESON[] `read Q6 s = a ==> !a'. a = a' ==> read Q6 s = a'`)) THEN *) FIRST_X_ASSUM(MP_TAC o SPEC @@ -829,10 +814,7 @@ let AES256_ENCRYPT_ONE_BLOCK_CORRECT = prove( ANTS_TAC THENL [ASM_REWRITE_TAC[] THEN AESENC_TAC; DISCH_TAC] THEN (* Simulate until the one-block input encryption until before XORing the iv with the output. *) - ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (70--78) THEN - ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (79--89) THEN - ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (90--90) THEN - ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (91--119) THEN + ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (66--106) THEN (* FIRST_X_ASSUM(MP_TAC o MATCH_MP (MESON[] `read Q0 s = a ==> !a'. a = a' ==> read Q0 s = a'`)) THEN *) FIRST_X_ASSUM(MP_TAC o SPEC @@ -848,10 +830,10 @@ let AES256_ENCRYPT_ONE_BLOCK_CORRECT = prove( ANTS_TAC THENL [ASM_REWRITE_TAC[] THEN AESENC_TAC; DISCH_TAC] THEN (* XOR the tweak with the output in Q0 *) - ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (120--120) THEN + ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (107--107) THEN (* Write it to the ciphertext output *) - ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (121--121) THEN + ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (108--108) THEN FIRST_X_ASSUM(MP_TAC o SPEC `(aes256_xts_encrypt_1block (pt_in:int128) @@ -864,8 +846,7 @@ let AES256_ENCRYPT_ONE_BLOCK_CORRECT = prove( ==> read (memory :> bytes128 ctxt_p) s = a'`)) THEN ANTS_TAC THENL [ASM_REWRITE_TAC[] THEN AESXTS_ENC_ONE_BLOCK_TAC; DISCH_TAC] THEN - ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (122--126) THEN - ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (127--132) THEN + ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (109--119) THEN ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN @@ -875,6 +856,8 @@ let AES256_ENCRYPT_ONE_BLOCK_CORRECT = prove( (*******************************************) (* Full proof *) +(* The following definitions that precede the proof are the same as + the decrypt proof except where stated *) let byte_list_l_at = define `byte_list_l_at (m : byte list) (l:num) (m_p : int64) s = ! i. i < l ==> read (memory :> bytes8(word_add m_p (word i))) s = EL i m`;; @@ -896,7 +879,7 @@ let LEN_FULL_BLOCKS_HI_BOUND_THM = prove( ==> val len_full_blocks <= 2 EXP 24`, BITBLAST_TAC);; - let TAIL_LEN_BOUND_THM = prove( +let TAIL_LEN_BOUND_THM = prove( `!(len:int64) tail_len. word_and len (word 0xf) = tail_len ==> val tail_len < 0x10`, BITBLAST_TAC);; @@ -917,6 +900,70 @@ let NUM_5BLOCKS_LO_BOUND_THM = prove( ASM_SIMP_TAC[MOD_LT] THEN ARITH_TAC );; + +let TWEAK_UPDATE_CONV = + let ADD_SUC_1 = ARITH_RULE `!n. n + 1 = SUC(n)` in + let ADD_SUC_2 = ARITH_RULE `!n. n + 2 = SUC(n + 1)` in + let ADD_SUC_3 = ARITH_RULE `!n. n + 3 = SUC(n + 2)` in + let ADD_SUC_4 = ARITH_RULE `!n. n + 4 = SUC(n + 3)` in + let ADD_SUC_5 = ARITH_RULE `!n. n + 5 = SUC(n + 4)` in + let ADD_SUC_6 = ARITH_RULE `!n. n + 6 = SUC(n + 5)` in + let ADD_SUC_7 = ARITH_RULE `!n. n + 7 = SUC(n + 6)` in + let ADD_SUC_8 = ARITH_RULE `!n. n + 8 = SUC(n + 7)` in + let ADD_SUC_9 = ARITH_RULE `!n. n + 9 = SUC(n + 8)` in + NUM_REDUCE_CONV THENC + RATOR_CONV (LAND_CONV (num_CONV ORELSEC + FIRST_CONV + [ CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_1]); + CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_2]); + CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_3]); + CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_4]); + CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_5]); + CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_6]); + CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_7]); + CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_8]); + CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_9]);])) THENC + REWRITE_CONV [CONJUNCT2 calculate_tweak] THENC + GF_128_MULT_BY_PRIMITIVE_CONV;; + +(* differs from the Decrypt definition in using key2_lst instead of key2 *) +let TWEAK_TAC reg ind indm1 = + let lower_term = subst [ind,`ind:num`] `(word_zx:int128->int64) (calculate_tweak ind iv key2_lst)` in + let upper_term = subst [ind,`ind:num`] `(word_subword:int128->num#num->int64) (calculate_tweak ind iv key2_lst) (64,64)` in + let full_term = subst [ind,`ind:num`] `calculate_tweak ind iv key2_lst` in + let full_lemma = subst [reg,`reg:(armstate,int128)component`] `read (reg:(armstate,int128)component) (s:armstate) = a ==> !a'. a = a' ==> read reg s = a'` in + let abbrev_term = subst [indm1,`indm1:num`] `tweak_pre:int128 = (calculate_tweak indm1 iv key2_lst)` in + FIRST_X_ASSUM(MP_TAC o SPEC lower_term + o MATCH_MP (MESON[] `read X9 s = a ==> !a'. a = a' ==> read X9 s = a'`)) THEN + ANTS_TAC THENL [CONV_TAC (RAND_CONV (RAND_CONV TWEAK_UPDATE_CONV)) THEN + ABBREV_TAC abbrev_term THEN + BITBLAST_TAC; DISCH_TAC] THEN + FIRST_X_ASSUM(MP_TAC o SPEC upper_term + o MATCH_MP (MESON[] `read X10 s = a ==> !a'. a = a' ==> read X10 s = a'`)) THEN + ANTS_TAC THENL [CONV_TAC (RAND_CONV (RATOR_CONV (RAND_CONV TWEAK_UPDATE_CONV))) THEN + ABBREV_TAC abbrev_term THEN + BITBLAST_TAC; DISCH_TAC] THEN + FIRST_X_ASSUM(MP_TAC o SPEC full_term + o MATCH_MP (MESON[] full_lemma)) THEN + ANTS_TAC THENL [CONV_TAC (RAND_CONV TWEAK_UPDATE_CONV) THEN + ABBREV_TAC abbrev_term THEN + BITBLAST_TAC; DISCH_TAC];; + + let UDIV_OPT_THM = prove(`!n:num. n < 0x2 EXP 0x40 + ==> (word (val ((word ((n * 0xcccccccccccccccd) DIV 0x2 EXP 0x40)):int64) DIV 0x2 EXP 0x6)):int64 = word (n DIV 0x50)`, + REPEAT STRIP_TAC THEN + REWRITE_TAC[VAL_WORD; DIMINDEX_64] THEN + SUBGOAL_THEN `!p n:num. ~(p = 0) /\ n < p * p ==> n DIV p MOD p = n DIV p` + (MP_TAC o SPECL [`0x2 EXP 0x40`; `n * 0xcccccccccccccccd`]) THENL + [ REPEAT STRIP_TAC THEN + REWRITE_TAC[DIV_MOD] THEN + AP_THM_TAC THEN AP_TERM_TAC THEN + MATCH_MP_TAC MOD_LT THEN + ASM_ARITH_TAC; ALL_TAC] THEN + ANTS_TAC THENL [ASM_ARITH_TAC;ALL_TAC] THEN + DISCH_TAC THEN ASM_REWRITE_TAC[] THEN + AP_TERM_TAC THEN ASM_ARITH_TAC);; + (* void aes_hw_xts_encrypt(const uint8_t *in, uint8_t *out, size_t length, const AES_KEY *key1, const AES_KEY *key2, @@ -971,6 +1018,7 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( (word_and len (word 0xfffffffffffffff0)) = len:int64` ASSUME_TAC THENL [REWRITE_TAC[word_split_lemma]; ALL_TAC] THEN ABBREV_TAC `len_full_blocks:int64 = word_and len (word 0xfffffffffffffff0)` THEN + ABBREV_TAC `num_5blocks = (word (val (len_full_blocks:int64) DIV 0x50)):int64` THEN ABBREV_TAC `tail_len:int64 = word_and len (word 0xf)` THEN ABBREV_TAC `key1_lst:int128 list = [k1_0; k1_1; k1_2; k1_3; k1_4; k1_5; k1_6; k1_7; k1_8; k1_9; k1_10; k1_11; k1_12; k1_13; k1_14]` THEN @@ -990,8 +1038,6 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( *) ASM_CASES_TAC `val (len:int64) < 0x50` THENL [CHEAT_TAC; ALL_TAC] THEN - ABBREV_TAC `num_5blocks = (word (val (len_full_blocks:int64) DIV 0x50)):int64` THEN - SUBGOAL_THEN `~(val (len_full_blocks:int64) < 0x50)` ASSUME_TAC THENL [ UNDISCH_TAC `~(val (len:int64) < 0x50)` THEN UNDISCH_TAC `word_and len (word 0xfffffffffffffff0) = (len_full_blocks:int64)` THEN @@ -1023,15 +1069,110 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( read X0 s = ptxt_p /\ read X1 s = ctxt_p /\ read X2 s = len_full_blocks /\ - read X8 s = num_5blocks /\ read X21 s = tail_len /\ - read Q6 s = calculate_tweak 0 iv key2 /\ - read Q8 s = calculate_tweak 1 iv key2 /\ - read Q9 s = calculate_tweak 2 iv key2 /\ - read Q10 s = calculate_tweak 3 iv key2 /\ - read Q11 s = calculate_tweak 4 iv key2 /\ + read X8 s = num_5blocks /\ + read Q6 s = calculate_tweak 0 iv key2_lst /\ + read Q8 s = calculate_tweak 1 iv key2_lst /\ + read Q9 s = calculate_tweak 2 iv key2_lst /\ + read Q10 s = calculate_tweak 3 iv key2_lst /\ + read Q11 s = calculate_tweak 4 iv key2_lst /\ read X19 s = word 0x87 /\ - ` THEN + read Q16 s = k1_0 /\ read Q17 s = k1_1 /\ read Q12 s = k1_2 /\ read Q13 s = k1_3 /\ + read Q14 s = k1_4 /\ read Q15 s = k1_5 /\ read Q4 s = k1_6 /\ read Q5 s = k1_7 /\ + read Q18 s = k1_8 /\ read Q19 s = k1_9 /\ read Q20 s = k1_10 /\ read Q21 s = k1_11 /\ + read Q22 s = k1_12 /\ read Q23 s = k1_13 /\ read Q7 s = k1_14 + ` THEN + CONJ_TAC THENL + [ + (* ===> Symbolic Simulation: Start symbolic simulation*) + ENSURES_INIT_TAC "s0" THEN + ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (1--2) THEN + + (* Discharge if condition *) + SUBGOAL_THEN + `ival (word_sub (len:int64) (word 0x10)) < &0x0 + <=> ~(ival (len:int64) - &0x10 = ival (word_sub (len:int64) (word 0x10)))` MP_TAC THENL + [ MP_TAC (BITBLAST_RULE + `val (len:int64) >= 0x10 ==> val len <= 2 EXP 0x18 ==> + ival (word_sub len (word 0x10)) >= &0x0`) THEN + ASM_REWRITE_TAC[] THEN + MP_TAC (BITBLAST_RULE + `val (len:int64) >= 0x10 ==> val len <= 2 EXP 0x18 ==> + ival (len:int64) - &0x10 = ival (word_sub len (word 0x10))`) THEN + ASM_REWRITE_TAC[] THEN + ARITH_TAC;(* works on the goal; that's why we bring the assumptions we want as antecedants of the goal *) + ALL_TAC + ] THEN + ASM_REWRITE_TAC[] THEN + DISCH_TAC THEN POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th])) THEN + (* Try DISCH_THEN(RULE_ASSUM_TAC o REWRITE_RULE o CONJUNCTS) *) + + (* ===> Symbolic Simulation: Symbolic execution for initialization of tweak *) + ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (3--65) THEN + (* Prove Q6 stores initial tweak *) + FIRST_X_ASSUM(MP_TAC o SPEC `(calculate_tweak 0 iv key2_lst)` + o MATCH_MP (MESON[] `read Q6 s = a ==> !a'. a = a' ==> read Q6 s = a'`)) THEN + ANTS_TAC THENL + [REWRITE_TAC[CONJUNCT1 calculate_tweak; xts_init_tweak] THEN + EXPAND_TAC "key2_lst" THEN AESENC_TAC; DISCH_TAC] THEN + + (* ===> Symbolic Simulation: Symbolic simulating untill next branch: + - iv for second block + - load key schedule *) + ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (66--76) THEN + (* Branching on x2 *) + (* Eliminate 1 block case *) + SUBGOAL_THEN `~(val (len_full_blocks:int64) < 0x20)` MP_TAC THENL + [ UNDISCH_TAC `~(val (len_full_blocks:int64) < 0x50)` THEN ARITH_TAC; + DISCH_THEN(RULE_ASSUM_TAC o REWRITE_RULE o CONJUNCTS)] THEN + + (* Prove x9, x10 store lower and upper halves of tweak 1 and Q8 stores the full tweak 1 *) + ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (77--85) THEN + TWEAK_TAC `Q8:(armstate,int128)component` `1:num` `0:num` THEN + + (* Eliminate 2 blocks case *) + ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (86--87) THEN + SUBGOAL_THEN `~(val (len_full_blocks:int64) < 0x30)` MP_TAC THENL + [ UNDISCH_TAC `~(val (len_full_blocks:int64) < 0x50)` THEN ARITH_TAC; + DISCH_THEN(RULE_ASSUM_TAC o REWRITE_RULE o CONJUNCTS)] THEN + (* prove Q9 stores tweak of 3rd block (index 2) *) + ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (88--93) THEN + TWEAK_TAC `Q9:(armstate,int128)component` `2:num` `0:num` THEN + (* Eliminate 3 blocks case *) + ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (94--95) THEN + SUBGOAL_THEN `~(val (len_full_blocks:int64) < 0x40)` MP_TAC THENL + [ UNDISCH_TAC `~(val (len_full_blocks:int64) < 0x50)` THEN ARITH_TAC; + DISCH_THEN(RULE_ASSUM_TAC o REWRITE_RULE o CONJUNCTS)] THEN + (* prove Q10 stores tweak of 4th block (index 3) *) + ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (96--101) THEN + TWEAK_TAC `Q10:(armstate,int128)component` `3:num` `0:num` THEN + (* Eliminate 4 blocks case, proven by the assumption ~(len_full_blocks < 0x50)*) + ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (102--103) THEN + (* prove Q11 stores tweak of 5th block (index 4) *) + ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (105--110) THEN + TWEAK_TAC `Q11:(armstate,int128)component` `4:num` `0:num` THEN + + (* Prove the optimized udiv is basically udiv *) + ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (111--114) THEN + SUBGOAL_THEN `word_ushr + ((word ((val (len_full_blocks:int64) * 0xcccccccccccccccd) DIV 0x2 EXP 0x40)):int64) + 0x6 = + word ((val len_full_blocks) DIV 0x50)` ASSUME_TAC THENL + [ MP_TAC (BITBLAST_RULE `val (len_full_blocks:int64) < 2 EXP 64`) THEN + REWRITE_TAC[word_ushr] THEN + MP_TAC (SPECL [`val (len_full_blocks:int64)`] UDIV_OPT_THM) THEN SIMP_TAC[] + ; ALL_TAC] THEN + POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th])) THEN +(* + 43 [`read X8 s113 = + word_ushr (word ((val len * 0xcccccccccccccccd) DIV 0x2 EXP 0x40)) 0x6`] + 20 [`word (val len_full_blocks DIV 0x50) = num_5blocks`] + 105 [`word_ushr + (word ((val len_full_blocks * 0xcccccccccccccccd) DIV 0x2 EXP 0x40)) + 0x6 = + word (val len_full_blocks DIV 0x50)`] *) + ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN + ] (* Loop invariant *) ENSURES_WHILE_PAUP_TAC From e09df03f03e3fd09bbd5c4765759b7109cccc889 Mon Sep 17 00:00:00 2001 From: Nevine Ebeid Date: Fri, 3 Oct 2025 10:41:51 -0400 Subject: [PATCH 066/132] Update byte_list_at. --- arm/proofs/aes-xts-armv8.ml | 44 ++++++++++++++++++------------------- 1 file changed, 21 insertions(+), 23 deletions(-) diff --git a/arm/proofs/aes-xts-armv8.ml b/arm/proofs/aes-xts-armv8.ml index 914d77eeb..6faaa8000 100644 --- a/arm/proofs/aes-xts-armv8.ml +++ b/arm/proofs/aes-xts-armv8.ml @@ -4,6 +4,8 @@ *) use_file_raise_failure := true;; +arm_print_log := true;; +components_print_log := true;; needs "arm/proofs/base.ml";; needs "arm/proofs/aes_encrypt_spec.ml";; @@ -858,9 +860,9 @@ let AES256_ENCRYPT_ONE_BLOCK_CORRECT = prove( (* The following definitions that precede the proof are the same as the decrypt proof except where stated *) -let byte_list_l_at = define - `byte_list_l_at (m : byte list) (l:num) (m_p : int64) s = - ! i. i < l ==> read (memory :> bytes8(word_add m_p (word i))) s = EL i m`;; +let byte_list_at = define + `byte_list_at (m : byte list) (m_p : int64) (len:int64) s = + ! i. i < val len ==> read (memory :> bytes8(word_add m_p (word i))) s = EL i m`;; let word_split_lemma = prove( `!len:int64. word_add (word_and len (word 0xf)) @@ -990,8 +992,8 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( read PC s = word (pc + 28) /\ read SP s = stackpointer /\ C_ARGUMENTS [ptxt_p; ctxt_p; len; key1_p; key2_p; iv_p] s /\ - byte_list_l_at pt_in (val len) ptxt_p s /\ - byte_list_l_at ct_err 15 ct_org s /\ + byte_list_at pt_in ptxt_p len s /\ + byte_list_at ct_err ct_org (word 15) s /\ read(memory :> bytes128 ctxt_p) s = err /\ read(memory :> bytes128 iv_p) s = iv /\ set_key_schedule s key1_p k1_0 k1_1 k1_2 k1_3 k1_4 k1_5 k1_6 k1_7 k1_8 k1_9 k1_10 k1_11 k1_12 k1_13 k1_14 /\ @@ -999,10 +1001,10 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( ) // postcondition (\s. read PC s = word (pc + LENGTH aes256_xts_encrypt_mc - 8*4) /\ - byte_list_l_at (aes256_xts_encrypt pt_in (val len) iv + byte_list_at (aes256_xts_encrypt pt_in (val len) iv [k1_0; k1_1; k1_2; k1_3; k1_4; k1_5; k1_6; k1_7; k1_8; k1_9; k1_10; k1_11; k1_12; k1_13; k1_14] [k2_0; k2_1; k2_2; k2_3; k2_4; k2_5; k2_6; k2_7; k2_8; k2_9; k2_10; k2_11; k2_12; k2_13; k2_14] ct_err) - (val len) ctxt_p s + ctxt_p len s ) (MAYCHANGE [PC;X0;X1;X2;X4;X6;X7;X8;X9;X10;X11;X19;X20;X21;X22],, MAYCHANGE [Q0;Q1;Q4;Q5;Q6;Q7;Q8;Q9;Q10;Q11;Q12;Q13;Q14;Q15;Q16;Q17;Q18;Q19;Q20;Q21;Q22;Q23;Q24;Q25;Q26],, @@ -1010,7 +1012,7 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( MAYCHANGE [events])`, REWRITE_TAC [(REWRITE_CONV [aes256_xts_encrypt_mc] THENC LENGTH_CONV) `LENGTH aes256_xts_encrypt_mc`] THEN - REWRITE_TAC[byte_list_l_at; set_key_schedule; NONOVERLAPPING_CLAUSES; C_ARGUMENTS; SOME_FLAGS; PAIRWISE; ALL] THEN + REWRITE_TAC[byte_list_at; set_key_schedule; NONOVERLAPPING_CLAUSES; C_ARGUMENTS; SOME_FLAGS; PAIRWISE; ALL] THEN REPEAT STRIP_TAC THEN (* Break len into full blocks and tail *) @@ -1163,16 +1165,10 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( MP_TAC (SPECL [`val (len_full_blocks:int64)`] UDIV_OPT_THM) THEN SIMP_TAC[] ; ALL_TAC] THEN POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th])) THEN -(* - 43 [`read X8 s113 = - word_ushr (word ((val len * 0xcccccccccccccccd) DIV 0x2 EXP 0x40)) 0x6`] - 20 [`word (val len_full_blocks DIV 0x50) = num_5blocks`] - 105 [`word_ushr - (word ((val len_full_blocks * 0xcccccccccccccccd) DIV 0x2 EXP 0x40)) - 0x6 = - word (val len_full_blocks DIV 0x50)`] *) - ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN - ] + + ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[]; + ALL_TAC + ] THEN (* Loop invariant *) ENSURES_WHILE_PAUP_TAC @@ -1181,12 +1177,14 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( `pc + 0x140` (* loop body start PC *) `pc + 0x430` (* loop backedge branch PC *) `\i s. - // loop invariant at the end of the loop - (read X8 s = word_sub num_5blocks (word i) /\ - read X0 s = word_add ptxt_p (word_mul (word 0x50) (word i)) /\ + // loop invariant at the end of the loop + (read X0 s = word_add ptxt_p (word_mul (word 0x50) (word i)) /\ read X1 s = word_add ctxt_p (word_mul (word 0x50) (word i)) /\ - byte_list_l_at (aes256_xts_encrypt pt_in (i * 0x50) iv key1_lst key2_lst ct_err) - (i * 0x50) ptxt_p s) /\ + read X21 s = tail_len /\ + read X2 s = word_sub len_full_blocks (word_mul (word 0x50) (word i)) /\ + read X8 s = word_sub num_5blocks (word i) /\ + byte_list_at (aes256_xts_encrypt pt_in (i * 0x50) iv key1_lst key2_lst ct_err) + ptxt_p val (i * 0x50) s) /\ // loop backedge condition (read ZF s <=> i = val (num_5blocks:int64))` THEN ASM_REWRITE_TAC[] THEN REPEAT CONJ_TAC THENL From 2e59a4e4fc08592944e59666f4e7eae4b28f8086 Mon Sep 17 00:00:00 2001 From: Nevine Ebeid Date: Fri, 3 Oct 2025 12:27:09 -0400 Subject: [PATCH 067/132] Update AES-XTS encrypt spec removing the byte list returned in case of error, matching the decrypt spec updates. --- arm/proofs/aes-xts-armv8.ml | 460 +---------------------------- arm/proofs/aes_xts_encrypt_spec.ml | 130 ++++---- 2 files changed, 65 insertions(+), 525 deletions(-) diff --git a/arm/proofs/aes-xts-armv8.ml b/arm/proofs/aes-xts-armv8.ml index 6faaa8000..e370b386d 100644 --- a/arm/proofs/aes-xts-armv8.ml +++ b/arm/proofs/aes-xts-armv8.ml @@ -973,7 +973,7 @@ void aes_hw_xts_encrypt(const uint8_t *in, uint8_t *out, size_t length, *) let AES256_XTS_ENCRYPT_CORRECT = prove( - `!ptxt_p ctxt_p len key1_p key2_p iv_p ct_org + `!ptxt_p ctxt_p len key1_p key2_p iv_p pt_in iv k1_0 k1_1 k1_2 k1_3 k1_4 k1_5 k1_6 k1_7 k1_8 k1_9 k1_10 k1_11 k1_12 k1_13 k1_14 k2_0 k2_1 k2_2 k2_3 k2_4 k2_5 k2_6 k2_7 k2_8 k2_9 k2_10 k2_11 k2_12 k2_13 k2_14 @@ -993,8 +993,6 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( read SP s = stackpointer /\ C_ARGUMENTS [ptxt_p; ctxt_p; len; key1_p; key2_p; iv_p] s /\ byte_list_at pt_in ptxt_p len s /\ - byte_list_at ct_err ct_org (word 15) s /\ - read(memory :> bytes128 ctxt_p) s = err /\ read(memory :> bytes128 iv_p) s = iv /\ set_key_schedule s key1_p k1_0 k1_1 k1_2 k1_3 k1_4 k1_5 k1_6 k1_7 k1_8 k1_9 k1_10 k1_11 k1_12 k1_13 k1_14 /\ set_key_schedule s key2_p k2_0 k2_1 k2_2 k2_3 k2_4 k2_5 k2_6 k2_7 k2_8 k2_9 k2_10 k2_11 k2_12 k2_13 k2_14 @@ -1003,7 +1001,7 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( (\s. read PC s = word (pc + LENGTH aes256_xts_encrypt_mc - 8*4) /\ byte_list_at (aes256_xts_encrypt pt_in (val len) iv [k1_0; k1_1; k1_2; k1_3; k1_4; k1_5; k1_6; k1_7; k1_8; k1_9; k1_10; k1_11; k1_12; k1_13; k1_14] - [k2_0; k2_1; k2_2; k2_3; k2_4; k2_5; k2_6; k2_7; k2_8; k2_9; k2_10; k2_11; k2_12; k2_13; k2_14] ct_err) + [k2_0; k2_1; k2_2; k2_3; k2_4; k2_5; k2_6; k2_7; k2_8; k2_9; k2_10; k2_11; k2_12; k2_13; k2_14]) ctxt_p len s ) (MAYCHANGE [PC;X0;X1;X2;X4;X6;X7;X8;X9;X10;X11;X19;X20;X21;X22],, @@ -1183,8 +1181,8 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( read X21 s = tail_len /\ read X2 s = word_sub len_full_blocks (word_mul (word 0x50) (word i)) /\ read X8 s = word_sub num_5blocks (word i) /\ - byte_list_at (aes256_xts_encrypt pt_in (i * 0x50) iv key1_lst key2_lst ct_err) - ptxt_p val (i * 0x50) s) /\ + byte_list_at (aes256_xts_encrypt pt_in (i * 0x50) iv key1_lst key2_lst) + ptxt_p (word (i * 0x50)) s) /\ // loop backedge condition (read ZF s <=> i = val (num_5blocks:int64))` THEN ASM_REWRITE_TAC[] THEN REPEAT CONJ_TAC THENL @@ -1198,454 +1196,6 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( ENSURES_INIT_TAC "s0" THEN ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN REPEAT CONJ_TAC THENL - (* - `aligned_bytes_loaded s0 (word pc) aes256_xts_encrypt_mc /\ - read PC s0 = word (pc + 0x140) /\ - read X8 s0 = word_sub num_5blocks (word 0x0) /\ - read X0 s0 = word_add ptxt_p (word_mul (word 0x50) (word 0x0)) /\ - read X1 s0 = word_add ctxt_p (word_mul (word 0x50) (word 0x0)) /\ - (forall i. - i < 0x0 * 0x50 - ==> read (memory :> bytes8 (word_add ptxt_p (word i))) s0 = - EL i - (aes256_xts_encrypt pt_in (0x0 * 0x50) iv key1_lst key2_lst ct_err))` + ] -`eventually arm - (\s'. - (aligned_bytes_loaded s' (word pc) aes256_xts_encrypt_mc /\ - read PC s' = word (pc + 0x140) /\ - read X8 s' = word_sub num_5blocks (word 0x0) /\ - read X0 s' = word_add ptxt_p (word_mul (word 0x50) (word 0x0)) /\ - read X1 s' = word_add ctxt_p (word_mul (word 0x50) (word 0x0)) /\ - (forall i. - i < 0x0 * 0x50 - ==> read (memory :> bytes8 (word_add ptxt_p (word i))) s' = - EL i - (aes256_xts_encrypt pt_in (0x0 * 0x50) iv key1_lst key2_lst - ct_err))) /\ - (MAYCHANGE - [PC; X0; X1; X2; X4; X6; X7; X8; X9; X10; X11; X19; X20; X21; X22] ,, - MAYCHANGE - [Q0; Q1; Q4; Q5; Q6; Q7; Q8; Q9; Q10; Q11; Q12; Q13; Q14; Q15; Q16; - Q17; Q18; Q19; Q20; Q21; Q22; Q23; Q24; Q25; Q26] ,, - MAYCHANGE [NF; ZF; CF; VF] ,, - MAYCHANGE [memory :> bytes128 ctxt_p] ,, - MAYCHANGE [events]) - s0 - s') - s0` - - 0 [`aligned 0x10 stackpointer`] - 1 [`nonoverlapping_modulo (0x2 EXP 0x40) (val stackpointer,0x6 * 0x10) - (pc,0xa80)`] - 2 [`nonoverlapping_modulo (0x2 EXP 0x40) (val stackpointer,0x6 * 0x10) - (val ctxt_p,val len)`] - 3 [`nonoverlapping_modulo (0x2 EXP 0x40) (val stackpointer,0x6 * 0x10) - (val key1_p,0xf4)`] - 4 [`nonoverlapping_modulo (0x2 EXP 0x40) (val stackpointer,0x6 * 0x10) - (val key2_p,0xf4)`] - 5 [`nonoverlapping_modulo (0x2 EXP 0x40) (pc,0xa80) (val ctxt_p,val len)`] - 6 [`nonoverlapping_modulo (0x2 EXP 0x40) (pc,0xa80) (val key1_p,0xf4)`] - 7 [`nonoverlapping_modulo (0x2 EXP 0x40) (pc,0xa80) (val key2_p,0xf4)`] - 8 [`nonoverlapping_modulo (0x2 EXP 0x40) (val ctxt_p,val len) - (val key1_p,0xf4)`] - 9 [`nonoverlapping_modulo (0x2 EXP 0x40) (val ctxt_p,val len) - (val key2_p,0xf4)`] - 10 [`nonoverlapping_modulo (0x2 EXP 0x40) (val key1_p,0xf4) - (val key2_p,0xf4)`] - 11 [`val len >= 0x10`] - 12 [`val len <= 0x2 EXP 0x18`] - 13 [`LENGTH pt_in = val len`] - 14 [`word_add tail_len len_full_blocks = len`] - 15 [`word_and len (word 0xfffffffffffffff0) = len_full_blocks`] - 16 [`word_and len (word 0xf) = tail_len`] - 17 [`[k1_0; k1_1; k1_2; k1_3; k1_4; k1_5; k1_6; k1_7; k1_8; k1_9; k1_10; - k1_11; k1_12; k1_13; k1_14] = - key1_lst`] - 18 [`[k2_0; k2_1; k2_2; k2_3; k2_4; k2_5; k2_6; k2_7; k2_8; k2_9; k2_10; - k2_11; k2_12; k2_13; k2_14] = - key2_lst`] - 19 [`~(val len < 0x50)`] - 20 [`word (val len_full_blocks DIV 0x50) = num_5blocks`] - 21 [`~(val len_full_blocks < 0x50)`] - 22 [`val len_full_blocks <= 0x2 EXP 0x18`] - 23 [`0x0 < val num_5blocks`] - -`ensures arm - (\s. - aligned_bytes_loaded s (word pc) aes256_xts_encrypt_mc /\ - read PC s = word (pc + 0x1c) /\ - read SP s = stackpointer /\ - (read X0 s = ptxt_p /\ - read X1 s = ctxt_p /\ - read X2 s = len /\ - read X3 s = key1_p /\ - read X4 s = key2_p /\ - read X5 s = iv_p) /\ - (forall i. - i < val len - ==> read (memory :> bytes8 (word_add ptxt_p (word i))) s = - EL i pt_in) /\ - (forall i. - i < 0xf - ==> read (memory :> bytes8 (word_add ct_org (word i))) s = - EL i ct_err) /\ - read (memory :> bytes128 ctxt_p) s = err /\ - read (memory :> bytes128 iv_p) s = iv /\ - (read (memory :> bytes128 key1_p) s = k1_0 /\ - read (memory :> bytes128 (word_add key1_p (word 0x10))) s = k1_1 /\ - read (memory :> bytes128 (word_add key1_p (word 0x20))) s = k1_2 /\ - read (memory :> bytes128 (word_add key1_p (word 0x30))) s = k1_3 /\ - read (memory :> bytes128 (word_add key1_p (word 0x40))) s = k1_4 /\ - read (memory :> bytes128 (word_add key1_p (word 0x50))) s = k1_5 /\ - read (memory :> bytes128 (word_add key1_p (word 0x60))) s = k1_6 /\ - read (memory :> bytes128 (word_add key1_p (word 0x70))) s = k1_7 /\ - read (memory :> bytes128 (word_add key1_p (word 0x80))) s = k1_8 /\ - read (memory :> bytes128 (word_add key1_p (word 0x90))) s = k1_9 /\ - read (memory :> bytes128 (word_add key1_p (word 0xa0))) s = k1_10 /\ - read (memory :> bytes128 (word_add key1_p (word 0xb0))) s = k1_11 /\ - read (memory :> bytes128 (word_add key1_p (word 0xc0))) s = k1_12 /\ - read (memory :> bytes128 (word_add key1_p (word 0xd0))) s = k1_13 /\ - read (memory :> bytes128 (word_add key1_p (word 0xe0))) s = k1_14 /\ - read (memory :> bytes32 (word_add key1_p (word 0xf0))) s = word 0xe) /\ - read (memory :> bytes128 key2_p) s = k2_0 /\ - read (memory :> bytes128 (word_add key2_p (word 0x10))) s = k2_1 /\ - read (memory :> bytes128 (word_add key2_p (word 0x20))) s = k2_2 /\ - read (memory :> bytes128 (word_add key2_p (word 0x30))) s = k2_3 /\ - read (memory :> bytes128 (word_add key2_p (word 0x40))) s = k2_4 /\ - read (memory :> bytes128 (word_add key2_p (word 0x50))) s = k2_5 /\ - read (memory :> bytes128 (word_add key2_p (word 0x60))) s = k2_6 /\ - read (memory :> bytes128 (word_add key2_p (word 0x70))) s = k2_7 /\ - read (memory :> bytes128 (word_add key2_p (word 0x80))) s = k2_8 /\ - read (memory :> bytes128 (word_add key2_p (word 0x90))) s = k2_9 /\ - read (memory :> bytes128 (word_add key2_p (word 0xa0))) s = k2_10 /\ - read (memory :> bytes128 (word_add key2_p (word 0xb0))) s = k2_11 /\ - read (memory :> bytes128 (word_add key2_p (word 0xc0))) s = k2_12 /\ - read (memory :> bytes128 (word_add key2_p (word 0xd0))) s = k2_13 /\ - read (memory :> bytes128 (word_add key2_p (word 0xe0))) s = k2_14 /\ - read (memory :> bytes32 (word_add key2_p (word 0xf0))) s = word 0xe) - (\s. - aligned_bytes_loaded s (word pc) aes256_xts_encrypt_mc /\ - read PC s = word (pc + 0x140) /\ - read X8 s = word_sub num_5blocks (word 0x0) /\ - read X0 s = word_add ptxt_p (word_mul (word 0x50) (word 0x0)) /\ - read X1 s = word_add ctxt_p (word_mul (word 0x50) (word 0x0)) /\ - byte_list_l_at - (aes256_xts_encrypt pt_in (0x0 * 0x50) iv key1_lst key2_lst ct_err) - (0x0 * 0x50) - ptxt_p - s) - (MAYCHANGE - [PC; X0; X1; X2; X4; X6; X7; X8; X9; X10; X11; X19; X20; X21; X22] ,, - MAYCHANGE - [Q0; Q1; Q4; Q5; Q6; Q7; Q8; Q9; Q10; Q11; Q12; Q13; Q14; Q15; Q16; Q17; - Q18; Q19; Q20; Q21; Q22; Q23; Q24; Q25; Q26] ,, - MAYCHANGE [NF; ZF; CF; VF] ,, - MAYCHANGE [memory :> bytes128 ctxt_p] ,, - MAYCHANGE [events])` - - -(* - Decrypt Subgoal 2 without the ENSURES_SEQUENCE_TAC before the loop invariant - - 0 [`nonoverlapping_modulo (0x2 EXP 0x40) (pc,0xb20) (val pt_ptr,val len)`] - 1 [`nonoverlapping_modulo (0x2 EXP 0x40) (val ct_ptr,val len) - (val pt_ptr,val len)`] - 2 [`val len >= 0x10`] - 3 [`val len <= 0x2 EXP 0x18`] - 4 [`LENGTH ct = val len`] - 5 [`word_add tail_len num_blocks = len`] - 6 [`word_and len (word 0xfffffffffffffff0) = num_blocks`] - 7 [`word_and len (word 0xf) = tail_len`] - 8 [`[k00; k01; k02; k03; k04; k05; k06; k07; k08; k09; k0a; k0b; k0c; k0d; - k0e] = - key1`] - 9 [`[k10; k11; k12; k13; k14; k15; k16; k17; k18; k19; k1a; k1b; k1c; k1d; - k1e] = - key2`] - 10 [`~(val len < 0x60)`] - 11 [`(if val tail_len = 0x0 - then num_blocks - else word_sub num_blocks (word 0x10)) = - num_blocks_adjusted`] - 12 [`word (val num_blocks_adjusted DIV 0x50) = num_5blocks_adjusted`] - 13 [`~(val num_blocks < 0x60)`] - 14 [`val num_blocks <= 0x2 EXP 0x18`] - 15 [`~(val num_blocks_adjusted < 0x50)`] - 16 [`val num_blocks_adjusted <= 0x2 EXP 0x18`] - 17 [`0x0 < val num_5blocks_adjusted`] - -`ensures arm - (\s. - aligned_bytes_loaded s (word pc) aes_xts_decrypt_mc /\ - read PC s = word (pc + 0x1c) /\ - (read X0 s = ct_ptr /\ - read X1 s = pt_ptr /\ - read X2 s = len /\ - read X3 s = key1_ptr /\ - read X4 s = key2_ptr /\ - read X5 s = iv_ptr) /\ - (forall i. - i < val len - ==> read (memory :> bytes8 (word_add ct_ptr (word i))) s = EL i ct) /\ - (forall i. - i < LENGTH pt_init - ==> read (memory :> bytes8 (word_add pt_ptr (word i))) s = - EL i pt_init) /\ - read (memory :> bytes128 iv_ptr) s = iv /\ - (read (memory :> bytes128 key1_ptr) s = k00 /\ - read (memory :> bytes128 (word_add key1_ptr (word 0x10))) s = k01 /\ - read (memory :> bytes128 (word_add key1_ptr (word 0x20))) s = k02 /\ - read (memory :> bytes128 (word_add key1_ptr (word 0x30))) s = k03 /\ - read (memory :> bytes128 (word_add key1_ptr (word 0x40))) s = k04 /\ - read (memory :> bytes128 (word_add key1_ptr (word 0x50))) s = k05 /\ - read (memory :> bytes128 (word_add key1_ptr (word 0x60))) s = k06 /\ - read (memory :> bytes128 (word_add key1_ptr (word 0x70))) s = k07 /\ - read (memory :> bytes128 (word_add key1_ptr (word 0x80))) s = k08 /\ - read (memory :> bytes128 (word_add key1_ptr (word 0x90))) s = k09 /\ - read (memory :> bytes128 (word_add key1_ptr (word 0xa0))) s = k0a /\ - read (memory :> bytes128 (word_add key1_ptr (word 0xb0))) s = k0b /\ - read (memory :> bytes128 (word_add key1_ptr (word 0xc0))) s = k0c /\ - read (memory :> bytes128 (word_add key1_ptr (word 0xd0))) s = k0d /\ - read (memory :> bytes128 (word_add key1_ptr (word 0xe0))) s = k0e /\ - read (memory :> bytes32 (word_add key1_ptr (word 0xf0))) s = word 0xe) /\ - read (memory :> bytes128 key2_ptr) s = k10 /\ - read (memory :> bytes128 (word_add key2_ptr (word 0x10))) s = k11 /\ - read (memory :> bytes128 (word_add key2_ptr (word 0x20))) s = k12 /\ - read (memory :> bytes128 (word_add key2_ptr (word 0x30))) s = k13 /\ - read (memory :> bytes128 (word_add key2_ptr (word 0x40))) s = k14 /\ - read (memory :> bytes128 (word_add key2_ptr (word 0x50))) s = k15 /\ - read (memory :> bytes128 (word_add key2_ptr (word 0x60))) s = k16 /\ - read (memory :> bytes128 (word_add key2_ptr (word 0x70))) s = k17 /\ - read (memory :> bytes128 (word_add key2_ptr (word 0x80))) s = k18 /\ - read (memory :> bytes128 (word_add key2_ptr (word 0x90))) s = k19 /\ - read (memory :> bytes128 (word_add key2_ptr (word 0xa0))) s = k1a /\ - read (memory :> bytes128 (word_add key2_ptr (word 0xb0))) s = k1b /\ - read (memory :> bytes128 (word_add key2_ptr (word 0xc0))) s = k1c /\ - read (memory :> bytes128 (word_add key2_ptr (word 0xd0))) s = k1d /\ - read (memory :> bytes128 (word_add key2_ptr (word 0xe0))) s = k1e /\ - read (memory :> bytes32 (word_add key2_ptr (word 0xf0))) s = word 0xe) - (\s. - aligned_bytes_loaded s (word pc) aes_xts_decrypt_mc /\ - read PC s = word (pc + 0x170) /\ - read X0 s = word_add ct_ptr (word_mul (word 0x50) (word 0x0)) /\ - read X1 s = word_add pt_ptr (word_mul (word 0x50) (word 0x0)) /\ - read X3 s = key1_ptr /\ - read X21 s = tail_len /\ - read X2 s = - word_sub num_blocks_adjusted (word_mul (word 0x50) (word 0x0)) /\ - read X8 s = word_sub num_5blocks_adjusted (word 0x0) /\ - read Q6 s = calculate_tweak (0x0 * 0x5) iv key2 /\ - read Q8 s = calculate_tweak (0x0 * 0x5 + 0x1) iv key2 /\ - read Q9 s = calculate_tweak (0x0 * 0x5 + 0x2) iv key2 /\ - read Q10 s = calculate_tweak (0x0 * 0x5 + 0x3) iv key2 /\ - read Q11 s = calculate_tweak (0x0 * 0x5 + 0x4) iv key2 /\ - read X19 s = word 0x87 /\ - read X10 s = - word_subword (calculate_tweak (0x0 * 0x5 + 0x4) iv key2) (0x40,0x40) /\ - read X9 s = word_zx (calculate_tweak (0x0 * 0x5 + 0x4) iv key2) /\ - read Q16 s = k00 /\ - read Q17 s = k01 /\ - read Q12 s = k02 /\ - read Q13 s = k03 /\ - read Q14 s = k04 /\ - read Q15 s = k05 /\ - read Q4 s = k06 /\ - read Q5 s = k07 /\ - read Q18 s = k08 /\ - read Q19 s = k09 /\ - read Q20 s = k0a /\ - read Q21 s = k0b /\ - read Q22 s = k0c /\ - read Q23 s = k0d /\ - read Q7 s = k0e /\ - byte_list_at ct ct_ptr s /\ - byte_list_at - (aes256_xts_decrypt ct (0x0 * 0x5 * 0x10) iv key1 key2 pt_init) - pt_ptr - s) - (MAYCHANGE [PC] ,, - MAYCHANGE [events] ,, - MAYCHANGE [X21; X2; X6; X4; X9; X10; X19; X22; X11; X7; X0; X1; X8] ,, - MAYCHANGE - [Q6; Q1; Q0; Q8; Q9; Q10; Q11; Q16; Q17; Q12; Q13; Q14; Q15; Q4; Q5; Q18; - Q19; Q20; Q21; Q22; Q23; Q7; Q29; Q24; Q25; Q26] ,, - MAYCHANGE [NF; ZF; CF; VF] ,, - MAYCHANGE [memory :> bytes (pt_ptr,val len)])` -*) - -(* loop.ml subgoal 2 *) -`ensures arm - (\s. - aligned_bytes_loaded s (word pc) loop_mc /\ - read PC s = word pc /\ - read X30 s = word retpc) - (\s. - aligned_bytes_loaded s (word pc) loop_mc /\ - read PC s = word (pc + 0x8) /\ - read X1 s = word 0x0 /\ - read X0 s = word (0x0 * 0x2) /\ - read X30 s = word retpc) - (MAYCHANGE [PC; X0; X1] ,, MAYCHANGE [NF; ZF; CF; VF] ,, MAYCHANGE [events])` - *) - (* - `word_xor - (aes256_encrypt - (word_xor - (aes256_encrypt iv - [k2_0; k2_1; k2_2; k2_3; k2_4; k2_5; k2_6; k2_7; k2_8; k2_9; k2_10; k2_11; - k2_12; k2_13; k2_14]) - pt_in) - [k1_0; k1_1; k1_2; k1_3; k1_4; k1_5; k1_6; k1_7; k1_8; k1_9; k1_10; k1_11; - k1_12; k1_13; k1_14]) - (aes256_encrypt iv - [k2_0; k2_1; k2_2; k2_3; k2_4; k2_5; k2_6; k2_7; k2_8; k2_9; k2_10; k2_11; - k2_12; k2_13; k2_14]) = - word_xor - (aes256_encrypt - (word_xor pt_in - (aes256_encrypt iv - [k2_0; k2_1; k2_2; k2_3; k2_4; k2_5; k2_6; k2_7; k2_8; k2_9; k2_10; k2_11; - k2_12; k2_13; k2_14])) - [k1_0; k1_1; k1_2; k1_3; k1_4; k1_5; k1_6; k1_7; k1_8; k1_9; k1_10; k1_11; - k1_12; k1_13; k1_14]) - (aes256_encrypt iv - [k2_0; k2_1; k2_2; k2_3; k2_4; k2_5; k2_6; k2_7; k2_8; k2_9; k2_10; k2_11; - k2_12; k2_13; k2_14])` - -# e(AP_THM_TAC);; - - `word_xor - (aes256_encrypt - (word_xor - (aes256_encrypt iv - [k2_0; k2_1; k2_2; k2_3; k2_4; k2_5; k2_6; k2_7; k2_8; k2_9; k2_10; k2_11; - k2_12; k2_13; k2_14]) - pt_in) - [k1_0; k1_1; k1_2; k1_3; k1_4; k1_5; k1_6; k1_7; k1_8; k1_9; k1_10; k1_11; - k1_12; k1_13; k1_14]) = - word_xor - (aes256_encrypt - (word_xor pt_in - (aes256_encrypt iv - [k2_0; k2_1; k2_2; k2_3; k2_4; k2_5; k2_6; k2_7; k2_8; k2_9; k2_10; k2_11; - k2_12; k2_13; k2_14])) - [k1_0; k1_1; k1_2; k1_3; k1_4; k1_5; k1_6; k1_7; k1_8; k1_9; k1_10; k1_11; - k1_12; k1_13; k1_14])` - -# e(AP_TERM_TAC);; - -`aes256_encrypt - (word_xor - (aes256_encrypt iv - [k2_0; k2_1; k2_2; k2_3; k2_4; k2_5; k2_6; k2_7; k2_8; k2_9; k2_10; k2_11; - k2_12; k2_13; k2_14]) - pt_in) - [k1_0; k1_1; k1_2; k1_3; k1_4; k1_5; k1_6; k1_7; k1_8; k1_9; k1_10; k1_11; - k1_12; k1_13; k1_14] = - aes256_encrypt - (word_xor pt_in - (aes256_encrypt iv - [k2_0; k2_1; k2_2; k2_3; k2_4; k2_5; k2_6; k2_7; k2_8; k2_9; k2_10; k2_11; - k2_12; k2_13; k2_14])) - [k1_0; k1_1; k1_2; k1_3; k1_4; k1_5; k1_6; k1_7; k1_8; k1_9; k1_10; k1_11; - k1_12; k1_13; k1_14]` - -# e(AP_THM_TAC);; - `aes256_encrypt - (word_xor - (aes256_encrypt iv - [k2_0; k2_1; k2_2; k2_3; k2_4; k2_5; k2_6; k2_7; k2_8; k2_9; k2_10; k2_11; - k2_12; k2_13; k2_14]) - pt_in) = - aes256_encrypt - (word_xor pt_in - (aes256_encrypt iv - [k2_0; k2_1; k2_2; k2_3; k2_4; k2_5; k2_6; k2_7; k2_8; k2_9; k2_10; k2_11; - k2_12; k2_13; k2_14]))` - -# e(AP_TERM_TAC);; -`word_xor - (aes256_encrypt iv - [k2_0; k2_1; k2_2; k2_3; k2_4; k2_5; k2_6; k2_7; k2_8; k2_9; k2_10; k2_11; - k2_12; k2_13; k2_14]) - pt_in = - word_xor pt_in - (aes256_encrypt iv - [k2_0; k2_1; k2_2; k2_3; k2_4; k2_5; k2_6; k2_7; k2_8; k2_9; k2_10; k2_11; - k2_12; k2_13; k2_14])` -*) - - -(* -If I don't make the second FIRST_X_ASSUM before XORING with the tweak, -How can I go within this term to do it later in the second argument of the -first xor to make it aes256_encrypt? - - 83 [`read (memory :> bytes128 ctxt) s117 = - word_xor - (aes256_encrypt iv - [k2_0; k2_1; k2_2; k2_3; k2_4; k2_5; k2_6; k2_7; k2_8; k2_9; k2_10; - k2_11; k2_12; k2_13; k2_14]) - (word_xor k1_14 - (aese - (aesmc - (aese - (aesmc - (aese - (aesmc - (aese - (aesmc - (aese - (aesmc - (aese - (aesmc - (aese - (aesmc - (aese - (aesmc - (aese - (aesmc - (aese - (aesmc - (aese - (aesmc - (aese - (aesmc - (aese - (aesmc - (aese - (word_xor - (aes256_encrypt iv - [k2_0; k2_1; k2_2; k2_3; k2_4; k2_5; k2_6; k2_7; k2_8; - k2_9; k2_10; k2_11; k2_12; k2_13; k2_14]) - pt_in) - k1_0)) - k1_1)) - k1_2)) - k1_3)) - k1_4)) - k1_5)) - k1_6)) - k1_7)) - k1_8)) - k1_9)) - k1_10)) - k1_11)) - k1_12)) - k1_13))`] - - -RULE_ASSUM_TAC(REWRITE_RULE[GSYM specth]) - -Why the REPEAT line in the following doesn't return back? -let AESXTS_ENC_ONE_BLOCK_TAC = - REWRITE_TAC [aes256_xts_encrypt_one_block] THEN - CONV_TAC (TOP_DEPTH_CONV let_CONV) THEN - REPEAT (GEN_REWRITE_TAC LAND_CONV [WORD_XOR_SYM] ORELSE AP_THM_TAC ORELSE AP_TERM_TAC) THEN - BITBLAST_TAC;; - - REWRITE_TAC may just repeat (without REPEAT) would arrive at a canonical form - June: TARGET_REWRITE_TAC -*) diff --git a/arm/proofs/aes_xts_encrypt_spec.ml b/arm/proofs/aes_xts_encrypt_spec.ml index c33cafabb..461458765 100644 --- a/arm/proofs/aes_xts_encrypt_spec.ml +++ b/arm/proofs/aes_xts_encrypt_spec.ml @@ -39,30 +39,41 @@ For partial final blocks, ciphertext stealing is used as per Section 5.3.2. (* Helper functions derived from Amanda's code: https://github.com/amanda-zx/s2n-bignum/blob/sha512/arm/sha512/sha512_specs.ml#L360 *) -(* XTS tweak initialization - encrypt the IV with key2 *) (* TODO: put it in a common place to be used with decrypt Start *) -let xts_init_tweak = new_definition - `xts_init_tweak (iv:int128) (key2:int128 list) = - aes256_encrypt iv key2`;; let bytes_to_int128 = define `bytes_to_int128 (bs : byte list) : int128 = - word_join - (word_join - (word_join - (word_join (EL 15 bs) (EL 14 bs) : int16) - (word_join (EL 13 bs) (EL 12 bs) : int16) : int32) - (word_join - (word_join (EL 11 bs) (EL 10 bs) : int16) - (word_join (EL 9 bs) (EL 8 bs) : int16) : int32) : int64) - (word_join - (word_join - (word_join (EL 7 bs) (EL 6 bs) : int16) - (word_join (EL 5 bs) (EL 4 bs) : int16) : int32) - (word_join - (word_join (EL 3 bs) (EL 2 bs) : int16) - (word_join (EL 1 bs) (EL 0 bs) : int16) : int32) : int64)`;; + (word_join:120 word->8 word->int128) + ((word_join:112 word->8 word->120 word) + ((word_join:104 word->8 word->112 word) + ((word_join:96 word->8 word->104 word) + ((word_join:88 word->8 word->96 word) + ((word_join:80 word->8 word->88 word) + ((word_join:72 word->8 word->80 word) + ((word_join:64 word->8 word->72 word) + ((word_join:56 word->8 word->64 word) + ((word_join:48 word->8 word->56 word) + ((word_join:40 word->8 word->48 word) + ((word_join:32 word->8 word->40 word) + ((word_join:24 word->8 word->32 word) + ((word_join:16 word->8 word->24 word) + ((word_join:8 word->8 word->16 word) + (EL 15 bs) (EL 14 bs)) + (EL 13 bs)) + (EL 12 bs)) + (EL 11 bs)) + (EL 10 bs)) + (EL 9 bs)) + (EL 8 bs)) + (EL 7 bs)) + (EL 6 bs)) + (EL 5 bs)) + (EL 4 bs)) + (EL 3 bs)) + (EL 2 bs)) + (EL 1 bs)) + (EL 0 bs)`;; let int128_to_bytes = define `int128_to_bytes (w : int128) : byte list = @@ -71,6 +82,11 @@ let int128_to_bytes = define word_subword w (64, 8); word_subword w (72, 8); word_subword w (80, 8); word_subword w (88, 8); word_subword w (96, 8); word_subword w (104, 8); word_subword w (112, 8); word_subword w (120, 8)]`;; +(* XTS tweak initialization - encrypt the IV with key2 *) +let xts_init_tweak = new_definition + `xts_init_tweak (iv:int128) (key2:int128 list) = + aes256_encrypt iv key2`;; + (* Multiplication by the primitive element \alpha in GF(2^128) *) let GF_128_mult_by_primitive = new_definition `GF_128_mult_by_primitive (tweak:(128)word) = @@ -78,13 +94,13 @@ let GF_128_mult_by_primitive = new_definition let mask = word_ishr tweak 127 in word_xor (word_and mask (word 0x87)) shifted`;; -(* TODO: put it in a common place to be used with decrypt - End *) let calculate_tweak = new_recursive_definition num_RECURSION `calculate_tweak 0 (iv:(128)word) (key2:int128 list) = xts_init_tweak iv key2 /\ calculate_tweak (SUC n) (iv:(128)word) (key2:int128 list) = GF_128_mult_by_primitive (calculate_tweak n iv key2)`;; +(* TODO: put it in a common place to be used with decrypt + End *) (* AES-XTS encryption round function *) let aes256_xts_encrypt_round = new_definition `aes256_xts_encrypt_round (P:int128) (tk:int128) (key1:int128 list) = @@ -102,14 +118,14 @@ let aes256_xts_encrypt_1block = new_definition let eth = prove_general_recursive_function_exists `?aes256_xts_encrypt_rec. ! (i:num) (m:num) (P:byte list) (iv:int128) (key1:int128 list) (key2:int128 list). - aes256_xts_encrypt_rec i m P iv key1 key2 : (byte list)#num = - if m < i then ([], i) + aes256_xts_encrypt_rec i m P iv key1 key2 : (byte list) = + if m < i then [] else let current_block = bytes_to_int128 (SUB_LIST (i * 16, 16) P) in let twk = calculate_tweak i iv key2 in let curr = int128_to_bytes (aes256_xts_encrypt_round current_block twk key1) in let res = aes256_xts_encrypt_rec (i + 1) m P iv key1 key2 in - (APPEND curr (FST res), SND res)`;; + APPEND curr res`;; let wfth = prove(hd(hyp eth), EXISTS_TAC `MEASURE (\(i:num,m:num,P:byte list,iv:int128,key1:int128 list,key2:int128 list). (m + 1) - i)` THEN @@ -160,19 +176,16 @@ let aes256_xts_encrypt_tail = new_definition iv: Initialization vector (tweak) as an int128 key1: Key schedule for AES-256 encryption key2: Key schedule for AES-256 encryption for the tweak - C_error: Error output ciphertext in case of invalid input length return: Output ciphertext as a byte list - When input len < 16, the function returns C_error, - which will be the initial value stored in output address. + When input len < 16, the function returns []. *) -(* TODO: Challenge lemma: proving that the output is of same length as input *) (* TODO: Double check if NIST spec talks about the error case len < 16 *) (* TODO: Double check the pseudo code in the spec for tweak calculation in ANEX c *) let aes256_xts_encrypt = new_definition `aes256_xts_encrypt - (P:byte list) (len:num) (iv:int128) (key1:int128 list) (key2:int128 list) (err:byte list) : byte list = + (P:byte list) (len:num) (iv:int128) (key1:int128 list) (key2:int128 list) : byte list = if len < 16 then - err + [] else let tail_len = len MOD 16 in let m = (len - tail_len) DIV 16 in @@ -180,8 +193,8 @@ let aes256_xts_encrypt = new_definition aes256_xts_encrypt_tail 0 tail_len P iv key1 key2 else let res = aes256_xts_encrypt_rec 0 (m - 2) P iv key1 key2 in - let Ctail = aes256_xts_encrypt_tail (SND res) tail_len P iv key1 key2 in - APPEND (FST res) Ctail`;; + let Ctail = aes256_xts_encrypt_tail (m - 1) tail_len P iv key1 key2 in + APPEND res Ctail`;; (***********************************************) (* Conversions and test vectors *) @@ -255,10 +268,6 @@ let ctext = new_definition `ctext = int128_to_bytes (word 0x9BCF70E3996C83E48603772F103A3B1C : int128 )`;; -let cerr = new_definition - `cerr = - int128_to_bytes (word 0x0)`;; - let iv1 = new_definition `iv1 = (word 0x000000000000000000000000000000FF) : int128`;; @@ -594,7 +603,7 @@ let rec AES256_XTS_ENCRYPT_REC_CONV tm = SUBLET_CONV (RAND_CONV AES256_XTS_ENCRYPT_ROUND_CONV) THENC SUBLET_CONV INT128_TO_BYTES_CONV THENC let_CONV THENC SUBLET_CONV AES256_XTS_ENCRYPT_REC_CONV THENC let_CONV THENC - REWRITE_CONV [FST;SND;APPEND] in + REWRITE_CONV [APPEND] in match tm with | Comb (Comb @@ -626,22 +635,6 @@ let rec AES256_XTS_ENCRYPT_REC_CONV tm = `aes256_xts_encrypt_rec 0 1 ptext2 iv1 data_key_schedule tweak_key_schedule`;; *) -(* -let CIPHER_STEALING_ENCRYPT_CONV = - REWRITE_CONV [cipher_stealing_encrypt] THENC - SUBLET_CONV CALCULATE_TWEAK_CONV THENC let_CONV THENC - SUBLET_CONV (ONCE_DEPTH_CONV BYTES_TO_INT128_CONV) THENC - SUBLET_CONV (RAND_CONV AES256_XTS_ENCRYPT_ROUND_CONV) THENC - SUBLET_CONV INT128_TO_BYTES_CONV THENC let_CONV THENC - SUBLET_CONV SUB_LIST_CONV THENC let_CONV THENC - SUBLET_CONV (DEPTH_CONV NUM_RED_CONV) THENC (* For evaluating 16 - tail_len *) - SUBLET_CONV SUB_LIST_CONV THENC let_CONV THENC - SUBLET_CONV (ONCE_DEPTH_CONV (REWRITE_CONV [APPEND])) THENC - SUBLET_CONV BYTES_TO_INT128_CONV THENC let_CONV THENC - SUBLET_CONV GF_128_MULT_BY_PRIMITIVE_CONV THENC let_CONV THENC - SUBLET_CONV (RAND_CONV AES256_XTS_ENCRYPT_ROUND_CONV) THENC - SUBLET_CONV INT128_TO_BYTES_CONV THENC let_CONV;; -*) let CIPHER_STEALING_ENCRYPT_CONV = REWR_CONV cipher_stealing_encrypt THENC SUBLET_CONV CALCULATE_TWEAK_CONV THENC let_CONV THENC @@ -713,7 +706,6 @@ let AES256_XTS_ENCRYPT_CONV tm = DEPTH_CONV NUM_RED_CONV in let MORE_THAN_2_CONV = SUBLET_CONV AES256_XTS_ENCRYPT_REC_CONV THENC let_CONV THENC - REWRITE_CONV [FST;SND] THENC SUBLET_CONV AES256_XTS_ENCRYPT_TAIL_CONV THENC let_CONV THENC REWRITE_CONV [APPEND] in let BODY_CONV = @@ -728,9 +720,7 @@ let AES256_XTS_ENCRYPT_CONV tm = (Comb (Comb (Comb - (Comb - (Const ("aes256_xts_encrypt", _), _), len), - _), + (Const ("aes256_xts_encrypt", _), _), len), _), _), _) -> @@ -740,27 +730,27 @@ let AES256_XTS_ENCRYPT_CONV tm = | _ -> failwith "AES256_XTS_ENCRYPT_CONV: inapplicable";; (* -(REWRITE_CONV [cerr; int128_to_bytes] THENC AES256_XTS_ENCRYPT_CONV) - `aes256_xts_encrypt p0 5 iv_tweak key_1 key_2 cerr`;; +(REWRITE_CONV [int128_to_bytes] THENC AES256_XTS_ENCRYPT_CONV) + `aes256_xts_encrypt p0 5 iv_tweak key_1 key_2`;; -(*(REWRITE_CONV [ptext; cerr; int128_to_bytes; iv_tweak; key_1; key_2] THENC AES256_XTS_ENCRYPT_CONV) - `aes256_xts_encrypt ptext 16 iv_tweak key_1 key_2 cerr`;;*) +(*(REWRITE_CONV [ptext; int128_to_bytes; iv_tweak; key_1; key_2] THENC AES256_XTS_ENCRYPT_CONV) + `aes256_xts_encrypt ptext 16 iv_tweak key_1 key_2`;;*) -(* 1 block : 68 sec on M3 *) -time prove (`aes256_xts_encrypt ptext 16 iv_tweak key_1 key_2 cerr = c0`, - CONV_TAC(LAND_CONV (REWRITE_CONV [ptext; cerr; int128_to_bytes; iv_tweak; key_1; key_2] +(* 1 block : 70 sec on M3 *) +time prove (`aes256_xts_encrypt ptext 16 iv_tweak key_1 key_2 = c0`, + CONV_TAC(LAND_CONV (REWRITE_CONV [ptext; int128_to_bytes; iv_tweak; key_1; key_2] THENC AES256_XTS_ENCRYPT_CONV)) THEN REWRITE_TAC [c0] THEN REFL_TAC);; -(* 1 block + 6 bytes : 102 sec on M3 *) -time prove (`aes256_xts_encrypt p1 22 iv_tweak key_1 key_2 cerr = c1`, - CONV_TAC(LAND_CONV (REWRITE_CONV [p1; cerr; int128_to_bytes; iv_tweak; key_1; key_2] +(* 1 block + 6 bytes : 104 sec on M3 *) +time prove (`aes256_xts_encrypt p1 22 iv_tweak key_1 key_2 = c1`, + CONV_TAC(LAND_CONV (REWRITE_CONV [p1; int128_to_bytes; iv_tweak; key_1; key_2] THENC AES256_XTS_ENCRYPT_CONV)) THEN REWRITE_TAC [c1] THEN REFL_TAC);; -(* 3 blocks + 3 bytes : 240 sec on M3 *) -time prove (`aes256_xts_encrypt p2 51 iv_tweak key_1 key_2 cerr = c2`, - CONV_TAC(LAND_CONV (REWRITE_CONV [p2; cerr; int128_to_bytes; iv_tweak; key_1; key_2] +(* 3 blocks + 3 bytes : 243 sec on M3 *) +time prove (`aes256_xts_encrypt p2 51 iv_tweak key_1 key_2 = c2`, + CONV_TAC(LAND_CONV (REWRITE_CONV [p2; int128_to_bytes; iv_tweak; key_1; key_2] THENC AES256_XTS_ENCRYPT_CONV)) THEN REWRITE_TAC [c2] THEN REFL_TAC);; *) From b1747137fe8781a79b8c822004d28b624f17051e Mon Sep 17 00:00:00 2001 From: Nevine Ebeid Date: Fri, 3 Oct 2025 16:44:03 -0400 Subject: [PATCH 068/132] Subgoal 2 of the loop invariant proven. --- arm/proofs/aes-xts-armv8.ml | 332 ++++++++++++++++++++++++------------ 1 file changed, 227 insertions(+), 105 deletions(-) diff --git a/arm/proofs/aes-xts-armv8.ml b/arm/proofs/aes-xts-armv8.ml index e370b386d..dc9d046f6 100644 --- a/arm/proofs/aes-xts-armv8.ml +++ b/arm/proofs/aes-xts-armv8.ml @@ -1062,111 +1062,124 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( - First 5 tweaks are calculated from the iv - X2 contains len_full_blocks - X8 contains num_5_blocks - - key1 schedule is loaded in Q registers *) - ENSURES_SEQUENCE_TAC - `pc + 0x140` - `\s. - read X0 s = ptxt_p /\ - read X1 s = ctxt_p /\ - read X2 s = len_full_blocks /\ - read X21 s = tail_len /\ - read X8 s = num_5blocks /\ - read Q6 s = calculate_tweak 0 iv key2_lst /\ - read Q8 s = calculate_tweak 1 iv key2_lst /\ - read Q9 s = calculate_tweak 2 iv key2_lst /\ - read Q10 s = calculate_tweak 3 iv key2_lst /\ - read Q11 s = calculate_tweak 4 iv key2_lst /\ - read X19 s = word 0x87 /\ - read Q16 s = k1_0 /\ read Q17 s = k1_1 /\ read Q12 s = k1_2 /\ read Q13 s = k1_3 /\ - read Q14 s = k1_4 /\ read Q15 s = k1_5 /\ read Q4 s = k1_6 /\ read Q5 s = k1_7 /\ - read Q18 s = k1_8 /\ read Q19 s = k1_9 /\ read Q20 s = k1_10 /\ read Q21 s = k1_11 /\ - read Q22 s = k1_12 /\ read Q23 s = k1_13 /\ read Q7 s = k1_14 - ` THEN - CONJ_TAC THENL - [ - (* ===> Symbolic Simulation: Start symbolic simulation*) - ENSURES_INIT_TAC "s0" THEN - ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (1--2) THEN + - key1 schedule is loaded in Q registers + - X9 and X10 are not needed to be spelled out for the proof itself, but to be + kept in the assumption list after the proof *) + ENSURES_SEQUENCE_TAC + `pc + 0x140` + `\s. + read X0 s = ptxt_p /\ + read X1 s = ctxt_p /\ + read X2 s = len_full_blocks /\ + read X21 s = tail_len /\ + read X8 s = num_5blocks /\ + read X9 s = word_zx (calculate_tweak 4 iv key2_lst) /\ + read X10 s = word_subword (calculate_tweak 4 iv key2_lst) (64,64) /\ + read Q6 s = calculate_tweak 0 iv key2_lst /\ + read Q8 s = calculate_tweak 1 iv key2_lst /\ + read Q9 s = calculate_tweak 2 iv key2_lst /\ + read Q10 s = calculate_tweak 3 iv key2_lst /\ + read Q11 s = calculate_tweak 4 iv key2_lst /\ + read X19 s = word 0x87 /\ + read Q16 s = k1_0 /\ read Q17 s = k1_1 /\ read Q12 s = k1_2 /\ read Q13 s = k1_3 /\ + read Q14 s = k1_4 /\ read Q15 s = k1_5 /\ read Q4 s = k1_6 /\ read Q5 s = k1_7 /\ + read Q18 s = k1_8 /\ read Q19 s = k1_9 /\ read Q20 s = k1_10 /\ read Q21 s = k1_11 /\ + read Q22 s = k1_12 /\ read Q23 s = k1_13 /\ read Q7 s = k1_14 /\ + byte_list_at pt_in ptxt_p len s /\ + byte_list_at (aes256_xts_encrypt pt_in 0 iv key1_lst key2_lst) + ctxt_p (word 0) s + ` THEN + CONJ_TAC THENL + [ + (* ===> Symbolic Simulation: Start symbolic simulation*) + ENSURES_INIT_TAC "s0" THEN + ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (1--2) THEN - (* Discharge if condition *) - SUBGOAL_THEN - `ival (word_sub (len:int64) (word 0x10)) < &0x0 - <=> ~(ival (len:int64) - &0x10 = ival (word_sub (len:int64) (word 0x10)))` MP_TAC THENL - [ MP_TAC (BITBLAST_RULE - `val (len:int64) >= 0x10 ==> val len <= 2 EXP 0x18 ==> - ival (word_sub len (word 0x10)) >= &0x0`) THEN - ASM_REWRITE_TAC[] THEN - MP_TAC (BITBLAST_RULE - `val (len:int64) >= 0x10 ==> val len <= 2 EXP 0x18 ==> - ival (len:int64) - &0x10 = ival (word_sub len (word 0x10))`) THEN - ASM_REWRITE_TAC[] THEN - ARITH_TAC;(* works on the goal; that's why we bring the assumptions we want as antecedants of the goal *) - ALL_TAC - ] THEN + (* Discharge if condition *) + SUBGOAL_THEN + `ival (word_sub (len:int64) (word 0x10)) < &0x0 + <=> ~(ival (len:int64) - &0x10 = ival (word_sub (len:int64) (word 0x10)))` MP_TAC THENL + [ MP_TAC (BITBLAST_RULE + `val (len:int64) >= 0x10 ==> val len <= 2 EXP 0x18 ==> + ival (word_sub len (word 0x10)) >= &0x0`) THEN + ASM_REWRITE_TAC[] THEN + MP_TAC (BITBLAST_RULE + `val (len:int64) >= 0x10 ==> val len <= 2 EXP 0x18 ==> + ival (len:int64) - &0x10 = ival (word_sub len (word 0x10))`) THEN ASM_REWRITE_TAC[] THEN - DISCH_TAC THEN POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th])) THEN - (* Try DISCH_THEN(RULE_ASSUM_TAC o REWRITE_RULE o CONJUNCTS) *) + ARITH_TAC;(* works on the goal; that's why we bring the assumptions we want as antecedants of the goal *) + ALL_TAC + ] THEN + ASM_REWRITE_TAC[] THEN + DISCH_TAC THEN POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th])) THEN + (* Try DISCH_THEN(RULE_ASSUM_TAC o REWRITE_RULE o CONJUNCTS) *) - (* ===> Symbolic Simulation: Symbolic execution for initialization of tweak *) - ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (3--65) THEN - (* Prove Q6 stores initial tweak *) - FIRST_X_ASSUM(MP_TAC o SPEC `(calculate_tweak 0 iv key2_lst)` - o MATCH_MP (MESON[] `read Q6 s = a ==> !a'. a = a' ==> read Q6 s = a'`)) THEN - ANTS_TAC THENL - [REWRITE_TAC[CONJUNCT1 calculate_tweak; xts_init_tweak] THEN - EXPAND_TAC "key2_lst" THEN AESENC_TAC; DISCH_TAC] THEN + (* ===> Symbolic Simulation: Symbolic execution for initialization of tweak *) + ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (3--65) THEN + (* Prove Q6 stores initial tweak *) + FIRST_X_ASSUM(MP_TAC o SPEC `(calculate_tweak 0 iv key2_lst)` + o MATCH_MP (MESON[] `read Q6 s = a ==> !a'. a = a' ==> read Q6 s = a'`)) THEN + ANTS_TAC THENL + [REWRITE_TAC[CONJUNCT1 calculate_tweak; xts_init_tweak] THEN + EXPAND_TAC "key2_lst" THEN AESENC_TAC; DISCH_TAC] THEN - (* ===> Symbolic Simulation: Symbolic simulating untill next branch: - - iv for second block - - load key schedule *) - ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (66--76) THEN - (* Branching on x2 *) - (* Eliminate 1 block case *) - SUBGOAL_THEN `~(val (len_full_blocks:int64) < 0x20)` MP_TAC THENL - [ UNDISCH_TAC `~(val (len_full_blocks:int64) < 0x50)` THEN ARITH_TAC; - DISCH_THEN(RULE_ASSUM_TAC o REWRITE_RULE o CONJUNCTS)] THEN + (* ===> Symbolic Simulation: Symbolic simulating untill next branch: + - iv for second block + - load key schedule *) + ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (66--76) THEN + (* Branching on x2 *) + (* Eliminate 1 block case *) + SUBGOAL_THEN `~(val (len_full_blocks:int64) < 0x20)` MP_TAC THENL + [ UNDISCH_TAC `~(val (len_full_blocks:int64) < 0x50)` THEN ARITH_TAC; + DISCH_THEN(RULE_ASSUM_TAC o REWRITE_RULE o CONJUNCTS)] THEN - (* Prove x9, x10 store lower and upper halves of tweak 1 and Q8 stores the full tweak 1 *) - ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (77--85) THEN - TWEAK_TAC `Q8:(armstate,int128)component` `1:num` `0:num` THEN + (* Prove x9, x10 store lower and upper halves of tweak 1 and Q8 stores the full tweak 1 *) + ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (77--85) THEN + TWEAK_TAC `Q8:(armstate,int128)component` `1:num` `0:num` THEN - (* Eliminate 2 blocks case *) - ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (86--87) THEN - SUBGOAL_THEN `~(val (len_full_blocks:int64) < 0x30)` MP_TAC THENL - [ UNDISCH_TAC `~(val (len_full_blocks:int64) < 0x50)` THEN ARITH_TAC; - DISCH_THEN(RULE_ASSUM_TAC o REWRITE_RULE o CONJUNCTS)] THEN - (* prove Q9 stores tweak of 3rd block (index 2) *) - ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (88--93) THEN - TWEAK_TAC `Q9:(armstate,int128)component` `2:num` `0:num` THEN - (* Eliminate 3 blocks case *) - ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (94--95) THEN - SUBGOAL_THEN `~(val (len_full_blocks:int64) < 0x40)` MP_TAC THENL - [ UNDISCH_TAC `~(val (len_full_blocks:int64) < 0x50)` THEN ARITH_TAC; - DISCH_THEN(RULE_ASSUM_TAC o REWRITE_RULE o CONJUNCTS)] THEN - (* prove Q10 stores tweak of 4th block (index 3) *) - ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (96--101) THEN - TWEAK_TAC `Q10:(armstate,int128)component` `3:num` `0:num` THEN - (* Eliminate 4 blocks case, proven by the assumption ~(len_full_blocks < 0x50)*) - ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (102--103) THEN - (* prove Q11 stores tweak of 5th block (index 4) *) - ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (105--110) THEN - TWEAK_TAC `Q11:(armstate,int128)component` `4:num` `0:num` THEN + (* Eliminate 2 blocks case *) + ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (86--87) THEN + SUBGOAL_THEN `~(val (len_full_blocks:int64) < 0x30)` MP_TAC THENL + [ UNDISCH_TAC `~(val (len_full_blocks:int64) < 0x50)` THEN ARITH_TAC; + DISCH_THEN(RULE_ASSUM_TAC o REWRITE_RULE o CONJUNCTS)] THEN + (* prove Q9 stores tweak of 3rd block (index 2) *) + ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (88--93) THEN + TWEAK_TAC `Q9:(armstate,int128)component` `2:num` `0:num` THEN + (* Eliminate 3 blocks case *) + ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (94--95) THEN + SUBGOAL_THEN `~(val (len_full_blocks:int64) < 0x40)` MP_TAC THENL + [ UNDISCH_TAC `~(val (len_full_blocks:int64) < 0x50)` THEN ARITH_TAC; + DISCH_THEN(RULE_ASSUM_TAC o REWRITE_RULE o CONJUNCTS)] THEN + (* prove Q10 stores tweak of 4th block (index 3) *) + ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (96--101) THEN + TWEAK_TAC `Q10:(armstate,int128)component` `3:num` `0:num` THEN + (* Eliminate 4 blocks case, proven by the assumption ~(len_full_blocks < 0x50)*) + ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (102--103) THEN + (* prove Q11 stores tweak of 5th block (index 4) *) + ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (105--110) THEN + TWEAK_TAC `Q11:(armstate,int128)component` `4:num` `0:num` THEN - (* Prove the optimized udiv is basically udiv *) - ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (111--114) THEN - SUBGOAL_THEN `word_ushr - ((word ((val (len_full_blocks:int64) * 0xcccccccccccccccd) DIV 0x2 EXP 0x40)):int64) - 0x6 = - word ((val len_full_blocks) DIV 0x50)` ASSUME_TAC THENL - [ MP_TAC (BITBLAST_RULE `val (len_full_blocks:int64) < 2 EXP 64`) THEN - REWRITE_TAC[word_ushr] THEN - MP_TAC (SPECL [`val (len_full_blocks:int64)`] UDIV_OPT_THM) THEN SIMP_TAC[] - ; ALL_TAC] THEN - POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th])) THEN + (* Prove the optimized udiv is basically udiv *) + ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (111--114) THEN + SUBGOAL_THEN `word_ushr + ((word ((val (len_full_blocks:int64) * 0xcccccccccccccccd) DIV 0x2 EXP 0x40)):int64) + 0x6 = + word ((val len_full_blocks) DIV 0x50)` ASSUME_TAC THENL + [ MP_TAC (BITBLAST_RULE `val (len_full_blocks:int64) < 2 EXP 64`) THEN + REWRITE_TAC[word_ushr] THEN + MP_TAC (SPECL [`val (len_full_blocks:int64)`] UDIV_OPT_THM) THEN SIMP_TAC[] + ; ALL_TAC] THEN + POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th])) THEN - ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[]; - ALL_TAC - ] THEN + ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN + REPEAT CONJ_TAC THENL + [ ASM_REWRITE_TAC[byte_list_at]; + REWRITE_TAC[aes256_xts_encrypt] THEN + CONV_TAC (DEPTH_CONV NUM_RED_CONV) THEN + ASM_REWRITE_TAC[byte_list_at] THEN + REWRITE_TAC[VAL_WORD_0] THEN ARITH_TAC ] + ; ALL_TAC + ] THEN (* Loop invariant *) ENSURES_WHILE_PAUP_TAC @@ -1176,26 +1189,135 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( `pc + 0x430` (* loop backedge branch PC *) `\i s. // loop invariant at the end of the loop - (read X0 s = word_add ptxt_p (word_mul (word 0x50) (word i)) /\ - read X1 s = word_add ctxt_p (word_mul (word 0x50) (word i)) /\ + (read X0 s = word_add ptxt_p (word_mul (word 0x50) (word i)) /\ + read X1 s = word_add ctxt_p (word_mul (word 0x50) (word i)) /\ read X21 s = tail_len /\ - read X2 s = word_sub len_full_blocks (word_mul (word 0x50) (word i)) /\ - read X8 s = word_sub num_5blocks (word i) /\ + read X2 s = word_sub len_full_blocks (word_mul (word 0x50) (word i)) /\ + read X8 s = word_sub num_5blocks (word i) /\ + read X19 s = word 0x87 /\ + read X9 s = word_zx (calculate_tweak (i * 5 + 4) iv key2_lst) /\ + read X10 s = word_subword (calculate_tweak (i * 5 + 4) iv key2_lst) (64,64) /\ + read Q6 s = calculate_tweak (i * 5) iv key2_lst /\ + read Q8 s = calculate_tweak (i * 5 + 1) iv key2_lst /\ + read Q9 s = calculate_tweak (i * 5 + 2) iv key2_lst /\ + read Q10 s = calculate_tweak (i * 5 + 3) iv key2_lst /\ + read Q11 s = calculate_tweak (i * 5 + 4) iv key2_lst /\ + read Q16 s = k1_0 /\ read Q17 s = k1_1 /\ read Q12 s = k1_2 /\ read Q13 s = k1_3 /\ + read Q14 s = k1_4 /\ read Q15 s = k1_5 /\ read Q4 s = k1_6 /\ read Q5 s = k1_7 /\ + read Q18 s = k1_8 /\ read Q19 s = k1_9 /\ read Q20 s = k1_10 /\ read Q21 s = k1_11 /\ + read Q22 s = k1_12 /\ read Q23 s = k1_13 /\ read Q7 s = k1_14 /\ + byte_list_at pt_in ptxt_p len s /\ byte_list_at (aes256_xts_encrypt pt_in (i * 0x50) iv key1_lst key2_lst) - ptxt_p (word (i * 0x50)) s) /\ + ctxt_p (word (i * 0x50)) s) /\ // loop backedge condition (read ZF s <=> i = val (num_5blocks:int64))` THEN ASM_REWRITE_TAC[] THEN REPEAT CONJ_TAC THENL [ (* Subgoal 1. - 0 < `val (num_5blocks:int64)`` + 0 < `val (num_5blocks:int64)` automatically discharged by asm *) - (* Subgoal 2. *) - REWRITE_TAC[byte_list_l_at] THEN + (* Subgoal 2. Invariant holds before entering the loop *) + REWRITE_TAC[byte_list_at] THEN ENSURES_INIT_TAC "s0" THEN ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN REPEAT CONJ_TAC THENL + [ WORD_ARITH_TAC; WORD_ARITH_TAC; WORD_ARITH_TAC; WORD_ARITH_TAC; + CONV_TAC NUM_REDUCE_CONV; + CONV_TAC NUM_REDUCE_CONV; + CONV_TAC NUM_REDUCE_CONV; + CONV_TAC NUM_REDUCE_CONV; + CONV_TAC NUM_REDUCE_CONV; + CONV_TAC NUM_REDUCE_CONV; + CONV_TAC NUM_REDUCE_CONV; + ASM_REWRITE_TAC[] ] ] +(* +# e(CONV_TAC NUM_REDUCE_CONV);; +val it : goalstack = 1 subgoal (4 total) + + 0 [`aligned 0x10 stackpointer`] + 1 [`nonoverlapping_modulo (0x2 EXP 0x40) (val stackpointer,0x6 * 0x10) + (pc,0xa80)`] + 2 [`nonoverlapping_modulo (0x2 EXP 0x40) (val stackpointer,0x6 * 0x10) + (val ctxt_p,val len)`] + 3 [`nonoverlapping_modulo (0x2 EXP 0x40) (val stackpointer,0x6 * 0x10) + (val key1_p,0xf4)`] + 4 [`nonoverlapping_modulo (0x2 EXP 0x40) (val stackpointer,0x6 * 0x10) + (val key2_p,0xf4)`] + 5 [`nonoverlapping_modulo (0x2 EXP 0x40) (pc,0xa80) (val ctxt_p,val len)`] + 6 [`nonoverlapping_modulo (0x2 EXP 0x40) (pc,0xa80) (val key1_p,0xf4)`] + 7 [`nonoverlapping_modulo (0x2 EXP 0x40) (pc,0xa80) (val key2_p,0xf4)`] + 8 [`nonoverlapping_modulo (0x2 EXP 0x40) (val ctxt_p,val len) + (val key1_p,0xf4)`] + 9 [`nonoverlapping_modulo (0x2 EXP 0x40) (val ctxt_p,val len) + (val key2_p,0xf4)`] + 10 [`nonoverlapping_modulo (0x2 EXP 0x40) (val key1_p,0xf4) + (val key2_p,0xf4)`] + 11 [`val len >= 0x10`] + 12 [`val len <= 0x2 EXP 0x18`] + 13 [`LENGTH pt_in = val len`] + 14 [`word_add tail_len len_full_blocks = len`] + 15 [`word_and len (word 0xfffffffffffffff0) = len_full_blocks`] + 16 [`word (val len_full_blocks DIV 0x50) = num_5blocks`] + 17 [`word_and len (word 0xf) = tail_len`] + 18 [`[k1_0; k1_1; k1_2; k1_3; k1_4; k1_5; k1_6; k1_7; k1_8; k1_9; k1_10; + k1_11; k1_12; k1_13; k1_14] = + key1_lst`] + 19 [`[k2_0; k2_1; k2_2; k2_3; k2_4; k2_5; k2_6; k2_7; k2_8; k2_9; k2_10; + k2_11; k2_12; k2_13; k2_14] = + key2_lst`] + 20 [`~(val len < 0x50)`] + 21 [`~(val len_full_blocks < 0x50)`] + 22 [`val len_full_blocks <= 0x2 EXP 0x18`] + 23 [`0x0 < val num_5blocks`] + 24 [`aligned_bytes_loaded s0 (word pc) aes256_xts_encrypt_mc`] + 25 [`read PC s0 = word (pc + 0x140)`] + 26 [`read X0 s0 = ptxt_p`] + 27 [`read X1 s0 = ctxt_p`] + 28 [`read X2 s0 = len_full_blocks`] + 29 [`read X21 s0 = tail_len`] + 30 [`read X8 s0 = num_5blocks`] + 31 [`read X9 s0 = word_zx (calculate_tweak 0x4 iv key2_lst)`] + 32 [`read X10 s0 = + word_subword (calculate_tweak 0x4 iv key2_lst) (0x40,0x40)`] + 33 [`read Q6 s0 = calculate_tweak 0x0 iv key2_lst`] + 34 [`read Q8 s0 = calculate_tweak 0x1 iv key2_lst`] + 35 [`read Q9 s0 = calculate_tweak 0x2 iv key2_lst`] + 36 [`read Q10 s0 = calculate_tweak 0x3 iv key2_lst`] + 37 [`read Q11 s0 = calculate_tweak 0x4 iv key2_lst`] + 38 [`read X19 s0 = word 0x87`] + 39 [`read Q16 s0 = k1_0`] + 40 [`read Q17 s0 = k1_1`] + 41 [`read Q12 s0 = k1_2`] + 42 [`read Q13 s0 = k1_3`] + 43 [`read Q14 s0 = k1_4`] + 44 [`read Q15 s0 = k1_5`] + 45 [`read Q4 s0 = k1_6`] + 46 [`read Q5 s0 = k1_7`] + 47 [`read Q18 s0 = k1_8`] + 48 [`read Q19 s0 = k1_9`] + 49 [`read Q20 s0 = k1_10`] + 50 [`read Q21 s0 = k1_11`] + 51 [`read Q22 s0 = k1_12`] + 52 [`read Q23 s0 = k1_13`] + 53 [`read Q7 s0 = k1_14`] + 54 [`forall i. + i < val len + ==> read (memory :> bytes8 (word_add ptxt_p (word i))) s0 = + EL i pt_in`] + 55 [`forall i. + i < val (word 0x0) + ==> read (memory :> bytes8 (word_add ctxt_p (word i))) s0 = + EL i (aes256_xts_encrypt pt_in 0x0 iv key1_lst key2_lst)`] + 56 [`(MAYCHANGE:((armstate,?275580)component)list->armstate->armstate->bool) + [] + s0 + s0`] +`forall i. + i < val (word 0x0) + ==> read (memory :> bytes8 (word_add ctxt_p (word i))) s0 = + EL i (aes256_xts_encrypt pt_in 0x0 iv key1_lst key2_lst)` +*) From 16d95d85525e3221cea1451c78b52ae73f603fb9 Mon Sep 17 00:00:00 2001 From: Nevine Ebeid Date: Wed, 8 Oct 2025 10:31:18 -0400 Subject: [PATCH 069/132] Changed back bytes_to_int128 to its original definition. --- arm/proofs/aes_xts_encrypt_spec.ml | 38 ++++++------------------------ 1 file changed, 7 insertions(+), 31 deletions(-) diff --git a/arm/proofs/aes_xts_encrypt_spec.ml b/arm/proofs/aes_xts_encrypt_spec.ml index 461458765..a592e835f 100644 --- a/arm/proofs/aes_xts_encrypt_spec.ml +++ b/arm/proofs/aes_xts_encrypt_spec.ml @@ -41,39 +41,15 @@ For partial final blocks, ciphertext stealing is used as per Section 5.3.2. (* TODO: put it in a common place to be used with decrypt Start *) - let bytes_to_int128 = define `bytes_to_int128 (bs : byte list) : int128 = - (word_join:120 word->8 word->int128) - ((word_join:112 word->8 word->120 word) - ((word_join:104 word->8 word->112 word) - ((word_join:96 word->8 word->104 word) - ((word_join:88 word->8 word->96 word) - ((word_join:80 word->8 word->88 word) - ((word_join:72 word->8 word->80 word) - ((word_join:64 word->8 word->72 word) - ((word_join:56 word->8 word->64 word) - ((word_join:48 word->8 word->56 word) - ((word_join:40 word->8 word->48 word) - ((word_join:32 word->8 word->40 word) - ((word_join:24 word->8 word->32 word) - ((word_join:16 word->8 word->24 word) - ((word_join:8 word->8 word->16 word) - (EL 15 bs) (EL 14 bs)) - (EL 13 bs)) - (EL 12 bs)) - (EL 11 bs)) - (EL 10 bs)) - (EL 9 bs)) - (EL 8 bs)) - (EL 7 bs)) - (EL 6 bs)) - (EL 5 bs)) - (EL 4 bs)) - (EL 3 bs)) - (EL 2 bs)) - (EL 1 bs)) - (EL 0 bs)`;; + word_join + (word_join + (word_join (word_join (EL 15 bs) (EL 14 bs) : int16) (word_join (EL 13 bs) (EL 12 bs) : int16) : int32) + (word_join (word_join (EL 11 bs) (EL 10 bs) : int16) (word_join (EL 9 bs) (EL 8 bs) : int16) : int32) : int64) + (word_join + (word_join (word_join (EL 7 bs) (EL 6 bs) : int16) (word_join (EL 5 bs) (EL 4 bs) : int16) : int32) + (word_join (word_join (EL 3 bs) (EL 2 bs) : int16) (word_join (EL 1 bs) (EL 0 bs) : int16) : int32) : int64)`;; let int128_to_bytes = define `int128_to_bytes (w : int128) : byte list = From be9b78d0664380726ad53f7e151be4059430f3c1 Mon Sep 17 00:00:00 2001 From: Nevine Ebeid Date: Wed, 8 Oct 2025 10:32:12 -0400 Subject: [PATCH 070/132] WIP: subgoal 3 of the loop invariant. --- arm/proofs/aes-xts-armv8.ml | 164 +++++++++++++++++++++++++++++++++++- 1 file changed, 162 insertions(+), 2 deletions(-) diff --git a/arm/proofs/aes-xts-armv8.ml b/arm/proofs/aes-xts-armv8.ml index dc9d046f6..7b5fd0829 100644 --- a/arm/proofs/aes-xts-armv8.ml +++ b/arm/proofs/aes-xts-armv8.ml @@ -869,6 +869,89 @@ let word_split_lemma = prove( (word_and len (word 0xfffffffffffffff0)) = len`, BITBLAST_TAC);; + +let BYTE_LIST_AT_ADD_ASSUM_TAC new_pos bound = + let rule = subst [new_pos, `new_pos:num`; bound, `bound:num`] + `(pos:num) + bound <= LENGTH (bl:byte list) ==> new_pos < LENGTH bl` in + let p = subst [new_pos, `new_pos:num`] `new_pos:num` in + MP_TAC (ARITH_RULE rule) THEN + ASM_REWRITE_TAC[] THEN DISCH_THEN (LABEL_TAC "tmp") THEN + FIRST_ASSUM(fun th -> MP_TAC(SPEC p th)) THEN + USE_THEN "tmp" (fun th -> REWRITE_TAC[th]) THEN + POP_ASSUM (K ALL_TAC);; + +let WORD_JOIN_16_8_ASSOC = WORD_BLAST + `!(x0:byte) (x1:byte) (x2:byte) (x3:byte) + (x4:byte) (x5:byte) (x6:byte) (x7:byte) + (x8:byte) (x9:byte) (x10:byte) (x11:byte) + (x12:byte) (x13:byte) (x14:byte) (x15:byte). + (word_join + (word_join + (word_join (word_join x15 x14 : int16) (word_join x13 x12 : int16) : int32) + (word_join (word_join x11 x10 : int16) (word_join x9 x8 : int16) : int32) : int64) + (word_join + (word_join (word_join x7 x6 : int16) (word_join x5 x4 : int16) : int32) + (word_join (word_join x3 x2 : int16) (word_join x1 x0 : int16) : int32) : int64)) = + (word_join + (word_join + (word_join + (word_join + (word_join + (word_join + (word_join + (word_join + (word_join + (word_join + (word_join + (word_join + (word_join + (word_join + (word_join x15 x14:16 word) + x13:24 word) + x12:32 word) + x11:40 word) + x10:48 word) + x9:56 word) + x8:64 word) + x7:72 word) + x6:80 word) + x5:88 word) + x4:96 word) + x3:104 word) + x2:112 word) + x1:120 word) + x0:128 word)`;; + +let BYTES128_TO_BYTES8_THM = prove( + `!pos bl_ptr s. + read (memory :> bytes128 (word_add bl_ptr (word pos))) s = + bytes_to_int128 + [read (memory :> bytes8 (word_add bl_ptr (word (pos + 0x0)))) s; + read (memory :> bytes8 (word_add bl_ptr (word (pos + 0x1)))) s; + read (memory :> bytes8 (word_add bl_ptr (word (pos + 0x2)))) s; + read (memory :> bytes8 (word_add bl_ptr (word (pos + 0x3)))) s; + read (memory :> bytes8 (word_add bl_ptr (word (pos + 0x4)))) s; + read (memory :> bytes8 (word_add bl_ptr (word (pos + 0x5)))) s; + read (memory :> bytes8 (word_add bl_ptr (word (pos + 0x6)))) s; + read (memory :> bytes8 (word_add bl_ptr (word (pos + 0x7)))) s; + read (memory :> bytes8 (word_add bl_ptr (word (pos + 0x8)))) s; + read (memory :> bytes8 (word_add bl_ptr (word (pos + 0x9)))) s; + read (memory :> bytes8 (word_add bl_ptr (word (pos + 0xa)))) s; + read (memory :> bytes8 (word_add bl_ptr (word (pos + 0xb)))) s; + read (memory :> bytes8 (word_add bl_ptr (word (pos + 0xc)))) s; + read (memory :> bytes8 (word_add bl_ptr (word (pos + 0xd)))) s; + read (memory :> bytes8 (word_add bl_ptr (word (pos + 0xe)))) s; + read (memory :> bytes8 (word_add bl_ptr (word (pos + 0xf)))) s]`, + REPEAT STRIP_TAC THEN + REWRITE_TAC[bytes_to_int128] THEN + REWRITE_TAC EL_16_8_CLAUSES THEN + GEN_REWRITE_TAC TOP_DEPTH_CONV [READ_MEMORY_BYTESIZED_SPLIT; WORD_ADD_ASSOC_CONSTS] THEN + CONV_TAC(DEPTH_CONV WORD_NUM_RED_CONV) THEN + ONCE_REWRITE_TAC [ARITH_RULE `pos + 0 = (pos:num)`] THEN + REFL_TAC +);; + +(* Different from decrypt in using len_full_blocks *) let LEN_FULL_BLOCKS_LO_BOUND_THM = prove( `!(len:int64) len_full_blocks. word_and len (word 0xfffffffffffffff0) = len_full_blocks ==> ~(val len < 0x50) @@ -881,11 +964,17 @@ let LEN_FULL_BLOCKS_HI_BOUND_THM = prove( ==> val len_full_blocks <= 2 EXP 24`, BITBLAST_TAC);; +let LEN_FULL_BLOCKS_LT_LEN_THM = prove( + `!(len:int64). val (word_and len (word 0xfffffffffffffff0)) <= val len`, + BITBLAST_TAC +);; + let TAIL_LEN_BOUND_THM = prove( `!(len:int64) tail_len. word_and len (word 0xf) = tail_len ==> val tail_len < 0x10`, BITBLAST_TAC);; +(* Different from decrypt in using num_5blocks *) let NUM_5BLOCKS_LO_BOUND_THM = prove( `!(len_full_blocks:int64) (num_5blocks:int64). val len_full_blocks <= 2 EXP 24 @@ -903,6 +992,7 @@ let NUM_5BLOCKS_LO_BOUND_THM = prove( ARITH_TAC );; + let TWEAK_UPDATE_CONV = let ADD_SUC_1 = ARITH_RULE `!n. n + 1 = SUC(n)` in let ADD_SUC_2 = ARITH_RULE `!n. n + 2 = SUC(n + 1)` in @@ -966,6 +1056,32 @@ let TWEAK_TAC reg ind indm1 = DISCH_TAC THEN ASM_REWRITE_TAC[] THEN AP_TERM_TAC THEN ASM_ARITH_TAC);; +(* Copied from Decrypt proof because it will be instantiated for ptxt_p *) +let READ_CT_LEMMA = prove( + `!ct_ptr i (len:int64) (ct:byte list) s. + (forall j. j < val len ==> read (memory :> bytes8 (word_add ct_ptr (word j))) s = EL j ct) + /\ i * 0x50 + 0x50 <= val len + /\ LENGTH ct = val len + ==> + read (memory :> bytes128 (word_add ct_ptr (word_mul (word 0x50) (word i)))) s = + bytes_to_int128 (SUB_LIST (i * 80, 16) ct) /\ + read (memory :> bytes128 (word_add (word_add ct_ptr (word_mul (word 0x50) (word i))) (word 0x10))) s = + bytes_to_int128 (SUB_LIST (i * 80 + 16, 16) ct) /\ + read (memory :> bytes128 (word_add (word_add ct_ptr (word_mul (word 0x50) (word i))) (word 0x20))) s = + bytes_to_int128 (SUB_LIST (i * 80 + 32, 16) ct) /\ + read (memory :> bytes128 (word_add (word_add ct_ptr (word_mul (word 0x50) (word i))) (word 0x30))) s = + bytes_to_int128 (SUB_LIST (i * 80 + 48, 16) ct) /\ + read (memory :> bytes128 (word_add (word_add ct_ptr (word_mul (word 0x50) (word i))) (word 0x40))) s = + bytes_to_int128 (SUB_LIST (i * 80 + 64, 16) ct) + `, + REPEAT GEN_TAC THEN STRIP_TAC THEN + REWRITE_TAC [WORD_RULE `word_mul (word 0x50) (word i) = word (i * 80)`] THEN + MP_TAC + (SPECL [`(i * 80):num`; `ct:byte list`; `ct_ptr:int64`; `len:int64`; `s:armstate`] + BYTE_LIST_AT_5BLOCKS) THEN + REWRITE_TAC[byte_list_at] THEN ASM_SIMP_TAC[] +);; + (* void aes_hw_xts_encrypt(const uint8_t *in, uint8_t *out, size_t length, const AES_KEY *key1, const AES_KEY *key2, @@ -1006,7 +1122,7 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( ) (MAYCHANGE [PC;X0;X1;X2;X4;X6;X7;X8;X9;X10;X11;X19;X20;X21;X22],, MAYCHANGE [Q0;Q1;Q4;Q5;Q6;Q7;Q8;Q9;Q10;Q11;Q12;Q13;Q14;Q15;Q16;Q17;Q18;Q19;Q20;Q21;Q22;Q23;Q24;Q25;Q26],, - MAYCHANGE SOME_FLAGS,, MAYCHANGE [memory :> bytes128 ctxt_p],, + MAYCHANGE SOME_FLAGS,, MAYCHANGE [memory :> bytes(ctxt_p, val len)],, MAYCHANGE [events])`, REWRITE_TAC [(REWRITE_CONV [aes256_xts_encrypt_mc] THENC LENGTH_CONV) `LENGTH aes256_xts_encrypt_mc`] THEN @@ -1230,7 +1346,51 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( CONV_TAC NUM_REDUCE_CONV; CONV_TAC NUM_REDUCE_CONV; CONV_TAC NUM_REDUCE_CONV; - ASM_REWRITE_TAC[] ] + CONV_TAC NUM_REDUCE_CONV THEN REWRITE_TAC[VAL_WORD_0] THEN ARITH_TAC ] + + (* Subgoal 3: loop body *) + REPEAT STRIP_TAC THEN + + SUBGOAL_THEN `i * 0x50 + 0x50 <= val (len:int64)` ASSUME_TAC THENL + [ + SUBGOAL_THEN `i + 1 <= val (num_5blocks:int64)` MP_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC ] THEN + SUBGOAL_THEN `val (len_full_blocks:int64) <= val (len:int64)` ASSUME_TAC THENL + [ EXPAND_TAC "len_full_blocks" THEN SIMP_TAC[LEN_FULL_BLOCKS_LT_LEN_THM] ] + SUBGOAL_THEN `val (num_5blocks:int64) * 0x50 <= val (len:int64)` ASSUME_TAC THENL + [ EXPAND_TAC "num_5blocks" THEN + REWRITE_TAC [VAL_WORD; DIMINDEX_64] THEN + UNDISCH_TAC `val (len_full_blocks:int64) <= val (len:int64)` THEN + ARITH_TAC; ALL_TAC ] + SUBGOAL_THEN `(i + 1) * 0x50 <= val (len:int64)` MP_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC ] THEN + ARITH_TAC; ALL_TAC + ] + + MATCH_MP_TAC ENSURES_FRAME_SUBSUMED THEN + EXISTS_TAC `MAYCHANGE + [PC; X0; X1; X2; X4; X6; X7; X8; X9; X10; X11; X19; X20; X21; X22] ,, + MAYCHANGE [Q0; Q1; Q4; Q5; Q6; Q7; Q8; Q9; Q10; Q11; Q12; Q13; Q14; Q15; Q16; Q17; + Q18; Q19; Q20; Q21; Q22; Q23; Q24; Q25; Q26] ,, + MAYCHANGE [NF; ZF; CF; VF] ,, + MAYCHANGE [memory :> bytes128 (word_add ctxt_p (word (0x50 * i))); + memory :> bytes128 (word_add ctxt_p (word (0x50 * i + 0x10))); + memory :> bytes128 (word_add ctxt_p (word (0x50 * i + 0x20))); + memory :> bytes128 (word_add ctxt_p (word (0x50 * i + 0x30))); + memory :> bytes128 (word_add ctxt_p (word (0x50 * i + 0x40)))],, + MAYCHANGE [events]` THEN + CONJ_TAC THENL[ + REPEAT (GEN_REWRITE_TAC ONCE_DEPTH_CONV [GSYM SEQ_ASSOC] THEN + MATCH_MP_TAC SUBSUMED_SEQ THEN REWRITE_TAC[SUBSUMED_REFL]) THEN + (* see https://hol-light.zulipchat.com/#narrow/channel/474190-s2n-bignum/topic/.E2.9C.94.20SUBSUMED_MAYCHANGE.20proof/near/541307474 *) + ABBREV_TAC `vallen = val (len:int64)` THEN + SUBSUMED_MAYCHANGE_TAC; ALL_TAC] THEN + ] + + (* ===> Symbolic Simulation: Start symbolic simulation*) + ASM_REWRITE_TAC[byte_list_at] THEN + ENSURES_INIT_TAC "s0" THEN + ] (* From fd5608aa67d70f3ad0ec45a876baecf78691f816 Mon Sep 17 00:00:00 2001 From: Nevine Ebeid Date: Fri, 10 Oct 2025 18:21:52 -0400 Subject: [PATCH 071/132] WIP: subgoal 3 of the loop invariant, arrived at the inductive step. --- arm/proofs/aes-xts-armv8.ml | 316 +++++++++++++++++++++++++----------- 1 file changed, 218 insertions(+), 98 deletions(-) diff --git a/arm/proofs/aes-xts-armv8.ml b/arm/proofs/aes-xts-armv8.ml index 7b5fd0829..2cbaf1578 100644 --- a/arm/proofs/aes-xts-armv8.ml +++ b/arm/proofs/aes-xts-armv8.ml @@ -118,6 +118,9 @@ let aes256_xts_encrypt_mc = define_assert_from_elf "aes256_xts_encrypt_mc" "arm/ 0xf29999a8; (* arm_MOVK X8 (word 0xcccd) 0x0 *) 0x9bc87c48; (* arm_UMULH X8 X2 X8 *) 0xd346fd08; (* arm_LSR X8 X8 0x6 *) + + (* .Loop5x_xts_enc: *) + (* pc + 0x140 *) 0xacc28400; (* arm_LDP Q0 Q1 X0 (Postimmediate_Offset (iword (&0x50))) *) 0xad7ee418; (* arm_LDP Q24 Q25 X0 (Immediate_Offset (iword (-- &0x30))) *) 0x3cdf001a; (* arm_LDR Q26 X0 (Immediate_Offset (word 0xfffffffffffffff0)) *) @@ -307,6 +310,8 @@ let aes256_xts_encrypt_mc = define_assert_from_elf "aes256_xts_encrypt_mc" "arm/ 0xd1014042; (* arm_SUB X2 X2 (rvalue (word 0x50)) *) 0xf1000508; (* arm_SUBS X8 X8 (rvalue (word 0x1)) *) 0xb5ffe888; (* arm_CBNZ X8 (word 0x1ffd10) *) + + (* .Loop5x_enc_after: *) 0xf101005f; (* arm_CMP X2 (rvalue (word 0x40)) *) 0x54000140; (* arm_BEQ (word 0x28) *) 0xf100c05f; (* arm_CMP X2 (rvalue (word 0x30)) *) @@ -869,7 +874,6 @@ let word_split_lemma = prove( (word_and len (word 0xfffffffffffffff0)) = len`, BITBLAST_TAC);; - let BYTE_LIST_AT_ADD_ASSUM_TAC new_pos bound = let rule = subst [new_pos, `new_pos:num`; bound, `bound:num`] `(pos:num) + bound <= LENGTH (bl:byte list) ==> new_pos < LENGTH bl` in @@ -880,6 +884,7 @@ let BYTE_LIST_AT_ADD_ASSUM_TAC new_pos bound = USE_THEN "tmp" (fun th -> REWRITE_TAC[th]) THEN POP_ASSUM (K ALL_TAC);; +(* is this needed? *) let WORD_JOIN_16_8_ASSOC = WORD_BLAST `!(x0:byte) (x1:byte) (x2:byte) (x3:byte) (x4:byte) (x5:byte) (x6:byte) (x7:byte) @@ -951,6 +956,112 @@ let BYTES128_TO_BYTES8_THM = prove( REFL_TAC );; +let SUB_LIST_SUCSPLIT = prove( + `!(l:A list) n p. SUB_LIST(p,SUC n) l = APPEND (SUB_LIST(p,1) l) (SUB_LIST(p+1,n) l)`, + REPEAT STRIP_TAC THEN + REWRITE_TAC [ARITH_RULE `SUC n = 1 + n`] THEN + REWRITE_TAC [SUB_LIST_SPLIT] +);; + +let SUB_LIST_16_TAC n exp = + let subgoal = subst [exp, `exp:num`] `exp < LENGTH (l:A list)` in + CONV_TAC(RAND_CONV (REWRITE_CONV[num_CONV n; SUB_LIST_SUCSPLIT])) THEN + SUBGOAL_THEN subgoal ASSUME_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN + REWRITE_TAC[SUB_LIST_1] THEN ASM_SIMP_TAC[GSYM ADD_ASSOC] THEN NUM_REDUCE_TAC;; + +let SUB_LIST_16 = prove( + `!(l:A list) n. n + 16 <= LENGTH l ==> + [ EL (n + 0) l; EL (n + 1) l; EL (n + 2) l; EL (n + 3) l; + EL (n + 4) l; EL (n + 5) l; EL (n + 6) l; EL (n + 7) l; + EL (n + 8) l; EL (n + 9) l; EL (n + 10) l; EL (n + 11) l; + EL (n + 12) l; EL (n + 13) l; EL (n + 14) l; EL (n + 15) l + ] = SUB_LIST (n,16) l`, + REPEAT STRIP_TAC THEN + MAP_EVERY (fun i -> + if i == 0 + then SUB_LIST_16_TAC `0x10` `n:num` + else SUB_LIST_16_TAC (mk_numeral (num (16 - i))) + (mk_binop (mk_const("+", [`:num`, `:A`])) (mk_var("n", `:num`)) + (mk_numeral (num i)))) (0--14) THEN + SUBGOAL_THEN `n + 15 < LENGTH (l:A list)` ASSUME_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[APPEND; ARITH_RULE `n + 0 = n`] +);; + +let BYTE_LIST_AT_5BLOCKS = prove( + `! pos bl bl_ptr len s. + byte_list_at bl bl_ptr len s + ==> LENGTH bl = val len + ==> pos + 0x50 <= LENGTH bl + ==> (read (memory :> bytes128 (word_add bl_ptr (word pos))) s = + bytes_to_int128 (SUB_LIST (pos, 0x10) bl) /\ + read (memory :> bytes128 (word_add (word_add bl_ptr (word pos)) (word 0x10))) s = + bytes_to_int128 (SUB_LIST (pos + 0x10, 0x10) bl) /\ + read (memory :> bytes128 (word_add (word_add bl_ptr (word pos)) (word 0x20))) s = + bytes_to_int128 (SUB_LIST (pos + 0x20, 0x10) bl) /\ + read (memory :> bytes128 (word_add (word_add bl_ptr (word pos)) (word 0x30))) s = + bytes_to_int128 (SUB_LIST (pos + 0x30, 0x10) bl) /\ + read (memory :> bytes128 (word_add (word_add bl_ptr (word pos)) (word 0x40))) s = + bytes_to_int128 (SUB_LIST (pos + 0x40, 0x10) bl))`, + REWRITE_TAC[byte_list_at] THEN + REPEAT STRIP_TAC THENL + [ (* Subgoal1 *) + MAP_EVERY (fun i -> BYTE_LIST_AT_ADD_ASSUM_TAC + (mk_binop (mk_const("+", [`:num`, `:A`])) (mk_var("pos", `:num`)) + (mk_numeral (num i))) `0x50`) (0--15) THEN + REWRITE_TAC[WORD_ADD_ASSOC_CONSTS] THEN + REPEAT STRIP_TAC THEN + ASM_REWRITE_TAC[BYTES128_TO_BYTES8_THM; GSYM ADD_ASSOC] THEN + NUM_REDUCE_TAC THEN ASM_REWRITE_TAC[] THEN AP_TERM_TAC THEN + MP_TAC (ISPECL [`bl:byte list`; `pos:num`] SUB_LIST_16) THEN + REWRITE_TAC[GSYM ADD_ASSOC] THEN NUM_REDUCE_TAC THEN + DISCH_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_ARITH_TAC; + (* Subgoal2 *) + MAP_EVERY (fun i -> BYTE_LIST_AT_ADD_ASSUM_TAC + (mk_binop (mk_const("+", [`:num`, `:A`])) (mk_var("pos", `:num`)) + (mk_numeral (num i))) `0x50`) (16--31) THEN + REWRITE_TAC[WORD_ADD_ASSOC_CONSTS] THEN + REPEAT STRIP_TAC THEN + ASM_REWRITE_TAC[BYTES128_TO_BYTES8_THM; GSYM ADD_ASSOC] THEN + NUM_REDUCE_TAC THEN ASM_REWRITE_TAC[] THEN AP_TERM_TAC THEN + MP_TAC (ISPECL [`bl:byte list`; `(pos+0x10):num`] SUB_LIST_16) THEN + REWRITE_TAC[GSYM ADD_ASSOC] THEN NUM_REDUCE_TAC THEN + DISCH_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_ARITH_TAC; + (* Subgoal3 *) + MAP_EVERY (fun i -> BYTE_LIST_AT_ADD_ASSUM_TAC + (mk_binop (mk_const("+", [`:num`, `:A`])) (mk_var("pos", `:num`)) + (mk_numeral (num i))) `0x50`) (32--47) THEN + REWRITE_TAC[WORD_ADD_ASSOC_CONSTS] THEN + REPEAT STRIP_TAC THEN + ASM_REWRITE_TAC[BYTES128_TO_BYTES8_THM; GSYM ADD_ASSOC] THEN + NUM_REDUCE_TAC THEN ASM_REWRITE_TAC[] THEN AP_TERM_TAC THEN + MP_TAC (ISPECL [`bl:byte list`; `(pos+0x20):num`] SUB_LIST_16) THEN + REWRITE_TAC[GSYM ADD_ASSOC] THEN NUM_REDUCE_TAC THEN + DISCH_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_ARITH_TAC; + (* Subgoal4 *) + MAP_EVERY (fun i -> BYTE_LIST_AT_ADD_ASSUM_TAC + (mk_binop (mk_const("+", [`:num`, `:A`])) (mk_var("pos", `:num`)) + (mk_numeral (num i))) `0x50`) (48--63) THEN + REWRITE_TAC[WORD_ADD_ASSOC_CONSTS] THEN + REPEAT STRIP_TAC THEN + ASM_REWRITE_TAC[BYTES128_TO_BYTES8_THM; GSYM ADD_ASSOC] THEN + NUM_REDUCE_TAC THEN ASM_REWRITE_TAC[] THEN AP_TERM_TAC THEN + MP_TAC (ISPECL [`bl:byte list`; `(pos+0x30):num`] SUB_LIST_16) THEN + REWRITE_TAC[GSYM ADD_ASSOC] THEN NUM_REDUCE_TAC THEN + DISCH_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_ARITH_TAC; + (* Subgoal 5 *) + MAP_EVERY (fun i -> BYTE_LIST_AT_ADD_ASSUM_TAC + (mk_binop (mk_const("+", [`:num`, `:A`])) (mk_var("pos", `:num`)) + (mk_numeral (num i))) `0x50`) (64--79) THEN + REWRITE_TAC[WORD_ADD_ASSOC_CONSTS] THEN + REPEAT STRIP_TAC THEN + ASM_REWRITE_TAC[BYTES128_TO_BYTES8_THM; GSYM ADD_ASSOC] THEN + NUM_REDUCE_TAC THEN ASM_REWRITE_TAC[] THEN AP_TERM_TAC THEN + MP_TAC (ISPECL [`bl:byte list`; `(pos+0x40):num`] SUB_LIST_16) THEN + REWRITE_TAC[GSYM ADD_ASSOC] THEN NUM_REDUCE_TAC THEN + DISCH_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_ARITH_TAC + ] +);; + (* Different from decrypt in using len_full_blocks *) let LEN_FULL_BLOCKS_LO_BOUND_THM = prove( `!(len:int64) len_full_blocks. word_and len (word 0xfffffffffffffff0) = len_full_blocks @@ -992,7 +1103,6 @@ let NUM_5BLOCKS_LO_BOUND_THM = prove( ARITH_TAC );; - let TWEAK_UPDATE_CONV = let ADD_SUC_1 = ARITH_RULE `!n. n + 1 = SUC(n)` in let ADD_SUC_2 = ARITH_RULE `!n. n + 2 = SUC(n + 1)` in @@ -1041,6 +1151,25 @@ let TWEAK_TAC reg ind indm1 = ABBREV_TAC abbrev_term THEN BITBLAST_TAC; DISCH_TAC];; +let XTSENC_TAC reg ind ind_tweak = + let tm = subst [ind, `ind:num`; ind_tweak, `ind_tweak:num`] + `aes256_xts_encrypt_round (bytes_to_int128 (SUB_LIST (ind,0x10) (pt_in:byte list))) + (calculate_tweak (ind_tweak) iv key2_lst) key1_lst` in + let lemma = subst [reg, `reg:(armstate,int128)component`] + `read (reg:(armstate,int128)component) (s:armstate) = a ==> !a'. a = a' ==> read reg s = a'` in + let _ = print_term tm in + let _ = print_term lemma in + FIRST_X_ASSUM(MP_TAC o SPEC tm o MATCH_MP (MESON[] lemma)) THEN + ANTS_TAC THENL + [ EXPAND_TAC "key1_lst" THEN + CONV_TAC (RAND_CONV ( + REWRITE_CONV [aes256_xts_encrypt_round] THENC + DEPTH_CONV let_CONV)) THEN + GEN_REWRITE_TAC LAND_CONV [WORD_XOR_SYM] THEN + REPEAT (AP_THM_TAC THEN AP_TERM_TAC) THEN + GEN_REWRITE_TAC ONCE_DEPTH_CONV [WORD_XOR_SYM] THEN + AESENC_TAC; DISCH_TAC ];; + let UDIV_OPT_THM = prove(`!n:num. n < 0x2 EXP 0x40 ==> (word (val ((word ((n * 0xcccccccccccccccd) DIV 0x2 EXP 0x40)):int64) DIV 0x2 EXP 0x6)):int64 = word (n DIV 0x50)`, REPEAT STRIP_TAC THEN @@ -1056,7 +1185,7 @@ let TWEAK_TAC reg ind indm1 = DISCH_TAC THEN ASM_REWRITE_TAC[] THEN AP_TERM_TAC THEN ASM_ARITH_TAC);; -(* Copied from Decrypt proof because it will be instantiated for ptxt_p *) +(* Copied from Decrypt proof without change because it can be instantiated for ptxt_p *) let READ_CT_LEMMA = prove( `!ct_ptr i (len:int64) (ct:byte list) s. (forall j. j < val len ==> read (memory :> bytes8 (word_add ct_ptr (word j))) s = EL j ct) @@ -1098,6 +1227,7 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( PAIRWISE nonoverlapping [(stackpointer, 6*16); (word pc, LENGTH aes256_xts_encrypt_mc); + (ptxt_p, val len); (ctxt_p, val len); (key1_p, 244); (key2_p, 244)] /\ @@ -1346,7 +1476,7 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( CONV_TAC NUM_REDUCE_CONV; CONV_TAC NUM_REDUCE_CONV; CONV_TAC NUM_REDUCE_CONV; - CONV_TAC NUM_REDUCE_CONV THEN REWRITE_TAC[VAL_WORD_0] THEN ARITH_TAC ] + CONV_TAC NUM_REDUCE_CONV THEN REWRITE_TAC[VAL_WORD_0] THEN ARITH_TAC ]; (* Subgoal 3: loop body *) REPEAT STRIP_TAC THEN @@ -1356,16 +1486,16 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( SUBGOAL_THEN `i + 1 <= val (num_5blocks:int64)` MP_TAC THENL [ ASM_ARITH_TAC; ALL_TAC ] THEN SUBGOAL_THEN `val (len_full_blocks:int64) <= val (len:int64)` ASSUME_TAC THENL - [ EXPAND_TAC "len_full_blocks" THEN SIMP_TAC[LEN_FULL_BLOCKS_LT_LEN_THM] ] + [ EXPAND_TAC "len_full_blocks" THEN SIMP_TAC[LEN_FULL_BLOCKS_LT_LEN_THM]; ALL_TAC ] THEN SUBGOAL_THEN `val (num_5blocks:int64) * 0x50 <= val (len:int64)` ASSUME_TAC THENL [ EXPAND_TAC "num_5blocks" THEN REWRITE_TAC [VAL_WORD; DIMINDEX_64] THEN UNDISCH_TAC `val (len_full_blocks:int64) <= val (len:int64)` THEN - ARITH_TAC; ALL_TAC ] + ARITH_TAC; ALL_TAC ] THEN SUBGOAL_THEN `(i + 1) * 0x50 <= val (len:int64)` MP_TAC THENL [ ASM_ARITH_TAC; ALL_TAC ] THEN ARITH_TAC; ALL_TAC - ] + ] THEN MATCH_MP_TAC ENSURES_FRAME_SUBSUMED THEN EXISTS_TAC `MAYCHANGE @@ -1384,100 +1514,90 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( MATCH_MP_TAC SUBSUMED_SEQ THEN REWRITE_TAC[SUBSUMED_REFL]) THEN (* see https://hol-light.zulipchat.com/#narrow/channel/474190-s2n-bignum/topic/.E2.9C.94.20SUBSUMED_MAYCHANGE.20proof/near/541307474 *) ABBREV_TAC `vallen = val (len:int64)` THEN - SUBSUMED_MAYCHANGE_TAC; ALL_TAC] THEN - ] + SUBSUMED_MAYCHANGE_TAC; ALL_TAC + ] THEN (* ===> Symbolic Simulation: Start symbolic simulation*) ASM_REWRITE_TAC[byte_list_at] THEN ENSURES_INIT_TAC "s0" THEN - ] + (* List values for ptxt_p + [0 .. 0x40] *) + MP_TAC (SPECL [`ptxt_p:int64`; `i:num`; `len:int64`; `pt_in:byte list`; `s0:armstate`] READ_CT_LEMMA) THEN + ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN + (* Prove Q0, Q1, Q24, Q25, Q26 stores correct plaintext *) + (* and prove Q6, Q8, Q9, Q10, Q11 stores correct tweak: *) + (* Run simulation until after every ciphertext block and new tweak are calculated + and prove they're correct in their registers *) + ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (1--151) THEN + XTSENC_TAC `Q0:(armstate,int128)component` `i * 0x50` `i * 0x5` THEN + TWEAK_TAC `Q6:(armstate,int128)component` `i * 5 + 5` `i * 5 + 4` THEN + + ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (152--159) THEN + XTSENC_TAC `Q1:(armstate,int128)component` `i * 0x50 + 0x10` `i * 0x5 + 0x1` THEN + TWEAK_TAC `Q8:(armstate,int128)component` `i * 5 + 6` `i * 5 + 5` THEN + + ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (160--167) THEN + XTSENC_TAC `Q24:(armstate,int128)component` `i * 0x50 + 0x20` `i * 0x5 + 0x2` THEN + TWEAK_TAC `Q9:(armstate,int128)component` `i * 5 + 7` `i * 5 + 6` THEN + + ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (168--175) THEN + XTSENC_TAC `Q25:(armstate,int128)component` `i * 0x50 + 0x30` `i * 0x5 + 0x3` THEN + TWEAK_TAC `Q10:(armstate,int128)component` `i * 5 + 8` `i * 5 + 7` THEN + + ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (176--183) THEN + XTSENC_TAC `Q26:(armstate,int128)component` `i * 0x50 + 0x40` `i * 0x5 + 0x4` THEN + TWEAK_TAC `Q11:(armstate,int128)component` `i * 5 + 9` `i * 5 + 8` THEN + + (* The following lemmas are for NONSELFMODIFYING_STATE_UPDATE_TAC when store back to pt_ptr, + and for the MAYCHANGE clauses *) + RULE_ASSUM_TAC(REWRITE_RULE + [WORD_RULE `word_mul (word 0x50) (word i):int64 = word(0x50 * i)`]) THEN + + (* Rewrite to help reasoning about nonoverlapping + so that the universally quantified assumption stays. + See: https://hol-light.zulipchat.com/#narrow/channel/474190-s2n-bignum/topic/.E2.9C.94.20Symbolic.20simulation.20removed.20assumption/with/541554894 *) + SUBGOAL_THEN `val ((word (i * 0x50)):int64) = 0x50 * i` MP_TAC THENL [ + IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN ASM_ARITH_TAC; ALL_TAC] THEN + DISCH_THEN(RULE_ASSUM_TAC o REWRITE_RULE o CONJUNCTS) THEN + + (* Simulate until end of loop *) + ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (184--188) THEN + ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN + REPEAT CONJ_TAC THENL + [ REWRITE_TAC[WORD_RULE `word_mul (word 0x50) (word (i + 1)):int64 = word_add (word(0x50 * i)) (word 0x50)`] THEN + REWRITE_TAC[WORD_ADD_ASSOC]; + REWRITE_TAC[WORD_RULE `word_mul (word 0x50) (word (i + 1)):int64 = word_add (word(0x50 * i)) (word 0x50)`] THEN + REWRITE_TAC[WORD_ADD_ASSOC]; + REWRITE_TAC[WORD_RULE `word_mul (word 0x50) (word (i + 1)):int64 = word_add (word(0x50 * i)) (word 0x50)`] THEN + REWRITE_TAC[WORD_ADD_ASSOC]; + CONV_TAC WORD_RULE; + CONV_TAC WORD_RULE; + REWRITE_TAC[WORD_RULE `(i + 0x1) * 0x5 + 0x4 = i * 0x5 + 0x9`]; + REWRITE_TAC[WORD_RULE `(i + 0x1) * 0x5 + 0x4 = i * 0x5 + 0x9`]; + REWRITE_TAC[WORD_RULE `(i + 0x1) * 0x5 = i * 0x5 + 0x5`]; + REWRITE_TAC[WORD_RULE `(i + 0x1) * 0x5 + 0x1 = i * 0x5 + 0x6`]; + REWRITE_TAC[WORD_RULE `(i + 0x1) * 0x5 + 0x2 = i * 0x5 + 0x7`]; + REWRITE_TAC[WORD_RULE `(i + 0x1) * 0x5 + 0x3 = i * 0x5 + 0x8`]; + REWRITE_TAC[WORD_RULE `(i + 0x1) * 0x5 + 0x4 = i * 0x5 + 0x9`]; + + (* The following is the main proof for inductive step *) + REWRITE_TAC[ARITH_RULE `(i + 0x1) * 0x50 = 0x50 * i + 0x50`] THEN + SUBGOAL_THEN `val ((word (0x50 * i + 0x50)):int64) = 0x50 * i + 0x50` ASSUME_TAC THENL [ + IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN + UNDISCH_TAC `i * 0x50 + 0x50 <= val (len:int64)` THEN + UNDISCH_TAC `val (len:int64) <= 2 EXP 24` THEN + ARITH_TAC; ALL_TAC] THEN + ASM_REWRITE_TAC[] THEN -(* -# e(CONV_TAC NUM_REDUCE_CONV);; -val it : goalstack = 1 subgoal (4 total) - - 0 [`aligned 0x10 stackpointer`] - 1 [`nonoverlapping_modulo (0x2 EXP 0x40) (val stackpointer,0x6 * 0x10) - (pc,0xa80)`] - 2 [`nonoverlapping_modulo (0x2 EXP 0x40) (val stackpointer,0x6 * 0x10) - (val ctxt_p,val len)`] - 3 [`nonoverlapping_modulo (0x2 EXP 0x40) (val stackpointer,0x6 * 0x10) - (val key1_p,0xf4)`] - 4 [`nonoverlapping_modulo (0x2 EXP 0x40) (val stackpointer,0x6 * 0x10) - (val key2_p,0xf4)`] - 5 [`nonoverlapping_modulo (0x2 EXP 0x40) (pc,0xa80) (val ctxt_p,val len)`] - 6 [`nonoverlapping_modulo (0x2 EXP 0x40) (pc,0xa80) (val key1_p,0xf4)`] - 7 [`nonoverlapping_modulo (0x2 EXP 0x40) (pc,0xa80) (val key2_p,0xf4)`] - 8 [`nonoverlapping_modulo (0x2 EXP 0x40) (val ctxt_p,val len) - (val key1_p,0xf4)`] - 9 [`nonoverlapping_modulo (0x2 EXP 0x40) (val ctxt_p,val len) - (val key2_p,0xf4)`] - 10 [`nonoverlapping_modulo (0x2 EXP 0x40) (val key1_p,0xf4) - (val key2_p,0xf4)`] - 11 [`val len >= 0x10`] - 12 [`val len <= 0x2 EXP 0x18`] - 13 [`LENGTH pt_in = val len`] - 14 [`word_add tail_len len_full_blocks = len`] - 15 [`word_and len (word 0xfffffffffffffff0) = len_full_blocks`] - 16 [`word (val len_full_blocks DIV 0x50) = num_5blocks`] - 17 [`word_and len (word 0xf) = tail_len`] - 18 [`[k1_0; k1_1; k1_2; k1_3; k1_4; k1_5; k1_6; k1_7; k1_8; k1_9; k1_10; - k1_11; k1_12; k1_13; k1_14] = - key1_lst`] - 19 [`[k2_0; k2_1; k2_2; k2_3; k2_4; k2_5; k2_6; k2_7; k2_8; k2_9; k2_10; - k2_11; k2_12; k2_13; k2_14] = - key2_lst`] - 20 [`~(val len < 0x50)`] - 21 [`~(val len_full_blocks < 0x50)`] - 22 [`val len_full_blocks <= 0x2 EXP 0x18`] - 23 [`0x0 < val num_5blocks`] - 24 [`aligned_bytes_loaded s0 (word pc) aes256_xts_encrypt_mc`] - 25 [`read PC s0 = word (pc + 0x140)`] - 26 [`read X0 s0 = ptxt_p`] - 27 [`read X1 s0 = ctxt_p`] - 28 [`read X2 s0 = len_full_blocks`] - 29 [`read X21 s0 = tail_len`] - 30 [`read X8 s0 = num_5blocks`] - 31 [`read X9 s0 = word_zx (calculate_tweak 0x4 iv key2_lst)`] - 32 [`read X10 s0 = - word_subword (calculate_tweak 0x4 iv key2_lst) (0x40,0x40)`] - 33 [`read Q6 s0 = calculate_tweak 0x0 iv key2_lst`] - 34 [`read Q8 s0 = calculate_tweak 0x1 iv key2_lst`] - 35 [`read Q9 s0 = calculate_tweak 0x2 iv key2_lst`] - 36 [`read Q10 s0 = calculate_tweak 0x3 iv key2_lst`] - 37 [`read Q11 s0 = calculate_tweak 0x4 iv key2_lst`] - 38 [`read X19 s0 = word 0x87`] - 39 [`read Q16 s0 = k1_0`] - 40 [`read Q17 s0 = k1_1`] - 41 [`read Q12 s0 = k1_2`] - 42 [`read Q13 s0 = k1_3`] - 43 [`read Q14 s0 = k1_4`] - 44 [`read Q15 s0 = k1_5`] - 45 [`read Q4 s0 = k1_6`] - 46 [`read Q5 s0 = k1_7`] - 47 [`read Q18 s0 = k1_8`] - 48 [`read Q19 s0 = k1_9`] - 49 [`read Q20 s0 = k1_10`] - 50 [`read Q21 s0 = k1_11`] - 51 [`read Q22 s0 = k1_12`] - 52 [`read Q23 s0 = k1_13`] - 53 [`read Q7 s0 = k1_14`] - 54 [`forall i. - i < val len - ==> read (memory :> bytes8 (word_add ptxt_p (word i))) s0 = - EL i pt_in`] - 55 [`forall i. - i < val (word 0x0) - ==> read (memory :> bytes8 (word_add ctxt_p (word i))) s0 = - EL i (aes256_xts_encrypt pt_in 0x0 iv key1_lst key2_lst)`] - 56 [`(MAYCHANGE:((armstate,?275580)component)list->armstate->armstate->bool) - [] - s0 - s0`] - -`forall i. - i < val (word 0x0) - ==> read (memory :> bytes8 (word_add ctxt_p (word i))) s0 = - EL i (aes256_xts_encrypt pt_in 0x0 iv key1_lst key2_lst)` -*) + (* Remove quantifier over reading one byte at a time, i'*) + UNDISCH_TAC + `forall i'. + i' < 0x50 * i + ==> read (memory :> bytes8 (word_add ctxt_p (word i'))) s188 = + EL i' (aes256_xts_encrypt pt_in (i * 0x50) iv key1_lst key2_lst)` THEN + + ] + + + ] +);; From a40790cbe712a46bdfc35d9ca28916ed98ea18f4 Mon Sep 17 00:00:00 2001 From: Nevine Ebeid Date: Thu, 16 Oct 2025 13:58:46 -0400 Subject: [PATCH 072/132] WIP: subgoal 3 of the loop invariant, going through the inductive step. --- arm/proofs/aes-xts-armv8.ml | 844 +++++++++++++++++++++++++++++++----- 1 file changed, 735 insertions(+), 109 deletions(-) diff --git a/arm/proofs/aes-xts-armv8.ml b/arm/proofs/aes-xts-armv8.ml index 2cbaf1578..4c121bf27 100644 --- a/arm/proofs/aes-xts-armv8.ml +++ b/arm/proofs/aes-xts-armv8.ml @@ -763,6 +763,73 @@ let AESXTS_ENC_ONE_BLOCK_TAC = REPEAT (AP_THM_TAC THEN AP_TERM_TAC) THEN BITBLAST_TAC;; +let TWEAK_UPDATE_CONV = + let ADD_SUC_1 = ARITH_RULE `!n. n + 1 = SUC(n)` in + let ADD_SUC_2 = ARITH_RULE `!n. n + 2 = SUC(n + 1)` in + let ADD_SUC_3 = ARITH_RULE `!n. n + 3 = SUC(n + 2)` in + let ADD_SUC_4 = ARITH_RULE `!n. n + 4 = SUC(n + 3)` in + let ADD_SUC_5 = ARITH_RULE `!n. n + 5 = SUC(n + 4)` in + let ADD_SUC_6 = ARITH_RULE `!n. n + 6 = SUC(n + 5)` in + let ADD_SUC_7 = ARITH_RULE `!n. n + 7 = SUC(n + 6)` in + let ADD_SUC_8 = ARITH_RULE `!n. n + 8 = SUC(n + 7)` in + let ADD_SUC_9 = ARITH_RULE `!n. n + 9 = SUC(n + 8)` in + NUM_REDUCE_CONV THENC + RATOR_CONV (LAND_CONV (num_CONV ORELSEC + FIRST_CONV + [ CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_1]); + CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_2]); + CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_3]); + CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_4]); + CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_5]); + CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_6]); + CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_7]); + CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_8]); + CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_9]);])) THENC + REWRITE_CONV [CONJUNCT2 calculate_tweak] THENC + GF_128_MULT_BY_PRIMITIVE_CONV;; + +(* differs from the Decrypt definition in using key2_lst instead of key2 *) +let TWEAK_TAC reg ind indm1 = + let lower_term = subst [ind,`ind:num`] `(word_zx:int128->int64) (calculate_tweak ind iv key2_lst)` in + let upper_term = subst [ind,`ind:num`] `(word_subword:int128->num#num->int64) (calculate_tweak ind iv key2_lst) (64,64)` in + let full_term = subst [ind,`ind:num`] `calculate_tweak ind iv key2_lst` in + let full_lemma = subst [reg,`reg:(armstate,int128)component`] `read (reg:(armstate,int128)component) (s:armstate) = a ==> !a'. a = a' ==> read reg s = a'` in + let abbrev_term = subst [indm1,`indm1:num`] `tweak_pre:int128 = (calculate_tweak indm1 iv key2_lst)` in + FIRST_X_ASSUM(MP_TAC o SPEC lower_term + o MATCH_MP (MESON[] `read X9 s = a ==> !a'. a = a' ==> read X9 s = a'`)) THEN + ANTS_TAC THENL [CONV_TAC (RAND_CONV (RAND_CONV TWEAK_UPDATE_CONV)) THEN + ABBREV_TAC abbrev_term THEN + BITBLAST_TAC; DISCH_TAC] THEN + FIRST_X_ASSUM(MP_TAC o SPEC upper_term + o MATCH_MP (MESON[] `read X10 s = a ==> !a'. a = a' ==> read X10 s = a'`)) THEN + ANTS_TAC THENL [CONV_TAC (RAND_CONV (RATOR_CONV (RAND_CONV TWEAK_UPDATE_CONV))) THEN + ABBREV_TAC abbrev_term THEN + BITBLAST_TAC; DISCH_TAC] THEN + FIRST_X_ASSUM(MP_TAC o SPEC full_term + o MATCH_MP (MESON[] full_lemma)) THEN + ANTS_TAC THENL [CONV_TAC (RAND_CONV TWEAK_UPDATE_CONV) THEN + ABBREV_TAC abbrev_term THEN + BITBLAST_TAC; DISCH_TAC];; + +let XTSENC_TAC reg ind ind_tweak = + let tm = subst [ind, `ind:num`; ind_tweak, `ind_tweak:num`] + `aes256_xts_encrypt_round (bytes_to_int128 (SUB_LIST (ind,0x10) (pt_in:byte list))) + (calculate_tweak (ind_tweak) iv key2_lst) key1_lst` in + let lemma = subst [reg, `reg:(armstate,int128)component`] + `read (reg:(armstate,int128)component) (s:armstate) = a ==> !a'. a = a' ==> read reg s = a'` in + let _ = print_term tm in + let _ = print_term lemma in + FIRST_X_ASSUM(MP_TAC o SPEC tm o MATCH_MP (MESON[] lemma)) THEN + ANTS_TAC THENL + [ EXPAND_TAC "key1_lst" THEN + CONV_TAC (RAND_CONV ( + REWRITE_CONV [aes256_xts_encrypt_round] THENC + DEPTH_CONV let_CONV)) THEN + GEN_REWRITE_TAC LAND_CONV [WORD_XOR_SYM] THEN + REPEAT (AP_THM_TAC THEN AP_TERM_TAC) THEN + GEN_REWRITE_TAC ONCE_DEPTH_CONV [WORD_XOR_SYM] THEN + AESENC_TAC; DISCH_TAC ];; + (* void aes_hw_xts_encrypt(const uint8_t *in, uint8_t *out, size_t length, const AES_KEY *key1, const AES_KEY *key2, @@ -884,49 +951,6 @@ let BYTE_LIST_AT_ADD_ASSUM_TAC new_pos bound = USE_THEN "tmp" (fun th -> REWRITE_TAC[th]) THEN POP_ASSUM (K ALL_TAC);; -(* is this needed? *) -let WORD_JOIN_16_8_ASSOC = WORD_BLAST - `!(x0:byte) (x1:byte) (x2:byte) (x3:byte) - (x4:byte) (x5:byte) (x6:byte) (x7:byte) - (x8:byte) (x9:byte) (x10:byte) (x11:byte) - (x12:byte) (x13:byte) (x14:byte) (x15:byte). - (word_join - (word_join - (word_join (word_join x15 x14 : int16) (word_join x13 x12 : int16) : int32) - (word_join (word_join x11 x10 : int16) (word_join x9 x8 : int16) : int32) : int64) - (word_join - (word_join (word_join x7 x6 : int16) (word_join x5 x4 : int16) : int32) - (word_join (word_join x3 x2 : int16) (word_join x1 x0 : int16) : int32) : int64)) = - (word_join - (word_join - (word_join - (word_join - (word_join - (word_join - (word_join - (word_join - (word_join - (word_join - (word_join - (word_join - (word_join - (word_join - (word_join x15 x14:16 word) - x13:24 word) - x12:32 word) - x11:40 word) - x10:48 word) - x9:56 word) - x8:64 word) - x7:72 word) - x6:80 word) - x5:88 word) - x4:96 word) - x3:104 word) - x2:112 word) - x1:120 word) - x0:128 word)`;; - let BYTES128_TO_BYTES8_THM = prove( `!pos bl_ptr s. read (memory :> bytes128 (word_add bl_ptr (word pos))) s = @@ -1103,74 +1127,398 @@ let NUM_5BLOCKS_LO_BOUND_THM = prove( ARITH_TAC );; -let TWEAK_UPDATE_CONV = - let ADD_SUC_1 = ARITH_RULE `!n. n + 1 = SUC(n)` in - let ADD_SUC_2 = ARITH_RULE `!n. n + 2 = SUC(n + 1)` in - let ADD_SUC_3 = ARITH_RULE `!n. n + 3 = SUC(n + 2)` in - let ADD_SUC_4 = ARITH_RULE `!n. n + 4 = SUC(n + 3)` in - let ADD_SUC_5 = ARITH_RULE `!n. n + 5 = SUC(n + 4)` in - let ADD_SUC_6 = ARITH_RULE `!n. n + 6 = SUC(n + 5)` in - let ADD_SUC_7 = ARITH_RULE `!n. n + 7 = SUC(n + 6)` in - let ADD_SUC_8 = ARITH_RULE `!n. n + 8 = SUC(n + 7)` in - let ADD_SUC_9 = ARITH_RULE `!n. n + 9 = SUC(n + 8)` in - NUM_REDUCE_CONV THENC - RATOR_CONV (LAND_CONV (num_CONV ORELSEC - FIRST_CONV - [ CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_1]); - CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_2]); - CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_3]); - CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_4]); - CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_5]); - CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_6]); - CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_7]); - CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_8]); - CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_9]);])) THENC - REWRITE_CONV [CONJUNCT2 calculate_tweak] THENC - GF_128_MULT_BY_PRIMITIVE_CONV;; +let NUM_BLOCKS_ADJUSTED_LT_LEN_THM = prove( + `!(len:int64) num_blocks. + word_and len (word 0xfffffffffffffff0) = num_blocks + ==> ~(val num_blocks < 0x60) + ==> val (word_sub num_blocks (word 0x10)) <= val len`, + BITBLAST_TAC +);; -(* differs from the Decrypt definition in using key2_lst instead of key2 *) -let TWEAK_TAC reg ind indm1 = - let lower_term = subst [ind,`ind:num`] `(word_zx:int128->int64) (calculate_tweak ind iv key2_lst)` in - let upper_term = subst [ind,`ind:num`] `(word_subword:int128->num#num->int64) (calculate_tweak ind iv key2_lst) (64,64)` in - let full_term = subst [ind,`ind:num`] `calculate_tweak ind iv key2_lst` in - let full_lemma = subst [reg,`reg:(armstate,int128)component`] `read (reg:(armstate,int128)component) (s:armstate) = a ==> !a'. a = a' ==> read reg s = a'` in - let abbrev_term = subst [indm1,`indm1:num`] `tweak_pre:int128 = (calculate_tweak indm1 iv key2_lst)` in - FIRST_X_ASSUM(MP_TAC o SPEC lower_term - o MATCH_MP (MESON[] `read X9 s = a ==> !a'. a = a' ==> read X9 s = a'`)) THEN - ANTS_TAC THENL [CONV_TAC (RAND_CONV (RAND_CONV TWEAK_UPDATE_CONV)) THEN - ABBREV_TAC abbrev_term THEN - BITBLAST_TAC; DISCH_TAC] THEN - FIRST_X_ASSUM(MP_TAC o SPEC upper_term - o MATCH_MP (MESON[] `read X10 s = a ==> !a'. a = a' ==> read X10 s = a'`)) THEN - ANTS_TAC THENL [CONV_TAC (RAND_CONV (RATOR_CONV (RAND_CONV TWEAK_UPDATE_CONV))) THEN - ABBREV_TAC abbrev_term THEN - BITBLAST_TAC; DISCH_TAC] THEN - FIRST_X_ASSUM(MP_TAC o SPEC full_term - o MATCH_MP (MESON[] full_lemma)) THEN - ANTS_TAC THENL [CONV_TAC (RAND_CONV TWEAK_UPDATE_CONV) THEN - ABBREV_TAC abbrev_term THEN - BITBLAST_TAC; DISCH_TAC];; +let NUM_OF_BYTELIST_APPEND = prove + (`!l1 l2. num_of_bytelist (APPEND l1 l2) = + num_of_bytelist l1 + 2 EXP (8 * LENGTH l1) * num_of_bytelist l2`, + LIST_INDUCT_TAC THENL + [ REWRITE_TAC[APPEND; LENGTH; num_of_bytelist; MULT_CLAUSES; EXP; ADD_CLAUSES]; + REWRITE_TAC[APPEND; LENGTH; num_of_bytelist] THEN + ASM_REWRITE_TAC[] THEN + REWRITE_TAC[MULT_SUC; EXP_ADD] THEN + REWRITE_TAC[MULT_ASSOC; LEFT_ADD_DISTRIB] THEN + ARITH_TAC]);; + +let NUM_OF_BYTELIST_OF_SUB_LIST = prove( + `!sz len (x:byte list). + sz <= LENGTH x ==> + num_of_bytelist (SUB_LIST (0, sz + len) x) = + num_of_bytelist (SUB_LIST (0, sz) x) + + 2 EXP (8 * sz) * num_of_bytelist (SUB_LIST (sz, len) x)`, + REPEAT STRIP_TAC THEN + SUBST1_TAC(ISPECL [`x:byte list`; `sz:num`; `len:num`; `0:num`] SUB_LIST_SPLIT) THEN + REWRITE_TAC[NUM_OF_BYTELIST_APPEND] THEN + ASM_SIMP_TAC[LENGTH_SUB_LIST; SUB_0; MIN; ARITH_RULE `0 + sz = sz`] +);; -let XTSENC_TAC reg ind ind_tweak = - let tm = subst [ind, `ind:num`; ind_tweak, `ind_tweak:num`] - `aes256_xts_encrypt_round (bytes_to_int128 (SUB_LIST (ind,0x10) (pt_in:byte list))) - (calculate_tweak (ind_tweak) iv key2_lst) key1_lst` in - let lemma = subst [reg, `reg:(armstate,int128)component`] - `read (reg:(armstate,int128)component) (s:armstate) = a ==> !a'. a = a' ==> read reg s = a'` in - let _ = print_term tm in - let _ = print_term lemma in - FIRST_X_ASSUM(MP_TAC o SPEC tm o MATCH_MP (MESON[] lemma)) THEN - ANTS_TAC THENL - [ EXPAND_TAC "key1_lst" THEN - CONV_TAC (RAND_CONV ( - REWRITE_CONV [aes256_xts_encrypt_round] THENC - DEPTH_CONV let_CONV)) THEN - GEN_REWRITE_TAC LAND_CONV [WORD_XOR_SYM] THEN - REPEAT (AP_THM_TAC THEN AP_TERM_TAC) THEN - GEN_REWRITE_TAC ONCE_DEPTH_CONV [WORD_XOR_SYM] THEN - AESENC_TAC; DISCH_TAC ];; +let MEMORY_READ_SUBSET_LEMMA = prove + (`!len (ptr:int64) (bl:byte list) s. + (forall i. + i < SUC len + ==> read (memory :> bytes8 (word_add ptr (word i))) s = EL i bl) ==> + (forall i. + i < len + ==> read (memory :> bytes8 (word_add ptr (word i))) s = EL i bl) /\ + read (memory :> bytes (word_add ptr (word len),1)) s = + val(read (memory :> bytes8 (word_add ptr (word len))) s) + `, + REPEAT GEN_TAC THEN + DISCH_TAC THEN + CONJ_TAC THENL + [ GEN_TAC THEN DISCH_TAC THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_REWRITE_TAC[LT_SUC_LE] THEN + ASM_ARITH_TAC; + ALL_TAC] THEN + REWRITE_TAC[bytes8; READ_COMPONENT_COMPOSE; asword; through; read] THEN + REWRITE_TAC[VAL_WORD; DIMINDEX_8] THEN + CONV_TAC NUM_REDUCE_CONV THEN + IMP_REWRITE_TAC[MOD_LT] THEN + MP_TAC (ISPECL [`(word_add (ptr:int64) (word len)):int64`; `1:num`; `(read memory s):int64->byte`] READ_BYTES_BOUND) THEN + CONV_TAC NUM_REDUCE_CONV +);; - let UDIV_OPT_THM = prove(`!n:num. n < 0x2 EXP 0x40 +let BYTE_LIST_AT_SPLIT = prove( + `!len (ptr:int64) (bl:byte list) s. + SUC len <= LENGTH bl ==> + ((forall i. + i < SUC len + ==> read (memory :> bytes8 (word_add ptr (word i))) s = EL i bl) <=> + ((forall i. + i < len + ==> read (memory :> bytes8 (word_add ptr (word i))) s = EL i bl) /\ + read (memory :> bytes8 (word_add ptr (word len))) s = EL len bl))`, + REPEAT STRIP_TAC THEN + EQ_TAC THENL + [ STRIP_TAC THEN + CONJ_TAC THENL + [ ASM_SIMP_TAC[ARITH_RULE `i < len ==> i < SUC len`]; + ASM_SIMP_TAC[ARITH_RULE `len < SUC len`]]; + ALL_TAC ] THEN + REPEAT STRIP_TAC THEN + ASM_CASES_TAC `i < len` THENL + [ FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_SIMP_TAC[]; + SUBGOAL_THEN `i = len:num` SUBST1_TAC THENL + [ASM_ARITH_TAC; ASM_REWRITE_TAC[]] + ] +);; + +let MEMORY_READ_BYTES_SUBSET_LEMMA = prove( + `!len (ptr:int64) (bl:byte list) s. + SUC len <= LENGTH bl ==> + read (memory :> bytes (ptr,SUC len)) s = + num_of_bytelist (SUB_LIST (0x0,SUC len) bl) ==> + read (memory :> bytes (ptr,len)) s = + num_of_bytelist (SUB_LIST (0x0,len) bl) /\ + read (memory :> bytes8 (word_add ptr (word len))) s = EL len bl`, + REPEAT GEN_TAC THEN STRIP_TAC THEN + SUBGOAL_THEN `SUC len = len + 1` SUBST_ALL_TAC THENL [ARITH_TAC; ALL_TAC] THEN + REWRITE_TAC[READ_COMPONENT_COMPOSE] THEN + SUBGOAL_THEN `len <= LENGTH (bl:byte list)` ASSUME_TAC THENL [ ASM_ARITH_TAC; ALL_TAC] THEN + (* Use READ_BYTES_COMBINE to decompose the memory read *) + MP_TAC(ISPECL [`ptr:int64`; `len:num`; `1:num`; `(read memory s):int64->byte`] READ_BYTES_COMBINE) THEN + DISCH_TAC THEN + (* Use SUB_LIST_SPLIT to decompose the byte list *) + MP_TAC(ISPECL [`bl:byte list`; `len:num`; `1:num`; `0:num`] SUB_LIST_SPLIT) THEN + REWRITE_TAC[ADD_CLAUSES] THEN DISCH_TAC THEN + (* Decompose num_of_bytelist *) + SUBGOAL_THEN + `num_of_bytelist (SUB_LIST (0,len + 1) (bl:byte list)) = + num_of_bytelist (SUB_LIST (0,len) bl) + + 2 EXP (8 * len) * num_of_bytelist (SUB_LIST (len,1) bl)` + ASSUME_TAC THENL + [ ASM_REWRITE_TAC[] THEN + REWRITE_TAC[NUM_OF_BYTELIST_APPEND] THEN + AP_TERM_TAC THEN AP_THM_TAC THEN REPEAT_N 3 AP_TERM_TAC THEN + IMP_REWRITE_TAC[LENGTH_SUB_LIST; MIN; SUB_0] THEN + ASM_SIMP_TAC[] + ; ALL_TAC] THEN + (* Rewrite in goal *) + ASM_REWRITE_TAC[] THEN + DISCH_TAC THEN + CONJ_TAC THENL + [ (* First part: read (memory :> bytes (ptr,len)) s = num_of_bytelist (SUB_LIST (0,len) bl) *) + FIRST_X_ASSUM(MP_TAC o AP_TERM `\x. x MOD 2 EXP (8 * len)`) THEN + ASM_REWRITE_TAC[] THEN + REWRITE_TAC[MOD_MULT_ADD; MOD_LT] THEN + REWRITE_TAC[READ_BYTES_MOD; MIN] THEN + SIMP_TAC[ARITH_RULE `len <= len`] THEN + DISCH_TAC THEN + IMP_REWRITE_TAC[MOD_LT] THEN + MP_TAC (SPEC `(SUB_LIST (0,len) bl:byte list)` NUM_OF_BYTELIST_BOUND) THEN + IMP_REWRITE_TAC[LENGTH_SUB_LIST; SUB_0; MIN] THEN + SUBGOAL_THEN `256 EXP len = 2 EXP (8 * len)` SUBST1_TAC THENL + [ REWRITE_TAC[ARITH_RULE `256 = 2 EXP 8`; EXP_EXP]; ALL_TAC] THEN + SIMP_TAC[]; + ALL_TAC + ] THEN + (* Second part: read (memory :> bytes8 (word_add ptr (word len))) s = EL len bl *) + FIRST_X_ASSUM(MP_TAC o AP_TERM `\x. x DIV 2 EXP (8 * len)`) THEN + ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN `~(0x2 EXP (0x8 * len) = 0x0)` ASSUME_TAC THENL + [ REWRITE_TAC[EXP_EQ_0; ARITH_EQ]; ALL_TAC] THEN + IMP_REWRITE_TAC[DIV_MULT_ADD] THEN + SUBGOAL_THEN `read (bytes (ptr,len)) (read memory s) < 0x2 EXP (0x8 * len)` ASSUME_TAC THENL + [ REWRITE_TAC[READ_BYTES_BOUND]; ALL_TAC] THEN + SUBGOAL_THEN `num_of_bytelist (SUB_LIST (0x0,len) bl) < 0x2 EXP (0x8 * len)` ASSUME_TAC THENL + [ MP_TAC (SPEC `(SUB_LIST (0,len) bl:byte list)` NUM_OF_BYTELIST_BOUND) THEN + IMP_REWRITE_TAC[LENGTH_SUB_LIST; SUB_0; MIN] THEN + SUBGOAL_THEN `256 EXP len = 2 EXP (8 * len)` SUBST1_TAC THENL + [ REWRITE_TAC[ARITH_RULE `256 = 2 EXP 8`; EXP_EXP]; ALL_TAC] THEN SIMP_TAC[]; ALL_TAC] THEN + IMP_REWRITE_TAC[DIV_LT; ADD] THEN + (* Some rewrites to close the goal *) + REWRITE_TAC[bytes8; READ_COMPONENT_COMPOSE; asword; through; read] THEN + SUBGOAL_THEN `len < LENGTH (bl:byte list)` ASSUME_TAC THENL [ ASM_ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[SUB_LIST_1] THEN + REWRITE_TAC[num_of_bytelist; MULT_CLAUSES; ADD_CLAUSES; WORD_VAL] +);; + +let BYTE_LIST_TO_NUM_THM = prove( + `!len (ptr:int64) (bl:byte list) s. + len <= LENGTH bl ==> + ((forall i. i < len + ==> read (memory :> bytes8 (word_add ptr (word i))) s = EL i bl) <=> + (read (memory :> bytes (ptr, len)) s = num_of_bytelist (SUB_LIST (0, len) bl)))`, + REPEAT GEN_TAC THEN + SPEC_TAC (`len:num`, `len:num`) THEN + (* Base case: len = 0 *) + INDUCT_TAC THENL + [ STRIP_TAC THEN + REWRITE_TAC[READ_COMPONENT_COMPOSE; READ_BYTES_TRIVIAL; + CONJUNCT1 SUB_LIST; CONJUNCT1 num_of_bytelist] THEN + GEN_TAC THEN MESON_TAC[ARITH_RULE `~(i < 0)`]; + ALL_TAC] THEN + + (* Inductive step: left to right *) + STRIP_TAC THEN + EQ_TAC THENL + [ MP_TAC (ARITH_RULE `SUC len <= LENGTH (bl:byte list) ==> len <= LENGTH bl`) THEN + ASM_SIMP_TAC[] THEN REPEAT DISCH_TAC THEN + MP_TAC (SPECL [`len:num`; `ptr:int64`; `bl:byte list`; `s:armstate`] MEMORY_READ_SUBSET_LEMMA) THEN + ASM_SIMP_TAC[] THEN + DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN + REWRITE_TAC[READ_COMPONENT_COMPOSE; ADD1] THEN + ONCE_REWRITE_TAC[READ_BYTES_COMBINE] THEN + REWRITE_TAC[SUB_LIST_SPLIT; NUM_OF_BYTELIST_APPEND; CONJUNCT1 ADD] THEN + IMP_REWRITE_TAC[ARITH_RULE `a = c ==> (a + b = c + d) = (b = d)`] THEN + CONJ_TAC THENL [ + REWRITE_TAC[LENGTH_SUB_LIST; MIN; SUB_0] THEN + ASM_SIMP_TAC[] THEN + AP_TERM_TAC THEN + REWRITE_TAC[GSYM READ_COMPONENT_COMPOSE] THEN + FIRST_X_ASSUM (fun th -> MP_TAC (SPEC `len:num` th)) THEN + REWRITE_TAC[ARITH_RULE `len < SUC len`] THEN + SUBGOAL_THEN `len < LENGTH (bl:byte list)` ASSUME_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC] THEN + ASM_REWRITE_TAC[SUB_LIST_1; num_of_bytelist] THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[ADD_0] THEN + STRIP_TAC THEN AP_TERM_TAC THEN ASM_SIMP_TAC[] + ; ALL_TAC] THEN + REWRITE_TAC[GSYM READ_COMPONENT_COMPOSE] THEN + ASM_SIMP_TAC[] + ; ALL_TAC] THEN + + (* Inductive step: right to left *) + MP_TAC (ARITH_RULE `SUC len <= LENGTH (bl:byte list) ==> len <= LENGTH bl`) THEN + ASM_SIMP_TAC[] THEN REPEAT DISCH_TAC THEN + MP_TAC (SPECL [`len:num`; `ptr:int64`; `bl:byte list`; `s:armstate`] MEMORY_READ_BYTES_SUBSET_LEMMA) THEN + ASM_SIMP_TAC[] THEN + DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN + IMP_REWRITE_TAC[BYTE_LIST_AT_SPLIT] THEN + CONJ_TAC THENL [ASM_SIMP_TAC[]; ALL_TAC] THEN + ASM_SIMP_TAC[] +);; + +let MEMORY_BYTES_BOUND = prove + (`read (memory :> bytes (x,16)) s < 2 EXP dimindex (:128)`, + REWRITE_TAC[READ_COMPONENT_COMPOSE; DIMINDEX_128] THEN + SUBST1_TAC(ARITH_RULE `128 = 8 * 16`) THEN REWRITE_TAC[READ_BYTES_BOUND] + );; + +(* Copied from bignum_copy_row_from_table_8n.ml *) +let READ_MEMORY_BYTES_BYTES128 = prove(`!z s. + read (memory :> bytes (z,16)) s = val (read (memory :> bytes128 z) s)`, + REPEAT GEN_TAC THEN + REWRITE_TAC[el 1 (CONJUNCTS READ_MEMORY_BYTESIZED_SPLIT)] THEN + REWRITE_TAC[VAL_WORD_JOIN;DIMINDEX_64;DIMINDEX_128] THEN + IMP_REWRITE_TAC[MOD_LT] THEN + REWRITE_TAC[ARITH_RULE`2 EXP 128 = 2 EXP 64 * 2 EXP 64`] THEN + IMP_REWRITE_TAC[LT_MULT_ADD_MULT] THEN + REWRITE_TAC[VAL_BOUND_64;ARITH_RULE`0<2 EXP 64`;LE_REFL] THEN + REWRITE_TAC[ARITH_RULE`16 = 8*(1+1)`;GSYM BIGNUM_FROM_MEMORY_BYTES;BIGNUM_FROM_MEMORY_STEP;BIGNUM_FROM_MEMORY_SING] THEN + REWRITE_TAC[ARITH_RULE`8*1=8`;ARITH_RULE`64*1=64`] THEN ARITH_TAC);; + +let READ_MEMORY_BYTES128_BYTES = prove(`!z s. + read (memory :> bytes128 z) s = word (read (memory :> bytes (z,16)) s)`, + REPEAT STRIP_TAC THEN + ONCE_REWRITE_TAC[GSYM VAL_EQ] THEN + IMP_REWRITE_TAC [VAL_WORD_EQ] THEN + CONJ_TAC THENL [REWRITE_TAC [READ_MEMORY_BYTES_BYTES128]; ALL_TAC] THEN + REWRITE_TAC [MEMORY_BYTES_BOUND] + );; + +let WORD_JOIN_BOUND_TAC x y = + REWRITE_TAC[VAL_WORD_JOIN; DIMINDEX_CLAUSES] THEN + CONV_TAC NUM_REDUCE_CONV THEN + IMP_REWRITE_TAC[MOD_LT] THEN + CONJ_TAC THENL[ REWRITE_TAC[ADD_SYM]; ALL_TAC ] THEN + MP_TAC (ISPECL [x] VAL_BOUND) THEN + MP_TAC (ISPECL [y] VAL_BOUND) THEN + REWRITE_TAC[DIMINDEX_CLAUSES] THEN + CONV_TAC NUM_REDUCE_CONV THEN + ARITH_TAC;; + +let WORD_JOIN_16_8_ASSOC = WORD_BLAST + `!(x0:byte) (x1:byte) (x2:byte) (x3:byte) + (x4:byte) (x5:byte) (x6:byte) (x7:byte) + (x8:byte) (x9:byte) (x10:byte) (x11:byte) + (x12:byte) (x13:byte) (x14:byte) (x15:byte). + (word_join + (word_join + (word_join (word_join x15 x14 : int16) (word_join x13 x12 : int16) : int32) + (word_join (word_join x11 x10 : int16) (word_join x9 x8 : int16) : int32) : int64) + (word_join + (word_join (word_join x7 x6 : int16) (word_join x5 x4 : int16) : int32) + (word_join (word_join x3 x2 : int16) (word_join x1 x0 : int16) : int32) : int64)) = + (word_join + (word_join + (word_join + (word_join + (word_join + (word_join + (word_join + (word_join + (word_join + (word_join + (word_join + (word_join + (word_join + (word_join + (word_join x15 x14:16 word) + x13:24 word) + x12:32 word) + x11:40 word) + x10:48 word) + x9:56 word) + x8:64 word) + x7:72 word) + x6:80 word) + x5:88 word) + x4:96 word) + x3:104 word) + x2:112 word) + x1:120 word) + x0:128 word)`;; + +let VAL_OF_BYTES_TO_INT128_EQ_NUM_OF_BYTELIST = prove( + `!x:byte list. LENGTH x = 16 ==> val (bytes_to_int128 x) = num_of_bytelist x`, + REPEAT STRIP_TAC THEN + (* conversion for breaking down a list *) + MP_TAC ((GEN_REWRITE_CONV I [LENGTH_EQ_LIST_OF_SEQ] THENC + RAND_CONV LIST_OF_SEQ_CONV) `LENGTH (x:byte list) = 16`) THEN + ASM_SIMP_TAC[] THEN + DISCH_THEN (fun th -> ONCE_REWRITE_TAC[th]) THEN + REWRITE_TAC[bytes_to_int128] THEN + REWRITE_TAC EL_16_8_CLAUSES THEN + REPEAT_N 16 (ONCE_REWRITE_TAC[num_of_bytelist]) THEN + REWRITE_TAC[CONJUNCT1 num_of_bytelist] THEN + MAP_EVERY ABBREV_TAC + [`x0 = EL 0 x:byte`; `x1 = EL 1 x:byte`; `x2 = EL 2 x:byte`; `x3 = EL 3 x:byte`; + `x4 = EL 4 x:byte`; `x5 = EL 5 x:byte`; `x6 = EL 6 x:byte`; `x7 = EL 7 x:byte`; + `x8 = EL 8 x:byte`; `x9 = EL 9 x:byte`; `x10 = EL 10 x:byte`; `x11 = EL 11 x:byte`; + `x12 = EL 12 x:byte`; `x13 = EL 13 x:byte`; `x14 = EL 14 x:byte`; `x15 = EL 15 x:byte`] THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[ADD_0; WORD_JOIN_16_8_ASSOC] THEN + (* reduce RHS to LHS *) + SUBGOAL_THEN `val (x14:byte) + 0x100 * val (x15:byte) = val ((word_join x15 x14):int16)` SUBST1_TAC THENL + [ WORD_JOIN_BOUND_TAC `x15:byte` `x14:byte`; ALL_TAC] THEN ABBREV_TAC `y14:int16 = word_join (x15:byte) (x14:byte)` THEN + SUBGOAL_THEN `val (x13:byte) + 0x100 * val (y14:16 word) = val ((word_join y14 x13):24 word)` SUBST1_TAC THENL + [ WORD_JOIN_BOUND_TAC `y14:16 word` `x13:byte`; ALL_TAC] THEN ABBREV_TAC `y13:24 word = word_join (y14:16 word) (x13:byte)` THEN + SUBGOAL_THEN `val (x12:byte) + 0x100 * val (y13:24 word) = val ((word_join y13 x12):32 word)` SUBST1_TAC THENL + [ WORD_JOIN_BOUND_TAC `y13:24 word` `x12:byte`; ALL_TAC] THEN ABBREV_TAC `y12:32 word = word_join (y13:24 word) (x12:byte)` THEN + SUBGOAL_THEN `val (x11:byte) + 0x100 * val (y12:32 word) = val ((word_join y12 x11):40 word)` SUBST1_TAC THENL + [ WORD_JOIN_BOUND_TAC `y12:32 word` `x11:byte`; ALL_TAC] THEN ABBREV_TAC `y11:40 word = word_join (y12:32 word) (x11:byte)` THEN + SUBGOAL_THEN `val (x10:byte) + 0x100 * val (y11:40 word) = val ((word_join y11 x10):48 word)` SUBST1_TAC THENL + [ WORD_JOIN_BOUND_TAC `y11:40 word` `x10:byte`; ALL_TAC] THEN ABBREV_TAC `y10:48 word = word_join (y11:40 word) (x10:byte)` THEN + SUBGOAL_THEN `val (x9:byte) + 0x100 * val (y10:48 word) = val ((word_join y10 x9):56 word)` SUBST1_TAC THENL + [ WORD_JOIN_BOUND_TAC `y10:48 word` `x9:byte`; ALL_TAC] THEN ABBREV_TAC `y9:56 word = word_join (y10:48 word) (x9:byte)` THEN + SUBGOAL_THEN `val (x8:byte) + 0x100 * val (y9:56 word) = val ((word_join y9 x8):64 word)` SUBST1_TAC THENL + [ WORD_JOIN_BOUND_TAC `y9:56 word` `x8:byte`; ALL_TAC] THEN ABBREV_TAC `y8:64 word = word_join (y9:56 word) (x8:byte)` THEN + SUBGOAL_THEN `val (x7:byte) + 0x100 * val (y8:64 word) = val ((word_join y8 x7):72 word)` SUBST1_TAC THENL + [ WORD_JOIN_BOUND_TAC `y8:64 word` `x7:byte`; ALL_TAC] THEN ABBREV_TAC `y7:72 word = word_join (y8:64 word) (x7:byte)` THEN + SUBGOAL_THEN `val (x6:byte) + 0x100 * val (y7:72 word) = val ((word_join y7 x6):80 word)` SUBST1_TAC THENL + [ WORD_JOIN_BOUND_TAC `y7:72 word` `x6:byte`; ALL_TAC] THEN ABBREV_TAC `y6:80 word = word_join (y7:72 word) (x6:byte)` THEN + SUBGOAL_THEN `val (x5:byte) + 0x100 * val (y6:80 word) = val ((word_join y6 x5):88 word)` SUBST1_TAC THENL + [ WORD_JOIN_BOUND_TAC `y6:80 word` `x5:byte`; ALL_TAC] THEN ABBREV_TAC `y5:88 word = word_join (y6:80 word) (x5:byte)` THEN + SUBGOAL_THEN `val (x4:byte) + 0x100 * val (y5:88 word) = val ((word_join y5 x4):96 word)` SUBST1_TAC THENL + [ WORD_JOIN_BOUND_TAC `y5:88 word` `x4:byte`; ALL_TAC] THEN ABBREV_TAC `y4:96 word = word_join (y5:88 word) (x4:byte)` THEN + SUBGOAL_THEN `val (x3:byte) + 0x100 * val (y4:96 word) = val ((word_join y4 x3):104 word)` SUBST1_TAC THENL + [ WORD_JOIN_BOUND_TAC `y4:96 word` `x3:byte`; ALL_TAC] THEN ABBREV_TAC `y3:104 word = word_join (y4:96 word) (x3:byte)` THEN + SUBGOAL_THEN `val (x2:byte) + 0x100 * val (y3:104 word) = val ((word_join y3 x2):112 word)` SUBST1_TAC THENL + [ WORD_JOIN_BOUND_TAC `y3:104 word` `x2:byte`; ALL_TAC] THEN ABBREV_TAC `y2:112 word = word_join (y3:104 word) (x2:byte)` THEN + SUBGOAL_THEN `val (x1:byte) + 0x100 * val (y2:112 word) = val ((word_join y2 x1):120 word)` SUBST1_TAC THENL + [ WORD_JOIN_BOUND_TAC `y2:112 word` `x1:byte`; ALL_TAC] THEN ABBREV_TAC `y1:120 word = word_join (y2:112 word) (x1:byte)` THEN + SUBGOAL_THEN `val (x0:byte) + 0x100 * val (y1:120 word) = val ((word_join y1 x0):128 word)` SUBST1_TAC THENL + [ WORD_JOIN_BOUND_TAC `y1:120 word` `x0:byte`; ALL_TAC] THEN ABBREV_TAC `y0:128 word = word_join (y1:120 word) (x0:byte)` THEN + REFL_TAC +);; + +let READ_BYTES_AND_BYTE128_SPLIT = prove( + `!(pt_ptr:int64) (sz:num) (x:byte list) (s:armstate). + sz + 16 <= LENGTH x ==> + read (memory :> bytes128 (word_add pt_ptr (word sz))) s = bytes_to_int128 (SUB_LIST (sz, 0x10) x) + /\ read (memory :> bytes (pt_ptr, sz)) s = num_of_bytelist (SUB_LIST (0, sz) x) + ==> read (memory :> bytes (pt_ptr,sz + 0x10)) s = num_of_bytelist (SUB_LIST (0, sz + 0x10) x)`, + REWRITE_TAC[READ_MEMORY_BYTES128_BYTES] THEN + REPEAT STRIP_TAC THEN + + SUBGOAL_THEN `sz <= LENGTH (x:byte list)` ASSUME_TAC THENL + [ UNDISCH_TAC `sz + 16 <= LENGTH (x:byte list)` THEN ARITH_TAC; ALL_TAC ] THEN + + SUBGOAL_THEN `16 <= LENGTH (x:byte list) - sz` ASSUME_TAC THENL + [ UNDISCH_TAC `sz + 16 <= LENGTH (x:byte list)` THEN ARITH_TAC; ALL_TAC ] THEN + + SUBGOAL_THEN `read (memory :> bytes (pt_ptr, sz + 16)) s = + read (memory :> bytes (pt_ptr, sz)) s + + 2 EXP (8 * sz) * (read (memory :> bytes (word_add pt_ptr (word sz), 16)) s)` SUBST1_TAC THENL + [ REWRITE_TAC[READ_COMPONENT_COMPOSE] THEN + REWRITE_TAC[READ_BYTES_COMBINE]; ALL_TAC] THEN + + ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN `read (memory :> bytes (word_add pt_ptr (word sz),0x10)) s = + val (bytes_to_int128 (SUB_LIST (sz,0x10) x))` SUBST1_TAC THENL + [ UNDISCH_THEN + `word (read (memory :> bytes (word_add (pt_ptr:int64) (word sz),0x10)) s) = + bytes_to_int128 (SUB_LIST (sz,0x10) x)` + (fun th -> MP_TAC (AP_TERM `val:int128->num` th)) THEN + IMP_REWRITE_TAC[VAL_WORD] THEN + SUBGOAL_THEN `read (memory :> bytes (word_add pt_ptr (word sz),0x10)) s < 2 EXP dimindex (:128)` ASSUME_TAC THENL + [ SIMP_TAC[MEMORY_BYTES_BOUND] ; ALL_TAC] THEN + SUBST_ALL_TAC DIMINDEX_128 THEN + ASM_SIMP_TAC[MOD_LT]; ALL_TAC] THEN + + IMP_REWRITE_TAC[NUM_OF_BYTELIST_OF_SUB_LIST] THEN + IMP_REWRITE_TAC[VAL_OF_BYTES_TO_INT128_EQ_NUM_OF_BYTELIST] THEN + REWRITE_TAC[LENGTH_SUB_LIST; MIN] THEN ASM_SIMP_TAC[] + );; + +let SUB_LIST_LENGTH_IMPLIES = prove( + `!(l:A list) n. LENGTH l = n ==> SUB_LIST(0,n) l = l`, + REPEAT STRIP_TAC THEN + UNDISCH_THEN `LENGTH (l:A list) = n` (fun th -> REWRITE_TAC[GSYM th]) THEN + REWRITE_TAC[SUB_LIST_LENGTH] +);; + +let UDIV_OPT_THM = prove(`!n:num. n < 0x2 EXP 0x40 ==> (word (val ((word ((n * 0xcccccccccccccccd) DIV 0x2 EXP 0x40)):int64) DIV 0x2 EXP 0x6)):int64 = word (n DIV 0x50)`, REPEAT STRIP_TAC THEN REWRITE_TAC[VAL_WORD; DIMINDEX_64] THEN @@ -1211,6 +1559,152 @@ let READ_CT_LEMMA = prove( REWRITE_TAC[byte_list_at] THEN ASM_SIMP_TAC[] );; +let LENGTH_OF_INT128_TO_BYTES = prove( + `!x. LENGTH(int128_to_bytes x) = 16`, + STRIP_TAC THEN + REWRITE_TAC[int128_to_bytes] THEN + REWRITE_TAC[LENGTH] THEN + CONV_TAC NUM_REDUCE_CONV +);; + +(* ********************************************************** *) +(* Properties that we prove about the specification functions *) +(* Similar to the Decrypt ones but specified for Encrypt *) + +let LENGTH_OF_AES256_XTS_ENCRYPT_REC = prove( + `!(i:num) (m:num) (C:byte list) (iv:int128) (key1:int128 list) (key2:int128 list). + LENGTH(aes256_xts_encrypt_rec i m P iv key1 key2) = (if m < i then 0 else (m - i + 1) * 0x10)`, + REPEAT GEN_TAC THEN + (* Wellfounded induction with measure (m + 1) - i + Note that the parentheses are essential because of the precedence of + and - *) + WF_INDUCT_TAC `(m + 1) - i` THEN + ONCE_REWRITE_TAC[aes256_xts_encrypt_rec] THEN + COND_CASES_TAC THENL + [ SIMP_TAC[LENGTH_EQ_NIL]; + SIMP_TAC[] THEN + REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + REWRITE_TAC[LENGTH_APPEND] THEN + SUBGOAL_THEN `~(m < i) ==> (m + 1) - (i + 1) < (m + 1) - i` ASSUME_TAC THENL + [ ASM_ARITH_TAC ; ALL_TAC ] THEN + ASM_SIMP_TAC[] THEN + REWRITE_TAC[LENGTH_OF_INT128_TO_BYTES] THEN + COND_CASES_TAC THENL + [ASM_ARITH_TAC; ASM_ARITH_TAC]] +);; + +let LENGTH_OF_FST_OF_CIPHER_STEALING = prove( + `!(block:byte list) (tail:byte list) (tail_len:num) + (iv:int128) (i:num) (key1:int128 list) (key2:int128 list). + LENGTH (FST (cipher_stealing_encrypt block tail tail_len iv i key1 key2)) = 16`, + REPEAT STRIP_TAC THEN + REWRITE_TAC[cipher_stealing_encrypt] THEN + ASM_REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + REWRITE_TAC[LENGTH_OF_INT128_TO_BYTES] +);; + +let LENGTH_OF_SND_OF_CIPHER_STEALING = prove( + `!(block:byte list) (tail:byte list) (tail_len:num) + (iv:int128) (i:num) (key1:int128 list) (key2:int128 list). + LENGTH (SND (cipher_stealing_encrypt block tail tail_len iv i key1 key2)) = MIN tail_len 16`, + REPEAT STRIP_TAC THEN + REWRITE_TAC[cipher_stealing_encrypt] THEN + ASM_REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + REWRITE_TAC[LENGTH_SUB_LIST] THEN + REWRITE_TAC[LENGTH_OF_INT128_TO_BYTES] THEN + REWRITE_TAC[MIN] THEN + CONV_TAC NUM_REDUCE_CONV +);; + +let LENGTH_OF_AES256_XTS_ENCRYPT_TAIL = prove( + `! (i:num) (tail_len:num) (P:byte list) (iv:int128) (key1:int128 list) (key2:int128 list). + LENGTH(aes256_xts_encrypt_tail i tail_len P iv key1 key2) = 0x10 + MIN tail_len 16`, + REPEAT STRIP_TAC THEN + REWRITE_TAC[aes256_xts_encrypt_tail] THEN + COND_CASES_TAC THENL [ + ASM_REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + REWRITE_TAC[LENGTH_OF_INT128_TO_BYTES] THEN + REWRITE_TAC[ADD_CLAUSES; MIN] THEN + CONV_TAC NUM_REDUCE_CONV; + + REWRITE_TAC[LET_DEF; LET_END_DEF; LENGTH_APPEND] THEN + REWRITE_TAC[LENGTH_OF_FST_OF_CIPHER_STEALING] THEN + REWRITE_TAC[LENGTH_OF_SND_OF_CIPHER_STEALING]] +);; + +let LENGTH_OF_AES256_XTS_ENCRYPT_REC_TRIVIAL = prove( + `!(pt:byte list) (iv:int128) (key1:int128 list) (key2:int128 list). + LENGTH (aes256_xts_encrypt_rec 0x0 0x0 pt iv key1 key2) = 16`, + REPEAT STRIP_TAC THEN + REWRITE_TAC[LENGTH_OF_AES256_XTS_ENCRYPT_REC] THEN + CONV_TAC NUM_REDUCE_CONV +);; + +let LENGTH_OF_AES256_XTS_ENCRYPT_TAIL_TRIVIAL = prove( + `!(pt:byte list) (iv:int128) (key1:int128 list) (key2:int128 list). + LENGTH(aes256_xts_encrypt_tail 0 0 pt iv key1 key2) = 16`, + REPEAT STRIP_TAC THEN + REWRITE_TAC[LENGTH_OF_AES256_XTS_ENCRYPT_TAIL] THEN + CONV_TAC NUM_REDUCE_CONV +);; + +let AES256_XTS_ENCRYPT_REC_EQ_TAIL_TRIVIAL = prove( + `!(pt:byte list) (iv:int128) (key1:int128 list) (key2:int128 list). + aes256_xts_encrypt_rec 0x0 0x0 ct iv key1 key2 = + aes256_xts_encrypt_tail 0x0 0x0 ct iv key1 key2`, + REPEAT STRIP_TAC THEN + ONCE_REWRITE_TAC[aes256_xts_encrypt_rec] THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + ONCE_REWRITE_TAC[aes256_xts_encrypt_rec] THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[APPEND_NIL] THEN + + REWRITE_TAC[aes256_xts_encrypt_tail] THEN + REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + CONV_TAC NUM_REDUCE_CONV +);; + +let LENGTH_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS = prove( + `! (i:num) (pt:byte list) (iv:int128) (key1:int128 list) (key2:int128 list). + LENGTH(aes256_xts_encrypt pt (0x10 * i) iv key1 key2) = 0x10 * i`, + REPEAT STRIP_TAC THEN + SPEC_TAC (`i:num`, `i:num`) THEN + INDUCT_TAC THENL + [ + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[aes256_xts_encrypt] THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[LENGTH_EQ_NIL]; + ALL_TAC] THEN + + REWRITE_TAC[ADD1; LEFT_ADD_DISTRIB] THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[aes256_xts_encrypt] THEN + + ASM_CASES_TAC `i = 0` THENL + [ ASM_SIMP_TAC[] THEN + CONV_TAC NUM_REDUCE_CONV THEN + IMP_REWRITE_TAC[LET_DEF;LET_END_DEF;SUB_0] THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[LENGTH_OF_AES256_XTS_ENCRYPT_TAIL_TRIVIAL] + ; ALL_TAC + ] THEN + + SUBGOAL_THEN `~(0x10 * i + 0x10 < 0x10)` ASSUME_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC ] THEN ASM_SIMP_TAC[] THEN + REWRITE_TAC[ARITH_RULE `0x10 * i + 0x10 = 0x10 * (i + 1)`; MOD_MULT] THEN + IMP_REWRITE_TAC[LET_DEF; LET_END_DEF;SUB_0;DIV_MULT] THEN + CONJ_TAC THENL [ALL_TAC; ARITH_TAC] THEN + SUBGOAL_THEN `~(i + 0x1 < 0x2)` ASSUME_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC] THEN ASM_SIMP_TAC[] THEN + REWRITE_TAC[LENGTH_APPEND] THEN + REWRITE_TAC[LENGTH_OF_AES256_XTS_ENCRYPT_REC] THEN + REWRITE_TAC[LENGTH_OF_AES256_XTS_ENCRYPT_TAIL] THEN + CONV_TAC NUM_REDUCE_CONV THEN + ASM_ARITH_TAC +);; + + (* void aes_hw_xts_encrypt(const uint8_t *in, uint8_t *out, size_t length, const AES_KEY *key1, const AES_KEY *key2, @@ -1548,7 +2042,8 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( XTSENC_TAC `Q26:(armstate,int128)component` `i * 0x50 + 0x40` `i * 0x5 + 0x4` THEN TWEAK_TAC `Q11:(armstate,int128)component` `i * 5 + 9` `i * 5 + 8` THEN - (* The following lemmas are for NONSELFMODIFYING_STATE_UPDATE_TAC when store back to pt_ptr, + (* [TODO: update comment] + The following lemmas are for NONSELFMODIFYING_STATE_UPDATE_TAC when store back to pt_ptr, and for the MAYCHANGE clauses *) RULE_ASSUM_TAC(REWRITE_RULE [WORD_RULE `word_mul (word 0x50) (word i):int64 = word(0x50 * i)`]) THEN @@ -1595,9 +2090,140 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( i' < 0x50 * i ==> read (memory :> bytes8 (word_add ctxt_p (word i'))) s188 = EL i' (aes256_xts_encrypt pt_in (i * 0x50) iv key1_lst key2_lst)` THEN + MP_TAC (SPECL [`0x50 * i + 0x50:num`; `ctxt_p:int64`; + `(aes256_xts_encrypt pt_in (0x50 * i + 0x50) iv key1_lst key2_lst):byte list`; + `s188:armstate`] BYTE_LIST_TO_NUM_THM) THEN + ANTS_TAC THENL[ + REWRITE_TAC[ARITH_RULE `0x50 * i + 0x50 = 0x10 * (5 * i + 5)`; + LENGTH_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS] THEN + ARITH_TAC + ; ALL_TAC] THEN + DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN + MP_TAC (SPECL [`0x50 * i:num`; `ctxt_p:int64`; + `(aes256_xts_encrypt pt_in (i * 0x50) iv key1_lst key2_lst):byte list`; + `s188:armstate`] BYTE_LIST_TO_NUM_THM) THEN + ANTS_TAC THENL[ + REWRITE_TAC[ARITH_RULE `i * 0x50 = 0x10 * 5 * i`; + LENGTH_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS] THEN + ARITH_TAC + ; ALL_TAC] THEN + DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN + DISCH_TAC THEN + + (* Prove one block equivalence and reduce proving the following: + `read (memory :> bytes (pt_ptr,0x50 * i + 0x50)) s188 = + num_of_bytelist + (aes256_xts_decrypt ct (0x50 * i + 0x50) iv key1 key2)` + to: + `read (memory :> bytes (pt_ptr,0x10 * 0x5 * i + 0x40)) s188 = + num_of_bytelist + (aes256_xts_decrypt ct (0x10 * 0x5 * i + 0x40) iv key1 key2)` *) + IMP_REWRITE_TAC[ARITH_RULE `0x50 * i + 0x50 = (0x50 * i + 0x40) + 0x10`; READ_BYTES_AND_BYTE128_SPLIT] THEN + EXISTS_TAC `(aes256_xts_encrypt pt_in (0x50 * i + 0x50) iv key1_lst key2_lst)` THEN + REPEAT CONJ_TAC THENL [ + REWRITE_TAC [ARITH_RULE `(0x50 * i + 0x40) + 0x10 = 0x50 * i + 0x50`]; + + MP_TAC (SPECL [`0x5 * i + 0x5:num`; `pt_in:byte list`; `iv:int128`; `key1_lst:int128 list`; + `key2_lst:int128 list`] LENGTH_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS) THEN + REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC; GSYM ADD_ASSOC] THEN + CONV_TAC NUM_REDUCE_CONV THEN (* DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] *) + DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN + ARITH_TAC; + + (* Establish that one xts decrypt round is the same as + selecting one block of bytes from calling the top-level function. *) + REWRITE_TAC[aes256_xts_encrypt] THEN + SIMP_TAC[ARITH_RULE `~(0x50 * i + 0x50 < 0x10)`] THEN + SUBGOAL_THEN `(0x50 * i + 0x50) MOD 0x10 = 0` SUBST1_TAC THENL + [ REWRITE_TAC[ARITH_RULE `80 * i + 80 = 16 * (5 * i + 5)`] THEN + REWRITE_TAC[MOD_MULT] + ; ALL_TAC] THEN + CONV_TAC (DEPTH_CONV let_CONV) THEN + REWRITE_TAC[SUB_0; ARITH_RULE `(0x50 * i + 0x50) DIV 0x10 = 0x5 * i + 0x5`] THEN + SIMP_TAC[ARITH_RULE `~(0x5 * i + 0x5 < 0x2)`; + ARITH_RULE `(0x5 * i + 0x5) - 0x2 = 0x5 * i + 0x3`; + ARITH_RULE `(0x5 * i + 0x5) - 0x1 = 0x5 * i + 0x4`] THEN + + MP_TAC (SPECL [`0`;`5 * i + 3:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + LENGTH_OF_AES256_XTS_DECRYPT_REC) THEN + SIMP_TAC[ARITH_RULE `~(5 * i + 3 < 0)`; + ARITH_RULE `((0x5 * i + 0x3) - 0x0 + 0x1) * 0x10 = 0x50 * i + 0x40`] THEN + IMP_REWRITE_TAC[SUB_LIST_APPEND_RIGHT_LEMMA] THEN DISCH_TAC THEN + + MP_TAC (SPECL [`5 * i + 4:num`; `0x0:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + LENGTH_OF_AES256_XTS_DECRYPT_TAIL) THEN + CONV_TAC NUM_REDUCE_CONV THEN REWRITE_TAC[ADD_0] THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN + + REWRITE_TAC[AES256_XTS_DECRYPT_TAIL_WHEN_1BLOCK] THEN + SIMP_TAC[ARITH_RULE `i * 0x50 + 0x40 = (i * 0x5 + 0x4) * 0x10`; + ARITH_RULE `i * 0x5 = 0x5 * i`]; + + (* Proving that reading previous bytes is the same as the spec *) + REWRITE_TAC[ARITH_RULE `0x50 * i + 0x40 = 0x10 * (5 * i + 4)`; + ARITH_RULE `0x50 * i + 0x50 = 0x10 * (5 * i + 4) + 0x10`] THEN + REWRITE_TAC[SUB_LIST_OF_AES256_XTS_DECRYPT_FULL_BLOCKS] THEN + ASM_REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC] THEN CONV_TAC NUM_REDUCE_CONV + ] THEN ] ] );; + +(* +`exists x. + num_of_bytelist (SUB_LIST (0x0,(0x50 * i + 0x40) + 0x10) x) = + num_of_bytelist + (SUB_LIST (0x0,(0x50 * i + 0x40) + 0x10) + (aes256_xts_encrypt pt_in ((0x50 * i + 0x40) + 0x10) iv key1_lst + key2_lst)) /\ + (0x50 * i + 0x40) + 0x10 <= LENGTH x /\ + aes256_xts_encrypt_round + (bytes_to_int128 (SUB_LIST (i * 0x50 + 0x40,0x10) pt_in)) + (calculate_tweak (i * 0x5 + 0x4) iv key2_lst) + key1_lst = + bytes_to_int128 (SUB_LIST (0x50 * i + 0x40,0x10) x) /\ + read (memory :> bytes (ctxt_p,0x50 * i + 0x40)) s188 = + num_of_bytelist (SUB_LIST (0x0,0x50 * i + 0x40) x)` + +`read (memory :> bytes (ctxt_p,0x50 * i + 0x50)) s188 = + num_of_bytelist + (SUB_LIST (0x0,0x50 * i + 0x50) + (aes256_xts_encrypt pt_in (0x50 * i + 0x50) iv key1_lst key2_lst))` + +`((forall i'. + i' < 0x50 * i + 0x50 + ==> read (memory :> bytes8 (word_add ctxt_p (word i'))) s188 = + EL i' + (aes256_xts_encrypt pt_in (0x50 * i + 0x50) iv key1_lst key2_lst)) <=> + read (memory :> bytes (ctxt_p,0x50 * i + 0x50)) s188 = + num_of_bytelist + (SUB_LIST (0x0,0x50 * i + 0x50) + (aes256_xts_encrypt pt_in (0x50 * i + 0x50) iv key1_lst key2_lst))) + ==> (forall i'. + i' < 0x50 * i + ==> read (memory :> bytes8 (word_add ctxt_p (word i'))) s188 = + EL i' + (aes256_xts_encrypt pt_in (i * 0x50) iv key1_lst key2_lst)) + ==> (forall i'. + i' < 0x50 * i + 0x50 + ==> read (memory :> bytes8 (word_add ctxt_p (word i'))) s188 = + EL i' + (aes256_xts_encrypt pt_in (0x50 * i + 0x50) iv key1_lst + key2_lst))` + +`(forall i'. + i' < 0x50 * i + ==> read (memory :> bytes8 (word_add ctxt_p (word i'))) s188 = + EL i' (aes256_xts_encrypt pt_in (i * 0x50) iv key1_lst key2_lst)) + ==> (forall i'. + i' < 0x50 * i + 0x50 + ==> read (memory :> bytes8 (word_add ctxt_p (word i'))) s188 = + EL i' + (aes256_xts_encrypt pt_in (0x50 * i + 0x50) iv key1_lst + key2_lst))` + +*) \ No newline at end of file From 0c17c9e6c25ba55dad2b85e9e71aa5aad8e7d159 Mon Sep 17 00:00:00 2001 From: Nevine Ebeid Date: Thu, 16 Oct 2025 15:58:08 -0400 Subject: [PATCH 073/132] WIP: subgoal 3 of the loop invariant, at the inductive step, reduced the goal by proving the last round in the loop (following the decrypt proof). --- arm/proofs/aes-xts-armv8.ml | 150 +++++++++++++++++++++++++++++++++--- 1 file changed, 141 insertions(+), 9 deletions(-) diff --git a/arm/proofs/aes-xts-armv8.ml b/arm/proofs/aes-xts-armv8.ml index 4c121bf27..b55af07b3 100644 --- a/arm/proofs/aes-xts-armv8.ml +++ b/arm/proofs/aes-xts-armv8.ml @@ -1511,6 +1511,17 @@ let READ_BYTES_AND_BYTE128_SPLIT = prove( REWRITE_TAC[LENGTH_SUB_LIST; MIN] THEN ASM_SIMP_TAC[] );; +let SUB_LIST_APPEND_RIGHT_LEMMA = prove( + `!(x:A list) y n m. LENGTH x = n ==> SUB_LIST (n,m) (APPEND x y) = SUB_LIST (0,m) y`, + LIST_INDUCT_TAC THENL + [ REPEAT GEN_TAC THEN + SIMP_TAC[CONJUNCT1 LENGTH; APPEND; SUB_LIST_CLAUSES]; + + ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN + INDUCT_TAC THENL[ + SIMP_TAC[LENGTH_EQ_NIL] THEN REWRITE_TAC[APPEND]; + ASM_SIMP_TAC[APPEND; LENGTH; SUB_LIST_CLAUSES; SUC_INJ]]]);; + let SUB_LIST_LENGTH_IMPLIES = prove( `!(l:A list) n. LENGTH l = n ==> SUB_LIST(0,n) l = l`, REPEAT STRIP_TAC THEN @@ -1572,7 +1583,7 @@ let LENGTH_OF_INT128_TO_BYTES = prove( (* Similar to the Decrypt ones but specified for Encrypt *) let LENGTH_OF_AES256_XTS_ENCRYPT_REC = prove( - `!(i:num) (m:num) (C:byte list) (iv:int128) (key1:int128 list) (key2:int128 list). + `!(i:num) (m:num) (P:byte list) (iv:int128) (key1:int128 list) (key2:int128 list). LENGTH(aes256_xts_encrypt_rec i m P iv key1 key2) = (if m < i then 0 else (m - i + 1) * 0x10)`, REPEAT GEN_TAC THEN (* Wellfounded induction with measure (m + 1) - i @@ -1704,6 +1715,126 @@ let LENGTH_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS = prove( ASM_ARITH_TAC );; +let BYTES_TO_INT128_OF_INT128_TO_BYTES = prove( + `!x. bytes_to_int128 (int128_to_bytes x) = x`, + GEN_TAC THEN + REWRITE_TAC[int128_to_bytes; bytes_to_int128] THEN + REWRITE_TAC EL_16_8_CLAUSES THEN + BITBLAST_TAC +);; + +let AES256_XTS_ENCRYPT_TAIL_WHEN_1BLOCK = prove( + `!(n:num) (pt:byte list) (iv:int128) (key1:int128 list) (key2:int128 list). + bytes_to_int128 + (aes256_xts_encrypt_tail n 0x0 pt iv key1 key2) = + aes256_xts_encrypt_round + (bytes_to_int128 (SUB_LIST (n * 0x10,0x10) pt)) + (calculate_tweak n iv key2) key1`, + REPEAT STRIP_TAC THEN + REWRITE_TAC[aes256_xts_encrypt_tail] THEN + REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + REWRITE_TAC[BYTES_TO_INT128_OF_INT128_TO_BYTES] +);; + +let AES256_XTS_ENCRYPT_REC_EQ_TAIL = prove( + `!(i:num) (k:num) (pt:byte list) (iv:int128) (key1:int128 list) (key2:int128 list). + k >= i ==> + aes256_xts_encrypt_rec i (k + 1) pt iv key1 key2 = + APPEND (aes256_xts_encrypt_rec i k pt iv key1 key2) + (aes256_xts_encrypt_tail (k + 1) 0x0 pt iv key1 key2)`, + REPEAT GEN_TAC THEN + WF_INDUCT_TAC `(k + 1) - i` THEN + STRIP_TAC THEN + GEN_REWRITE_TAC (RATOR_CONV o ONCE_DEPTH_CONV) [aes256_xts_encrypt_rec] THEN + SUBGOAL_THEN `~(k + 0x1 < i)` ASSUME_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[] THEN + REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + SUBGOAL_THEN `(k + 1) - (i + 1) < (k + 1) - i` ASSUME_TAC THENL [ ASM_ARITH_TAC; ALL_TAC] THEN + FIRST_X_ASSUM (MP_TAC o SPECL [`k:num`; `i + 1:num`]) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN + ASM_CASES_TAC `k >= i + 1` THENL + [ + ASM_SIMP_TAC[] THEN DISCH_TAC THEN + REWRITE_TAC[APPEND_ASSOC] THEN + AP_THM_TAC THEN + GEN_REWRITE_TAC (RAND_CONV o ONCE_DEPTH_CONV) [aes256_xts_encrypt_rec] THEN + SUBGOAL_THEN `~(k < i)` ASSUME_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[] THEN + REWRITE_TAC[LET_DEF; LET_END_DEF]; ALL_TAC + ] THEN + SUBGOAL_THEN `k:num = i` ASSUME_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + ONCE_REWRITE_TAC[aes256_xts_encrypt_rec] THEN + REWRITE_TAC[LT_REFL; LET_DEF; LET_END_DEF] THEN + ONCE_REWRITE_TAC[aes256_xts_encrypt_rec] THEN + REWRITE_TAC[ARITH_RULE `i < i + 1`; APPEND_NIL] THEN + AP_TERM_TAC THEN + REWRITE_TAC[aes256_xts_encrypt_tail; LET_DEF; LET_END_DEF] +);; + +let SUB_LIST_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS = prove( + `!(i:num) (pt:byte list) (iv:int128) (key1:int128 list) (key2:int128 list). + (SUB_LIST (0,16 * i) + (aes256_xts_encrypt pt (16 * i + 16) iv key1 key2)) + = aes256_xts_encrypt pt (16 * i) iv key1 key2`, + REPEAT STRIP_TAC THEN + + (* when i = 0, trivial *) + ASM_CASES_TAC `i = 0` THENL + [ + ASM_REWRITE_TAC[] THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[CONJUNCT1 SUB_LIST; aes256_xts_encrypt] THEN + CONV_TAC NUM_REDUCE_CONV; + ALL_TAC + ] THEN + + (* when i = 1, using aes256_xts_encrypt_tail *) + ASM_CASES_TAC `i = 1` THENL + [ + ASM_REWRITE_TAC[] THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[aes256_xts_encrypt] THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + CONV_TAC NUM_REDUCE_CONV THEN + MP_TAC (SPECL [`pt:byte list`; `iv:int128`; `key1: int128 list`; `key2: int128 list`] + LENGTH_OF_AES256_XTS_ENCRYPT_REC_TRIVIAL) THEN + DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_APPEND_LEFT] THEN + CONV_TAC NUM_REDUCE_CONV THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN + REWRITE_TAC[AES256_XTS_ENCRYPT_REC_EQ_TAIL_TRIVIAL]; + ALL_TAC + ] THEN + + (* when i >= 2, using aes256_xts_encrypt_rec *) + REWRITE_TAC[aes256_xts_encrypt] THEN + CONV_TAC NUM_REDUCE_CONV THEN + SUBGOAL_THEN `~(0x10 * i < 0x10)` ASSUME_TAC THENL + [ ASM_ARITH_TAC ; ALL_TAC] THEN + SUBGOAL_THEN `~(0x10 * i + 0x10 < 0x10)` ASSUME_TAC THENL + [ ASM_ARITH_TAC ; ALL_TAC] THEN + ASM_SIMP_TAC[] THEN + REWRITE_TAC[ARITH_RULE `16 * i + 16 = 16 * (i + 1)`; MOD_MULT] THEN + IMP_REWRITE_TAC[LET_DEF;LET_END_DEF;SUB_0;DIV_MULT] THEN + CONV_TAC NUM_REDUCE_CONV THEN + SUBGOAL_THEN `~(i < 0x2)` ASSUME_TAC THENL + [ ASM_ARITH_TAC ; ALL_TAC] THEN + SUBGOAL_THEN `~(i + 1 < 0x2)` ASSUME_TAC THENL + [ ASM_ARITH_TAC ; ALL_TAC] THEN + ASM_SIMP_TAC[ARITH_RULE `(i + 0x1) - 0x2 = i - 1`; ADD_SUB] THEN + SUBGOAL_THEN `LENGTH (aes256_xts_encrypt_rec 0x0 (i - 0x1) pt iv key1 key2) = 16 * i` ASSUME_TAC THENL + [ REWRITE_TAC[LENGTH_OF_AES256_XTS_ENCRYPT_REC] THEN + ASM_ARITH_TAC; ALL_TAC] THEN + IMP_REWRITE_TAC[SUB_LIST_APPEND_LEFT; SUB_LIST_LENGTH_IMPLIES] THEN + CONJ_TAC THENL [ALL_TAC; ARITH_TAC] THEN + SUBGOAL_THEN `i - 1 = i - 2 + 1` ASSUME_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC ] THEN + ASM_REWRITE_TAC[] THEN + IMP_REWRITE_TAC[AES256_XTS_ENCRYPT_REC_EQ_TAIL] THEN + ASM_ARITH_TAC +);; (* void aes_hw_xts_encrypt(const uint8_t *in, uint8_t *out, size_t length, @@ -2115,9 +2246,9 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( num_of_bytelist (aes256_xts_decrypt ct (0x50 * i + 0x50) iv key1 key2)` to: - `read (memory :> bytes (pt_ptr,0x10 * 0x5 * i + 0x40)) s188 = + `read (memory :> bytes (pt_ptr, 0x50 * i + 0x40)) s188 = num_of_bytelist - (aes256_xts_decrypt ct (0x10 * 0x5 * i + 0x40) iv key1 key2)` *) + (aes256_xts_decrypt ct (0x50 * i + 0x40) iv key1 key2)` *) IMP_REWRITE_TAC[ARITH_RULE `0x50 * i + 0x50 = (0x50 * i + 0x40) + 0x10`; READ_BYTES_AND_BYTE128_SPLIT] THEN EXISTS_TAC `(aes256_xts_encrypt pt_in (0x50 * i + 0x50) iv key1_lst key2_lst)` THEN REPEAT CONJ_TAC THENL [ @@ -2145,25 +2276,26 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( ARITH_RULE `(0x5 * i + 0x5) - 0x2 = 0x5 * i + 0x3`; ARITH_RULE `(0x5 * i + 0x5) - 0x1 = 0x5 * i + 0x4`] THEN - MP_TAC (SPECL [`0`;`5 * i + 3:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] - LENGTH_OF_AES256_XTS_DECRYPT_REC) THEN + MP_TAC (SPECL [`0`;`5 * i + 3:num`; `pt_in:byte list`; `iv:int128`; `key1_lst:int128 list`; `key2_lst:int128 list`] + LENGTH_OF_AES256_XTS_ENCRYPT_REC) THEN SIMP_TAC[ARITH_RULE `~(5 * i + 3 < 0)`; ARITH_RULE `((0x5 * i + 0x3) - 0x0 + 0x1) * 0x10 = 0x50 * i + 0x40`] THEN IMP_REWRITE_TAC[SUB_LIST_APPEND_RIGHT_LEMMA] THEN DISCH_TAC THEN - MP_TAC (SPECL [`5 * i + 4:num`; `0x0:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] - LENGTH_OF_AES256_XTS_DECRYPT_TAIL) THEN + MP_TAC (SPECL [`5 * i + 4:num`; `0x0:num`; `pt_in:byte list`; `iv:int128`; + `key1_lst:int128 list`; `key2_lst:int128 list`] + LENGTH_OF_AES256_XTS_ENCRYPT_TAIL) THEN CONV_TAC NUM_REDUCE_CONV THEN REWRITE_TAC[ADD_0] THEN DISCH_TAC THEN IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN - REWRITE_TAC[AES256_XTS_DECRYPT_TAIL_WHEN_1BLOCK] THEN + REWRITE_TAC[AES256_XTS_ENCRYPT_TAIL_WHEN_1BLOCK] THEN SIMP_TAC[ARITH_RULE `i * 0x50 + 0x40 = (i * 0x5 + 0x4) * 0x10`; ARITH_RULE `i * 0x5 = 0x5 * i`]; (* Proving that reading previous bytes is the same as the spec *) REWRITE_TAC[ARITH_RULE `0x50 * i + 0x40 = 0x10 * (5 * i + 4)`; ARITH_RULE `0x50 * i + 0x50 = 0x10 * (5 * i + 4) + 0x10`] THEN - REWRITE_TAC[SUB_LIST_OF_AES256_XTS_DECRYPT_FULL_BLOCKS] THEN + REWRITE_TAC[SUB_LIST_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS] THEN ASM_REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC] THEN CONV_TAC NUM_REDUCE_CONV ] THEN From e0b92985857586e2a3d13e9bce318fc17b39d07f Mon Sep 17 00:00:00 2001 From: Nevine Ebeid Date: Thu, 16 Oct 2025 18:00:53 -0400 Subject: [PATCH 074/132] WIP: subgoal 3 of the loop invariant, at the inductive step, reduced the goal by proving the last 3 rounds in the loop (following the decrypt proof). --- arm/proofs/aes-xts-armv8.ml | 113 ++++++++++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+) diff --git a/arm/proofs/aes-xts-armv8.ml b/arm/proofs/aes-xts-armv8.ml index b55af07b3..f3b84b4f2 100644 --- a/arm/proofs/aes-xts-armv8.ml +++ b/arm/proofs/aes-xts-armv8.ml @@ -2299,6 +2299,119 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( ASM_REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC] THEN CONV_TAC NUM_REDUCE_CONV ] THEN + (* Reduce the goal to contain 0x50 * i + 0x30 *) + IMP_REWRITE_TAC[ARITH_RULE `0x50 * i + 0x40 = (0x50 * i + 0x30) + 0x10`; READ_BYTES_AND_BYTE128_SPLIT] THEN + EXISTS_TAC `(aes256_xts_encrypt pt_in (0x50 * i + 0x40) iv key1_lst key2_lst)` THEN + REPEAT CONJ_TAC THENL [ + REWRITE_TAC [ARITH_RULE `(0x50 * i + 0x30) + 0x10 = 0x50 * i + 0x40`]; + + MP_TAC (SPECL [`0x5 * i + 0x4:num`; `pt_in:byte list`; `iv:int128`; `key1_lst:int128 list`; + `key2_lst:int128 list`] LENGTH_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS) THEN + REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC; GSYM ADD_ASSOC] THEN + CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES]; + + MP_TAC (SPECL [`0x5 * i + 0x4:num`; `pt_in:byte list`; `iv:int128`; `key1_lst:int128 list`; + `key2_lst:int128 list`] LENGTH_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS) THEN + REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC; GSYM ADD_ASSOC] THEN + CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN + ARITH_TAC; + + (* Establish that one xts decrypt round is the same as + selecting one block of bytes from calling the top-level function. *) + REWRITE_TAC[aes256_xts_encrypt] THEN + SIMP_TAC[ARITH_RULE `~(0x50 * i + 0x40 < 0x10)`] THEN + SUBGOAL_THEN `(0x50 * i + 0x40) MOD 0x10 = 0` SUBST1_TAC THENL + [ REWRITE_TAC[ARITH_RULE `80 * i + 64 = 16 * (5 * i + 4)`] THEN + REWRITE_TAC[MOD_MULT] + ; ALL_TAC] THEN + CONV_TAC (DEPTH_CONV let_CONV) THEN + REWRITE_TAC[SUB_0; ARITH_RULE `(0x50 * i + 0x40) DIV 0x10 = 0x5 * i + 0x4`] THEN + SIMP_TAC[ARITH_RULE `~(0x5 * i + 0x4 < 0x2)`; + ARITH_RULE `(0x5 * i + 0x4) - 0x2 = 0x5 * i + 0x2`; + ARITH_RULE `(0x5 * i + 0x4) - 0x1 = 0x5 * i + 0x3`] THEN + + MP_TAC (SPECL [`0`;`5 * i + 2:num`; `pt_in:byte list`; `iv:int128`; `key1_lst:int128 list`; `key2_lst:int128 list`] + LENGTH_OF_AES256_XTS_ENCRYPT_REC) THEN + SIMP_TAC[ARITH_RULE `~(5 * i + 2 < 0)`; + ARITH_RULE `((0x5 * i + 0x2) - 0x0 + 0x1) * 0x10 = 0x50 * i + 0x30`] THEN + IMP_REWRITE_TAC[SUB_LIST_APPEND_RIGHT_LEMMA] THEN DISCH_TAC THEN + + MP_TAC (SPECL [`5 * i + 3:num`; `0x0:num`; `pt_in:byte list`; `iv:int128`; + `key1_lst:int128 list`; `key2_lst:int128 list`] + LENGTH_OF_AES256_XTS_ENCRYPT_TAIL) THEN + CONV_TAC NUM_REDUCE_CONV THEN REWRITE_TAC[ADD_0] THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN + + REWRITE_TAC[AES256_XTS_ENCRYPT_TAIL_WHEN_1BLOCK] THEN + SIMP_TAC[ARITH_RULE `i * 0x50 + 0x30 = (i * 0x5 + 0x3) * 0x10`; + ARITH_RULE `i * 0x5 = 0x5 * i`]; + + (* Proving that reading previous bytes is the same as the spec *) + REWRITE_TAC[ARITH_RULE `0x50 * i + 0x30 = 0x10 * (5 * i + 3)`; + ARITH_RULE `0x50 * i + 0x40 = 0x10 * (5 * i + 3) + 0x10`] THEN + REWRITE_TAC[SUB_LIST_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS] THEN + ASM_REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC] THEN CONV_TAC NUM_REDUCE_CONV + ] THEN + + (* Reduce the goal to contain 0x50 * i + 0x20 *) + IMP_REWRITE_TAC[ARITH_RULE `0x50 * i + 0x30 = (0x50 * i + 0x20) + 0x10`; READ_BYTES_AND_BYTE128_SPLIT] THEN + EXISTS_TAC `(aes256_xts_encrypt pt_in (0x50 * i + 0x30) iv key1_lst key2_lst)` THEN + REPEAT CONJ_TAC THENL [ + REWRITE_TAC [ARITH_RULE `(0x50 * i + 0x20) + 0x10 = 0x50 * i + 0x30`]; + + MP_TAC (SPECL [`0x5 * i + 0x3:num`; `pt_in:byte list`; `iv:int128`; `key1_lst:int128 list`; + `key2_lst:int128 list`] LENGTH_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS) THEN + REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC; GSYM ADD_ASSOC] THEN + CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES]; + + MP_TAC (SPECL [`0x5 * i + 0x3:num`; `pt_in:byte list`; `iv:int128`; `key1_lst:int128 list`; + `key2_lst:int128 list`] LENGTH_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS) THEN + REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC; GSYM ADD_ASSOC] THEN + CONV_TAC NUM_REDUCE_CONV THEN + DISCH_TAC THEN + ASM_REWRITE_TAC[] THEN + ARITH_TAC; + + (* Establish that one xts decrypt round is the same as + selecting one block of bytes from calling the top-level function. *) + REWRITE_TAC[aes256_xts_encrypt] THEN + SIMP_TAC[ARITH_RULE `~(0x50 * i + 0x30 < 0x10)`] THEN + SUBGOAL_THEN `(0x50 * i + 0x30) MOD 0x10 = 0` SUBST1_TAC THENL + [ REWRITE_TAC[ARITH_RULE `80 * i + 48 = 16 * (5 * i + 3)`] THEN + REWRITE_TAC[MOD_MULT] + ; ALL_TAC] THEN + CONV_TAC (DEPTH_CONV let_CONV) THEN + REWRITE_TAC[SUB_0; ARITH_RULE `(0x50 * i + 0x30) DIV 0x10 = 0x5 * i + 0x3`] THEN + SIMP_TAC[ARITH_RULE `~(0x5 * i + 0x3 < 0x2)`; + ARITH_RULE `(0x5 * i + 0x3) - 0x2 = 0x5 * i + 0x1`; + ARITH_RULE `(0x5 * i + 0x3) - 0x1 = 0x5 * i + 0x2`] THEN + + MP_TAC (SPECL [`0`;`5 * i + 1:num`; `pt_in:byte list`; `iv:int128`; `key1_lst:int128 list`; `key2_lst:int128 list`] + LENGTH_OF_AES256_XTS_ENCRYPT_REC) THEN + SIMP_TAC[ARITH_RULE `~(5 * i + 1 < 0)`; + ARITH_RULE `((0x5 * i + 0x1) - 0x0 + 0x1) * 0x10 = 0x50 * i + 0x20`] THEN + IMP_REWRITE_TAC[SUB_LIST_APPEND_RIGHT_LEMMA] THEN DISCH_TAC THEN + + MP_TAC (SPECL [`5 * i + 2:num`; `0x0:num`; `pt_in:byte list`; `iv:int128`; + `key1_lst:int128 list`; `key2_lst:int128 list`] + LENGTH_OF_AES256_XTS_ENCRYPT_TAIL) THEN + CONV_TAC NUM_REDUCE_CONV THEN REWRITE_TAC[ADD_0] THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN + + REWRITE_TAC[AES256_XTS_ENCRYPT_TAIL_WHEN_1BLOCK] THEN + SIMP_TAC[ARITH_RULE `i * 0x50 + 0x20 = (i * 0x5 + 0x2) * 0x10`; + ARITH_RULE `i * 0x5 = 0x5 * i`]; + + (* Proving that reading previous bytes is the same as the spec *) + REWRITE_TAC[ARITH_RULE `0x50 * i + 0x20 = 0x10 * (5 * i + 2)`; + ARITH_RULE `0x50 * i + 0x30 = 0x10 * (5 * i + 2) + 0x10`] THEN + REWRITE_TAC[SUB_LIST_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS] THEN + ASM_REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC] THEN CONV_TAC NUM_REDUCE_CONV + ] THEN + ] From 3e1e4b75920e8580c0841e50ee7b7c125529e1b2 Mon Sep 17 00:00:00 2001 From: Nevine Ebeid Date: Fri, 17 Oct 2025 13:23:21 -0400 Subject: [PATCH 075/132] subgoal 3 of the loop invariant; the inductive step - DONE. --- arm/proofs/aes-xts-armv8.ml | 209 +++++++++++++++++++++++++++++++++++- 1 file changed, 206 insertions(+), 3 deletions(-) diff --git a/arm/proofs/aes-xts-armv8.ml b/arm/proofs/aes-xts-armv8.ml index f3b84b4f2..1089fb581 100644 --- a/arm/proofs/aes-xts-armv8.ml +++ b/arm/proofs/aes-xts-armv8.ml @@ -2299,7 +2299,7 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( ASM_REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC] THEN CONV_TAC NUM_REDUCE_CONV ] THEN - (* Reduce the goal to contain 0x50 * i + 0x30 *) + (** Reduce the goal to contain 0x50 * i + 0x30 **) IMP_REWRITE_TAC[ARITH_RULE `0x50 * i + 0x40 = (0x50 * i + 0x30) + 0x10`; READ_BYTES_AND_BYTE128_SPLIT] THEN EXISTS_TAC `(aes256_xts_encrypt pt_in (0x50 * i + 0x40) iv key1_lst key2_lst)` THEN REPEAT CONJ_TAC THENL [ @@ -2355,7 +2355,7 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( ASM_REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC] THEN CONV_TAC NUM_REDUCE_CONV ] THEN - (* Reduce the goal to contain 0x50 * i + 0x20 *) + (** Reduce the goal to contain 0x50 * i + 0x20 **) IMP_REWRITE_TAC[ARITH_RULE `0x50 * i + 0x30 = (0x50 * i + 0x20) + 0x10`; READ_BYTES_AND_BYTE128_SPLIT] THEN EXISTS_TAC `(aes256_xts_encrypt pt_in (0x50 * i + 0x30) iv key1_lst key2_lst)` THEN REPEAT CONJ_TAC THENL [ @@ -2412,13 +2412,216 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( ASM_REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC] THEN CONV_TAC NUM_REDUCE_CONV ] THEN - ] + (** Reduce the goal to contain 0x50 * i + 0x10 **) + REWRITE_TAC[ARITH_RULE `0x50 * i + 0x20 = (0x50 * i + 0x10) + 0x10`] THEN + (* Use SPECL to force IMP_REWRITE_TAC to apply once *) + IMP_REWRITE_TAC[(SPECL [`ctxt_p:int64`; `(0x50 * i + 0x10):num`; + `x:byte list`; `s188:armstate`] READ_BYTES_AND_BYTE128_SPLIT)] THEN + EXISTS_TAC `(aes256_xts_encrypt pt_in (0x50 * i + 0x20) iv key1_lst key2_lst)` THEN + REPEAT CONJ_TAC THENL [ + REWRITE_TAC [ARITH_RULE `(0x50 * i + 0x10) + 0x10 = 0x50 * i + 0x20`]; + + MP_TAC (SPECL [`0x5 * i + 0x2:num`; `pt_in:byte list`; `iv:int128`; `key1_lst:int128 list`; + `key2_lst:int128 list`] LENGTH_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS) THEN + REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC; GSYM ADD_ASSOC] THEN + CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES]; + + MP_TAC (SPECL [`0x5 * i + 0x2:num`; `pt_in:byte list`; `iv:int128`; `key1_lst:int128 list`; + `key2_lst:int128 list`] LENGTH_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS) THEN + REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC; GSYM ADD_ASSOC] THEN + CONV_TAC NUM_REDUCE_CONV THEN + DISCH_TAC THEN + ASM_REWRITE_TAC[] THEN + ARITH_TAC; + + (* Establish that one xts decrypt round is the same as + selecting one block of bytes from calling the top-level function. *) + REWRITE_TAC[aes256_xts_encrypt] THEN + SIMP_TAC[ARITH_RULE `~(0x50 * i + 0x20 < 0x10)`] THEN + SUBGOAL_THEN `(0x50 * i + 0x20) MOD 0x10 = 0` SUBST1_TAC THENL + [ REWRITE_TAC[ARITH_RULE `80 * i + 32 = 16 * (5 * i + 2)`] THEN + REWRITE_TAC[MOD_MULT] + ; ALL_TAC] THEN + CONV_TAC (DEPTH_CONV let_CONV) THEN + REWRITE_TAC[SUB_0; ARITH_RULE `(0x50 * i + 0x20) DIV 0x10 = 0x5 * i + 0x2`] THEN + SIMP_TAC[ARITH_RULE `~(0x5 * i + 0x2 < 0x2)`; + ARITH_RULE `(0x5 * i + 0x2) - 0x2 = 0x5 * i`; + ARITH_RULE `(0x5 * i + 0x2) - 0x1 = 0x5 * i + 0x1`] THEN + + MP_TAC (SPECL [`0`;`5 * i:num`; `pt_in:byte list`; `iv:int128`; `key1_lst:int128 list`; `key2_lst:int128 list`] + LENGTH_OF_AES256_XTS_ENCRYPT_REC) THEN + SIMP_TAC[ARITH_RULE `~(5 * i < 0)`; + ARITH_RULE `((0x5 * i) - 0x0 + 0x1) * 0x10 = 0x50 * i + 0x10`] THEN + IMP_REWRITE_TAC[SUB_LIST_APPEND_RIGHT_LEMMA] THEN DISCH_TAC THEN + + MP_TAC (SPECL [`5 * i + 1:num`; `0x0:num`; `pt_in:byte list`; `iv:int128`; + `key1_lst:int128 list`; `key2_lst:int128 list`] + LENGTH_OF_AES256_XTS_ENCRYPT_TAIL) THEN + CONV_TAC NUM_REDUCE_CONV THEN REWRITE_TAC[ADD_0] THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN + + REWRITE_TAC[AES256_XTS_ENCRYPT_TAIL_WHEN_1BLOCK] THEN + SIMP_TAC[ARITH_RULE `i * 0x50 + 0x10 = (i * 0x5 + 0x1) * 0x10`; + ARITH_RULE `i * 0x5 = 0x5 * i`]; + + (* Proving that reading previous bytes is the same as the spec *) + REWRITE_TAC[ARITH_RULE `0x50 * i + 0x10 = 0x10 * (5 * i + 1)`; + ARITH_RULE `0x50 * i + 0x20 = 0x10 * (5 * i + 1) + 0x10`] THEN + REWRITE_TAC[SUB_LIST_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS] THEN + ASM_REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC] THEN CONV_TAC NUM_REDUCE_CONV + ] THEN + + (** Reduce the goal to ?? **) + (* + `read (memory :> bytes (ctxt_p,0x50 * i + 0x10)) s188 = + num_of_bytelist + (aes256_xts_encrypt pt_in (0x50 * i + 0x10) iv key1_lst key2_lst)` + *) + (* Using SPECL with `x` does not yield a correct goal; it contains as one of the conjuctions: + `num_of_bytelist + (SUB_LIST (0x0,0x50 * i + 0x10) + (aes256_xts_encrypt pt_in (i * 0x50) iv key1_lst key2_lst)) = + num_of_bytelist + (aes256_xts_encrypt pt_in (0x50 * i + 0x10) iv key1_lst key2_lst) + *) + IMP_REWRITE_TAC[(SPECL [`ctxt_p:int64`; `(0x50 * i):num`; + `(aes256_xts_encrypt pt_in (0x50 * i + 0x10) iv key1_lst key2_lst):byte list`; `s188:armstate`] + READ_BYTES_AND_BYTE128_SPLIT)] THEN + EXISTS_TAC `iv:int128` THEN EXISTS_TAC `key1_lst:int128 list` THEN + EXISTS_TAC `key2_lst:int128 list` THEN EXISTS_TAC `pt_in:byte list` THEN + + REPEAT CONJ_TAC THENL [ + MP_TAC (SPECL [`0x5 * i + 0x1:num`; `pt_in:byte list`; `iv:int128`; `key1_lst:int128 list`; + `key2_lst:int128 list`] LENGTH_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS) THEN + REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC; GSYM ADD_ASSOC] THEN + CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES]; + + MP_TAC (SPECL [`0x5 * i + 0x1:num`; `pt_in:byte list`; `iv:int128`; `key1_lst:int128 list`; + `key2_lst:int128 list`] LENGTH_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS) THEN + REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC; GSYM ADD_ASSOC] THEN + CONV_TAC NUM_REDUCE_CONV THEN + DISCH_TAC THEN ASM_REWRITE_TAC[] THEN ARITH_TAC; + + (* Establish that one xts decrypt round is the same as + selecting one block of bytes from calling the top-level function. *) + REWRITE_TAC[aes256_xts_encrypt] THEN + SIMP_TAC[ARITH_RULE `~(0x50 * i + 0x10 < 0x10)`] THEN + SUBGOAL_THEN `(0x50 * i + 0x10) MOD 0x10 = 0` SUBST1_TAC THENL + [ REWRITE_TAC[ARITH_RULE `80 * i + 16 = 16 * (5 * i + 1)`] THEN + REWRITE_TAC[MOD_MULT] + ; ALL_TAC] THEN + CONV_TAC (DEPTH_CONV let_CONV) THEN + REWRITE_TAC[SUB_0; ARITH_RULE `(0x50 * i + 0x10) DIV 0x10 = 0x5 * i + 0x1`] THEN + + (* Two cases: i = 0 then execute tail branch, else execute recursion branch *) + COND_CASES_TAC THENL + [ SUBGOAL_THEN `i = 0` SUBST1_TAC THENL + [ UNDISCH_TAC `5 * i + 1 < 2` THEN + UNDISCH_TAC `0 <= i` THEN + ARITH_TAC + ; ALL_TAC] THEN CONV_TAC NUM_REDUCE_CONV THEN + + MP_TAC (SPECL [`0:num`; `0x0:num`; `pt_in:byte list`; `iv:int128`; `key1_lst:int128 list`; `key2_lst:int128 list`] + LENGTH_OF_AES256_XTS_ENCRYPT_TAIL) THEN + CONV_TAC NUM_REDUCE_CONV THEN REWRITE_TAC[ADD_0] THEN DISCH_TAC THEN + IMP_REWRITE_TAC[(ISPECL [`(aes256_xts_encrypt_tail 0x0 0x0 pt_in iv key1_lst key2_lst):byte list`; + `0x10:num`] SUB_LIST_LENGTH_IMPLIES)] THEN + + REWRITE_TAC[AES256_XTS_DECRYPT_TAIL_WHEN_1BLOCK] THEN + CONV_TAC NUM_REDUCE_CONV; + + (* i != 0 *) + SIMP_TAC[ARITH_RULE `(0x5 * i + 0x1) - 0x2 = 0x5 * i - 0x1`; + ARITH_RULE `(0x5 * i + 0x1) - 0x1 = 0x5 * i`] THEN + MP_TAC (SPECL [`0`;`5 * i - 1:num`; `pt_in:byte list`; `iv:int128`; `key1_lst:int128 list`; `key2_lst:int128 list`] + LENGTH_OF_AES256_XTS_ENCRYPT_REC) THEN + SUBGOAL_THEN `~(0x5 * i - 0x1 < 0x0)` ASSUME_TAC THENL + [ UNDISCH_TAC `~(0x5 * i + 0x1 < 0x2)` THEN ARITH_TAC; ALL_TAC ] THEN + ASM_SIMP_TAC[] THEN + IMP_REWRITE_TAC[ARITH_RULE `~(0x5 * i + 0x1 < 0x2) ==> (0x5 * i - 1 - 0x0 + 0x1) * 0x10 = 0x50 * i`] THEN + IMP_REWRITE_TAC[SUB_LIST_APPEND_RIGHT_LEMMA] THEN DISCH_TAC THEN + + MP_TAC (SPECL [`5 * i:num`; `0x0:num`; `pt_in:byte list`; `iv:int128`; + `key1_lst:int128 list`; `key2_lst:int128 list`] + LENGTH_OF_AES256_XTS_ENCRYPT_TAIL) THEN + CONV_TAC NUM_REDUCE_CONV THEN REWRITE_TAC[ADD_0] THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN + + REWRITE_TAC[AES256_XTS_DECRYPT_TAIL_WHEN_1BLOCK] THEN + SIMP_TAC[ARITH_RULE `i * 0x50 = (i * 0x5) * 0x10`; + ARITH_RULE `i * 0x5 = 0x5 * i`] + ]; + + (* Proving that reading previous bytes is the same as the spec *) + REWRITE_TAC[ARITH_RULE `i * 0x50 = 0x50 * i`; + ARITH_RULE `0x50 * i = 0x10 * 5 * i`; + ARITH_RULE `0x50 * i + 0x10 = 0x10 * 5 * i + 0x10`] THEN + REWRITE_TAC[SUB_LIST_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS] THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN + REWRITE_TAC[LENGTH_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS] + ]; + + SUBGOAL_THEN `i + 1 < 2 EXP 64` ASSUME_TAC THENL + [ + UNDISCH_TAC `i < val (num_5blocks:int64)` THEN + EXPAND_TAC "num_5blocks" THEN + UNDISCH_TAC `val (len_full_blocks:int64) <= 0x2 EXP 0x18` THEN + REWRITE_TAC [VAL_WORD; DIMINDEX_64] THEN ARITH_TAC; ALL_TAC + ] THEN + EQ_TAC THENL + [ REWRITE_TAC[WORD_RULE `!x:int64 a b. (word_sub (word_sub x a) b) = word_sub x (word_add a b)`] THEN + ASM_SIMP_TAC[WORD_RULE `!a b. a + b < 2 EXP 64 ==> (word_add (word a) (word b)) = word (a + b)`] THEN + REWRITE_TAC[VAL_EQ_0; WORD_SUB_EQ_0] THEN + DISCH_TAC THEN ASM_REWRITE_TAC[] THEN + IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT]; + REWRITE_TAC[WORD_RULE `!x:int64 a b. (word_sub (word_sub x a) b) = word_sub x (word_add a b)`] THEN + ASM_SIMP_TAC[WORD_RULE `!a b. a + b < 2 EXP 64 ==> (word_add (word a) (word b)) = word (a + b)`] THEN + REWRITE_TAC[VAL_EQ_0; WORD_SUB_EQ_0; WORD_VAL] + ] + ]; ] );; (* + +(* + IMP_REWRITE_TAC[ARITH_RULE `0x50 * i + 0x20 = (0x50 * i + 0x10) + 0x10`; READ_BYTES_AND_BYTE128_SPLIT] THEN + EXISTS_TAC `(aes256_xts_encrypt pt_in (0x50 * i + 0x20) iv key1_lst key2_lst)` THEN + +`num_of_bytelist + (SUB_LIST (0x0,(0x50 * i + 0x10) + 0x10) + (aes256_xts_encrypt pt_in (0x50 * i + 0x20) iv key1_lst key2_lst)) = + num_of_bytelist + (aes256_xts_encrypt pt_in ((0x50 * i + 0x10) + 0x10) iv key1_lst key2_lst) /\ + (0x50 * i + 0x10) + 0x10 <= + LENGTH (aes256_xts_encrypt pt_in (0x50 * i + 0x20) iv key1_lst key2_lst) /\ + aes256_xts_encrypt_round + (bytes_to_int128 (SUB_LIST (i * 0x50 + 0x10,0x10) pt_in)) + (calculate_tweak (i * 0x5 + 0x1) iv key2_lst) + key1_lst = + bytes_to_int128 + (SUB_LIST (0x50 * i + 0x10,0x10) + (aes256_xts_encrypt pt_in (0x50 * i + 0x20) iv key1_lst key2_lst)) /\ + num_of_bytelist + (SUB_LIST (0x0,0x50 * i + 0x10) + (aes256_xts_encrypt pt_in (i * 0x50) iv key1_lst key2_lst)) = + num_of_bytelist + (SUB_LIST (0x0,0x50 * i + 0x10) + (aes256_xts_encrypt pt_in (0x50 * i + 0x20) iv key1_lst key2_lst)) /\ + aes256_xts_encrypt_round (bytes_to_int128 (SUB_LIST (i * 0x50,0x10) pt_in)) + (calculate_tweak (i * 0x5) iv key2_lst) + key1_lst = + bytes_to_int128 + (SUB_LIST (0x50 * i,0x10) + (aes256_xts_encrypt pt_in (i * 0x50) iv key1_lst key2_lst)) /\ + 0x50 * i + 0x10 <= + LENGTH (aes256_xts_encrypt pt_in (i * 0x50) iv key1_lst key2_lst)` +*) + `exists x. num_of_bytelist (SUB_LIST (0x0,(0x50 * i + 0x40) + 0x10) x) = num_of_bytelist From c7d22eef9a512ec06c6b1eb88275dda85092d257 Mon Sep 17 00:00:00 2001 From: Nevine Ebeid Date: Mon, 20 Oct 2025 12:10:52 -0400 Subject: [PATCH 076/132] Subgoal 4 of main loop invariant: backedge is not taken until i = num_5blocks. --- arm/proofs/aes-xts-armv8.ml | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/arm/proofs/aes-xts-armv8.ml b/arm/proofs/aes-xts-armv8.ml index 1089fb581..d3b7ebf18 100644 --- a/arm/proofs/aes-xts-armv8.ml +++ b/arm/proofs/aes-xts-armv8.ml @@ -2472,7 +2472,7 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( ASM_REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC] THEN CONV_TAC NUM_REDUCE_CONV ] THEN - (** Reduce the goal to ?? **) + (** Reduce the goal to 0x50 * i **) (* `read (memory :> bytes (ctxt_p,0x50 * i + 0x10)) s188 = num_of_bytelist @@ -2582,6 +2582,17 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( ] ]; + (** Subgoal 4 of main loop invariant: + prove backedge is taken if i != val num_5blocks **) + REPEAT STRIP_TAC THEN + REWRITE_TAC[byte_list_at] THEN + ENSURES_INIT_TAC "s0" THEN + ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (1--1) THEN + SUBGOAL_THEN `~(val (word_sub (num_5blocks:int64) (word i)) = 0x0)` ASSUME_TAC THENL + [ UNDISCH_TAC `i < val (num_5blocks:int64)` THEN WORD_ARITH_TAC; ALL_TAC] THEN + POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th])) THEN + ENSURES_FINAL_STATE_TAC THEN ASM_SIMP_TAC[]; + ] );; From 4ad8a49788ce1bcf01bd87caace563c949089ce7 Mon Sep 17 00:00:00 2001 From: Nevine Ebeid Date: Fri, 24 Oct 2025 19:44:27 -0400 Subject: [PATCH 077/132] Assembly changes in cipher-stealing from AWS-LC PR2734 to avoid looping. Subgoal 5: WIP. --- arm/aes-xts/aes-xts-armv8.S | 32 +- arm/aes-xts/aes-xts-armv8.txt | 43 +- arm/proofs/aes-xts-armv8.ml | 1244 +++++++++++++++++++++++++++++---- 3 files changed, 1154 insertions(+), 165 deletions(-) diff --git a/arm/aes-xts/aes-xts-armv8.S b/arm/aes-xts/aes-xts-armv8.S index 7d7d2d394..d53d44b09 100644 --- a/arm/aes-xts/aes-xts-armv8.S +++ b/arm/aes-xts/aes-xts-armv8.S @@ -577,22 +577,22 @@ S2N_BN_SYMBOL(aes_hw_xts_encrypt): eor v26.16b,v26.16b,v6.16b // Encrypt the composite block to get the last second encrypted text block - ldr w6,[x3,#240] // load key schedule... - ld1 {v0.16b},[x3],#16 - sub w6,w6,#2 - ld1 {v1.16b},[x3],#16 // load key schedule... -.Loop_final_enc: - aesr(v26.16b, v0.16b) - ld1 {v0.4s},[x3],#16 - subs w6,w6,#2 - aesr(v26.16b, v1.16b) - ld1 {v1.4s},[x3],#16 - b.gt .Loop_final_enc - - aesr(v26.16b, v0.16b) - ld1 {v0.4s},[x3] - aese v26.16b,v1.16b - eor v26.16b,v26.16b,v0.16b + aesr(v26.16b, v16.16b) + aesr(v26.16b, v17.16b) + aesr(v26.16b, v12.16b) + aesr(v26.16b, v13.16b) + aesr(v26.16b, v14.16b) + aesr(v26.16b, v15.16b) + aesr(v26.16b, v4.16b) + aesr(v26.16b, v5.16b) + aesr(v26.16b, v18.16b) + aesr(v26.16b, v19.16b) + aesr(v26.16b, v20.16b) + aesr(v26.16b, v21.16b) + aesr(v26.16b, v22.16b) + aese v26.16b,v23.16b + eor v26.16b,v26.16b,v7.16b + eor v26.16b,v26.16b,v6.16b st1 {v26.16b},[x1] diff --git a/arm/aes-xts/aes-xts-armv8.txt b/arm/aes-xts/aes-xts-armv8.txt index ad2f00663..3c82bd3d7 100644 --- a/arm/aes-xts/aes-xts-armv8.txt +++ b/arm/aes-xts/aes-xts-armv8.txt @@ -7,7 +7,7 @@ 0xa90053f3; (* arm_STP X19 X20 SP (Immediate_Offset (iword (&0x0))) *) 0xa9015bf5; (* arm_STP X21 X22 SP (Immediate_Offset (iword (&0x10))) *) 0xf100405f; (* arm_CMP X2 (rvalue (word 0x10)) *) - 0x5400520b; (* arm_BLT (word 0xa40) *) + 0x5400536b; (* arm_BLT (word 0xa6c) *) 0xd503201f; (* arm_NOP *) 0xd503201f; (* arm_NOP *) 0xd503201f; (* arm_NOP *) @@ -632,7 +632,7 @@ 0x14000002; (* arm_B (word 0x8) *) 0xd503201f; (* arm_NOP *) 0xf2400ebf; (* arm_TST X21 (rvalue (word 0xf)) *) - 0x540003e0; (* arm_BEQ (word 0x7c) *) + 0x54000540; (* arm_BEQ (word 0xa8) *) 0xaa0003f4; (* arm_MOV X20 X0 *) 0xaa0103ed; (* arm_MOV X13 X1 *) 0xd1004021; (* arm_SUB X1 X1 (rvalue (word 0x10)) *) @@ -644,23 +644,34 @@ 0x54ffff6c; (* arm_BGT (word 0x1fffec) *) 0x4c40703a; (* arm_LDR Q26 X1 No_Offset *) 0x6e261f5a; (* arm_EOR_VEC Q26 Q26 Q6 0x80 *) - 0xb940f066; (* arm_LDR W6 X3 (Immediate_Offset (word 0xf0)) *) - 0x4cdf7060; (* arm_LDR Q0 X3 (Postimmediate_Offset (word 0x10)) *) - 0x510008c6; (* arm_SUB W6 W6 (rvalue (word 0x2)) *) - 0x4cdf7061; (* arm_LDR Q1 X3 (Postimmediate_Offset (word 0x10)) *) - 0x4e28481a; (* arm_AESE Q26 Q0 *) + 0x4e284a1a; (* arm_AESE Q26 Q16 *) 0x4e286b5a; (* arm_AESMC Q26 Q26 *) - 0x4cdf7860; (* arm_LDR Q0 X3 (Postimmediate_Offset (word 0x10)) *) - 0x710008c6; (* arm_SUBS W6 W6 (rvalue (word 0x2)) *) - 0x4e28483a; (* arm_AESE Q26 Q1 *) + 0x4e284a3a; (* arm_AESE Q26 Q17 *) 0x4e286b5a; (* arm_AESMC Q26 Q26 *) - 0x4cdf7861; (* arm_LDR Q1 X3 (Postimmediate_Offset (word 0x10)) *) - 0x54ffff2c; (* arm_BGT (word 0x1fffe4) *) - 0x4e28481a; (* arm_AESE Q26 Q0 *) + 0x4e28499a; (* arm_AESE Q26 Q12 *) + 0x4e286b5a; (* arm_AESMC Q26 Q26 *) + 0x4e2849ba; (* arm_AESE Q26 Q13 *) + 0x4e286b5a; (* arm_AESMC Q26 Q26 *) + 0x4e2849da; (* arm_AESE Q26 Q14 *) + 0x4e286b5a; (* arm_AESMC Q26 Q26 *) + 0x4e2849fa; (* arm_AESE Q26 Q15 *) + 0x4e286b5a; (* arm_AESMC Q26 Q26 *) + 0x4e28489a; (* arm_AESE Q26 Q4 *) 0x4e286b5a; (* arm_AESMC Q26 Q26 *) - 0x4c407860; (* arm_LDR Q0 X3 No_Offset *) - 0x4e28483a; (* arm_AESE Q26 Q1 *) - 0x6e201f5a; (* arm_EOR_VEC Q26 Q26 Q0 0x80 *) + 0x4e2848ba; (* arm_AESE Q26 Q5 *) + 0x4e286b5a; (* arm_AESMC Q26 Q26 *) + 0x4e284a5a; (* arm_AESE Q26 Q18 *) + 0x4e286b5a; (* arm_AESMC Q26 Q26 *) + 0x4e284a7a; (* arm_AESE Q26 Q19 *) + 0x4e286b5a; (* arm_AESMC Q26 Q26 *) + 0x4e284a9a; (* arm_AESE Q26 Q20 *) + 0x4e286b5a; (* arm_AESMC Q26 Q26 *) + 0x4e284aba; (* arm_AESE Q26 Q21 *) + 0x4e286b5a; (* arm_AESMC Q26 Q26 *) + 0x4e284ada; (* arm_AESE Q26 Q22 *) + 0x4e286b5a; (* arm_AESMC Q26 Q26 *) + 0x4e284afa; (* arm_AESE Q26 Q23 *) + 0x6e271f5a; (* arm_EOR_VEC Q26 Q26 Q7 0x80 *) 0x6e261f5a; (* arm_EOR_VEC Q26 Q26 Q6 0x80 *) 0x4c00703a; (* arm_STR Q26 X1 No_Offset *) 0xa94053f3; (* arm_LDP X19 X20 SP (Immediate_Offset (iword (&0x0))) *) diff --git a/arm/proofs/aes-xts-armv8.ml b/arm/proofs/aes-xts-armv8.ml index d3b7ebf18..bbee43e2c 100644 --- a/arm/proofs/aes-xts-armv8.ml +++ b/arm/proofs/aes-xts-armv8.ml @@ -36,7 +36,7 @@ let aes256_xts_encrypt_mc = define_assert_from_elf "aes256_xts_encrypt_mc" "arm/ 0xa90053f3; (* arm_STP X19 X20 SP (Immediate_Offset (iword (&0x0))) *) 0xa9015bf5; (* arm_STP X21 X22 SP (Immediate_Offset (iword (&0x10))) *) 0xf100405f; (* arm_CMP X2 (rvalue (word 0x10)) *) - 0x5400520b; (* arm_BLT (word 0xa40) *) + 0x5400536b; (* arm_BLT (word 0xa6c) *) 0xd503201f; (* arm_NOP *) 0xd503201f; (* arm_NOP *) 0xd503201f; (* arm_NOP *) @@ -312,6 +312,7 @@ let aes256_xts_encrypt_mc = define_assert_from_elf "aes256_xts_encrypt_mc" "arm/ 0xb5ffe888; (* arm_CBNZ X8 (word 0x1ffd10) *) (* .Loop5x_enc_after: *) + (* pc + 0x434 *) 0xf101005f; (* arm_CMP X2 (rvalue (word 0x40)) *) 0x54000140; (* arm_BEQ (word 0x28) *) 0xf100c05f; (* arm_CMP X2 (rvalue (word 0x30)) *) @@ -635,6 +636,7 @@ let aes256_xts_encrypt_mc = define_assert_from_elf "aes256_xts_encrypt_mc" "arm/ 0x1400002b; (* arm_B (word 0xac) *) (* Lxts_enc_tail1x: *) + (* pc + 0x938 *) 0x4cdf7000; (* arm_LDR Q0 X0 (Postimmediate_Offset (word 0x10)) *) 0x6e261c00; (* arm_EOR_VEC Q0 Q0 Q6 0x80 *) 0x4e284a00; (* arm_AESE Q0 Q16 *) @@ -679,8 +681,9 @@ let aes256_xts_encrypt_mc = define_assert_from_elf "aes256_xts_encrypt_mc" "arm/ 0xd503201f; (* arm_NOP *) (* Lxts_enc_done: *) + (* pc + 0x9e0 *) 0xf2400ebf; (* arm_TST X21 (rvalue (word 0xf)) *) - 0x540003e0; (* arm_BEQ (word 0x7c) *) + 0x54000540; (* arm_BEQ (word 0xa8) *) 0xaa0003f4; (* arm_MOV X20 X0 *) 0xaa0103ed; (* arm_MOV X13 X1 *) 0xd1004021; (* arm_SUB X1 X1 (rvalue (word 0x10)) *) @@ -692,23 +695,36 @@ let aes256_xts_encrypt_mc = define_assert_from_elf "aes256_xts_encrypt_mc" "arm/ 0x54ffff6c; (* arm_BGT (word 0x1fffec) *) 0x4c40703a; (* arm_LDR Q26 X1 No_Offset *) 0x6e261f5a; (* arm_EOR_VEC Q26 Q26 Q6 0x80 *) - 0xb940f066; (* arm_LDR W6 X3 (Immediate_Offset (word 0xf0)) *) - 0x4cdf7060; (* arm_LDR Q0 X3 (Postimmediate_Offset (word 0x10)) *) - 0x510008c6; (* arm_SUB W6 W6 (rvalue (word 0x2)) *) - 0x4cdf7061; (* arm_LDR Q1 X3 (Postimmediate_Offset (word 0x10)) *) - 0x4e28481a; (* arm_AESE Q26 Q0 *) + + 0x4e284a1a; (* arm_AESE Q26 Q16 *) 0x4e286b5a; (* arm_AESMC Q26 Q26 *) - 0x4cdf7860; (* arm_LDR Q0 X3 (Postimmediate_Offset (word 0x10)) *) - 0x710008c6; (* arm_SUBS W6 W6 (rvalue (word 0x2)) *) - 0x4e28483a; (* arm_AESE Q26 Q1 *) + 0x4e284a3a; (* arm_AESE Q26 Q17 *) 0x4e286b5a; (* arm_AESMC Q26 Q26 *) - 0x4cdf7861; (* arm_LDR Q1 X3 (Postimmediate_Offset (word 0x10)) *) - 0x54ffff2c; (* arm_BGT (word 0x1fffe4) *) - 0x4e28481a; (* arm_AESE Q26 Q0 *) + 0x4e28499a; (* arm_AESE Q26 Q12 *) + 0x4e286b5a; (* arm_AESMC Q26 Q26 *) + 0x4e2849ba; (* arm_AESE Q26 Q13 *) + 0x4e286b5a; (* arm_AESMC Q26 Q26 *) + 0x4e2849da; (* arm_AESE Q26 Q14 *) + 0x4e286b5a; (* arm_AESMC Q26 Q26 *) + 0x4e2849fa; (* arm_AESE Q26 Q15 *) 0x4e286b5a; (* arm_AESMC Q26 Q26 *) - 0x4c407860; (* arm_LDR Q0 X3 No_Offset *) - 0x4e28483a; (* arm_AESE Q26 Q1 *) - 0x6e201f5a; (* arm_EOR_VEC Q26 Q26 Q0 0x80 *) + 0x4e28489a; (* arm_AESE Q26 Q4 *) + 0x4e286b5a; (* arm_AESMC Q26 Q26 *) + 0x4e2848ba; (* arm_AESE Q26 Q5 *) + 0x4e286b5a; (* arm_AESMC Q26 Q26 *) + 0x4e284a5a; (* arm_AESE Q26 Q18 *) + 0x4e286b5a; (* arm_AESMC Q26 Q26 *) + 0x4e284a7a; (* arm_AESE Q26 Q19 *) + 0x4e286b5a; (* arm_AESMC Q26 Q26 *) + 0x4e284a9a; (* arm_AESE Q26 Q20 *) + 0x4e286b5a; (* arm_AESMC Q26 Q26 *) + 0x4e284aba; (* arm_AESE Q26 Q21 *) + 0x4e286b5a; (* arm_AESMC Q26 Q26 *) + 0x4e284ada; (* arm_AESE Q26 Q22 *) + 0x4e286b5a; (* arm_AESMC Q26 Q26 *) + 0x4e284afa; (* arm_AESE Q26 Q23 *) + 0x6e271f5a; (* arm_EOR_VEC Q26 Q26 Q7 0x80 *) + 0x6e261f5a; (* arm_EOR_VEC Q26 Q26 Q6 0x80 *) 0x4c00703a; (* arm_STR Q26 X1 No_Offset *) 0xa94053f3; (* arm_LDP X19 X20 SP (Immediate_Offset (iword (&0x0))) *) @@ -1086,6 +1102,318 @@ let BYTE_LIST_AT_5BLOCKS = prove( ] );; +let BYTE_LIST_AT_4BLOCKS = prove( + `! pos bl bl_ptr len s. + byte_list_at bl bl_ptr len s + ==> LENGTH bl = val len + ==> pos + 0x40 <= LENGTH bl + ==> (read (memory :> bytes128 (word_add bl_ptr (word pos))) s = + bytes_to_int128 (SUB_LIST (pos, 0x10) bl) /\ + read (memory :> bytes128 (word_add (word_add bl_ptr (word pos)) (word 0x10))) s = + bytes_to_int128 (SUB_LIST (pos + 0x10, 0x10) bl) /\ + read (memory :> bytes128 (word_add (word_add bl_ptr (word pos)) (word 0x20))) s = + bytes_to_int128 (SUB_LIST (pos + 0x20, 0x10) bl) /\ + read (memory :> bytes128 (word_add (word_add bl_ptr (word pos)) (word 0x30))) s = + bytes_to_int128 (SUB_LIST (pos + 0x30, 0x10) bl))`, + REWRITE_TAC[byte_list_at] THEN + REPEAT STRIP_TAC THENL + [ (* Subgoal1 *) + MAP_EVERY (fun i -> BYTE_LIST_AT_ADD_ASSUM_TAC + (mk_binop (mk_const("+", [`:num`, `:A`])) (mk_var("pos", `:num`)) + (mk_numeral (num i))) `0x40`) (0--15) THEN + REWRITE_TAC[WORD_ADD_ASSOC_CONSTS] THEN + REPEAT STRIP_TAC THEN + ASM_REWRITE_TAC[BYTES128_TO_BYTES8_THM; GSYM ADD_ASSOC] THEN + NUM_REDUCE_TAC THEN ASM_REWRITE_TAC[] THEN AP_TERM_TAC THEN + MP_TAC (ISPECL [`bl:byte list`; `pos:num`] SUB_LIST_16) THEN + REWRITE_TAC[GSYM ADD_ASSOC] THEN NUM_REDUCE_TAC THEN + DISCH_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_ARITH_TAC; + (* Subgoal2 *) + MAP_EVERY (fun i -> BYTE_LIST_AT_ADD_ASSUM_TAC + (mk_binop (mk_const("+", [`:num`, `:A`])) (mk_var("pos", `:num`)) + (mk_numeral (num i))) `0x40`) (16--31) THEN + REWRITE_TAC[WORD_ADD_ASSOC_CONSTS] THEN + REPEAT STRIP_TAC THEN + ASM_REWRITE_TAC[BYTES128_TO_BYTES8_THM; GSYM ADD_ASSOC] THEN + NUM_REDUCE_TAC THEN ASM_REWRITE_TAC[] THEN AP_TERM_TAC THEN + MP_TAC (ISPECL [`bl:byte list`; `(pos+0x10):num`] SUB_LIST_16) THEN + REWRITE_TAC[GSYM ADD_ASSOC] THEN NUM_REDUCE_TAC THEN + DISCH_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_ARITH_TAC; + (* Subgoal3 *) + MAP_EVERY (fun i -> BYTE_LIST_AT_ADD_ASSUM_TAC + (mk_binop (mk_const("+", [`:num`, `:A`])) (mk_var("pos", `:num`)) + (mk_numeral (num i))) `0x40`) (32--47) THEN + REWRITE_TAC[WORD_ADD_ASSOC_CONSTS] THEN + REPEAT STRIP_TAC THEN + ASM_REWRITE_TAC[BYTES128_TO_BYTES8_THM; GSYM ADD_ASSOC] THEN + NUM_REDUCE_TAC THEN ASM_REWRITE_TAC[] THEN AP_TERM_TAC THEN + MP_TAC (ISPECL [`bl:byte list`; `(pos+0x20):num`] SUB_LIST_16) THEN + REWRITE_TAC[GSYM ADD_ASSOC] THEN NUM_REDUCE_TAC THEN + DISCH_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_ARITH_TAC; + (* Subgoal4 *) + MAP_EVERY (fun i -> BYTE_LIST_AT_ADD_ASSUM_TAC + (mk_binop (mk_const("+", [`:num`, `:A`])) (mk_var("pos", `:num`)) + (mk_numeral (num i))) `0x40`) (48--63) THEN + REWRITE_TAC[WORD_ADD_ASSOC_CONSTS] THEN + REPEAT STRIP_TAC THEN + ASM_REWRITE_TAC[BYTES128_TO_BYTES8_THM; GSYM ADD_ASSOC] THEN + NUM_REDUCE_TAC THEN ASM_REWRITE_TAC[] THEN AP_TERM_TAC THEN + MP_TAC (ISPECL [`bl:byte list`; `(pos+0x30):num`] SUB_LIST_16) THEN + REWRITE_TAC[GSYM ADD_ASSOC] THEN NUM_REDUCE_TAC THEN + DISCH_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_ARITH_TAC + ] +);; + +let BYTE_LIST_AT_3BLOCKS = prove( + `! pos bl bl_ptr len s. + byte_list_at bl bl_ptr len s + ==> LENGTH bl = val len + ==> pos + 0x30 <= LENGTH bl + ==> (read (memory :> bytes128 (word_add bl_ptr (word pos))) s = + bytes_to_int128 (SUB_LIST (pos, 0x10) bl) /\ + read (memory :> bytes128 (word_add (word_add bl_ptr (word pos)) (word 0x10))) s = + bytes_to_int128 (SUB_LIST (pos + 0x10, 0x10) bl) /\ + read (memory :> bytes128 (word_add (word_add bl_ptr (word pos)) (word 0x20))) s = + bytes_to_int128 (SUB_LIST (pos + 0x20, 0x10) bl))`, + REWRITE_TAC[byte_list_at] THEN + REPEAT STRIP_TAC THENL + [ (* Subgoal1 *) + MAP_EVERY (fun i -> BYTE_LIST_AT_ADD_ASSUM_TAC + (mk_binop (mk_const("+", [`:num`, `:A`])) (mk_var("pos", `:num`)) + (mk_numeral (num i))) `0x30`) (0--15) THEN + REWRITE_TAC[WORD_ADD_ASSOC_CONSTS] THEN + REPEAT STRIP_TAC THEN + ASM_REWRITE_TAC[BYTES128_TO_BYTES8_THM; GSYM ADD_ASSOC] THEN + NUM_REDUCE_TAC THEN ASM_REWRITE_TAC[] THEN AP_TERM_TAC THEN + MP_TAC (ISPECL [`bl:byte list`; `pos:num`] SUB_LIST_16) THEN + REWRITE_TAC[GSYM ADD_ASSOC] THEN NUM_REDUCE_TAC THEN + DISCH_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_ARITH_TAC; + (* Subgoal2 *) + MAP_EVERY (fun i -> BYTE_LIST_AT_ADD_ASSUM_TAC + (mk_binop (mk_const("+", [`:num`, `:A`])) (mk_var("pos", `:num`)) + (mk_numeral (num i))) `0x30`) (16--31) THEN + REWRITE_TAC[WORD_ADD_ASSOC_CONSTS] THEN + REPEAT STRIP_TAC THEN + ASM_REWRITE_TAC[BYTES128_TO_BYTES8_THM; GSYM ADD_ASSOC] THEN + NUM_REDUCE_TAC THEN ASM_REWRITE_TAC[] THEN AP_TERM_TAC THEN + MP_TAC (ISPECL [`bl:byte list`; `(pos+0x10):num`] SUB_LIST_16) THEN + REWRITE_TAC[GSYM ADD_ASSOC] THEN NUM_REDUCE_TAC THEN + DISCH_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_ARITH_TAC; + (* Subgoal3 *) + MAP_EVERY (fun i -> BYTE_LIST_AT_ADD_ASSUM_TAC + (mk_binop (mk_const("+", [`:num`, `:A`])) (mk_var("pos", `:num`)) + (mk_numeral (num i))) `0x30`) (32--47) THEN + REWRITE_TAC[WORD_ADD_ASSOC_CONSTS] THEN + REPEAT STRIP_TAC THEN + ASM_REWRITE_TAC[BYTES128_TO_BYTES8_THM; GSYM ADD_ASSOC] THEN + NUM_REDUCE_TAC THEN ASM_REWRITE_TAC[] THEN AP_TERM_TAC THEN + MP_TAC (ISPECL [`bl:byte list`; `(pos+0x20):num`] SUB_LIST_16) THEN + REWRITE_TAC[GSYM ADD_ASSOC] THEN NUM_REDUCE_TAC THEN + DISCH_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_ARITH_TAC + ] +);; + +let BYTE_LIST_AT_2BLOCKS = prove( + `! pos bl bl_ptr len s. + byte_list_at bl bl_ptr len s + ==> LENGTH bl = val len + ==> pos + 0x20 <= LENGTH bl + ==> (read (memory :> bytes128 (word_add bl_ptr (word pos))) s = + bytes_to_int128 (SUB_LIST (pos, 0x10) bl) /\ + read (memory :> bytes128 (word_add (word_add bl_ptr (word pos)) (word 0x10))) s = + bytes_to_int128 (SUB_LIST (pos + 0x10, 0x10) bl))`, + REWRITE_TAC[byte_list_at] THEN + REPEAT STRIP_TAC THENL + [ (* Subgoal1 *) + MAP_EVERY (fun i -> BYTE_LIST_AT_ADD_ASSUM_TAC + (mk_binop (mk_const("+", [`:num`, `:A`])) (mk_var("pos", `:num`)) + (mk_numeral (num i))) `0x20`) (0--15) THEN + REWRITE_TAC[WORD_ADD_ASSOC_CONSTS] THEN + REPEAT STRIP_TAC THEN + ASM_REWRITE_TAC[BYTES128_TO_BYTES8_THM; GSYM ADD_ASSOC] THEN + NUM_REDUCE_TAC THEN ASM_REWRITE_TAC[] THEN AP_TERM_TAC THEN + MP_TAC (ISPECL [`bl:byte list`; `pos:num`] SUB_LIST_16) THEN + REWRITE_TAC[GSYM ADD_ASSOC] THEN NUM_REDUCE_TAC THEN + DISCH_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_ARITH_TAC; + (* Subgoal2 *) + MAP_EVERY (fun i -> BYTE_LIST_AT_ADD_ASSUM_TAC + (mk_binop (mk_const("+", [`:num`, `:A`])) (mk_var("pos", `:num`)) + (mk_numeral (num i))) `0x20`) (16--31) THEN + REWRITE_TAC[WORD_ADD_ASSOC_CONSTS] THEN + REPEAT STRIP_TAC THEN + ASM_REWRITE_TAC[BYTES128_TO_BYTES8_THM; GSYM ADD_ASSOC] THEN + NUM_REDUCE_TAC THEN ASM_REWRITE_TAC[] THEN AP_TERM_TAC THEN + MP_TAC (ISPECL [`bl:byte list`; `(pos+0x10):num`] SUB_LIST_16) THEN + REWRITE_TAC[GSYM ADD_ASSOC] THEN NUM_REDUCE_TAC THEN + DISCH_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_ARITH_TAC + ] +);; + +let BYTE_LIST_AT_1BLOCKS = prove( + `! pos bl bl_ptr len s. + byte_list_at bl bl_ptr len s + ==> LENGTH bl = val len + ==> pos + 0x10 <= LENGTH bl + ==> read (memory :> bytes128 (word_add bl_ptr (word pos))) s = + bytes_to_int128 (SUB_LIST (pos, 0x10) bl)`, + REWRITE_TAC[byte_list_at] THEN + REPEAT STRIP_TAC THENL + [ (* Subgoal1 *) + MAP_EVERY (fun i -> BYTE_LIST_AT_ADD_ASSUM_TAC + (mk_binop (mk_const("+", [`:num`, `:A`])) (mk_var("pos", `:num`)) + (mk_numeral (num i))) `0x10`) (0--15) THEN + REWRITE_TAC[WORD_ADD_ASSOC_CONSTS] THEN + REPEAT STRIP_TAC THEN + ASM_REWRITE_TAC[BYTES128_TO_BYTES8_THM; GSYM ADD_ASSOC] THEN + NUM_REDUCE_TAC THEN ASM_REWRITE_TAC[] THEN AP_TERM_TAC THEN + MP_TAC (ISPECL [`bl:byte list`; `pos:num`] SUB_LIST_16) THEN + REWRITE_TAC[GSYM ADD_ASSOC] THEN NUM_REDUCE_TAC THEN + DISCH_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_ARITH_TAC + ] +);; + +(* Copied from Decrypt proof without change because it can be instantiated for ptxt_p *) +let READ_CT_LEMMA = prove( + `!ct_ptr i (len:int64) (ct:byte list) s. + (forall j. j < val len ==> read (memory :> bytes8 (word_add ct_ptr (word j))) s = EL j ct) + /\ i * 0x50 + 0x50 <= val len + /\ LENGTH ct = val len + ==> + read (memory :> bytes128 (word_add ct_ptr (word_mul (word 0x50) (word i)))) s = + bytes_to_int128 (SUB_LIST (i * 80, 16) ct) /\ + read (memory :> bytes128 (word_add (word_add ct_ptr (word_mul (word 0x50) (word i))) (word 0x10))) s = + bytes_to_int128 (SUB_LIST (i * 80 + 16, 16) ct) /\ + read (memory :> bytes128 (word_add (word_add ct_ptr (word_mul (word 0x50) (word i))) (word 0x20))) s = + bytes_to_int128 (SUB_LIST (i * 80 + 32, 16) ct) /\ + read (memory :> bytes128 (word_add (word_add ct_ptr (word_mul (word 0x50) (word i))) (word 0x30))) s = + bytes_to_int128 (SUB_LIST (i * 80 + 48, 16) ct) /\ + read (memory :> bytes128 (word_add (word_add ct_ptr (word_mul (word 0x50) (word i))) (word 0x40))) s = + bytes_to_int128 (SUB_LIST (i * 80 + 64, 16) ct) + `, + REPEAT GEN_TAC THEN STRIP_TAC THEN + REWRITE_TAC [WORD_RULE `word_mul (word 0x50) (word i) = word (i * 80)`] THEN + MP_TAC + (SPECL [`(i * 80):num`; `ct:byte list`; `ct_ptr:int64`; `len:int64`; `s:armstate`] + BYTE_LIST_AT_5BLOCKS) THEN + REWRITE_TAC[byte_list_at] THEN ASM_SIMP_TAC[] +);; + +(* Same as Decrypt but with "num_5blocks_adjusted" replaced by "num_5blocks", + which can still be used with Decrypt since it's universally quantified at the beginning of this lemma + and the following ones *) +let READ_CT_TAIL4_LEMMA = prove( + `!ct_ptr (num_5blocks:int64) (len:int64) (ct:byte list) s. + (forall j. j < val len ==> read (memory :> bytes8 (word_add ct_ptr (word j))) s = EL j ct) + /\ val num_5blocks * 0x50 + 0x40 <= val len + /\ LENGTH ct = val len + ==> + read (memory :> bytes128 (word_add + (word_add ct_ptr (word_mul (word 0x50) num_5blocks)) + (word 0x30))) s = + bytes_to_int128 (SUB_LIST (val num_5blocks * 80 + 0x30, 16) ct) /\ + read (memory :> bytes128 (word_add + (word_add ct_ptr (word_mul (word 0x50) num_5blocks)) + (word 0x20))) s = + bytes_to_int128 (SUB_LIST (val num_5blocks * 80 + 0x20, 16) ct) /\ + read (memory :> bytes128 (word_add + (word_add ct_ptr (word_mul (word 0x50) num_5blocks)) + (word 0x10))) s = + bytes_to_int128 (SUB_LIST (val num_5blocks * 80 + 0x10, 16) ct) /\ + read (memory :> bytes128 + (word_add ct_ptr (word_mul (word 0x50) num_5blocks))) s = + bytes_to_int128 (SUB_LIST (val num_5blocks * 80, 16) ct) + `, + REPEAT GEN_TAC THEN STRIP_TAC THEN + REWRITE_TAC [WORD_RULE `(word_mul (word 0x50) (num_5blocks:int64)) = word (val num_5blocks * 80)`] THEN + MP_TAC + (SPECL [`(val (num_5blocks:int64) * 80):num`; `ct:byte list`; `ct_ptr:int64`; `len:int64`; `s:armstate`] + BYTE_LIST_AT_4BLOCKS) THEN + REWRITE_TAC[byte_list_at] THEN ASM_SIMP_TAC[] +);; + +let READ_CT_TAIL3_LEMMA = prove( + `!ct_ptr (num_5blocks:int64) (len:int64) (ct:byte list) s. + (forall j. j < val len ==> read (memory :> bytes8 (word_add ct_ptr (word j))) s = EL j ct) + /\ val num_5blocks * 0x50 + 0x30 <= val len + /\ LENGTH ct = val len + ==> + read (memory :> bytes128 (word_add + (word_add ct_ptr (word_mul (word 0x50) num_5blocks)) + (word 0x20))) s = + bytes_to_int128 (SUB_LIST (val num_5blocks * 80 + 0x20, 16) ct) /\ + read (memory :> bytes128 (word_add + (word_add ct_ptr (word_mul (word 0x50) num_5blocks)) + (word 0x10))) s = + bytes_to_int128 (SUB_LIST (val num_5blocks * 80 + 0x10, 16) ct) /\ + read (memory :> bytes128 + (word_add ct_ptr (word_mul (word 0x50) num_5blocks))) s = + bytes_to_int128 (SUB_LIST (val num_5blocks * 80, 16) ct) + `, + REPEAT GEN_TAC THEN STRIP_TAC THEN + REWRITE_TAC [WORD_RULE `(word_mul (word 0x50) (num_5blocks:int64)) = word (val num_5blocks * 80)`] THEN + MP_TAC + (SPECL [`(val (num_5blocks:int64) * 80):num`; `ct:byte list`; `ct_ptr:int64`; `len:int64`; `s:armstate`] + BYTE_LIST_AT_3BLOCKS) THEN + REWRITE_TAC[byte_list_at] THEN ASM_SIMP_TAC[] +);; + +let READ_CT_TAIL2_LEMMA = prove( + `!ct_ptr (num_5blocks:int64) (len:int64) (ct:byte list) s. + (forall j. j < val len ==> read (memory :> bytes8 (word_add ct_ptr (word j))) s = EL j ct) + /\ val num_5blocks * 0x50 + 0x20 <= val len + /\ LENGTH ct = val len + ==> + read (memory :> bytes128 (word_add + (word_add ct_ptr (word_mul (word 0x50) num_5blocks)) + (word 0x10))) s = + bytes_to_int128 (SUB_LIST (val num_5blocks * 80 + 0x10, 16) ct) /\ + read (memory :> bytes128 + (word_add ct_ptr (word_mul (word 0x50) num_5blocks))) s = + bytes_to_int128 (SUB_LIST (val num_5blocks * 80, 16) ct) + `, + REPEAT GEN_TAC THEN STRIP_TAC THEN + REWRITE_TAC [WORD_RULE `(word_mul (word 0x50) (num_5blocks:int64)) = word (val num_5blocks * 80)`] THEN + MP_TAC + (SPECL [`(val (num_5blocks:int64) * 80):num`; `ct:byte list`; `ct_ptr:int64`; `len:int64`; `s:armstate`] + BYTE_LIST_AT_2BLOCKS) THEN + REWRITE_TAC[byte_list_at] THEN ASM_SIMP_TAC[] +);; + +let READ_CT_TAIL1_LEMMA = prove( + `!ct_ptr (num_5blocks:int64) (len:int64) (ct:byte list) s. + (forall j. j < val len ==> read (memory :> bytes8 (word_add ct_ptr (word j))) s = EL j ct) + /\ val num_5blocks * 0x50 + 0x10 <= val len + /\ LENGTH ct = val len + ==> + read (memory :> bytes128 + (word_add ct_ptr (word_mul (word 0x50) num_5blocks))) s = + bytes_to_int128 (SUB_LIST (val num_5blocks * 80, 16) ct) + `, + REPEAT GEN_TAC THEN STRIP_TAC THEN + REWRITE_TAC [WORD_RULE `(word_mul (word 0x50) (num_5blocks:int64)) = word (val num_5blocks * 80)`] THEN + MP_TAC + (SPECL [`(val (num_5blocks:int64) * 80):num`; `ct:byte list`; `ct_ptr:int64`; `len:int64`; `s:armstate`] + BYTE_LIST_AT_1BLOCKS) THEN + REWRITE_TAC[byte_list_at] THEN ASM_SIMP_TAC[] +);; + +(* TODO: do I need this in encrypt? *) +let READ_CT_LAST_LEMMA = prove( + `!ct_ptr (curr_len:num) (len:int64) (ct:byte list) s. + (forall j. j < val len ==> read (memory :> bytes8 (word_add ct_ptr (word j))) s = EL j ct) + /\ curr_len + 0x10 <= val len + /\ LENGTH ct = val len + ==> + read (memory :> bytes128 (word_add ct_ptr (word curr_len))) s = + bytes_to_int128 (SUB_LIST (curr_len, 16) ct) + `, + REPEAT GEN_TAC THEN STRIP_TAC THEN + MP_TAC + (SPECL [`curr_len:num`; `ct:byte list`; `ct_ptr:int64`; `len:int64`; `s:armstate`] + BYTE_LIST_AT_1BLOCKS) THEN + REWRITE_TAC[byte_list_at] THEN ASM_SIMP_TAC[] +);; + (* Different from decrypt in using len_full_blocks *) let LEN_FULL_BLOCKS_LO_BOUND_THM = prove( `!(len:int64) len_full_blocks. word_and len (word 0xfffffffffffffff0) = len_full_blocks @@ -1126,7 +1454,7 @@ let NUM_5BLOCKS_LO_BOUND_THM = prove( ASM_SIMP_TAC[MOD_LT] THEN ARITH_TAC );; - +(* let NUM_BLOCKS_ADJUSTED_LT_LEN_THM = prove( `!(len:int64) num_blocks. word_and len (word 0xfffffffffffffff0) = num_blocks @@ -1134,7 +1462,7 @@ let NUM_BLOCKS_ADJUSTED_LT_LEN_THM = prove( ==> val (word_sub num_blocks (word 0x10)) <= val len`, BITBLAST_TAC );; - +*) let NUM_OF_BYTELIST_APPEND = prove (`!l1 l2. num_of_bytelist (APPEND l1 l2) = num_of_bytelist l1 + 2 EXP (8 * LENGTH l1) * num_of_bytelist l2`, @@ -1544,32 +1872,6 @@ let UDIV_OPT_THM = prove(`!n:num. n < 0x2 EXP 0x40 DISCH_TAC THEN ASM_REWRITE_TAC[] THEN AP_TERM_TAC THEN ASM_ARITH_TAC);; -(* Copied from Decrypt proof without change because it can be instantiated for ptxt_p *) -let READ_CT_LEMMA = prove( - `!ct_ptr i (len:int64) (ct:byte list) s. - (forall j. j < val len ==> read (memory :> bytes8 (word_add ct_ptr (word j))) s = EL j ct) - /\ i * 0x50 + 0x50 <= val len - /\ LENGTH ct = val len - ==> - read (memory :> bytes128 (word_add ct_ptr (word_mul (word 0x50) (word i)))) s = - bytes_to_int128 (SUB_LIST (i * 80, 16) ct) /\ - read (memory :> bytes128 (word_add (word_add ct_ptr (word_mul (word 0x50) (word i))) (word 0x10))) s = - bytes_to_int128 (SUB_LIST (i * 80 + 16, 16) ct) /\ - read (memory :> bytes128 (word_add (word_add ct_ptr (word_mul (word 0x50) (word i))) (word 0x20))) s = - bytes_to_int128 (SUB_LIST (i * 80 + 32, 16) ct) /\ - read (memory :> bytes128 (word_add (word_add ct_ptr (word_mul (word 0x50) (word i))) (word 0x30))) s = - bytes_to_int128 (SUB_LIST (i * 80 + 48, 16) ct) /\ - read (memory :> bytes128 (word_add (word_add ct_ptr (word_mul (word 0x50) (word i))) (word 0x40))) s = - bytes_to_int128 (SUB_LIST (i * 80 + 64, 16) ct) - `, - REPEAT GEN_TAC THEN STRIP_TAC THEN - REWRITE_TAC [WORD_RULE `word_mul (word 0x50) (word i) = word (i * 80)`] THEN - MP_TAC - (SPECL [`(i * 80):num`; `ct:byte list`; `ct_ptr:int64`; `len:int64`; `s:armstate`] - BYTE_LIST_AT_5BLOCKS) THEN - REWRITE_TAC[byte_list_at] THEN ASM_SIMP_TAC[] -);; - let LENGTH_OF_INT128_TO_BYTES = prove( `!x. LENGTH(int128_to_bytes x) = 16`, STRIP_TAC THEN @@ -1578,6 +1880,86 @@ let LENGTH_OF_INT128_TO_BYTES = prove( CONV_TAC NUM_REDUCE_CONV );; +let DIVISION_BY_80_LEMMA = prove( + `!(a:num) b. a DIV 0x50 = b /\ + 0x10 divides a /\ + ~(a - b * 0x50 = 0x10) /\ + ~(a - b * 0x50 = 0x20) /\ + ~(a - b * 0x50 = 0x30) /\ + ~(a - b * 0x50 = 0x40) ==> + b * 0x50 = a`, + REPEAT STRIP_TAC THEN + (* Use the division theorem: a = b * 0x50 + (a MOD 0x50) *) + MP_TAC (SPECL [`a:num`; `0x50`] DIVISION) THEN + CONV_TAC NUM_REDUCE_CONV THEN + REPEAT STRIP_TAC THEN + + (* We have a = b * 0x50 + (a MOD 0x50) and a DIV 0x50 = b *) + SUBGOAL_THEN `a = b * 0x50 + (a MOD 0x50)` ASSUME_TAC THENL [ + ASM_ARITH_TAC; ALL_TAC] THEN + + (* Show that a MOD 0x50 = 0 by case analysis *) + SUBGOAL_THEN `a MOD 0x50 = 0` ASSUME_TAC THENL [ + (* Since 0x10 divides a, we know a = k * 0x10 for some k *) + UNDISCH_TAC `0x10 divides a` THEN + REWRITE_TAC[divides] THEN + STRIP_TAC THEN + + (* The remainder a MOD 0x50 must be a multiple of 0x10 and < 0x50 *) + (* So it's one of: 0, 0x10, 0x20, 0x30, 0x40 *) + SUBGOAL_THEN `(a MOD 0x50 = 0) \/ (a MOD 0x50 = 0x10) \/ + (a MOD 0x50 = 0x20) \/ (a MOD 0x50 = 0x30) \/ + (a MOD 0x50 = 0x40)` ASSUME_TAC THENL + [ ASM_REWRITE_TAC[] THEN + + SUBGOAL_THEN `(0x10 * x) MOD 0x50 = (x MOD 5) * 0x10` SUBST1_TAC THENL [ + SUBGOAL_THEN `0x50 = 5 * 0x10` SUBST1_TAC THENL [ + CONV_TAC NUM_REDUCE_CONV; ALL_TAC] THEN + MP_TAC (SPECL [`0x10 * x`; `0x10`; `5`] MOD_MULT_MOD) THEN + REWRITE_TAC[MOD_MULT; ADD_CLAUSES] THEN + IMP_REWRITE_TAC[DIV_MULT] THEN + CONV_TAC NUM_REDUCE_CONV THEN + SIMP_TAC[] THEN DISCH_TAC THEN + REWRITE_TAC[MULT_SYM] + ; ALL_TAC] THEN + + SUBGOAL_THEN `x MOD 5 < 5` ASSUME_TAC THENL [ + REWRITE_TAC[MOD_LT_EQ] THEN CONV_TAC NUM_REDUCE_CONV; ALL_TAC] THEN + SUBGOAL_THEN `x MOD 5 = 0 \/ x MOD 5 = 1 \/ x MOD 5 = 2 \/ x MOD 5 = 3 \/ x MOD 5 = 4` ASSUME_TAC THENL [ + UNDISCH_TAC `x MOD 0x5 < 0x5` THEN ARITH_TAC ; ALL_TAC] THEN + + REPEAT (FIRST_X_ASSUM DISJ_CASES_TAC) THENL + [ ASM_REWRITE_TAC[] THEN CONV_TAC NUM_REDUCE_CONV; + ASM_REWRITE_TAC[] THEN CONV_TAC NUM_REDUCE_CONV; + ASM_REWRITE_TAC[] THEN CONV_TAC NUM_REDUCE_CONV; + ASM_REWRITE_TAC[] THEN CONV_TAC NUM_REDUCE_CONV; + ASM_REWRITE_TAC[] THEN CONV_TAC NUM_REDUCE_CONV] + ; ALL_TAC] THEN + + (* Now eliminate the non-zero cases using the assumptions *) + SUBGOAL_THEN `~(a MOD 0x50 = 0x10)` ASSUME_TAC THENL + [ UNDISCH_TAC `~(a - b * 0x50 = 0x10)` THEN + UNDISCH_TAC `a = b * 0x50 + a MOD 0x50` THEN + ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `~(a MOD 0x50 = 0x20)` ASSUME_TAC THENL + [ UNDISCH_TAC `~(a - b * 0x50 = 0x20)` THEN + UNDISCH_TAC `a = b * 0x50 + a MOD 0x50` THEN + ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `~(a MOD 0x50 = 0x30)` ASSUME_TAC THENL + [ UNDISCH_TAC `~(a - b * 0x50 = 0x30)` THEN + UNDISCH_TAC `a = b * 0x50 + a MOD 0x50` THEN + ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `~(a MOD 0x50 = 0x40)` ASSUME_TAC THENL + [ UNDISCH_TAC `~(a - b * 0x50 = 0x40)` THEN + UNDISCH_TAC `a = b * 0x50 + a MOD 0x50` THEN + ARITH_TAC; ALL_TAC] THEN + + ASM_MESON_TAC[]; ALL_TAC + ] THEN + + (* Finally conclude b * 0x50 = a *) + ASM_ARITH_TAC +);; (* ********************************************************** *) (* Properties that we prove about the specification functions *) (* Similar to the Decrypt ones but specified for Encrypt *) @@ -1836,6 +2218,82 @@ let SUB_LIST_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS = prove( ASM_ARITH_TAC );; + +let acc_len = new_definition +`acc_len (i:int64) (len:int64) : num = + if val i * 0x50 + 0x40 = val len then 0x50 * val i + 0x40 + else + if val i * 0x50 + 0x30 = val len then 0x50 * val i + 0x30 + else + if val i * 0x50 + 0x20 = val len then 0x50 * val i + 0x20 + else + if val i * 0x50 + 0x10 = val len then 0x50 * val i + 0x10 + else 0x50 * val i`;; + +let VALUE_OF_ACC_LEN = prove( + `!(i:int64) (len:int64). + val i * 0x50 <= val len ==> + val len DIV 0x50 = val i ==> + 0x10 divides val len ==> + acc_len i len = val len`, + REPEAT STRIP_TAC THEN + REWRITE_TAC[acc_len] THEN + REPEAT COND_CASES_TAC THENL + [ + ASM_ARITH_TAC; + ASM_ARITH_TAC; + ASM_ARITH_TAC; + ASM_ARITH_TAC; + REWRITE_TAC[ARITH_RULE `!a. 0x50 * a = a * 0x50`] THEN + SUBGOAL_THEN `val (i:int64) * 0x50 = val (len:int64)` ASSUME_TAC THENL + [ MATCH_MP_TAC (SPECL [`val (len:int64)`; `val (i:int64)`] DIVISION_BY_80_LEMMA) THEN + REPEAT CONJ_TAC THENL + [ + ASM_SIMP_TAC[]; + ASM_SIMP_TAC[]; + UNDISCH_TAC `~(val (i:int64) * 0x50 + 0x10 = val (len:int64))` THEN + UNDISCH_TAC `val (i:int64) * 0x50 <= val (len:int64)` THEN + ARITH_TAC; + UNDISCH_TAC `~(val (i:int64) * 0x50 + 0x20 = val (len:int64))` THEN + UNDISCH_TAC `val (i:int64) * 0x50 <= val (len:int64)` THEN + ARITH_TAC; + UNDISCH_TAC `~(val (i:int64) * 0x50 + 0x30 = val (len:int64))` THEN + UNDISCH_TAC `val (i:int64) * 0x50 <= val (len:int64)` THEN + ARITH_TAC; + UNDISCH_TAC `~(val (i:int64) * 0x50 + 0x40 = val (len:int64))` THEN + UNDISCH_TAC `val (i:int64) * 0x50 <= val (len:int64)` THEN + ARITH_TAC + ]; ALL_TAC] THEN + ASM_ARITH_TAC + ] +);; + +let BOUND_OF_ACC_LEN = prove( + `!(i:int64) (len:int64) x. + val i * 0x50 <= val len ==> + val len DIV 0x50 = val i ==> + 0x10 divides val len ==> + val len < x ==> acc_len i len < x`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN `acc_len i len = val (len:int64)` ASSUME_TAC THENL + [ MP_TAC (SPECL [`i:int64`; `len:int64`] VALUE_OF_ACC_LEN) THEN + ASM_SIMP_TAC[]; ALL_TAC] THEN + ASM_ARITH_TAC +);; + +(* For X9 and X10, they stand for i * 0x5 + 4 when number of blocks is divisible by 5. TODO: check for enrypt *) +let acc_blocks = new_definition +`acc_blocks (i:int64) (len:int64) (last:bool) : num = + if val i * 0x50 + 0x40 = val len then val i * 0x5 + 4 + else + if val i * 0x50 + 0x30 = val len then val i * 0x5 + 3 + else + if val i * 0x50 + 0x20 = val len then val i * 0x5 + 2 + else + if val i * 0x50 + 0x10 = val len then val i * 0x5 + 1 + else + if last then val i * 0x5 else val i * 0x5 + 4`;; + (* void aes_hw_xts_encrypt(const uint8_t *in, uint8_t *out, size_t length, const AES_KEY *key1, const AES_KEY *key2, @@ -1847,11 +2305,9 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( pt_in iv k1_0 k1_1 k1_2 k1_3 k1_4 k1_5 k1_6 k1_7 k1_8 k1_9 k1_10 k1_11 k1_12 k1_13 k1_14 k2_0 k2_1 k2_2 k2_3 k2_4 k2_5 k2_6 k2_7 k2_8 k2_9 k2_10 k2_11 k2_12 k2_13 k2_14 - pc stackpointer. - aligned 16 stackpointer /\ + pc. PAIRWISE nonoverlapping - [(stackpointer, 6*16); - (word pc, LENGTH aes256_xts_encrypt_mc); + [(word pc, LENGTH aes256_xts_encrypt_mc); (ptxt_p, val len); (ctxt_p, val len); (key1_p, 244); @@ -1909,16 +2365,19 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( *) ASM_CASES_TAC `val (len:int64) < 0x50` THENL [CHEAT_TAC; ALL_TAC] THEN + (* Prove the bounds on len_full_blocks, num_5blocks and len and their relationships *) SUBGOAL_THEN `~(val (len_full_blocks:int64) < 0x50)` ASSUME_TAC THENL [ UNDISCH_TAC `~(val (len:int64) < 0x50)` THEN UNDISCH_TAC `word_and len (word 0xfffffffffffffff0) = (len_full_blocks:int64)` THEN MP_TAC (SPECL [`len:int64`; `len_full_blocks:int64`] LEN_FULL_BLOCKS_LO_BOUND_THM) THEN SIMP_TAC[]; ALL_TAC] THEN + SUBGOAL_THEN `val (len_full_blocks:int64) <= 0x2 EXP 24` ASSUME_TAC THENL [ UNDISCH_TAC `val (len:int64) <= 0x2 EXP 24` THEN UNDISCH_TAC `word_and len (word 0xfffffffffffffff0) = (len_full_blocks:int64)` THEN MP_TAC (SPECL [`len:int64`; `len_full_blocks:int64`] LEN_FULL_BLOCKS_HI_BOUND_THM) THEN SIMP_TAC[]; ALL_TAC] THEN + SUBGOAL_THEN `0 < val (num_5blocks:int64)` ASSUME_TAC THENL [ UNDISCH_TAC `word (val (len_full_blocks:int64) DIV 0x50) = (num_5blocks:int64)` THEN UNDISCH_TAC `~(val (len_full_blocks:int64) < 0x50)` THEN @@ -1927,6 +2386,15 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( NUM_5BLOCKS_LO_BOUND_THM) THEN SIMP_TAC[] ; ALL_TAC] THEN + SUBGOAL_THEN `val (len_full_blocks:int64) <= val (len:int64)` ASSUME_TAC THENL + [ EXPAND_TAC "len_full_blocks" THEN SIMP_TAC[LEN_FULL_BLOCKS_LT_LEN_THM]; ALL_TAC] THEN + + SUBGOAL_THEN `val (num_5blocks:int64) * 0x50 <= val (len_full_blocks:int64)` ASSUME_TAC THENL + [ EXPAND_TAC "num_5blocks" THEN + REWRITE_TAC [VAL_WORD; DIMINDEX_64] THEN + UNDISCH_TAC `val (len_full_blocks:int64) <= 0x2 EXP 0x18` THEN + ARITH_TAC; ALL_TAC] THEN + (* Verify properties of the program until the beginning of the loop. This saves work in the second subgoal of the loop invariant and brings it here. Up to the loop: @@ -2050,9 +2518,29 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( ASM_REWRITE_TAC[byte_list_at] THEN REWRITE_TAC[VAL_WORD_0] THEN ARITH_TAC ] ; ALL_TAC - ] THEN + ] THEN + + (* Prove property until right before cipher stealing *) + ENSURES_SEQUENCE_TAC `pc + 0x9e0` + `\s. + read X0 s = word_add ptxt_p (word (acc_len num_5blocks len_full_blocks)) /\ + read X1 s = word_add ctxt_p (word (acc_len num_5blocks len_full_blocks)) /\ + read X21 s = tail_len /\ + read Q6 s = calculate_tweak (acc_blocks num_5blocks len_full_blocks T) iv key2_lst /\ + read X19 s = word 0x87 /\ + read X10 s = word_subword (calculate_tweak (acc_blocks num_5blocks len_full_blocks F) iv key2_lst) (64,64) /\ + read X9 s = word_zx (calculate_tweak (acc_blocks num_5blocks len_full_blocks F) iv key2_lst) /\ + read Q16 s = k1_0 /\ read Q17 s = k1_1 /\ read Q12 s = k1_2 /\ read Q13 s = k1_3 /\ + read Q14 s = k1_4 /\ read Q15 s = k1_5 /\ read Q4 s = k1_6 /\ read Q5 s = k1_7 /\ + read Q18 s = k1_8 /\ read Q19 s = k1_9 /\ read Q20 s = k1_10 /\ read Q21 s = k1_11 /\ + read Q22 s = k1_12 /\ read Q23 s = k1_13 /\ read Q7 s = k1_14 /\ + byte_list_at pt_in ptxt_p len s /\ + byte_list_at (aes256_xts_encrypt pt_in (acc_len num_5blocks len_full_blocks) iv key1_lst key2_lst) + ctxt_p (word (acc_len num_5blocks len_full_blocks)) s` THEN + CONJ_TAC THENL + [ - (* Loop invariant *) + (* Main Loop invariant *) ENSURES_WHILE_PAUP_TAC `0` (* counter begin number *) `val (num_5blocks:int64)` (* counter end number *) @@ -2103,7 +2591,7 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( CONV_TAC NUM_REDUCE_CONV; CONV_TAC NUM_REDUCE_CONV THEN REWRITE_TAC[VAL_WORD_0] THEN ARITH_TAC ]; - (* Subgoal 3: loop body *) + (* Subgoal 3: inductive step in the loop body *) REPEAT STRIP_TAC THEN SUBGOAL_THEN `i * 0x50 + 0x50 <= val (len:int64)` ASSUME_TAC THENL @@ -2179,6 +2667,17 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( RULE_ASSUM_TAC(REWRITE_RULE [WORD_RULE `word_mul (word 0x50) (word i):int64 = word(0x50 * i)`]) THEN + (* + 38 [`forall i'. + i' < val (word (i * 0x50)). ====> becomes 0x50 * i + ==> read (memory :> bytes8 (word_add ctxt_p (word i'))) s183 = + EL i' + (aes256_xts_encrypt pt_in (i * 0x50) iv key1_lst key2_lst)`] + 39 [`forall i'. + i' < val len + ==> read (memory :> bytes8 (word_add ptxt_p (word i'))) s183 = + EL i' pt_in`] + *) (* Rewrite to help reasoning about nonoverlapping so that the universally quantified assumption stays. See: https://hol-light.zulipchat.com/#narrow/channel/474190-s2n-bignum/topic/.E2.9C.94.20Symbolic.20simulation.20removed.20assumption/with/541554894 *) @@ -2190,12 +2689,45 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (184--188) THEN ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN REPEAT CONJ_TAC THENL + (* + val it : goalstack = 13 subgoals (16 total) + +`word_add (word_add ptxt_p (word (0x50 * i))) (word 0x50) = + word_add ptxt_p (word_mul (word 0x50) (word (i + 0x1))) /\ + word_add (word_add ctxt_p (word (0x50 * i))) (word 0x50) = + word_add ctxt_p (word_mul (word 0x50) (word (i + 0x1))) /\ + word_sub (word_sub len_full_blocks (word (0x50 * i))) (word 0x50) = + word_sub len_full_blocks (word_mul (word 0x50) (word (i + 0x1))) /\ + word_sub (word_sub num_5blocks (word i)) (word 0x1) = + word_sub num_5blocks (word (i + 0x1)) /\ + word_zx (calculate_tweak (i * 0x5 + 0x9) iv key2_lst) = + word_zx (calculate_tweak ((i + 0x1) * 0x5 + 0x4) iv key2_lst) /\ + word_subword (calculate_tweak (i * 0x5 + 0x9) iv key2_lst) (0x40,0x40) = + word_subword (calculate_tweak ((i + 0x1) * 0x5 + 0x4) iv key2_lst) + (0x40,0x40) /\ + calculate_tweak (i * 0x5 + 0x5) iv key2_lst = + calculate_tweak ((i + 0x1) * 0x5) iv key2_lst /\ + calculate_tweak (i * 0x5 + 0x6) iv key2_lst = + calculate_tweak ((i + 0x1) * 0x5 + 0x1) iv key2_lst /\ + calculate_tweak (i * 0x5 + 0x7) iv key2_lst = + calculate_tweak ((i + 0x1) * 0x5 + 0x2) iv key2_lst /\ + calculate_tweak (i * 0x5 + 0x8) iv key2_lst = + calculate_tweak ((i + 0x1) * 0x5 + 0x3) iv key2_lst /\ + calculate_tweak (i * 0x5 + 0x9) iv key2_lst = + calculate_tweak ((i + 0x1) * 0x5 + 0x4) iv key2_lst /\ + (forall i'. + i' < val (word ((i + 0x1) * 0x50)) + ==> read (memory :> bytes8 (word_add ctxt_p (word i'))) s188 = + EL i' + (aes256_xts_encrypt pt_in ((i + 0x1) * 0x50) iv key1_lst key2_lst)) /\ + (val (word_sub (word_sub num_5blocks (word i)) (word 0x1)) = 0x0 <=> + i + 0x1 = val num_5blocks)` + *) [ REWRITE_TAC[WORD_RULE `word_mul (word 0x50) (word (i + 1)):int64 = word_add (word(0x50 * i)) (word 0x50)`] THEN REWRITE_TAC[WORD_ADD_ASSOC]; REWRITE_TAC[WORD_RULE `word_mul (word 0x50) (word (i + 1)):int64 = word_add (word(0x50 * i)) (word 0x50)`] THEN REWRITE_TAC[WORD_ADD_ASSOC]; REWRITE_TAC[WORD_RULE `word_mul (word 0x50) (word (i + 1)):int64 = word_add (word(0x50 * i)) (word 0x50)`] THEN - REWRITE_TAC[WORD_ADD_ASSOC]; CONV_TAC WORD_RULE; CONV_TAC WORD_RULE; REWRITE_TAC[WORD_RULE `(i + 0x1) * 0x5 + 0x4 = i * 0x5 + 0x9`]; @@ -2303,8 +2835,7 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( IMP_REWRITE_TAC[ARITH_RULE `0x50 * i + 0x40 = (0x50 * i + 0x30) + 0x10`; READ_BYTES_AND_BYTE128_SPLIT] THEN EXISTS_TAC `(aes256_xts_encrypt pt_in (0x50 * i + 0x40) iv key1_lst key2_lst)` THEN REPEAT CONJ_TAC THENL [ - REWRITE_TAC [ARITH_RULE `(0x50 * i + 0x30) + 0x10 = 0x50 * i + 0x40`]; - + REWRITE_TAC [ARITH_RULE `(0x50 * i + 0x30) + 0x10 = 0x50 * i + 0x40`] THEN MP_TAC (SPECL [`0x5 * i + 0x4:num`; `pt_in:byte list`; `iv:int128`; `key1_lst:int128 list`; `key2_lst:int128 list`] LENGTH_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS) THEN REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC; GSYM ADD_ASSOC] THEN @@ -2359,8 +2890,7 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( IMP_REWRITE_TAC[ARITH_RULE `0x50 * i + 0x30 = (0x50 * i + 0x20) + 0x10`; READ_BYTES_AND_BYTE128_SPLIT] THEN EXISTS_TAC `(aes256_xts_encrypt pt_in (0x50 * i + 0x30) iv key1_lst key2_lst)` THEN REPEAT CONJ_TAC THENL [ - REWRITE_TAC [ARITH_RULE `(0x50 * i + 0x20) + 0x10 = 0x50 * i + 0x30`]; - + REWRITE_TAC [ARITH_RULE `(0x50 * i + 0x20) + 0x10 = 0x50 * i + 0x30`] THEN MP_TAC (SPECL [`0x5 * i + 0x3:num`; `pt_in:byte list`; `iv:int128`; `key1_lst:int128 list`; `key2_lst:int128 list`] LENGTH_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS) THEN REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC; GSYM ADD_ASSOC] THEN @@ -2419,8 +2949,7 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( `x:byte list`; `s188:armstate`] READ_BYTES_AND_BYTE128_SPLIT)] THEN EXISTS_TAC `(aes256_xts_encrypt pt_in (0x50 * i + 0x20) iv key1_lst key2_lst)` THEN REPEAT CONJ_TAC THENL [ - REWRITE_TAC [ARITH_RULE `(0x50 * i + 0x10) + 0x10 = 0x50 * i + 0x20`]; - + REWRITE_TAC [ARITH_RULE `(0x50 * i + 0x10) + 0x10 = 0x50 * i + 0x20`] THEN MP_TAC (SPECL [`0x5 * i + 0x2:num`; `pt_in:byte list`; `iv:int128`; `key1_lst:int128 list`; `key2_lst:int128 list`] LENGTH_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS) THEN REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC; GSYM ADD_ASSOC] THEN @@ -2563,6 +3092,7 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( REWRITE_TAC[LENGTH_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS] ]; + (* 4 goals total from here *) SUBGOAL_THEN `i + 1 < 2 EXP 64` ASSUME_TAC THENL [ UNDISCH_TAC `i < val (num_5blocks:int64)` THEN @@ -2581,7 +3111,7 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( REWRITE_TAC[VAL_EQ_0; WORD_SUB_EQ_0; WORD_VAL] ] ]; - + (* 3 goals total from here *) (** Subgoal 4 of main loop invariant: prove backedge is taken if i != val num_5blocks **) REPEAT STRIP_TAC THEN @@ -2593,86 +3123,534 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th])) THEN ENSURES_FINAL_STATE_TAC THEN ASM_SIMP_TAC[]; + (* 2 goals total from here *) + (** Subgoal 5: Prove the invariant implies post-condition + Backedge instruction is executed here **) + REPEAT STRIP_TAC THEN + REWRITE_TAC[byte_list_at] THEN + SUBST_ALL_TAC (WORD_RULE `(word (val (num_5blocks:int64))):int64 = num_5blocks`) THEN - ] -);; + MATCH_MP_TAC ENSURES_FRAME_SUBSUMED THEN + EXISTS_TAC `//MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI ,, + //MAYCHANGE [X19; X20; X21; X22],, why these registers? + //MAYCHANGE [Q8; Q9; Q10; Q11; Q12; Q13; Q14; Q15],, + MAYCHANGE [PC; X0; X1; X2; X4; X6; X7; X8; X9; X10; X11; X19; X20; X21; X22] ,, + MAYCHANGE [Q0; Q1; Q4; Q5; Q6; Q7; Q8; Q9; Q10; Q11; Q12; Q13; Q14; Q15; Q16; Q17; + Q18; Q19; Q20; Q21; Q22; Q23; Q24; Q25; Q26] ,, + MAYCHANGE [NF; ZF; CF; VF] ,, + if val (num_5blocks:int64) * 0x50 + 0x40 = val (len_full_blocks:int64) + then + MAYCHANGE [memory :> bytes128 (word_add ctxt_p (word (0x50 * val (num_5blocks:int64)))); + memory :> bytes128 (word_add ctxt_p (word (0x50 * val num_5blocks + 0x10))); + memory :> bytes128 (word_add ctxt_p (word (0x50 * val num_5blocks + 0x20))); + memory :> bytes128 (word_add ctxt_p (word (0x50 * val num_5blocks + 0x30)))] + else + (if val (num_5blocks:int64) * 0x50 + 0x30 = val (len_full_blocks:int64) + then + MAYCHANGE [memory :> bytes128 (word_add ctxt_p (word (0x50 * val (num_5blocks:int64)))); + memory :> bytes128 (word_add ctxt_p (word (0x50 * val num_5blocks + 0x10))); + memory :> bytes128 (word_add ctxt_p (word (0x50 * val num_5blocks + 0x20)))] + else + (if val (num_5blocks:int64) * 0x50 + 0x20 = val (len_full_blocks:int64) + then + MAYCHANGE [memory :> bytes128 (word_add ctxt_p (word (0x50 * val (num_5blocks:int64)))); + memory :> bytes128 (word_add ctxt_p (word (0x50 * val num_5blocks + 0x10)))] + else + (if val (num_5blocks:int64) * 0x50 + 0x10 = val (len_full_blocks:int64) + then + MAYCHANGE [memory :> bytes128 (word_add ctxt_p (word (0x50 * val (num_5blocks:int64))))] + else + MAYCHANGE []))) ,, + MAYCHANGE [events]` THEN + CONJ_TAC THENL [ + REPEAT (GEN_REWRITE_TAC ONCE_DEPTH_CONV [GSYM SEQ_ASSOC] THEN + MATCH_MP_TAC SUBSUMED_SEQ THEN REWRITE_TAC[SUBSUMED_REFL]) THEN + REPEAT COND_CASES_TAC THENL + [ SUBGOAL_THEN `0x50 * val (num_5blocks:int64) + 0x40 <= val (len:int64)` ASSUME_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC] THEN + ABBREV_TAC `val5blocks = val (num_5blocks:int64)` THEN + ABBREV_TAC `vallen = val (len:int64)` THEN + SUBSUMED_MAYCHANGE_TAC; + SUBGOAL_THEN `0x50 * val (num_5blocks:int64) + 0x30 <= val (len:int64)` ASSUME_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC] THEN + ABBREV_TAC `val5blocks = val (num_5blocks:int64)` THEN + ABBREV_TAC `vallen = val (len:int64)` THEN + SUBSUMED_MAYCHANGE_TAC; + SUBGOAL_THEN `0x50 * val (num_5blocks:int64) + 0x20 <= val (len:int64)` ASSUME_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC] THEN + ABBREV_TAC `val5blocks = val (num_5blocks:int64)` THEN + ABBREV_TAC `vallen = val (len:int64)` THEN + SUBSUMED_MAYCHANGE_TAC; + SUBGOAL_THEN `0x50 * val (num_5blocks:int64) + 0x10 <= val (len:int64)` ASSUME_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC] THEN + ABBREV_TAC `val5blocks = val (num_5blocks:int64)` THEN + ABBREV_TAC `vallen = val (len:int64)` THEN + SUBSUMED_MAYCHANGE_TAC; + SUBSUMED_MAYCHANGE_TAC] + ; ALL_TAC + ] THEN -(* + ENSURES_INIT_TAC "s0" THEN + ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (1--3) THEN + FIRST_X_ASSUM MP_TAC THEN + + (* Assumptions that help with reasoning about nonoverlapping + so that the universally quantified assumption stays. + See: https://hol-light.zulipchat.com/#narrow/channel/474190-s2n-bignum/topic/.E2.9C.94.20Symbolic.20simulation.20removed.20assumption/with/541554894 *) + SUBGOAL_THEN `(val (num_5blocks:int64)) * 0x50 < 0x2 EXP 0x40` ASSUME_TAC THENL + [ UNDISCH_TAC `val (num_5blocks:int64) * 0x50 <= val (len_full_blocks:int64)` THEN + UNDISCH_TAC `val (len_full_blocks:int64) <= 0x2 EXP 0x18` THEN + ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `val ((word (val (num_5blocks:int64) * 0x50)):int64) = 0x50 * val num_5blocks` ASSUME_TAC THENL [ + IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN ASM_ARITH_TAC; ALL_TAC] THEN + POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th])) THEN -(* - IMP_REWRITE_TAC[ARITH_RULE `0x50 * i + 0x20 = (0x50 * i + 0x10) + 0x10`; READ_BYTES_AND_BYTE128_SPLIT] THEN - EXISTS_TAC `(aes256_xts_encrypt pt_in (0x50 * i + 0x20) iv key1_lst key2_lst)` THEN + COND_CASES_TAC THENL + [ (* Case: len % 0x50 = 0x40 *) + DISCH_TAC THEN -`num_of_bytelist - (SUB_LIST (0x0,(0x50 * i + 0x10) + 0x10) - (aes256_xts_encrypt pt_in (0x50 * i + 0x20) iv key1_lst key2_lst)) = - num_of_bytelist - (aes256_xts_encrypt pt_in ((0x50 * i + 0x10) + 0x10) iv key1_lst key2_lst) /\ - (0x50 * i + 0x10) + 0x10 <= - LENGTH (aes256_xts_encrypt pt_in (0x50 * i + 0x20) iv key1_lst key2_lst) /\ - aes256_xts_encrypt_round - (bytes_to_int128 (SUB_LIST (i * 0x50 + 0x10,0x10) pt_in)) - (calculate_tweak (i * 0x5 + 0x1) iv key2_lst) - key1_lst = - bytes_to_int128 - (SUB_LIST (0x50 * i + 0x10,0x10) - (aes256_xts_encrypt pt_in (0x50 * i + 0x20) iv key1_lst key2_lst)) /\ - num_of_bytelist - (SUB_LIST (0x0,0x50 * i + 0x10) - (aes256_xts_encrypt pt_in (i * 0x50) iv key1_lst key2_lst)) = - num_of_bytelist - (SUB_LIST (0x0,0x50 * i + 0x10) - (aes256_xts_encrypt pt_in (0x50 * i + 0x20) iv key1_lst key2_lst)) /\ - aes256_xts_encrypt_round (bytes_to_int128 (SUB_LIST (i * 0x50,0x10) pt_in)) - (calculate_tweak (i * 0x5) iv key2_lst) - key1_lst = - bytes_to_int128 - (SUB_LIST (0x50 * i,0x10) - (aes256_xts_encrypt pt_in (i * 0x50) iv key1_lst key2_lst)) /\ - 0x50 * i + 0x10 <= - LENGTH (aes256_xts_encrypt pt_in (i * 0x50) iv key1_lst key2_lst)` -*) + SUBGOAL_THEN `val (num_5blocks:int64) * 0x50 + 0x40 = val (len_full_blocks:int64)` ASSUME_TAC THENL + [ UNDISCH_TAC `val (word_sub + (word_sub (len_full_blocks:int64) + (word_mul (word 0x50) (num_5blocks:int64))) + (word 0x40)) = + 0x0` THEN + REWRITE_TAC [VAL_EQ_0; WORD_SUB_EQ_0] THEN + REWRITE_TAC [WORD_RULE `!x:int64. word_mul (word 0x50) x = word(val x * 0x50)`] THEN + REWRITE_TAC[GSYM VAL_EQ] THEN + SUBGOAL_THEN `val (num_5blocks:int64) * 0x50 < 2 EXP 64` MP_TAC THENL + [ UNDISCH_TAC `val (num_5blocks:int64) * 0x50 <= val (len_full_blocks:int64)` THEN + UNDISCH_TAC `val (len_full_blocks:int64) <= 2 EXP 24` THEN + ARITH_TAC; ALL_TAC] THEN + REWRITE_TAC[VAL_WORD_SUB_CASES] THEN + SIMP_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN + UNDISCH_TAC `val (num_5blocks:int64) * 0x50 <= val (len_full_blocks:int64)` THEN + NUM_REDUCE_TAC THEN ARITH_TAC + ; ALL_TAC] THEN -`exists x. - num_of_bytelist (SUB_LIST (0x0,(0x50 * i + 0x40) + 0x10) x) = - num_of_bytelist - (SUB_LIST (0x0,(0x50 * i + 0x40) + 0x10) - (aes256_xts_encrypt pt_in ((0x50 * i + 0x40) + 0x10) iv key1_lst - key2_lst)) /\ - (0x50 * i + 0x40) + 0x10 <= LENGTH x /\ - aes256_xts_encrypt_round - (bytes_to_int128 (SUB_LIST (i * 0x50 + 0x40,0x10) pt_in)) - (calculate_tweak (i * 0x5 + 0x4) iv key2_lst) - key1_lst = - bytes_to_int128 (SUB_LIST (0x50 * i + 0x40,0x10) x) /\ - read (memory :> bytes (ctxt_p,0x50 * i + 0x40)) s188 = - num_of_bytelist (SUB_LIST (0x0,0x50 * i + 0x40) x)` - -`read (memory :> bytes (ctxt_p,0x50 * i + 0x50)) s188 = - num_of_bytelist - (SUB_LIST (0x0,0x50 * i + 0x50) - (aes256_xts_encrypt pt_in (0x50 * i + 0x50) iv key1_lst key2_lst))` - -`((forall i'. - i' < 0x50 * i + 0x50 - ==> read (memory :> bytes8 (word_add ctxt_p (word i'))) s188 = - EL i' - (aes256_xts_encrypt pt_in (0x50 * i + 0x50) iv key1_lst key2_lst)) <=> - read (memory :> bytes (ctxt_p,0x50 * i + 0x50)) s188 = + SUBGOAL_THEN `val (num_5blocks:int64) * 0x50 + 0x40 <= val (len:int64)` ASSUME_TAC THENL + [ UNDISCH_TAC `val (num_5blocks:int64) * 0x50 + 0x40 = val (len_full_blocks:int64)` THEN + UNDISCH_TAC `val (len_full_blocks:int64) <= val (len:int64)` THEN + ARITH_TAC + ; ALL_TAC] THEN + MP_TAC (SPECL [`ptxt_p:int64`; `num_5blocks:int64`; `len:int64`; `pt_in:byte list`; `s3:armstate`] READ_CT_TAIL4_LEMMA) THEN + ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN + + (* Assumptions that help with reasoning about nonoverlapping + so that the universally quantified assumption stays. + See: https://hol-light.zulipchat.com/#narrow/channel/474190-s2n-bignum/topic/.E2.9C.94.20Symbolic.20simulation.20removed.20assumption/with/541554894 *) + (*SUBGOAL_THEN `0x50 * (val (num_5blocks:int64)) < 0x2 EXP 0x40` ASSUME_TAC THENL + [ UNDISCH_TAC `val (num_5blocks:int64) * 0x50 <= val (len_full_blocks:int64)` THEN + UNDISCH_TAC `val (len_full_blocks:int64) <= 0x2 EXP 0x18` THEN + ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `val ((word (0x50 * val (num_5blocks:int64))):int64) = 0x50 * val num_5blocks` ASSUME_TAC THENL [ + IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN ASM_ARITH_TAC; ALL_TAC] THEN + POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th])) THEN *) + + ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (4--127) THEN + XTSENC_TAC `Q0:(armstate,int128)component` + `val (num_5blocks:int64) * 0x50` `val (num_5blocks:int64) * 0x5` THEN + XTSENC_TAC `Q1:(armstate,int128)component` + `val (num_5blocks:int64) * 0x50 + 0x10` `val (num_5blocks:int64) * 0x5 + 0x1` THEN + XTSENC_TAC `Q24:(armstate,int128)component` + `val (num_5blocks:int64) * 0x50 + 0x20` `val (num_5blocks:int64) * 0x5 + 0x2` THEN + XTSENC_TAC `Q25:(armstate,int128)component` + `val (num_5blocks:int64) * 0x50 + 0x30` `val (num_5blocks:int64) * 0x5 + 0x3` THEN + + (* The following lemmas are for NONSELFMODIFYING_STATE_UPDATE_TAC when store back to ctxt_p + Otherwise symbolic simulation fails with + Failure "could not prove that updates will not modify the program code" *) + CHANGED_TAC (RULE_ASSUM_TAC(REWRITE_RULE + [WORD_RULE `word_mul (word 0x50) num_5blocks:int64 = word(0x50 * val num_5blocks)`])) THEN + CHANGED_TAC (RULE_ASSUM_TAC(REWRITE_RULE + [WORD_RULE `!base m n. word_add (word_add base (word m)) (word n) = word_add base (word(m + n))`])) THEN + + ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (128--129) THEN (* Store 4 blocks in ctxt_p *) + ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (130--137) THEN (* Calculate tweak *) + TWEAK_TAC `Q6:(armstate,int128)component` `val (num_5blocks:int64) * 0x5 + 0x4` `val (num_5blocks:int64) * 0x5 + 0x3` THEN + + (* TODO: Still have the same problem *) + ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (138--138) THEN + ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN + REPEAT CONJ_TAC THENL (* 7 subgoals (9 total) *) + [ + REWRITE_TAC[acc_len] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; + REWRITE_TAC[acc_len] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; + REWRITE_TAC[acc_blocks] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; + REWRITE_TAC[acc_blocks] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; + REWRITE_TAC[acc_blocks] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; (* 4 total *) + + REWRITE_TAC[acc_len] THEN ASM_SIMP_TAC[LE_REFL] THEN + SUBGOAL_THEN `val ((word (0x50 * val (num_5blocks:int64) + 0x40)):int64) = + 0x50 * val num_5blocks + 0x40` ASSUME_TAC THENL + [ IMP_REWRITE_TAC[VAL_WORD; MOD_LT; DIMINDEX_64] THEN + UNDISCH_TAC `val (num_5blocks:int64) * 0x50 + 0x40 <= val (len:int64)` THEN + UNDISCH_TAC `val (len:int64) <= 0x2 EXP 0x18` THEN + ARITH_TAC; ALL_TAC] THEN + CHANGED_TAC (POP_ASSUM(fun th -> REWRITE_TAC[th])) THEN + + (* TODO: Manually add the assumption as a temporary fix to: + the symbolic simulation only contained results for 0th 1st and 3rd blocks, + but doesn't have 2nd *) + SUBGOAL_THEN `read + (memory :> + bytes128 + (word_add (ctxt_p:int64) (word (0x50 * val (num_5blocks:int64) + 0x20)))) + s138 = + aes256_xts_encrypt_round + (bytes_to_int128 + (SUB_LIST (val num_5blocks * 0x50 + 0x20,0x10) ct)) + (calculate_tweak (val num_5blocks * 0x5 + 0x2) iv key2_lst) + key1_lst` ASSUME_TAC THENL [CHEAT_TAC; ALL_TAC] THEN + (* TODO: ??? *) + CHANGED_TAC(RULE_ASSUM_TAC(REWRITE_RULE + [WORD_RULE `(word_add (word_add ctxt_p (word (0x50 * val num_5blocks))) + (word 0x30)) = (word_add (ctxt_p:int64) (word (0x50 * val (num_5blocks:int64) + 0x30)))`])) THEN + + (* Remove quantifier *) + UNDISCH_TAC + `forall i. + i < 0x50 * val (num_5blocks:int64) + ==> read (memory :> bytes8 (word_add ctxt_p (word i))) s138 = + EL i (aes256_xts_encrypt pt_in (val num_5blocks * 0x50) iv key1_lst key2_lst)` THEN + MP_TAC (SPECL [`0x50 * val (num_5blocks:int64) + 0x40:num`; `ctxt_p:int64`; + `(aes256_xts_encrypt pt_in (0x50 * val (num_5blocks:int64) + 0x40) iv key1_lst key2_lst):byte list`; + `s138:armstate`] BYTE_LIST_TO_NUM_THM) THEN + ANTS_TAC THENL[ + REWRITE_TAC[ARITH_RULE `0x50 * i + 0x40 = 0x10 * (5 * i + 4)`; + LENGTH_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS] THEN + ARITH_TAC + ; ALL_TAC] THEN +(* +`((forall i. + i < 0x50 * val num_5blocks + 0x40 + ==> read (memory :> bytes8 (word_add ctxt_p (word i))) s138 = + EL i + (aes256_xts_encrypt pt_in (0x50 * val num_5blocks + 0x40) iv + key1_lst + key2_lst)) <=> + read (memory :> bytes (ctxt_p,0x50 * val num_5blocks + 0x40)) s138 = num_of_bytelist - (SUB_LIST (0x0,0x50 * i + 0x50) - (aes256_xts_encrypt pt_in (0x50 * i + 0x50) iv key1_lst key2_lst))) - ==> (forall i'. - i' < 0x50 * i - ==> read (memory :> bytes8 (word_add ctxt_p (word i'))) s188 = - EL i' - (aes256_xts_encrypt pt_in (i * 0x50) iv key1_lst key2_lst)) - ==> (forall i'. - i' < 0x50 * i + 0x50 - ==> read (memory :> bytes8 (word_add ctxt_p (word i'))) s188 = - EL i' - (aes256_xts_encrypt pt_in (0x50 * i + 0x50) iv key1_lst + (SUB_LIST (0x0,0x50 * val num_5blocks + 0x40) + (aes256_xts_encrypt pt_in (0x50 * val num_5blocks + 0x40) iv key1_lst + key2_lst))) + ==> (forall i. + i < 0x50 * val num_5blocks + ==> read (memory :> bytes8 (word_add ctxt_p (word i))) s138 = + EL i + (aes256_xts_encrypt pt_in (val num_5blocks * 0x50) iv key1_lst + key2_lst)) + ==> (forall i. + i < 0x50 * val num_5blocks + 0x40 + ==> read (memory :> bytes8 (word_add ctxt_p (word i))) s138 = + EL i + (aes256_xts_encrypt pt_in (0x50 * val num_5blocks + 0x40) iv + key1_lst key2_lst))` +*) + DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN +(* + MP_TAC (SPECL [`0x50 * val (num_5blocks:int64):num`; `pt_ptr:int64`; + `(aes256_xts_decrypt ct (0x50 * val (num_5blocks:int64)) iv key1 key2):byte list`; + `s136:armstate`] BYTE_LIST_TO_NUM_THM) THEN + ANTS_TAC THENL[ + REWRITE_TAC[ARITH_RULE `0x50 * i = 0x10 * 5 * i`; + LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS] THEN + ARITH_TAC + ; ALL_TAC] THEN + DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN + DISCH_TAC THEN + + IMP_REWRITE_TAC[ARITH_RULE `0x50 * i + 0x40 = (0x50 * i + 0x30) + 0x10`; READ_BYTES_AND_BYTE128_SPLIT] THEN + EXISTS_TAC `(aes256_xts_decrypt ct (0x50 * val (num_5blocks:int64) + 0x40) iv key1 key2)` THEN + REPEAT CONJ_TAC THENL [ + REWRITE_TAC [ARITH_RULE `(0x50 * i + 0x30) + 0x10 = 0x50 * i + 0x40`]; + + MP_TAC (SPECL [`0x5 * val (num_5blocks:int64) + 0x4:num`; + `ct:byte list`; `iv:int128`; `key1:int128 list`; + `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN + REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC; GSYM ADD_ASSOC] THEN + CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC THEN + ASM_REWRITE_TAC[] THEN ARITH_TAC; + + (* Establish that one xts decrypt round is the same as + selecting one block of bytes from calling the top-level function. *) + REWRITE_TAC[aes256_xts_decrypt] THEN + SIMP_TAC[ARITH_RULE `~(0x50 * val (num_5blocks:int64) + 0x40 < 0x10)`] THEN + SUBGOAL_THEN `(0x50 * val (num_5blocks:int64) + 0x40) MOD 0x10 = 0` SUBST1_TAC THENL + [ REWRITE_TAC[ARITH_RULE `80 * i + 64 = 16 * (5 * i + 4)`] THEN + REWRITE_TAC[MOD_MULT] + ; ALL_TAC] THEN + CONV_TAC (DEPTH_CONV let_CONV) THEN + REWRITE_TAC[SUB_0; ARITH_RULE `(0x50 * i + 0x40) DIV 0x10 = 0x5 * i + 0x4`] THEN + SIMP_TAC[ARITH_RULE `~(0x5 * i + 0x4 < 0x2)`; + ARITH_RULE `(0x5 * i + 0x4) - 0x2 = 0x5 * i + 0x2`; + ARITH_RULE `(0x5 * i + 0x4) - 0x1 = 0x5 * i + 0x3`] THEN + + MP_TAC (SPECL [`0`;`5 * val (num_5blocks:int64) + 2:num`; + `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + LENGTH_OF_AES256_XTS_DECRYPT_REC) THEN + SIMP_TAC[ARITH_RULE `~(5 * i + 2 < 0)`; + ARITH_RULE `((0x5 * i + 0x2) - 0x0 + 0x1) * 0x10 = 0x50 * i + 0x30`] THEN + IMP_REWRITE_TAC[SUB_LIST_APPEND_RIGHT_LEMMA] THEN DISCH_TAC THEN + + MP_TAC (SPECL [`5 * val (num_5blocks:int64) + 3:num`; + `0x0:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + LENGTH_OF_AES256_XTS_DECRYPT_TAIL) THEN + CONV_TAC NUM_REDUCE_CONV THEN REWRITE_TAC[ADD_0] THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN + + REWRITE_TAC[AES256_XTS_DECRYPT_TAIL_WHEN_1BLOCK] THEN + ASM_SIMP_TAC[ARITH_RULE `(i * 0x5 + 0x3) * 0x10 = i * 0x50 + 0x30`; + ARITH_RULE `5 * i + 3 = i * 5 + 3`]; + + (* Proving that reading previous bytes is the same as the spec *) + REWRITE_TAC[ARITH_RULE `0x50 * i + 0x30 = 0x10 * (5 * i + 3)`; + ARITH_RULE `0x50 * i + 0x40 = 0x10 * (5 * i + 3) + 0x10`] THEN + REWRITE_TAC[SUB_LIST_OF_AES256_XTS_DECRYPT_FULL_BLOCKS] THEN + ASM_REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC] THEN CONV_TAC NUM_REDUCE_CONV + ] THEN + + IMP_REWRITE_TAC[ARITH_RULE `0x50 * i + 0x30 = (0x50 * i + 0x20) + 0x10`; READ_BYTES_AND_BYTE128_SPLIT] THEN + EXISTS_TAC `(aes256_xts_decrypt ct (0x50 * val (num_5blocks:int64) + 0x30) iv key1 key2)` THEN + REPEAT CONJ_TAC THENL [ + MP_TAC (SPECL [`0x5 * val (num_5blocks:int64) + 0x3:num`; + `ct:byte list`; `iv:int128`; `key1:int128 list`; + `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN + REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC; GSYM ADD_ASSOC] THEN + CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES]; + + REWRITE_TAC [ARITH_RULE `(0x50 * i + 0x20) + 0x10 = 0x50 * i + 0x30`] THEN + MP_TAC (SPECL [`0x5 * val (num_5blocks:int64) + 0x3:num`; + `ct:byte list`; `iv:int128`; `key1:int128 list`; + `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN + REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC; GSYM ADD_ASSOC] THEN + CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN ARITH_TAC; + + (* Establish that one xts decrypt round is the same as + selecting one block of bytes from calling the top-level function. *) + REWRITE_TAC[aes256_xts_decrypt] THEN + SIMP_TAC[ARITH_RULE `~(0x50 * i + 0x30 < 0x10)`] THEN + SUBGOAL_THEN `(0x50 * val (num_5blocks:int64) + 0x30) MOD 0x10 = 0` SUBST1_TAC THENL + [ REWRITE_TAC[ARITH_RULE `80 * i + 48 = 16 * (5 * i + 3)`] THEN + REWRITE_TAC[MOD_MULT] + ; ALL_TAC] THEN + CONV_TAC (DEPTH_CONV let_CONV) THEN + REWRITE_TAC[SUB_0; ARITH_RULE `(0x50 * i + 0x30) DIV 0x10 = 0x5 * i + 0x3`] THEN + SIMP_TAC[ARITH_RULE `~(0x5 * i + 0x3 < 0x2)`; + ARITH_RULE `(0x5 * i + 0x3) - 0x2 = 0x5 * i + 0x1`; + ARITH_RULE `(0x5 * i + 0x3) - 0x1 = 0x5 * i + 0x2`] THEN + + MP_TAC (SPECL [`0`;`5 * val (num_5blocks:int64) + 1:num`; + `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + LENGTH_OF_AES256_XTS_DECRYPT_REC) THEN + SIMP_TAC[ARITH_RULE `~(5 * i + 1 < 0)`] THEN + REWRITE_TAC[ARITH_RULE `((0x5 * i + 0x1) - 0x0 + 0x1) * 0x10 = 0x50 * i + 0x20`] THEN + IMP_REWRITE_TAC[SUB_LIST_APPEND_RIGHT_LEMMA] THEN DISCH_TAC THEN + + MP_TAC (SPECL [`5 * val (num_5blocks:int64) + 2:num`; `0x0:num`; + `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + LENGTH_OF_AES256_XTS_DECRYPT_TAIL) THEN + CONV_TAC NUM_REDUCE_CONV THEN REWRITE_TAC[ADD_0] THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN + + REWRITE_TAC[AES256_XTS_DECRYPT_TAIL_WHEN_1BLOCK] THEN + ASM_SIMP_TAC[ARITH_RULE `(i * 0x5 + 0x2) * 0x10 = i * 0x50 + 0x20`; + ARITH_RULE `5 * i + 2 = i * 5 + 2`]; + + (* Proving that reading previous bytes is the same as the spec *) + REWRITE_TAC[ARITH_RULE `0x50 * i + 0x20 = 0x10 * (5 * i + 2)`; + ARITH_RULE `0x50 * i + 0x30 = 0x10 * (5 * i + 2) + 0x10`] THEN + REWRITE_TAC[SUB_LIST_OF_AES256_XTS_DECRYPT_FULL_BLOCKS] THEN + ASM_REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC] THEN CONV_TAC NUM_REDUCE_CONV + ] THEN + + REWRITE_TAC[ARITH_RULE `0x50 * i + 0x20 = (0x50 * i + 0x10) + 0x10`] THEN + (* Use SPECL to force IMP_REWRITE_TAC to apply once once *) + IMP_REWRITE_TAC[(SPECL [`pt_ptr:int64`; `(0x50 * val (num_5blocks:int64) + 0x10):num`; + `x:byte list`; `s188:armstate`] READ_BYTES_AND_BYTE128_SPLIT)] THEN + EXISTS_TAC `(aes256_xts_decrypt ct (0x50 * val (num_5blocks:int64) + 0x20) iv key1 key2)` THEN + REPEAT CONJ_TAC THENL [ + MP_TAC (SPECL [`0x5 * val (num_5blocks:int64) + 0x2:num`; + `ct:byte list`; `iv:int128`; `key1:int128 list`; + `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN + REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC; GSYM ADD_ASSOC] THEN + CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN ARITH_TAC; + + MP_TAC (SPECL [`0x5 * val (num_5blocks:int64) + 0x2:num`; + `ct:byte list`; `iv:int128`; `key1:int128 list`; + `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN + REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC; GSYM ADD_ASSOC] THEN + CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN ARITH_TAC; + + (* Establish that one xts decrypt round is the same as + selecting one block of bytes from calling the top-level function. *) + REWRITE_TAC[aes256_xts_decrypt] THEN + SIMP_TAC[ARITH_RULE `~(0x50 * i + 0x20 < 0x10)`] THEN + SUBGOAL_THEN `(0x50 * val (num_5blocks:int64) + 0x20) MOD 0x10 = 0` SUBST1_TAC THENL + [ REWRITE_TAC[ARITH_RULE `80 * i + 32 = 16 * (5 * i + 2)`] THEN + REWRITE_TAC[MOD_MULT] + ; ALL_TAC] THEN + CONV_TAC (DEPTH_CONV let_CONV) THEN + REWRITE_TAC[SUB_0; ARITH_RULE `(0x50 * i + 0x20) DIV 0x10 = 0x5 * i + 0x2`] THEN + SIMP_TAC[ARITH_RULE `~(0x5 * i + 0x2 < 0x2)`; + ARITH_RULE `(0x5 * i + 0x2) - 0x2 = 0x5 * i`; + ARITH_RULE `(0x5 * i + 0x2) - 0x1 = 0x5 * i + 0x1`] THEN + + MP_TAC (SPECL [`0`;`5 * val (num_5blocks:int64):num`; + `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + LENGTH_OF_AES256_XTS_DECRYPT_REC) THEN + SIMP_TAC[ARITH_RULE `~(5 * i < 0)`; + ARITH_RULE `(0x5 * i - 0x0 + 0x1) * 0x10 = 0x50 * i + 0x10`] THEN + IMP_REWRITE_TAC[SUB_LIST_APPEND_RIGHT_LEMMA] THEN DISCH_TAC THEN + + MP_TAC (SPECL [`5 * val (num_5blocks:int64) + 1:num`; `0x0:num`; + `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + LENGTH_OF_AES256_XTS_DECRYPT_TAIL) THEN + CONV_TAC NUM_REDUCE_CONV THEN REWRITE_TAC[ADD_0] THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN + + REWRITE_TAC[AES256_XTS_DECRYPT_TAIL_WHEN_1BLOCK] THEN + SIMP_TAC[ARITH_RULE `i * 0x50 + 0x10 = (i * 0x5 + 0x1) * 0x10`; + ARITH_RULE `i * 0x5 = 0x5 * i`]; + + (* Proving that reading previous bytes is the same as the spec *) + REWRITE_TAC[ARITH_RULE `0x50 * i + 0x10 = 0x10 * (5 * i + 1)`; + ARITH_RULE `0x50 * i + 0x20 = 0x10 * (5 * i + 1) + 0x10`] THEN + REWRITE_TAC[SUB_LIST_OF_AES256_XTS_DECRYPT_FULL_BLOCKS] THEN + ASM_REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC] THEN CONV_TAC NUM_REDUCE_CONV + ] THEN + + IMP_REWRITE_TAC[(SPECL [`pt_ptr:int64`; `(0x50 * val (num_5blocks:int64)):num`; + `(aes256_xts_decrypt ct (0x50 * val (num_5blocks:int64) + 0x10) iv key1 key2):byte list`; + `s188:armstate`] + READ_BYTES_AND_BYTE128_SPLIT)] THEN + EXISTS_TAC `ct:byte list` THEN EXISTS_TAC `iv:int128` THEN + EXISTS_TAC `key1:int128 list` THEN EXISTS_TAC `key2:int128 list` THEN + REPEAT CONJ_TAC THENL [ + MP_TAC (SPECL [`0x5 * val (num_5blocks:int64) + 0x1:num`; + `ct:byte list`; `iv:int128`; `key1:int128 list`; + `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN + REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC; GSYM ADD_ASSOC] THEN + CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN ARITH_TAC; + + MP_TAC (SPECL [`0x5 * val (num_5blocks:int64) + 0x1:num`; + `ct:byte list`; `iv:int128`; `key1:int128 list`; + `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN + REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC; GSYM ADD_ASSOC] THEN + CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN ARITH_TAC; + + (* Establish that one xts decrypt round is the same as + selecting one block of bytes from calling the top-level function. *) + REWRITE_TAC[aes256_xts_decrypt] THEN + SIMP_TAC[ARITH_RULE `~(0x50 * i + 0x10 < 0x10)`] THEN + SUBGOAL_THEN `(0x50 * val (num_5blocks:int64) + 0x10) MOD 0x10 = 0` SUBST1_TAC THENL + [ REWRITE_TAC[ARITH_RULE `80 * i + 16 = 16 * (5 * i + 1)`] THEN + REWRITE_TAC[MOD_MULT] + ; ALL_TAC] THEN + CONV_TAC (DEPTH_CONV let_CONV) THEN + REWRITE_TAC[SUB_0; ARITH_RULE `(0x50 * i + 0x10) DIV 0x10 = 0x5 * i + 0x1`] THEN + (* Two cases: i = 0 then execute tail branch, else execute recursion branch *) + COND_CASES_TAC THENL + [ SUBGOAL_THEN `val (num_5blocks:int64) = 0` SUBST1_TAC THENL + [ UNDISCH_TAC `5 * val (num_5blocks:int64) + 1 < 2` THEN + UNDISCH_TAC `0 < val (num_5blocks:int64)` THEN + ARITH_TAC + ; ALL_TAC] THEN CONV_TAC NUM_REDUCE_CONV THEN + + MP_TAC (SPECL [`0x0:num`; `0x0:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + LENGTH_OF_AES256_XTS_DECRYPT_TAIL) THEN + CONV_TAC NUM_REDUCE_CONV THEN REWRITE_TAC[ADD_0] THEN DISCH_TAC THEN + IMP_REWRITE_TAC[(ISPECL [`(aes256_xts_decrypt_tail 0x0 0x0 ct iv key1 key2):byte list`; + `0x10:num`] SUB_LIST_LENGTH_IMPLIES)] THEN + + REWRITE_TAC[AES256_XTS_DECRYPT_TAIL_WHEN_1BLOCK] THEN + CONV_TAC NUM_REDUCE_CONV; + + SIMP_TAC[ARITH_RULE `(0x5 * i + 0x1) - 0x2 = 0x5 * i - 0x1`; + ARITH_RULE `(0x5 * i + 0x1) - 0x1 = 0x5 * i`] THEN + + MP_TAC (SPECL [`0`;`5 * val (num_5blocks:int64) - 1:num`; + `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + LENGTH_OF_AES256_XTS_DECRYPT_REC) THEN + SUBGOAL_THEN `~(0x5 * val (num_5blocks:int64) - 0x1 < 0x0)` ASSUME_TAC THENL + [ UNDISCH_TAC `~(0x5 * val (num_5blocks:int64) + 0x1 < 0x2)` THEN ARITH_TAC; ALL_TAC ] THEN + ASM_SIMP_TAC[] THEN + IMP_REWRITE_TAC[ARITH_RULE `~(0x5 * i + 0x1 < 0x2) ==> (0x5 * i - 1 - 0x0 + 0x1) * 0x10 = 0x50 * i`] THEN + IMP_REWRITE_TAC[SUB_LIST_APPEND_RIGHT_LEMMA] THEN DISCH_TAC THEN + + MP_TAC (SPECL [`5 * val (num_5blocks:int64):num`; + `0x0:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + LENGTH_OF_AES256_XTS_DECRYPT_TAIL) THEN + CONV_TAC NUM_REDUCE_CONV THEN REWRITE_TAC[ADD_0] THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN + + REWRITE_TAC[AES256_XTS_DECRYPT_TAIL_WHEN_1BLOCK] THEN + SIMP_TAC[ARITH_RULE `i * 0x50 = (i * 0x5) * 0x10`; + ARITH_RULE `i * 0x5 = 0x5 * i`]]; + + (* Proving that reading previous bytes is the same as the spec *) + REWRITE_TAC[ARITH_RULE `0x50 * i = 0x10 * 5 * i`; + ARITH_RULE `0x50 * i + 0x10 = 0x10 * 5 * i + 0x10`] THEN + REWRITE_TAC[SUB_LIST_OF_AES256_XTS_DECRYPT_FULL_BLOCKS] THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN + REWRITE_TAC[LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS]] + ] + ; ALL_TAC] THEN + ] + ] +);; + + +(* +`MAYCHANGE [X9; X10; X11; X22] ,, + MAYCHANGE [Q0; Q1; Q24; Q25; Q6] ,, + (if val num_5blocks * 0x50 + 0x40 = val len_full_blocks + then MAYCHANGE + [memory :> bytes128 (word_add ctxt_p (word (0x50 * val num_5blocks))); + memory :> + bytes128 (word_add ctxt_p (word (0x50 * val num_5blocks + 0x10))); + memory :> + bytes128 (word_add ctxt_p (word (0x50 * val num_5blocks + 0x20))); + memory :> + bytes128 (word_add ctxt_p (word (0x50 * val num_5blocks + 0x30)))] + else if val num_5blocks * 0x50 + 0x30 = val len_full_blocks + then MAYCHANGE + [memory :> + bytes128 (word_add ctxt_p (word (0x50 * val num_5blocks))); + memory :> + bytes128 + (word_add ctxt_p (word (0x50 * val num_5blocks + 0x10))); + memory :> + bytes128 + (word_add ctxt_p (word (0x50 * val num_5blocks + 0x20)))] + else if val num_5blocks * 0x50 + 0x20 = val len_full_blocks + then MAYCHANGE + [memory :> + bytes128 (word_add ctxt_p (word (0x50 * val num_5blocks))); + memory :> + bytes128 + (word_add ctxt_p (word (0x50 * val num_5blocks + 0x10)))] + else if val num_5blocks * 0x50 + 0x10 = val len_full_blocks + then MAYCHANGE + [memory :> + bytes128 + (word_add ctxt_p (word (0x50 * val num_5blocks)))] + else (MAYCHANGE:((armstate,?443102)component)list->armstate->armstate->bool) + []) subsumed + MAYCHANGE [PC; X0; X1; X2; X4; X6; X7; X8; X9; X10; X11; X19; X20; X21; X22] ,, + MAYCHANGE + [Q0; Q1; Q4; Q5; Q6; Q7; Q8; Q9; Q10; Q11; Q12; Q13; Q14; Q15; Q16; Q17; + Q18; Q19; Q20; Q21; Q22; Q23; Q24; Q25; Q26] ,, + MAYCHANGE [NF; ZF; CF; VF] ,, + MAYCHANGE [memory :> bytes (ctxt_p,val len)] ,, + MAYCHANGE [events]` `(forall i'. i' < 0x50 * i @@ -2685,4 +3663,4 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( (aes256_xts_encrypt pt_in (0x50 * i + 0x50) iv key1_lst key2_lst))` -*) \ No newline at end of file +*) From 0d537e7da4bd3e2ab3ff494c82068025dbce62e5 Mon Sep 17 00:00:00 2001 From: Nevine Ebeid Date: Tue, 28 Oct 2025 15:43:30 -0400 Subject: [PATCH 078/132] Subgoal 5: case len mod 0x50 = 0x40. --- arm/proofs/aes-xts-armv8.ml | 234 ++++++++++++++++++------------------ 1 file changed, 115 insertions(+), 119 deletions(-) diff --git a/arm/proofs/aes-xts-armv8.ml b/arm/proofs/aes-xts-armv8.ml index bbee43e2c..a04a17bc9 100644 --- a/arm/proofs/aes-xts-armv8.ml +++ b/arm/proofs/aes-xts-armv8.ml @@ -2333,8 +2333,9 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( ) (MAYCHANGE [PC;X0;X1;X2;X4;X6;X7;X8;X9;X10;X11;X19;X20;X21;X22],, MAYCHANGE [Q0;Q1;Q4;Q5;Q6;Q7;Q8;Q9;Q10;Q11;Q12;Q13;Q14;Q15;Q16;Q17;Q18;Q19;Q20;Q21;Q22;Q23;Q24;Q25;Q26],, - MAYCHANGE SOME_FLAGS,, MAYCHANGE [memory :> bytes(ctxt_p, val len)],, - MAYCHANGE [events])`, + MAYCHANGE SOME_FLAGS,, + MAYCHANGE [events],, + MAYCHANGE [memory :> bytes(ctxt_p, val len)])`, REWRITE_TAC [(REWRITE_CONV [aes256_xts_encrypt_mc] THENC LENGTH_CONV) `LENGTH aes256_xts_encrypt_mc`] THEN REWRITE_TAC[byte_list_at; set_key_schedule; NONOVERLAPPING_CLAUSES; C_ARGUMENTS; SOME_FLAGS; PAIRWISE; ALL] THEN @@ -2616,12 +2617,12 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( MAYCHANGE [Q0; Q1; Q4; Q5; Q6; Q7; Q8; Q9; Q10; Q11; Q12; Q13; Q14; Q15; Q16; Q17; Q18; Q19; Q20; Q21; Q22; Q23; Q24; Q25; Q26] ,, MAYCHANGE [NF; ZF; CF; VF] ,, + MAYCHANGE [events] ,, MAYCHANGE [memory :> bytes128 (word_add ctxt_p (word (0x50 * i))); memory :> bytes128 (word_add ctxt_p (word (0x50 * i + 0x10))); memory :> bytes128 (word_add ctxt_p (word (0x50 * i + 0x20))); memory :> bytes128 (word_add ctxt_p (word (0x50 * i + 0x30))); - memory :> bytes128 (word_add ctxt_p (word (0x50 * i + 0x40)))],, - MAYCHANGE [events]` THEN + memory :> bytes128 (word_add ctxt_p (word (0x50 * i + 0x40)))]` THEN CONJ_TAC THENL[ REPEAT (GEN_REWRITE_TAC ONCE_DEPTH_CONV [GSYM SEQ_ASSOC] THEN MATCH_MP_TAC SUBSUMED_SEQ THEN REWRITE_TAC[SUBSUMED_REFL]) THEN @@ -2773,7 +2774,7 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN DISCH_TAC THEN - (* Prove one block equivalence and reduce proving the following: + (* Prove one block equivalence and reduce proving the following: TODO: change comment to encrypt pt_in ... `read (memory :> bytes (pt_ptr,0x50 * i + 0x50)) s188 = num_of_bytelist (aes256_xts_decrypt ct (0x50 * i + 0x50) iv key1 key2)` @@ -3111,6 +3112,7 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( REWRITE_TAC[VAL_EQ_0; WORD_SUB_EQ_0; WORD_VAL] ] ]; + (* 3 goals total from here *) (** Subgoal 4 of main loop invariant: prove backedge is taken if i != val num_5blocks **) @@ -3132,12 +3134,13 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( MATCH_MP_TAC ENSURES_FRAME_SUBSUMED THEN EXISTS_TAC `//MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI ,, - //MAYCHANGE [X19; X20; X21; X22],, why these registers? + //MAYCHANGE [X19; X20; X21; X22],, //MAYCHANGE [Q8; Q9; Q10; Q11; Q12; Q13; Q14; Q15],, MAYCHANGE [PC; X0; X1; X2; X4; X6; X7; X8; X9; X10; X11; X19; X20; X21; X22] ,, MAYCHANGE [Q0; Q1; Q4; Q5; Q6; Q7; Q8; Q9; Q10; Q11; Q12; Q13; Q14; Q15; Q16; Q17; Q18; Q19; Q20; Q21; Q22; Q23; Q24; Q25; Q26] ,, MAYCHANGE [NF; ZF; CF; VF] ,, + MAYCHANGE [events] ,, if val (num_5blocks:int64) * 0x50 + 0x40 = val (len_full_blocks:int64) then MAYCHANGE [memory :> bytes128 (word_add ctxt_p (word (0x50 * val (num_5blocks:int64)))); @@ -3160,8 +3163,9 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( then MAYCHANGE [memory :> bytes128 (word_add ctxt_p (word (0x50 * val (num_5blocks:int64))))] else - MAYCHANGE []))) ,, - MAYCHANGE [events]` THEN + MAYCHANGE []))) + ` THEN + (* REWRITE_TAC[MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI] THEN *) CONJ_TAC THENL [ REPEAT (GEN_REWRITE_TAC ONCE_DEPTH_CONV [GSYM SEQ_ASSOC] THEN MATCH_MP_TAC SUBSUMED_SEQ THEN REWRITE_TAC[SUBSUMED_REFL]) THEN @@ -3299,7 +3303,7 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( s138 = aes256_xts_encrypt_round (bytes_to_int128 - (SUB_LIST (val num_5blocks * 0x50 + 0x20,0x10) ct)) + (SUB_LIST (val num_5blocks * 0x50 + 0x20,0x10) pt_in)) (calculate_tweak (val num_5blocks * 0x5 + 0x2) iv key2_lst) key1_lst` ASSUME_TAC THENL [CHEAT_TAC; ALL_TAC] THEN (* TODO: ??? *) @@ -3307,7 +3311,21 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( [WORD_RULE `(word_add (word_add ctxt_p (word (0x50 * val num_5blocks))) (word 0x30)) = (word_add (ctxt_p:int64) (word (0x50 * val (num_5blocks:int64) + 0x30)))`])) THEN - (* Remove quantifier *) + (* Remove quantifier in conclusion then in antecedent of the goal: + ==> (forall i. + i < 0x50 * val num_5blocks + ==> read (memory :> bytes8 (word_add ctxt_p (word i))) s138 = + EL i + (aes256_xts_encrypt pt_in (val num_5blocks * 0x50) iv key1_lst + key2_lst)) + ==> (forall i. + i < 0x50 * val num_5blocks + 0x40 + ==> read (memory :> bytes8 (word_add ctxt_p (word i))) s138 = + EL i + (aes256_xts_encrypt pt_in (0x50 * val num_5blocks + 0x40) iv + key1_lst + key2_lst))` + *) UNDISCH_TAC `forall i. i < 0x50 * val (num_5blocks:int64) @@ -3321,61 +3339,35 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( LENGTH_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS] THEN ARITH_TAC ; ALL_TAC] THEN -(* -`((forall i. - i < 0x50 * val num_5blocks + 0x40 - ==> read (memory :> bytes8 (word_add ctxt_p (word i))) s138 = - EL i - (aes256_xts_encrypt pt_in (0x50 * val num_5blocks + 0x40) iv - key1_lst - key2_lst)) <=> - read (memory :> bytes (ctxt_p,0x50 * val num_5blocks + 0x40)) s138 = - num_of_bytelist - (SUB_LIST (0x0,0x50 * val num_5blocks + 0x40) - (aes256_xts_encrypt pt_in (0x50 * val num_5blocks + 0x40) iv key1_lst - key2_lst))) - ==> (forall i. - i < 0x50 * val num_5blocks - ==> read (memory :> bytes8 (word_add ctxt_p (word i))) s138 = - EL i - (aes256_xts_encrypt pt_in (val num_5blocks * 0x50) iv key1_lst - key2_lst)) - ==> (forall i. - i < 0x50 * val num_5blocks + 0x40 - ==> read (memory :> bytes8 (word_add ctxt_p (word i))) s138 = - EL i - (aes256_xts_encrypt pt_in (0x50 * val num_5blocks + 0x40) iv - key1_lst - key2_lst))` -*) + DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN -(* - MP_TAC (SPECL [`0x50 * val (num_5blocks:int64):num`; `pt_ptr:int64`; - `(aes256_xts_decrypt ct (0x50 * val (num_5blocks:int64)) iv key1 key2):byte list`; - `s136:armstate`] BYTE_LIST_TO_NUM_THM) THEN + + MP_TAC (SPECL [`0x50 * val (num_5blocks:int64):num`; `ctxt_p:int64`; + `(aes256_xts_encrypt pt_in (val (num_5blocks:int64) * 0x50) iv key1_lst key2_lst):byte list`; + `s138:armstate`] BYTE_LIST_TO_NUM_THM) THEN ANTS_TAC THENL[ - REWRITE_TAC[ARITH_RULE `0x50 * i = 0x10 * 5 * i`; - LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS] THEN + REWRITE_TAC[ARITH_RULE `i * 0x50 = 0x10 * 5 * i`; + LENGTH_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS] THEN ARITH_TAC ; ALL_TAC] THEN DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN DISCH_TAC THEN IMP_REWRITE_TAC[ARITH_RULE `0x50 * i + 0x40 = (0x50 * i + 0x30) + 0x10`; READ_BYTES_AND_BYTE128_SPLIT] THEN - EXISTS_TAC `(aes256_xts_decrypt ct (0x50 * val (num_5blocks:int64) + 0x40) iv key1 key2)` THEN + EXISTS_TAC `(aes256_xts_encrypt pt_in (0x50 * val (num_5blocks:int64) + 0x40) iv key1_lst key2_lst)` THEN REPEAT CONJ_TAC THENL [ REWRITE_TAC [ARITH_RULE `(0x50 * i + 0x30) + 0x10 = 0x50 * i + 0x40`]; MP_TAC (SPECL [`0x5 * val (num_5blocks:int64) + 0x4:num`; - `ct:byte list`; `iv:int128`; `key1:int128 list`; - `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN + `pt_in:byte list`; `iv:int128`; `key1_lst:int128 list`; + `key2_lst:int128 list`] LENGTH_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS) THEN REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC; GSYM ADD_ASSOC] THEN CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC THEN ASM_REWRITE_TAC[] THEN ARITH_TAC; - (* Establish that one xts decrypt round is the same as + (* Establish that one xts encrypt round is the same as selecting one block of bytes from calling the top-level function. *) - REWRITE_TAC[aes256_xts_decrypt] THEN + REWRITE_TAC[aes256_xts_encrypt] THEN SIMP_TAC[ARITH_RULE `~(0x50 * val (num_5blocks:int64) + 0x40 < 0x10)`] THEN SUBGOAL_THEN `(0x50 * val (num_5blocks:int64) + 0x40) MOD 0x10 = 0` SUBST1_TAC THENL [ REWRITE_TAC[ARITH_RULE `80 * i + 64 = 16 * (5 * i + 4)`] THEN @@ -3384,54 +3376,54 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( CONV_TAC (DEPTH_CONV let_CONV) THEN REWRITE_TAC[SUB_0; ARITH_RULE `(0x50 * i + 0x40) DIV 0x10 = 0x5 * i + 0x4`] THEN SIMP_TAC[ARITH_RULE `~(0x5 * i + 0x4 < 0x2)`; - ARITH_RULE `(0x5 * i + 0x4) - 0x2 = 0x5 * i + 0x2`; - ARITH_RULE `(0x5 * i + 0x4) - 0x1 = 0x5 * i + 0x3`] THEN + ARITH_RULE `(0x5 * i + 0x4) - 0x2 = 0x5 * i + 0x2`; + ARITH_RULE `(0x5 * i + 0x4) - 0x1 = 0x5 * i + 0x3`] THEN - MP_TAC (SPECL [`0`;`5 * val (num_5blocks:int64) + 2:num`; - `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] - LENGTH_OF_AES256_XTS_DECRYPT_REC) THEN + MP_TAC (SPECL [`0`;`5 * val (num_5blocks:int64) + 2:num`; `pt_in:byte list`; `iv:int128`; + `key1_lst:int128 list`; `key2_lst:int128 list`] + LENGTH_OF_AES256_XTS_ENCRYPT_REC) THEN SIMP_TAC[ARITH_RULE `~(5 * i + 2 < 0)`; - ARITH_RULE `((0x5 * i + 0x2) - 0x0 + 0x1) * 0x10 = 0x50 * i + 0x30`] THEN + ARITH_RULE `((0x5 * i + 0x2) - 0x0 + 0x1) * 0x10 = 0x50 * i + 0x30`] THEN IMP_REWRITE_TAC[SUB_LIST_APPEND_RIGHT_LEMMA] THEN DISCH_TAC THEN - MP_TAC (SPECL [`5 * val (num_5blocks:int64) + 3:num`; - `0x0:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] - LENGTH_OF_AES256_XTS_DECRYPT_TAIL) THEN + MP_TAC (SPECL [`5 * val (num_5blocks:int64) + 3:num`; `0x0:num`; `pt_in:byte list`; `iv:int128`; + `key1_lst:int128 list`; `key2_lst:int128 list`] + LENGTH_OF_AES256_XTS_ENCRYPT_TAIL) THEN CONV_TAC NUM_REDUCE_CONV THEN REWRITE_TAC[ADD_0] THEN DISCH_TAC THEN IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN - REWRITE_TAC[AES256_XTS_DECRYPT_TAIL_WHEN_1BLOCK] THEN + REWRITE_TAC[AES256_XTS_ENCRYPT_TAIL_WHEN_1BLOCK] THEN ASM_SIMP_TAC[ARITH_RULE `(i * 0x5 + 0x3) * 0x10 = i * 0x50 + 0x30`; ARITH_RULE `5 * i + 3 = i * 5 + 3`]; (* Proving that reading previous bytes is the same as the spec *) REWRITE_TAC[ARITH_RULE `0x50 * i + 0x30 = 0x10 * (5 * i + 3)`; ARITH_RULE `0x50 * i + 0x40 = 0x10 * (5 * i + 3) + 0x10`] THEN - REWRITE_TAC[SUB_LIST_OF_AES256_XTS_DECRYPT_FULL_BLOCKS] THEN + REWRITE_TAC[SUB_LIST_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS] THEN ASM_REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC] THEN CONV_TAC NUM_REDUCE_CONV ] THEN IMP_REWRITE_TAC[ARITH_RULE `0x50 * i + 0x30 = (0x50 * i + 0x20) + 0x10`; READ_BYTES_AND_BYTE128_SPLIT] THEN - EXISTS_TAC `(aes256_xts_decrypt ct (0x50 * val (num_5blocks:int64) + 0x30) iv key1 key2)` THEN + EXISTS_TAC `(aes256_xts_encrypt pt_in (0x50 * val (num_5blocks:int64) + 0x30) iv key1_lst key2_lst)` THEN REPEAT CONJ_TAC THENL [ MP_TAC (SPECL [`0x5 * val (num_5blocks:int64) + 0x3:num`; - `ct:byte list`; `iv:int128`; `key1:int128 list`; - `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN + `pt_in:byte list`; `iv:int128`; `key1_lst:int128 list`; + `key2_lst:int128 list`] LENGTH_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS) THEN REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC; GSYM ADD_ASSOC] THEN CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC THEN IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES]; REWRITE_TAC [ARITH_RULE `(0x50 * i + 0x20) + 0x10 = 0x50 * i + 0x30`] THEN MP_TAC (SPECL [`0x5 * val (num_5blocks:int64) + 0x3:num`; - `ct:byte list`; `iv:int128`; `key1:int128 list`; - `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN + `pt_in:byte list`; `iv:int128`; `key1_lst:int128 list`; + `key2_lst:int128 list`] LENGTH_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS) THEN REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC; GSYM ADD_ASSOC] THEN CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC THEN IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN ARITH_TAC; - (* Establish that one xts decrypt round is the same as + (* Establish that one xts encrypt round is the same as selecting one block of bytes from calling the top-level function. *) - REWRITE_TAC[aes256_xts_decrypt] THEN + REWRITE_TAC[aes256_xts_encrypt] THEN SIMP_TAC[ARITH_RULE `~(0x50 * i + 0x30 < 0x10)`] THEN SUBGOAL_THEN `(0x50 * val (num_5blocks:int64) + 0x30) MOD 0x10 = 0` SUBST1_TAC THENL [ REWRITE_TAC[ARITH_RULE `80 * i + 48 = 16 * (5 * i + 3)`] THEN @@ -3443,53 +3435,53 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( ARITH_RULE `(0x5 * i + 0x3) - 0x2 = 0x5 * i + 0x1`; ARITH_RULE `(0x5 * i + 0x3) - 0x1 = 0x5 * i + 0x2`] THEN - MP_TAC (SPECL [`0`;`5 * val (num_5blocks:int64) + 1:num`; - `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] - LENGTH_OF_AES256_XTS_DECRYPT_REC) THEN + MP_TAC (SPECL [`0`;`5 * val (num_5blocks:int64) + 1:num`; `pt_in:byte list`; `iv:int128`; + `key1_lst:int128 list`; `key2_lst:int128 list`] + LENGTH_OF_AES256_XTS_ENCRYPT_REC) THEN SIMP_TAC[ARITH_RULE `~(5 * i + 1 < 0)`] THEN REWRITE_TAC[ARITH_RULE `((0x5 * i + 0x1) - 0x0 + 0x1) * 0x10 = 0x50 * i + 0x20`] THEN IMP_REWRITE_TAC[SUB_LIST_APPEND_RIGHT_LEMMA] THEN DISCH_TAC THEN - MP_TAC (SPECL [`5 * val (num_5blocks:int64) + 2:num`; `0x0:num`; - `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] - LENGTH_OF_AES256_XTS_DECRYPT_TAIL) THEN + MP_TAC (SPECL [`5 * val (num_5blocks:int64) + 2:num`; `0x0:num`; `pt_in:byte list`; `iv:int128`; + `key1_lst:int128 list`; `key2_lst:int128 list`] + LENGTH_OF_AES256_XTS_ENCRYPT_TAIL) THEN CONV_TAC NUM_REDUCE_CONV THEN REWRITE_TAC[ADD_0] THEN DISCH_TAC THEN IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN - REWRITE_TAC[AES256_XTS_DECRYPT_TAIL_WHEN_1BLOCK] THEN + REWRITE_TAC[AES256_XTS_ENCRYPT_TAIL_WHEN_1BLOCK] THEN ASM_SIMP_TAC[ARITH_RULE `(i * 0x5 + 0x2) * 0x10 = i * 0x50 + 0x20`; ARITH_RULE `5 * i + 2 = i * 5 + 2`]; - (* Proving that reading previous bytes is the same as the spec *) - REWRITE_TAC[ARITH_RULE `0x50 * i + 0x20 = 0x10 * (5 * i + 2)`; - ARITH_RULE `0x50 * i + 0x30 = 0x10 * (5 * i + 2) + 0x10`] THEN - REWRITE_TAC[SUB_LIST_OF_AES256_XTS_DECRYPT_FULL_BLOCKS] THEN - ASM_REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC] THEN CONV_TAC NUM_REDUCE_CONV + (* Proving that reading previous bytes is the same as the spec *) + REWRITE_TAC[ARITH_RULE `0x50 * i + 0x20 = 0x10 * (5 * i + 2)`; + ARITH_RULE `0x50 * i + 0x30 = 0x10 * (5 * i + 2) + 0x10`] THEN + REWRITE_TAC[SUB_LIST_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS] THEN + ASM_REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC] THEN CONV_TAC NUM_REDUCE_CONV ] THEN REWRITE_TAC[ARITH_RULE `0x50 * i + 0x20 = (0x50 * i + 0x10) + 0x10`] THEN (* Use SPECL to force IMP_REWRITE_TAC to apply once once *) - IMP_REWRITE_TAC[(SPECL [`pt_ptr:int64`; `(0x50 * val (num_5blocks:int64) + 0x10):num`; - `x:byte list`; `s188:armstate`] READ_BYTES_AND_BYTE128_SPLIT)] THEN - EXISTS_TAC `(aes256_xts_decrypt ct (0x50 * val (num_5blocks:int64) + 0x20) iv key1 key2)` THEN + IMP_REWRITE_TAC[(SPECL [`ctxt_p:int64`; `(0x50 * val (num_5blocks:int64) + 0x10):num`; + `x:byte list`; `s138:armstate`] READ_BYTES_AND_BYTE128_SPLIT)] THEN + EXISTS_TAC `(aes256_xts_encrypt pt_in (0x50 * val (num_5blocks:int64) + 0x20) iv key1_lst key2_lst)` THEN REPEAT CONJ_TAC THENL [ MP_TAC (SPECL [`0x5 * val (num_5blocks:int64) + 0x2:num`; - `ct:byte list`; `iv:int128`; `key1:int128 list`; - `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN + `pt_in:byte list`; `iv:int128`; `key1_lst:int128 list`; + `key2_lst:int128 list`] LENGTH_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS) THEN REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC; GSYM ADD_ASSOC] THEN CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC THEN IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN ARITH_TAC; MP_TAC (SPECL [`0x5 * val (num_5blocks:int64) + 0x2:num`; - `ct:byte list`; `iv:int128`; `key1:int128 list`; - `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN + `pt_in:byte list`; `iv:int128`; `key1_lst:int128 list`; + `key2_lst:int128 list`] LENGTH_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS) THEN REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC; GSYM ADD_ASSOC] THEN CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC THEN IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN ARITH_TAC; - (* Establish that one xts decrypt round is the same as + (* Establish that one xts encrypt round is the same as selecting one block of bytes from calling the top-level function. *) - REWRITE_TAC[aes256_xts_decrypt] THEN + REWRITE_TAC[aes256_xts_encrypt] THEN SIMP_TAC[ARITH_RULE `~(0x50 * i + 0x20 < 0x10)`] THEN SUBGOAL_THEN `(0x50 * val (num_5blocks:int64) + 0x20) MOD 0x10 = 0` SUBST1_TAC THENL [ REWRITE_TAC[ARITH_RULE `80 * i + 32 = 16 * (5 * i + 2)`] THEN @@ -3502,53 +3494,52 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( ARITH_RULE `(0x5 * i + 0x2) - 0x1 = 0x5 * i + 0x1`] THEN MP_TAC (SPECL [`0`;`5 * val (num_5blocks:int64):num`; - `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] - LENGTH_OF_AES256_XTS_DECRYPT_REC) THEN + `pt_in:byte list`; `iv:int128`; `key1_lst:int128 list`; `key2_lst:int128 list`] + LENGTH_OF_AES256_XTS_ENCRYPT_REC) THEN SIMP_TAC[ARITH_RULE `~(5 * i < 0)`; ARITH_RULE `(0x5 * i - 0x0 + 0x1) * 0x10 = 0x50 * i + 0x10`] THEN IMP_REWRITE_TAC[SUB_LIST_APPEND_RIGHT_LEMMA] THEN DISCH_TAC THEN MP_TAC (SPECL [`5 * val (num_5blocks:int64) + 1:num`; `0x0:num`; - `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] - LENGTH_OF_AES256_XTS_DECRYPT_TAIL) THEN + `pt_in:byte list`; `iv:int128`; `key1_lst:int128 list`; `key2_lst:int128 list`] + LENGTH_OF_AES256_XTS_ENCRYPT_TAIL) THEN CONV_TAC NUM_REDUCE_CONV THEN REWRITE_TAC[ADD_0] THEN DISCH_TAC THEN IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN - REWRITE_TAC[AES256_XTS_DECRYPT_TAIL_WHEN_1BLOCK] THEN + REWRITE_TAC[AES256_XTS_ENCRYPT_TAIL_WHEN_1BLOCK] THEN SIMP_TAC[ARITH_RULE `i * 0x50 + 0x10 = (i * 0x5 + 0x1) * 0x10`; ARITH_RULE `i * 0x5 = 0x5 * i`]; (* Proving that reading previous bytes is the same as the spec *) REWRITE_TAC[ARITH_RULE `0x50 * i + 0x10 = 0x10 * (5 * i + 1)`; ARITH_RULE `0x50 * i + 0x20 = 0x10 * (5 * i + 1) + 0x10`] THEN - REWRITE_TAC[SUB_LIST_OF_AES256_XTS_DECRYPT_FULL_BLOCKS] THEN + REWRITE_TAC[SUB_LIST_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS] THEN ASM_REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC] THEN CONV_TAC NUM_REDUCE_CONV ] THEN - IMP_REWRITE_TAC[(SPECL [`pt_ptr:int64`; `(0x50 * val (num_5blocks:int64)):num`; - `(aes256_xts_decrypt ct (0x50 * val (num_5blocks:int64) + 0x10) iv key1 key2):byte list`; - `s188:armstate`] - READ_BYTES_AND_BYTE128_SPLIT)] THEN - EXISTS_TAC `ct:byte list` THEN EXISTS_TAC `iv:int128` THEN - EXISTS_TAC `key1:int128 list` THEN EXISTS_TAC `key2:int128 list` THEN + IMP_REWRITE_TAC[(SPECL [`ctxt_p:int64`; `(0x50 * val (num_5blocks:int64)):num`; + `(aes256_xts_encrypt pt_in (0x50 * val (num_5blocks:int64) + 0x10) iv key1_lst key2_lst):byte list`; + `s138:armstate`] READ_BYTES_AND_BYTE128_SPLIT)] THEN + EXISTS_TAC `iv:int128` THEN EXISTS_TAC `key1_lst:int128 list` THEN + EXISTS_TAC `key2_lst:int128 list` THEN EXISTS_TAC `pt_in:byte list` THEN REPEAT CONJ_TAC THENL [ MP_TAC (SPECL [`0x5 * val (num_5blocks:int64) + 0x1:num`; - `ct:byte list`; `iv:int128`; `key1:int128 list`; - `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN + `pt_in:byte list`; `iv:int128`; `key1_lst:int128 list`; + `key2_lst:int128 list`] LENGTH_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS) THEN REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC; GSYM ADD_ASSOC] THEN CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC THEN IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN ARITH_TAC; MP_TAC (SPECL [`0x5 * val (num_5blocks:int64) + 0x1:num`; - `ct:byte list`; `iv:int128`; `key1:int128 list`; - `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN + `pt_in:byte list`; `iv:int128`; `key1_lst:int128 list`; + `key2_lst:int128 list`] LENGTH_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS) THEN REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC; GSYM ADD_ASSOC] THEN CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC THEN IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN ARITH_TAC; - (* Establish that one xts decrypt round is the same as + (* Establish that one xts encrypt round is the same as selecting one block of bytes from calling the top-level function. *) - REWRITE_TAC[aes256_xts_decrypt] THEN + REWRITE_TAC[aes256_xts_encrypt] THEN SIMP_TAC[ARITH_RULE `~(0x50 * i + 0x10 < 0x10)`] THEN SUBGOAL_THEN `(0x50 * val (num_5blocks:int64) + 0x10) MOD 0x10 = 0` SUBST1_TAC THENL [ REWRITE_TAC[ARITH_RULE `80 * i + 16 = 16 * (5 * i + 1)`] THEN @@ -3564,21 +3555,21 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( ARITH_TAC ; ALL_TAC] THEN CONV_TAC NUM_REDUCE_CONV THEN - MP_TAC (SPECL [`0x0:num`; `0x0:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] - LENGTH_OF_AES256_XTS_DECRYPT_TAIL) THEN + MP_TAC (SPECL [`0x0:num`; `0x0:num`; `pt_in:byte list`; `iv:int128`; `key1_lst:int128 list`; `key2_lst:int128 list`] + LENGTH_OF_AES256_XTS_ENCRYPT_TAIL) THEN CONV_TAC NUM_REDUCE_CONV THEN REWRITE_TAC[ADD_0] THEN DISCH_TAC THEN - IMP_REWRITE_TAC[(ISPECL [`(aes256_xts_decrypt_tail 0x0 0x0 ct iv key1 key2):byte list`; + IMP_REWRITE_TAC[(ISPECL [`(aes256_xts_encrypt_tail 0x0 0x0 pt_in iv key1_lst key2_lst):byte list`; `0x10:num`] SUB_LIST_LENGTH_IMPLIES)] THEN - REWRITE_TAC[AES256_XTS_DECRYPT_TAIL_WHEN_1BLOCK] THEN + REWRITE_TAC[AES256_XTS_ENCRYPT_TAIL_WHEN_1BLOCK] THEN CONV_TAC NUM_REDUCE_CONV; SIMP_TAC[ARITH_RULE `(0x5 * i + 0x1) - 0x2 = 0x5 * i - 0x1`; ARITH_RULE `(0x5 * i + 0x1) - 0x1 = 0x5 * i`] THEN MP_TAC (SPECL [`0`;`5 * val (num_5blocks:int64) - 1:num`; - `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] - LENGTH_OF_AES256_XTS_DECRYPT_REC) THEN + `pt_in:byte list`; `iv:int128`; `key1_lst:int128 list`; `key2_lst:int128 list`] + LENGTH_OF_AES256_XTS_ENCRYPT_REC) THEN SUBGOAL_THEN `~(0x5 * val (num_5blocks:int64) - 0x1 < 0x0)` ASSUME_TAC THENL [ UNDISCH_TAC `~(0x5 * val (num_5blocks:int64) + 0x1 < 0x2)` THEN ARITH_TAC; ALL_TAC ] THEN ASM_SIMP_TAC[] THEN @@ -3586,23 +3577,28 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( IMP_REWRITE_TAC[SUB_LIST_APPEND_RIGHT_LEMMA] THEN DISCH_TAC THEN MP_TAC (SPECL [`5 * val (num_5blocks:int64):num`; - `0x0:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] - LENGTH_OF_AES256_XTS_DECRYPT_TAIL) THEN + `0x0:num`; `pt_in:byte list`; `iv:int128`; `key1_lst:int128 list`; `key2_lst:int128 list`] + LENGTH_OF_AES256_XTS_ENCRYPT_TAIL) THEN CONV_TAC NUM_REDUCE_CONV THEN REWRITE_TAC[ADD_0] THEN DISCH_TAC THEN IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN - REWRITE_TAC[AES256_XTS_DECRYPT_TAIL_WHEN_1BLOCK] THEN + REWRITE_TAC[AES256_XTS_ENCRYPT_TAIL_WHEN_1BLOCK] THEN SIMP_TAC[ARITH_RULE `i * 0x50 = (i * 0x5) * 0x10`; - ARITH_RULE `i * 0x5 = 0x5 * i`]]; + ARITH_RULE `i * 0x5 = 0x5 * i`] + ]; (* Proving that reading previous bytes is the same as the spec *) - REWRITE_TAC[ARITH_RULE `0x50 * i = 0x10 * 5 * i`; + REWRITE_TAC[ARITH_RULE `i * 0x50 = 0x50 * i`; + ARITH_RULE `0x50 * i = 0x10 * 5 * i`; ARITH_RULE `0x50 * i + 0x10 = 0x10 * 5 * i + 0x10`] THEN - REWRITE_TAC[SUB_LIST_OF_AES256_XTS_DECRYPT_FULL_BLOCKS] THEN + REWRITE_TAC[SUB_LIST_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS] THEN IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN - REWRITE_TAC[LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS]] + REWRITE_TAC[LENGTH_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS]] ] - ; ALL_TAC] THEN + ; ALL_TAC + ] THEN + + DISCH_TAC THEN ] ] );; From de50b6504c68b44795754755608e6fd7d5be8cec Mon Sep 17 00:00:00 2001 From: Nevine Ebeid Date: Thu, 30 Oct 2025 18:17:48 -0400 Subject: [PATCH 079/132] Subgoal 5: case len mod 0x50 = 0x30. --- arm/proofs/aes-xts-armv8.ml | 489 ++++++++++++++++++++++++++++++++++-- 1 file changed, 472 insertions(+), 17 deletions(-) diff --git a/arm/proofs/aes-xts-armv8.ml b/arm/proofs/aes-xts-armv8.ml index a04a17bc9..8995c18c0 100644 --- a/arm/proofs/aes-xts-armv8.ml +++ b/arm/proofs/aes-xts-armv8.ml @@ -1298,7 +1298,7 @@ let READ_CT_LEMMA = prove( REWRITE_TAC[byte_list_at] THEN ASM_SIMP_TAC[] );; -(* Same as Decrypt but with "num_5blocks_adjusted" replaced by "num_5blocks", +(* Same as Decrypt but with "num_5blocks" replaced by "num_5blocks", which can still be used with Decrypt since it's universally quantified at the beginning of this lemma and the following ones *) let READ_CT_TAIL4_LEMMA = prove( @@ -1455,7 +1455,7 @@ let NUM_5BLOCKS_LO_BOUND_THM = prove( ARITH_TAC );; (* -let NUM_BLOCKS_ADJUSTED_LT_LEN_THM = prove( +let len_full_blocks_LT_LEN_THM = prove( `!(len:int64) num_blocks. word_and len (word 0xfffffffffffffff0) = num_blocks ==> ~(val num_blocks < 0x60) @@ -3283,7 +3283,15 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( REWRITE_TAC[acc_blocks] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; REWRITE_TAC[acc_blocks] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; REWRITE_TAC[acc_blocks] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; (* 4 total *) - +(* +`forall i. + i < val (word (acc_len num_5blocks len_full_blocks)) + ==> read (memory :> bytes8 (word_add ctxt_p (word i))) s138 = + EL i + (aes256_xts_encrypt pt_in (acc_len num_5blocks len_full_blocks) iv + key1_lst + key2_lst)` +*) REWRITE_TAC[acc_len] THEN ASM_SIMP_TAC[LE_REFL] THEN SUBGOAL_THEN `val ((word (0x50 * val (num_5blocks:int64) + 0x40)):int64) = 0x50 * val num_5blocks + 0x40` ASSUME_TAC THENL @@ -3292,7 +3300,15 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( UNDISCH_TAC `val (len:int64) <= 0x2 EXP 0x18` THEN ARITH_TAC; ALL_TAC] THEN CHANGED_TAC (POP_ASSUM(fun th -> REWRITE_TAC[th])) THEN - +(* +`forall i. + i < 0x50 * val num_5blocks + 0x40 + ==> read (memory :> bytes8 (word_add ctxt_p (word i))) s138 = + EL i + (aes256_xts_encrypt pt_in (0x50 * val num_5blocks + 0x40) iv + key1_lst + key2_lst)` +*) (* TODO: Manually add the assumption as a temporary fix to: the symbolic simulation only contained results for 0th 1st and 3rd blocks, but doesn't have 2nd *) @@ -3339,9 +3355,20 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( LENGTH_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS] THEN ARITH_TAC ; ALL_TAC] THEN - DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN - +(* +`(forall i. + i < 0x50 * val num_5blocks + ==> read (memory :> bytes8 (word_add ctxt_p (word i))) s138 = + EL i + (aes256_xts_encrypt pt_in (val num_5blocks * 0x50) iv key1_lst + key2_lst)) + ==> read (memory :> bytes (ctxt_p,0x50 * val num_5blocks + 0x40)) s138 = + num_of_bytelist + (SUB_LIST (0x0,0x50 * val num_5blocks + 0x40) + (aes256_xts_encrypt pt_in (0x50 * val num_5blocks + 0x40) iv key1_lst + key2_lst))` +*) MP_TAC (SPECL [`0x50 * val (num_5blocks:int64):num`; `ctxt_p:int64`; `(aes256_xts_encrypt pt_in (val (num_5blocks:int64) * 0x50) iv key1_lst key2_lst):byte list`; `s138:armstate`] BYTE_LIST_TO_NUM_THM) THEN @@ -3351,20 +3378,45 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( ARITH_TAC ; ALL_TAC] THEN DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN +(* +`read (memory :> bytes (ctxt_p,0x50 * val num_5blocks)) s138 = + num_of_bytelist + (SUB_LIST (0x0,0x50 * val num_5blocks) + (aes256_xts_encrypt pt_in (val num_5blocks * 0x50) iv key1_lst key2_lst)) + ==> read (memory :> bytes (ctxt_p,0x50 * val num_5blocks + 0x40)) s138 = + num_of_bytelist + (SUB_LIST (0x0,0x50 * val num_5blocks + 0x40) + (aes256_xts_encrypt pt_in (0x50 * val num_5blocks + 0x40) iv key1_lst + key2_lst))` +*) DISCH_TAC THEN IMP_REWRITE_TAC[ARITH_RULE `0x50 * i + 0x40 = (0x50 * i + 0x30) + 0x10`; READ_BYTES_AND_BYTE128_SPLIT] THEN EXISTS_TAC `(aes256_xts_encrypt pt_in (0x50 * val (num_5blocks:int64) + 0x40) iv key1_lst key2_lst)` THEN REPEAT CONJ_TAC THENL [ REWRITE_TAC [ARITH_RULE `(0x50 * i + 0x30) + 0x10 = 0x50 * i + 0x40`]; - +(* +`(0x50 * val num_5blocks + 0x30) + 0x10 <= + LENGTH + (aes256_xts_encrypt pt_in (0x50 * val num_5blocks + 0x40) iv key1_lst + key2_lst)` +*) MP_TAC (SPECL [`0x5 * val (num_5blocks:int64) + 0x4:num`; `pt_in:byte list`; `iv:int128`; `key1_lst:int128 list`; `key2_lst:int128 list`] LENGTH_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS) THEN REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC; GSYM ADD_ASSOC] THEN CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC THEN - ASM_REWRITE_TAC[] THEN ARITH_TAC; - + ASM_REWRITE_TAC[] THEN ARITH_TAC; (* 4 total *) +(* +`aes256_xts_encrypt_round + (bytes_to_int128 (SUB_LIST (val num_5blocks * 0x50 + 0x30,0x10) pt_in)) + (calculate_tweak (val num_5blocks * 0x5 + 0x3) iv key2_lst) + key1_lst = + bytes_to_int128 + (SUB_LIST (0x50 * val num_5blocks + 0x30,0x10) + (aes256_xts_encrypt pt_in (0x50 * val num_5blocks + 0x40) iv key1_lst + key2_lst))` +*) (* Establish that one xts encrypt round is the same as selecting one block of bytes from calling the top-level function. *) REWRITE_TAC[aes256_xts_encrypt] THEN @@ -3378,29 +3430,94 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( SIMP_TAC[ARITH_RULE `~(0x5 * i + 0x4 < 0x2)`; ARITH_RULE `(0x5 * i + 0x4) - 0x2 = 0x5 * i + 0x2`; ARITH_RULE `(0x5 * i + 0x4) - 0x1 = 0x5 * i + 0x3`] THEN - +(* +`aes256_xts_encrypt_round + (bytes_to_int128 (SUB_LIST (val num_5blocks * 0x50 + 0x30,0x10) pt_in)) + (calculate_tweak (val num_5blocks * 0x5 + 0x3) iv key2_lst) + key1_lst = + bytes_to_int128 + (SUB_LIST (0x50 * val num_5blocks + 0x30,0x10) + (APPEND + (aes256_xts_encrypt_rec 0x0 (0x5 * val num_5blocks + 0x2) pt_in iv key1_lst + key2_lst) + (aes256_xts_encrypt_tail (0x5 * val num_5blocks + 0x3) 0x0 pt_in iv key1_lst + key2_lst)))` +*) MP_TAC (SPECL [`0`;`5 * val (num_5blocks:int64) + 2:num`; `pt_in:byte list`; `iv:int128`; `key1_lst:int128 list`; `key2_lst:int128 list`] LENGTH_OF_AES256_XTS_ENCRYPT_REC) THEN SIMP_TAC[ARITH_RULE `~(5 * i + 2 < 0)`; ARITH_RULE `((0x5 * i + 0x2) - 0x0 + 0x1) * 0x10 = 0x50 * i + 0x30`] THEN +(* +`LENGTH + (aes256_xts_encrypt_rec 0x0 (0x5 * val num_5blocks + 0x2) pt_in iv key1_lst + key2_lst) = + 0x50 * val num_5blocks + 0x30 + ==> aes256_xts_encrypt_round + (bytes_to_int128 (SUB_LIST (val num_5blocks * 0x50 + 0x30,0x10) pt_in)) + (calculate_tweak (val num_5blocks * 0x5 + 0x3) iv key2_lst) + key1_lst = + bytes_to_int128 + (SUB_LIST (0x50 * val num_5blocks + 0x30,0x10) + (APPEND + (aes256_xts_encrypt_rec 0x0 (0x5 * val num_5blocks + 0x2) pt_in iv + key1_lst + key2_lst) + (aes256_xts_encrypt_tail (0x5 * val num_5blocks + 0x3) 0x0 pt_in iv + key1_lst + key2_lst)))` +*) IMP_REWRITE_TAC[SUB_LIST_APPEND_RIGHT_LEMMA] THEN DISCH_TAC THEN +(* +`aes256_xts_encrypt_round + (bytes_to_int128 (SUB_LIST (val num_5blocks * 0x50 + 0x30,0x10) pt_in)) + (calculate_tweak (val num_5blocks * 0x5 + 0x3) iv key2_lst) + key1_lst = + bytes_to_int128 + (SUB_LIST (0x0,0x10) + (aes256_xts_encrypt_tail (0x5 * val num_5blocks + 0x3) 0x0 pt_in iv key1_lst + key2_lst))` +*) MP_TAC (SPECL [`5 * val (num_5blocks:int64) + 3:num`; `0x0:num`; `pt_in:byte list`; `iv:int128`; `key1_lst:int128 list`; `key2_lst:int128 list`] LENGTH_OF_AES256_XTS_ENCRYPT_TAIL) THEN CONV_TAC NUM_REDUCE_CONV THEN REWRITE_TAC[ADD_0] THEN DISCH_TAC THEN +(* +`aes256_xts_encrypt_round + (bytes_to_int128 (SUB_LIST (val num_5blocks * 0x50 + 0x30,0x10) pt_in)) + (calculate_tweak (val num_5blocks * 0x5 + 0x3) iv key2_lst) + key1_lst = + bytes_to_int128 + (SUB_LIST (0x0,0x10) + (aes256_xts_encrypt_tail (0x5 * val num_5blocks + 0x3) 0x0 pt_in iv key1_lst + key2_lst))` +*) IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN - +(* +`aes256_xts_encrypt_round + (bytes_to_int128 (SUB_LIST (val num_5blocks * 0x50 + 0x30,0x10) pt_in)) + (calculate_tweak (val num_5blocks * 0x5 + 0x3) iv key2_lst) + key1_lst = + bytes_to_int128 + (aes256_xts_encrypt_tail (0x5 * val num_5blocks + 0x3) 0x0 pt_in iv key1_lst + key2_lst)` +*) REWRITE_TAC[AES256_XTS_ENCRYPT_TAIL_WHEN_1BLOCK] THEN ASM_SIMP_TAC[ARITH_RULE `(i * 0x5 + 0x3) * 0x10 = i * 0x50 + 0x30`; - ARITH_RULE `5 * i + 3 = i * 5 + 3`]; - + ARITH_RULE `5 * i + 3 = i * 5 + 3`]; (* 3 total *) +(* +`read (memory :> bytes (ctxt_p,0x50 * val num_5blocks + 0x30)) s138 = + num_of_bytelist + (SUB_LIST (0x0,0x50 * val num_5blocks + 0x30) + (aes256_xts_encrypt pt_in (0x50 * val num_5blocks + 0x40) iv key1_lst + key2_lst))` +*) (* Proving that reading previous bytes is the same as the spec *) REWRITE_TAC[ARITH_RULE `0x50 * i + 0x30 = 0x10 * (5 * i + 3)`; ARITH_RULE `0x50 * i + 0x40 = 0x10 * (5 * i + 3) + 0x10`] THEN REWRITE_TAC[SUB_LIST_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS] THEN - ASM_REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC] THEN CONV_TAC NUM_REDUCE_CONV + ASM_REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC] THEN CONV_TAC NUM_REDUCE_CONV (* 3 total *) ] THEN IMP_REWRITE_TAC[ARITH_RULE `0x50 * i + 0x30 = (0x50 * i + 0x20) + 0x10`; READ_BYTES_AND_BYTE128_SPLIT] THEN @@ -3517,6 +3634,299 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( ASM_REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC] THEN CONV_TAC NUM_REDUCE_CONV ] THEN + IMP_REWRITE_TAC[(SPECL [`ctxt_p:int64`; `(0x50 * val (num_5blocks:int64)):num`; + `(aes256_xts_encrypt pt_in (0x50 * val (num_5blocks:int64) + 0x10) iv key1_lst key2_lst):byte list`; + `s138:armstate`] READ_BYTES_AND_BYTE128_SPLIT)] THEN + EXISTS_TAC `iv:int128` THEN EXISTS_TAC `key1_lst:int128 list` THEN + EXISTS_TAC `key2_lst:int128 list` THEN EXISTS_TAC `pt_in:byte list` THEN + REPEAT CONJ_TAC THENL [ + MP_TAC (SPECL [`0x5 * val (num_5blocks:int64) + 0x1:num`; + `pt_in:byte list`; `iv:int128`; `key1_lst:int128 list`; + `key2_lst:int128 list`] LENGTH_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS) THEN + REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC; GSYM ADD_ASSOC] THEN + CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN ARITH_TAC; + + MP_TAC (SPECL [`0x5 * val (num_5blocks:int64) + 0x1:num`; + `pt_in:byte list`; `iv:int128`; `key1_lst:int128 list`; + `key2_lst:int128 list`] LENGTH_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS) THEN + REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC; GSYM ADD_ASSOC] THEN + CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN ARITH_TAC; + + (* Establish that one xts encrypt round is the same as + selecting one block of bytes from calling the top-level function. *) + REWRITE_TAC[aes256_xts_encrypt] THEN + SIMP_TAC[ARITH_RULE `~(0x50 * i + 0x10 < 0x10)`] THEN + SUBGOAL_THEN `(0x50 * val (num_5blocks:int64) + 0x10) MOD 0x10 = 0` SUBST1_TAC THENL + [ REWRITE_TAC[ARITH_RULE `80 * i + 16 = 16 * (5 * i + 1)`] THEN + REWRITE_TAC[MOD_MULT] + ; ALL_TAC] THEN + CONV_TAC (DEPTH_CONV let_CONV) THEN + REWRITE_TAC[SUB_0; ARITH_RULE `(0x50 * i + 0x10) DIV 0x10 = 0x5 * i + 0x1`] THEN + (* Two cases: i = 0 then execute tail branch, else execute recursion branch *) + COND_CASES_TAC THENL + [ SUBGOAL_THEN `val (num_5blocks:int64) = 0` SUBST1_TAC THENL + [ UNDISCH_TAC `5 * val (num_5blocks:int64) + 1 < 2` THEN + UNDISCH_TAC `0 < val (num_5blocks:int64)` THEN + ARITH_TAC + ; ALL_TAC] THEN CONV_TAC NUM_REDUCE_CONV THEN + + MP_TAC (SPECL [`0x0:num`; `0x0:num`; `pt_in:byte list`; `iv:int128`; `key1_lst:int128 list`; `key2_lst:int128 list`] + LENGTH_OF_AES256_XTS_ENCRYPT_TAIL) THEN + CONV_TAC NUM_REDUCE_CONV THEN REWRITE_TAC[ADD_0] THEN DISCH_TAC THEN + IMP_REWRITE_TAC[(ISPECL [`(aes256_xts_encrypt_tail 0x0 0x0 pt_in iv key1_lst key2_lst):byte list`; + `0x10:num`] SUB_LIST_LENGTH_IMPLIES)] THEN + + REWRITE_TAC[AES256_XTS_ENCRYPT_TAIL_WHEN_1BLOCK] THEN + CONV_TAC NUM_REDUCE_CONV; + + SIMP_TAC[ARITH_RULE `(0x5 * i + 0x1) - 0x2 = 0x5 * i - 0x1`; + ARITH_RULE `(0x5 * i + 0x1) - 0x1 = 0x5 * i`] THEN + + MP_TAC (SPECL [`0`;`5 * val (num_5blocks:int64) - 1:num`; + `pt_in:byte list`; `iv:int128`; `key1_lst:int128 list`; `key2_lst:int128 list`] + LENGTH_OF_AES256_XTS_ENCRYPT_REC) THEN + SUBGOAL_THEN `~(0x5 * val (num_5blocks:int64) - 0x1 < 0x0)` ASSUME_TAC THENL + [ UNDISCH_TAC `~(0x5 * val (num_5blocks:int64) + 0x1 < 0x2)` THEN ARITH_TAC; ALL_TAC ] THEN + ASM_SIMP_TAC[] THEN + IMP_REWRITE_TAC[ARITH_RULE `~(0x5 * i + 0x1 < 0x2) ==> (0x5 * i - 1 - 0x0 + 0x1) * 0x10 = 0x50 * i`] THEN + IMP_REWRITE_TAC[SUB_LIST_APPEND_RIGHT_LEMMA] THEN DISCH_TAC THEN + + MP_TAC (SPECL [`5 * val (num_5blocks:int64):num`; + `0x0:num`; `pt_in:byte list`; `iv:int128`; `key1_lst:int128 list`; `key2_lst:int128 list`] + LENGTH_OF_AES256_XTS_ENCRYPT_TAIL) THEN + CONV_TAC NUM_REDUCE_CONV THEN REWRITE_TAC[ADD_0] THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN + + REWRITE_TAC[AES256_XTS_ENCRYPT_TAIL_WHEN_1BLOCK] THEN + SIMP_TAC[ARITH_RULE `i * 0x50 = (i * 0x5) * 0x10`; + ARITH_RULE `i * 0x5 = 0x5 * i`] + ]; + + (* Proving that reading previous bytes is the same as the spec *) + REWRITE_TAC[ARITH_RULE `i * 0x50 = 0x50 * i`; + ARITH_RULE `0x50 * i = 0x10 * 5 * i`; + ARITH_RULE `0x50 * i + 0x10 = 0x10 * 5 * i + 0x10`] THEN + REWRITE_TAC[SUB_LIST_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS] THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN + REWRITE_TAC[LENGTH_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS] + ] + ] ; ALL_TAC + ] THEN (* 2 total *) + + DISCH_TAC THEN + ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (4--5) THEN + FIRST_X_ASSUM MP_TAC THEN + COND_CASES_TAC THENL + [ (* Case: len % 0x50 = 0x30 *) + DISCH_TAC THEN + SUBGOAL_THEN `val (num_5blocks:int64) * 0x50 + 0x30 = val (len_full_blocks:int64)` ASSUME_TAC THENL + [ UNDISCH_TAC `val (word_sub + (word_sub (len_full_blocks:int64) + (word_mul (word 0x50) (num_5blocks:int64))) + (word 0x30)) = + 0x0` THEN + REWRITE_TAC [VAL_EQ_0; WORD_SUB_EQ_0] THEN + REWRITE_TAC [WORD_RULE `!x:int64. word_mul (word 0x50) x = word(val x * 0x50)`] THEN + REWRITE_TAC[GSYM VAL_EQ] THEN + SUBGOAL_THEN `val (num_5blocks:int64) * 0x50 < 2 EXP 64` MP_TAC THENL + [ UNDISCH_TAC `val (num_5blocks:int64) * 0x50 <= val (len_full_blocks:int64)` THEN + UNDISCH_TAC `val (len_full_blocks:int64) <= 2 EXP 24` THEN + ARITH_TAC; ALL_TAC] THEN + REWRITE_TAC[VAL_WORD_SUB_CASES] THEN + SIMP_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN + UNDISCH_TAC `val (num_5blocks:int64) * 0x50 <= val (len_full_blocks:int64)` THEN + NUM_REDUCE_TAC THEN ARITH_TAC; ALL_TAC] THEN + + SUBGOAL_THEN `~(val (num_5blocks:int64) * 0x50 + 0x40 = val (len_full_blocks:int64))` ASSUME_TAC THENL + [ UNDISCH_TAC `val (num_5blocks:int64) * 0x50 + 0x30 = val (len_full_blocks:int64)` THEN + ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `val (num_5blocks:int64) * 0x50 + 0x30 <= val (len:int64)` ASSUME_TAC THENL + [ UNDISCH_TAC `val (num_5blocks:int64) * 0x50 + 0x30 = val (len_full_blocks:int64)` THEN + UNDISCH_TAC `val (len_full_blocks:int64) <= val (len:int64)` THEN + ARITH_TAC; ALL_TAC] THEN + MP_TAC (SPECL [`ptxt_p:int64`; `num_5blocks:int64`; `len:int64`; `pt_in:byte list`; `s5:armstate`] READ_CT_TAIL3_LEMMA) THEN + ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN + + ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (6--97) THEN + XTSENC_TAC `Q0:(armstate,int128)component` + `val (num_5blocks:int64) * 0x50` `val (num_5blocks:int64) * 0x5` THEN + XTSENC_TAC `Q1:(armstate,int128)component` + `val (num_5blocks:int64) * 0x50 + 0x10` `val (num_5blocks:int64) * 0x5 + 0x1` THEN + XTSENC_TAC `Q24:(armstate,int128)component` + `val (num_5blocks:int64) * 0x50 + 0x20` `val (num_5blocks:int64) * 0x5 + 0x2` THEN + + (* The following lemmas are for NONSELFMODIFYING_STATE_UPDATE_TAC when store back to pt_ptr *) + RULE_ASSUM_TAC(REWRITE_RULE + [WORD_RULE `word_mul (word 0x50) num_5blocks:int64 = word(0x50 * val num_5blocks)`]) THEN + + ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (98--108) THEN + TWEAK_TAC `Q6:(armstate,int128)component` `val (num_5blocks:int64) * 0x5 + 0x3` `val (num_5blocks:int64) * 0x5 + 0x2` THEN + + ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN + REPEAT CONJ_TAC THENL + [ + REWRITE_TAC[acc_len] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; + REWRITE_TAC[acc_len] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; + REWRITE_TAC[acc_blocks] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; + REWRITE_TAC[acc_blocks] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; + REWRITE_TAC[acc_blocks] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; (* 3 total *) + + REWRITE_TAC[acc_len] THEN ASM_SIMP_TAC[LE_REFL] THEN + SUBGOAL_THEN `val ((word (0x50 * val (num_5blocks:int64) + 0x30)):int64) = + 0x50 * val num_5blocks + 0x30` ASSUME_TAC THENL + [ IMP_REWRITE_TAC[VAL_WORD; MOD_LT; DIMINDEX_64] THEN + UNDISCH_TAC `val (num_5blocks:int64) * 0x50 + 0x30 <= val (len:int64)` THEN + UNDISCH_TAC `val (len:int64) <= 0x2 EXP 0x18` THEN + ARITH_TAC; ALL_TAC] THEN + POP_ASSUM(fun th -> REWRITE_TAC[th]) THEN + + (* Remove quantifier *) + UNDISCH_TAC + `forall i. + i < 0x50 * val (num_5blocks:int64) + ==> read (memory :> bytes8 (word_add ctxt_p (word i))) s108 = + EL i (aes256_xts_encrypt pt_in (val num_5blocks * 0x50) iv key1_lst key2_lst)` THEN + MP_TAC (SPECL [`0x50 * val (num_5blocks:int64) + 0x30:num`; `ctxt_p:int64`; + `(aes256_xts_encrypt pt_in (0x50 * val (num_5blocks:int64) + 0x30) iv key1_lst key2_lst):byte list`; + `s108:armstate`] BYTE_LIST_TO_NUM_THM) THEN + ANTS_TAC THENL[ + REWRITE_TAC[ARITH_RULE `0x50 * i + 0x30 = 0x10 * (5 * i + 3)`; + LENGTH_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS] THEN + ARITH_TAC + ; ALL_TAC] THEN + DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN + + MP_TAC (SPECL [`0x50 * val (num_5blocks:int64):num`; `ctxt_p:int64`; + `(aes256_xts_encrypt pt_in (val (num_5blocks:int64) * 0x50) iv key1_lst key2_lst):byte list`; + `s108:armstate`] BYTE_LIST_TO_NUM_THM) THEN + ANTS_TAC THENL[ + REWRITE_TAC[ARITH_RULE `i * 0x50 = 0x10 * 5 * i`; + LENGTH_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS] THEN + ARITH_TAC + ; ALL_TAC] THEN + DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN + DISCH_TAC THEN + + IMP_REWRITE_TAC[ARITH_RULE `0x50 * i + 0x30 = (0x50 * i + 0x20) + 0x10`; READ_BYTES_AND_BYTE128_SPLIT] THEN + EXISTS_TAC `(aes256_xts_encrypt pt_in (0x50 * val (num_5blocks:int64) + 0x30) iv key1_lst key2_lst)` THEN + REPEAT CONJ_TAC THENL [ + REWRITE_TAC [ARITH_RULE `(0x50 * i + 0x20) + 0x10 = 0x50 * i + 0x30`]; + + MP_TAC (SPECL [`0x5 * val (num_5blocks:int64) + 0x3:num`; + `pt_in:byte list`; `iv:int128`; `key1_lst:int128 list`; + `key2_lst:int128 list`] LENGTH_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS) THEN + REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC; GSYM ADD_ASSOC] THEN + CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC THEN + ASM_REWRITE_TAC[] THEN ARITH_TAC; (* 4 total *) + (* IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES]; *) + (* + REWRITE_TAC [ARITH_RULE `(0x50 * i + 0x20) + 0x10 = 0x50 * i + 0x30`] THEN + MP_TAC (SPECL [`0x5 * val (num_5blocks:int64) + 0x3:num`; + `pt_in:byte list`; `iv:int128`; `key1_lst:int128 list`; + `key2_lst:int128 list`] LENGTH_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS) THEN + REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC; GSYM ADD_ASSOC] THEN + CONV_TAC NUM_REDUCE_CONV; (* THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN ARITH_TAC; *) + *) + + (* Establish that one xts encrypt round is the same as + selecting one block of bytes from calling the top-level function. *) + REWRITE_TAC[aes256_xts_encrypt] THEN + SIMP_TAC[ARITH_RULE `~(0x50 * i + 0x30 < 0x10)`] THEN + SUBGOAL_THEN `(0x50 * val (num_5blocks:int64) + 0x30) MOD 0x10 = 0` SUBST1_TAC THENL + [ REWRITE_TAC[ARITH_RULE `80 * i + 48 = 16 * (5 * i + 3)`] THEN + REWRITE_TAC[MOD_MULT] + ; ALL_TAC] THEN + CONV_TAC (DEPTH_CONV let_CONV) THEN + REWRITE_TAC[SUB_0; ARITH_RULE `(0x50 * i + 0x30) DIV 0x10 = 0x5 * i + 0x3`] THEN + SIMP_TAC[ARITH_RULE `~(0x5 * i + 0x3 < 0x2)`; + ARITH_RULE `(0x5 * i + 0x3) - 0x2 = 0x5 * i + 0x1`; + ARITH_RULE `(0x5 * i + 0x3) - 0x1 = 0x5 * i + 0x2`] THEN + + MP_TAC (SPECL [`0`;`5 * val (num_5blocks:int64) + 1:num`; + `pt_in:byte list`; `iv:int128`; `key1_lst:int128 list`; `key2_lst:int128 list`] + LENGTH_OF_AES256_XTS_ENCRYPT_REC) THEN + SIMP_TAC[ARITH_RULE `~(5 * i + 1 < 0)`] THEN + REWRITE_TAC[ARITH_RULE `((0x5 * i + 0x1) - 0x0 + 0x1) * 0x10 = 0x50 * i + 0x20`] THEN + IMP_REWRITE_TAC[SUB_LIST_APPEND_RIGHT_LEMMA] THEN DISCH_TAC THEN + + MP_TAC (SPECL [`5 * val (num_5blocks:int64) + 2:num`; `0x0:num`; + `pt_in:byte list`; `iv:int128`; `key1_lst:int128 list`; `key2_lst:int128 list`] + LENGTH_OF_AES256_XTS_ENCRYPT_TAIL) THEN + CONV_TAC NUM_REDUCE_CONV THEN REWRITE_TAC[ADD_0] THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN + + REWRITE_TAC[AES256_XTS_ENCRYPT_TAIL_WHEN_1BLOCK] THEN + ASM_SIMP_TAC[ARITH_RULE `(i * 0x5 + 0x2) * 0x10 = i * 0x50 + 0x20`; + ARITH_RULE `5 * i + 2 = i * 5 + 2`]; + + (* Proving that reading previous bytes is the same as the spec *) + REWRITE_TAC[ARITH_RULE `0x50 * i + 0x20 = 0x10 * (5 * i + 2)`; + ARITH_RULE `0x50 * i + 0x30 = 0x10 * (5 * i + 2) + 0x10`] THEN + REWRITE_TAC[SUB_LIST_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS] THEN + ASM_REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC] THEN CONV_TAC NUM_REDUCE_CONV (* 3 total *) + ] THEN + + REWRITE_TAC[ARITH_RULE `0x50 * i + 0x20 = (0x50 * i + 0x10) + 0x10`] THEN + (* Use SPECL to force IMP_REWRITE_TAC to apply once once *) + IMP_REWRITE_TAC[(SPECL [`ctxt_p:int64`; `(0x50 * val (num_5blocks:int64) + 0x10):num`; + `x:byte list`; `s138:armstate`] READ_BYTES_AND_BYTE128_SPLIT)] THEN + EXISTS_TAC `(aes256_xts_encrypt pt_in (0x50 * val (num_5blocks:int64) + 0x20) iv key1_lst key2_lst)` THEN + REPEAT CONJ_TAC THENL [ + MP_TAC (SPECL [`0x5 * val (num_5blocks:int64) + 0x2:num`; + `pt_in:byte list`; `iv:int128`; `key1_lst:int128 list`; + `key2_lst:int128 list`] LENGTH_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS) THEN + REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC; GSYM ADD_ASSOC] THEN + CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN ARITH_TAC; + + MP_TAC (SPECL [`0x5 * val (num_5blocks:int64) + 0x2:num`; + `pt_in:byte list`; `iv:int128`; `key1_lst:int128 list`; + `key2_lst:int128 list`] LENGTH_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS) THEN + REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC; GSYM ADD_ASSOC] THEN + CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN ARITH_TAC; + + (* Establish that one xts encrypt round is the same as + selecting one block of bytes from calling the top-level function. *) + REWRITE_TAC[aes256_xts_encrypt] THEN + SIMP_TAC[ARITH_RULE `~(0x50 * i + 0x20 < 0x10)`] THEN + SUBGOAL_THEN `(0x50 * val (num_5blocks:int64) + 0x20) MOD 0x10 = 0` SUBST1_TAC THENL + [ REWRITE_TAC[ARITH_RULE `80 * i + 32 = 16 * (5 * i + 2)`] THEN + REWRITE_TAC[MOD_MULT] + ; ALL_TAC] THEN + CONV_TAC (DEPTH_CONV let_CONV) THEN + REWRITE_TAC[SUB_0; ARITH_RULE `(0x50 * i + 0x20) DIV 0x10 = 0x5 * i + 0x2`] THEN + SIMP_TAC[ARITH_RULE `~(0x5 * i + 0x2 < 0x2)`; + ARITH_RULE `(0x5 * i + 0x2) - 0x2 = 0x5 * i`; + ARITH_RULE `(0x5 * i + 0x2) - 0x1 = 0x5 * i + 0x1`] THEN + + MP_TAC (SPECL [`0`;`5 * val (num_5blocks:int64):num`; + `pt_in:byte list`; `iv:int128`; `key1_lst:int128 list`; `key2_lst:int128 list`] + LENGTH_OF_AES256_XTS_ENCRYPT_REC) THEN + SIMP_TAC[ARITH_RULE `~(5 * i < 0)`; + ARITH_RULE `(0x5 * i - 0x0 + 0x1) * 0x10 = 0x50 * i + 0x10`] THEN + IMP_REWRITE_TAC[SUB_LIST_APPEND_RIGHT_LEMMA] THEN DISCH_TAC THEN + + MP_TAC (SPECL [`5 * val (num_5blocks:int64) + 1:num`; `0x0:num`; + `pt_in:byte list`; `iv:int128`; `key1_lst:int128 list`; `key2_lst:int128 list`] + LENGTH_OF_AES256_XTS_ENCRYPT_TAIL) THEN + CONV_TAC NUM_REDUCE_CONV THEN REWRITE_TAC[ADD_0] THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN + + REWRITE_TAC[AES256_XTS_ENCRYPT_TAIL_WHEN_1BLOCK] THEN + SIMP_TAC[ARITH_RULE `i * 0x50 + 0x10 = (i * 0x5 + 0x1) * 0x10`; + ARITH_RULE `i * 0x5 = 0x5 * i`]; + + (* Proving that reading previous bytes is the same as the spec *) + REWRITE_TAC[ARITH_RULE `0x50 * i + 0x10 = 0x10 * (5 * i + 1)`; + ARITH_RULE `0x50 * i + 0x20 = 0x10 * (5 * i + 1) + 0x10`] THEN + REWRITE_TAC[SUB_LIST_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS] THEN + ASM_REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC] THEN CONV_TAC NUM_REDUCE_CONV + ] THEN + IMP_REWRITE_TAC[(SPECL [`ctxt_p:int64`; `(0x50 * val (num_5blocks:int64)):num`; `(aes256_xts_encrypt pt_in (0x50 * val (num_5blocks:int64) + 0x10) iv key1_lst key2_lst):byte list`; `s138:armstate`] READ_BYTES_AND_BYTE128_SPLIT)] THEN @@ -3593,12 +4003,57 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( ARITH_RULE `0x50 * i + 0x10 = 0x10 * 5 * i + 0x10`] THEN REWRITE_TAC[SUB_LIST_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS] THEN IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN - REWRITE_TAC[LENGTH_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS]] + REWRITE_TAC[LENGTH_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS] ] - ; ALL_TAC - ] THEN + ] ; ALL_TAC + ] THEN (* 2 total *) DISCH_TAC THEN + ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (6--7) THEN + FIRST_X_ASSUM MP_TAC THEN + COND_CASES_TAC THENL + [ (* Case: len % 0x50 = 0x20 *) + DISCH_TAC THEN + SUBGOAL_THEN `val (num_5blocks:int64) * 0x50 + 0x20 = val (len_full_blocks:int64)` ASSUME_TAC THENL + [ UNDISCH_TAC `val (word_sub + (word_sub (len_full_blocks:int64) + (word_mul (word 0x50) (num_5blocks:int64))) + (word 0x20)) = + 0x0` THEN + REWRITE_TAC [VAL_EQ_0; WORD_SUB_EQ_0] THEN + REWRITE_TAC [WORD_RULE `!x:int64. word_mul (word 0x50) x = word(val x * 0x50)`] THEN + REWRITE_TAC[GSYM VAL_EQ] THEN + SUBGOAL_THEN `val (num_5blocks:int64) * 0x50 < 2 EXP 64` MP_TAC THENL + [ UNDISCH_TAC `val (num_5blocks:int64) * 0x50 <= val (len_full_blocks:int64)` THEN + UNDISCH_TAC `val (len_full_blocks:int64) <= 2 EXP 24` THEN + ARITH_TAC; ALL_TAC] THEN + REWRITE_TAC[VAL_WORD_SUB_CASES] THEN + SIMP_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN + UNDISCH_TAC `val (num_5blocks:int64) * 0x50 <= val (len_full_blocks:int64)` THEN + NUM_REDUCE_TAC THEN ARITH_TAC; ALL_TAC] THEN + + SUBGOAL_THEN `~(val (num_5blocks:int64) * 0x50 + 0x40 = val (len_full_blocks:int64))` ASSUME_TAC THENL + [ UNDISCH_TAC `val (num_5blocks:int64) * 0x50 + 0x20 = val (len_full_blocks:int64)` THEN + ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `~(val (num_5blocks:int64) * 0x50 + 0x30 = val (len_full_blocks:int64))` ASSUME_TAC THENL + [ UNDISCH_TAC `val (num_5blocks:int64) * 0x50 + 0x20 = val (len_full_blocks:int64)` THEN + ARITH_TAC; ALL_TAC] THEN + + SUBGOAL_THEN `val (num_5blocks:int64) * 0x50 + 0x20 <= val (len:int64)` ASSUME_TAC THENL + [ UNDISCH_TAC `val (num_5blocks:int64) * 0x50 + 0x20 = val (len_full_blocks:int64)` THEN + UNDISCH_TAC `val (len_full_blocks:int64) <= val (len:int64)` THEN + ARITH_TAC; ALL_TAC] THEN + MP_TAC (SPECL [`ptxt_p:int64`; `num_5blocks:int64`; `len:int64`; `pt_in:byte list`; `s5:armstate`] + READ_CT_TAIL2_LEMMA) THEN + ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN + + ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (8--68) THEN + XTSENC_TAC `Q0:(armstate,int128)component` + `val (num_5blocks:int64) * 0x50` `val (num_5blocks:int64) * 0x5` THEN + XTSENC_TAC `Q1:(armstate,int128)component` + `val (num_5blocks:int64) * 0x50 + 0x10` `val (num_5blocks:int64) * 0x5 + 0x1` THEN + + ] ] ] );; From 52764d72653fa515559e31e6b0d579e67cd74be8 Mon Sep 17 00:00:00 2001 From: Nevine Ebeid Date: Fri, 31 Oct 2025 10:40:23 -0400 Subject: [PATCH 080/132] Subgoal 5: case len mod 0x50 = 0x20. --- arm/proofs/aes-xts-armv8.ml | 207 ++++++++++++++++++++++++++++++++++-- 1 file changed, 196 insertions(+), 11 deletions(-) diff --git a/arm/proofs/aes-xts-armv8.ml b/arm/proofs/aes-xts-armv8.ml index 8995c18c0..9b281792f 100644 --- a/arm/proofs/aes-xts-armv8.ml +++ b/arm/proofs/aes-xts-armv8.ml @@ -3059,7 +3059,7 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( IMP_REWRITE_TAC[(ISPECL [`(aes256_xts_encrypt_tail 0x0 0x0 pt_in iv key1_lst key2_lst):byte list`; `0x10:num`] SUB_LIST_LENGTH_IMPLIES)] THEN - REWRITE_TAC[AES256_XTS_DECRYPT_TAIL_WHEN_1BLOCK] THEN + REWRITE_TAC[AES256_XTS_ENCRYPT_TAIL_WHEN_1BLOCK] THEN CONV_TAC NUM_REDUCE_CONV; (* i != 0 *) @@ -3079,7 +3079,7 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( CONV_TAC NUM_REDUCE_CONV THEN REWRITE_TAC[ADD_0] THEN DISCH_TAC THEN IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN - REWRITE_TAC[AES256_XTS_DECRYPT_TAIL_WHEN_1BLOCK] THEN + REWRITE_TAC[AES256_XTS_ENCRYPT_TAIL_WHEN_1BLOCK] THEN SIMP_TAC[ARITH_RULE `i * 0x50 = (i * 0x5) * 0x10`; ARITH_RULE `i * 0x5 = 0x5 * i`] ]; @@ -3111,9 +3111,8 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( ASM_SIMP_TAC[WORD_RULE `!a b. a + b < 2 EXP 64 ==> (word_add (word a) (word b)) = word (a + b)`] THEN REWRITE_TAC[VAL_EQ_0; WORD_SUB_EQ_0; WORD_VAL] ] - ]; + ]; (* 3 goals total from here *) - (* 3 goals total from here *) (** Subgoal 4 of main loop invariant: prove backedge is taken if i != val num_5blocks **) REPEAT STRIP_TAC THEN @@ -3123,9 +3122,8 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( SUBGOAL_THEN `~(val (word_sub (num_5blocks:int64) (word i)) = 0x0)` ASSUME_TAC THENL [ UNDISCH_TAC `i < val (num_5blocks:int64)` THEN WORD_ARITH_TAC; ALL_TAC] THEN POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th])) THEN - ENSURES_FINAL_STATE_TAC THEN ASM_SIMP_TAC[]; + ENSURES_FINAL_STATE_TAC THEN ASM_SIMP_TAC[]; (* 2 goals total from here *) - (* 2 goals total from here *) (** Subgoal 5: Prove the invariant implies post-condition Backedge instruction is executed here **) REPEAT STRIP_TAC THEN @@ -3746,7 +3744,8 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( [ UNDISCH_TAC `val (num_5blocks:int64) * 0x50 + 0x30 = val (len_full_blocks:int64)` THEN UNDISCH_TAC `val (len_full_blocks:int64) <= val (len:int64)` THEN ARITH_TAC; ALL_TAC] THEN - MP_TAC (SPECL [`ptxt_p:int64`; `num_5blocks:int64`; `len:int64`; `pt_in:byte list`; `s5:armstate`] READ_CT_TAIL3_LEMMA) THEN + MP_TAC (SPECL [`ptxt_p:int64`; `num_5blocks:int64`; `len:int64`; `pt_in:byte list`; `s5:armstate`] + READ_CT_TAIL3_LEMMA) THEN ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (6--97) THEN @@ -3872,7 +3871,7 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( REWRITE_TAC[ARITH_RULE `0x50 * i + 0x20 = (0x50 * i + 0x10) + 0x10`] THEN (* Use SPECL to force IMP_REWRITE_TAC to apply once once *) IMP_REWRITE_TAC[(SPECL [`ctxt_p:int64`; `(0x50 * val (num_5blocks:int64) + 0x10):num`; - `x:byte list`; `s138:armstate`] READ_BYTES_AND_BYTE128_SPLIT)] THEN + `x:byte list`; `s108:armstate`] READ_BYTES_AND_BYTE128_SPLIT)] THEN EXISTS_TAC `(aes256_xts_encrypt pt_in (0x50 * val (num_5blocks:int64) + 0x20) iv key1_lst key2_lst)` THEN REPEAT CONJ_TAC THENL [ MP_TAC (SPECL [`0x5 * val (num_5blocks:int64) + 0x2:num`; @@ -3929,7 +3928,7 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( IMP_REWRITE_TAC[(SPECL [`ctxt_p:int64`; `(0x50 * val (num_5blocks:int64)):num`; `(aes256_xts_encrypt pt_in (0x50 * val (num_5blocks:int64) + 0x10) iv key1_lst key2_lst):byte list`; - `s138:armstate`] READ_BYTES_AND_BYTE128_SPLIT)] THEN + `s108:armstate`] READ_BYTES_AND_BYTE128_SPLIT)] THEN EXISTS_TAC `iv:int128` THEN EXISTS_TAC `key1_lst:int128 list` THEN EXISTS_TAC `key2_lst:int128 list` THEN EXISTS_TAC `pt_in:byte list` THEN REPEAT CONJ_TAC THENL [ @@ -4043,7 +4042,7 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( [ UNDISCH_TAC `val (num_5blocks:int64) * 0x50 + 0x20 = val (len_full_blocks:int64)` THEN UNDISCH_TAC `val (len_full_blocks:int64) <= val (len:int64)` THEN ARITH_TAC; ALL_TAC] THEN - MP_TAC (SPECL [`ptxt_p:int64`; `num_5blocks:int64`; `len:int64`; `pt_in:byte list`; `s5:armstate`] + MP_TAC (SPECL [`ptxt_p:int64`; `num_5blocks:int64`; `len:int64`; `pt_in:byte list`; `s7:armstate`] READ_CT_TAIL2_LEMMA) THEN ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN @@ -4053,7 +4052,193 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( XTSENC_TAC `Q1:(armstate,int128)component` `val (num_5blocks:int64) * 0x50 + 0x10` `val (num_5blocks:int64) * 0x5 + 0x1` THEN - ] + (* The following lemmas are for NONSELFMODIFYING_STATE_UPDATE_TAC when store back to pt_ptr *) + RULE_ASSUM_TAC(REWRITE_RULE + [WORD_RULE `word_mul (word 0x50) num_5blocks:int64 = word(0x50 * val num_5blocks)`]) THEN + + ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (69--78) THEN + TWEAK_TAC `Q6:(armstate,int128)component` `val (num_5blocks:int64) * 0x5 + 0x2` `val (num_5blocks:int64) * 0x5 + 0x1` THEN + + ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN + REPEAT CONJ_TAC THENL + [ + REWRITE_TAC[acc_len] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; + REWRITE_TAC[acc_len] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; + REWRITE_TAC[acc_blocks] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; + REWRITE_TAC[acc_blocks] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; + REWRITE_TAC[acc_blocks] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; (* 3 total *) + + REWRITE_TAC[acc_len] THEN ASM_SIMP_TAC[LE_REFL] THEN + SUBGOAL_THEN `val ((word (0x50 * val (num_5blocks:int64) + 0x20)):int64) = + 0x50 * val num_5blocks + 0x20` ASSUME_TAC THENL + [ IMP_REWRITE_TAC[VAL_WORD; MOD_LT; DIMINDEX_64] THEN + UNDISCH_TAC `val (num_5blocks:int64) * 0x50 + 0x20 <= val (len:int64)` THEN + UNDISCH_TAC `val (len:int64) <= 0x2 EXP 0x18` THEN + ARITH_TAC; ALL_TAC] THEN + POP_ASSUM(fun th -> REWRITE_TAC[th]) THEN + + (* Remove quantifier *) + UNDISCH_TAC + `forall i. + i < 0x50 * val (num_5blocks:int64) + ==> read (memory :> bytes8 (word_add ctxt_p (word i))) s78 = + EL i (aes256_xts_encrypt pt_in (val num_5blocks * 0x50) iv key1_lst key2_lst)` THEN + MP_TAC (SPECL [`0x50 * val (num_5blocks:int64) + 0x20:num`; `ctxt_p:int64`; + `(aes256_xts_encrypt pt_in (0x50 * val (num_5blocks:int64) + 0x20) iv key1_lst key2_lst):byte list`; + `s78:armstate`] BYTE_LIST_TO_NUM_THM) THEN + ANTS_TAC THENL[ + REWRITE_TAC[ARITH_RULE `0x50 * i + 0x20 = 0x10 * (5 * i + 2)`; + LENGTH_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS] THEN + ARITH_TAC + ; ALL_TAC] THEN + DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN + + MP_TAC (SPECL [`0x50 * val (num_5blocks:int64):num`; `ctxt_p:int64`; + `(aes256_xts_encrypt pt_in (val (num_5blocks:int64) * 0x50) iv key1_lst key2_lst):byte list`; + `s78:armstate`] BYTE_LIST_TO_NUM_THM) THEN + ANTS_TAC THENL[ + REWRITE_TAC[ARITH_RULE `0x50 * i = i * 0x50`; + ARITH_RULE `i * 0x50 = 0x10 * 5 * i`; + LENGTH_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS] THEN + ARITH_TAC + ; ALL_TAC] THEN + DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN + DISCH_TAC THEN + + REWRITE_TAC[ARITH_RULE `0x50 * i + 0x20 = (0x50 * i + 0x10) + 0x10`] THEN + (* Use SPECL to force IMP_REWRITE_TAC to apply once once *) + IMP_REWRITE_TAC[(SPECL [`ctxt_p:int64`; `(0x50 * val (num_5blocks:int64) + 0x10):num`; + `x:byte list`; `s78:armstate`] READ_BYTES_AND_BYTE128_SPLIT)] THEN + EXISTS_TAC `(aes256_xts_encrypt pt_in (0x50 * val (num_5blocks:int64) + 0x20) iv key1_lst key2_lst)` THEN + REPEAT CONJ_TAC THENL [ + REWRITE_TAC [ARITH_RULE `(0x50 * i + 0x10) + 0x10 = 0x50 * i + 0x20`]; + + MP_TAC (SPECL [`0x5 * val (num_5blocks:int64) + 0x2:num`; + `pt_in:byte list`; `iv:int128`; `key1_lst:int128 list`; + `key2_lst:int128 list`] LENGTH_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS) THEN + REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC; GSYM ADD_ASSOC] THEN + CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN ARITH_TAC; + + (* Establish that one xts encrypt round is the same as + selecting one block of bytes from calling the top-level function. *) + REWRITE_TAC[aes256_xts_encrypt] THEN + SIMP_TAC[ARITH_RULE `~(0x50 * i + 0x20 < 0x10)`] THEN + SUBGOAL_THEN `(0x50 * val (num_5blocks:int64) + 0x20) MOD 0x10 = 0` SUBST1_TAC THENL + [ REWRITE_TAC[ARITH_RULE `80 * i + 32 = 16 * (5 * i + 2)`] THEN + REWRITE_TAC[MOD_MULT] + ; ALL_TAC] THEN + CONV_TAC (DEPTH_CONV let_CONV) THEN + REWRITE_TAC[SUB_0; ARITH_RULE `(0x50 * i + 0x20) DIV 0x10 = 0x5 * i + 0x2`] THEN + SIMP_TAC[ARITH_RULE `~(0x5 * i + 0x2 < 0x2)`; + ARITH_RULE `(0x5 * i + 0x2) - 0x2 = 0x5 * i`; + ARITH_RULE `(0x5 * i + 0x2) - 0x1 = 0x5 * i + 0x1`] THEN + + MP_TAC (SPECL [`0`;`5 * val (num_5blocks:int64):num`; + `pt_in:byte list`; `iv:int128`; `key1_lst:int128 list`; `key2_lst:int128 list`] + LENGTH_OF_AES256_XTS_ENCRYPT_REC) THEN + SIMP_TAC[ARITH_RULE `~(5 * i < 0)`; + ARITH_RULE `(0x5 * i - 0x0 + 0x1) * 0x10 = 0x50 * i + 0x10`] THEN + IMP_REWRITE_TAC[SUB_LIST_APPEND_RIGHT_LEMMA] THEN DISCH_TAC THEN + + MP_TAC (SPECL [`5 * val (num_5blocks:int64) + 1:num`; `0x0:num`; + `pt_in:byte list`; `iv:int128`; `key1_lst:int128 list`; `key2_lst:int128 list`] + LENGTH_OF_AES256_XTS_ENCRYPT_TAIL) THEN + CONV_TAC NUM_REDUCE_CONV THEN REWRITE_TAC[ADD_0] THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN + + REWRITE_TAC[AES256_XTS_ENCRYPT_TAIL_WHEN_1BLOCK] THEN + SIMP_TAC[ARITH_RULE `i * 0x50 + 0x10 = (i * 0x5 + 0x1) * 0x10`; + ARITH_RULE `i * 0x5 = 0x5 * i`]; + + (* Proving that reading previous bytes is the same as the spec *) + REWRITE_TAC[ARITH_RULE `0x50 * i + 0x10 = 0x10 * (5 * i + 1)`; + ARITH_RULE `0x50 * i + 0x20 = 0x10 * (5 * i + 1) + 0x10`] THEN + REWRITE_TAC[SUB_LIST_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS] THEN + ASM_REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC] THEN CONV_TAC NUM_REDUCE_CONV + ] THEN + + IMP_REWRITE_TAC[(SPECL [`ctxt_p:int64`; `(0x50 * val (num_5blocks:int64)):num`; + `(aes256_xts_encrypt pt_in (0x50 * val (num_5blocks:int64) + 0x10) iv key1_lst key2_lst):byte list`; + `s78:armstate`] READ_BYTES_AND_BYTE128_SPLIT)] THEN + EXISTS_TAC `iv:int128` THEN EXISTS_TAC `key1_lst:int128 list` THEN + EXISTS_TAC `key2_lst:int128 list` THEN EXISTS_TAC `pt_in:byte list` THEN + REPEAT CONJ_TAC THENL [ + MP_TAC (SPECL [`0x5 * val (num_5blocks:int64) + 0x1:num`; + `pt_in:byte list`; `iv:int128`; `key1_lst:int128 list`; + `key2_lst:int128 list`] LENGTH_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS) THEN + REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC; GSYM ADD_ASSOC] THEN + CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN ARITH_TAC; + + MP_TAC (SPECL [`0x5 * val (num_5blocks:int64) + 0x1:num`; + `pt_in:byte list`; `iv:int128`; `key1_lst:int128 list`; + `key2_lst:int128 list`] LENGTH_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS) THEN + REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC; GSYM ADD_ASSOC] THEN + CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN ARITH_TAC; + + (* Establish that one xts encrypt round is the same as + selecting one block of bytes from calling the top-level function. *) + REWRITE_TAC[aes256_xts_encrypt] THEN + SIMP_TAC[ARITH_RULE `~(0x50 * i + 0x10 < 0x10)`] THEN + SUBGOAL_THEN `(0x50 * val (num_5blocks:int64) + 0x10) MOD 0x10 = 0` SUBST1_TAC THENL + [ REWRITE_TAC[ARITH_RULE `80 * i + 16 = 16 * (5 * i + 1)`] THEN + REWRITE_TAC[MOD_MULT] + ; ALL_TAC] THEN + CONV_TAC (DEPTH_CONV let_CONV) THEN + REWRITE_TAC[SUB_0; ARITH_RULE `(0x50 * i + 0x10) DIV 0x10 = 0x5 * i + 0x1`] THEN + (* Two cases: i = 0 then execute tail branch, else execute recursion branch *) + COND_CASES_TAC THENL + [ SUBGOAL_THEN `val (num_5blocks:int64) = 0` SUBST1_TAC THENL + [ UNDISCH_TAC `5 * val (num_5blocks:int64) + 1 < 2` THEN + UNDISCH_TAC `0 < val (num_5blocks:int64)` THEN + ARITH_TAC + ; ALL_TAC] THEN CONV_TAC NUM_REDUCE_CONV THEN + + MP_TAC (SPECL [`0x0:num`; `0x0:num`; `pt_in:byte list`; `iv:int128`; `key1_lst:int128 list`; `key2_lst:int128 list`] + LENGTH_OF_AES256_XTS_ENCRYPT_TAIL) THEN + CONV_TAC NUM_REDUCE_CONV THEN REWRITE_TAC[ADD_0] THEN DISCH_TAC THEN + IMP_REWRITE_TAC[(ISPECL [`(aes256_xts_encrypt_tail 0x0 0x0 pt_in iv key1_lst key2_lst):byte list`; + `0x10:num`] SUB_LIST_LENGTH_IMPLIES)] THEN + + REWRITE_TAC[AES256_XTS_ENCRYPT_TAIL_WHEN_1BLOCK] THEN + CONV_TAC NUM_REDUCE_CONV; + + SIMP_TAC[ARITH_RULE `(0x5 * i + 0x1) - 0x2 = 0x5 * i - 0x1`; + ARITH_RULE `(0x5 * i + 0x1) - 0x1 = 0x5 * i`] THEN + + MP_TAC (SPECL [`0`;`5 * val (num_5blocks:int64) - 1:num`; + `pt_in:byte list`; `iv:int128`; `key1_lst:int128 list`; `key2_lst:int128 list`] + LENGTH_OF_AES256_XTS_ENCRYPT_REC) THEN + SUBGOAL_THEN `~(0x5 * val (num_5blocks:int64) - 0x1 < 0x0)` ASSUME_TAC THENL + [ UNDISCH_TAC `~(0x5 * val (num_5blocks:int64) + 0x1 < 0x2)` THEN ARITH_TAC; ALL_TAC ] THEN + ASM_SIMP_TAC[] THEN + IMP_REWRITE_TAC[ARITH_RULE `~(0x5 * i + 0x1 < 0x2) ==> (0x5 * i - 1 - 0x0 + 0x1) * 0x10 = 0x50 * i`] THEN + IMP_REWRITE_TAC[SUB_LIST_APPEND_RIGHT_LEMMA] THEN DISCH_TAC THEN + + MP_TAC (SPECL [`5 * val (num_5blocks:int64):num`; + `0x0:num`; `pt_in:byte list`; `iv:int128`; `key1_lst:int128 list`; `key2_lst:int128 list`] + LENGTH_OF_AES256_XTS_ENCRYPT_TAIL) THEN + CONV_TAC NUM_REDUCE_CONV THEN REWRITE_TAC[ADD_0] THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN + + REWRITE_TAC[AES256_XTS_ENCRYPT_TAIL_WHEN_1BLOCK] THEN + SIMP_TAC[ARITH_RULE `i * 0x50 = (i * 0x5) * 0x10`; + ARITH_RULE `i * 0x5 = 0x5 * i`] + ]; + + (* Proving that reading previous bytes is the same as the spec *) + REWRITE_TAC[ARITH_RULE `i * 0x50 = 0x50 * i`; + ARITH_RULE `0x50 * i = 0x10 * 5 * i`; + ARITH_RULE `0x50 * i + 0x10 = 0x10 * 5 * i + 0x10`] THEN + REWRITE_TAC[SUB_LIST_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS] THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN + REWRITE_TAC[LENGTH_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS] + ] + ] ; ALL_TAC + ] THEN (* 2 total *) + ] ] );; From b1022a7304bdac898960b233dc0687fa1076545c Mon Sep 17 00:00:00 2001 From: Nevine Ebeid Date: Fri, 31 Oct 2025 12:36:46 -0400 Subject: [PATCH 081/132] Subgoal 5: case len mod 0x50 = 0x10. --- arm/proofs/aes-xts-armv8.ml | 189 ++++++++++++++++++++++++++++++++++-- 1 file changed, 182 insertions(+), 7 deletions(-) diff --git a/arm/proofs/aes-xts-armv8.ml b/arm/proofs/aes-xts-armv8.ml index 9b281792f..d914096a8 100644 --- a/arm/proofs/aes-xts-armv8.ml +++ b/arm/proofs/aes-xts-armv8.ml @@ -2774,14 +2774,14 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN DISCH_TAC THEN - (* Prove one block equivalence and reduce proving the following: TODO: change comment to encrypt pt_in ... - `read (memory :> bytes (pt_ptr,0x50 * i + 0x50)) s188 = + (* Prove one block equivalence and reduce proving the following: + `read (memory :> bytes (ctxt_p,0x50 * i + 0x50)) s188 = num_of_bytelist - (aes256_xts_decrypt ct (0x50 * i + 0x50) iv key1 key2)` + (aes256_xts_encrypt pt_in (0x50 * i + 0x50) iv key1_lst key2_lst)` to: - `read (memory :> bytes (pt_ptr, 0x50 * i + 0x40)) s188 = + `read (memory :> bytes (ctxt_p, 0x50 * i + 0x40)) s188 = num_of_bytelist - (aes256_xts_decrypt ct (0x50 * i + 0x40) iv key1 key2)` *) + (aes256_xts_encrypt pt_in (0x50 * i + 0x40) iv key1_lst key2_lst)` *) IMP_REWRITE_TAC[ARITH_RULE `0x50 * i + 0x50 = (0x50 * i + 0x40) + 0x10`; READ_BYTES_AND_BYTE128_SPLIT] THEN EXISTS_TAC `(aes256_xts_encrypt pt_in (0x50 * i + 0x50) iv key1_lst key2_lst)` THEN REPEAT CONJ_TAC THENL [ @@ -3756,7 +3756,7 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( XTSENC_TAC `Q24:(armstate,int128)component` `val (num_5blocks:int64) * 0x50 + 0x20` `val (num_5blocks:int64) * 0x5 + 0x2` THEN - (* The following lemmas are for NONSELFMODIFYING_STATE_UPDATE_TAC when store back to pt_ptr *) + (* The following lemmas are for NONSELFMODIFYING_STATE_UPDATE_TAC when store back to ctxt_p *) RULE_ASSUM_TAC(REWRITE_RULE [WORD_RULE `word_mul (word 0x50) num_5blocks:int64 = word(0x50 * val num_5blocks)`]) THEN @@ -4052,7 +4052,7 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( XTSENC_TAC `Q1:(armstate,int128)component` `val (num_5blocks:int64) * 0x50 + 0x10` `val (num_5blocks:int64) * 0x5 + 0x1` THEN - (* The following lemmas are for NONSELFMODIFYING_STATE_UPDATE_TAC when store back to pt_ptr *) + (* The following lemmas are for NONSELFMODIFYING_STATE_UPDATE_TAC when store back to ctxt_p *) RULE_ASSUM_TAC(REWRITE_RULE [WORD_RULE `word_mul (word 0x50) num_5blocks:int64 = word(0x50 * val num_5blocks)`]) THEN @@ -4239,6 +4239,181 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( ] ; ALL_TAC ] THEN (* 2 total *) + DISCH_TAC THEN + ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (8--9) THEN + FIRST_X_ASSUM MP_TAC THEN + COND_CASES_TAC THENL + [ (* Case: len % 0x50 = 0x10 *) + DISCH_TAC THEN + + SUBGOAL_THEN `val (num_5blocks:int64) * 0x50 + 0x10 = val (len_full_blocks:int64)` ASSUME_TAC THENL + [ UNDISCH_TAC `val (word_sub + (word_sub (len_full_blocks:int64) + (word_mul (word 0x50) (num_5blocks:int64))) + (word 0x10)) = + 0x0` THEN + REWRITE_TAC [VAL_EQ_0; WORD_SUB_EQ_0] THEN + REWRITE_TAC [WORD_RULE `!x:int64. word_mul (word 0x50) x = word(val x * 0x50)`] THEN + REWRITE_TAC[GSYM VAL_EQ] THEN + SUBGOAL_THEN `val (num_5blocks:int64) * 0x50 < 2 EXP 64` MP_TAC THENL + [ UNDISCH_TAC `val (num_5blocks:int64) * 0x50 <= val (len_full_blocks:int64)` THEN + UNDISCH_TAC `val (len_full_blocks:int64) <= 2 EXP 24` THEN + ARITH_TAC; ALL_TAC] THEN + REWRITE_TAC[VAL_WORD_SUB_CASES] THEN + SIMP_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN + UNDISCH_TAC `val (num_5blocks:int64) * 0x50 <= val (len_full_blocks:int64)` THEN + NUM_REDUCE_TAC THEN ARITH_TAC; ALL_TAC] THEN + + SUBGOAL_THEN `~(val (num_5blocks:int64) * 0x50 + 0x40 = val (len_full_blocks:int64))` ASSUME_TAC THENL + [ UNDISCH_TAC `val (num_5blocks:int64) * 0x50 + 0x10 = val (len_full_blocks:int64)` THEN + ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `~(val (num_5blocks:int64) * 0x50 + 0x30 = val (len_full_blocks:int64))` ASSUME_TAC THENL + [ UNDISCH_TAC `val (num_5blocks:int64) * 0x50 + 0x10 = val (len_full_blocks:int64)` THEN + ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `~(val (num_5blocks:int64) * 0x50 + 0x20 = val (len_full_blocks:int64))` ASSUME_TAC THENL + [ UNDISCH_TAC `val (num_5blocks:int64) * 0x50 + 0x10 = val (len_full_blocks:int64)` THEN + ARITH_TAC; ALL_TAC] THEN + + SUBGOAL_THEN `val (num_5blocks:int64) * 0x50 + 0x10 <= val (len:int64)` ASSUME_TAC THENL + [ UNDISCH_TAC `val (num_5blocks:int64) * 0x50 + 0x10 = val (len_full_blocks:int64)` THEN + UNDISCH_TAC `val (len_full_blocks:int64) <= val (len:int64)` THEN + ARITH_TAC; ALL_TAC] THEN + MP_TAC (SPECL [`ptxt_p:int64`; `num_5blocks:int64`; `len:int64`; `pt_in:byte list`; `s9:armstate`] + READ_CT_TAIL1_LEMMA) THEN + ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN + + ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (10--40) THEN + XTSENC_TAC `Q0:(armstate,int128)component` + `val (num_5blocks:int64) * 0x50` `val (num_5blocks:int64) * 0x5` THEN + + (* The following lemmas are for NONSELFMODIFYING_STATE_UPDATE_TAC when store back to ctxt_p *) + RULE_ASSUM_TAC(REWRITE_RULE + [WORD_RULE `word_mul (word 0x50) num_5blocks:int64 = word(0x50 * val num_5blocks)`]) THEN + + ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (41--50) THEN + TWEAK_TAC `Q6:(armstate,int128)component` `val (num_5blocks:int64) * 0x5 + 0x1` `val (num_5blocks:int64) * 0x5` THEN + + ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN + REPEAT CONJ_TAC THENL + [ + REWRITE_TAC[acc_len] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; + REWRITE_TAC[acc_len] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; + REWRITE_TAC[acc_blocks] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; + REWRITE_TAC[acc_blocks] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; + REWRITE_TAC[acc_blocks] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; (* 3 total *) + + REWRITE_TAC[acc_len] THEN ASM_SIMP_TAC[LE_REFL] THEN + SUBGOAL_THEN `val ((word (0x50 * val (num_5blocks:int64) + 0x10)):int64) = + 0x50 * val num_5blocks + 0x10` ASSUME_TAC THENL + [ IMP_REWRITE_TAC[VAL_WORD; MOD_LT; DIMINDEX_64] THEN + UNDISCH_TAC `val (num_5blocks:int64) * 0x50 + 0x10 <= val (len:int64)` THEN + UNDISCH_TAC `val (len:int64) <= 0x2 EXP 0x18` THEN + ARITH_TAC; ALL_TAC] THEN + POP_ASSUM(fun th -> REWRITE_TAC[th]) THEN + + (* Remove quantifier *) + UNDISCH_TAC + `forall i. + i < 0x50 * val (num_5blocks:int64) + ==> read (memory :> bytes8 (word_add ctxt_p (word i))) s50 = + EL i (aes256_xts_encrypt pt_in (val num_5blocks * 0x50) iv key1_lst key2_lst)` THEN + MP_TAC (SPECL [`0x50 * val (num_5blocks:int64) + 0x10:num`; `ctxt_p:int64`; + `(aes256_xts_encrypt pt_in (0x50 * val (num_5blocks:int64) + 0x10) iv key1_lst key2_lst):byte list`; + `s50:armstate`] BYTE_LIST_TO_NUM_THM) THEN + ANTS_TAC THENL[ + REWRITE_TAC[ARITH_RULE `0x50 * i + 0x10 = 0x10 * (5 * i + 1)`; + LENGTH_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS] THEN + ARITH_TAC + ; ALL_TAC] THEN + DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN + + MP_TAC (SPECL [`0x50 * val (num_5blocks:int64):num`; `ctxt_p:int64`; + `(aes256_xts_encrypt pt_in (val (num_5blocks:int64) * 0x50) iv key1_lst key2_lst):byte list`; + `s50:armstate`] BYTE_LIST_TO_NUM_THM) THEN + ANTS_TAC THENL[ + REWRITE_TAC[ARITH_RULE `0x50 * i = i * 0x50`; + ARITH_RULE `i * 0x50 = 0x10 * 5 * i`; + LENGTH_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS] THEN + ARITH_TAC + ; ALL_TAC] THEN + DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN + DISCH_TAC THEN + + IMP_REWRITE_TAC[(SPECL [`ctxt_p:int64`; `(0x50 * val (num_5blocks:int64)):num`; + `(aes256_xts_encrypt pt_in (0x50 * val (num_5blocks:int64) + 0x10) iv key1_lst key2_lst):byte list`; + `s50:armstate`] READ_BYTES_AND_BYTE128_SPLIT)] THEN + EXISTS_TAC `iv:int128` THEN EXISTS_TAC `key1_lst:int128 list` THEN + EXISTS_TAC `key2_lst:int128 list` THEN EXISTS_TAC `pt_in:byte list` THEN + REPEAT CONJ_TAC THENL [ + REFL_TAC THEN + + MP_TAC (SPECL [`0x5 * val (num_5blocks:int64) + 0x1:num`; + `pt_in:byte list`; `iv:int128`; `key1_lst:int128 list`; + `key2_lst:int128 list`] LENGTH_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS) THEN + REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC; GSYM ADD_ASSOC] THEN + CONV_TAC NUM_REDUCE_CONV THEN ARITH_TAC; + + (* Establish that one xts encrypt round is the same as + selecting one block of bytes from calling the top-level function. *) + REWRITE_TAC[aes256_xts_encrypt] THEN + SIMP_TAC[ARITH_RULE `~(0x50 * i + 0x10 < 0x10)`] THEN + SUBGOAL_THEN `(0x50 * val (num_5blocks:int64) + 0x10) MOD 0x10 = 0` SUBST1_TAC THENL + [ REWRITE_TAC[ARITH_RULE `80 * i + 16 = 16 * (5 * i + 1)`] THEN + REWRITE_TAC[MOD_MULT] + ; ALL_TAC] THEN + CONV_TAC (DEPTH_CONV let_CONV) THEN + REWRITE_TAC[SUB_0; ARITH_RULE `(0x50 * i + 0x10) DIV 0x10 = 0x5 * i + 0x1`] THEN + (* Two cases: i = 0 then execute tail branch, else execute recursion branch *) + COND_CASES_TAC THENL + [ SUBGOAL_THEN `val (num_5blocks:int64) = 0` SUBST1_TAC THENL + [ UNDISCH_TAC `5 * val (num_5blocks:int64) + 1 < 2` THEN + UNDISCH_TAC `0 < val (num_5blocks:int64)` THEN + ARITH_TAC + ; ALL_TAC] THEN CONV_TAC NUM_REDUCE_CONV THEN + + MP_TAC (SPECL [`0x0:num`; `0x0:num`; `pt_in:byte list`; `iv:int128`; `key1_lst:int128 list`; `key2_lst:int128 list`] + LENGTH_OF_AES256_XTS_ENCRYPT_TAIL) THEN + CONV_TAC NUM_REDUCE_CONV THEN REWRITE_TAC[ADD_0] THEN DISCH_TAC THEN + IMP_REWRITE_TAC[(ISPECL [`(aes256_xts_encrypt_tail 0x0 0x0 pt_in iv key1_lst key2_lst):byte list`; + `0x10:num`] SUB_LIST_LENGTH_IMPLIES)] THEN + + REWRITE_TAC[AES256_XTS_ENCRYPT_TAIL_WHEN_1BLOCK] THEN + CONV_TAC NUM_REDUCE_CONV; + + SIMP_TAC[ARITH_RULE `(0x5 * i + 0x1) - 0x2 = 0x5 * i - 0x1`; + ARITH_RULE `(0x5 * i + 0x1) - 0x1 = 0x5 * i`] THEN + + MP_TAC (SPECL [`0`;`5 * val (num_5blocks:int64) - 1:num`; + `pt_in:byte list`; `iv:int128`; `key1_lst:int128 list`; `key2_lst:int128 list`] + LENGTH_OF_AES256_XTS_ENCRYPT_REC) THEN + SUBGOAL_THEN `~(0x5 * val (num_5blocks:int64) - 0x1 < 0x0)` ASSUME_TAC THENL + [ UNDISCH_TAC `~(0x5 * val (num_5blocks:int64) + 0x1 < 0x2)` THEN ARITH_TAC; ALL_TAC ] THEN + ASM_SIMP_TAC[] THEN + IMP_REWRITE_TAC[ARITH_RULE `~(0x5 * i + 0x1 < 0x2) ==> (0x5 * i - 1 - 0x0 + 0x1) * 0x10 = 0x50 * i`] THEN + IMP_REWRITE_TAC[SUB_LIST_APPEND_RIGHT_LEMMA] THEN DISCH_TAC THEN + + MP_TAC (SPECL [`5 * val (num_5blocks:int64):num`; + `0x0:num`; `pt_in:byte list`; `iv:int128`; `key1_lst:int128 list`; `key2_lst:int128 list`] + LENGTH_OF_AES256_XTS_ENCRYPT_TAIL) THEN + CONV_TAC NUM_REDUCE_CONV THEN REWRITE_TAC[ADD_0] THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN + + REWRITE_TAC[AES256_XTS_ENCRYPT_TAIL_WHEN_1BLOCK] THEN + SIMP_TAC[ARITH_RULE `i * 0x50 = (i * 0x5) * 0x10`; + ARITH_RULE `i * 0x5 = 0x5 * i`] + ]; + + (* Proving that reading previous bytes is the same as the spec *) + REWRITE_TAC[ARITH_RULE `i * 0x50 = 0x50 * i`; + ARITH_RULE `0x50 * i = 0x10 * 5 * i`; + ARITH_RULE `0x50 * i + 0x10 = 0x10 * 5 * i + 0x10`] THEN + REWRITE_TAC[SUB_LIST_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS] THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN + REWRITE_TAC[LENGTH_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS] + + ] + + ] ] ] );; From f58dd818a696e645d80a856b865cd9b042a2ee32 Mon Sep 17 00:00:00 2001 From: Nevine Ebeid Date: Fri, 31 Oct 2025 17:22:03 -0400 Subject: [PATCH 082/132] Subgoal 5: case len mod 0x50 = 0 (wip). --- arm/proofs/aes-xts-armv8.ml | 218 +++++++++++++++++++++++++++++++++++- 1 file changed, 216 insertions(+), 2 deletions(-) diff --git a/arm/proofs/aes-xts-armv8.ml b/arm/proofs/aes-xts-armv8.ml index d914096a8..d1fe7a3e0 100644 --- a/arm/proofs/aes-xts-armv8.ml +++ b/arm/proofs/aes-xts-armv8.ml @@ -1960,6 +1960,53 @@ let DIVISION_BY_80_LEMMA = prove( (* Finally conclude b * 0x50 = a *) ASM_ARITH_TAC );; + +let WORD_AND_MASK16 = prove( + `word_and (len:int64) (word 0xfffffffffffffff0) = word_sub len (word_and len (word 0xf))`, + BITBLAST_TAC +);; + +(* Same as Decrypt proof with a different name *) +let LEN_FULL_BLOCKS_TO_VAL = prove( + `!(len:int64). word_and len (word 0xfffffffffffffff0) = word (16 * (val len DIV 16))`, + GEN_TAC THEN + REWRITE_TAC[WORD_AND_MASK16] THEN + REWRITE_TAC[GSYM VAL_EQ] THEN + SUBGOAL_THEN `16 * val (len:int64) DIV 16 = val len - (val len MOD 16)` SUBST1_TAC THENL + [REWRITE_TAC[DIVISION_SIMP] THEN ARITH_TAC; ALL_TAC] THEN + REWRITE_TAC[ARITH_RULE `0xf = 2 EXP 4 - 1`] THEN + REWRITE_TAC[WORD_AND_MASK_WORD] THEN + CONV_TAC NUM_REDUCE_CONV THEN + + REWRITE_TAC[VAL_WORD_SUB] THEN + SUBGOAL_THEN `val (len:int64) >= val ((word (val len MOD 0x10)):int64)` ASSUME_TAC THENL [ + REWRITE_TAC[VAL_WORD; DIMINDEX_64; GE] THEN + MP_TAC (SPECL [`val (len:int64) MOD 0x10`; `0x2 EXP 0x40`] MOD_LE) THEN + ARITH_TAC; + ALL_TAC + ] THEN + REWRITE_TAC[VAL_WORD; DIMINDEX_64] THEN + + SUBGOAL_THEN `val (len:int64) MOD 0x10 < 0x2 EXP 0x40` ASSUME_TAC THENL + [ TRANS_TAC LET_TRANS `val (len:int64)` THEN + REWRITE_TAC[VAL_BOUND_64; MOD_LE]; ALL_TAC] THEN + + SUBGOAL_THEN `val (len:int64) MOD 0x10 MOD 0x2 EXP 0x40 = val len MOD 0x10` ASSUME_TAC THENL + [ MP_TAC (SPECL [`val (len:int64) MOD 0x10`; `0x2 EXP 0x40`] MOD_LT) THEN + ASM_SIMP_TAC[]; ALL_TAC] THEN + ASM_REWRITE_TAC[] THEN + + MP_TAC (SPECL [`val (len:int64)`; `0x2 EXP 0x40`; `val (len:int64) MOD 0x10`] + (ARITH_RULE `!a b c. c <= a ==> c <= b ==> a + b - c = (a - c) + b`)) THEN + ANTS_TAC THENL [ REWRITE_TAC[MOD_LE]; ALL_TAC] THEN + ANTS_TAC THENL [ ASM_ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[] THEN DISCH_TAC THEN + + MP_TAC (SPECL [`1`; `0x2 EXP 0x40`; `val (len:int64) - val len MOD 0x10`] + (CONJUNCT1 (CONJUNCT2 (CONJUNCT2 MOD_MULT_ADD)))) THEN + CONV_TAC NUM_REDUCE_CONV + );; + (* ********************************************************** *) (* Properties that we prove about the specification functions *) (* Similar to the Decrypt ones but specified for Encrypt *) @@ -4410,10 +4457,177 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( REWRITE_TAC[SUB_LIST_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS] THEN IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN REWRITE_TAC[LENGTH_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS] + ] + ] ; ALL_TAC + ] THEN (* 2 total *) - ] + (* Case: len % 0x50 = 0 *) + DISCH_TAC THEN + SUBGOAL_THEN `val (num_5blocks:int64) * 0x50 = val (len_full_blocks:int64)` ASSUME_TAC THENL + [ MATCH_MP_TAC (SPECL [`val (len_full_blocks:int64)`; `val (num_5blocks:int64)`] + DIVISION_BY_80_LEMMA) THEN + REPEAT CONJ_TAC THENL + [ + EXPAND_TAC "num_5blocks" THEN + IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN + UNDISCH_TAC `val (len_full_blocks:int64) <= 0x2 EXP 0x18` THEN + ARITH_TAC; + + EXPAND_TAC "len_full_blocks" THEN + REWRITE_TAC[LEN_FULL_BLOCKS_TO_VAL] THEN + IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT; DIVIDES_RMUL; DIVIDES_REFL] THEN + UNDISCH_TAC `val (len:int64) <= 0x2 EXP 0x18` THEN + ARITH_TAC; + + UNDISCH_TAC `~(val (word_sub + (word_sub (len_full_blocks:int64) + (word_mul (word 0x50) (num_5blocks:int64))) + (word 0x10)) = 0x0)` THEN + REWRITE_TAC[CONTRAPOS_THM] THEN + REWRITE_TAC[VAL_WORD_SUB_EQ_0; VAL_WORD_MUL; VAL_WORD; DIMINDEX_64; + ARITH_RULE `0x10 MOD 0x2 EXP 0x40 = 0x10`] THEN + REWRITE_TAC[VAL_WORD_SUB; VAL_WORD_MUL; VAL_WORD; DIMINDEX_64; + ARITH_RULE `0x50 MOD 0x2 EXP 0x40 = 0x50`] THEN + + SUBGOAL_THEN `0x50 * val (num_5blocks:int64) < 2 EXP 64` ASSUME_TAC THENL + [ UNDISCH_TAC `val (num_5blocks:int64) * 0x50 <= val (len_full_blocks:int64)` THEN + UNDISCH_TAC `val (len_full_blocks:int64) <= 2 EXP 24` THEN + ARITH_TAC; ALL_TAC] THEN + MP_TAC (SPECL [`0x50 * val (num_5blocks:int64)`; `2 EXP 64`] MOD_LT) THEN + ANTS_TAC THENL [ASM_SIMP_TAC[]; ALL_TAC] THEN + SIMP_TAC[] THEN DISCH_TAC THEN + + MP_TAC (SPECL [`val (len_full_blocks:int64)`; `0x2 EXP 0x40`; + `0x50 * val (num_5blocks:int64)`] + (ARITH_RULE `!a b c. c <= a ==> c <= b ==> a + b - c = (a - c) + b`)) THEN + ANTS_TAC THENL [ + UNDISCH_TAC `val (num_5blocks:int64) * 0x50 <= val (len_full_blocks:int64)` THEN + SIMP_TAC[MULT_SYM]; ALL_TAC] THEN + ANTS_TAC THENL [ + UNDISCH_TAC `0x50 * val (num_5blocks:int64) < 2 EXP 64` THEN + ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[] THEN DISCH_TAC THEN + + MP_TAC (SPECL [`1`; `0x2 EXP 0x40`; + `val (len_full_blocks:int64) - 0x50 * val (num_5blocks:int64)`] + (CONJUNCT1 (CONJUNCT2 (CONJUNCT2 MOD_MULT_ADD)))) THEN + REWRITE_TAC[ARITH_RULE `1 * 2 EXP 64 = 2 EXP 64`] THEN + SIMP_TAC[] THEN DISCH_TAC THEN + SIMP_TAC[MULT_SYM] THEN DISCH_TAC THEN + CONV_TAC NUM_REDUCE_CONV; + + UNDISCH_TAC `~(val (word_sub + (word_sub (len_full_blocks:int64) + (word_mul (word 0x50) (num_5blocks:int64))) + (word 0x20)) = 0x0)` THEN + REWRITE_TAC[CONTRAPOS_THM] THEN + REWRITE_TAC[VAL_WORD_SUB_EQ_0; VAL_WORD_MUL; VAL_WORD; DIMINDEX_64; + ARITH_RULE `0x10 MOD 0x2 EXP 0x40 = 0x10`] THEN + REWRITE_TAC[VAL_WORD_SUB; VAL_WORD_MUL; VAL_WORD; DIMINDEX_64; + ARITH_RULE `0x50 MOD 0x2 EXP 0x40 = 0x50`] THEN + + SUBGOAL_THEN `0x50 * val (num_5blocks:int64) < 2 EXP 64` ASSUME_TAC THENL + [ UNDISCH_TAC `val (num_5blocks:int64) * 0x50 <= val (len_full_blocks:int64)` THEN + UNDISCH_TAC `val (len_full_blocks:int64) <= 2 EXP 24` THEN + ARITH_TAC; ALL_TAC] THEN + MP_TAC (SPECL [`0x50 * val (num_5blocks:int64)`; `2 EXP 64`] MOD_LT) THEN + ANTS_TAC THENL [ASM_SIMP_TAC[]; ALL_TAC] THEN + SIMP_TAC[] THEN DISCH_TAC THEN + + MP_TAC (SPECL [`val (len_full_blocks:int64)`; `0x2 EXP 0x40`; + `0x50 * val (num_5blocks:int64)`] + (ARITH_RULE `!a b c. c <= a ==> c <= b ==> a + b - c = (a - c) + b`)) THEN + ANTS_TAC THENL [ + UNDISCH_TAC `val (num_5blocks:int64) * 0x50 <= val (len_full_blocks:int64)` THEN + SIMP_TAC[MULT_SYM]; ALL_TAC] THEN + ANTS_TAC THENL [ + UNDISCH_TAC `0x50 * val (num_5blocks:int64) < 2 EXP 64` THEN + ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[] THEN DISCH_TAC THEN + + MP_TAC (SPECL [`1`; `0x2 EXP 0x40`; + `val (len_full_blocks:int64) - 0x50 * val (num_5blocks:int64)`] + (CONJUNCT1 (CONJUNCT2 (CONJUNCT2 MOD_MULT_ADD)))) THEN + REWRITE_TAC[ARITH_RULE `1 * 2 EXP 64 = 2 EXP 64`] THEN + SIMP_TAC[] THEN DISCH_TAC THEN + SIMP_TAC[MULT_SYM] THEN DISCH_TAC THEN + CONV_TAC NUM_REDUCE_CONV; + + UNDISCH_TAC `~(val (word_sub + (word_sub (len_full_blocks:int64) + (word_mul (word 0x50) (num_5blocks:int64))) + (word 0x30)) = 0x0)` THEN + REWRITE_TAC[CONTRAPOS_THM] THEN + REWRITE_TAC[VAL_WORD_SUB_EQ_0; VAL_WORD_MUL; VAL_WORD; DIMINDEX_64; + ARITH_RULE `0x10 MOD 0x2 EXP 0x40 = 0x10`] THEN + REWRITE_TAC[VAL_WORD_SUB; VAL_WORD_MUL; VAL_WORD; DIMINDEX_64; + ARITH_RULE `0x50 MOD 0x2 EXP 0x40 = 0x50`] THEN + + SUBGOAL_THEN `0x50 * val (num_5blocks:int64) < 2 EXP 64` ASSUME_TAC THENL + [ UNDISCH_TAC `val (num_5blocks:int64) * 0x50 <= val (len_full_blocks:int64)` THEN + UNDISCH_TAC `val (len_full_blocks:int64) <= 2 EXP 24` THEN + ARITH_TAC; ALL_TAC] THEN + MP_TAC (SPECL [`0x50 * val (num_5blocks:int64)`; `2 EXP 64`] MOD_LT) THEN + ANTS_TAC THENL [ASM_SIMP_TAC[]; ALL_TAC] THEN + SIMP_TAC[] THEN DISCH_TAC THEN + + MP_TAC (SPECL [`val (len_full_blocks:int64)`; `0x2 EXP 0x40`; + `0x50 * val (num_5blocks:int64)`] + (ARITH_RULE `!a b c. c <= a ==> c <= b ==> a + b - c = (a - c) + b`)) THEN + ANTS_TAC THENL [ + UNDISCH_TAC `val (num_5blocks:int64) * 0x50 <= val (len_full_blocks:int64)` THEN + SIMP_TAC[MULT_SYM]; ALL_TAC] THEN + ANTS_TAC THENL [ + UNDISCH_TAC `0x50 * val (num_5blocks:int64) < 2 EXP 64` THEN + ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[] THEN DISCH_TAC THEN - ] + MP_TAC (SPECL [`1`; `0x2 EXP 0x40`; + `val (len_full_blocks:int64) - 0x50 * val (num_5blocks:int64)`] + (CONJUNCT1 (CONJUNCT2 (CONJUNCT2 MOD_MULT_ADD)))) THEN + REWRITE_TAC[ARITH_RULE `1 * 2 EXP 64 = 2 EXP 64`] THEN + SIMP_TAC[] THEN DISCH_TAC THEN + SIMP_TAC[MULT_SYM] THEN DISCH_TAC THEN + CONV_TAC NUM_REDUCE_CONV; + + UNDISCH_TAC `~(val (word_sub + (word_sub (len_full_blocks:int64) + (word_mul (word 0x50) (num_5blocks:int64))) + (word 0x40)) = 0x0)` THEN + REWRITE_TAC[CONTRAPOS_THM] THEN + REWRITE_TAC[VAL_WORD_SUB_EQ_0; VAL_WORD_MUL; VAL_WORD; DIMINDEX_64; + ARITH_RULE `0x10 MOD 0x2 EXP 0x40 = 0x10`] THEN + REWRITE_TAC[VAL_WORD_SUB; VAL_WORD_MUL; VAL_WORD; DIMINDEX_64; + ARITH_RULE `0x50 MOD 0x2 EXP 0x40 = 0x50`] THEN + + SUBGOAL_THEN `0x50 * val (num_5blocks:int64) < 2 EXP 64` ASSUME_TAC THENL + [ UNDISCH_TAC `val (num_5blocks:int64) * 0x50 <= val (len_full_blocks:int64)` THEN + UNDISCH_TAC `val (len_full_blocks:int64) <= 2 EXP 24` THEN + ARITH_TAC; ALL_TAC] THEN + MP_TAC (SPECL [`0x50 * val (num_5blocks:int64)`; `2 EXP 64`] MOD_LT) THEN + ANTS_TAC THENL [ASM_SIMP_TAC[]; ALL_TAC] THEN + SIMP_TAC[] THEN DISCH_TAC THEN + + MP_TAC (SPECL [`val (len_full_blocks:int64)`; `0x2 EXP 0x40`; + `0x50 * val (num_5blocks:int64)`] + (ARITH_RULE `!a b c. c <= a ==> c <= b ==> a + b - c = (a - c) + b`)) THEN + ANTS_TAC THENL [ + UNDISCH_TAC `val (num_5blocks:int64) * 0x50 <= val (len_full_blocks:int64)` THEN + SIMP_TAC[MULT_SYM]; ALL_TAC] THEN + ANTS_TAC THENL [ + UNDISCH_TAC `0x50 * val (num_5blocks:int64) < 2 EXP 64` THEN + ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[] THEN DISCH_TAC THEN + + MP_TAC (SPECL [`1`; `0x2 EXP 0x40`; + `val (len_full_blocks:int64) - 0x50 * val (num_5blocks:int64)`] + (CONJUNCT1 (CONJUNCT2 (CONJUNCT2 MOD_MULT_ADD)))) THEN + REWRITE_TAC[ARITH_RULE `1 * 2 EXP 64 = 2 EXP 64`] THEN + SIMP_TAC[] THEN DISCH_TAC THEN + SIMP_TAC[MULT_SYM] THEN DISCH_TAC THEN + CONV_TAC NUM_REDUCE_CONV; + ] ; ALL_TAC + ] THEN ] ] );; From 2613e3083c98b4bdb559c383b5ace211877a04cf Mon Sep 17 00:00:00 2001 From: Nevine Ebeid Date: Mon, 3 Nov 2025 11:56:18 -0500 Subject: [PATCH 083/132] Subgoal 5: case len mod 0x50 = 0. --- arm/proofs/aes-xts-armv8.ml | 52 ++++++++++++++++++++++++++++++++++--- 1 file changed, 48 insertions(+), 4 deletions(-) diff --git a/arm/proofs/aes-xts-armv8.ml b/arm/proofs/aes-xts-armv8.ml index d1fe7a3e0..0362f54e8 100644 --- a/arm/proofs/aes-xts-armv8.ml +++ b/arm/proofs/aes-xts-armv8.ml @@ -2709,8 +2709,7 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( XTSENC_TAC `Q26:(armstate,int128)component` `i * 0x50 + 0x40` `i * 0x5 + 0x4` THEN TWEAK_TAC `Q11:(armstate,int128)component` `i * 5 + 9` `i * 5 + 8` THEN - (* [TODO: update comment] - The following lemmas are for NONSELFMODIFYING_STATE_UPDATE_TAC when store back to pt_ptr, + (* The following lemmas are for NONSELFMODIFYING_STATE_UPDATE_TAC when store back to ctxt_p, and for the MAYCHANGE clauses *) RULE_ASSUM_TAC(REWRITE_RULE [WORD_RULE `word_mul (word 0x50) (word i):int64 = word(0x50 * i)`]) THEN @@ -4628,8 +4627,53 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( CONV_TAC NUM_REDUCE_CONV; ] ; ALL_TAC ] THEN - ] - ] + + SUBGOAL_THEN `~(val (num_5blocks:int64) * 0x50 + 0x40 = val (len_full_blocks:int64))` ASSUME_TAC THENL + [ UNDISCH_TAC `val (num_5blocks:int64) * 0x50 = val (len_full_blocks:int64)` THEN + ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `~(val (num_5blocks:int64) * 0x50 + 0x30 = val (len_full_blocks:int64))` ASSUME_TAC THENL + [ UNDISCH_TAC `val (num_5blocks:int64) * 0x50 = val (len_full_blocks:int64)` THEN + ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `~(val (num_5blocks:int64) * 0x50 + 0x20 = val (len_full_blocks:int64))` ASSUME_TAC THENL + [ UNDISCH_TAC `val (num_5blocks:int64) * 0x50 = val (len_full_blocks:int64)` THEN + ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `~(val (num_5blocks:int64) * 0x50 + 0x10 = val (len_full_blocks:int64))` ASSUME_TAC THENL + [ UNDISCH_TAC `val (num_5blocks:int64) * 0x50 = val (len_full_blocks:int64)` THEN + ARITH_TAC; ALL_TAC] THEN + + ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (10--10) THEN + ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN + REPEAT CONJ_TAC THENL [ + REWRITE_TAC[acc_len] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; + REWRITE_TAC[acc_len] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; + REWRITE_TAC[acc_blocks] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; + REWRITE_TAC[acc_blocks] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; + REWRITE_TAC[acc_blocks] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; + + REWRITE_TAC[acc_len] THEN ASM_SIMP_TAC[] THEN + + (* Rewrite to help reasoning about nonoverlapping + so that the universally quantified assumption stays. + See: https://hol-light.zulipchat.com/#narrow/channel/474190-s2n-bignum/topic/.E2.9C.94.20Symbolic.20simulation.20removed.20assumption/with/541554894 *) + SUBGOAL_THEN `val (word (0x50 * val (num_5blocks:int64)):int64) = 0x50 * val num_5blocks` MP_TAC THENL [ + IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN + UNDISCH_TAC `val (num_5blocks:int64) * 0x50 < 0x2 EXP 0x40` THEN + ARITH_TAC; ALL_TAC] THEN + DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN + + UNDISCH_TAC + `forall i. + i < 0x50 * val (num_5blocks:int64) + ==> read (memory :> bytes8 (word_add ctxt_p (word i))) s10 = + EL i + (aes256_xts_encrypt pt_in (val num_5blocks * 0x50) iv key1_lst + key2_lst)` THEN + REWRITE_TAC[ARITH_RULE `i * 0x50 = 0x50 * i`] + ] + ] (* End of loop invariant proof *) + ; ALL_TAC + ] THEN + );; From 20c362ef434e3f5d18ca3c233b5c086cf88d4d80 Mon Sep 17 00:00:00 2001 From: Nevine Ebeid Date: Tue, 4 Nov 2025 14:38:31 -0500 Subject: [PATCH 084/132] Cipher-stealing: case tail = 0. --- arm/proofs/aes-xts-armv8.ml | 677 +++++++++++++++++++++++++++++++++--- 1 file changed, 623 insertions(+), 54 deletions(-) diff --git a/arm/proofs/aes-xts-armv8.ml b/arm/proofs/aes-xts-armv8.ml index 0362f54e8..230fb1613 100644 --- a/arm/proofs/aes-xts-armv8.ml +++ b/arm/proofs/aes-xts-armv8.ml @@ -1421,6 +1421,12 @@ let LEN_FULL_BLOCKS_LO_BOUND_THM = prove( ==> ~(val len_full_blocks < 0x50)`, BITBLAST_TAC);; +let LEN_FULL_BLOCKS_LO_BOUND_1BLOCK_THM = prove( + `!(len:int64) len_full_blocks. word_and len (word 0xfffffffffffffff0) = len_full_blocks + ==> ~(val len < 0x10) + ==> ~(val len_full_blocks < 0x10)`, + BITBLAST_TAC);; + let LEN_FULL_BLOCKS_HI_BOUND_THM = prove( `!(len:int64) len_full_blocks. word_and len (word 0xfffffffffffffff0) = len_full_blocks ==> val len <= 2 EXP 24 @@ -2341,6 +2347,526 @@ let acc_blocks = new_definition else if last then val i * 0x5 else val i * 0x5 + 4`;; + +let cipher_stealing_inv = new_definition +`cipher_stealing_inv (i:num) (curr_len:num) (tail_len:num) (CC:int128) (pt:byte list): int128 = + bytes_to_int128( + APPEND (SUB_LIST (0, i) (int128_to_bytes CC)) + (APPEND (SUB_LIST (i, tail_len - i) (SUB_LIST (curr_len + 16, tail_len) pt)) + (SUB_LIST (tail_len, 16 - tail_len) (int128_to_bytes CC))))`;; + + +let CIPHER_STEALING_BYTE_EQUAL = prove( + `!(i:num) (curr_len:num) (tail_len:int64) (PP:int128) (ct:byte list). + i < val tail_len /\ val tail_len < 16 ==> + curr_len + 16 + val tail_len = LENGTH ct ==> + let InvPP = cipher_stealing_inv (i + 1) curr_len (val tail_len) PP ct + and InvPP' = cipher_stealing_inv i curr_len (val tail_len) PP ct in + (!j. 0 <= j /\ j < 16 /\ ~(j = i) ==> EL j (int128_to_bytes InvPP) = EL j (int128_to_bytes InvPP')) /\ + EL i (int128_to_bytes InvPP') = word_zx (EL (curr_len + 16 + i) ct)`, + REPEAT STRIP_TAC THEN + REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + CONJ_TAC THENL + [ + REPEAT STRIP_TAC THEN + REWRITE_TAC[cipher_stealing_inv] THEN + IMP_REWRITE_TAC[INT128_TO_BYTES_OF_BYTES_TO_INT128] THEN + REPEAT CONJ_TAC THENL + [ + (* Three cases: 0 <= j < i, i < j < val tail_len, val tail_len <= j < 16 *) + ASM_CASES_TAC `j < i` THENL + [ + SUBGOAL_THEN `j < LENGTH (SUB_LIST (0x0,i + 0x1) (int128_to_bytes PP))` ASSUME_TAC THENL + [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN + ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `j < LENGTH (SUB_LIST (0x0,i) (int128_to_bytes PP))` ASSUME_TAC THENL + [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN + ASM_ARITH_TAC ; ALL_TAC] THEN + REWRITE_TAC[EL_APPEND] THEN + ASM_SIMP_TAC[] THEN + MP_TAC (ISPECL [`j:num`; `i:num`; `(int128_to_bytes PP):byte list`] EL_SUB_LIST) THEN + ANTS_TAC THENL + [ REWRITE_TAC[LENGTH_OF_INT128_TO_BYTES] THEN + ASM_ARITH_TAC; ALL_TAC ] THEN + MP_TAC (ISPECL [`j:num`; `(i + 1):num`; `(int128_to_bytes PP):byte list`] EL_SUB_LIST) THEN + ANTS_TAC THENL + [ REWRITE_TAC[LENGTH_OF_INT128_TO_BYTES] THEN + ASM_ARITH_TAC; ALL_TAC ] THEN + SIMP_TAC[]; ALL_TAC + ] THEN + ASM_CASES_TAC `j < val (tail_len:int64)` THENL + [ + SUBGOAL_THEN `j > i` ASSUME_TAC THENL[ASM_ARITH_TAC; ALL_TAC] THEN + REWRITE_TAC[EL_APPEND] THEN + SUBGOAL_THEN `LENGTH (SUB_LIST (0x0,i + 0x1) (int128_to_bytes PP)) = i + 1` SUBST1_TAC THENL + [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN + ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `LENGTH (SUB_LIST (0x0,i) (int128_to_bytes PP)) = i` SUBST1_TAC THENL + [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN + ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `LENGTH (SUB_LIST (i + 0x1,val (tail_len:int64) - (i + 0x1)) + (SUB_LIST (curr_len + 0x10,val tail_len) (ct:byte list))) + = val tail_len - (i + 1)` SUBST1_TAC THENL + [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN + ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `LENGTH (SUB_LIST (i,val (tail_len:int64) - i) + (SUB_LIST (curr_len + 0x10,val tail_len) (ct:byte list))) + = val tail_len - i` SUBST1_TAC THENL + [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN + ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `~(j < i)` ASSUME_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `~(j < i + 1)` ASSUME_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `j - i < val (tail_len:int64) - i` ASSUME_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `j - (i + 1) < val (tail_len:int64) - (i + 1)` ASSUME_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[] THEN + MP_TAC (ISPECL [`(j - i):num`; `i:num`; + `(SUB_LIST (curr_len + 16,val (tail_len:int64)) (ct:byte list)):byte list`; + `(val (tail_len:int64) - i):num`] EL_SUB_LIST_SHIFT) THEN + ASM_SIMP_TAC[] THEN + ANTS_TAC THENL [ REWRITE_TAC[LENGTH_SUB_LIST] THEN ASM_ARITH_TAC; ALL_TAC] THEN + IMP_REWRITE_TAC[ARITH_RULE `!i j. j > i ==> j - i - 1 = j - (i + 1)`] THEN + ASM_ARITH_TAC; ALL_TAC + ] THEN + (* j >= val tail_len *) + REWRITE_TAC[EL_APPEND] THEN + SUBGOAL_THEN `LENGTH (SUB_LIST (0x0,i + 0x1) (int128_to_bytes PP)) = i + 1` SUBST1_TAC THENL + [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN + ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `LENGTH (SUB_LIST (0x0,i) (int128_to_bytes PP)) = i` SUBST1_TAC THENL + [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN + ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `LENGTH (SUB_LIST (i + 0x1,val (tail_len:int64) - (i + 0x1)) + (SUB_LIST (curr_len + 0x10,val tail_len) (ct:byte list))) + = val tail_len - (i + 1)` SUBST1_TAC THENL + [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN + ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `LENGTH (SUB_LIST (i,val (tail_len:int64) - i) + (SUB_LIST (curr_len + 0x10,val tail_len) (ct:byte list))) + = val tail_len - i` SUBST1_TAC THENL + [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN + ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `~(j < i)` ASSUME_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `~(j < i + 1)` ASSUME_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `~(j - i < val (tail_len:int64) - i)` ASSUME_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `~(j - (i + 1) < val (tail_len:int64) - (i + 1))` ASSUME_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[] THEN + AP_THM_TAC THEN AP_TERM_TAC THEN + ASM_ARITH_TAC; + + REWRITE_TAC[LENGTH_APPEND] THEN + REWRITE_TAC[LENGTH_SUB_LIST] THEN + REWRITE_TAC[LENGTH_OF_INT128_TO_BYTES] THEN + CONV_TAC NUM_REDUCE_CONV THEN + IMP_REWRITE_TAC[ARITH_RULE `i < 16 ==> MIN i 16 = i`] THEN + SUBGOAL_THEN `LENGTH (ct:byte list) - (curr_len + 16) = val (tail_len:int64)` SUBST1_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC ] THEN + REWRITE_TAC[ARITH_RULE `!x. MIN x x = x`] THEN + ASM_ARITH_TAC; + + REWRITE_TAC[LENGTH_APPEND] THEN + REWRITE_TAC[LENGTH_SUB_LIST] THEN + REWRITE_TAC[LENGTH_OF_INT128_TO_BYTES] THEN + CONV_TAC NUM_REDUCE_CONV THEN + IMP_REWRITE_TAC[ARITH_RULE `i < 16 ==> MIN (i + 1) 16 = i + 1`] THEN + SUBGOAL_THEN `LENGTH (ct:byte list) - (curr_len + 16) = val (tail_len:int64)` SUBST1_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC ] THEN + REWRITE_TAC[ARITH_RULE `!x. MIN x x = x`] THEN + ASM_ARITH_TAC + ] ; ALL_TAC + ] THEN + + REWRITE_TAC[cipher_stealing_inv] THEN + IMP_REWRITE_TAC[INT128_TO_BYTES_OF_BYTES_TO_INT128] THEN + CONJ_TAC THENL [ + REWRITE_TAC[EL_APPEND] THEN + SUBGOAL_THEN `LENGTH (SUB_LIST (0x0,i) (int128_to_bytes PP)) = i` SUBST1_TAC THENL + [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN + ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `LENGTH (SUB_LIST (i,val (tail_len:int64) - i) + (SUB_LIST (curr_len + 0x10,val tail_len) (ct:byte list))) + = val tail_len - i` SUBST1_TAC THENL + [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN + ASM_ARITH_TAC; ALL_TAC] THEN + SIMP_TAC[ARITH_RULE `~(i < i)`; SUB_REFL] THEN + SUBGOAL_THEN `0 < val (tail_len:int64) - i` ASSUME_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[] THEN + MP_TAC (ISPECL [`curr_len + 0x10:num`; `i:num`; `ct:byte list`; + `val (tail_len:int64) - i:num`; `val (tail_len:int64)`] SUB_LIST_MIN_GENERAL) THEN + REWRITE_TAC[ARITH_RULE `!a. MIN a a = a`; GSYM ADD_ASSOC] THEN + DISCH_THEN (fun th -> (REWRITE_TAC [th])) THEN + REWRITE_TAC[WORD_ZX_TRIVIAL; EL] THEN + MATCH_MP_TAC HD_SUB_LIST_CONS_GENERAL THEN + ASM_ARITH_TAC; ALL_TAC] THEN + REWRITE_TAC[LENGTH_APPEND] THEN + REWRITE_TAC[LENGTH_SUB_LIST] THEN + REWRITE_TAC[LENGTH_OF_INT128_TO_BYTES] THEN + CONV_TAC NUM_REDUCE_CONV THEN + ASM_ARITH_TAC +);; + +let CIPHER_STEALING_INV_SELECT = prove( + `!(i:num) (curr_len:num) (tail_len:int64) (PP:int128) (ct:byte list). + i < val tail_len ==> val tail_len < 16 ==> + curr_len + 16 + (val tail_len) = LENGTH ct ==> + EL i (int128_to_bytes (cipher_stealing_inv (i + 1) curr_len (val tail_len) PP ct)) = + EL i (int128_to_bytes PP)`, + REPEAT STRIP_TAC THEN + REWRITE_TAC[cipher_stealing_inv] THEN + IMP_REWRITE_TAC[INT128_TO_BYTES_OF_BYTES_TO_INT128] THEN + CONJ_TAC THENL [ + SUBGOAL_THEN `LENGTH (SUB_LIST (0x0,i + 1) (int128_to_bytes PP)) <= i + 1` ASSUME_TAC THENL + [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN + ARITH_TAC; ALL_TAC] THEN + REWRITE_TAC[EL_APPEND] THEN + SUBGOAL_THEN `i < LENGTH (SUB_LIST (0x0,i + 0x1) (int128_to_bytes PP))` ASSUME_TAC THENL + [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN + ASM_ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[] THEN + MATCH_MP_TAC EL_SUB_LIST THEN + REWRITE_TAC[LENGTH_OF_INT128_TO_BYTES] THEN + ASM_ARITH_TAC; ALL_TAC + ] THEN + + REWRITE_TAC[LENGTH_APPEND] THEN + REWRITE_TAC[LENGTH_SUB_LIST] THEN + REWRITE_TAC[LENGTH_OF_INT128_TO_BYTES] THEN + CONV_TAC NUM_REDUCE_CONV THEN + IMP_REWRITE_TAC[ARITH_RULE `i < 16 ==> MIN (i + 1) 16 = i + 1`] THEN + SUBGOAL_THEN `LENGTH (ct:byte list) - (curr_len + 16) = val (tail_len:int64)` SUBST1_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC ] THEN + REWRITE_TAC[ARITH_RULE `!x. MIN x x = x`] THEN + ASM_ARITH_TAC +);; + +let CIPHER_STEALING_INV_SIMP_TAC i = + ( FIRST_ASSUM (fun th -> MATCH_MP_TAC(SPEC i th)) THEN CONV_TAC NUM_REDUCE_CONV) ORELSE + ( ASM_REWRITE_TAC[] THEN + REWRITE_TAC[WORD_RULE `!a b. word_add ((word a):int64) (word b) = word (a + b)`] THEN + REWRITE_TAC[GSYM ADD_ASSOC] THEN + CONV_TAC NUM_REDUCE_CONV THEN + IMP_REWRITE_TAC[WORD_ZX_ZX; WORD_ZX_TRIVIAL] THEN + REWRITE_TAC[DIMINDEX_8; DIMINDEX_32; DIMINDEX_64] THEN + IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN + ASM_ARITH_TAC);; + +let TAIL_SWAP_CASE_TAC case = + let c_tm = `case:num` in + let v_tm = `v:num` in + let v = rand (concl (NUM_RED_CONV (subst [case,c_tm] `0x10 + case`))) in + let r1 = subst [case,c_tm; v,v_tm] `curr_len + 0x10 + case = curr_len + v` in + let t1 = subst [case,c_tm] `(cipher_stealing_inv case curr_len (val (tail_len:int64)) PP ct):int128` in + POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th]) THEN REWRITE_TAC[th]) THEN + (* Simplify so that symbolic execution could match up, but couldn't use + CONV_TAC NUM_REDUCE_CONV because of non-overlapping *) + RULE_ASSUM_TAC(REWRITE_RULE[ARITH_RULE r1]) THEN + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (1--5) THEN + RULE_ASSUM_TAC(REWRITE_RULE[GSYM ADD_ASSOC]) THEN + RULE_ASSUM_TAC (CONV_RULE NUM_REDUCE_CONV) THEN + ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN + REPEAT CONJ_TAC THENL + [ + REWRITE_TAC[ + WORD_RULE `!(a:int64) b c. word_add (word_add a b) c = word_add a (word_add b c)`; + WORD_RULE `!a b. word_add ((word a):int64) (word b) = word (a + b)`]; + + MATCH_MP_TAC (snd (EQ_IMP_RULE (SPECL [`(word_add pt_ptr (word curr_len)):int64`; + `s5:armstate`; t1] BREAK_ONE_BLOCK_INTO_BYTES))) THEN + REWRITE_TAC[ + WORD_RULE `!(a:int64) b c. word_add (word_add a b) c = word_add a (word_add b c)`; + WORD_RULE `!a b. word_add ((word a):int64) (word b) = word (a + b)`] THEN + ASM_REWRITE_TAC[] THEN + CONV_TAC NUM_REDUCE_CONV THEN + + MP_TAC (SPECL [case; `curr_len:num`; `tail_len:int64`; `PP:int128`; `ct:byte list`] + CIPHER_STEALING_BYTE_EQUAL) THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + ANTS_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN + ANTS_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN + STRIP_TAC THEN + + MAP_EVERY (fun i -> CONJ_TAC THENL + [CIPHER_STEALING_INV_SIMP_TAC (mk_numeral (num i)); ALL_TAC]) + (0--0xe) THEN + CIPHER_STEALING_INV_SIMP_TAC `0xf:num`; + + MP_TAC (SPECL [`pt_ptr:int64`; case; `val (tail_len:int64)`; + `curr_len:num`; `(int128_to_bytes PP):byte list`; `s5:armstate`] + BYTE_LIST_AT_SPLIT_BACKWARDS) THEN + REWRITE_TAC[LENGTH_OF_INT128_TO_BYTES] THEN + CONV_TAC NUM_REDUCE_CONV THEN + ASM_SIMP_TAC[] THEN + ANTS_TAC THENL + [ IMP_REWRITE_TAC[WORD_ZX_ZX] THEN + REWRITE_TAC[DIMINDEX_8; DIMINDEX_32; DIMINDEX_64] THEN + MP_TAC (SPECL [case; `curr_len:num`; `tail_len:int64`; `PP:int128`; `ct:byte list`] + CIPHER_STEALING_INV_SELECT) THEN + CONV_TAC NUM_REDUCE_CONV THEN + ASM_SIMP_TAC[] + ; ALL_TAC ] THEN + MESON_TAC[]; + + WORD_ARITH_TAC; + WORD_ARITH_TAC +];; + +let TAIL_SWAP_ASM_CASES_TAC case = + let c_tm = `case:num` in + let asm_case = subst [case, c_tm] `(i:num) = case` in + ASM_CASES_TAC asm_case THENL [ TAIL_SWAP_CASE_TAC case; ALL_TAC] THEN + MP_TAC (SPECL [case; `i:num`] LE_LT) THEN + ASM_SIMP_TAC[] THEN + DISCH_TAC THEN + MP_TAC (SPECL [case; `i:num`] LE_SUC_LT) THEN + ASM_SIMP_TAC[] THEN + CONV_TAC NUM_REDUCE_CONV THEN + ASM_SIMP_TAC[] THEN + DISCH_TAC;; + + +let BREAK_DATA_INTO_PARTS = prove( + `!curr_len (tail_len:int64) (pt_ptr:int64) (s:armstate). + ((curr_len + 0x10 + val tail_len <= LENGTH bl) /\ + (forall i. i < curr_len + ==> read (memory :> bytes8 (word_add pt_ptr (word i))) s = EL i bl) /\ + (forall i. i < 16 + ==> read (memory :> bytes8 (word_add (word_add pt_ptr (word curr_len)) (word i))) s = + EL i (SUB_LIST (curr_len, 16 + val tail_len) bl)) /\ + (forall i. i < val tail_len + ==> read (memory :> bytes8 + (word_add (word_add pt_ptr (word (curr_len + 0x10))) (word i))) s = + EL i (SUB_LIST (curr_len + 16, val tail_len) bl))) ==> + forall i. + i < curr_len + 0x10 + val tail_len + ==> read (memory :> bytes8 (word_add pt_ptr (word i))) s = EL i bl`, + REPEAT GEN_TAC THEN + DISCH_THEN (CONJUNCTS_THEN2 (LABEL_TAC "H") + (CONJUNCTS_THEN2 (LABEL_TAC "H1") + (CONJUNCTS_THEN2 (LABEL_TAC "H2") (LABEL_TAC "H3")))) THEN + REPEAT STRIP_TAC THEN + + ASM_CASES_TAC `i < curr_len` THENL + [ + FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[]; + ALL_TAC + ] THEN + + ASM_CASES_TAC `i < curr_len + 16` THENL + [ + USE_THEN "H2" (fun th -> MP_TAC (SPEC `i - curr_len` th)) THEN + REMOVE_THEN "H2" (K ALL_TAC) THEN + SUBGOAL_THEN `(word_add (word_add (pt_ptr:int64) (word curr_len)) (word (i - curr_len))) + = (word_add pt_ptr (word i))` ASSUME_TAC THENL + [ REWRITE_TAC[WORD_RULE `word_add (word_add a (word b)) (word c) = word_add a (word (b + c))`] THEN + AP_TERM_TAC THEN AP_TERM_TAC THEN + ASM_ARITH_TAC; ALL_TAC] THEN + ASM_REWRITE_TAC[] THEN + ANTS_TAC THENL[ASM_ARITH_TAC; ALL_TAC] THEN + SIMP_TAC[] THEN DISCH_TAC THEN + IMP_REWRITE_TAC[EL_SUB_LIST_GENERAL] THEN + ASM_ARITH_TAC; + ALL_TAC + ] THEN + + ASM_CASES_TAC `i < curr_len + 16 + val (tail_len:int64)` THENL + [ + USE_THEN "H3" (fun th -> MP_TAC (SPEC `i - curr_len - 16` th)) THEN + REMOVE_THEN "H3" (K ALL_TAC) THEN + SUBGOAL_THEN `(word_add (word_add (pt_ptr:int64) (word (curr_len + 0x10))) + (word (i - curr_len - 0x10))) = (word_add pt_ptr (word i))` ASSUME_TAC THENL + [ REWRITE_TAC[WORD_RULE `word_add (word_add a (word b)) (word c) = word_add a (word (b + c))`] THEN + AP_TERM_TAC THEN AP_TERM_TAC THEN + ASM_ARITH_TAC; ALL_TAC] THEN + ASM_REWRITE_TAC[] THEN + ANTS_TAC THENL[ASM_ARITH_TAC; ALL_TAC] THEN + SIMP_TAC[] THEN DISCH_TAC THEN + REWRITE_TAC[ARITH_RULE `i - curr_len - 16 = i - (curr_len + 16)`] THEN + IMP_REWRITE_TAC[EL_SUB_LIST_GENERAL] THEN + ASM_ARITH_TAC; + ALL_TAC + ] THEN + + ASM_ARITH_TAC +);; + +(* ************************************** *) +(* Assembly proofs *) + +(* Proof: Cipher stealing *) +let CIPHER_STEALING_CORRECT = time prove( + `!ptxt_p ctxt_p len key1_p + pt_in iv tail_len len_full_blocks num_5_blocks + k1_0 k1_1 k1_2 k1_3 k1_4 k1_5 k1_6 k1_7 k1_8 k1_9 k1_10 k1_11 k1_12 k1_13 k1_14 + pc. + PAIRWISE nonoverlapping + [(word pc, LENGTH aes256_xts_encrypt_mc); + (ptxt_p, val len); + (ctxt_p, val len); + (key1_p, 244)] /\ + val len >= 16 /\ val len <= 2 EXP 24 /\ LENGTH pt_in = val len /\ + LENGTH pt_in = val len /\ + word_and len (word 0xfffffffffffffff0) = len_full_blocks /\ + word_and len (word 0xf) = tail_len /\ + word (val len_full_blocks DIV 0x50) = num_5blocks /\ + word_add tail_len len_full_blocks = len /\ + [k1_0; k1_1; k1_2; k1_3; k1_4; k1_5; k1_6; k1_7; k1_8; k1_9; k1_10; + k1_11; k1_12; k1_13; k1_14] = key1_lst + ==> ensures arm + (\s. aligned_bytes_loaded s (word pc) aes256_xts_encrypt_mc /\ + read PC s = word (pc + 0x9e0) /\ + read X0 s = word_add ptxt_p (word (acc_len num_5blocks len_full_blocks)) /\ + read X1 s = word_add ctxt_p (word (acc_len num_5blocks len_full_blocks)) /\ + // read X3 s = key1_p /\ + read X21 s = tail_len /\ + read Q6 s = calculate_tweak (acc_blocks num_5blocks len_full_blocks true) iv key2_lst /\ + read X19 s = word 0x87 /\ + read Q16 s = k1_0 /\ read Q17 s = k1_1 /\ read Q12 s = k1_2 /\ read Q13 s = k1_3 /\ + read Q14 s = k1_4 /\ read Q15 s = k1_5 /\ read Q4 s = k1_6 /\ read Q5 s = k1_7 /\ + read Q18 s = k1_8 /\ read Q19 s = k1_9 /\ read Q20 s = k1_10 /\ read Q21 s = k1_11 /\ + read Q22 s = k1_12 /\ read Q23 s = k1_13 /\ read Q7 s = k1_14 /\ byte_list_at pt_in ptxt_p len s /\ + byte_list_at pt_in ptxt_p len s /\ + byte_list_at (aes256_xts_encrypt pt_in (acc_len num_5blocks len_full_blocks) iv key1_lst key2_lst) + ctxt_p (word (acc_len num_5blocks len_full_blocks)) s) + (\s. + read PC s = word (pc + LENGTH aes256_xts_encrypt_mc - 8*4) /\ + byte_list_at (aes256_xts_encrypt pt_in (val len) iv key1_lst key2_lst) ctxt_p len s ) + ( MAYCHANGE [PC; X0; X1; X2; X4; X6; X7; X8; X9; X10; X11; X19; X20; X21; X22] ,, + MAYCHANGE [Q0; Q1; Q4; Q5; Q6; Q7; Q8; Q9; Q10; Q11; Q12; Q13; Q14; Q15; Q16; Q17; + Q18; Q19; Q20; Q21; Q22; Q23; Q24; Q25; Q26] ,, + MAYCHANGE [NF; ZF; CF; VF] ,, + MAYCHANGE [events] ,, + MAYCHANGE [memory :> bytes (ctxt_p,val len)]) + `, + REWRITE_TAC [(REWRITE_CONV [aes256_xts_encrypt_mc] THENC LENGTH_CONV) `LENGTH aes256_xts_encrypt_mc`] THEN + REWRITE_TAC[byte_list_at; NONOVERLAPPING_CLAUSES; PAIRWISE; ALL] THEN + REPEAT STRIP_TAC THEN + + (* Prove the bounds on len_full_blocks, num_5blocks and len and their relationships *) + SUBGOAL_THEN `~(val (len_full_blocks:int64) < 0x10)` ASSUME_TAC THENL + [ SUBGOAL_THEN `~(val (len:int64) < 0x10)` MP_TAC THENL + [ASM_ARITH_TAC; ALL_TAC] THEN + UNDISCH_TAC `word_and len (word 0xfffffffffffffff0) = (len_full_blocks:int64)` THEN + MP_TAC (SPECL [`len:int64`; `len_full_blocks:int64`] LEN_FULL_BLOCKS_LO_BOUND_1BLOCK_THM) THEN + SIMP_TAC[]; ALL_TAC] THEN + + SUBGOAL_THEN `val (len_full_blocks:int64) <= 0x2 EXP 24` ASSUME_TAC THENL + [ UNDISCH_TAC `val (len:int64) <= 0x2 EXP 24` THEN + UNDISCH_TAC `word_and len (word 0xfffffffffffffff0) = (len_full_blocks:int64)` THEN + MP_TAC (SPECL [`len:int64`; `len_full_blocks:int64`] LEN_FULL_BLOCKS_HI_BOUND_THM) THEN + SIMP_TAC[]; ALL_TAC] THEN + (* + SUBGOAL_THEN `~(val (len_full_blocks:int64) < 0)` ASSUME_TAC THENL + [ UNDISCH_TAC `~(val (len_full_blocks:int64) < 0x10)` THEN + *) + + SUBGOAL_THEN `val (tail_len:int64) < 16` ASSUME_TAC THENL + [ EXPAND_TAC "tail_len" THEN + REWRITE_TAC[ARITH_RULE `0xf = 2 EXP 4 - 1`] THEN + REWRITE_TAC[VAL_WORD_AND_MASK_WORD] THEN + CONV_TAC NUM_REDUCE_CONV THEN + SIMP_TAC[MOD_LT_EQ] THEN + CONV_TAC NUM_REDUCE_CONV + ; ALL_TAC] THEN + + (* relationship between variables *) + SUBGOAL_THEN `val (len_full_blocks:int64) <= val (len:int64)` ASSUME_TAC THENL + [ EXPAND_TAC "len_full_blocks" THEN SIMP_TAC[LEN_FULL_BLOCKS_LT_LEN_THM]; ALL_TAC] THEN + + SUBGOAL_THEN `val (num_5blocks:int64) * 0x50 <= val (len_full_blocks:int64)` ASSUME_TAC THENL + [ EXPAND_TAC "num_5blocks" THEN + REWRITE_TAC [VAL_WORD; DIMINDEX_64] THEN + UNDISCH_TAC `val (len_full_blocks:int64) <= 0x2 EXP 0x18` THEN + ARITH_TAC; ALL_TAC] THEN + + (* Prove more properties about len_full_blocks and num_5blocks *) + SUBGOAL_THEN `val (len_full_blocks:int64) DIV 0x50 = val (num_5blocks:int64)` ASSUME_TAC THENL + [ EXPAND_TAC "num_5blocks" THEN + IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN + UNDISCH_TAC `val (len_full_blocks:int64) <= 0x2 EXP 0x18` THEN + ARITH_TAC; ALL_TAC] THEN + + SUBGOAL_THEN `0x10 divides val (len_full_blocks:int64)` ASSUME_TAC THENL + [ EXPAND_TAC "len_full_blocks" THEN + REWRITE_TAC[LEN_FULL_BLOCKS_TO_VAL] THEN + IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT; DIVIDES_RMUL; DIVIDES_REFL] THEN + ASM_ARITH_TAC; ALL_TAC] THEN + + (* If no tail, execute to the end *) + ASM_CASES_TAC `val (tail_len:int64) = 0` THENL + [ + ENSURES_INIT_TAC "s0" THEN + ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (1--2) THEN (* tst x21, #0xf; b.eq .Lxts_enc_abort *) + (* Discharge if condition *) + SUBGOAL_THEN `val (word_and (tail_len:int64) (word 0xf)) = 0x0` MP_TAC THENL + [ UNDISCH_TAC `val (tail_len:int64) = 0x0` THEN BITBLAST_TAC; ALL_TAC] THEN + ASM_REWRITE_TAC[] THEN DISCH_TAC THEN + POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th])) THEN + + ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN + CONV_TAC NUM_REDUCE_CONV THEN + + SUBGOAL_THEN `val (word (acc_len (num_5blocks:int64) (len_full_blocks:int64)):int64) = + acc_len num_5blocks len_full_blocks` ASSUME_TAC THENL + [ IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN + MP_TAC (SPECL [`num_5blocks:int64`; `len_full_blocks:int64`; `2 EXP 64`] + BOUND_OF_ACC_LEN) THEN + ANTS_TAC THENL [ ASM_ARITH_TAC; ALL_TAC] THEN + ANTS_TAC THENL [ ASM_SIMP_TAC[]; ALL_TAC] THEN + ANTS_TAC THENL [ ASM_SIMP_TAC[]; ALL_TAC] THEN + ANTS_TAC THENL [ ASM_ARITH_TAC; ALL_TAC] THEN + SIMP_TAC[]; ALL_TAC] THEN + POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th])) THEN + + (* Prove that acc_len is equal to total len because there is no tail *) + SUBGOAL_THEN `val (len:int64) = + acc_len (num_5blocks:int64) (len_full_blocks:int64)` SUBST1_TAC THENL + [ SUBGOAL_THEN `len = (len_full_blocks:int64)` SUBST1_TAC THENL + [ EXPAND_TAC "len" THEN + SUBGOAL_THEN `tail_len:int64 = word 0` ASSUME_TAC THENL + [ REWRITE_TAC[GSYM VAL_EQ_0] THEN ASM_REWRITE_TAC[]; ALL_TAC] THEN + REWRITE_TAC[ASSUME `tail_len:int64 = word 0`; WORD_ADD_0] + ; ALL_TAC] THEN + REWRITE_TAC[acc_len] THEN + REPEAT_N 4 (COND_CASES_TAC THENL[ASM_ARITH_TAC; ALL_TAC]) THEN + + CONV_TAC SYM_CONV THEN + REWRITE_TAC[ARITH_RULE `!a. 0x50 * a = a * 0x50`] THEN + MATCH_MP_TAC (SPECL [`val (len_full_blocks:int64)`; `val (num_5blocks:int64)`] DIVISION_BY_80_LEMMA) THEN + REPEAT CONJ_TAC THENL + [ + ASM_SIMP_TAC[]; + ASM_SIMP_TAC[]; + + UNDISCH_TAC `~(val (num_5blocks:int64) * 0x50 + 0x10 = val (len_full_blocks:int64))` THEN + ARITH_TAC; + + UNDISCH_TAC `~(val (num_5blocks:int64) * 0x50 + 0x20 = val (len_full_blocks:int64))` THEN + ARITH_TAC; + + UNDISCH_TAC `~(val (num_5blocks:int64) * 0x50 + 0x30 = val (len_full_blocks:int64))` THEN + ARITH_TAC; + + UNDISCH_TAC `~(val (num_5blocks:int64) * 0x50 + 0x40 = val (len_full_blocks:int64))` THEN + ARITH_TAC] + ; ALL_TAC] THEN + ASM_SIMP_TAC[] + ; ALL_TAC + ] THEN + + ] + + +);; + (* void aes_hw_xts_encrypt(const uint8_t *in, uint8_t *out, size_t length, const AES_KEY *key1, const AES_KEY *key2, @@ -4678,58 +5204,101 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( (* -`MAYCHANGE [X9; X10; X11; X22] ,, - MAYCHANGE [Q0; Q1; Q24; Q25; Q6] ,, - (if val num_5blocks * 0x50 + 0x40 = val len_full_blocks - then MAYCHANGE - [memory :> bytes128 (word_add ctxt_p (word (0x50 * val num_5blocks))); - memory :> - bytes128 (word_add ctxt_p (word (0x50 * val num_5blocks + 0x10))); - memory :> - bytes128 (word_add ctxt_p (word (0x50 * val num_5blocks + 0x20))); - memory :> - bytes128 (word_add ctxt_p (word (0x50 * val num_5blocks + 0x30)))] - else if val num_5blocks * 0x50 + 0x30 = val len_full_blocks - then MAYCHANGE - [memory :> - bytes128 (word_add ctxt_p (word (0x50 * val num_5blocks))); - memory :> - bytes128 - (word_add ctxt_p (word (0x50 * val num_5blocks + 0x10))); - memory :> - bytes128 - (word_add ctxt_p (word (0x50 * val num_5blocks + 0x20)))] - else if val num_5blocks * 0x50 + 0x20 = val len_full_blocks - then MAYCHANGE - [memory :> - bytes128 (word_add ctxt_p (word (0x50 * val num_5blocks))); - memory :> - bytes128 - (word_add ctxt_p (word (0x50 * val num_5blocks + 0x10)))] - else if val num_5blocks * 0x50 + 0x10 = val len_full_blocks - then MAYCHANGE - [memory :> - bytes128 - (word_add ctxt_p (word (0x50 * val num_5blocks)))] - else (MAYCHANGE:((armstate,?443102)component)list->armstate->armstate->bool) - []) subsumed - MAYCHANGE [PC; X0; X1; X2; X4; X6; X7; X8; X9; X10; X11; X19; X20; X21; X22] ,, - MAYCHANGE - [Q0; Q1; Q4; Q5; Q6; Q7; Q8; Q9; Q10; Q11; Q12; Q13; Q14; Q15; Q16; Q17; - Q18; Q19; Q20; Q21; Q22; Q23; Q24; Q25; Q26] ,, - MAYCHANGE [NF; ZF; CF; VF] ,, - MAYCHANGE [memory :> bytes (ctxt_p,val len)] ,, - MAYCHANGE [events]` - -`(forall i'. - i' < 0x50 * i - ==> read (memory :> bytes8 (word_add ctxt_p (word i'))) s188 = - EL i' (aes256_xts_encrypt pt_in (i * 0x50) iv key1_lst key2_lst)) - ==> (forall i'. - i' < 0x50 * i + 0x50 - ==> read (memory :> bytes8 (word_add ctxt_p (word i'))) s188 = - EL i' - (aes256_xts_encrypt pt_in (0x50 * i + 0x50) iv key1_lst - key2_lst))` - +val it : goalstack = 1 subgoal (1 total) + + 0 [`nonoverlapping_modulo (0x2 EXP 0x40) (pc,0xaac) (val ptxt_p,val len)`] + 1 [`nonoverlapping_modulo (0x2 EXP 0x40) (pc,0xaac) (val ctxt_p,val len)`] + 2 [`nonoverlapping_modulo (0x2 EXP 0x40) (pc,0xaac) (val key1_p,0xf4)`] + 3 [`nonoverlapping_modulo (0x2 EXP 0x40) (pc,0xaac) (val key2_p,0xf4)`] + 4 [`nonoverlapping_modulo (0x2 EXP 0x40) (val ptxt_p,val len) + (val ctxt_p,val len)`] + 5 [`nonoverlapping_modulo (0x2 EXP 0x40) (val ptxt_p,val len) + (val key1_p,0xf4)`] + 6 [`nonoverlapping_modulo (0x2 EXP 0x40) (val ptxt_p,val len) + (val key2_p,0xf4)`] + 7 [`nonoverlapping_modulo (0x2 EXP 0x40) (val ctxt_p,val len) + (val key1_p,0xf4)`] + 8 [`nonoverlapping_modulo (0x2 EXP 0x40) (val ctxt_p,val len) + (val key2_p,0xf4)`] + 9 [`nonoverlapping_modulo (0x2 EXP 0x40) (val key1_p,0xf4) + (val key2_p,0xf4)`] + 10 [`val len >= 0x10`] + 11 [`val len <= 0x2 EXP 0x18`] + 12 [`LENGTH pt_in = val len`] + 13 [`word_add tail_len len_full_blocks = len`] + 14 [`word_and len (word 0xfffffffffffffff0) = len_full_blocks`] + 15 [`word (val len_full_blocks DIV 0x50) = num_5blocks`] + 16 [`word_and len (word 0xf) = tail_len`] + 17 [`[k1_0; k1_1; k1_2; k1_3; k1_4; k1_5; k1_6; k1_7; k1_8; k1_9; k1_10; + k1_11; k1_12; k1_13; k1_14] = + key1_lst`] + 18 [`[k2_0; k2_1; k2_2; k2_3; k2_4; k2_5; k2_6; k2_7; k2_8; k2_9; k2_10; + k2_11; k2_12; k2_13; k2_14] = + key2_lst`] + 19 [`~(val len < 0x50)`] + 20 [`~(val len_full_blocks < 0x50)`] + 21 [`val len_full_blocks <= 0x2 EXP 0x18`] + 22 [`0x0 < val num_5blocks`] + 23 [`val len_full_blocks <= val len`] + 24 [`val num_5blocks * 0x50 <= val len_full_blocks`] + +`ensures arm + (\s. + aligned_bytes_loaded s (word pc) aes256_xts_encrypt_mc /\ + read PC s = word (pc + 0x9e0) /\ + read X0 s = + word_add ptxt_p (word (acc_len num_5blocks len_full_blocks)) /\ + read X1 s = + word_add ctxt_p (word (acc_len num_5blocks len_full_blocks)) /\ + read X21 s = tail_len /\ + read Q6 s = + calculate_tweak (acc_blocks num_5blocks len_full_blocks true) iv + key2_lst /\ + read X19 s = word 0x87 /\ + read X10 s = + word_subword + (calculate_tweak (acc_blocks num_5blocks len_full_blocks false) iv + key2_lst) + (0x40,0x40) /\ + read X9 s = + word_zx + (calculate_tweak (acc_blocks num_5blocks len_full_blocks false) iv + key2_lst) /\ + read Q16 s = k1_0 /\ + read Q17 s = k1_1 /\ + read Q12 s = k1_2 /\ + read Q13 s = k1_3 /\ + read Q14 s = k1_4 /\ + read Q15 s = k1_5 /\ + read Q4 s = k1_6 /\ + read Q5 s = k1_7 /\ + read Q18 s = k1_8 /\ + read Q19 s = k1_9 /\ + read Q20 s = k1_10 /\ + read Q21 s = k1_11 /\ + read Q22 s = k1_12 /\ + read Q23 s = k1_13 /\ + read Q7 s = k1_14 /\ + byte_list_at pt_in ptxt_p len s /\ + byte_list_at + (aes256_xts_encrypt pt_in (acc_len num_5blocks len_full_blocks) iv + key1_lst + key2_lst) + ctxt_p + (word (acc_len num_5blocks len_full_blocks)) + s) + (\s. + read PC s = word (pc + 0xaac - 0x8 * 0x4) /\ + (forall i. + i < val len + ==> read (memory :> bytes8 (word_add ctxt_p (word i))) s = + EL i (aes256_xts_encrypt pt_in (val len) iv key1_lst key2_lst))) + (MAYCHANGE + [PC; X0; X1; X2; X4; X6; X7; X8; X9; X10; X11; X19; X20; X21; X22] ,, + MAYCHANGE + [Q0; Q1; Q4; Q5; Q6; Q7; Q8; Q9; Q10; Q11; Q12; Q13; Q14; Q15; Q16; Q17; + Q18; Q19; Q20; Q21; Q22; Q23; Q24; Q25; Q26] ,, + MAYCHANGE [NF; ZF; CF; VF] ,, + MAYCHANGE [events] ,, + MAYCHANGE [memory :> bytes (ctxt_p,val len)])` *) From 751144fed54005530017c7e988f9ec7aeedc2461 Mon Sep 17 00:00:00 2001 From: Nevine Ebeid Date: Thu, 6 Nov 2025 14:01:54 -0500 Subject: [PATCH 085/132] Cipher-stealing: case tail != 0, loop invariant up to subgoal 2. --- arm/proofs/aes-xts-armv8.ml | 591 +++++++++++++++++++++++++++++++----- 1 file changed, 519 insertions(+), 72 deletions(-) diff --git a/arm/proofs/aes-xts-armv8.ml b/arm/proofs/aes-xts-armv8.ml index 230fb1613..37b63c32a 100644 --- a/arm/proofs/aes-xts-armv8.ml +++ b/arm/proofs/aes-xts-armv8.ml @@ -1492,6 +1492,20 @@ let NUM_OF_BYTELIST_OF_SUB_LIST = prove( ASM_SIMP_TAC[LENGTH_SUB_LIST; SUB_0; MIN; ARITH_RULE `0 + sz = sz`] );; +let INT128_TO_BYTES_OF_BYTES_TO_INT128 = prove( + `!x. LENGTH x = 16 ==> int128_to_bytes (bytes_to_int128 x) = x`, + REPEAT STRIP_TAC THEN + MP_TAC ((GEN_REWRITE_CONV I [LENGTH_EQ_LIST_OF_SEQ] THENC + RAND_CONV LIST_OF_SEQ_CONV) `LENGTH (x:byte list) = 16`) THEN + ASM_SIMP_TAC[] THEN + DISCH_THEN (fun th -> ONCE_REWRITE_TAC[th]) THEN + REWRITE_TAC[bytes_to_int128] THEN + REWRITE_TAC EL_16_8_CLAUSES THEN + REWRITE_TAC[int128_to_bytes] THEN + REWRITE_TAC[CONS_11] THEN + REPEAT (CONJ_TAC THEN BITBLAST_TAC) +);; + let MEMORY_READ_SUBSET_LEMMA = prove (`!len (ptr:int64) (bl:byte list) s. (forall i. @@ -1545,6 +1559,144 @@ let BYTE_LIST_AT_SPLIT = prove( ] );; +let HD_SUB_LIST_CONS = prove + (`!(h:A) (t:A list) n. 0 < n ==> HD (SUB_LIST (0,n) (CONS h t)) = h`, + REPEAT GEN_TAC THEN STRIP_TAC THEN + MP_TAC(SPEC `n:num` num_CASES) THEN + ASM_SIMP_TAC[ARITH_RULE `0 < n ==> ~(n = 0)`] THEN + DISCH_THEN(X_CHOOSE_THEN `m:num` SUBST_ALL_TAC) THEN + REWRITE_TAC[SUB_LIST_CLAUSES; HD]);; + +let HD_SUB_LIST_CONS_GENERAL = prove( + `!p n (l:A list). p < LENGTH l /\ 0 < n ==> HD (SUB_LIST (p,n) l) = EL p l`, + INDUCT_TAC THENL + [ + GEN_TAC THEN + LIST_INDUCT_TAC THENL + [ + REWRITE_TAC[LENGTH] THEN ARITH_TAC; + REPEAT STRIP_TAC THEN + REWRITE_TAC[EL; HD] THEN + MP_TAC (SPECL [`h:A`; `t:A list`; `n:num`] HD_SUB_LIST_CONS) THEN + ASM_SIMP_TAC[] + ]; ALL_TAC + ] THEN + GEN_TAC THEN + LIST_INDUCT_TAC THENL + [ + REWRITE_TAC[LENGTH] THEN ARITH_TAC; + REPEAT STRIP_TAC THEN + REWRITE_TAC[SUB_LIST_CLAUSES] THEN + REWRITE_TAC[EL; TL] THEN + FIRST_X_ASSUM (fun th -> MATCH_MP_TAC (SPECL [`n:num`; `t:A list`] th)) THEN + ASM_SIMP_TAC[] THEN + UNDISCH_TAC `SUC p < LENGTH (CONS h (t:A list))` THEN + REWRITE_TAC[LENGTH] THEN + ARITH_TAC + ] +);; + +let TL_SUB_LIST_CONS = prove +(`!(h:A) (t:A list) n. 0 < n ==> TL (SUB_LIST (0,n) (CONS h t)) = SUB_LIST (0, n - 1) t`, + REPEAT GEN_TAC THEN STRIP_TAC THEN + MP_TAC(SPEC `n:num` num_CASES) THEN + ASM_SIMP_TAC[ARITH_RULE `0 < n ==> ~(n = 0)`] THEN + DISCH_THEN(X_CHOOSE_THEN `m:num` SUBST_ALL_TAC) THEN + REWRITE_TAC[SUB_LIST_CLAUSES; TL] THEN + REWRITE_TAC[ARITH_RULE `SUC m - 1 = m`]);; + +let TL_SUB_LIST_CONS_GENERAL = prove( + `!p n (l:A list). p < LENGTH l ==> 0 < n + ==> TL (SUB_LIST (p, n) l) = SUB_LIST (p + 1, n - 1) l`, + INDUCT_TAC THENL + [ + GEN_TAC THEN + LIST_INDUCT_TAC THENL + [ + REWRITE_TAC[LENGTH] THEN ARITH_TAC; + CONV_TAC NUM_REDUCE_CONV THEN + REPEAT STRIP_TAC THEN + MP_TAC (SPECL [`h:A`; `t:A list`; `n:num`] TL_SUB_LIST_CONS) THEN + ASM_SIMP_TAC[num_CONV `1`; SUB_LIST_CLAUSES] + ]; ALL_TAC + ] THEN + GEN_TAC THEN + LIST_INDUCT_TAC THENL + [ + REWRITE_TAC[LENGTH] THEN ARITH_TAC; + REPEAT STRIP_TAC THEN + REWRITE_TAC[ARITH_RULE `SUC p + 1 = SUC (p + 1)`] THEN + REWRITE_TAC[SUB_LIST_CLAUSES] THEN + FIRST_X_ASSUM (fun th -> MP_TAC (SPECL [`n:num`; `t:A list`] th)) THEN + SUBGOAL_THEN `p < LENGTH (t:A list)` ASSUME_TAC THENL + [ UNDISCH_TAC `SUC p < LENGTH (CONS h (t:A list))` THEN + REWRITE_TAC[LENGTH] THEN ARITH_TAC + ; ALL_TAC] THEN + ASM_SIMP_TAC[] + ] +);; + +let EL_SUB_LIST = prove( + `!(i:num) n (l:A list). i < n /\ n <= LENGTH l ==> + EL i (SUB_LIST (0, n) l) = EL i l`, + INDUCT_TAC THENL + [ (* i = 0 *) + ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN + LIST_INDUCT_TAC THENL + [ + REPEAT STRIP_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_TRIVIAL] THEN + REWRITE_TAC[LENGTH] THEN + ARITH_TAC; ALL_TAC + ] THEN + REPEAT STRIP_TAC THEN + IMP_REWRITE_TAC[EL; HD; HD_SUB_LIST_CONS]; + ALL_TAC + ] THEN + (* i != 0 *) + ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN + LIST_INDUCT_TAC THENL + [ + REPEAT STRIP_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_TRIVIAL] THEN + REWRITE_TAC[LENGTH] THEN + ARITH_TAC; ALL_TAC + ] THEN + REPEAT STRIP_TAC THEN + REWRITE_TAC[EL; TL] THEN + IMP_REWRITE_TAC[TL_SUB_LIST_CONS] THEN + REPEAT CONJ_TAC THENL + [ ASM_SIMP_TAC[ARITH_RULE `SUC i < n ==> i < n - 1`]; + SUBGOAL_THEN `LENGTH (CONS h (t:A list)) = SUC (LENGTH t)` ASSUME_TAC THENL + [ REWRITE_TAC[LENGTH]; ALL_TAC ] THEN + ASM_ARITH_TAC; + MP_TAC (ARITH_RULE `SUC i < n ==> 0 < n`) THEN + ASM_SIMP_TAC[] + ] +);; + +let EL_SUB_LIST_SHIFT = prove( + `!(i:num) p (l:A list) n. 0 < i /\ i < n /\ n <= LENGTH l - p ==> + EL (i - 1) (SUB_LIST (p + 1, n - 1) l) = EL i (SUB_LIST (p, n) l)`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN `EL i (SUB_LIST (p, n) (l:A list)) = EL (SUC (i - 1)) (SUB_LIST (p, SUC (n - 1)) l)` SUBST1_TAC THENL + [ IMP_REWRITE_TAC[ARITH_RULE `0 < i ==> SUC (i - 1) = i`] THEN + ASM_ARITH_TAC; ALL_TAC ] THEN + DISJ_CASES_TAC (ISPEC `l:(A)list` list_CASES) THENL [ + FIRST_X_ASSUM SUBST_ALL_TAC THEN + UNDISCH_TAC `n <= LENGTH ([]:A list) - p` THEN + REWRITE_TAC[LENGTH] THEN + ASM_ARITH_TAC; ALL_TAC + ] THEN + + REPEAT_N 2 (FIRST_X_ASSUM CHOOSE_TAC) THEN + FIRST_X_ASSUM SUBST_ALL_TAC THEN + REWRITE_TAC[EL; TL] THEN + IMP_REWRITE_TAC[TL_SUB_LIST_CONS_GENERAL] THEN + IMP_REWRITE_TAC[ARITH_RULE `0 < n ==> SUC (n - 1) = n`] THEN + ASM_ARITH_TAC + );; + let MEMORY_READ_BYTES_SUBSET_LEMMA = prove( `!len (ptr:int64) (bl:byte list) s. SUC len <= LENGTH bl ==> @@ -1863,6 +2015,175 @@ let SUB_LIST_LENGTH_IMPLIES = prove( REWRITE_TAC[SUB_LIST_LENGTH] );; +let SUB_LIST_IDEMPOTENT_P = prove( + `!p n (l:(A)list). SUB_LIST (0,n) (SUB_LIST (p,n) l) = SUB_LIST (p,n) l`, + INDUCT_TAC THENL[ + REWRITE_TAC[SUB_LIST_IDEMPOTENT]; + + REPEAT STRIP_TAC THEN + DISJ_CASES_TAC (ISPEC `l:(A)list` list_CASES) THENL [ + ASM_REWRITE_TAC[] THEN REWRITE_TAC[SUB_LIST_CLAUSES]; + ALL_TAC + ] THEN + FIRST_X_ASSUM MP_TAC THEN STRIP_TAC THEN + ASM_REWRITE_TAC[] THEN REWRITE_TAC[SUB_LIST_CLAUSES] THEN + ASM_REWRITE_TAC[] + ] +);; + + +let SUB_LIST_MIN_RIGHT = prove( + `!p (l:(A)list) (n:num) m. SUB_LIST (0,n) (SUB_LIST (p,m) l) = SUB_LIST (p, MIN n m) l`, + REPEAT STRIP_TAC THEN + ASM_CASES_TAC `(m:num) <= n` THENL [ + FIRST_X_ASSUM MP_TAC THEN REWRITE_TAC[LE_EXISTS] THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[SUB_LIST_SPLIT;ADD_CLAUSES;ARITH_RULE`MIN ((x:num)+y) x = x`] THEN + REWRITE_TAC[SUB_LIST_IDEMPOTENT_P] THEN + GEN_REWRITE_TAC RAND_CONV [GSYM APPEND_NIL] THEN + AP_TERM_TAC THEN MATCH_MP_TAC SUB_LIST_TRIVIAL THEN + REWRITE_TAC[LENGTH_SUB_LIST] THEN ARITH_TAC; ALL_TAC] THEN + + IMP_REWRITE_TAC[ARITH_RULE `~(m <= n) ==> MIN n m = n`] THEN + FIRST_X_ASSUM MP_TAC THEN REWRITE_TAC[NOT_LE;LT_EXISTS] THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[SUB_LIST_SPLIT;ADD_CLAUSES;ARITH_RULE`MIN (x:num) (x+y) = x`] THEN + + MP_TAC (ISPECL [`l:A list`; `p:num`; `n:num`] LENGTH_SUB_LIST) THEN + ASM_CASES_TAC `n <= LENGTH (l:A list) - p` THENL [ + IMP_REWRITE_TAC[ARITH_RULE `!n m. n <= m ==> MIN n m = n`] THEN + DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_APPEND_LEFT] THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN + ARITH_TAC; ALL_TAC + ] THEN + + IMP_REWRITE_TAC[ARITH_RULE `!n m. ~(n <= m) ==> MIN n m = m`] THEN + SUBGOAL_THEN `SUB_LIST (p + n,SUC d) (l:A list) = []` SUBST1_TAC THENL + [ MATCH_MP_TAC SUB_LIST_TRIVIAL THEN + ASM_ARITH_TAC; ALL_TAC] THEN + REWRITE_TAC[APPEND_NIL] THEN + REWRITE_TAC[SUB_LIST_IDEMPOTENT_P] +);; + +let SUB_LIST_MIN_LEFT = prove( + `!q (l:A list) n m. + SUB_LIST (q,n) (SUB_LIST (0,m) l) = SUB_LIST (q, MIN n (m - q)) l`, + REPEAT STRIP_TAC THEN + ASM_CASES_TAC `n <= m - q` THENL [ + IMP_REWRITE_TAC[ARITH_RULE `x <= y ==> MIN x y = x`] THEN + UNDISCH_TAC `n <= m - q` THEN + MAP_EVERY SPEC1_TAC [`n:num`; `l:A list`; `q:num`; `m:num`] THEN + (* Induct over m *) + INDUCT_TAC THENL + [ + REPEAT STRIP_TAC THEN + IMP_REWRITE_TAC[ARITH_RULE `n <= 0 - q ==> n = 0`] THEN + REWRITE_TAC[SUB_LIST_CLAUSES]; + + INDUCT_TAC THENL + [ + REWRITE_TAC[SUB_0] THEN + REPEAT STRIP_TAC THEN + MP_TAC (SPECL [`0:num`; `l:A list`; `n:num`; `SUC m:num`] SUB_LIST_MIN_RIGHT) THEN + IMP_REWRITE_TAC[ARITH_RULE `x <= y ==> MIN x y = x`]; + + LIST_INDUCT_TAC THENL[ + REWRITE_TAC[SUB_LIST_CLAUSES]; + REWRITE_TAC[SUB_LIST_CLAUSES] THEN + REPEAT STRIP_TAC THEN + FIRST_X_ASSUM + (fun th -> MP_TAC + (SPECL [`q:num`; `t:A list`; `n:num`] th)) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN + SIMP_TAC[] + ] + ] + ]; ALL_TAC + ] THEN + + (* Case n > m - q*) + IMP_REWRITE_TAC[ARITH_RULE `~(x <= y) ==> MIN x y = y`] THEN + UNDISCH_TAC `~(n <= m - q)` THEN + MAP_EVERY SPEC1_TAC [`n:num`; `l:A list`; `q:num`; `m:num`] THEN + INDUCT_TAC THENL + [ + REPEAT STRIP_TAC THEN + REWRITE_TAC[ARITH_RULE `0 - q = 0`] THEN + REWRITE_TAC[SUB_LIST_CLAUSES]; + + INDUCT_TAC THENL + [ + REWRITE_TAC[SUB_0] THEN + REPEAT STRIP_TAC THEN + MP_TAC (SPECL [`0:num`; `l:A list`; `n:num`; `SUC m:num`] SUB_LIST_MIN_RIGHT) THEN + IMP_REWRITE_TAC[ARITH_RULE `~(x <= y) ==> MIN x y = y`]; + + LIST_INDUCT_TAC THENL[ + REWRITE_TAC[SUB_LIST_CLAUSES]; + REWRITE_TAC[SUB_LIST_CLAUSES] THEN + REPEAT STRIP_TAC THEN + REWRITE_TAC[ARITH_RULE `SUC m - SUC q = m - q`] THEN + FIRST_X_ASSUM + (fun th -> MP_TAC + (SPECL [`q:num`; `t:A list`; `n:num`] th)) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN + SIMP_TAC[] + ] + ] + ] +);; + +let SUB_LIST_MIN_GENERAL = prove( + `!p q (l:(A)list) (n:num) m. + SUB_LIST (q,n) (SUB_LIST (p,m) l) = SUB_LIST (p + q, MIN n (m - q)) l`, + REPEAT STRIP_TAC THEN + (* Case n <= m - q *) + ASM_CASES_TAC `n <= m - q` THENL [ + IMP_REWRITE_TAC[ARITH_RULE `x <= y ==> MIN x y = x`] THEN + (* Induct over p *) + UNDISCH_TAC `n <= m - q` THEN + MAP_EVERY SPEC1_TAC [`m:num`; `n:num`; `l:A list`; `q:num`; `p:num`] THEN + INDUCT_TAC THENL + [ + REWRITE_TAC[ADD] THEN + REPEAT STRIP_TAC THEN + MP_TAC (SPECL [`q:num`; `l:A list`; `n:num`; `m:num`] SUB_LIST_MIN_LEFT) THEN + IMP_REWRITE_TAC[ARITH_RULE `x <= y ==> MIN x y = x`]; + ALL_TAC + ] THEN + + ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN + LIST_INDUCT_TAC THENL[ + REWRITE_TAC[SUB_LIST_CLAUSES]; + REWRITE_TAC[ARITH_RULE `SUC p + q = SUC (p + q)`] THEN + REWRITE_TAC[SUB_LIST_CLAUSES] THEN + ASM_REWRITE_TAC[] + ]; ALL_TAC + ] THEN + + (* Case n > m - q*) + IMP_REWRITE_TAC[ARITH_RULE `~(x <= y) ==> MIN x y = y`] THEN + UNDISCH_TAC `~(n <= m - q)` THEN + MAP_EVERY SPEC1_TAC [`m:num`; `n:num`; `l:A list`; `q:num`; `p:num`] THEN + INDUCT_TAC THENL + [ + REWRITE_TAC[ADD] THEN + REPEAT STRIP_TAC THEN + MP_TAC (SPECL [`q:num`; `l:A list`; `n:num`; `m:num`] SUB_LIST_MIN_LEFT) THEN + IMP_REWRITE_TAC[ARITH_RULE `~(x <= y) ==> MIN x y = y`]; + ALL_TAC + ] THEN + + ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN + LIST_INDUCT_TAC THENL[ + REWRITE_TAC[SUB_LIST_CLAUSES]; + REWRITE_TAC[ARITH_RULE `SUC p + q = SUC (p + q)`] THEN + REWRITE_TAC[SUB_LIST_CLAUSES] THEN + ASM_REWRITE_TAC[] + ] +);; + let UDIV_OPT_THM = prove(`!n:num. n < 0x2 EXP 0x40 ==> (word (val ((word ((n * 0xcccccccccccccccd) DIV 0x2 EXP 0x40)):int64) DIV 0x2 EXP 0x6)):int64 = word (n DIV 0x50)`, REPEAT STRIP_TAC THEN @@ -1972,6 +2293,11 @@ let WORD_AND_MASK16 = prove( BITBLAST_TAC );; + +let WORD_AND_MASK16_EQ_0 = prove( + `!(x:int64). val x < 16 ==> ~(val x = 0x0) ==> ~(val (word_and x (word 0xf)) = 0x0)`, + BITBLAST_TAC);; + (* Same as Decrypt proof with a different name *) let LEN_FULL_BLOCKS_TO_VAL = prove( `!(len:int64). word_and len (word 0xfffffffffffffff0) = word (16 * (val len DIV 16))`, @@ -2347,48 +2673,51 @@ let acc_blocks = new_definition else if last then val i * 0x5 else val i * 0x5 + 4`;; - -let cipher_stealing_inv = new_definition -`cipher_stealing_inv (i:num) (curr_len:num) (tail_len:num) (CC:int128) (pt:byte list): int128 = +(* The cipher-stealing invariant is the block read at ctxt_p + curr_len where Cm is being replaced by Pm + one byte at a time with a decreasing offset i from the beginning of the block. + Differs from decrypt in that, there, it's curr_len + 16 *) +let cipher_stealing_enc_inv = new_definition +`cipher_stealing_enc_inv (i:num) (curr_len:num) (tail_len:num) (CC:int128) (pt:byte list): int128 = bytes_to_int128( APPEND (SUB_LIST (0, i) (int128_to_bytes CC)) - (APPEND (SUB_LIST (i, tail_len - i) (SUB_LIST (curr_len + 16, tail_len) pt)) + (APPEND (SUB_LIST (i, tail_len - i) (SUB_LIST (curr_len, tail_len) pt)) (SUB_LIST (tail_len, 16 - tail_len) (int128_to_bytes CC))))`;; - -let CIPHER_STEALING_BYTE_EQUAL = prove( - `!(i:num) (curr_len:num) (tail_len:int64) (PP:int128) (ct:byte list). +(* In the cipher-stealing loop invariant, all bytes remain the same between iterations + except the current byte i, which is from the corresponding location i in the tail of pt *) +let CIPHER_STEALING_ENC_BYTE_EQUAL = prove( + `!(i:num) (curr_len:num) (tail_len:int64) (CC:int128) (pt:byte list). i < val tail_len /\ val tail_len < 16 ==> - curr_len + 16 + val tail_len = LENGTH ct ==> - let InvPP = cipher_stealing_inv (i + 1) curr_len (val tail_len) PP ct - and InvPP' = cipher_stealing_inv i curr_len (val tail_len) PP ct in - (!j. 0 <= j /\ j < 16 /\ ~(j = i) ==> EL j (int128_to_bytes InvPP) = EL j (int128_to_bytes InvPP')) /\ - EL i (int128_to_bytes InvPP') = word_zx (EL (curr_len + 16 + i) ct)`, + curr_len + val tail_len = LENGTH pt ==> + let InvCC = cipher_stealing_enc_inv (i + 1) curr_len (val tail_len) CC pt + and InvCC' = cipher_stealing_enc_inv i curr_len (val tail_len) CC pt in + (!j. 0 <= j /\ j < 16 /\ ~(j = i) ==> EL j (int128_to_bytes InvCC) = EL j (int128_to_bytes InvCC')) /\ + EL i (int128_to_bytes InvCC') = word_zx (EL (curr_len + i) pt)`, REPEAT STRIP_TAC THEN REWRITE_TAC[LET_DEF; LET_END_DEF] THEN CONJ_TAC THENL [ REPEAT STRIP_TAC THEN - REWRITE_TAC[cipher_stealing_inv] THEN + REWRITE_TAC[cipher_stealing_enc_inv] THEN IMP_REWRITE_TAC[INT128_TO_BYTES_OF_BYTES_TO_INT128] THEN REPEAT CONJ_TAC THENL [ (* Three cases: 0 <= j < i, i < j < val tail_len, val tail_len <= j < 16 *) ASM_CASES_TAC `j < i` THENL [ - SUBGOAL_THEN `j < LENGTH (SUB_LIST (0x0,i + 0x1) (int128_to_bytes PP))` ASSUME_TAC THENL + SUBGOAL_THEN `j < LENGTH (SUB_LIST (0x0,i + 0x1) (int128_to_bytes CC))` ASSUME_TAC THENL [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN ASM_ARITH_TAC; ALL_TAC] THEN - SUBGOAL_THEN `j < LENGTH (SUB_LIST (0x0,i) (int128_to_bytes PP))` ASSUME_TAC THENL + SUBGOAL_THEN `j < LENGTH (SUB_LIST (0x0,i) (int128_to_bytes CC))` ASSUME_TAC THENL [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN ASM_ARITH_TAC ; ALL_TAC] THEN REWRITE_TAC[EL_APPEND] THEN ASM_SIMP_TAC[] THEN - MP_TAC (ISPECL [`j:num`; `i:num`; `(int128_to_bytes PP):byte list`] EL_SUB_LIST) THEN + MP_TAC (ISPECL [`j:num`; `i:num`; `(int128_to_bytes CC):byte list`] EL_SUB_LIST) THEN ANTS_TAC THENL [ REWRITE_TAC[LENGTH_OF_INT128_TO_BYTES] THEN ASM_ARITH_TAC; ALL_TAC ] THEN - MP_TAC (ISPECL [`j:num`; `(i + 1):num`; `(int128_to_bytes PP):byte list`] EL_SUB_LIST) THEN + MP_TAC (ISPECL [`j:num`; `(i + 1):num`; `(int128_to_bytes CC):byte list`] EL_SUB_LIST) THEN ANTS_TAC THENL [ REWRITE_TAC[LENGTH_OF_INT128_TO_BYTES] THEN ASM_ARITH_TAC; ALL_TAC ] THEN @@ -2398,19 +2727,19 @@ let CIPHER_STEALING_BYTE_EQUAL = prove( [ SUBGOAL_THEN `j > i` ASSUME_TAC THENL[ASM_ARITH_TAC; ALL_TAC] THEN REWRITE_TAC[EL_APPEND] THEN - SUBGOAL_THEN `LENGTH (SUB_LIST (0x0,i + 0x1) (int128_to_bytes PP)) = i + 1` SUBST1_TAC THENL + SUBGOAL_THEN `LENGTH (SUB_LIST (0x0,i + 0x1) (int128_to_bytes CC)) = i + 1` SUBST1_TAC THENL [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN ASM_ARITH_TAC; ALL_TAC] THEN - SUBGOAL_THEN `LENGTH (SUB_LIST (0x0,i) (int128_to_bytes PP)) = i` SUBST1_TAC THENL + SUBGOAL_THEN `LENGTH (SUB_LIST (0x0,i) (int128_to_bytes CC)) = i` SUBST1_TAC THENL [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN ASM_ARITH_TAC; ALL_TAC] THEN SUBGOAL_THEN `LENGTH (SUB_LIST (i + 0x1,val (tail_len:int64) - (i + 0x1)) - (SUB_LIST (curr_len + 0x10,val tail_len) (ct:byte list))) + (SUB_LIST (curr_len,val tail_len) (pt:byte list))) = val tail_len - (i + 1)` SUBST1_TAC THENL [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN ASM_ARITH_TAC; ALL_TAC] THEN SUBGOAL_THEN `LENGTH (SUB_LIST (i,val (tail_len:int64) - i) - (SUB_LIST (curr_len + 0x10,val tail_len) (ct:byte list))) + (SUB_LIST (curr_len,val tail_len) (pt:byte list))) = val tail_len - i` SUBST1_TAC THENL [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN ASM_ARITH_TAC; ALL_TAC] THEN @@ -2424,7 +2753,7 @@ let CIPHER_STEALING_BYTE_EQUAL = prove( [ ASM_ARITH_TAC; ALL_TAC] THEN ASM_SIMP_TAC[] THEN MP_TAC (ISPECL [`(j - i):num`; `i:num`; - `(SUB_LIST (curr_len + 16,val (tail_len:int64)) (ct:byte list)):byte list`; + `(SUB_LIST (curr_len,val (tail_len:int64)) (pt:byte list)):byte list`; `(val (tail_len:int64) - i):num`] EL_SUB_LIST_SHIFT) THEN ASM_SIMP_TAC[] THEN ANTS_TAC THENL [ REWRITE_TAC[LENGTH_SUB_LIST] THEN ASM_ARITH_TAC; ALL_TAC] THEN @@ -2433,19 +2762,19 @@ let CIPHER_STEALING_BYTE_EQUAL = prove( ] THEN (* j >= val tail_len *) REWRITE_TAC[EL_APPEND] THEN - SUBGOAL_THEN `LENGTH (SUB_LIST (0x0,i + 0x1) (int128_to_bytes PP)) = i + 1` SUBST1_TAC THENL + SUBGOAL_THEN `LENGTH (SUB_LIST (0x0,i + 0x1) (int128_to_bytes CC)) = i + 1` SUBST1_TAC THENL [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN ASM_ARITH_TAC; ALL_TAC] THEN - SUBGOAL_THEN `LENGTH (SUB_LIST (0x0,i) (int128_to_bytes PP)) = i` SUBST1_TAC THENL + SUBGOAL_THEN `LENGTH (SUB_LIST (0x0,i) (int128_to_bytes CC)) = i` SUBST1_TAC THENL [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN ASM_ARITH_TAC; ALL_TAC] THEN SUBGOAL_THEN `LENGTH (SUB_LIST (i + 0x1,val (tail_len:int64) - (i + 0x1)) - (SUB_LIST (curr_len + 0x10,val tail_len) (ct:byte list))) + (SUB_LIST (curr_len,val tail_len) (pt:byte list))) = val tail_len - (i + 1)` SUBST1_TAC THENL [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN ASM_ARITH_TAC; ALL_TAC] THEN SUBGOAL_THEN `LENGTH (SUB_LIST (i,val (tail_len:int64) - i) - (SUB_LIST (curr_len + 0x10,val tail_len) (ct:byte list))) + (SUB_LIST (curr_len,val tail_len) (pt:byte list))) = val tail_len - i` SUBST1_TAC THENL [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN ASM_ARITH_TAC; ALL_TAC] THEN @@ -2466,7 +2795,7 @@ let CIPHER_STEALING_BYTE_EQUAL = prove( REWRITE_TAC[LENGTH_OF_INT128_TO_BYTES] THEN CONV_TAC NUM_REDUCE_CONV THEN IMP_REWRITE_TAC[ARITH_RULE `i < 16 ==> MIN i 16 = i`] THEN - SUBGOAL_THEN `LENGTH (ct:byte list) - (curr_len + 16) = val (tail_len:int64)` SUBST1_TAC THENL + SUBGOAL_THEN `LENGTH (pt:byte list) - (curr_len) = val (tail_len:int64)` SUBST1_TAC THENL [ ASM_ARITH_TAC; ALL_TAC ] THEN REWRITE_TAC[ARITH_RULE `!x. MIN x x = x`] THEN ASM_ARITH_TAC; @@ -2476,22 +2805,22 @@ let CIPHER_STEALING_BYTE_EQUAL = prove( REWRITE_TAC[LENGTH_OF_INT128_TO_BYTES] THEN CONV_TAC NUM_REDUCE_CONV THEN IMP_REWRITE_TAC[ARITH_RULE `i < 16 ==> MIN (i + 1) 16 = i + 1`] THEN - SUBGOAL_THEN `LENGTH (ct:byte list) - (curr_len + 16) = val (tail_len:int64)` SUBST1_TAC THENL + SUBGOAL_THEN `LENGTH (pt:byte list) - (curr_len) = val (tail_len:int64)` SUBST1_TAC THENL [ ASM_ARITH_TAC; ALL_TAC ] THEN REWRITE_TAC[ARITH_RULE `!x. MIN x x = x`] THEN ASM_ARITH_TAC ] ; ALL_TAC ] THEN - REWRITE_TAC[cipher_stealing_inv] THEN + REWRITE_TAC[cipher_stealing_enc_inv] THEN IMP_REWRITE_TAC[INT128_TO_BYTES_OF_BYTES_TO_INT128] THEN CONJ_TAC THENL [ REWRITE_TAC[EL_APPEND] THEN - SUBGOAL_THEN `LENGTH (SUB_LIST (0x0,i) (int128_to_bytes PP)) = i` SUBST1_TAC THENL + SUBGOAL_THEN `LENGTH (SUB_LIST (0x0,i) (int128_to_bytes CC)) = i` SUBST1_TAC THENL [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN ASM_ARITH_TAC; ALL_TAC] THEN SUBGOAL_THEN `LENGTH (SUB_LIST (i,val (tail_len:int64) - i) - (SUB_LIST (curr_len + 0x10,val tail_len) (ct:byte list))) + (SUB_LIST (curr_len,val tail_len) (pt:byte list))) = val tail_len - i` SUBST1_TAC THENL [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN ASM_ARITH_TAC; ALL_TAC] THEN @@ -2499,7 +2828,7 @@ let CIPHER_STEALING_BYTE_EQUAL = prove( SUBGOAL_THEN `0 < val (tail_len:int64) - i` ASSUME_TAC THENL [ ASM_ARITH_TAC; ALL_TAC] THEN ASM_SIMP_TAC[] THEN - MP_TAC (ISPECL [`curr_len + 0x10:num`; `i:num`; `ct:byte list`; + MP_TAC (ISPECL [`curr_len:num`; `i:num`; `pt:byte list`; `val (tail_len:int64) - i:num`; `val (tail_len:int64)`] SUB_LIST_MIN_GENERAL) THEN REWRITE_TAC[ARITH_RULE `!a. MIN a a = a`; GSYM ADD_ASSOC] THEN DISCH_THEN (fun th -> (REWRITE_TAC [th])) THEN @@ -2513,21 +2842,21 @@ let CIPHER_STEALING_BYTE_EQUAL = prove( ASM_ARITH_TAC );; -let CIPHER_STEALING_INV_SELECT = prove( - `!(i:num) (curr_len:num) (tail_len:int64) (PP:int128) (ct:byte list). +let CIPHER_STEALING_ENC_INV_SELECT = prove( + `!(i:num) (curr_len:num) (tail_len:int64) (CC:int128) (pt:byte list). i < val tail_len ==> val tail_len < 16 ==> - curr_len + 16 + (val tail_len) = LENGTH ct ==> - EL i (int128_to_bytes (cipher_stealing_inv (i + 1) curr_len (val tail_len) PP ct)) = - EL i (int128_to_bytes PP)`, + curr_len + 16 + (val tail_len) = LENGTH pt ==> + EL i (int128_to_bytes (cipher_stealing_enc_inv (i + 1) curr_len (val tail_len) CC pt)) = + EL i (int128_to_bytes CC)`, REPEAT STRIP_TAC THEN - REWRITE_TAC[cipher_stealing_inv] THEN + REWRITE_TAC[cipher_stealing_enc_inv] THEN IMP_REWRITE_TAC[INT128_TO_BYTES_OF_BYTES_TO_INT128] THEN CONJ_TAC THENL [ - SUBGOAL_THEN `LENGTH (SUB_LIST (0x0,i + 1) (int128_to_bytes PP)) <= i + 1` ASSUME_TAC THENL + SUBGOAL_THEN `LENGTH (SUB_LIST (0x0,i + 1) (int128_to_bytes CC)) <= i + 1` ASSUME_TAC THENL [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN ARITH_TAC; ALL_TAC] THEN REWRITE_TAC[EL_APPEND] THEN - SUBGOAL_THEN `i < LENGTH (SUB_LIST (0x0,i + 0x1) (int128_to_bytes PP))` ASSUME_TAC THENL + SUBGOAL_THEN `i < LENGTH (SUB_LIST (0x0,i + 0x1) (int128_to_bytes CC))` ASSUME_TAC THENL [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN ASM_ARITH_TAC; ALL_TAC] THEN ASM_SIMP_TAC[] THEN @@ -2541,13 +2870,13 @@ let CIPHER_STEALING_INV_SELECT = prove( REWRITE_TAC[LENGTH_OF_INT128_TO_BYTES] THEN CONV_TAC NUM_REDUCE_CONV THEN IMP_REWRITE_TAC[ARITH_RULE `i < 16 ==> MIN (i + 1) 16 = i + 1`] THEN - SUBGOAL_THEN `LENGTH (ct:byte list) - (curr_len + 16) = val (tail_len:int64)` SUBST1_TAC THENL + SUBGOAL_THEN `LENGTH (pt:byte list) - (curr_len + 16) = val (tail_len:int64)` SUBST1_TAC THENL [ ASM_ARITH_TAC; ALL_TAC ] THEN REWRITE_TAC[ARITH_RULE `!x. MIN x x = x`] THEN ASM_ARITH_TAC );; -let CIPHER_STEALING_INV_SIMP_TAC i = +let CIPHER_STEALING_ENC_INV_SIMP_TAC i = ( FIRST_ASSUM (fun th -> MATCH_MP_TAC(SPEC i th)) THEN CONV_TAC NUM_REDUCE_CONV) ORELSE ( ASM_REWRITE_TAC[] THEN REWRITE_TAC[WORD_RULE `!a b. word_add ((word a):int64) (word b) = word (a + b)`] THEN @@ -2563,7 +2892,7 @@ let TAIL_SWAP_CASE_TAC case = let v_tm = `v:num` in let v = rand (concl (NUM_RED_CONV (subst [case,c_tm] `0x10 + case`))) in let r1 = subst [case,c_tm; v,v_tm] `curr_len + 0x10 + case = curr_len + v` in - let t1 = subst [case,c_tm] `(cipher_stealing_inv case curr_len (val (tail_len:int64)) PP ct):int128` in + let t1 = subst [case,c_tm] `(cipher_stealing_enc_inv case curr_len (val (tail_len:int64)) CC pt):int128` in POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th]) THEN REWRITE_TAC[th]) THEN (* Simplify so that symbolic execution could match up, but couldn't use CONV_TAC NUM_REDUCE_CONV because of non-overlapping *) @@ -2586,8 +2915,8 @@ let TAIL_SWAP_CASE_TAC case = ASM_REWRITE_TAC[] THEN CONV_TAC NUM_REDUCE_CONV THEN - MP_TAC (SPECL [case; `curr_len:num`; `tail_len:int64`; `PP:int128`; `ct:byte list`] - CIPHER_STEALING_BYTE_EQUAL) THEN + MP_TAC (SPECL [case; `curr_len:num`; `tail_len:int64`; `CC:int128`; `pt:byte list`] + CIPHER_STEALING_ENC_BYTE_EQUAL) THEN CONV_TAC NUM_REDUCE_CONV THEN REWRITE_TAC[LET_DEF; LET_END_DEF] THEN ANTS_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN @@ -2595,12 +2924,12 @@ let TAIL_SWAP_CASE_TAC case = STRIP_TAC THEN MAP_EVERY (fun i -> CONJ_TAC THENL - [CIPHER_STEALING_INV_SIMP_TAC (mk_numeral (num i)); ALL_TAC]) + [CIPHER_STEALING_ENC_INV_SIMP_TAC (mk_numeral (num i)); ALL_TAC]) (0--0xe) THEN - CIPHER_STEALING_INV_SIMP_TAC `0xf:num`; + CIPHER_STEALING_ENC_INV_SIMP_TAC `0xf:num`; MP_TAC (SPECL [`pt_ptr:int64`; case; `val (tail_len:int64)`; - `curr_len:num`; `(int128_to_bytes PP):byte list`; `s5:armstate`] + `curr_len:num`; `(int128_to_bytes CC):byte list`; `s5:armstate`] BYTE_LIST_AT_SPLIT_BACKWARDS) THEN REWRITE_TAC[LENGTH_OF_INT128_TO_BYTES] THEN CONV_TAC NUM_REDUCE_CONV THEN @@ -2608,8 +2937,8 @@ let TAIL_SWAP_CASE_TAC case = ANTS_TAC THENL [ IMP_REWRITE_TAC[WORD_ZX_ZX] THEN REWRITE_TAC[DIMINDEX_8; DIMINDEX_32; DIMINDEX_64] THEN - MP_TAC (SPECL [case; `curr_len:num`; `tail_len:int64`; `PP:int128`; `ct:byte list`] - CIPHER_STEALING_INV_SELECT) THEN + MP_TAC (SPECL [case; `curr_len:num`; `tail_len:int64`; `CC:int128`; `pt:byte list`] + CIPHER_STEALING_ENC_INV_SELECT) THEN CONV_TAC NUM_REDUCE_CONV THEN ASM_SIMP_TAC[] ; ALL_TAC ] THEN @@ -2702,7 +3031,7 @@ let BREAK_DATA_INTO_PARTS = prove( (* Assembly proofs *) (* Proof: Cipher stealing *) -let CIPHER_STEALING_CORRECT = time prove( +let CIPHER_STEALING_ENC_CORRECT = time prove( `!ptxt_p ctxt_p len key1_p pt_in iv tail_len len_full_blocks num_5_blocks k1_0 k1_1 k1_2 k1_3 k1_4 k1_5 k1_6 k1_7 k1_8 k1_9 k1_10 k1_11 k1_12 k1_13 k1_14 @@ -2739,15 +3068,14 @@ let CIPHER_STEALING_CORRECT = time prove( (\s. read PC s = word (pc + LENGTH aes256_xts_encrypt_mc - 8*4) /\ byte_list_at (aes256_xts_encrypt pt_in (val len) iv key1_lst key2_lst) ctxt_p len s ) - ( MAYCHANGE [PC; X0; X1; X2; X4; X6; X7; X8; X9; X10; X11; X19; X20; X21; X22] ,, - MAYCHANGE [Q0; Q1; Q4; Q5; Q6; Q7; Q8; Q9; Q10; Q11; Q12; Q13; Q14; Q15; Q16; Q17; - Q18; Q19; Q20; Q21; Q22; Q23; Q24; Q25; Q26] ,, - MAYCHANGE [NF; ZF; CF; VF] ,, - MAYCHANGE [events] ,, + ( MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI,, + MAYCHANGE [X19; X20; X21; X22] ,, + MAYCHANGE [Q8; Q9; Q10; Q11; Q12; Q13; Q14; Q15] ,, MAYCHANGE [memory :> bytes (ctxt_p,val len)]) `, REWRITE_TAC [(REWRITE_CONV [aes256_xts_encrypt_mc] THENC LENGTH_CONV) `LENGTH aes256_xts_encrypt_mc`] THEN - REWRITE_TAC[byte_list_at; NONOVERLAPPING_CLAUSES; PAIRWISE; ALL] THEN + REWRITE_TAC[byte_list_at; NONOVERLAPPING_CLAUSES; PAIRWISE; ALL; + MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI] THEN REPEAT STRIP_TAC THEN (* Prove the bounds on len_full_blocks, num_5blocks and len and their relationships *) @@ -2824,7 +3152,7 @@ let CIPHER_STEALING_CORRECT = time prove( ANTS_TAC THENL [ ASM_SIMP_TAC[]; ALL_TAC] THEN ANTS_TAC THENL [ ASM_ARITH_TAC; ALL_TAC] THEN SIMP_TAC[]; ALL_TAC] THEN - POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th])) THEN + POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th])) THEN (* Prove that acc_len is equal to total len because there is no tail *) SUBGOAL_THEN `val (len:int64) = @@ -2845,25 +3173,144 @@ let CIPHER_STEALING_CORRECT = time prove( [ ASM_SIMP_TAC[]; ASM_SIMP_TAC[]; - - UNDISCH_TAC `~(val (num_5blocks:int64) * 0x50 + 0x10 = val (len_full_blocks:int64))` THEN - ARITH_TAC; - - UNDISCH_TAC `~(val (num_5blocks:int64) * 0x50 + 0x20 = val (len_full_blocks:int64))` THEN - ARITH_TAC; - - UNDISCH_TAC `~(val (num_5blocks:int64) * 0x50 + 0x30 = val (len_full_blocks:int64))` THEN - ARITH_TAC; - - UNDISCH_TAC `~(val (num_5blocks:int64) * 0x50 + 0x40 = val (len_full_blocks:int64))` THEN - ARITH_TAC] + UNDISCH_TAC `~(val (num_5blocks:int64) * 0x50 + 0x10 = val (len_full_blocks:int64))` THEN ARITH_TAC; + UNDISCH_TAC `~(val (num_5blocks:int64) * 0x50 + 0x20 = val (len_full_blocks:int64))` THEN ARITH_TAC; + UNDISCH_TAC `~(val (num_5blocks:int64) * 0x50 + 0x30 = val (len_full_blocks:int64))` THEN ARITH_TAC; + UNDISCH_TAC `~(val (num_5blocks:int64) * 0x50 + 0x40 = val (len_full_blocks:int64))` THEN ARITH_TAC ] ; ALL_TAC] THEN ASM_SIMP_TAC[] ; ALL_TAC ] THEN - ] + (* The cipher stealing branch *) + (* Break the rest of the program into two parts: before byte-swap and after. + This is because byte-swap needs another invariant proof. *) + ABBREV_TAC `curr_len = (acc_len (num_5blocks:int64) (len_full_blocks:int64)):num` THEN + ABBREV_TAC `curr_blocks = (acc_blocks (num_5blocks:int64) (len_full_blocks:int64) T):num` THEN + + SUBGOAL_THEN `curr_len <= val (len:int64)` ASSUME_TAC THENL (* differs from decrypt *) + [ EXPAND_TAC "curr_len" THEN + MP_TAC (SPECL [`num_5blocks:int64`; `len_full_blocks:int64`] VALUE_OF_ACC_LEN) THEN + REPEAT_N 3 (ANTS_TAC THENL [ASM_ARITH_TAC ORELSE ASM_SIMP_TAC[]; ALL_TAC]) THEN + SIMP_TAC[] THEN DISCH_TAC THEN + ASM_SIMP_TAC[]; ALL_TAC ] THEN + + SUBGOAL_THEN `val ((word curr_len):int64) = curr_len` ASSUME_TAC THENL + [ IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN + EXPAND_TAC "curr_len" THEN + MP_TAC (SPECL [`num_5blocks:int64`; `len_full_blocks:int64`; `2 EXP 64`] + BOUND_OF_ACC_LEN) THEN + REPEAT_N 4 (ANTS_TAC THENL [ASM_ARITH_TAC ORELSE ASM_SIMP_TAC[]; ALL_TAC]) THEN + SIMP_TAC[]; ALL_TAC] THEN + + ABBREV_TAC `CC = aes256_xts_encrypt_round + (bytes_to_int128 (SUB_LIST (curr_len-0x10,0x10) (pt_in:byte list))) + (calculate_tweak (curr_blocks) (iv:int128) (key2_lst:int128 list)) + (key1_lst:int128 list)` THEN + + (* Invariant proof for .composite_enc_loop *) + (* Invariant: + X0 points to tail of pt_in; Pm in specs + X1 points to starting of last full block of ct_out; CC + X13 points to tail of ct_out; will become Cm at the end of the loop + X20 = X0, points to tail of pt_in; Pm + X21 holds decreasing tail_len + Q6 holds last tweak + Q16 ... Q7 holds the key schedule for encryption + + Memory: ptxt_p points to the input + Memory: Up to the last block, the output pointed to by ctxt_p matches the specification + Memory: X13 points to tail location in the output, to which Cm is copyied byte by byte from where X1 points + Memory: X1 (= X13 - 0x10) points to CC = [Cm | CP] will become PP = [Pm | CP] by copying Pm one byte at a time to override Cm + Loop: bytes are copied in decreasing addresses, i.e. X21 is an offset to both X1 and X13 + decreasing from "tail" down to 0. The iterator i is the value of X21. + Memory: For the last block, CC, pointed to by X1, for each byte + [0,i) -- previous decryption result, Cm + [i,tail_len) -- equal corresponding pt_in tail bytes, Pm + [tail_len,16] -- previous decryption result, CP + Memory: For the tail, Cm, pointed to by X13, for each byte + [i,tail_len) -- copied over from Pm block + *) + +ENSURES_WHILE_PADOWN_TAC + `val (tail_len:int64)` (* counter begin number *) + `0` (* counter end number *) + `pc + 0x9f4` (* loop body start PC *) + `pc + 0xa08` (* loop backedge branch PC *) + `\i s. + // loop invariant at the end of the loop iteration + ( read X0 s = word_add ptxt_p (word curr_len) /\ + read X1 s = word_sub (word_add ctxt_p (word curr_len)) (word 0x10) /\ + read X13 s = word_add ctxt_p (word curr_len) /\ + read X20 s = word_add ptxt_p (word curr_len) /\ + read X21 s = (word i):int64 /\ + read Q6 s = calculate_tweak curr_blocks iv key2_lst /\ + read Q16 s = k1_0 /\ read Q17 s = k1_1 /\ read Q12 s = k1_2 /\ read Q13 s = k1_3 /\ + read Q14 s = k1_4 /\ read Q15 s = k1_5 /\ read Q4 s = k1_6 /\ read Q5 s = k1_7 /\ + read Q18 s = k1_8 /\ read Q19 s = k1_9 /\ read Q20 s = k1_10 /\ read Q21 s = k1_11 /\ + read Q22 s = k1_12 /\ read Q23 s = k1_13 /\ read Q7 s = k1_14 /\ + byte_list_at pt_in ptxt_p len s /\ + byte_list_at (aes256_xts_encrypt pt_in curr_len iv key1_lst key2_lst) + ctxt_p (word curr_len) s /\ + // Contents of CC at each i + read (memory :> bytes128 (word_sub (word_add ctxt_p (word curr_len)) (word 0x10))) s = + cipher_stealing_enc_inv i curr_len (val (tail_len:int64)) CC pt_in /\ + + // bytes of Cm at offset i to (tail_len -i) in CC + // are stored at their final location in ciphertext in the tail part + // they're copied from CC before they're overwritten by bytes from Pm + byte_list_at (SUB_LIST (i, val tail_len - i) (int128_to_bytes CC)) + (word_add ctxt_p (word (curr_len + i))) + (word ((val tail_len) - i)) s) /\ + // loop backedge condition + (read ZF s <=> i = 0) /\ + (read NF s <=> ival ((word i):int64) < &0) /\ + (read VF s <=> ~(ival ((word (i + 1)):int64) - &1 = ival ((word i):int64)))` THEN + ASM_REWRITE_TAC[] THEN REPEAT CONJ_TAC THENL + [ + (* Subgoal1: 0 < val tail_len *) + ASM_ARITH_TAC; + + (* Subgoal2: invariant holds before entering loop *) + REWRITE_TAC[byte_list_at] THEN + UNDISCH_THEN `val ((word curr_len):int64) = curr_len` + (fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th]) THEN REWRITE_TAC[th]) THEN + + ENSURES_INIT_TAC "s0" THEN + ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (1--2) THEN + (* Discharge if condition *) + SUBGOAL_THEN `~(val (word_and (tail_len:int64) (word 0xf)) = 0x0)` MP_TAC THENL + [ UNDISCH_TAC `~(val (tail_len:int64) = 0x0)` THEN + UNDISCH_TAC `val (tail_len:int64) < 16` THEN + MP_TAC (SPEC `tail_len:int64` WORD_AND_MASK16_EQ_0) THEN + SIMP_TAC[]; ALL_TAC] THEN + ASM_REWRITE_TAC[] THEN DISCH_TAC THEN + POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th])) THEN + + ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (3--5) THEN + ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN + REPEAT CONJ_TAC THENL + [ + REWRITE_TAC[WORD_VAL]; + + REWRITE_TAC[cipher_stealing_enc_inv; SUB_REFL] THEN + SUBGOAL_THEN `SUB_LIST (val (tail_len:int64),0x0) (SUB_LIST (curr_len,val tail_len) (pt_in:byte list)) = []` SUBST1_TAC THENL + [ REWRITE_TAC[SUB_LIST_CLAUSES]; ALL_TAC] THEN + REWRITE_TAC[CONJUNCT1 APPEND] THEN + SUBGOAL_THEN `APPEND (SUB_LIST (0x0,val (tail_len:int64)) (int128_to_bytes CC)) + (SUB_LIST (val tail_len,0x10 - val tail_len) (int128_to_bytes CC)) = + (int128_to_bytes CC)` SUBST1_TAC THENL + [ MP_TAC (ISPECL [`int128_to_bytes CC`; `val (tail_len:int64)`; `16 - val (tail_len:int64)`; `0`] (GSYM SUB_LIST_SPLIT)) THEN + IMP_REWRITE_TAC[ADD_CLAUSES; ARITH_RULE `!x. x < 16 ==> x + 16 - x = 16`] THEN + DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES; LENGTH_OF_INT128_TO_BYTES] + ; ALL_TAC] THEN + REWRITE_TAC[BYTES_TO_INT128_OF_INT128_TO_BYTES]; + REWRITE_TAC[VAL_WORD_0] THEN ARITH_TAC; + ]; + + ] );; @@ -3121,7 +3568,7 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( `pc + 0x140` (* loop body start PC *) `pc + 0x430` (* loop backedge branch PC *) `\i s. - // loop invariant at the end of the loop + // loop invariant at the end of the loop iteration (read X0 s = word_add ptxt_p (word_mul (word 0x50) (word i)) /\ read X1 s = word_add ctxt_p (word_mul (word 0x50) (word i)) /\ read X21 s = tail_len /\ From be81ad313b2c8efdc6938062eba795ec26d49910 Mon Sep 17 00:00:00 2001 From: Nevine Ebeid Date: Mon, 10 Nov 2025 11:09:28 -0500 Subject: [PATCH 086/132] Cipher-stealing: case tail != 0, loop invariant subgoal 3: WIP. --- arm/proofs/aes-xts-armv8.ml | 79 +++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/arm/proofs/aes-xts-armv8.ml b/arm/proofs/aes-xts-armv8.ml index 37b63c32a..187601c10 100644 --- a/arm/proofs/aes-xts-armv8.ml +++ b/arm/proofs/aes-xts-armv8.ml @@ -3310,6 +3310,85 @@ ENSURES_WHILE_PADOWN_TAC REWRITE_TAC[VAL_WORD_0] THEN ARITH_TAC; ]; + (* Subgoal 3: inductive step *) + REPEAT STRIP_TAC THEN + + (* For non-overlapping and MAYCHANGE address reasoning *) + SUBGOAL_THEN `curr_len + i < val (len:int64)` ASSUME_TAC THENL + [ REWRITE_TAC[GSYM (ASSUME `acc_len num_5blocks len_full_blocks = curr_len`)] THEN + MP_TAC (SPECL [`num_5blocks:int64`; `len_full_blocks:int64`] VALUE_OF_ACC_LEN) THEN + REPEAT_N 3 (ANTS_TAC THENL [ASM_ARITH_TAC ORELSE ASM_SIMP_TAC[]; ALL_TAC]) THEN + SIMP_TAC[] THEN DISCH_TAC THEN + + UNDISCH_TAC `word_add (tail_len:int64) (len_full_blocks:int64) = len` THEN + UNDISCH_TAC `i < val (tail_len:int64)` THEN + + ONCE_REWRITE_TAC[GSYM VAL_EQ] THEN + REWRITE_TAC[VAL_WORD_ADD;DIMINDEX_64] THEN + IMP_REWRITE_TAC[MOD_LT] THEN + ASM_ARITH_TAC ; ALL_TAC ] THEN + + MATCH_MP_TAC ENSURES_FRAME_SUBSUMED THEN + EXISTS_TAC `MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI ,, + MAYCHANGE [X19; X20; X21; X22],, + MAYCHANGE [Q8; Q9; Q10; Q11; Q12; Q13; Q14; Q15],, + MAYCHANGE [memory :> bytes8 (word_add ctxt_p (word (curr_len - 0x10 + i)))],, + MAYCHANGE [memory :> bytes8 (word_add ctxt_p (word (curr_len + i)))]` THEN + REWRITE_TAC[MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI] THEN + CONJ_TAC THENL [ + REPEAT (GEN_REWRITE_TAC ONCE_DEPTH_CONV [GSYM SEQ_ASSOC] THEN + MATCH_MP_TAC SUBSUMED_SEQ THEN REWRITE_TAC[SUBSUMED_REFL]) THEN + ABBREV_TAC `vallen = val (len:int64)` THEN + SUBSUMED_MAYCHANGE_TAC; ALL_TAC] THEN + + REWRITE_TAC[byte_list_at] THEN + UNDISCH_THEN `val ((word curr_len):int64) = curr_len` + (fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th]) THEN REWRITE_TAC[th]) THEN + ENSURES_INIT_TAC "s0" THEN + + SUBGOAL_THEN `val ((word (val (tail_len:int64) - i)):int64) = val tail_len - i` SUBST_ALL_TAC THENL + [ IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN + UNDISCH_TAC `i < val (tail_len:int64)` THEN + UNDISCH_TAC `val (tail_len:int64) < 0x10` THEN + ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `val ((word (val (tail_len:int64) - (i + 0x1))):int64) = val tail_len - (i + 1)` SUBST_ALL_TAC THENL + [ IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN + UNDISCH_TAC `i < val (tail_len:int64)` THEN + UNDISCH_TAC `val (tail_len:int64) < 0x10` THEN + ARITH_TAC; ALL_TAC] THEN + + SUBGOAL_THEN `word_sub ((word (i + 0x1)):int64) (word 0x1) = word i` ASSUME_TAC THENL + [ REWRITE_TAC[GSYM VAL_EQ; VAL_WORD_SUB; DIMINDEX_64] THEN + MP_TAC (SPECL [`val ((word (i + 0x1)):int64)`; `0x2 EXP 0x40`; `val ((word 0x1):int64)`] + (ARITH_RULE `!a b c. c <= a ==> c <= b ==> a + b - c = (a - c) + b`)) THEN + ANTS_TAC THENL [ + IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN ASM_ARITH_TAC + ; ALL_TAC] THEN + ANTS_TAC THENL [ WORD_ARITH_TAC; ALL_TAC] THEN + SIMP_TAC[] THEN DISCH_TAC THEN + MP_TAC (SPECL [`1`; `0x2 EXP 0x40`; `val ((word (i + 0x1)):int64) - val ((word 0x1):int64)`] + (CONJUNCT1 (CONJUNCT2 (CONJUNCT2 MOD_MULT_ADD)))) THEN + SIMP_TAC[ARITH_RULE `!x. 1 * x = x`] THEN DISCH_TAC THEN + IMP_REWRITE_TAC[MOD_LT] THEN + CONJ_TAC THENL + [ SUBGOAL_THEN `i + 1 < 2 EXP 64` MP_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN + IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN + ARITH_TAC; + UNDISCH_TAC `i < val (tail_len:int64)` THEN + UNDISCH_TAC `val (tail_len:int64) < 0x10` THEN + WORD_ARITH_TAC] + ; ALL_TAC] THEN + + CHANGED_TAC (RULE_ASSUM_TAC(REWRITE_RULE + [WORD_RULE `!base m n. (word m) >= (word 0x10) => word_add (word_add base (word_sub (word m)(word 0x10))) (word n) = + word_add base (word(m - 0x10 + n))`])) THEN + + ASSUME_TAC (WORD_ARITH + `(word_add (word_add ctxt_p (word_sub (word curr_len) (word 0x10))) (word i)) = + word_add ctxt_p (word (curr_len - 0x10 + i))`) THEN + + + ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (1--3) THEN ] );; From 07ac140030b74fb99d3be213dfd86ccc401a258b Mon Sep 17 00:00:00 2001 From: Nevine Ebeid Date: Mon, 10 Nov 2025 18:27:07 -0500 Subject: [PATCH 087/132] Cipher-stealing: case tail != 0, loop invariant back to subgoal 2: WIP. --- arm/proofs/aes-xts-armv8.ml | 49 +++++++++++++++++++++++-------------- 1 file changed, 31 insertions(+), 18 deletions(-) diff --git a/arm/proofs/aes-xts-armv8.ml b/arm/proofs/aes-xts-armv8.ml index 187601c10..6a5dfda75 100644 --- a/arm/proofs/aes-xts-armv8.ml +++ b/arm/proofs/aes-xts-armv8.ml @@ -4,13 +4,14 @@ *) use_file_raise_failure := true;; -arm_print_log := true;; -components_print_log := true;; needs "arm/proofs/base.ml";; needs "arm/proofs/aes_encrypt_spec.ml";; needs "arm/proofs/aes_xts_encrypt_spec.ml";; +arm_print_log := true;; +components_print_log := true;; + (* print_literal_from_elf "arm/aes-xts/aes-xts-armv8.o";; *) (* save_literal_from_elf "arm/aes-xts/aes-xts-armv8.txt" "arm/aes-xts/aes-xts-armv8.o";; *) @@ -2887,6 +2888,7 @@ let CIPHER_STEALING_ENC_INV_SIMP_TAC i = IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN ASM_ARITH_TAC);; +(* TODO: change to match encrypt *) let TAIL_SWAP_CASE_TAC case = let c_tm = `case:num` in let v_tm = `v:num` in @@ -3091,10 +3093,6 @@ let CIPHER_STEALING_ENC_CORRECT = time prove( UNDISCH_TAC `word_and len (word 0xfffffffffffffff0) = (len_full_blocks:int64)` THEN MP_TAC (SPECL [`len:int64`; `len_full_blocks:int64`] LEN_FULL_BLOCKS_HI_BOUND_THM) THEN SIMP_TAC[]; ALL_TAC] THEN - (* - SUBGOAL_THEN `~(val (len_full_blocks:int64) < 0)` ASSUME_TAC THENL - [ UNDISCH_TAC `~(val (len_full_blocks:int64) < 0x10)` THEN - *) SUBGOAL_THEN `val (tail_len:int64) < 16` ASSUME_TAC THENL [ EXPAND_TAC "tail_len" THEN @@ -3183,8 +3181,7 @@ let CIPHER_STEALING_ENC_CORRECT = time prove( ] THEN (* The cipher stealing branch *) - (* Break the rest of the program into two parts: before byte-swap and after. - This is because byte-swap needs another invariant proof. *) + (* The byte-swap needs another invariant proof. *) ABBREV_TAC `curr_len = (acc_len (num_5blocks:int64) (len_full_blocks:int64)):num` THEN ABBREV_TAC `curr_blocks = (acc_blocks (num_5blocks:int64) (len_full_blocks:int64) T):num` THEN @@ -3305,7 +3302,7 @@ ENSURES_WHILE_PADOWN_TAC DISCH_TAC THEN IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES; LENGTH_OF_INT128_TO_BYTES] ; ALL_TAC] THEN - REWRITE_TAC[BYTES_TO_INT128_OF_INT128_TO_BYTES]; + REWRITE_TAC[BYTES_TO_INT128_OF_INT128_TO_BYTES] THEN REWRITE_TAC[VAL_WORD_0] THEN ARITH_TAC; ]; @@ -3328,6 +3325,27 @@ ENSURES_WHILE_PADOWN_TAC IMP_REWRITE_TAC[MOD_LT] THEN ASM_ARITH_TAC ; ALL_TAC ] THEN + + SUBGOAL_THEN `curr_len >= 16` ASSUME_TAC THENL + [ + REWRITE_TAC[GSYM (ASSUME `acc_len num_5blocks len_full_blocks = curr_len`)] THEN + MP_TAC (SPECL [`num_5blocks:int64`; `len_full_blocks:int64`] VALUE_OF_ACC_LEN) THEN + REPEAT_N 3 (ANTS_TAC THENL [ASM_ARITH_TAC ORELSE ASM_SIMP_TAC[]; ALL_TAC]) THEN + SIMP_TAC[] THEN DISCH_TAC THEN + UNDISCH_TAC `word_add (tail_len:int64) (len_full_blocks:int64) = len` THEN + ONCE_REWRITE_TAC[GSYM VAL_EQ] THEN + REWRITE_TAC[VAL_WORD_ADD;DIMINDEX_64] THEN + IMP_REWRITE_TAC[MOD_LT] THEN + ASM_ARITH_TAC; ALL TAC ] THEN + + SUBGOAL_THEN `(word_add (word_add (ctxt_p:int64) (word_sub (word curr_len) (word 0x10))) (word i)) = + word_add (ctxt_p:int64) (word (curr_len - 0x10 + i))` ASSUME_TAC THEN + REWRITE_TAC[GSYM WORD_ADD_ASSOC] THEN + AP_TERM_TAC THEN + REWRITE_TAC[WORD_ADD;WORD_SUB] THEN + ASM_ARITH_TAC THEN + + MATCH_MP_TAC ENSURES_FRAME_SUBSUMED THEN EXISTS_TAC `MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI ,, MAYCHANGE [X19; X20; X21; X22],, @@ -3379,16 +3397,11 @@ ENSURES_WHILE_PADOWN_TAC WORD_ARITH_TAC] ; ALL_TAC] THEN - CHANGED_TAC (RULE_ASSUM_TAC(REWRITE_RULE - [WORD_RULE `!base m n. (word m) >= (word 0x10) => word_add (word_add base (word_sub (word m)(word 0x10))) (word n) = - word_add base (word(m - 0x10 + n))`])) THEN - - ASSUME_TAC (WORD_ARITH - `(word_add (word_add ctxt_p (word_sub (word curr_len) (word 0x10))) (word i)) = - word_add ctxt_p (word (curr_len - 0x10 + i))`) THEN - ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (1--3) THEN + ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (1--5) THEN + ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN + REPEAT CONJ_TAC THENL ] );; @@ -5443,7 +5456,7 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( EXISTS_TAC `iv:int128` THEN EXISTS_TAC `key1_lst:int128 list` THEN EXISTS_TAC `key2_lst:int128 list` THEN EXISTS_TAC `pt_in:byte list` THEN REPEAT CONJ_TAC THENL [ - REFL_TAC THEN + REFL_TAC; MP_TAC (SPECL [`0x5 * val (num_5blocks:int64) + 0x1:num`; `pt_in:byte list`; `iv:int128`; `key1_lst:int128 list`; From e3930904c4dcf9e6bbd7b0ed234918140ad4d85f Mon Sep 17 00:00:00 2001 From: Nevine Ebeid Date: Fri, 14 Nov 2025 11:12:31 -0500 Subject: [PATCH 088/132] Cipher-stealing: case tail != 0, loop invariant subgoal 2: done. --- arm/proofs/aes-xts-armv8.ml | 147 +++++++++++++++++++++++++++++++++++- 1 file changed, 143 insertions(+), 4 deletions(-) diff --git a/arm/proofs/aes-xts-armv8.ml b/arm/proofs/aes-xts-armv8.ml index 6a5dfda75..64995340f 100644 --- a/arm/proofs/aes-xts-armv8.ml +++ b/arm/proofs/aes-xts-armv8.ml @@ -3200,9 +3200,29 @@ let CIPHER_STEALING_ENC_CORRECT = time prove( REPEAT_N 4 (ANTS_TAC THENL [ASM_ARITH_TAC ORELSE ASM_SIMP_TAC[]; ALL_TAC]) THEN SIMP_TAC[]; ALL_TAC] THEN + SUBGOAL_THEN `curr_len >= 16` ASSUME_TAC THENL + [ REWRITE_TAC[GSYM (ASSUME `acc_len num_5blocks len_full_blocks = curr_len`)] THEN + MP_TAC (SPECL [`num_5blocks:int64`; `len_full_blocks:int64`] VALUE_OF_ACC_LEN) THEN + REPEAT_N 3 (ANTS_TAC THENL [ASM_ARITH_TAC ORELSE ASM_SIMP_TAC[]; ALL_TAC]) THEN + SIMP_TAC[] THEN DISCH_TAC THEN + UNDISCH_TAC `word_add (tail_len:int64) (len_full_blocks:int64) = len` THEN + ONCE_REWRITE_TAC[GSYM VAL_EQ] THEN + REWRITE_TAC[VAL_WORD_ADD;DIMINDEX_64] THEN + IMP_REWRITE_TAC[MOD_LT] THEN + ASM_ARITH_TAC; ALL_TAC ] THEN + + SUBGOAL_THEN `16 * curr_blocks = curr_len` ASSUME_TAC THENL + [ REWRITE_TAC[GSYM (ASSUME `acc_len num_5blocks len_full_blocks = curr_len`)] THEN (* put in tips doc*) + (* or UNDISCH_THEN `acc_len (num_5blocks:int64) (len_full_blocks:int64) = curr_len` + (fun th -> REWRITE_TAC[GSYM th]) THEN *) + EXPAND_TAC "curr_blocks" THEN + REWRITE_TAC[acc_len; acc_blocks] THEN + REPEAT_N 4 (COND_CASES_TAC THENL [SIMP_TAC[] THEN ARITH_TAC; ALL_TAC] THEN SIMP_TAC[]) THEN + ARITH_TAC; ALL_TAC ] THEN + ABBREV_TAC `CC = aes256_xts_encrypt_round (bytes_to_int128 (SUB_LIST (curr_len-0x10,0x10) (pt_in:byte list))) - (calculate_tweak (curr_blocks) (iv:int128) (key2_lst:int128 list)) + (calculate_tweak (curr_blocks-0x1) (iv:int128) (key2_lst:int128 list)) (key1_lst:int128 list)` THEN (* Invariant proof for .composite_enc_loop *) @@ -3266,12 +3286,13 @@ ENSURES_WHILE_PADOWN_TAC ASM_REWRITE_TAC[] THEN REPEAT CONJ_TAC THENL [ (* Subgoal1: 0 < val tail_len *) - ASM_ARITH_TAC; + ASM_ARITH_TAC; (* 5 goals *) (* Subgoal2: invariant holds before entering loop *) REWRITE_TAC[byte_list_at] THEN UNDISCH_THEN `val ((word curr_len):int64) = curr_len` - (fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th]) THEN REWRITE_TAC[th]) THEN + (fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th]) THEN REWRITE_TAC[th] + THEN ASSUME_TAC th) THEN (* put in tips doc: keep the assumption *) ENSURES_INIT_TAC "s0" THEN ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (1--2) THEN @@ -3286,10 +3307,21 @@ ENSURES_WHILE_PADOWN_TAC ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (3--5) THEN ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN +(* +`tail_len = word (val tail_len) /\ + read (memory :> bytes128 (word_sub (word_add ctxt_p (word curr_len)) (word 0x10))) s5 + = cipher_stealing_enc_inv (val tail_len) curr_len (val tail_len) CC pt_in /\ + (forall i. + i < val (word 0x0) + ==> read (memory :> bytes8 (word_add (word_add ctxt_p (word (curr_len + val tail_len))) + (word i))) s5 + = EL i (SUB_LIST (val tail_len,0x0) (int128_to_bytes CC)))` *) (* 4 total *) REPEAT CONJ_TAC THENL [ REWRITE_TAC[WORD_VAL]; + (* `read (memory :> bytes128 (word_sub (word_add ctxt_p (word curr_len)) (word 0x10))) s5 + = cipher_stealing_enc_inv (val tail_len) curr_len (val tail_len) CC pt_in` *) REWRITE_TAC[cipher_stealing_enc_inv; SUB_REFL] THEN SUBGOAL_THEN `SUB_LIST (val (tail_len:int64),0x0) (SUB_LIST (curr_len,val tail_len) (pt_in:byte list)) = []` SUBST1_TAC THENL [ REWRITE_TAC[SUB_LIST_CLAUSES]; ALL_TAC] THEN @@ -3303,8 +3335,115 @@ ENSURES_WHILE_PADOWN_TAC IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES; LENGTH_OF_INT128_TO_BYTES] ; ALL_TAC] THEN REWRITE_TAC[BYTES_TO_INT128_OF_INT128_TO_BYTES] THEN + (* `read (memory :> bytes128 (word_sub (word_add ctxt_p (word curr_len)) (word 0x10))) s5 + = CC` *) + (* Apply READ_CT_LAST_LEMMA with proper arguments *) + MP_TAC (SPECL [`ctxt_p:int64`; `curr_len - 16:num`; `word curr_len:int64`; + `aes256_xts_encrypt pt_in curr_len iv key1_lst key2_lst:byte list`; `s5:armstate`] READ_CT_LAST_LEMMA) THEN + UNDISCH_THEN `val ((word curr_len):int64) = curr_len` + (fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th]) THEN REWRITE_TAC[th] THEN ASSUME_TAC th) THEN + ASM_SIMP_TAC[] THEN + (* `(curr_len - 0x10 + 0x10 <= curr_len /\ + LENGTH (aes256_xts_encrypt pt_in curr_len iv key1_lst key2_lst) = curr_len + ==> read (memory :> bytes128 (word_add ctxt_p (word (curr_len - 0x10)))) s5 = + bytes_to_int128 (SUB_LIST (curr_len - 0x10,0x10) + (aes256_xts_encrypt pt_in curr_len iv key1_lst key2_lst))) + ==> read (memory :> bytes128 (word_sub (word_add ctxt_p (word curr_len)) (word 0x10))) s5 + = CC` *) + ANTS_TAC THENL (* 6 total *) + [ CONJ_TAC THENL (* 7 total *) + [ UNDISCH_TAC `curr_len >= 0x10` THEN ARITH_TAC; + + (* `LENGTH (aes256_xts_encrypt pt_in curr_len iv key1_lst key2_lst) = curr_len`*) + REWRITE_TAC[GSYM (ASSUME `0x10 * curr_blocks = curr_len`); LENGTH_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS] ] + ; ALL_TAC ] THEN - REWRITE_TAC[VAL_WORD_0] THEN ARITH_TAC; + SUBGOAL_THEN `(word_sub (word_add (ctxt_p:int64) (word curr_len)) (word 0x10)) + = (word_add ctxt_p (word (curr_len - 0x10)))` SUBST1_TAC THENL + [ REWRITE_TAC[WORD_SUB] THEN + ASM_SIMP_TAC[ARITH_RULE `curr_len >= 0x10 ==> 0x10 <= curr_len`] THEN + WORD_ARITH_TAC + ; ALL_TAC] THEN + DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN + (* `bytes_to_int128 (SUB_LIST (curr_len - 0x10,0x10) + (aes256_xts_encrypt pt_in curr_len iv key1_lst key2_lst)) + = CC`. *) + (* Try proving the subgoal by expanding out aes256_xts_encrypt and then apply related LENGTH_OF_xxx and SUB_LIST_xxx lemmas *) + REWRITE_TAC[aes256_xts_encrypt] THEN + IMP_REWRITE_TAC[ARITH_RULE `curr_len >= 0x10 ==> ~(curr_len < 0x10)`] THEN + SUBGOAL_THEN `curr_len MOD 0x10 = 0` SUBST1_TAC THENL + [ REWRITE_TAC[GSYM (ASSUME `0x10 * curr_blocks = curr_len`); MOD_MULT] ; ALL_TAC ] THEN + CONV_TAC (DEPTH_CONV let_CONV) THEN + REWRITE_TAC[SUB_0] THEN + COND_CASES_TAC THENL + [ (* curr_len DIV 0x10 < 0x2 *) + EXPAND_TAC "CC" THEN + MP_TAC (SPECL [`0:num`; `0x0:num`; `pt_in:byte list`; `iv:int128`; + `key1_lst:int128 list`; `key2_lst:int128 list`] + LENGTH_OF_AES256_XTS_ENCRYPT_TAIL) THEN + CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC THEN + + SUBGOAL_THEN `curr_len = 0x10` ASSUME_TAC THENL + [ UNDISCH_TAC `curr_len >= 0x10` THEN + UNDISCH_TAC `curr_len DIV 0x10 < 0x2` THEN + REWRITE_TAC[GSYM (ASSUME `0x10 * curr_blocks = curr_len`)] THEN + SIMP_TAC[ARITH_RULE `(0x10 * curr_blocks) DIV 0x10 = curr_blocks`] THEN + (* or SIMP_TAC[DIV_MULT; ARITH] THEN *) + ARITH_TAC + ; ALL_TAC ] THEN + REWRITE_TAC[ASSUME `curr_len = 0x10`; SUB_REFL] THEN + + SUBGOAL_THEN `curr_blocks = 0x1` ASSUME_TAC THENL + [ UNDISCH_TAC `0x10 * curr_blocks = curr_len` THEN + REWRITE_TAC[ASSUME `curr_len = 0x10`] THEN + ARITH_TAC + ; ALL_TAC ] THEN + REWRITE_TAC[ASSUME `curr_blocks = 0x1`; SUB_REFL] THEN + + SIMP_TAC[ASSUME `LENGTH (aes256_xts_encrypt_tail 0x0 0x0 pt_in iv key1_lst key2_lst) = 0x10`; + SUB_LIST_LENGTH_IMPLIES] THEN + + REWRITE_TAC[AES256_XTS_ENCRYPT_TAIL_WHEN_1BLOCK] THEN + SIMPLE_ARITH_TAC + ; ALL_TAC ] THEN + + (* ~(curr_len DIV 0x10 < 0x2) *) + SUBGOAL_THEN `curr_blocks >= 2` ASSUME_TAC THENL + [ UNDISCH_TAC `~(curr_len DIV 0x10 < 0x2)` THEN + UNDISCH_TAC `0x10 * curr_blocks = curr_len` THEN + ARITH_TAC + ; ALL_TAC] THEN + SUBGOAL_THEN `curr_len DIV 0x10 = curr_blocks` ASSUME_TAC THENL + [ UNDISCH_TAC `0x10 * curr_blocks = curr_len` THEN + ARITH_TAC + ; ALL_TAC] THEN + POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th]) THEN REWRITE_TAC[th]) THEN + + MP_TAC (SPECL [`0`;`(curr_blocks - 2):num`; `pt_in:byte list`; `iv:int128`; + `key1_lst:int128 list`; `key2_lst:int128 list`] + LENGTH_OF_AES256_XTS_ENCRYPT_REC) THEN + ASM_SIMP_TAC[ARITH_RULE `curr_blocks >= 0x2 ==> ~(curr_blocks - 0x2 < 0x0)`] THEN + IMP_REWRITE_TAC[SUB_0; ARITH_RULE `curr_blocks >= 0x2 ==> curr_blocks - 2 + 1 = curr_blocks -1`] THEN + IMP_REWRITE_TAC[ARITH_RULE `0x10 * curr_blocks = curr_len ==> (curr_blocks - 0x1) * 0x10 = curr_len - 0x10`] THEN + DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_APPEND_RIGHT_LEMMA] THEN + (* `bytes_to_int128 (SUB_LIST (0x0,0x10) (aes256_xts_encrypt_tail (curr_blocks - 0x1) 0x0 pt_in iv key1_lst key2_lst)) + = CC`*) + MP_TAC (SPECL [`(curr_blocks - 0x1):num`; `0x0:num`; `pt_in:byte list`; `iv:int128`; + `key1_lst:int128 list`; `key2_lst:int128 list`] + LENGTH_OF_AES256_XTS_ENCRYPT_TAIL) THEN + CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC THEN + ASM_SIMP_TAC[SUB_LIST_LENGTH_IMPLIES] THEN + REWRITE_TAC[AES256_XTS_ENCRYPT_TAIL_WHEN_1BLOCK] THEN + EXPAND_TAC "CC" THEN + IMP_REWRITE_TAC[ARITH_RULE `0x10 * curr_blocks = curr_len ==> (curr_blocks - 0x1) * 0x10 = curr_len - 0x10`]; + + (* `forall i. + i < val (word 0x0) + ==> read (memory :> bytes8 (word_add (word_add ctxt_p (word (curr_len + val tail_len))) + (word i))) s5 + = EL i (SUB_LIST (val tail_len,0x0) (int128_to_bytes CC))`*) + REWRITE_TAC[VAL_WORD_0] THEN ARITH_TAC ]; (* Subgoal 3: inductive step *) From b573211eb9e5de5aa84a47cdd53fa00e70641016 Mon Sep 17 00:00:00 2001 From: Nevine Ebeid Date: Wed, 19 Nov 2025 17:43:23 -0500 Subject: [PATCH 089/132] Cipher-stealing: case tail != 0, loop invariant subgoal 3: symbolic simulation. --- arm/proofs/aes-xts-armv8.ml | 311 ++++++++++++++++++++++++++++++++++-- 1 file changed, 298 insertions(+), 13 deletions(-) diff --git a/arm/proofs/aes-xts-armv8.ml b/arm/proofs/aes-xts-armv8.ml index 64995340f..7dee0412b 100644 --- a/arm/proofs/aes-xts-armv8.ml +++ b/arm/proofs/aes-xts-armv8.ml @@ -2340,6 +2340,101 @@ let LEN_FULL_BLOCKS_TO_VAL = prove( CONV_TAC NUM_REDUCE_CONV );; +(* TODO: do I need NUM_BLOCKS_MINUS1_TO_VAL ? *) + +let BREAK_ONE_BLOCK_INTO_BYTES = prove( + `!(addr:int64) (s:armstate) (p:int128). + read (memory :> bytes128 addr) s = p <=> + (read (memory :> bytes8 addr) s = EL 0 (int128_to_bytes p) /\ + read (memory :> bytes8 (word_add addr (word 1))) s = EL 1 (int128_to_bytes p) /\ + read (memory :> bytes8 (word_add addr (word 2))) s = EL 2 (int128_to_bytes p) /\ + read (memory :> bytes8 (word_add addr (word 3))) s = EL 3 (int128_to_bytes p) /\ + read (memory :> bytes8 (word_add addr (word 4))) s = EL 4 (int128_to_bytes p) /\ + read (memory :> bytes8 (word_add addr (word 5))) s = EL 5 (int128_to_bytes p) /\ + read (memory :> bytes8 (word_add addr (word 6))) s = EL 6 (int128_to_bytes p) /\ + read (memory :> bytes8 (word_add addr (word 7))) s = EL 7 (int128_to_bytes p) /\ + read (memory :> bytes8 (word_add addr (word 8))) s = EL 8 (int128_to_bytes p) /\ + read (memory :> bytes8 (word_add addr (word 9))) s = EL 9 (int128_to_bytes p) /\ + read (memory :> bytes8 (word_add addr (word 10))) s = EL 10 (int128_to_bytes p) /\ + read (memory :> bytes8 (word_add addr (word 11))) s = EL 11 (int128_to_bytes p) /\ + read (memory :> bytes8 (word_add addr (word 12))) s = EL 12 (int128_to_bytes p) /\ + read (memory :> bytes8 (word_add addr (word 13))) s = EL 13 (int128_to_bytes p) /\ + read (memory :> bytes8 (word_add addr (word 14))) s = EL 14 (int128_to_bytes p) /\ + read (memory :> bytes8 (word_add addr (word 15))) s = EL 15 (int128_to_bytes p)) + `, + REPEAT GEN_TAC THEN + EQ_TAC THENL[ + STRIP_TAC THEN + MP_TAC (SPECL [`0:num`; `addr:int64`; `s:armstate`] BYTES128_TO_BYTES8_THM) THEN + REWRITE_TAC[WORD_ADD_0] THEN CONV_TAC NUM_REDUCE_CONV THEN + ASM_REWRITE_TAC[] THEN + DISCH_TAC THEN + REWRITE_TAC[int128_to_bytes] THEN + REWRITE_TAC EL_16_8_CLAUSES THEN + ASM_REWRITE_TAC[] THEN + REWRITE_TAC[bytes_to_int128] THEN + REWRITE_TAC EL_16_8_CLAUSES THEN + REWRITE_TAC[WORD_ADD_0] THEN + ABBREV_TAC `x0 = read (memory :> bytes8 (addr:int64)) s` THEN + ABBREV_TAC `x1 = read (memory :> bytes8 (word_add (addr:int64) (word 0x1))) s` THEN + ABBREV_TAC `x2 = read (memory :> bytes8 (word_add (addr:int64) (word 0x2))) s` THEN + ABBREV_TAC `x3 = read (memory :> bytes8 (word_add (addr:int64) (word 0x3))) s` THEN + ABBREV_TAC `x4 = read (memory :> bytes8 (word_add (addr:int64) (word 0x4))) s` THEN + ABBREV_TAC `x5 = read (memory :> bytes8 (word_add (addr:int64) (word 0x5))) s` THEN + ABBREV_TAC `x6 = read (memory :> bytes8 (word_add (addr:int64) (word 0x6))) s` THEN + ABBREV_TAC `x7 = read (memory :> bytes8 (word_add (addr:int64) (word 0x7))) s` THEN + ABBREV_TAC `x8 = read (memory :> bytes8 (word_add (addr:int64) (word 0x8))) s` THEN + ABBREV_TAC `x9 = read (memory :> bytes8 (word_add (addr:int64) (word 0x9))) s` THEN + ABBREV_TAC `xa = read (memory :> bytes8 (word_add (addr:int64) (word 0xa))) s` THEN + ABBREV_TAC `xb = read (memory :> bytes8 (word_add (addr:int64) (word 0xb))) s` THEN + ABBREV_TAC `xc = read (memory :> bytes8 (word_add (addr:int64) (word 0xc))) s` THEN + ABBREV_TAC `xd = read (memory :> bytes8 (word_add (addr:int64) (word 0xd))) s` THEN + ABBREV_TAC `xe = read (memory :> bytes8 (word_add (addr:int64) (word 0xe))) s` THEN + ABBREV_TAC `xf = read (memory :> bytes8 (word_add (addr:int64) (word 0xf))) s` THEN + REPEAT STRIP_TAC THEN + REPEAT BITBLAST_TAC; ALL_TAC] THEN + + REPEAT STRIP_TAC THEN + MP_TAC (SPECL [`0:num`; `addr:int64`; `s:armstate`] BYTES128_TO_BYTES8_THM) THEN + CONV_TAC NUM_REDUCE_CONV THEN REWRITE_TAC[WORD_ADD_0] THEN + ASM_REWRITE_TAC[] THEN + DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN + REWRITE_TAC[int128_to_bytes] THEN + REWRITE_TAC EL_16_8_CLAUSES THEN + REWRITE_TAC[bytes_to_int128] THEN + REWRITE_TAC EL_16_8_CLAUSES THEN + BITBLAST_TAC +);; + +let SELECT_ONE_BYTE_FROM_BLOCK = prove( + `!(addr:int64) (off:int64) (s:armstate) (p:int128). + read (memory :> bytes128 addr) s = p ==> + val off < 16 ==> + read (memory :> bytes8 (word_add addr off)) s = EL (val off) (int128_to_bytes p)`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM (STRIP_ASSUME_TAC o + MATCH_MP (fst (EQ_IMP_RULE + (SPECL [`addr:int64`; `s:armstate`; `p:int128`] BREAK_ONE_BLOCK_INTO_BYTES)))) THEN + SUBGOAL_THEN `word_add addr (off:int64) = word_add addr (word (val off))` SUBST1_TAC THENL + [REWRITE_TAC[WORD_VAL]; ALL_TAC] THEN + UNDISCH_TAC `val (off:int64) < 16` THEN + SPEC_TAC (`val (off:int64)`, `n:num`) THEN + CONV_TAC EXPAND_CASES_CONV THEN + ASM_REWRITE_TAC[WORD_ADD_0] +);; + +let SELECT_ONE_BYTE_FROM_FORALL = prove( + `!(ptr:int64) (len:int64) (addr:int64) (bl:byte list) (s:armstate). + (forall j. j < val len ==> read (memory :> bytes8 (word_add ptr (word j))) s = EL j bl) ==> + val addr < val len ==> + LENGTH bl = val len ==> + read (memory :> bytes8 (word_add ptr addr)) s = EL (val addr) bl`, + REPEAT STRIP_TAC THEN + FIRST_X_ASSUM (MP_TAC o SPEC `val (addr:int64)`) THEN + ASM_REWRITE_TAC[] THEN + REWRITE_TAC[WORD_VAL] +);; + (* ********************************************************** *) (* Properties that we prove about the specification functions *) (* Similar to the Decrypt ones but specified for Encrypt *) @@ -3462,8 +3557,8 @@ ENSURES_WHILE_PADOWN_TAC ONCE_REWRITE_TAC[GSYM VAL_EQ] THEN REWRITE_TAC[VAL_WORD_ADD;DIMINDEX_64] THEN IMP_REWRITE_TAC[MOD_LT] THEN - ASM_ARITH_TAC ; ALL_TAC ] THEN - + ASM_ARITH_TAC + ; ALL_TAC ] THEN SUBGOAL_THEN `curr_len >= 16` ASSUME_TAC THENL [ @@ -3475,15 +3570,16 @@ ENSURES_WHILE_PADOWN_TAC ONCE_REWRITE_TAC[GSYM VAL_EQ] THEN REWRITE_TAC[VAL_WORD_ADD;DIMINDEX_64] THEN IMP_REWRITE_TAC[MOD_LT] THEN - ASM_ARITH_TAC; ALL TAC ] THEN + ASM_ARITH_TAC + ; ALL_TAC ] THEN SUBGOAL_THEN `(word_add (word_add (ctxt_p:int64) (word_sub (word curr_len) (word 0x10))) (word i)) = - word_add (ctxt_p:int64) (word (curr_len - 0x10 + i))` ASSUME_TAC THEN - REWRITE_TAC[GSYM WORD_ADD_ASSOC] THEN - AP_TERM_TAC THEN - REWRITE_TAC[WORD_ADD;WORD_SUB] THEN - ASM_ARITH_TAC THEN - + word_add (ctxt_p:int64) (word (curr_len - 0x10 + i))` ASSUME_TAC THENL + [ REWRITE_TAC[GSYM WORD_ADD_ASSOC] THEN + AP_TERM_TAC THEN + REWRITE_TAC[WORD_ADD;WORD_SUB] THEN + ASM_ARITH_TAC + ; ALL_TAC ] THEN MATCH_MP_TAC ENSURES_FRAME_SUBSUMED THEN EXISTS_TAC `MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI ,, @@ -3534,13 +3630,202 @@ ENSURES_WHILE_PADOWN_TAC UNDISCH_TAC `i < val (tail_len:int64)` THEN UNDISCH_TAC `val (tail_len:int64) < 0x10` THEN WORD_ARITH_TAC] - ; ALL_TAC] THEN + ; ALL_TAC ] THEN + (* The symbolic simulation does not capture the LDR/STR at a byte level with i as the iterator, because it doesn't + know which i. So the following steps are to break the cases for values of i *) + (* Read a byte from Cm (at location curr_len -16 + i into w15 *) + MP_TAC (SPECL [`(word_sub (word_add ctxt_p (word curr_len)) (word 0x10)):int64`; `word i:int64`; `s0:armstate`; + `(cipher_stealing_enc_inv (i + 0x1) curr_len (val (tail_len:int64)) CC pt_in):int128`] + SELECT_ONE_BYTE_FROM_BLOCK) THEN - ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (1--5) THEN - ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN - REPEAT CONJ_TAC THENL + SUBGOAL_THEN `val ((word i):int64) < 0x10` ASSUME_TAC THENL + [ UNDISCH_TAC `i < val (tail_len:int64)` THEN + UNDISCH_TAC `val (tail_len:int64) < 0x10` THEN + WORD_ARITH_TAC; ALL_TAC ] THEN + ASM_SIMP_TAC[] THEN + REPEAT STRIP_TAC THEN + (* Added assumption + 65 [`read (memory :> bytes8 (word_add (word_sub (word_add ctxt_p (word curr_len)) (word 0x10)) + (word i))) s0 + = EL (val (word i)) + (int128_to_bytes (cipher_stealing_enc_inv (i + 0x1) curr_len (val tail_len) CC pt_in))` *) + + (* Read a byte from Pm at location curr_len + i into w14 *) + MP_TAC (SPECL [`ptxt_p:int64`; `len:int64`; `(word_add (word curr_len) (word i)):int64`; + `pt_in:byte list`; `s0:armstate`] SELECT_ONE_BYTE_FROM_FORALL) THEN + SUBGOAL_THEN `val (word_add ((word curr_len):int64) (word i)) < val (len:int64)` ASSUME_TAC THENL + [ REWRITE_TAC[WORD_RULE `!a b. word_add ((word a):int64) (word b) = word (a + b)`] THEN + IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN + ASM_ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[] THEN + STRIP_TAC THEN + (* Added assumption + 67 [`read (memory :> bytes8 (word_add ptxt_p (word_add (word curr_len) (word i)))) s0 + = EL (val (word_add (word curr_len) (word i))) pt_in`]*) + + (* Break the `read (memory :> bytes128 (word_sub (word_add ctxt_p (word curr_len)) (word 0x10))) s0 + into bytes using BREAK_ONE_BLOCK_INTO_BYTES *) + MP_TAC (SPECL [`(word_sub (word_add ctxt_p (word curr_len)) (word 0x10)):int64`; `s0:armstate`; + `(cipher_stealing_enc_inv (i + 0x1) curr_len (val (tail_len:int64)) CC pt_in):int128`] + BREAK_ONE_BLOCK_INTO_BYTES) THEN + ASM_SIMP_TAC[] THEN REPEAT STRIP_TAC THEN + + (* For address matching when symbolic simulation *) + SUBGOAL_THEN `word_add (ptxt_p:int64) (word_add (word curr_len) (word i)) = + word_add ptxt_p (word (curr_len + i))` SUBST_ALL_TAC THENL + [ REWRITE_TAC[WORD_RULE `!a b. word_add ((word a):int64) (word b) = word (a + b)`; ADD_ASSOC] + ; ALL_TAC] THEN + + SUBGOAL_THEN `word_add (word_sub (word_add (ctxt_p:int64) (word curr_len)) (word 0x10)) (word i) + = word_add ctxt_p (word (curr_len - 0x10 + i))` ASSUME_TAC THENL + [ UNDISCH_TAC `curr_len >= 0x10` THEN + SIMP_TAC[WORD_ADD; WORD_SUB; GE] THEN DISCH_TAC THEN + CONV_TAC WORD_RULE + ; ALL_TAC ] THEN + POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th]) THEN ASSUME_TAC th) THEN + + SUBGOAL_THEN `val ((word i):int64) = i` MP_TAC THENL + [ IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN + ASM_ARITH_TAC + ; ALL_TAC] THEN + DISCH_THEN(RULE_ASSUM_TAC o REWRITE_RULE o CONJUNCTS) THEN + + SUBGOAL_THEN `word_sub ((word (curr_len:num)):int64) (word (0x10 - i)) + = word (curr_len - (0x10 - i))` ASSUME_TAC THENL + [ UNDISCH_TAC `curr_len >= 0x10` THEN + SIMP_TAC[WORD_SUB; GE] THEN + SIMP_TAC[ARITH_RULE `0x10 <= curr_len ==> (0x10 - i) <= curr_len`] + ; ALL_TAC ] THEN + SUBGOAL_THEN `curr_len - (0x10 - i) = curr_len - 0x10 + i` SUBST_ALL_TAC THENL + [ UNDISCH_TAC `curr_len >= 0x10` THEN + UNDISCH_TAC `i < 0x10` THEN ARITH_TAC + ; ALL_TAC ] THEN + + SUBGOAL_THEN `word_sub ((word (curr_len:num)):int64) (word 0xd) < (len:int64)` ASSUME_TAC THENL + word_add ctxt_p (iword E) + word_ult () () + [ + ; ALL_TAC ] THEN + + ASM_CASES_TAC `i:num = 3` THENL + [ + POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th]) THEN REWRITE_TAC[th]) THEN + (* Simplify so that symbolic execution could match up, but couldn't use + CONV_TAC NUM_REDUCE_CONV because of non-overlapping *) + + let v = rand (concl (NUM_RED_CONV (`0x10 - 0x3`))) in + let ith = ARITH_RULE (subst [v,`v:num`] `curr_len >= 0x10 ==> curr_len - 0x10 + 0x3 = curr_len - v`) in + let ith2 = ARITH_RULE (subst [v,`v:num`] `0x10 - 0x3 = v`) in + (* RULE_ASSUM_TAC(REWRITE_RULE[ith]) THEN // doesn't replace in assumptions *) + FIRST_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[MATCH_MP ith th; ith2])) THEN + (* 34 [`word_add (word_add ctxt_p (word_sub (word curr_len) (word 0x10))) (word 0x3) + = word_add ctxt_p (word (curr_len - 0xd))`] + 65 [`read (memory :> bytes8 (word_add ctxt_p (word (curr_len - 0xd)))) s0 = + = EL (val (word 0x3)) (int128_to_bytes (cipher_stealing_enc_inv (0x3 + 0x1) curr_len (val tail_len) CC pt_in))`] + 71 [`read (memory :> bytes8 (word_add (word_sub (word_add ctxt_p (word curr_len)) (word 0x10)) + (word 0x3))) s0 + = EL 0x3 (int128_to_bytes (cipher_stealing_enc_inv (0x3 + 0x1) curr_len (val tail_len) CC pt_in))`] + 88 [`read X14 s3 = + word_zx + (word_zx (EL (val (word_add (word curr_len) (word 0x3))) pt_in))`] + Info: assumption `read X15 s2 = + word_zx + (word_zx + (read + (memory :> bytes8 (word_add ctxt_p (word_sub (word curr_len) (word 0xd)))) + s1))` is erased, but it might have contained useful information + + let v = rand (concl (NUM_RED_CONV (`0x10 - 0x3`))) in + let vreplace = subst [v,`v:num`] in + SUBGOAL_THEN (vreplace`word_sub ((word (curr_len:num)):int64) (word v) = word (curr_len - v)`) ASSUME_TAC THENL + [ UNDISCH_TAC `curr_len >= 0x10` THEN + SIMP_TAC[WORD_SUB; GE; ARITH_RULE (vreplace`0x10 <= curr_len ==> 0xd <= curr_len`)] + ; ALL_TAC ] THEN + *) + + ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (1--3) THEN + ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (4--4) THEN + CHANGED_TAC(UNDISCH_THEN `word_sub ((word curr_len):int64) (word 0xd) = word (curr_len - 0xd)` + (fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th]) THEN ASSUME_TAC th)) THEN + ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (5--5) THEN + (* Stepping to state s5 +Instruction at `pc + 2564 (0xa04)`: `arm_STRB W14 X1 (Register_Offset X21)` +Info: assumption `forall i. + i < curr_len + ==> read (memory :> bytes8 (word_add ctxt_p (word i))) s4 = + EL i (aes256_xts_encrypt pt_in curr_len iv key1_lst key2_lst)` is erased. +- Reason: NONOVERLAPPING_RULE: could not prove one of: + * `nonoverlapping (word_add ctxt_p (word _375691),0x1) +(word_add ctxt_p (word_sub (word curr_len) (word 0xd)),0x1)` +Info: assumption `read +(memory :> bytes128 (word_sub (word_add ctxt_p (word curr_len)) (word 0x10))) +s4 = +cipher_stealing_enc_inv (0x3 + 0x1) curr_len (val tail_len) CC pt_in` is erased. +- Reason: NONOVERLAPPING_RULE: could not prove one of: + * `nonoverlapping (word_sub (word_add ctxt_p (word curr_len)) (word 0x10),0x10) +(word_add ctxt_p (word_sub (word curr_len) (word 0xd)),0x1)` +Info: assumption `read (memory :> bytes8 (word_add ctxt_p (word (curr_len - 0xd)))) s4 = +EL 0x3 +(int128_to_bytes +(cipher_stealing_enc_inv (0x3 + 0x1) curr_len (val tail_len) CC pt_in))` is erased. +- Reason: NONOVERLAPPING_RULE: could not prove one of: + * `nonoverlapping (word_add ctxt_p (word (curr_len - 0xd)),0x1) +(word_add ctxt_p (word_sub (word curr_len) (word 0xd)),0x1)` +Info: assumption `read +(memory :> + bytes8 + (word_add (word_sub (word_add ctxt_p (word curr_len)) (word 0x10)) + (word 0x3))) +s4 = +EL 0x3 +(int128_to_bytes +(cipher_stealing_enc_inv (0x3 + 0x1) curr_len (val tail_len) CC pt_in))` is erased. +- Reason: NONOVERLAPPING_RULE: could not prove one of: + * `nonoverlapping +(word_add (word_sub (word_add ctxt_p (word curr_len)) (word 0x10)) (word 0x3), 0x1) +(word_add ctxt_p (word_sub (word curr_len) (word 0xd)),0x1)` + +ABBREV_TAC `short_len = curr_len - 0x10` +SUBGOAL_THEN `curr_len = short_len + 0x10` SUBST_ALL_TAC THENL +[EXPAND_TAC “short_len” THEN ARITH_TAC; ALL_TAC] + *) + + + ; ALL_TAC] + + (* case analysis based on i = 0 ... 14, because symbolic execution + needs to know which byte is being overwritten in pt_ptr to properly update the state. *) + MAP_EVERY (fun i -> TAIL_SWAP_ASM_CASES_TAC (mk_numeral (num i))) (0--14) THEN + UNDISCH_TAC `15 <= i` THEN + UNDISCH_TAC `i < val (tail_len:int64)` THEN + UNDISCH_TAC `val (tail_len:int64) < 16` THEN + ARITH_TAC; + + + ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (1--2) THEN + ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN (* 3 total *) + (* `((forall i. + i < curr_len + ==> read (memory :> bytes8 (word_add ctxt_p (word i))) s5 + = EL i (aes256_xts_encrypt pt_in curr_len iv key1_lst key2_lst)) /\ + read (memory :> bytes128 (word_sub (word_add ctxt_p (word curr_len)) (word 0x10))) s5 + = cipher_stealing_enc_inv i curr_len (val tail_len) CC pt_in /\ + (forall i'. + i' < val tail_len - i + ==> read (memory :> bytes8 (word_add (word_add ctxt_p (word (curr_len + i))) (word i'))) s5 + = EL i' (SUB_LIST (i,val tail_len - i) (int128_to_bytes CC))) /\ + (val (word i) = 0x0 <=> i = 0x0)) /\ + ((MAYCHANGE [PC] ,, ...) s0 s5` + *) + REPEAT CONJ_TAC THENL (* 5 subgoals (7 total) *) + [ + (* `forall i. + i < curr_len + ==> read (memory :> bytes8 (word_add ctxt_p (word i))) s5 + = EL i (aes256_xts_encrypt pt_in curr_len iv key1_lst key2_lst)` *) + ] ] );; From 43de77e5f4cd904ed9fe3e44df360c3bc930d431 Mon Sep 17 00:00:00 2001 From: Nevine Ebeid Date: Fri, 21 Nov 2025 18:10:11 -0500 Subject: [PATCH 090/132] Cipher-stealing: case tail != 0, loop invariant subgoal 3: symbolic simulation completed. Went back to subgoal 2. --- arm/proofs/aes-xts-armv8.ml | 477 +++++++++++++++++++++++++++++++++--- 1 file changed, 445 insertions(+), 32 deletions(-) diff --git a/arm/proofs/aes-xts-armv8.ml b/arm/proofs/aes-xts-armv8.ml index 7dee0412b..142b78634 100644 --- a/arm/proofs/aes-xts-armv8.ml +++ b/arm/proofs/aes-xts-armv8.ml @@ -3171,7 +3171,7 @@ let CIPHER_STEALING_ENC_CORRECT = time prove( MAYCHANGE [memory :> bytes (ctxt_p,val len)]) `, REWRITE_TAC [(REWRITE_CONV [aes256_xts_encrypt_mc] THENC LENGTH_CONV) `LENGTH aes256_xts_encrypt_mc`] THEN - REWRITE_TAC[byte_list_at; NONOVERLAPPING_CLAUSES; PAIRWISE; ALL; + REWRITE_TAC[byte_list_at; PAIRWISE; ALL; MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI] THEN REPEAT STRIP_TAC THEN @@ -3362,10 +3362,10 @@ ENSURES_WHILE_PADOWN_TAC read Q18 s = k1_8 /\ read Q19 s = k1_9 /\ read Q20 s = k1_10 /\ read Q21 s = k1_11 /\ read Q22 s = k1_12 /\ read Q23 s = k1_13 /\ read Q7 s = k1_14 /\ byte_list_at pt_in ptxt_p len s /\ - byte_list_at (aes256_xts_encrypt pt_in curr_len iv key1_lst key2_lst) - ctxt_p (word curr_len) s /\ + byte_list_at (aes256_xts_encrypt pt_in (curr_len-0x10) iv key1_lst key2_lst) + ctxt_p (word (curr_len-0x10)) s /\ // Contents of CC at each i - read (memory :> bytes128 (word_sub (word_add ctxt_p (word curr_len)) (word 0x10))) s = + read (memory :> bytes128 (word_add ctxt_p (word (curr_len - 0x10)))) s = cipher_stealing_enc_inv i curr_len (val (tail_len:int64)) CC pt_in /\ // bytes of Cm at offset i to (tail_len -i) in CC @@ -3411,12 +3411,81 @@ ENSURES_WHILE_PADOWN_TAC ==> read (memory :> bytes8 (word_add (word_add ctxt_p (word (curr_len + val tail_len))) (word i))) s5 = EL i (SUB_LIST (val tail_len,0x0) (int128_to_bytes CC)))` *) (* 4 total *) - REPEAT CONJ_TAC THENL +(* + `tail_len = word (val tail_len) /\ + (forall i. + i < val (word (curr_len - 0x10)) + ==> read (memory :> bytes8 (word_add ctxt_p (word i))) s5 = + EL i (aes256_xts_encrypt pt_in (curr_len - 0x10) iv key1_lst key2_lst)) /\ + read (memory :> bytes128 (word_add ctxt_p (word (curr_len - 0x10)))) s5 = + cipher_stealing_enc_inv (val tail_len) curr_len (val tail_len) CC pt_in /\ + (forall i. + i < val (word 0x0) + ==> read (memory :> bytes8 (word_add (word_add ctxt_p (word (curr_len + val tail_len))) (word i))) + s5 = EL i (SUB_LIST (val tail_len,0x0) (int128_to_bytes CC)))` +*) + REPEAT CONJ_TAC THENL (* 4 subgoals (7 total) *) [ REWRITE_TAC[WORD_VAL]; + (*`forall i. + i < val (word (curr_len - 0x10)) + ==> read (memory :> bytes8 (word_add ctxt_p (word i))) s5 = + EL i + (aes256_xts_encrypt pt_in (curr_len - 0x10) iv key1_lst key2_lst)`. *) + UNDISCH_TAC + `forall i. + i < curr_len + ==> read (memory :> bytes8 (word_add ctxt_p (word i))) s5 = + EL i (aes256_xts_encrypt pt_in curr_len iv key1_lst key2_lst)` THEN + MP_TAC (SPECL [`curr_len:num`; `ctxt_p:int64`; + `(aes256_xts_encrypt pt_in curr_len iv key1_lst key2_lst):byte list`; + `s5:armstate`] BYTE_LIST_TO_NUM_THM) THEN + ANTS_TAC THENL [ + REWRITE_TAC[GSYM (ASSUME `0x10 * curr_blocks = curr_len`)] THEN + REWRITE_TAC[LENGTH_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS] THEN + ARITH_TAC; ALL_TAC] + DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN + + MP_TAC (SPECL [`(curr_len-0x10):num`; `ctxt_p:int64`; + `(aes256_xts_encrypt pt_in (curr_len-0x10) iv key1_lst key2_lst):byte list`; + `s5:armstate`] BYTE_LIST_TO_NUM_THM) THEN + ANTS_TAC THENL [ + REWRITE_TAC[GSYM (ASSUME `0x10 * curr_blocks = curr_len`)] THEN + REWRITE_TAC[ARITH_RULE `0x10 * curr_blocks - 0x10 = 0x10 * (curr_blocks - 0x1)`] THEN + REWRITE_TAC[LENGTH_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS] THEN + ARITH_TAC; ALL_TAC] + SUBGOAL_THEN `val ((word (curr_len - 0x10)):int64) = curr_len - 0x10` SUBST1_TAC THENL + [ UNDISCH_TAC `curr_len >= 0x10` THEN + IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN + UNDISCH_TAC `curr_len <= val (len:int64)` THEN + UNDISCH_TAC `val (len:int64) <= 0x2 EXP 0x18` THEN + ARITH_TAC ; ALL_TAC ] + DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN + + REWRITE_TAC[GSYM (ASSUME `0x10 * curr_blocks = curr_len`)] THEN + REWRITE_TAC[ARITH_RULE `0x10 * curr_blocks - 0x10 = 0x10 * (curr_blocks - 0x1)`] THEN + MP_TAC(SPECL [`curr_blocks:num`; `pt_in:byte list`; `iv:int128`; `key1_lst:int128 list`; `key2_lst:int128 list`] + LENGTH_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS) THEN + MP_TAC(SPECL [`curr_blocks-1:num`; `pt_in:byte list`; `iv:int128`; `key1_lst:int128 list`; `key2_lst:int128 list`] + LENGTH_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS) THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN + DISCH_TAC THEN DISCH_TAC THEN + (*`read (memory :> bytes (ctxt_p,curr_len)) s5 = + num_of_bytelist (aes256_xts_encrypt pt_in curr_len iv key1_lst key2_lst) + ==> read (memory :> bytes (ctxt_p,0x10 * (curr_blocks - 0x1))) s5 = + num_of_bytelist + (aes256_xts_encrypt pt_in (0x10 * (curr_blocks - 0x1)) iv key1_lst + key2_lst)` *) + + + (* `read (memory :> bytes128 (word_sub (word_add ctxt_p (word curr_len)) (word 0x10))) s5 - = cipher_stealing_enc_inv (val tail_len) curr_len (val tail_len) CC pt_in` *) + = cipher_stealing_enc_inv (val tail_len) curr_len (val tail_len) CC pt_in` + changed to + `read (memory :> bytes128 (word_add ctxt_p (word (curr_len - 0x10)))) s5 = + cipher_stealing_enc_inv (val tail_len) curr_len (val tail_len) CC pt_in` + *) REWRITE_TAC[cipher_stealing_enc_inv; SUB_REFL] THEN SUBGOAL_THEN `SUB_LIST (val (tail_len:int64),0x0) (SUB_LIST (curr_len,val tail_len) (pt_in:byte list)) = []` SUBST1_TAC THENL [ REWRITE_TAC[SUB_LIST_CLAUSES]; ALL_TAC] THEN @@ -3450,16 +3519,19 @@ ENSURES_WHILE_PADOWN_TAC [ UNDISCH_TAC `curr_len >= 0x10` THEN ARITH_TAC; (* `LENGTH (aes256_xts_encrypt pt_in curr_len iv key1_lst key2_lst) = curr_len`*) - REWRITE_TAC[GSYM (ASSUME `0x10 * curr_blocks = curr_len`); LENGTH_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS] ] - ; ALL_TAC ] THEN + REWRITE_TAC[GSYM (ASSUME `0x10 * curr_blocks = curr_len`); LENGTH_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS] + ] THEN + (* SUBGOAL_THEN `(word_sub (word_add (ctxt_p:int64) (word curr_len)) (word 0x10)) = (word_add ctxt_p (word (curr_len - 0x10)))` SUBST1_TAC THENL [ REWRITE_TAC[WORD_SUB] THEN ASM_SIMP_TAC[ARITH_RULE `curr_len >= 0x10 ==> 0x10 <= curr_len`] THEN WORD_ARITH_TAC ; ALL_TAC] THEN + *) DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN + (* `bytes_to_int128 (SUB_LIST (curr_len - 0x10,0x10) (aes256_xts_encrypt pt_in curr_len iv key1_lst key2_lst)) = CC`. *) @@ -3573,7 +3645,7 @@ ENSURES_WHILE_PADOWN_TAC ASM_ARITH_TAC ; ALL_TAC ] THEN - SUBGOAL_THEN `(word_add (word_add (ctxt_p:int64) (word_sub (word curr_len) (word 0x10))) (word i)) = + SUBGOAL_THEN `(word_add (word_add (ctxt_p:int64) (word (curr_len - 0x10))) (word i)) = word_add (ctxt_p:int64) (word (curr_len - 0x10 + i))` ASSUME_TAC THENL [ REWRITE_TAC[GSYM WORD_ADD_ASSOC] THEN AP_TERM_TAC THEN @@ -3636,7 +3708,7 @@ ENSURES_WHILE_PADOWN_TAC know which i. So the following steps are to break the cases for values of i *) (* Read a byte from Cm (at location curr_len -16 + i into w15 *) - MP_TAC (SPECL [`(word_sub (word_add ctxt_p (word curr_len)) (word 0x10)):int64`; `word i:int64`; `s0:armstate`; + MP_TAC (SPECL [`(word_add ctxt_p (word (curr_len - 0x10))):int64`; `word i:int64`; `s0:armstate`; `(cipher_stealing_enc_inv (i + 0x1) curr_len (val (tail_len:int64)) CC pt_in):int128`] SELECT_ONE_BYTE_FROM_BLOCK) THEN @@ -3667,7 +3739,7 @@ ENSURES_WHILE_PADOWN_TAC (* Break the `read (memory :> bytes128 (word_sub (word_add ctxt_p (word curr_len)) (word 0x10))) s0 into bytes using BREAK_ONE_BLOCK_INTO_BYTES *) - MP_TAC (SPECL [`(word_sub (word_add ctxt_p (word curr_len)) (word 0x10)):int64`; `s0:armstate`; + MP_TAC (SPECL [`(word_add ctxt_p (word (curr_len - 0x10))):int64`; `s0:armstate`; `(cipher_stealing_enc_inv (i + 0x1) curr_len (val (tail_len:int64)) CC pt_in):int128`] BREAK_ONE_BLOCK_INTO_BYTES) THEN ASM_SIMP_TAC[] THEN REPEAT STRIP_TAC THEN @@ -3678,12 +3750,9 @@ ENSURES_WHILE_PADOWN_TAC [ REWRITE_TAC[WORD_RULE `!a b. word_add ((word a):int64) (word b) = word (a + b)`; ADD_ASSOC] ; ALL_TAC] THEN - SUBGOAL_THEN `word_add (word_sub (word_add (ctxt_p:int64) (word curr_len)) (word 0x10)) (word i) + SUBGOAL_THEN `word_add (word_add (ctxt_p:int64) (word (curr_len - 0x10))) (word i) = word_add ctxt_p (word (curr_len - 0x10 + i))` ASSUME_TAC THENL - [ UNDISCH_TAC `curr_len >= 0x10` THEN - SIMP_TAC[WORD_ADD; WORD_SUB; GE] THEN DISCH_TAC THEN - CONV_TAC WORD_RULE - ; ALL_TAC ] THEN + [ CONV_TAC WORD_RULE; ALL_TAC ] THEN POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th]) THEN ASSUME_TAC th) THEN SUBGOAL_THEN `val ((word i):int64) = i` MP_TAC THENL @@ -3692,6 +3761,23 @@ ENSURES_WHILE_PADOWN_TAC ; ALL_TAC] THEN DISCH_THEN(RULE_ASSUM_TAC o REWRITE_RULE o CONJUNCTS) THEN + +(*** + SUBGOAL_THEN `word_sub ((word (curr_len:num)):int64) (word_sub (word 0x10) (word i)) + = word (curr_len - 0x10 + i)` ASSUME_TAC THENL + [ UNDISCH_TAC `curr_len >= 0x10` THEN + SIMP_TAC[GE; WORD_ADD; WORD_SUB; LT_IMP_LE] THEN + CONV_TAC WORD_RULE + ; ALL_TAC ] + + (* `word_add (word_sub (word_add (ctxt_p:int64) (word curr_len)) (word 0x10)) (word i) = *) + SUBGOAL_THEN `word_add (ctxt_p:int64) (word_sub (word curr_len) (word (0x10-i))) + = word_add ctxt_p (word (curr_len - 0x10 + i))` ASSUME_TAC THENL + [ UNDISCH_TAC `curr_len >= 0x10` THEN + ASM_SIMP_TAC[GE; WORD_ADD; WORD_SUB; LT_IMP_LE] + ; ALL_TAC ] THEN +*) + (* Will I need the following to have (0x10 - i) in the assumptions? SUBGOAL_THEN `word_sub ((word (curr_len:num)):int64) (word (0x10 - i)) = word (curr_len - (0x10 - i))` ASSUME_TAC THENL [ UNDISCH_TAC `curr_len >= 0x10` THEN @@ -3702,12 +3788,31 @@ ENSURES_WHILE_PADOWN_TAC [ UNDISCH_TAC `curr_len >= 0x10` THEN UNDISCH_TAC `i < 0x10` THEN ARITH_TAC ; ALL_TAC ] THEN + *) - SUBGOAL_THEN `word_sub ((word (curr_len:num)):int64) (word 0xd) < (len:int64)` ASSUME_TAC THENL - word_add ctxt_p (iword E) - word_ult () () - [ - ; ALL_TAC ] THEN + (* (word_add (word_add ctxt_p (word_sub (word curr_len) (word 0x10))) (word 0xi)))*) + + SUBGOAL_THEN `word_sub (word_add ctxt_p (word curr_len)) (word 0x10):int64 = + word_add ctxt_p (word(curr_len - 0x10))` SUBST_ALL_TAC THENL + [ RULE_ASSUM_TAC(REWRITE_RULE[GE]) THEN + ASM_SIMP_TAC[WORD_SUB] THEN CONV_TAC WORD_RULE; + (* From John, it put all addresses in the read memory assumptions in canonical form *) + CHANGED_TAC(RULE_ASSUM_TAC(CONV_RULE(ONCE_DEPTH_CONV NORMALIZE_RELATIVE_ADDRESS_CONV)))] THEN + + (*(* Is this needed for nonoverlapping machinery in symbolic simulation? *) + SUBGOAL_THEN `curr_len - 0x10 + i < val (len:int64)` ASSUME_TAC THENL + (* word_ult () () *) + [ UNDISCH_TAC `curr_len + i < val (len:int64)` THEN ARITH_TAC; ALL_TAC ] THEN *) + + (* Went back on this suggestion + (* l1_curr_len is curr_len less 1 block*) + ABBREV_TAC `l1_curr_len = curr_len - 0x10` THEN + SUBGOAL_THEN `curr_len - 0x10 = l1_curr_len` SUBST_ALL_TAC THENL + [ EXPAND_TAC "l1_curr_len" THEN REFL_TAC; ALL_TAC ] + SUBGOAL_THEN `curr_len = l1_curr_len + 0x10` SUBST_ALL_TAC THENL + [ EXPAND_TAC "l1_curr_len" THEN + UNDISCH_TAC `curr_len >= 0x10` THEN ARITH_TAC; ALL_TAC ] + *) ASM_CASES_TAC `i:num = 3` THENL [ @@ -3715,11 +3820,19 @@ ENSURES_WHILE_PADOWN_TAC (* Simplify so that symbolic execution could match up, but couldn't use CONV_TAC NUM_REDUCE_CONV because of non-overlapping *) + (* Went back on this suggestion + let v = rand (concl (NUM_RED_CONV (`0x10 + 0x3`))) in + let ith = ARITH_RULE (subst [v,`v:num`] `l1_curr_len + 0x10 + 0x3 = l1_curr_len + v`) in + let ith2 = ARITH_RULE (subst [v,`v:num`] `0x10 + 0x3 = v`) in + FIRST_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[MATCH_MP ith th; ith2])) THEN + *) +(*** let v = rand (concl (NUM_RED_CONV (`0x10 - 0x3`))) in let ith = ARITH_RULE (subst [v,`v:num`] `curr_len >= 0x10 ==> curr_len - 0x10 + 0x3 = curr_len - v`) in let ith2 = ARITH_RULE (subst [v,`v:num`] `0x10 - 0x3 = v`) in (* RULE_ASSUM_TAC(REWRITE_RULE[ith]) THEN // doesn't replace in assumptions *) FIRST_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[MATCH_MP ith th; ith2])) THEN +*) (* 34 [`word_add (word_add ctxt_p (word_sub (word curr_len) (word 0x10))) (word 0x3) = word_add ctxt_p (word (curr_len - 0xd))`] 65 [`read (memory :> bytes8 (word_add ctxt_p (word (curr_len - 0xd)))) s0 = @@ -3728,15 +3841,11 @@ ENSURES_WHILE_PADOWN_TAC (word 0x3))) s0 = EL 0x3 (int128_to_bytes (cipher_stealing_enc_inv (0x3 + 0x1) curr_len (val tail_len) CC pt_in))`] 88 [`read X14 s3 = - word_zx - (word_zx (EL (val (word_add (word curr_len) (word 0x3))) pt_in))`] + word_zx (word_zx (EL (val (word_add (word curr_len) (word 0x3))) pt_in))`] Info: assumption `read X15 s2 = - word_zx - (word_zx - (read - (memory :> bytes8 (word_add ctxt_p (word_sub (word curr_len) (word 0xd)))) - s1))` is erased, but it might have contained useful information - + word_zx (word_zx (read (memory :> bytes8 (word_add ctxt_p (word_sub (word curr_len) (word 0xd)))) + s1))` is erased, but it might have contained useful information *) + (* let v = rand (concl (NUM_RED_CONV (`0x10 - 0x3`))) in let vreplace = subst [v,`v:num`] in SUBGOAL_THEN (vreplace`word_sub ((word (curr_len:num)):int64) (word v) = word (curr_len - v)`) ASSUME_TAC THENL @@ -3745,12 +3854,50 @@ ENSURES_WHILE_PADOWN_TAC ; ALL_TAC ] THEN *) - ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (1--3) THEN + ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (1--2) THEN + ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (3--3) THEN + ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (4--4) THEN +(* 90 [`read (memory :> bytes8 (word_add ctxt_p (word (curr_len + 0x3)))) s4 = + word_zx + (word_zx + (word_zx + (word_zx + (EL 0x3 + (int128_to_bytes + (cipher_stealing_enc_inv 0x4 curr_len (val tail_len) CC pt_in))))))`]*) + + (* CHANGED_TAC(UNDISCH_THEN `word_sub ((word curr_len):int64) (word 0xd) = word (curr_len - 0xd)` (fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th]) THEN ASSUME_TAC th)) THEN + + SUBGOAL_THEN `curr_len - 0xd < val (len:int64)` ASSUME_TAC THENL + (* word_ult () () *) + [ UNDISCH_TAC `curr_len + 0x3 < val (len:int64)` THEN ARITH_TAC; ALL_TAC ] THEN + *) ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (5--5) THEN - (* Stepping to state s5 + (* + - Reason: NONOVERLAPPING_RULE: could not prove one of: + * `nonoverlapping +(word_add (word_sub (word_add ctxt_p (word curr_len)) (word 0x10)) (word 0x3), 0x1) +(word_add ctxt_p (word_sub (word curr_len) (word 0xd)),0x1)` + + 34 [`word_add (word_add ctxt_p (word_sub (word curr_len) (word 0x10))) + (word 0x3) = + word_add ctxt_p (word (curr_len - 0xd))`] + 35 [`word_sub (word (0x3 + 0x1)) (word 0x1) = word 0x3`] + 36 [`0x3 < 0x10`] + 37 [`val (word_add (word curr_len) (word 0x3)) < val len`] + 38 [`word_add (word_sub (word_add ctxt_p (word curr_len)) (word 0x10)) + (word 0x3) = + word_add ctxt_p (word (curr_len - 0xd))`] + 39 [`word_sub (word curr_len) (word_sub (word 0x10) (word 0x3)) = + word (curr_len - 0xd)`] + 40 [`word_add ctxt_p (word_sub (word curr_len) (word 0xd)) = + word_add ctxt_p (word (curr_len - 0xd))`] + 41 [`curr_len - 0xd < val len`] + + Stepping to state s5 Instruction at `pc + 2564 (0xa04)`: `arm_STRB W14 X1 (Register_Offset X21)` Info: assumption `forall i. i < curr_len @@ -3826,10 +3973,276 @@ SUBGOAL_THEN `curr_len = short_len + 0x10` SUBST_ALL_TAC THENL ==> read (memory :> bytes8 (word_add ctxt_p (word i))) s5 = EL i (aes256_xts_encrypt pt_in curr_len iv key1_lst key2_lst)` *) ] - ] );; +(* Proof: Less than 2 blocks *) +let AES_XTS_DECRYPT_LT_2BLOCK_CORRECT = time prove( + `!ptxt_p ctxt_p len key1_p key2_p iv_p + pt_in iv + k1_0 k1_1 k1_2 k1_3 k1_4 k1_5 k1_6 k1_7 k1_8 k1_9 k1_10 k1_11 k1_12 k1_13 k1_14 + k2_0 k2_1 k2_2 k2_3 k2_4 k2_5 k2_6 k2_7 k2_8 k2_9 k2_10 k2_11 k2_12 k2_13 k2_14 + pc. + PAIRWISE nonoverlapping + [(word pc, LENGTH aes256_xts_encrypt_mc); + (ptxt_p, val len); + (ctxt_p, val len); + (key1_p, 244); + (key2_p, 244)] /\ + val len >= 16 /\ val len < 0x20 /\ LENGTH pt_in = val len /\ + [k1_0; k1_1; k1_2; k1_3; k1_4; k1_5; k1_6; k1_7; k1_8; k1_9; k1_10; + k1_11; k1_12; k1_13; k1_14] = key1_lst /\ + [k2_0; k2_1; k2_2; k2_3; k2_4; k2_5; k2_6; k2_7; k2_8; k2_9; k2_10; + k2_11; k2_12; k2_13; k2_14] = key2_lst + ==> ensures arm + (\s. aligned_bytes_loaded s (word pc) aes256_xts_encrypt_mc /\ + read PC s = word (pc + 0x1c) /\ + C_ARGUMENTS [ptxt_p; ctxt_p; len; key1_p; key2_p; iv_p] s /\ + byte_list_at pt_in ptxt_p len s /\ + read(memory :> bytes128 iv_p) s = iv /\ + set_key_schedule s key1_p k1_0 k1_1 k1_2 k1_3 k1_4 k1_5 k1_6 k1_7 k1_8 k1_9 k1_10 k1_11 k1_12 k1_13 k1_14 /\ + set_key_schedule s key2_p k2_0 k2_1 k2_2 k2_3 k2_4 k2_5 k2_6 k2_7 k2_8 k2_9 k2_10 k2_11 k2_12 k2_13 k2_14) + (\s. read PC s = word (pc + LENGTH aes256_xts_encrypt_mc - 8*4) /\ + byte_list_at (aes256_xts_encrypt pt_in (val len) iv key1_lst key2_lst) ctxt_p len s + ) + (MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI,, + MAYCHANGE [X19; X20; X21; X22],, + MAYCHANGE [Q8; Q9; Q10; Q11; Q12; Q13; Q14; Q15],, + MAYCHANGE [memory :> bytes(pt_ptr, val len)]) + `, + REWRITE_TAC [(REWRITE_CONV [aes256_xts_encrypt_mc] THENC LENGTH_CONV) `LENGTH aes256_xts_encrypt_mc`] THEN + REWRITE_TAC[set_key_schedule; byte_list_at; C_ARGUMENTS; SOME_FLAGS; + NONOVERLAPPING_CLAUSES; PAIRWISE; ALL; + MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI] THEN + REPEAT STRIP_TAC THEN + + SUBGOAL_THEN `word_add (word_and len (word 0xf)) + (word_and len (word 0xfffffffffffffff0)) = len:int64` ASSUME_TAC THENL + [REWRITE_TAC[word_split_lemma]; ALL_TAC] THEN + ABBREV_TAC `len_full_blocks:int64 = word_and len (word 0xfffffffffffffff0)` THEN + ABBREV_TAC `tail_len:int64 = word_and len (word 0xf)` THEN + ABBREV_TAC `num_5blocks = (word (val (len_full_blocks:int64) DIV 0x50)):int64` THEN + + SUBGOAL_THEN `val (len_full_blocks:int64) = 16` ASSUME_TAC THENL + [ EXPAND_TAC "len_full_blocks" THEN + REWRITE_TAC[LEN_FULL_BLOCKS_TO_VAL] THEN + IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN + CONV_TAC NUM_REDUCE_CONV THEN + SUBGOAL_THEN `val (len:int64) DIV 16 = 1` SUBST1_TAC THENL + [ MATCH_MP_TAC(MESON[LE_ANTISYM] `m <= n /\ n <= m ==> m = n`) THEN + CONJ_TAC THENL [ ASM_ARITH_TAC; ASM_ARITH_TAC]; + ALL_TAC] THEN + ARITH_TAC; ALL_TAC] THEN + + (* Prove property until start of cipher stealing. *) + ENSURES_SEQUENCE_TAC `pc + 0x9e0` + `\s. + read X0 s = word_add ct_ptr (word (acc_len num_5blocks_adjusted len_full_blocks_adjusted)) /\ + read X1 s = word_add pt_ptr (word (acc_len num_5blocks_adjusted len_full_blocks_adjusted)) /\ + read X3 s = key1_ptr /\ + read X21 s = tail_len /\ + read Q6 s = calculate_tweak (acc_blocks num_5blocks_adjusted len_full_blocks_adjusted T) iv key2 /\ + read X19 s = word 0x87 /\ + read Q16 s = k00 /\ read Q17 s = k01 /\ read Q12 s = k02 /\ read Q13 s = k03 /\ + read Q14 s = k04 /\ read Q15 s = k05 /\ read Q4 s = k06 /\ read Q5 s = k07 /\ + read Q18 s = k08 /\ read Q19 s = k09 /\ read Q20 s = k0a /\ read Q21 s = k0b /\ + read Q22 s = k0c /\ read Q23 s = k0d /\ read Q7 s = k0e /\ + byte_list_at ct ct_ptr len s /\ + byte_list_at (aes256_xts_encrypt pt_in (acc_len num_5blocks len_full_blocks) iv key1_lst key2_lst) + ctxt_p (word (acc_len num_5blocks len_full_blocks)) s` THEN + CONJ_TAC THENL + [ + MATCH_MP_TAC ENSURES_FRAME_SUBSUMED THEN + EXISTS_TAC `MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI ,, + MAYCHANGE [X19; X20; X21; X22],, + MAYCHANGE [Q8; Q9; Q10; Q11; Q12; Q13; Q14; Q15],, + MAYCHANGE [memory :> bytes128 pt_ptr]` THEN + REWRITE_TAC[MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI] THEN + CONJ_TAC THENL [ + REPEAT (GEN_REWRITE_TAC ONCE_DEPTH_CONV [GSYM SEQ_ASSOC] THEN + MATCH_MP_TAC SUBSUMED_SEQ THEN REWRITE_TAC[SUBSUMED_REFL]) THEN + ABBREV_TAC `vallen = val (len:int64)` THEN + SUBSUMED_MAYCHANGE_TAC; ALL_TAC] THEN + + REWRITE_TAC[byte_list_at] THEN + ENSURES_INIT_TAC "s0" THEN + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (1--2) THEN + + (* Discharge if condition *) + SUBGOAL_THEN + `ival (word_sub (len:int64) (word 0x10)) < &0x0 + <=> ~(ival (len:int64) - &0x10 = ival (word_sub (len:int64) (word 0x10)))` MP_TAC THENL + [ MP_TAC (BITBLAST_RULE + `val (len:int64) >= 0x10 ==> val len < 0x20 ==> + ival (word_sub len (word 0x10)) >= &0x0`) THEN + ASM_REWRITE_TAC[] THEN + MP_TAC (BITBLAST_RULE + `val (len:int64) >= 0x10 ==> val len < 0x20 ==> + ival (len:int64) - &0x10 = ival (word_sub len (word 0x10))`) THEN + ASM_REWRITE_TAC[] THEN + ARITH_TAC; + ALL_TAC] THEN + ASM_REWRITE_TAC[] THEN DISCH_TAC THEN + POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th])) THEN + + MP_TAC (SPECL [`ct_ptr:int64`; `len:int64`; `ct:byte list`; `s2:armstate`] READ_LT_2BLOCK) THEN + ASM_SIMP_TAC[] THEN DISCH_TAC THEN + + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (3--69) THEN + (* Prove Q6 stores initial tweak *) + FIRST_X_ASSUM(MP_TAC o SPEC `(calculate_tweak 0 iv key2)` + o MATCH_MP (MESON[] `read Q6 s = a ==> !a'. a = a' ==> read Q6 s = a'`)) THEN + ANTS_TAC THENL + [ REWRITE_TAC[CONJUNCT1 calculate_tweak; xts_init_tweak] THEN + EXPAND_TAC "key2" THEN AESENC_TAC; DISCH_TAC] THEN + + (* Simulating until branch for len_full_blocks adjustment *) + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (70--89) THEN + + (* Case split on whether there is a tail *) + FIRST_X_ASSUM MP_TAC THEN + COND_CASES_TAC THENL + [ + DISCH_TAC THEN + + SUBGOAL_THEN `val (tail_len:int64) = 0` SUBST_ALL_TAC THENL + [ UNDISCH_TAC `val (word_and (tail_len:int64) (word 0xf)) = 0x0` THEN + MP_TAC (SPECL [`len:int64`; `tail_len:int64`] TAIL_LEN_BOUND_THM) THEN + ASM_SIMP_TAC[] THEN DISCH_TAC THEN + SUBGOAL_THEN `val (word_and (tail_len:int64) (word 15)) = val tail_len` SUBST1_TAC THENL + [ REWRITE_TAC[VAL_WORD_AND_MASK_WORD; ARITH_RULE `15 = 2 EXP 4 - 1`] THEN + CONV_TAC NUM_REDUCE_CONV THEN ASM_REWRITE_TAC[] THEN + IMP_REWRITE_TAC[MOD_LT]; + ALL_TAC] THEN + SIMP_TAC[]; ALL_TAC] THEN + CONV_TAC NUM_REDUCE_CONV THEN + + SUBGOAL_THEN `val (len_full_blocks_adjusted:int64) = 16` ASSUME_TAC THENL + [ EXPAND_TAC "len_full_blocks_adjusted" THEN + CONV_TAC NUM_REDUCE_CONV THEN + ASM_REWRITE_TAC[] + ; ALL_TAC ] THEN + SUBGOAL_THEN `val (num_5blocks_adjusted:int64) = 0` ASSUME_TAC THENL + [ EXPAND_TAC "num_5blocks_adjusted" THEN + UNDISCH_TAC `val (len_full_blocks_adjusted:int64) = 16` THEN + SIMP_TAC[] THEN DISCH_TAC THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[VAL_WORD_0] + ; ALL_TAC ] THEN + + TWEAK_TAC `Q8:(armstate,int128)component` `1:num` `0:num` THEN + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (90--126) THEN + XTSDEC_TAC `Q0:(armstate,int128)component` `0` `0` THEN + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (127--136) THEN + TWEAK_TAC `Q6:(armstate,int128)component` `1:num` `0:num` THEN + + ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN + REPEAT CONJ_TAC THENL + [ + ASM_REWRITE_TAC[acc_len] THEN CONV_TAC NUM_REDUCE_CONV; + ASM_REWRITE_TAC[acc_len] THEN CONV_TAC NUM_REDUCE_CONV; + ASM_REWRITE_TAC[acc_blocks] THEN CONV_TAC NUM_REDUCE_CONV; + + ASM_REWRITE_TAC[acc_len] THEN + CONV_TAC NUM_REDUCE_CONV THEN + IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN + CONV_TAC NUM_REDUCE_CONV THEN + MP_TAC (SPECL [`16:num`; `pt_ptr:int64`; `(aes256_xts_decrypt ct 16 iv key1 key2):byte list`; `s136:armstate`] BYTE_LIST_TO_NUM_THM) THEN + ANTS_TAC THENL[ + MP_TAC (SPECL [`1`; `ct:byte list`; `iv:int128`; + `key1:int128 list`; `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN + ARITH_TAC; ALL_TAC] THEN + DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN + ASM_REWRITE_TAC[] THEN + IMP_REWRITE_TAC[READ_BYTES_EQ_READ_BYTE128_1BLOCK] + ] + ; ALL_TAC] THEN + + (* There is a tail *) + DISCH_TAC THEN + (* Prove ~ tail_len = 0 *) + SUBGOAL_THEN `~(val (tail_len:int64) = 0)` ASSUME_TAC THENL + [ UNDISCH_TAC `~(val (word_and (tail_len:int64) (word 0xf)) = 0x0)` THEN + MP_TAC (SPECL [`len:int64`; `tail_len:int64`] TAIL_LEN_BOUND_THM) THEN + ASM_REWRITE_TAC[] THEN + SUBST1_TAC(ARITH_RULE `0xf = 2 EXP 4 - 1`) THEN + REWRITE_TAC[VAL_WORD_AND_MASK_WORD] THEN + NUM_REDUCE_TAC THEN IMP_REWRITE_TAC[MOD_LT] + ; ALL_TAC] THEN + (* Prove len_full_blocks_adjusted = word_sub len_full_blocks (word 0x10) *) + SUBGOAL_THEN `word_sub len_full_blocks (word 0x10) = len_full_blocks_adjusted:int64` ASSUME_TAC THENL + [ UNDISCH_TAC `(if val (tail_len:int64) = 0x0 + then (len_full_blocks:int64) + else word_sub len_full_blocks (word 0x10)) = len_full_blocks_adjusted` THEN + ASM_REWRITE_TAC[]; ALL_TAC] THEN + SUBGOAL_THEN `val (len_full_blocks_adjusted:int64) = 0` ASSUME_TAC THENL + [ EXPAND_TAC "len_full_blocks_adjusted" THEN + UNDISCH_TAC `val (len_full_blocks:int64) = 16` THEN + WORD_ARITH_TAC + ; ALL_TAC ] THEN + SUBGOAL_THEN `val (num_5blocks_adjusted:int64) = 0` ASSUME_TAC THENL + [ EXPAND_TAC "num_5blocks_adjusted" THEN + REWRITE_TAC[ASSUME `val (len_full_blocks_adjusted:int64) = 0`] THEN + WORD_ARITH_TAC + ; ALL_TAC ] THEN + + TWEAK_TAC `Q8:(armstate,int128)component` `1:num` `0:num` THEN + ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (90--92) THEN + (* Discharge if condition *) + SUBGOAL_THEN + `~(ival (word_sub (len_full_blocks_adjusted:int64) (word 0x10)) < &0x0 <=> + ~(ival (len_full_blocks_adjusted:int64) - &0x10 = + ival (word_sub (len_full_blocks_adjusted:int64) (word 0x10))))` MP_TAC THENL + [ SUBGOAL_THEN `len_full_blocks_adjusted:int64 = (word 0)` SUBST1_TAC THENL + [ UNDISCH_TAC `val (len_full_blocks_adjusted:int64) = 0` THEN + WORD_ARITH_TAC; ALL_TAC] THEN + WORD_ARITH_TAC + ; ALL_TAC] THEN + DISCH_TAC THEN + POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th])) THEN + + ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN + REPEAT CONJ_TAC THENL + [ + ASM_REWRITE_TAC[acc_len] THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[WORD_ADD_0]; + ASM_REWRITE_TAC[acc_len] THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[WORD_ADD_0]; + ASM_REWRITE_TAC[acc_blocks] THEN CONV_TAC NUM_REDUCE_CONV; + + ASM_REWRITE_TAC[acc_len] THEN + CONV_TAC NUM_REDUCE_CONV THEN + IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN + CONV_TAC NUM_REDUCE_CONV THEN + MESON_TAC[ARITH_RULE `~(i < 0)`] + ] + ; ALL_TAC] THEN + + (* Reuse the cipher stealing proof *) + MP_TAC CIPHER_STEALING_CORRECT THEN + REWRITE_TAC [(REWRITE_CONV [aes_xts_decrypt_mc] THENC LENGTH_CONV) `LENGTH aes_xts_decrypt_mc`] THEN + REWRITE_TAC[set_key_schedule; C_ARGUMENTS; SOME_FLAGS; + NONOVERLAPPING_CLAUSES; byte_list_at; + MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI] THEN + DISCH_THEN MATCH_MP_TAC THEN + EXISTS_TAC `(word 16):int64` THEN + ASM_SIMP_TAC[] THEN + SUBGOAL_THEN `len_full_blocks:int64 = word 0x10` ASSUME_TAC THENL + [ UNDISCH_TAC `val (len_full_blocks:int64) = 16` THEN + WORD_ARITH_TAC; ALL_TAC] THEN + REPEAT CONJ_TAC THENL [ + ASM_ARITH_TAC; + EXPAND_TAC "len" THEN AP_TERM_TAC THEN + UNDISCH_TAC `val (len_full_blocks:int64) = 16` THEN + WORD_ARITH_TAC; + ASM_SIMP_TAC[]; + EXPAND_TAC "len_full_blocks_adjusted" THEN + REWRITE_TAC[ASSUME `len_full_blocks:int64 = word 16`] + ] +);; + (* void aes_hw_xts_encrypt(const uint8_t *in, uint8_t *out, size_t length, const AES_KEY *key1, const AES_KEY *key2, From 68c4b0105336cc4ecdc39aceb0d6127ea608f3f7 Mon Sep 17 00:00:00 2001 From: Nevine Ebeid Date: Mon, 24 Nov 2025 15:35:53 -0500 Subject: [PATCH 091/132] Cipher-stealing: case tail != 0, loop invariant subgoal 3: symbolic simulation completed. Went back to subgoal 2, fix typos and an extra pre-condition. --- arm/proofs/aes-xts-armv8.ml | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/arm/proofs/aes-xts-armv8.ml b/arm/proofs/aes-xts-armv8.ml index 142b78634..e331384d2 100644 --- a/arm/proofs/aes-xts-armv8.ml +++ b/arm/proofs/aes-xts-armv8.ml @@ -3124,13 +3124,27 @@ let BREAK_DATA_INTO_PARTS = prove( ASM_ARITH_TAC );; +(* + `forall i. + i < curr_len + ==> read (memory :> bytes8 (word_add ctxt_p (word i))) s5 = + EL i (aes256_xts_encrypt pt_in curr_len iv key1_lst key2_lst) +==> + (forall i. + i < val (word (curr_len - 0x10)) + ==> read (memory :> bytes8 (word_add ctxt_p (word i))) s5 = + EL i + (aes256_xts_encrypt pt_in (curr_len - 0x10) iv key1_lst key2_lst)) /\ + read (memory :> bytes128 (word_add ctxt_p (word (curr_len - 0x10)))) s5 = + cipher_stealing_enc_inv (val tail_len) curr_len (val tail_len) CC pt_in`` +*) (* ************************************** *) (* Assembly proofs *) (* Proof: Cipher stealing *) let CIPHER_STEALING_ENC_CORRECT = time prove( `!ptxt_p ctxt_p len key1_p - pt_in iv tail_len len_full_blocks num_5_blocks + pt_in iv tail_len len_full_blocks num_5blocks k1_0 k1_1 k1_2 k1_3 k1_4 k1_5 k1_6 k1_7 k1_8 k1_9 k1_10 k1_11 k1_12 k1_13 k1_14 pc. PAIRWISE nonoverlapping @@ -3158,7 +3172,7 @@ let CIPHER_STEALING_ENC_CORRECT = time prove( read Q16 s = k1_0 /\ read Q17 s = k1_1 /\ read Q12 s = k1_2 /\ read Q13 s = k1_3 /\ read Q14 s = k1_4 /\ read Q15 s = k1_5 /\ read Q4 s = k1_6 /\ read Q5 s = k1_7 /\ read Q18 s = k1_8 /\ read Q19 s = k1_9 /\ read Q20 s = k1_10 /\ read Q21 s = k1_11 /\ - read Q22 s = k1_12 /\ read Q23 s = k1_13 /\ read Q7 s = k1_14 /\ byte_list_at pt_in ptxt_p len s /\ + read Q22 s = k1_12 /\ read Q23 s = k1_13 /\ read Q7 s = k1_14 /\ byte_list_at pt_in ptxt_p len s /\ byte_list_at (aes256_xts_encrypt pt_in (acc_len num_5blocks len_full_blocks) iv key1_lst key2_lst) ctxt_p (word (acc_len num_5blocks len_full_blocks)) s) @@ -3365,7 +3379,7 @@ ENSURES_WHILE_PADOWN_TAC byte_list_at (aes256_xts_encrypt pt_in (curr_len-0x10) iv key1_lst key2_lst) ctxt_p (word (curr_len-0x10)) s /\ // Contents of CC at each i - read (memory :> bytes128 (word_add ctxt_p (word (curr_len - 0x10)))) s = + read (memory :> bytes128 (word_add ctxt_p (word (curr_len-0x10)))) s = cipher_stealing_enc_inv i curr_len (val (tail_len:int64)) CC pt_in /\ // bytes of Cm at offset i to (tail_len -i) in CC From 8939997980b83a30eca2772bc3d0c4ad46161d82 Mon Sep 17 00:00:00 2001 From: Nevine Ebeid Date: Mon, 24 Nov 2025 19:40:23 -0500 Subject: [PATCH 092/132] Cipher-stealing: case tail != 0, loop invariant: Reworking subgoal 2 based on l1_curr_len, using the same cipher_stealing_inv as decrypt. --- arm/proofs/aes-xts-armv8.ml | 421 +++++++++++++++++++++++++++++++----- 1 file changed, 367 insertions(+), 54 deletions(-) diff --git a/arm/proofs/aes-xts-armv8.ml b/arm/proofs/aes-xts-armv8.ml index e331384d2..dba2bb947 100644 --- a/arm/proofs/aes-xts-armv8.ml +++ b/arm/proofs/aes-xts-armv8.ml @@ -2769,9 +2769,10 @@ let acc_blocks = new_definition else if last then val i * 0x5 else val i * 0x5 + 4`;; -(* The cipher-stealing invariant is the block read at ctxt_p + curr_len where Cm is being replaced by Pm +(* The cipher-stealing invariant is the block read at ctxt_p + curr_len - 16 where Cm is being replaced by Pm one byte at a time with a decreasing offset i from the beginning of the block. - Differs from decrypt in that, there, it's curr_len + 16 *) + Differs from decrypt in that, there, it's curr_len *) +(* let cipher_stealing_enc_inv = new_definition `cipher_stealing_enc_inv (i:num) (curr_len:num) (tail_len:num) (CC:int128) (pt:byte list): int128 = bytes_to_int128( @@ -2982,6 +2983,222 @@ let CIPHER_STEALING_ENC_INV_SIMP_TAC i = REWRITE_TAC[DIMINDEX_8; DIMINDEX_32; DIMINDEX_64] THEN IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN ASM_ARITH_TAC);; +*) + +(* The cipher-stealing invariant is the block read at ctxt_p + curr_len - 16 where Cm is being replaced by Pm + one byte at a time with a decreasing offset i from the beginning of the block. + Differs from decrypt in that, there, it's curr_len. + The following is copied from decrypt and will be instantiated with l1_curr_len (= curr_len-16) instead of curr_len *) +let cipher_stealing_inv = new_definition +`cipher_stealing_inv (i:num) (curr_len:num) (tail_len:num) (PP:int128) (ct:byte list): int128 = + bytes_to_int128( + APPEND (SUB_LIST (0, i) (int128_to_bytes PP)) + (APPEND (SUB_LIST (i, tail_len - i) (SUB_LIST (curr_len + 16, tail_len) ct)) + (SUB_LIST (tail_len, 16 - tail_len) (int128_to_bytes PP))))`;; + +(* In the cipher-stealing loop invariant, all bytes remain the same between iterations + except the current byte i, which is from the corresponding location i in the tail of pt *) +let CIPHER_STEALING_BYTE_EQUAL = prove( + `!(i:num) (curr_len:num) (tail_len:int64) (PP:int128) (ct:byte list). + i < val tail_len /\ val tail_len < 16 ==> + curr_len + 16 + val tail_len = LENGTH ct ==> + let InvPP = cipher_stealing_inv (i + 1) curr_len (val tail_len) PP ct + and InvPP' = cipher_stealing_inv i curr_len (val tail_len) PP ct in + (!j. 0 <= j /\ j < 16 /\ ~(j = i) ==> EL j (int128_to_bytes InvPP) = EL j (int128_to_bytes InvPP')) /\ + EL i (int128_to_bytes InvPP') = word_zx (EL (curr_len + 16 + i) ct)`, + REPEAT STRIP_TAC THEN + REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + CONJ_TAC THENL + [ + REPEAT STRIP_TAC THEN + REWRITE_TAC[cipher_stealing_inv] THEN + IMP_REWRITE_TAC[INT128_TO_BYTES_OF_BYTES_TO_INT128] THEN + REPEAT CONJ_TAC THENL + [ + (* Three cases: 0 <= j < i, i < j < val tail_len, val tail_len <= j < 16 *) + ASM_CASES_TAC `j < i` THENL + [ + SUBGOAL_THEN `j < LENGTH (SUB_LIST (0x0,i + 0x1) (int128_to_bytes PP))` ASSUME_TAC THENL + [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN + ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `j < LENGTH (SUB_LIST (0x0,i) (int128_to_bytes PP))` ASSUME_TAC THENL + [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN + ASM_ARITH_TAC ; ALL_TAC] THEN + REWRITE_TAC[EL_APPEND] THEN + ASM_SIMP_TAC[] THEN + MP_TAC (ISPECL [`j:num`; `i:num`; `(int128_to_bytes PP):byte list`] EL_SUB_LIST) THEN + ANTS_TAC THENL + [ REWRITE_TAC[LENGTH_OF_INT128_TO_BYTES] THEN + ASM_ARITH_TAC; ALL_TAC ] THEN + MP_TAC (ISPECL [`j:num`; `(i + 1):num`; `(int128_to_bytes PP):byte list`] EL_SUB_LIST) THEN + ANTS_TAC THENL + [ REWRITE_TAC[LENGTH_OF_INT128_TO_BYTES] THEN + ASM_ARITH_TAC; ALL_TAC ] THEN + SIMP_TAC[]; ALL_TAC + ] THEN + ASM_CASES_TAC `j < val (tail_len:int64)` THENL + [ + SUBGOAL_THEN `j > i` ASSUME_TAC THENL[ASM_ARITH_TAC; ALL_TAC] THEN + REWRITE_TAC[EL_APPEND] THEN + SUBGOAL_THEN `LENGTH (SUB_LIST (0x0,i + 0x1) (int128_to_bytes PP)) = i + 1` SUBST1_TAC THENL + [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN + ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `LENGTH (SUB_LIST (0x0,i) (int128_to_bytes PP)) = i` SUBST1_TAC THENL + [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN + ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `LENGTH (SUB_LIST (i + 0x1,val (tail_len:int64) - (i + 0x1)) + (SUB_LIST (curr_len + 0x10,val tail_len) (ct:byte list))) + = val tail_len - (i + 1)` SUBST1_TAC THENL + [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN + ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `LENGTH (SUB_LIST (i,val (tail_len:int64) - i) + (SUB_LIST (curr_len + 0x10,val tail_len) (ct:byte list))) + = val tail_len - i` SUBST1_TAC THENL + [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN + ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `~(j < i)` ASSUME_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `~(j < i + 1)` ASSUME_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `j - i < val (tail_len:int64) - i` ASSUME_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `j - (i + 1) < val (tail_len:int64) - (i + 1)` ASSUME_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[] THEN + MP_TAC (ISPECL [`(j - i):num`; `i:num`; + `(SUB_LIST (curr_len + 16,val (tail_len:int64)) (ct:byte list)):byte list`; + `(val (tail_len:int64) - i):num`] EL_SUB_LIST_SHIFT) THEN + ASM_SIMP_TAC[] THEN + ANTS_TAC THENL [ REWRITE_TAC[LENGTH_SUB_LIST] THEN ASM_ARITH_TAC; ALL_TAC] THEN + IMP_REWRITE_TAC[ARITH_RULE `!i j. j > i ==> j - i - 1 = j - (i + 1)`] THEN + ASM_ARITH_TAC; ALL_TAC + ] THEN + (* j >= val tail_len *) + REWRITE_TAC[EL_APPEND] THEN + SUBGOAL_THEN `LENGTH (SUB_LIST (0x0,i + 0x1) (int128_to_bytes PP)) = i + 1` SUBST1_TAC THENL + [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN + ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `LENGTH (SUB_LIST (0x0,i) (int128_to_bytes PP)) = i` SUBST1_TAC THENL + [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN + ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `LENGTH (SUB_LIST (i + 0x1,val (tail_len:int64) - (i + 0x1)) + (SUB_LIST (curr_len + 0x10,val tail_len) (ct:byte list))) + = val tail_len - (i + 1)` SUBST1_TAC THENL + [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN + ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `LENGTH (SUB_LIST (i,val (tail_len:int64) - i) + (SUB_LIST (curr_len + 0x10,val tail_len) (ct:byte list))) + = val tail_len - i` SUBST1_TAC THENL + [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN + ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `~(j < i)` ASSUME_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `~(j < i + 1)` ASSUME_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `~(j - i < val (tail_len:int64) - i)` ASSUME_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `~(j - (i + 1) < val (tail_len:int64) - (i + 1))` ASSUME_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[] THEN + AP_THM_TAC THEN AP_TERM_TAC THEN + ASM_ARITH_TAC; + + REWRITE_TAC[LENGTH_APPEND] THEN + REWRITE_TAC[LENGTH_SUB_LIST] THEN + REWRITE_TAC[LENGTH_OF_INT128_TO_BYTES] THEN + CONV_TAC NUM_REDUCE_CONV THEN + IMP_REWRITE_TAC[ARITH_RULE `i < 16 ==> MIN i 16 = i`] THEN + SUBGOAL_THEN `LENGTH (ct:byte list) - (curr_len + 16) = val (tail_len:int64)` SUBST1_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC ] THEN + REWRITE_TAC[ARITH_RULE `!x. MIN x x = x`] THEN + ASM_ARITH_TAC; + + REWRITE_TAC[LENGTH_APPEND] THEN + REWRITE_TAC[LENGTH_SUB_LIST] THEN + REWRITE_TAC[LENGTH_OF_INT128_TO_BYTES] THEN + CONV_TAC NUM_REDUCE_CONV THEN + IMP_REWRITE_TAC[ARITH_RULE `i < 16 ==> MIN (i + 1) 16 = i + 1`] THEN + SUBGOAL_THEN `LENGTH (ct:byte list) - (curr_len + 16) = val (tail_len:int64)` SUBST1_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC ] THEN + REWRITE_TAC[ARITH_RULE `!x. MIN x x = x`] THEN + ASM_ARITH_TAC + ] ; ALL_TAC + ] THEN + + REWRITE_TAC[cipher_stealing_inv] THEN + IMP_REWRITE_TAC[INT128_TO_BYTES_OF_BYTES_TO_INT128] THEN + CONJ_TAC THENL [ + REWRITE_TAC[EL_APPEND] THEN + SUBGOAL_THEN `LENGTH (SUB_LIST (0x0,i) (int128_to_bytes PP)) = i` SUBST1_TAC THENL + [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN + ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `LENGTH (SUB_LIST (i,val (tail_len:int64) - i) + (SUB_LIST (curr_len + 0x10,val tail_len) (ct:byte list))) + = val tail_len - i` SUBST1_TAC THENL + [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN + ASM_ARITH_TAC; ALL_TAC] THEN + SIMP_TAC[ARITH_RULE `~(i < i)`; SUB_REFL] THEN + SUBGOAL_THEN `0 < val (tail_len:int64) - i` ASSUME_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[] THEN + MP_TAC (ISPECL [`curr_len + 0x10:num`; `i:num`; `ct:byte list`; + `val (tail_len:int64) - i:num`; `val (tail_len:int64)`] SUB_LIST_MIN_GENERAL) THEN + REWRITE_TAC[ARITH_RULE `!a. MIN a a = a`; GSYM ADD_ASSOC] THEN + DISCH_THEN (fun th -> (REWRITE_TAC [th])) THEN + REWRITE_TAC[WORD_ZX_TRIVIAL; EL] THEN + MATCH_MP_TAC HD_SUB_LIST_CONS_GENERAL THEN + ASM_ARITH_TAC; ALL_TAC] THEN + REWRITE_TAC[LENGTH_APPEND] THEN + REWRITE_TAC[LENGTH_SUB_LIST] THEN + REWRITE_TAC[LENGTH_OF_INT128_TO_BYTES] THEN + CONV_TAC NUM_REDUCE_CONV THEN + ASM_ARITH_TAC +);; + +let CIPHER_STEALING_INV_SELECT = prove( + `!(i:num) (curr_len:num) (tail_len:int64) (PP:int128) (ct:byte list). + i < val tail_len ==> val tail_len < 16 ==> + curr_len + 16 + (val tail_len) = LENGTH ct ==> + EL i (int128_to_bytes (cipher_stealing_inv (i + 1) curr_len (val tail_len) PP ct)) = + EL i (int128_to_bytes PP)`, + REPEAT STRIP_TAC THEN + REWRITE_TAC[cipher_stealing_inv] THEN + IMP_REWRITE_TAC[INT128_TO_BYTES_OF_BYTES_TO_INT128] THEN + CONJ_TAC THENL [ + SUBGOAL_THEN `LENGTH (SUB_LIST (0x0,i + 1) (int128_to_bytes PP)) <= i + 1` ASSUME_TAC THENL + [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN + ARITH_TAC; ALL_TAC] THEN + REWRITE_TAC[EL_APPEND] THEN + SUBGOAL_THEN `i < LENGTH (SUB_LIST (0x0,i + 0x1) (int128_to_bytes PP))` ASSUME_TAC THENL + [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN + ASM_ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[] THEN + MATCH_MP_TAC EL_SUB_LIST THEN + REWRITE_TAC[LENGTH_OF_INT128_TO_BYTES] THEN + ASM_ARITH_TAC; ALL_TAC + ] THEN + + REWRITE_TAC[LENGTH_APPEND] THEN + REWRITE_TAC[LENGTH_SUB_LIST] THEN + REWRITE_TAC[LENGTH_OF_INT128_TO_BYTES] THEN + CONV_TAC NUM_REDUCE_CONV THEN + IMP_REWRITE_TAC[ARITH_RULE `i < 16 ==> MIN (i + 1) 16 = i + 1`] THEN + SUBGOAL_THEN `LENGTH (ct:byte list) - (curr_len + 16) = val (tail_len:int64)` SUBST1_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC ] THEN + REWRITE_TAC[ARITH_RULE `!x. MIN x x = x`] THEN + ASM_ARITH_TAC +);; + +let CIPHER_STEALING_INV_SIMP_TAC i = + ( FIRST_ASSUM (fun th -> MATCH_MP_TAC(SPEC i th)) THEN CONV_TAC NUM_REDUCE_CONV) ORELSE + ( ASM_REWRITE_TAC[] THEN + REWRITE_TAC[WORD_RULE `!a b. word_add ((word a):int64) (word b) = word (a + b)`] THEN + REWRITE_TAC[GSYM ADD_ASSOC] THEN + CONV_TAC NUM_REDUCE_CONV THEN + IMP_REWRITE_TAC[WORD_ZX_ZX; WORD_ZX_TRIVIAL] THEN + REWRITE_TAC[DIMINDEX_8; DIMINDEX_32; DIMINDEX_64] THEN + IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN + ASM_ARITH_TAC);; (* TODO: change to match encrypt *) let TAIL_SWAP_CASE_TAC case = @@ -3291,48 +3508,136 @@ let CIPHER_STEALING_ENC_CORRECT = time prove( (* The cipher stealing branch *) (* The byte-swap needs another invariant proof. *) - ABBREV_TAC `curr_len = (acc_len (num_5blocks:int64) (len_full_blocks:int64)):num` THEN - ABBREV_TAC `curr_blocks = (acc_blocks (num_5blocks:int64) (len_full_blocks:int64) T):num` THEN - - SUBGOAL_THEN `curr_len <= val (len:int64)` ASSUME_TAC THENL (* differs from decrypt *) - [ EXPAND_TAC "curr_len" THEN + (* In the following "l1 means "less 1 block". This is to differentiate it from the decrypt case + where at the entry of cipher-stealing, we have one full block left to process and a tail, while + in encrypt that full block was already processed and that's why we need to go back "less 1" + to match the decrypt invariant. *) + ABBREV_TAC `l1_curr_len = ((acc_len (num_5blocks:int64) (len_full_blocks:int64)) - 0x10):num` THEN + ABBREV_TAC `l1_curr_blocks = ((acc_blocks (num_5blocks:int64) (len_full_blocks:int64) T) - 1):num` THEN + + SUBGOAL_THEN `l1_curr_len + 0x10 <= val (len:int64)` ASSUME_TAC THENL (* similar to decrypt *) + [ EXPAND_TAC "l1_curr_len" THEN MP_TAC (SPECL [`num_5blocks:int64`; `len_full_blocks:int64`] VALUE_OF_ACC_LEN) THEN REPEAT_N 3 (ANTS_TAC THENL [ASM_ARITH_TAC ORELSE ASM_SIMP_TAC[]; ALL_TAC]) THEN - SIMP_TAC[] THEN DISCH_TAC THEN - ASM_SIMP_TAC[]; ALL_TAC ] THEN + ASM_ARITH_TAC; ALL_TAC ] THEN - SUBGOAL_THEN `val ((word curr_len):int64) = curr_len` ASSUME_TAC THENL + SUBGOAL_THEN `val ((word l1_curr_len):int64) = l1_curr_len` ASSUME_TAC THENL [ IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN - EXPAND_TAC "curr_len" THEN - MP_TAC (SPECL [`num_5blocks:int64`; `len_full_blocks:int64`; `2 EXP 64`] - BOUND_OF_ACC_LEN) THEN - REPEAT_N 4 (ANTS_TAC THENL [ASM_ARITH_TAC ORELSE ASM_SIMP_TAC[]; ALL_TAC]) THEN - SIMP_TAC[]; ALL_TAC] THEN + ASM_ARITH_TAC; ALL_TAC] THEN - SUBGOAL_THEN `curr_len >= 16` ASSUME_TAC THENL - [ REWRITE_TAC[GSYM (ASSUME `acc_len num_5blocks len_full_blocks = curr_len`)] THEN + SUBGOAL_THEN `l1_curr_len >= 0` ASSUME_TAC THENL + [ REWRITE_TAC[GSYM (ASSUME `(acc_len num_5blocks len_full_blocks) - 0x10 = l1_curr_len`)] THEN MP_TAC (SPECL [`num_5blocks:int64`; `len_full_blocks:int64`] VALUE_OF_ACC_LEN) THEN REPEAT_N 3 (ANTS_TAC THENL [ASM_ARITH_TAC ORELSE ASM_SIMP_TAC[]; ALL_TAC]) THEN - SIMP_TAC[] THEN DISCH_TAC THEN - UNDISCH_TAC `word_add (tail_len:int64) (len_full_blocks:int64) = len` THEN - ONCE_REWRITE_TAC[GSYM VAL_EQ] THEN - REWRITE_TAC[VAL_WORD_ADD;DIMINDEX_64] THEN - IMP_REWRITE_TAC[MOD_LT] THEN - ASM_ARITH_TAC; ALL_TAC ] THEN + ASM_ARITH_TAC ; ALL_TAC ] THEN - SUBGOAL_THEN `16 * curr_blocks = curr_len` ASSUME_TAC THENL - [ REWRITE_TAC[GSYM (ASSUME `acc_len num_5blocks len_full_blocks = curr_len`)] THEN (* put in tips doc*) + SUBGOAL_THEN `16 * l1_curr_blocks = l1_curr_len` ASSUME_TAC THENL + [ REWRITE_TAC[GSYM (ASSUME `(acc_len num_5blocks len_full_blocks) - 0x10 = l1_curr_len`)] THEN (* put in tips doc*) (* or UNDISCH_THEN `acc_len (num_5blocks:int64) (len_full_blocks:int64) = curr_len` (fun th -> REWRITE_TAC[GSYM th]) THEN *) - EXPAND_TAC "curr_blocks" THEN + EXPAND_TAC "l1_curr_blocks" THEN REWRITE_TAC[acc_len; acc_blocks] THEN REPEAT_N 4 (COND_CASES_TAC THENL [SIMP_TAC[] THEN ARITH_TAC; ALL_TAC] THEN SIMP_TAC[]) THEN ARITH_TAC; ALL_TAC ] THEN ABBREV_TAC `CC = aes256_xts_encrypt_round - (bytes_to_int128 (SUB_LIST (curr_len-0x10,0x10) (pt_in:byte list))) - (calculate_tweak (curr_blocks-0x1) (iv:int128) (key2_lst:int128 list)) + (bytes_to_int128 (SUB_LIST (l1_curr_len,0x10) (pt_in:byte list))) + (calculate_tweak (l1_curr_blocks) (iv:int128) (key2_lst:int128 list)) (key1_lst:int128 list)` THEN +(* + word_sub (word_add ctxt_p (word (acc_len num_5blocks len_full_blocks))) + (word 0x10) = + word_add ctxt_p (word l1_curr_len) /\ + word_add ctxt_p (word (acc_len num_5blocks len_full_blocks)) = + word_add ctxt_p (word (l1_curr_len + 0x10)) /\ +word_sub (word_add ctxt_p (word (l1_curr_len + 0x10))) (word 0x10) = + word_add ctxt_p (word l1_curr_len) /\ +calculate_tweak (acc_blocks num_5blocks len_full_blocks true) iv key2_lst = + calculate_tweak (l1_curr_blocks + 0x1) iv key2_lst +*) + (* For address matching when symbolic simulation *) + + SUBGOAL_THEN `16 <= acc_len num_5blocks len_full_blocks` ASSUME_TAC THENL + [ MP_TAC (SPECL [`num_5blocks:int64`; `len_full_blocks:int64`] VALUE_OF_ACC_LEN) THEN + REPEAT_N 3 (ANTS_TAC THENL [ASM_ARITH_TAC ORELSE ASM_SIMP_TAC[]; ALL_TAC]) THEN + ASM_ARITH_TAC; ALL_TAC ] + + SUBGOAL_THEN ` (word (acc_len num_5blocks len_full_blocks):int64) = word (l1_curr_len + 0x10)` ASSUME_TAC THENL + [ AP_TERM_TAC THEN + REWRITE_TAC[GSYM (ASSUME `(acc_len num_5blocks len_full_blocks) - 0x10 = l1_curr_len`)] THEN + ASM_ARITH_TAC; ALL_TAC ] + + SUBGOAL_THEN `word_add (ptxt_p:int64) (word (acc_len num_5blocks len_full_blocks)) = + word_add ptxt_p (word (l1_curr_len + 0x10))` ASSUME_TAC THENL + [ REPEAT AP_TERM_TAC THEN + ASM_ARITH_TAC ; ALL_TAC ] + + SUBGOAL_THEN `word_sub (word_add ctxt_p (word (acc_len num_5blocks len_full_blocks))) (word 0x10):int64 = + word_add ctxt_p (word l1_curr_len)` ASSUME_TAC THENL + [ REWRITE_TAC[GSYM (ASSUME `(acc_len num_5blocks len_full_blocks) - 0x10 = l1_curr_len`)] THEN + ASM_SIMP_TAC[WORD_SUB] THEN + CONV_TAC WORD_RULE; ALL_TAC] + + SUBGOAL_THEN `word_sub (word_add ctxt_p (word (l1_curr_len + 0x10))) (word 0x10):int64 = + word_add ctxt_p (word l1_curr_len)` ASSUME_TAC THENL + [ REWRITE_TAC[GSYM (ASSUME `word (acc_len num_5blocks len_full_blocks) = word (l1_curr_len + 0x10):int64`)] THEN + ASM_SIMP_TAC[] ; ALL_TAC] + +(* + SUBGOAL_THEN `0x1 <= acc_blocks num_5blocks len_full_blocks true` ASSUME_TAC THENL + [ (*UNDISCH_TAC `acc_blocks num_5blocks len_full_blocks true - 0x1 = l1_curr_blocks` THEN*) + UNDISCH_TAC `0x10 * l1_curr_blocks = l1_curr_len` THEN + REWRITE_TAC[GSYM (ASSUME `(acc_len num_5blocks len_full_blocks) - 0x10 = l1_curr_len`)] THEN + EXPAND_TAC "l1_curr_blocks" THEN + UNDISCH_TAC `0x10 <= acc_len num_5blocks len_full_blocks` THEN + UNDISCH_TAC `l1_curr_len >= 0x0` THEN + + + REWRITE_TAC[ARITH_RULE `!a. 0x10 * (a:num - 0x1) = a - 0x10`] THEN + ARITH_TAC THEN + ASM_ARITH_TAC THEN + + ] + + SUBGOAL_THEN ` acc_blocks num_5blocks len_full_blocks true = (l1_curr_blocks + 0x1):num` ASSUME_TAC THENL + [ REWRITE_TAC[GSYM (ASSUME `acc_blocks num_5blocks len_full_blocks true - 0x1 = l1_curr_blocks`)] THEN + REWRITE_TAC[acc_blocks] THEN + REPEAT_N 4 (COND_CASES_TAC THENL [SIMP_TAC[] THEN ARITH_TAC; ALL_TAC] THEN SIMP_TAC[]) THEN + ARITH_TAC THEN + ARITH_TAC; ALL_TAC ] THEN + + ASM_ARITH_TAC THEN + ; ALL_TAC ] +*) + + (* + SUBGOAL_THEN `word_add (ptxt_p:int64) (word_add (word curr_len) (word i)) = + word_add ptxt_p (word (curr_len + i))` SUBST_ALL_TAC THENL + [ REWRITE_TAC[WORD_RULE `!a b. word_add ((word a):int64) (word b) = word (a + b)`; ADD_ASSOC] + ; ALL_TAC] THEN + + SUBGOAL_THEN `(word_add (word_add (ctxt_p:int64) (word (curr_len - 0x10))) (word i)) = + word_add (ctxt_p:int64) (word (curr_len - 0x10 + i))` ASSUME_TAC THENL + [ REWRITE_TAC[GSYM WORD_ADD_ASSOC] THEN + AP_TERM_TAC THEN + REWRITE_TAC[WORD_ADD;WORD_SUB] THEN + ASM_ARITH_TAC + ; ALL_TAC ] THEN + + SUBGOAL_THEN `word_sub (word_add ctxt_p (word curr_len)) (word 0x10):int64 = + word_add ctxt_p (word(curr_len - 0x10))` SUBST_ALL_TAC THENL + [ RULE_ASSUM_TAC(REWRITE_RULE[GE]) THEN + ASM_SIMP_TAC[WORD_SUB] THEN CONV_TAC WORD_RULE; + (* From John, it put all addresses in the read memory assumptions in canonical form *) + CHANGED_TAC(RULE_ASSUM_TAC(CONV_RULE(ONCE_DEPTH_CONV NORMALIZE_RELATIVE_ADDRESS_CONV)))] THEN + + SUBGOAL_THEN `(word_sub (word_add (ctxt_p:int64) (word curr_len)) (word 0x10)) + = (word_add ctxt_p (word (curr_len - 0x10)))` SUBST1_TAC THENL + [ REWRITE_TAC[WORD_SUB] THEN + ASM_SIMP_TAC[ARITH_RULE `curr_len >= 0x10 ==> 0x10 <= curr_len`] THEN + WORD_ARITH_TAC + ; ALL_TAC] THEN +*) (* Invariant proof for .composite_enc_loop *) (* Invariant: @@ -3365,28 +3670,29 @@ ENSURES_WHILE_PADOWN_TAC `pc + 0xa08` (* loop backedge branch PC *) `\i s. // loop invariant at the end of the loop iteration - ( read X0 s = word_add ptxt_p (word curr_len) /\ - read X1 s = word_sub (word_add ctxt_p (word curr_len)) (word 0x10) /\ - read X13 s = word_add ctxt_p (word curr_len) /\ - read X20 s = word_add ptxt_p (word curr_len) /\ + ( read X0 s = word_add ptxt_p (word (l1_curr_len + 0x10)) /\ + read X1 s = word_add ctxt_p (word l1_curr_len) /\ + read X13 s = word_add ctxt_p (word (l1_curr_len + 0x10)) /\ + read X20 s = word_add ptxt_p (word (l1_curr_len + 0x10)) /\ read X21 s = (word i):int64 /\ - read Q6 s = calculate_tweak curr_blocks iv key2_lst /\ + read Q6 s = calculate_tweak (acc_blocks num_5blocks len_full_blocks true) iv key2_lst /\ read Q16 s = k1_0 /\ read Q17 s = k1_1 /\ read Q12 s = k1_2 /\ read Q13 s = k1_3 /\ read Q14 s = k1_4 /\ read Q15 s = k1_5 /\ read Q4 s = k1_6 /\ read Q5 s = k1_7 /\ read Q18 s = k1_8 /\ read Q19 s = k1_9 /\ read Q20 s = k1_10 /\ read Q21 s = k1_11 /\ read Q22 s = k1_12 /\ read Q23 s = k1_13 /\ read Q7 s = k1_14 /\ byte_list_at pt_in ptxt_p len s /\ - byte_list_at (aes256_xts_encrypt pt_in (curr_len-0x10) iv key1_lst key2_lst) - ctxt_p (word (curr_len-0x10)) s /\ + // Encryption is correct up until l1_curr_len + byte_list_at (aes256_xts_encrypt pt_in l1_curr_len iv key1_lst key2_lst) + ctxt_p (word l1_curr_len) s /\ // Contents of CC at each i - read (memory :> bytes128 (word_add ctxt_p (word (curr_len-0x10)))) s = - cipher_stealing_enc_inv i curr_len (val (tail_len:int64)) CC pt_in /\ + read (memory :> bytes128 (word_add ctxt_p (word l1_curr_len))) s = + cipher_stealing_inv i l1_curr_len (val (tail_len:int64)) CC pt_in /\ - // bytes of Cm at offset i to (tail_len -i) in CC + // bytes of Cm at offset i to (tail_len-i) in CC // are stored at their final location in ciphertext in the tail part // they're copied from CC before they're overwritten by bytes from Pm byte_list_at (SUB_LIST (i, val tail_len - i) (int128_to_bytes CC)) - (word_add ctxt_p (word (curr_len + i))) + (word_add ctxt_p (word (l1_curr_len + 0x10 + i))) (word ((val tail_len) - i)) s) /\ // loop backedge condition (read ZF s <=> i = 0) /\ @@ -3399,7 +3705,7 @@ ENSURES_WHILE_PADOWN_TAC (* Subgoal2: invariant holds before entering loop *) REWRITE_TAC[byte_list_at] THEN - UNDISCH_THEN `val ((word curr_len):int64) = curr_len` + UNDISCH_THEN `val ((word l1_curr_len):int64) = l1_curr_len` (fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th]) THEN REWRITE_TAC[th] THEN ASSUME_TAC th) THEN (* put in tips doc: keep the assumption *) @@ -3426,32 +3732,38 @@ ENSURES_WHILE_PADOWN_TAC (word i))) s5 = EL i (SUB_LIST (val tail_len,0x0) (int128_to_bytes CC)))` *) (* 4 total *) (* - `tail_len = word (val tail_len) /\ +`tail_len = word (val tail_len) /\ (forall i. - i < val (word (curr_len - 0x10)) + i < l1_curr_len ==> read (memory :> bytes8 (word_add ctxt_p (word i))) s5 = - EL i (aes256_xts_encrypt pt_in (curr_len - 0x10) iv key1_lst key2_lst)) /\ - read (memory :> bytes128 (word_add ctxt_p (word (curr_len - 0x10)))) s5 = - cipher_stealing_enc_inv (val tail_len) curr_len (val tail_len) CC pt_in /\ + EL i (aes256_xts_encrypt pt_in l1_curr_len iv key1_lst key2_lst)) /\ + read (memory :> bytes128 (word_add ctxt_p (word l1_curr_len))) s5 = + cipher_stealing_inv (val tail_len) l1_curr_len (val tail_len) CC pt_in /\ (forall i. i < val (word 0x0) - ==> read (memory :> bytes8 (word_add (word_add ctxt_p (word (curr_len + val tail_len))) (word i))) - s5 = EL i (SUB_LIST (val tail_len,0x0) (int128_to_bytes CC)))` + ==> read + (memory :> + bytes8 + (word_add + (word_add ctxt_p (word (l1_curr_len + 0x10 + val tail_len))) + (word i))) + s5 = + EL i (SUB_LIST (val tail_len,0x0) (int128_to_bytes CC)))` *) REPEAT CONJ_TAC THENL (* 4 subgoals (7 total) *) [ REWRITE_TAC[WORD_VAL]; (*`forall i. - i < val (word (curr_len - 0x10)) + i < l1_curr_len ==> read (memory :> bytes8 (word_add ctxt_p (word i))) s5 = - EL i - (aes256_xts_encrypt pt_in (curr_len - 0x10) iv key1_lst key2_lst)`. *) + EL i (aes256_xts_encrypt pt_in l1_curr_len iv key1_lst key2_lst)`. *) UNDISCH_TAC `forall i. - i < curr_len + i < val (word (l1_curr_len + 0x10)) ==> read (memory :> bytes8 (word_add ctxt_p (word i))) s5 = - EL i (aes256_xts_encrypt pt_in curr_len iv key1_lst key2_lst)` THEN + EL i (aes256_xts_encrypt pt_in (acc_len num_5blocks len_full_blocks) + iv key1_lst key2_lst)` THEN MP_TAC (SPECL [`curr_len:num`; `ctxt_p:int64`; `(aes256_xts_encrypt pt_in curr_len iv key1_lst key2_lst):byte list`; `s5:armstate`] BYTE_LIST_TO_NUM_THM) THEN @@ -3500,7 +3812,7 @@ ENSURES_WHILE_PADOWN_TAC `read (memory :> bytes128 (word_add ctxt_p (word (curr_len - 0x10)))) s5 = cipher_stealing_enc_inv (val tail_len) curr_len (val tail_len) CC pt_in` *) - REWRITE_TAC[cipher_stealing_enc_inv; SUB_REFL] THEN + REWRITE_TAC[cipher_stealing_inv; SUB_REFL] THEN SUBGOAL_THEN `SUB_LIST (val (tail_len:int64),0x0) (SUB_LIST (curr_len,val tail_len) (pt_in:byte list)) = []` SUBST1_TAC THENL [ REWRITE_TAC[SUB_LIST_CLAUSES]; ALL_TAC] THEN REWRITE_TAC[CONJUNCT1 APPEND] THEN @@ -3720,7 +4032,7 @@ ENSURES_WHILE_PADOWN_TAC (* The symbolic simulation does not capture the LDR/STR at a byte level with i as the iterator, because it doesn't know which i. So the following steps are to break the cases for values of i *) - +(****TODO: change it to _inv *) (* Read a byte from Cm (at location curr_len -16 + i into w15 *) MP_TAC (SPECL [`(word_add ctxt_p (word (curr_len - 0x10))):int64`; `word i:int64`; `s0:armstate`; `(cipher_stealing_enc_inv (i + 0x1) curr_len (val (tail_len:int64)) CC pt_in):int128`] @@ -3751,6 +4063,7 @@ ENSURES_WHILE_PADOWN_TAC 67 [`read (memory :> bytes8 (word_add ptxt_p (word_add (word curr_len) (word i)))) s0 = EL (val (word_add (word curr_len) (word i))) pt_in`]*) +(****TODO: change it to _inv *) (* Break the `read (memory :> bytes128 (word_sub (word_add ctxt_p (word curr_len)) (word 0x10))) s0 into bytes using BREAK_ONE_BLOCK_INTO_BYTES *) MP_TAC (SPECL [`(word_add ctxt_p (word (curr_len - 0x10))):int64`; `s0:armstate`; From 33d6537fe44647aef4d3898fe7e89d3c6851ea9a Mon Sep 17 00:00:00 2001 From: Nevine Ebeid Date: Tue, 25 Nov 2025 17:13:58 -0500 Subject: [PATCH 093/132] Cipher-stealing: case tail != 0, loop invariant: Reworking subgoal 2 (wip), needing a new lemma. --- arm/proofs/aes-xts-armv8.ml | 241 ++++++++++++++++++------------------ 1 file changed, 122 insertions(+), 119 deletions(-) diff --git a/arm/proofs/aes-xts-armv8.ml b/arm/proofs/aes-xts-armv8.ml index dba2bb947..9f7170e67 100644 --- a/arm/proofs/aes-xts-armv8.ml +++ b/arm/proofs/aes-xts-armv8.ml @@ -1959,6 +1959,13 @@ let VAL_OF_BYTES_TO_INT128_EQ_NUM_OF_BYTELIST = prove( REFL_TAC );; +let READ_BYTES_AND_BYTE128_MERGE = prove( + `!(pt_ptr:int64) (sz:num) (x:byte list) (s:armstate). + sz + 16 <= LENGTH x ==> + read (memory :> bytes (pt_ptr,sz + 0x10)) s = num_of_bytelist (SUB_LIST (0, sz + 0x10) x) + ==> read (memory :> bytes (pt_ptr, sz)) s = num_of_bytelist (SUB_LIST (0, sz) x)`, + CHEAT_TAC);; + let READ_BYTES_AND_BYTE128_SPLIT = prove( `!(pt_ptr:int64) (sz:num) (x:byte list) (s:armstate). sz + 16 <= LENGTH x ==> @@ -3525,6 +3532,10 @@ let CIPHER_STEALING_ENC_CORRECT = time prove( [ IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `val ((word (l1_curr_len + 0x10)):int64) = l1_curr_len + 0x10` ASSUME_TAC THENL + [ IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN + ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `l1_curr_len >= 0` ASSUME_TAC THENL [ REWRITE_TAC[GSYM (ASSUME `(acc_len num_5blocks len_full_blocks) - 0x10 = l1_curr_len`)] THEN MP_TAC (SPECL [`num_5blocks:int64`; `len_full_blocks:int64`] VALUE_OF_ACC_LEN) THEN @@ -3544,100 +3555,32 @@ let CIPHER_STEALING_ENC_CORRECT = time prove( (bytes_to_int128 (SUB_LIST (l1_curr_len,0x10) (pt_in:byte list))) (calculate_tweak (l1_curr_blocks) (iv:int128) (key2_lst:int128 list)) (key1_lst:int128 list)` THEN -(* - word_sub (word_add ctxt_p (word (acc_len num_5blocks len_full_blocks))) - (word 0x10) = - word_add ctxt_p (word l1_curr_len) /\ - word_add ctxt_p (word (acc_len num_5blocks len_full_blocks)) = - word_add ctxt_p (word (l1_curr_len + 0x10)) /\ -word_sub (word_add ctxt_p (word (l1_curr_len + 0x10))) (word 0x10) = - word_add ctxt_p (word l1_curr_len) /\ -calculate_tweak (acc_blocks num_5blocks len_full_blocks true) iv key2_lst = - calculate_tweak (l1_curr_blocks + 0x1) iv key2_lst -*) - (* For address matching when symbolic simulation *) + (* For address matching when symbolic simulation *) SUBGOAL_THEN `16 <= acc_len num_5blocks len_full_blocks` ASSUME_TAC THENL [ MP_TAC (SPECL [`num_5blocks:int64`; `len_full_blocks:int64`] VALUE_OF_ACC_LEN) THEN REPEAT_N 3 (ANTS_TAC THENL [ASM_ARITH_TAC ORELSE ASM_SIMP_TAC[]; ALL_TAC]) THEN - ASM_ARITH_TAC; ALL_TAC ] + ASM_ARITH_TAC; ALL_TAC ] THEN - SUBGOAL_THEN ` (word (acc_len num_5blocks len_full_blocks):int64) = word (l1_curr_len + 0x10)` ASSUME_TAC THENL - [ AP_TERM_TAC THEN - REWRITE_TAC[GSYM (ASSUME `(acc_len num_5blocks len_full_blocks) - 0x10 = l1_curr_len`)] THEN - ASM_ARITH_TAC; ALL_TAC ] + SUBGOAL_THEN ` acc_len num_5blocks len_full_blocks = l1_curr_len + 0x10` ASSUME_TAC THENL + [ REWRITE_TAC[GSYM (ASSUME `(acc_len num_5blocks len_full_blocks) - 0x10 = l1_curr_len`)] THEN + ASM_ARITH_TAC; ALL_TAC ] THEN SUBGOAL_THEN `word_add (ptxt_p:int64) (word (acc_len num_5blocks len_full_blocks)) = word_add ptxt_p (word (l1_curr_len + 0x10))` ASSUME_TAC THENL [ REPEAT AP_TERM_TAC THEN - ASM_ARITH_TAC ; ALL_TAC ] + ASM_ARITH_TAC ; ALL_TAC ] THEN SUBGOAL_THEN `word_sub (word_add ctxt_p (word (acc_len num_5blocks len_full_blocks))) (word 0x10):int64 = word_add ctxt_p (word l1_curr_len)` ASSUME_TAC THENL [ REWRITE_TAC[GSYM (ASSUME `(acc_len num_5blocks len_full_blocks) - 0x10 = l1_curr_len`)] THEN ASM_SIMP_TAC[WORD_SUB] THEN - CONV_TAC WORD_RULE; ALL_TAC] + CONV_TAC WORD_RULE; ALL_TAC] THEN SUBGOAL_THEN `word_sub (word_add ctxt_p (word (l1_curr_len + 0x10))) (word 0x10):int64 = word_add ctxt_p (word l1_curr_len)` ASSUME_TAC THENL - [ REWRITE_TAC[GSYM (ASSUME `word (acc_len num_5blocks len_full_blocks) = word (l1_curr_len + 0x10):int64`)] THEN - ASM_SIMP_TAC[] ; ALL_TAC] - -(* - SUBGOAL_THEN `0x1 <= acc_blocks num_5blocks len_full_blocks true` ASSUME_TAC THENL - [ (*UNDISCH_TAC `acc_blocks num_5blocks len_full_blocks true - 0x1 = l1_curr_blocks` THEN*) - UNDISCH_TAC `0x10 * l1_curr_blocks = l1_curr_len` THEN - REWRITE_TAC[GSYM (ASSUME `(acc_len num_5blocks len_full_blocks) - 0x10 = l1_curr_len`)] THEN - EXPAND_TAC "l1_curr_blocks" THEN - UNDISCH_TAC `0x10 <= acc_len num_5blocks len_full_blocks` THEN - UNDISCH_TAC `l1_curr_len >= 0x0` THEN - - - REWRITE_TAC[ARITH_RULE `!a. 0x10 * (a:num - 0x1) = a - 0x10`] THEN - ARITH_TAC THEN - ASM_ARITH_TAC THEN - - ] - - SUBGOAL_THEN ` acc_blocks num_5blocks len_full_blocks true = (l1_curr_blocks + 0x1):num` ASSUME_TAC THENL - [ REWRITE_TAC[GSYM (ASSUME `acc_blocks num_5blocks len_full_blocks true - 0x1 = l1_curr_blocks`)] THEN - REWRITE_TAC[acc_blocks] THEN - REPEAT_N 4 (COND_CASES_TAC THENL [SIMP_TAC[] THEN ARITH_TAC; ALL_TAC] THEN SIMP_TAC[]) THEN - ARITH_TAC THEN - ARITH_TAC; ALL_TAC ] THEN - - ASM_ARITH_TAC THEN - ; ALL_TAC ] -*) - - (* - SUBGOAL_THEN `word_add (ptxt_p:int64) (word_add (word curr_len) (word i)) = - word_add ptxt_p (word (curr_len + i))` SUBST_ALL_TAC THENL - [ REWRITE_TAC[WORD_RULE `!a b. word_add ((word a):int64) (word b) = word (a + b)`; ADD_ASSOC] - ; ALL_TAC] THEN - - SUBGOAL_THEN `(word_add (word_add (ctxt_p:int64) (word (curr_len - 0x10))) (word i)) = - word_add (ctxt_p:int64) (word (curr_len - 0x10 + i))` ASSUME_TAC THENL - [ REWRITE_TAC[GSYM WORD_ADD_ASSOC] THEN - AP_TERM_TAC THEN - REWRITE_TAC[WORD_ADD;WORD_SUB] THEN - ASM_ARITH_TAC - ; ALL_TAC ] THEN - - SUBGOAL_THEN `word_sub (word_add ctxt_p (word curr_len)) (word 0x10):int64 = - word_add ctxt_p (word(curr_len - 0x10))` SUBST_ALL_TAC THENL - [ RULE_ASSUM_TAC(REWRITE_RULE[GE]) THEN - ASM_SIMP_TAC[WORD_SUB] THEN CONV_TAC WORD_RULE; - (* From John, it put all addresses in the read memory assumptions in canonical form *) - CHANGED_TAC(RULE_ASSUM_TAC(CONV_RULE(ONCE_DEPTH_CONV NORMALIZE_RELATIVE_ADDRESS_CONV)))] THEN - - SUBGOAL_THEN `(word_sub (word_add (ctxt_p:int64) (word curr_len)) (word 0x10)) - = (word_add ctxt_p (word (curr_len - 0x10)))` SUBST1_TAC THENL - [ REWRITE_TAC[WORD_SUB] THEN - ASM_SIMP_TAC[ARITH_RULE `curr_len >= 0x10 ==> 0x10 <= curr_len`] THEN - WORD_ARITH_TAC - ; ALL_TAC] THEN -*) + [ REWRITE_TAC[GSYM (ASSUME `acc_len num_5blocks len_full_blocks = l1_curr_len + 0x10`)] THEN + ASM_SIMP_TAC[] ; ALL_TAC] THEN (* Invariant proof for .composite_enc_loop *) (* Invariant: @@ -3663,7 +3606,7 @@ calculate_tweak (acc_blocks num_5blocks len_full_blocks true) iv key2_lst = [i,tail_len) -- copied over from Pm block *) -ENSURES_WHILE_PADOWN_TAC + ENSURES_WHILE_PADOWN_TAC `val (tail_len:int64)` (* counter begin number *) `0` (* counter end number *) `pc + 0x9f4` (* loop body start PC *) @@ -3708,6 +3651,9 @@ ENSURES_WHILE_PADOWN_TAC UNDISCH_THEN `val ((word l1_curr_len):int64) = l1_curr_len` (fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th]) THEN REWRITE_TAC[th] THEN ASSUME_TAC th) THEN (* put in tips doc: keep the assumption *) + UNDISCH_THEN `val ((word (l1_curr_len + 0x10)):int64) = l1_curr_len + 0x10` + (fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th]) THEN REWRITE_TAC[th] + THEN ASSUME_TAC th) THEN ENSURES_INIT_TAC "s0" THEN ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (1--2) THEN @@ -3741,17 +3687,12 @@ ENSURES_WHILE_PADOWN_TAC cipher_stealing_inv (val tail_len) l1_curr_len (val tail_len) CC pt_in /\ (forall i. i < val (word 0x0) - ==> read - (memory :> - bytes8 - (word_add - (word_add ctxt_p (word (l1_curr_len + 0x10 + val tail_len))) - (word i))) - s5 = - EL i (SUB_LIST (val tail_len,0x0) (int128_to_bytes CC)))` -*) + ==> read (memory :> bytes8 (word_add (word_add ctxt_p (word (l1_curr_len + 0x10 + val tail_len))) + (word i))) s5 = + EL i (SUB_LIST (val tail_len,0x0) (int128_to_bytes CC)))`. *) REPEAT CONJ_TAC THENL (* 4 subgoals (7 total) *) [ + (* `tail_len = word (val tail_len)` *) REWRITE_TAC[WORD_VAL]; (*`forall i. @@ -3760,49 +3701,111 @@ ENSURES_WHILE_PADOWN_TAC EL i (aes256_xts_encrypt pt_in l1_curr_len iv key1_lst key2_lst)`. *) UNDISCH_TAC `forall i. - i < val (word (l1_curr_len + 0x10)) - ==> read (memory :> bytes8 (word_add ctxt_p (word i))) s5 = - EL i (aes256_xts_encrypt pt_in (acc_len num_5blocks len_full_blocks) - iv key1_lst key2_lst)` THEN - MP_TAC (SPECL [`curr_len:num`; `ctxt_p:int64`; - `(aes256_xts_encrypt pt_in curr_len iv key1_lst key2_lst):byte list`; + i < l1_curr_len + 0x10 + ==> read (memory :> bytes8 (word_add (ctxt_p:int64) (word i))) s5 = + EL i (aes256_xts_encrypt pt_in (l1_curr_len + 0x10) iv key1_lst key2_lst)` THEN + REWRITE_TAC[GSYM (ASSUME `0x10 * l1_curr_blocks = l1_curr_len`)] THEN + REWRITE_TAC[ARITH_RULE `0x10 * l1_curr_blocks + 0x10 = 0x10 * (l1_curr_blocks + 0x1)`] THEN + MP_TAC (SPECL [`0x10 * (l1_curr_blocks + 0x1):num`; `ctxt_p:int64`; + `(aes256_xts_encrypt pt_in (0x10 * (l1_curr_blocks + 0x1)) iv key1_lst key2_lst):byte list`; `s5:armstate`] BYTE_LIST_TO_NUM_THM) THEN ANTS_TAC THENL [ - REWRITE_TAC[GSYM (ASSUME `0x10 * curr_blocks = curr_len`)] THEN REWRITE_TAC[LENGTH_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS] THEN - ARITH_TAC; ALL_TAC] + ARITH_TAC; ALL_TAC] THEN DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN - MP_TAC (SPECL [`(curr_len-0x10):num`; `ctxt_p:int64`; - `(aes256_xts_encrypt pt_in (curr_len-0x10) iv key1_lst key2_lst):byte list`; + MP_TAC (SPECL [`0x10 * l1_curr_blocks:num`; `ctxt_p:int64`; + `(aes256_xts_encrypt pt_in (0x10 * l1_curr_blocks) iv key1_lst key2_lst):byte list`; `s5:armstate`] BYTE_LIST_TO_NUM_THM) THEN ANTS_TAC THENL [ - REWRITE_TAC[GSYM (ASSUME `0x10 * curr_blocks = curr_len`)] THEN - REWRITE_TAC[ARITH_RULE `0x10 * curr_blocks - 0x10 = 0x10 * (curr_blocks - 0x1)`] THEN REWRITE_TAC[LENGTH_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS] THEN - ARITH_TAC; ALL_TAC] - SUBGOAL_THEN `val ((word (curr_len - 0x10)):int64) = curr_len - 0x10` SUBST1_TAC THENL - [ UNDISCH_TAC `curr_len >= 0x10` THEN - IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN - UNDISCH_TAC `curr_len <= val (len:int64)` THEN - UNDISCH_TAC `val (len:int64) <= 0x2 EXP 0x18` THEN - ARITH_TAC ; ALL_TAC ] + ARITH_TAC; ALL_TAC] THEN DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN - REWRITE_TAC[GSYM (ASSUME `0x10 * curr_blocks = curr_len`)] THEN - REWRITE_TAC[ARITH_RULE `0x10 * curr_blocks - 0x10 = 0x10 * (curr_blocks - 0x1)`] THEN - MP_TAC(SPECL [`curr_blocks:num`; `pt_in:byte list`; `iv:int128`; `key1_lst:int128 list`; `key2_lst:int128 list`] + MP_TAC(SPECL [`l1_curr_blocks:num`; `pt_in:byte list`; `iv:int128`; `key1_lst:int128 list`; `key2_lst:int128 list`] LENGTH_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS) THEN - MP_TAC(SPECL [`curr_blocks-1:num`; `pt_in:byte list`; `iv:int128`; `key1_lst:int128 list`; `key2_lst:int128 list`] + MP_TAC(SPECL [`l1_curr_blocks + 0x1:num`; `pt_in:byte list`; `iv:int128`; `key1_lst:int128 list`; `key2_lst:int128 list`] LENGTH_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS) THEN IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN + IMP_REWRITE_TAC[ARITH_RULE `0x10 * (l1_curr_blocks + 0x1) = 0x10 * l1_curr_blocks + 0x10`] THEN DISCH_TAC THEN DISCH_TAC THEN - (*`read (memory :> bytes (ctxt_p,curr_len)) s5 = - num_of_bytelist (aes256_xts_encrypt pt_in curr_len iv key1_lst key2_lst) - ==> read (memory :> bytes (ctxt_p,0x10 * (curr_blocks - 0x1))) s5 = - num_of_bytelist - (aes256_xts_encrypt pt_in (0x10 * (curr_blocks - 0x1)) iv key1_lst - key2_lst)` *) + (* `read (memory :> bytes (ctxt_p,0x10 * (l1_curr_blocks + 0x1))) s5 = + num_of_bytelist (aes256_xts_encrypt pt_in (0x10 * (l1_curr_blocks + 0x1)) iv key1_lst key2_lst) + ==> read (memory :> bytes (ctxt_p,l1_curr_len)) s5 = + num_of_bytelist (aes256_xts_encrypt pt_in l1_curr_len iv key1_lst key2_lst)` *) + + (* Prove one block equivalence *) + DISCH_TAC THEN + IMP_REWRITE_TAC[SPECL [`ctxt_p:int64`; `l1_curr_len:num`; + `(aes256_xts_encrypt pt_in (l1_curr_len + 0x10) iv key1_lst key2_lst):byte list`; + `s5:armstate`] READ_BYTES_AND_BYTE128_MERGE] THEN + (*DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o SPECL [`iv:int128`; `key1_lst:int128 list`; + `key2_lst:int128 list`; `pt_in:byte list`]) THEN *) + + EXISTS_TAC `iv:int128` THEN EXISTS_TAC `key1_lst:int128 list` THEN + EXISTS_TAC `key2_lst:int128 list` THEN EXISTS_TAC `pt_in:byte list` THEN + (* `num_of_bytelist + (SUB_LIST (0x0,l1_curr_len) + (aes256_xts_encrypt pt_in (l1_curr_len + 0x10) iv key1_lst key2_lst)) = + num_of_bytelist (aes256_xts_encrypt pt_in l1_curr_len iv key1_lst key2_lst) /\ + l1_curr_len + 0x10 <= + LENGTH (aes256_xts_encrypt pt_in (l1_curr_len + 0x10) iv key1_lst key2_lst) /\ + num_of_bytelist + (aes256_xts_encrypt pt_in (l1_curr_len + 0x10) iv key1_lst key2_lst) = + num_of_bytelist + (SUB_LIST (0x0,l1_curr_len + 0x10) + (aes256_xts_encrypt pt_in (l1_curr_len + 0x10) iv key1_lst key2_lst))` + *) + REPEAT CONJ_TAC THENL [ + AP_TERM_TAC; + SUB_LIST_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS + + ASM_ARITH_TAC; + ] + + ANTS_TAC THENL + (* `l1_curr_len + 0x10 <= + LENGTH (aes256_xts_encrypt pt_in (l1_curr_len + 0x10) iv key1_lst key2_lst) /\ + read (memory :> bytes128 (word_add ctxt_p (word l1_curr_len))) s5 = + bytes_to_int128 (SUB_LIST (l1_curr_len,0x10) + (aes256_xts_encrypt pt_in (l1_curr_len + 0x10) iv key1_lst key2_lst)) /\ + read (memory :> bytes (ctxt_p,l1_curr_len)) s5 = + num_of_bytelist (SUB_LIST (0x0,l1_curr_len) + (aes256_xts_encrypt pt_in (l1_curr_len + 0x10) iv key1_lst key2_lst))` *) + [ REPEAT CONJ_TAC THENL [ (* 3 subgoals (9 total) *) + ASM_ARITH_TAC; + + (* Establish that one xts encrypt round is the same as + selecting one block of bytes from calling the top-level function. *) + REWRITE_TAC[aes256_xts_encrypt] THEN + SIMP_TAC[ARITH_RULE `~(l1_curr_len + 0x10 < 0x10)`] THEN + REWRITE_TAC[GSYM (ASSUME `0x10 * l1_curr_blocks = l1_curr_len`)] THEN + SIMP_TAC[ARITH_RULE `0x10 * l1_curr_blocks + 0x10 = 0x10 * (l1_curr_blocks + 0x1)`; + MOD_MULT] THEN + CONV_TAC (DEPTH_CONV let_CONV) THEN + IMP_REWRITE_TAC[SUB_0; DIV_MULT] THEN + (* Two cases: l1_curr_blocks = 0 then execute tail branch, else execute recursion branch *) + COND_CASES_TAC THENL (* 2 subgoals (9 total) *) + [ (* `l1_curr_blocks + 0x1 < 0x2`*) + SUBGOAL_THEN `l1_curr_blocks = 0` SUBST1_TAC THENL + [ UNDISCH_TAC `l1_curr_blocks + 0x1 < 2` THEN + ARITH_TAC ; ALL_TAC] THEN + CONV_TAC NUM_REDUCE_CONV THEN + + MP_TAC (SPECL [`0x0:num`; `0x0:num`; `pt_in:byte list`; `iv:int128`; `key1_lst:int128 list`; `key2_lst:int128 list`] + LENGTH_OF_AES256_XTS_ENCRYPT_TAIL) THEN + CONV_TAC NUM_REDUCE_CONV THEN REWRITE_TAC[ADD_0] THEN DISCH_TAC THEN + SUBGOAL_THEN `l1_curr_len = 0` SUBST1_TAC THENL + [ UNDISCH_TAC `l1_curr_blocks + 0x1 < 2` THEN + REWRITE_TAC[GSYM (ASSUME `0x10 * l1_curr_blocks = l1_curr_len`)] THEN + ARITH_TAC ; ALL_TAC] THEN + IMP_REWRITE_TAC[(ISPECL [`(aes256_xts_encrypt_tail 0x0 0x0 pt_in iv key1_lst key2_lst):byte list`; + `0x10:num`] SUB_LIST_LENGTH_IMPLIES)] THEN + REWRITE_TAC[AES256_XTS_ENCRYPT_TAIL_WHEN_1BLOCK] THEN + CONV_TAC NUM_RED_CONV THEN + + + ] @@ -4817,8 +4820,8 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( CONJ_TAC THENL [ - (* Main Loop invariant *) - ENSURES_WHILE_PAUP_TAC + (* Main Loop invariant *) + ENSURES_WHILE_PAUP_TAC `0` (* counter begin number *) `val (num_5blocks:int64)` (* counter end number *) `pc + 0x140` (* loop body start PC *) @@ -6517,7 +6520,7 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( DISCH_TAC THEN ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (8--9) THEN FIRST_X_ASSUM MP_TAC THEN - COND_CASES_TAC THENL + COND_CASES_TAC THENL (*?? *) [ (* Case: len % 0x50 = 0x10 *) DISCH_TAC THEN From f7052bd8ee1f86b2fbcd04c69dc92fefe3292ee6 Mon Sep 17 00:00:00 2001 From: Nevine Ebeid Date: Wed, 26 Nov 2025 11:32:30 -0500 Subject: [PATCH 094/132] Cipher-stealing: case tail != 0, loop invariant: Subgoal 2: Done, pending a new lemma. --- arm/proofs/aes-xts-armv8.ml | 341 ++++++++++++++---------------------- 1 file changed, 133 insertions(+), 208 deletions(-) diff --git a/arm/proofs/aes-xts-armv8.ml b/arm/proofs/aes-xts-armv8.ml index 9f7170e67..99096382e 100644 --- a/arm/proofs/aes-xts-armv8.ml +++ b/arm/proofs/aes-xts-armv8.ml @@ -3513,9 +3513,9 @@ let CIPHER_STEALING_ENC_CORRECT = time prove( ; ALL_TAC ] THEN - (* The cipher stealing branch *) + (* The cipher stealing branch; tail != 0 *) (* The byte-swap needs another invariant proof. *) - (* In the following "l1 means "less 1 block". This is to differentiate it from the decrypt case + (* In the following "l1" means "less 1 block". This is to differentiate it from the decrypt case where at the entry of cipher-stealing, we have one full block left to process and a tail, while in encrypt that full block was already processed and that's why we need to go back "less 1" to match the decrypt invariant. *) @@ -3741,82 +3741,30 @@ let CIPHER_STEALING_ENC_CORRECT = time prove( `s5:armstate`] READ_BYTES_AND_BYTE128_MERGE] THEN (*DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o SPECL [`iv:int128`; `key1_lst:int128 list`; `key2_lst:int128 list`; `pt_in:byte list`]) THEN *) - EXISTS_TAC `iv:int128` THEN EXISTS_TAC `key1_lst:int128 list` THEN EXISTS_TAC `key2_lst:int128 list` THEN EXISTS_TAC `pt_in:byte list` THEN - (* `num_of_bytelist - (SUB_LIST (0x0,l1_curr_len) - (aes256_xts_encrypt pt_in (l1_curr_len + 0x10) iv key1_lst key2_lst)) = - num_of_bytelist (aes256_xts_encrypt pt_in l1_curr_len iv key1_lst key2_lst) /\ - l1_curr_len + 0x10 <= - LENGTH (aes256_xts_encrypt pt_in (l1_curr_len + 0x10) iv key1_lst key2_lst) /\ - num_of_bytelist - (aes256_xts_encrypt pt_in (l1_curr_len + 0x10) iv key1_lst key2_lst) = - num_of_bytelist - (SUB_LIST (0x0,l1_curr_len + 0x10) - (aes256_xts_encrypt pt_in (l1_curr_len + 0x10) iv key1_lst key2_lst))` - *) - REPEAT CONJ_TAC THENL [ - AP_TERM_TAC; - SUB_LIST_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS - - ASM_ARITH_TAC; - ] - - ANTS_TAC THENL - (* `l1_curr_len + 0x10 <= + (* `num_of_bytelist (SUB_LIST (0x0,l1_curr_len) + (aes256_xts_encrypt pt_in (l1_curr_len + 0x10) iv key1_lst key2_lst)) = + num_of_bytelist (aes256_xts_encrypt pt_in l1_curr_len iv key1_lst key2_lst) /\ + l1_curr_len + 0x10 <= LENGTH (aes256_xts_encrypt pt_in (l1_curr_len + 0x10) iv key1_lst key2_lst) /\ - read (memory :> bytes128 (word_add ctxt_p (word l1_curr_len))) s5 = - bytes_to_int128 (SUB_LIST (l1_curr_len,0x10) - (aes256_xts_encrypt pt_in (l1_curr_len + 0x10) iv key1_lst key2_lst)) /\ - read (memory :> bytes (ctxt_p,l1_curr_len)) s5 = - num_of_bytelist (SUB_LIST (0x0,l1_curr_len) - (aes256_xts_encrypt pt_in (l1_curr_len + 0x10) iv key1_lst key2_lst))` *) - [ REPEAT CONJ_TAC THENL [ (* 3 subgoals (9 total) *) - ASM_ARITH_TAC; - - (* Establish that one xts encrypt round is the same as - selecting one block of bytes from calling the top-level function. *) - REWRITE_TAC[aes256_xts_encrypt] THEN - SIMP_TAC[ARITH_RULE `~(l1_curr_len + 0x10 < 0x10)`] THEN - REWRITE_TAC[GSYM (ASSUME `0x10 * l1_curr_blocks = l1_curr_len`)] THEN - SIMP_TAC[ARITH_RULE `0x10 * l1_curr_blocks + 0x10 = 0x10 * (l1_curr_blocks + 0x1)`; - MOD_MULT] THEN - CONV_TAC (DEPTH_CONV let_CONV) THEN - IMP_REWRITE_TAC[SUB_0; DIV_MULT] THEN - (* Two cases: l1_curr_blocks = 0 then execute tail branch, else execute recursion branch *) - COND_CASES_TAC THENL (* 2 subgoals (9 total) *) - [ (* `l1_curr_blocks + 0x1 < 0x2`*) - SUBGOAL_THEN `l1_curr_blocks = 0` SUBST1_TAC THENL - [ UNDISCH_TAC `l1_curr_blocks + 0x1 < 2` THEN - ARITH_TAC ; ALL_TAC] THEN - CONV_TAC NUM_REDUCE_CONV THEN - - MP_TAC (SPECL [`0x0:num`; `0x0:num`; `pt_in:byte list`; `iv:int128`; `key1_lst:int128 list`; `key2_lst:int128 list`] - LENGTH_OF_AES256_XTS_ENCRYPT_TAIL) THEN - CONV_TAC NUM_REDUCE_CONV THEN REWRITE_TAC[ADD_0] THEN DISCH_TAC THEN - SUBGOAL_THEN `l1_curr_len = 0` SUBST1_TAC THENL - [ UNDISCH_TAC `l1_curr_blocks + 0x1 < 2` THEN - REWRITE_TAC[GSYM (ASSUME `0x10 * l1_curr_blocks = l1_curr_len`)] THEN - ARITH_TAC ; ALL_TAC] THEN - IMP_REWRITE_TAC[(ISPECL [`(aes256_xts_encrypt_tail 0x0 0x0 pt_in iv key1_lst key2_lst):byte list`; - `0x10:num`] SUB_LIST_LENGTH_IMPLIES)] THEN - REWRITE_TAC[AES256_XTS_ENCRYPT_TAIL_WHEN_1BLOCK] THEN - CONV_TAC NUM_RED_CONV THEN - - - ] + num_of_bytelist (aes256_xts_encrypt pt_in (l1_curr_len + 0x10) iv key1_lst key2_lst) = + num_of_bytelist (SUB_LIST (0x0,l1_curr_len + 0x10) + (aes256_xts_encrypt pt_in (l1_curr_len + 0x10) iv key1_lst key2_lst))` *) + REPEAT CONJ_TAC THENL [ (* 3 subgoals (8 total) *) + AP_TERM_TAC THEN + REWRITE_TAC[GSYM (ASSUME `0x10 * l1_curr_blocks = l1_curr_len`)] THEN + IMP_REWRITE_TAC[SUB_LIST_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS]; + ASM_ARITH_TAC; + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] + ]; - (* `read (memory :> bytes128 (word_sub (word_add ctxt_p (word curr_len)) (word 0x10))) s5 - = cipher_stealing_enc_inv (val tail_len) curr_len (val tail_len) CC pt_in` - changed to - `read (memory :> bytes128 (word_add ctxt_p (word (curr_len - 0x10)))) s5 = - cipher_stealing_enc_inv (val tail_len) curr_len (val tail_len) CC pt_in` - *) + (* `read (memory :> bytes128 (word_sub (word_add ctxt_p (word l1_curr_len)) (word 0x10))) s5 + = cipher_stealing_inv (val tail_len) l1_curr_len (val tail_len) CC pt_in` *) REWRITE_TAC[cipher_stealing_inv; SUB_REFL] THEN - SUBGOAL_THEN `SUB_LIST (val (tail_len:int64),0x0) (SUB_LIST (curr_len,val tail_len) (pt_in:byte list)) = []` SUBST1_TAC THENL + SUBGOAL_THEN `SUB_LIST (val (tail_len:int64),0x0) (SUB_LIST (l1_curr_len + 0x10,val tail_len) (pt_in:byte list)) = []` SUBST1_TAC THENL [ REWRITE_TAC[SUB_LIST_CLAUSES]; ALL_TAC] THEN REWRITE_TAC[CONJUNCT1 APPEND] THEN SUBGOAL_THEN `APPEND (SUB_LIST (0x0,val (tail_len:int64)) (int128_to_bytes CC)) @@ -3825,118 +3773,95 @@ let CIPHER_STEALING_ENC_CORRECT = time prove( [ MP_TAC (ISPECL [`int128_to_bytes CC`; `val (tail_len:int64)`; `16 - val (tail_len:int64)`; `0`] (GSYM SUB_LIST_SPLIT)) THEN IMP_REWRITE_TAC[ADD_CLAUSES; ARITH_RULE `!x. x < 16 ==> x + 16 - x = 16`] THEN DISCH_TAC THEN - IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES; LENGTH_OF_INT128_TO_BYTES] - ; ALL_TAC] THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES; LENGTH_OF_INT128_TO_BYTES] ; ALL_TAC] THEN REWRITE_TAC[BYTES_TO_INT128_OF_INT128_TO_BYTES] THEN (* `read (memory :> bytes128 (word_sub (word_add ctxt_p (word curr_len)) (word 0x10))) s5 = CC` *) (* Apply READ_CT_LAST_LEMMA with proper arguments *) - MP_TAC (SPECL [`ctxt_p:int64`; `curr_len - 16:num`; `word curr_len:int64`; - `aes256_xts_encrypt pt_in curr_len iv key1_lst key2_lst:byte list`; `s5:armstate`] READ_CT_LAST_LEMMA) THEN - UNDISCH_THEN `val ((word curr_len):int64) = curr_len` + MP_TAC (SPECL [`ctxt_p:int64`; `l1_curr_len:num`; `word (l1_curr_len+0x10):int64`; + `aes256_xts_encrypt pt_in (l1_curr_len+0x10) iv key1_lst key2_lst:byte list`; `s5:armstate`] READ_CT_LAST_LEMMA) THEN + UNDISCH_THEN `val ((word (l1_curr_len + 0x10)):int64) = l1_curr_len + 0x10` (fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th]) THEN REWRITE_TAC[th] THEN ASSUME_TAC th) THEN ASM_SIMP_TAC[] THEN - (* `(curr_len - 0x10 + 0x10 <= curr_len /\ - LENGTH (aes256_xts_encrypt pt_in curr_len iv key1_lst key2_lst) = curr_len - ==> read (memory :> bytes128 (word_add ctxt_p (word (curr_len - 0x10)))) s5 = - bytes_to_int128 (SUB_LIST (curr_len - 0x10,0x10) - (aes256_xts_encrypt pt_in curr_len iv key1_lst key2_lst))) - ==> read (memory :> bytes128 (word_sub (word_add ctxt_p (word curr_len)) (word 0x10))) s5 - = CC` *) - ANTS_TAC THENL (* 6 total *) - [ CONJ_TAC THENL (* 7 total *) - [ UNDISCH_TAC `curr_len >= 0x10` THEN ARITH_TAC; - - (* `LENGTH (aes256_xts_encrypt pt_in curr_len iv key1_lst key2_lst) = curr_len`*) - REWRITE_TAC[GSYM (ASSUME `0x10 * curr_blocks = curr_len`); LENGTH_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS] - ] THEN + (* `(l1_curr_len + 0x10 <= l1_curr_len + 0x10 /\ + LENGTH (aes256_xts_encrypt pt_in (l1_curr_len + 0x10) iv key1_lst key2_lst) = + l1_curr_len + 0x10 + ==> read (memory :> bytes128 (word_add ctxt_p (word l1_curr_len))) s5 = + bytes_to_int128 (SUB_LIST (l1_curr_len,0x10) + (aes256_xts_encrypt pt_in (l1_curr_len + 0x10) iv key1_lst key2_lst))) + ==> read (memory :> bytes128 (word_add ctxt_p (word l1_curr_len))) s5 = CC` *) + ANTS_TAC THENL + [ CONJ_TAC THENL + [ ARITH_TAC; + + (* `LENGTH (aes256_xts_encrypt pt_in l1_curr_len iv key1_lst key2_lst) = l1_curr_len`*) + REWRITE_TAC[GSYM (ASSUME `0x10 * l1_curr_blocks = l1_curr_len`); + ARITH_RULE `0x10 * l1_curr_blocks + 0x10 = 0x10 * (l1_curr_blocks + 0x1)`; + LENGTH_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS] ] + ; ALL_TAC ] THEN - (* - SUBGOAL_THEN `(word_sub (word_add (ctxt_p:int64) (word curr_len)) (word 0x10)) - = (word_add ctxt_p (word (curr_len - 0x10)))` SUBST1_TAC THENL - [ REWRITE_TAC[WORD_SUB] THEN - ASM_SIMP_TAC[ARITH_RULE `curr_len >= 0x10 ==> 0x10 <= curr_len`] THEN - WORD_ARITH_TAC - ; ALL_TAC] THEN - *) DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN - (* `bytes_to_int128 (SUB_LIST (curr_len - 0x10,0x10) - (aes256_xts_encrypt pt_in curr_len iv key1_lst key2_lst)) - = CC`. *) + (* `bytes_to_int128 (SUB_LIST (l1_curr_len,0x10) + (aes256_xts_encrypt pt_in (l1_curr_len + 0x10) iv key1_lst key2_lst)) + = CC` *) (* Try proving the subgoal by expanding out aes256_xts_encrypt and then apply related LENGTH_OF_xxx and SUB_LIST_xxx lemmas *) REWRITE_TAC[aes256_xts_encrypt] THEN - IMP_REWRITE_TAC[ARITH_RULE `curr_len >= 0x10 ==> ~(curr_len < 0x10)`] THEN - SUBGOAL_THEN `curr_len MOD 0x10 = 0` SUBST1_TAC THENL - [ REWRITE_TAC[GSYM (ASSUME `0x10 * curr_blocks = curr_len`); MOD_MULT] ; ALL_TAC ] THEN + SIMP_TAC[ARITH_RULE `~(l1_curr_len + 0x10 < 0x10)`] THEN + REWRITE_TAC[GSYM (ASSUME `0x10 * l1_curr_blocks = l1_curr_len`)] THEN + SIMP_TAC[ARITH_RULE `0x10 * l1_curr_blocks + 0x10 = 0x10 * (l1_curr_blocks + 0x1)`; + MOD_MULT] THEN CONV_TAC (DEPTH_CONV let_CONV) THEN - REWRITE_TAC[SUB_0] THEN + IMP_REWRITE_TAC[SUB_0; DIV_MULT] THEN + COND_CASES_TAC THENL - [ (* curr_len DIV 0x10 < 0x2 *) - EXPAND_TAC "CC" THEN - MP_TAC (SPECL [`0:num`; `0x0:num`; `pt_in:byte list`; `iv:int128`; - `key1_lst:int128 list`; `key2_lst:int128 list`] - LENGTH_OF_AES256_XTS_ENCRYPT_TAIL) THEN + [ (* `l1_curr_blocks + 0x1 < 0x2` *) + MP_TAC (SPECL [`0x0:num`; `0x0:num`; `pt_in:byte list`; `iv:int128`; + `key1_lst:int128 list`; `key2_lst:int128 list`] + LENGTH_OF_AES256_XTS_ENCRYPT_TAIL) THEN CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC THEN - SUBGOAL_THEN `curr_len = 0x10` ASSUME_TAC THENL - [ UNDISCH_TAC `curr_len >= 0x10` THEN - UNDISCH_TAC `curr_len DIV 0x10 < 0x2` THEN - REWRITE_TAC[GSYM (ASSUME `0x10 * curr_blocks = curr_len`)] THEN - SIMP_TAC[ARITH_RULE `(0x10 * curr_blocks) DIV 0x10 = curr_blocks`] THEN - (* or SIMP_TAC[DIV_MULT; ARITH] THEN *) - ARITH_TAC - ; ALL_TAC ] THEN - REWRITE_TAC[ASSUME `curr_len = 0x10`; SUB_REFL] THEN - - SUBGOAL_THEN `curr_blocks = 0x1` ASSUME_TAC THENL - [ UNDISCH_TAC `0x10 * curr_blocks = curr_len` THEN - REWRITE_TAC[ASSUME `curr_len = 0x10`] THEN - ARITH_TAC - ; ALL_TAC ] THEN - REWRITE_TAC[ASSUME `curr_blocks = 0x1`; SUB_REFL] THEN - - SIMP_TAC[ASSUME `LENGTH (aes256_xts_encrypt_tail 0x0 0x0 pt_in iv key1_lst key2_lst) = 0x10`; - SUB_LIST_LENGTH_IMPLIES] THEN - + EXPAND_TAC "CC" THEN + SUBGOAL_THEN `l1_curr_len = 0` SUBST1_TAC THENL + [ UNDISCH_TAC `l1_curr_blocks + 0x1 < 2` THEN + REWRITE_TAC[GSYM (ASSUME `0x10 * l1_curr_blocks = l1_curr_len`)] THEN + ARITH_TAC ; ALL_TAC] THEN + IMP_REWRITE_TAC[(ISPECL [`(aes256_xts_encrypt_tail 0x0 0x0 pt_in iv key1_lst key2_lst):byte list`; + `0x10:num`] SUB_LIST_LENGTH_IMPLIES)] THEN REWRITE_TAC[AES256_XTS_ENCRYPT_TAIL_WHEN_1BLOCK] THEN - SIMPLE_ARITH_TAC - ; ALL_TAC ] THEN - - (* ~(curr_len DIV 0x10 < 0x2) *) - SUBGOAL_THEN `curr_blocks >= 2` ASSUME_TAC THENL - [ UNDISCH_TAC `~(curr_len DIV 0x10 < 0x2)` THEN - UNDISCH_TAC `0x10 * curr_blocks = curr_len` THEN - ARITH_TAC - ; ALL_TAC] THEN - SUBGOAL_THEN `curr_len DIV 0x10 = curr_blocks` ASSUME_TAC THENL - [ UNDISCH_TAC `0x10 * curr_blocks = curr_len` THEN - ARITH_TAC - ; ALL_TAC] THEN - POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th]) THEN REWRITE_TAC[th]) THEN + SUBGOAL_THEN `l1_curr_blocks = 0` SUBST1_TAC THENL + [ UNDISCH_TAC `l1_curr_blocks + 0x1 < 2` THEN ARITH_TAC ; ALL_TAC] THEN + CONV_TAC NUM_REDUCE_CONV; - MP_TAC (SPECL [`0`;`(curr_blocks - 2):num`; `pt_in:byte list`; `iv:int128`; - `key1_lst:int128 list`; `key2_lst:int128 list`] - LENGTH_OF_AES256_XTS_ENCRYPT_REC) THEN - ASM_SIMP_TAC[ARITH_RULE `curr_blocks >= 0x2 ==> ~(curr_blocks - 0x2 < 0x0)`] THEN - IMP_REWRITE_TAC[SUB_0; ARITH_RULE `curr_blocks >= 0x2 ==> curr_blocks - 2 + 1 = curr_blocks -1`] THEN - IMP_REWRITE_TAC[ARITH_RULE `0x10 * curr_blocks = curr_len ==> (curr_blocks - 0x1) * 0x10 = curr_len - 0x10`] THEN - DISCH_TAC THEN - IMP_REWRITE_TAC[SUB_LIST_APPEND_RIGHT_LEMMA] THEN - (* `bytes_to_int128 (SUB_LIST (0x0,0x10) (aes256_xts_encrypt_tail (curr_blocks - 0x1) 0x0 pt_in iv key1_lst key2_lst)) - = CC`*) - MP_TAC (SPECL [`(curr_blocks - 0x1):num`; `0x0:num`; `pt_in:byte list`; `iv:int128`; - `key1_lst:int128 list`; `key2_lst:int128 list`] - LENGTH_OF_AES256_XTS_ENCRYPT_TAIL) THEN - CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC THEN - ASM_SIMP_TAC[SUB_LIST_LENGTH_IMPLIES] THEN - REWRITE_TAC[AES256_XTS_ENCRYPT_TAIL_WHEN_1BLOCK] THEN - EXPAND_TAC "CC" THEN - IMP_REWRITE_TAC[ARITH_RULE `0x10 * curr_blocks = curr_len ==> (curr_blocks - 0x1) * 0x10 = curr_len - 0x10`]; + (* ~(l1_curr_len DIV 0x10 < 0x2) *) + CONV_TAC NUM_REDUCE_CONV THEN + SUBGOAL_THEN `l1_curr_blocks >= 1` ASSUME_TAC THENL + [ ASM_ARITH_TAC ; ALL_TAC ] THEN + IMP_REWRITE_TAC[ARITH_RULE `l1_curr_blocks >= 0x1 ==> (l1_curr_blocks + 0x1) - 0x2 = l1_curr_blocks - 0x1`; + ARITH_RULE `l1_curr_blocks >= 0x1 ==> (l1_curr_blocks + 0x1) - 0x1 = l1_curr_blocks`] THEN + MP_TAC (SPECL [`0`;`(l1_curr_blocks - 1):num`; `pt_in:byte list`; `iv:int128`; + `key1_lst:int128 list`; `key2_lst:int128 list`] + LENGTH_OF_AES256_XTS_ENCRYPT_REC) THEN + ASM_SIMP_TAC[ARITH_RULE `l1_curr_blocks >= 0x1 ==> ~(l1_curr_blocks - 0x1 < 0x0)`] THEN + IMP_REWRITE_TAC[SUB_0; ARITH_RULE `l1_curr_blocks >= 0x1 ==> l1_curr_blocks - 1 + 1 = l1_curr_blocks`] THEN + REWRITE_TAC[GSYM (ASSUME `0x10 * l1_curr_blocks = l1_curr_len`)] THEN + IMP_REWRITE_TAC[SUB_LIST_APPEND_RIGHT_LEMMA] THEN + DISCH_TAC THEN + (* `bytes_to_int128 (SUB_LIST (0x0,0x10) (aes256_xts_encrypt_tail l1_curr_blocks 0x0 pt_in iv key1_lst key2_lst)) + = CC /\ l1_curr_blocks * 0x10 = l1_curr_len`*) + MP_TAC (SPECL [`l1_curr_blocks:num`; `0x0:num`; `pt_in:byte list`; `iv:int128`; + `key1_lst:int128 list`; `key2_lst:int128 list`] + LENGTH_OF_AES256_XTS_ENCRYPT_TAIL) THEN + CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC THEN + ASM_SIMP_TAC[SUB_LIST_LENGTH_IMPLIES] THEN + REWRITE_TAC[AES256_XTS_ENCRYPT_TAIL_WHEN_1BLOCK] THEN + EXPAND_TAC "CC" THEN + REWRITE_TAC[GSYM (ASSUME `0x10 * l1_curr_blocks = l1_curr_len`); CONJUNCT1 MULT_AC] + ]; (* `forall i. i < val (word 0x0) - ==> read (memory :> bytes8 (word_add (word_add ctxt_p (word (curr_len + val tail_len))) + ==> read (memory :> bytes8 (word_add (word_add ctxt_p (word (l1_curr_len + val tail_len))) (word i))) s5 = EL i (SUB_LIST (val tail_len,0x0) (int128_to_bytes CC))`*) REWRITE_TAC[VAL_WORD_0] THEN ARITH_TAC @@ -3946,8 +3871,8 @@ let CIPHER_STEALING_ENC_CORRECT = time prove( REPEAT STRIP_TAC THEN (* For non-overlapping and MAYCHANGE address reasoning *) - SUBGOAL_THEN `curr_len + i < val (len:int64)` ASSUME_TAC THENL - [ REWRITE_TAC[GSYM (ASSUME `acc_len num_5blocks len_full_blocks = curr_len`)] THEN + SUBGOAL_THEN `l1_curr_len + i < val (len:int64)` ASSUME_TAC THENL + [ REWRITE_TAC[GSYM (ASSUME `acc_len num_5blocks len_full_blocks = l1_curr_len`)] THEN MP_TAC (SPECL [`num_5blocks:int64`; `len_full_blocks:int64`] VALUE_OF_ACC_LEN) THEN REPEAT_N 3 (ANTS_TAC THENL [ASM_ARITH_TAC ORELSE ASM_SIMP_TAC[]; ALL_TAC]) THEN SIMP_TAC[] THEN DISCH_TAC THEN @@ -3961,9 +3886,9 @@ let CIPHER_STEALING_ENC_CORRECT = time prove( ASM_ARITH_TAC ; ALL_TAC ] THEN - SUBGOAL_THEN `curr_len >= 16` ASSUME_TAC THENL + SUBGOAL_THEN `l1_curr_len >= 16` ASSUME_TAC THENL [ - REWRITE_TAC[GSYM (ASSUME `acc_len num_5blocks len_full_blocks = curr_len`)] THEN + REWRITE_TAC[GSYM (ASSUME `acc_len num_5blocks len_full_blocks = l1_curr_len`)] THEN MP_TAC (SPECL [`num_5blocks:int64`; `len_full_blocks:int64`] VALUE_OF_ACC_LEN) THEN REPEAT_N 3 (ANTS_TAC THENL [ASM_ARITH_TAC ORELSE ASM_SIMP_TAC[]; ALL_TAC]) THEN SIMP_TAC[] THEN DISCH_TAC THEN @@ -3974,8 +3899,8 @@ let CIPHER_STEALING_ENC_CORRECT = time prove( ASM_ARITH_TAC ; ALL_TAC ] THEN - SUBGOAL_THEN `(word_add (word_add (ctxt_p:int64) (word (curr_len - 0x10))) (word i)) = - word_add (ctxt_p:int64) (word (curr_len - 0x10 + i))` ASSUME_TAC THENL + SUBGOAL_THEN `(word_add (word_add (ctxt_p:int64) (word (l1_curr_len - 0x10))) (word i)) = + word_add (ctxt_p:int64) (word (l1_curr_len - 0x10 + i))` ASSUME_TAC THENL [ REWRITE_TAC[GSYM WORD_ADD_ASSOC] THEN AP_TERM_TAC THEN REWRITE_TAC[WORD_ADD;WORD_SUB] THEN @@ -3986,8 +3911,8 @@ let CIPHER_STEALING_ENC_CORRECT = time prove( EXISTS_TAC `MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI ,, MAYCHANGE [X19; X20; X21; X22],, MAYCHANGE [Q8; Q9; Q10; Q11; Q12; Q13; Q14; Q15],, - MAYCHANGE [memory :> bytes8 (word_add ctxt_p (word (curr_len - 0x10 + i)))],, - MAYCHANGE [memory :> bytes8 (word_add ctxt_p (word (curr_len + i)))]` THEN + MAYCHANGE [memory :> bytes8 (word_add ctxt_p (word (l1_curr_len - 0x10 + i)))],, + MAYCHANGE [memory :> bytes8 (word_add ctxt_p (word (l1_curr_len + i)))]` THEN REWRITE_TAC[MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI] THEN CONJ_TAC THENL [ REPEAT (GEN_REWRITE_TAC ONCE_DEPTH_CONV [GSYM SEQ_ASSOC] THEN @@ -3996,7 +3921,7 @@ let CIPHER_STEALING_ENC_CORRECT = time prove( SUBSUMED_MAYCHANGE_TAC; ALL_TAC] THEN REWRITE_TAC[byte_list_at] THEN - UNDISCH_THEN `val ((word curr_len):int64) = curr_len` + UNDISCH_THEN `val ((word l1_curr_len):int64) = l1_curr_len` (fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th]) THEN REWRITE_TAC[th]) THEN ENSURES_INIT_TAC "s0" THEN @@ -4036,9 +3961,9 @@ let CIPHER_STEALING_ENC_CORRECT = time prove( (* The symbolic simulation does not capture the LDR/STR at a byte level with i as the iterator, because it doesn't know which i. So the following steps are to break the cases for values of i *) (****TODO: change it to _inv *) - (* Read a byte from Cm (at location curr_len -16 + i into w15 *) - MP_TAC (SPECL [`(word_add ctxt_p (word (curr_len - 0x10))):int64`; `word i:int64`; `s0:armstate`; - `(cipher_stealing_enc_inv (i + 0x1) curr_len (val (tail_len:int64)) CC pt_in):int128`] + (* Read a byte from Cm (at location l1_curr_len -16 + i into w15 *) + MP_TAC (SPECL [`(word_add ctxt_p (word (l1_curr_len - 0x10))):int64`; `word i:int64`; `s0:armstate`; + `(cipher_stealing_enc_inv (i + 0x1) l1_curr_len (val (tail_len:int64)) CC pt_in):int128`] SELECT_ONE_BYTE_FROM_BLOCK) THEN SUBGOAL_THEN `val ((word i):int64) < 0x10` ASSUME_TAC THENL @@ -4048,40 +3973,40 @@ let CIPHER_STEALING_ENC_CORRECT = time prove( ASM_SIMP_TAC[] THEN REPEAT STRIP_TAC THEN (* Added assumption - 65 [`read (memory :> bytes8 (word_add (word_sub (word_add ctxt_p (word curr_len)) (word 0x10)) + 65 [`read (memory :> bytes8 (word_add (word_sub (word_add ctxt_p (word l1_curr_len)) (word 0x10)) (word i))) s0 = EL (val (word i)) - (int128_to_bytes (cipher_stealing_enc_inv (i + 0x1) curr_len (val tail_len) CC pt_in))` *) + (int128_to_bytes (cipher_stealing_enc_inv (i + 0x1) l1_curr_len (val tail_len) CC pt_in))` *) - (* Read a byte from Pm at location curr_len + i into w14 *) - MP_TAC (SPECL [`ptxt_p:int64`; `len:int64`; `(word_add (word curr_len) (word i)):int64`; + (* Read a byte from Pm at location l1_curr_len + i into w14 *) + MP_TAC (SPECL [`ptxt_p:int64`; `len:int64`; `(word_add (word l1_curr_len) (word i)):int64`; `pt_in:byte list`; `s0:armstate`] SELECT_ONE_BYTE_FROM_FORALL) THEN - SUBGOAL_THEN `val (word_add ((word curr_len):int64) (word i)) < val (len:int64)` ASSUME_TAC THENL + SUBGOAL_THEN `val (word_add ((word l1_curr_len):int64) (word i)) < val (len:int64)` ASSUME_TAC THENL [ REWRITE_TAC[WORD_RULE `!a b. word_add ((word a):int64) (word b) = word (a + b)`] THEN IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN ASM_ARITH_TAC; ALL_TAC] THEN ASM_SIMP_TAC[] THEN STRIP_TAC THEN (* Added assumption - 67 [`read (memory :> bytes8 (word_add ptxt_p (word_add (word curr_len) (word i)))) s0 - = EL (val (word_add (word curr_len) (word i))) pt_in`]*) + 67 [`read (memory :> bytes8 (word_add ptxt_p (word_add (word l1_curr_len) (word i)))) s0 + = EL (val (word_add (word l1_curr_len) (word i))) pt_in`]*) (****TODO: change it to _inv *) - (* Break the `read (memory :> bytes128 (word_sub (word_add ctxt_p (word curr_len)) (word 0x10))) s0 + (* Break the `read (memory :> bytes128 (word_sub (word_add ctxt_p (word l1_curr_len)) (word 0x10))) s0 into bytes using BREAK_ONE_BLOCK_INTO_BYTES *) - MP_TAC (SPECL [`(word_add ctxt_p (word (curr_len - 0x10))):int64`; `s0:armstate`; - `(cipher_stealing_enc_inv (i + 0x1) curr_len (val (tail_len:int64)) CC pt_in):int128`] + MP_TAC (SPECL [`(word_add ctxt_p (word (l1_curr_len - 0x10))):int64`; `s0:armstate`; + `(cipher_stealing_enc_inv (i + 0x1) l1_curr_len (val (tail_len:int64)) CC pt_in):int128`] BREAK_ONE_BLOCK_INTO_BYTES) THEN ASM_SIMP_TAC[] THEN REPEAT STRIP_TAC THEN (* For address matching when symbolic simulation *) - SUBGOAL_THEN `word_add (ptxt_p:int64) (word_add (word curr_len) (word i)) = - word_add ptxt_p (word (curr_len + i))` SUBST_ALL_TAC THENL + SUBGOAL_THEN `word_add (ptxt_p:int64) (word_add (word l1_curr_len) (word i)) = + word_add ptxt_p (word (l1_curr_len + i))` SUBST_ALL_TAC THENL [ REWRITE_TAC[WORD_RULE `!a b. word_add ((word a):int64) (word b) = word (a + b)`; ADD_ASSOC] ; ALL_TAC] THEN - SUBGOAL_THEN `word_add (word_add (ctxt_p:int64) (word (curr_len - 0x10))) (word i) - = word_add ctxt_p (word (curr_len - 0x10 + i))` ASSUME_TAC THENL + SUBGOAL_THEN `word_add (word_add (ctxt_p:int64) (word (l1_curr_len - 0x10))) (word i) + = word_add ctxt_p (word (l1_curr_len - 0x10 + i))` ASSUME_TAC THENL [ CONV_TAC WORD_RULE; ALL_TAC ] THEN POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th]) THEN ASSUME_TAC th) THEN @@ -4093,46 +4018,46 @@ let CIPHER_STEALING_ENC_CORRECT = time prove( (*** - SUBGOAL_THEN `word_sub ((word (curr_len:num)):int64) (word_sub (word 0x10) (word i)) - = word (curr_len - 0x10 + i)` ASSUME_TAC THENL - [ UNDISCH_TAC `curr_len >= 0x10` THEN + SUBGOAL_THEN `word_sub ((word (l1_curr_len:num)):int64) (word_sub (word 0x10) (word i)) + = word (l1_curr_len - 0x10 + i)` ASSUME_TAC THENL + [ UNDISCH_TAC `l1_curr_len >= 0x10` THEN SIMP_TAC[GE; WORD_ADD; WORD_SUB; LT_IMP_LE] THEN CONV_TAC WORD_RULE ; ALL_TAC ] - (* `word_add (word_sub (word_add (ctxt_p:int64) (word curr_len)) (word 0x10)) (word i) = *) - SUBGOAL_THEN `word_add (ctxt_p:int64) (word_sub (word curr_len) (word (0x10-i))) - = word_add ctxt_p (word (curr_len - 0x10 + i))` ASSUME_TAC THENL - [ UNDISCH_TAC `curr_len >= 0x10` THEN + (* `word_add (word_sub (word_add (ctxt_p:int64) (word l1_curr_len)) (word 0x10)) (word i) = *) + SUBGOAL_THEN `word_add (ctxt_p:int64) (word_sub (word l1_curr_len) (word (0x10-i))) + = word_add ctxt_p (word (l1_curr_len - 0x10 + i))` ASSUME_TAC THENL + [ UNDISCH_TAC `l1_curr_len >= 0x10` THEN ASM_SIMP_TAC[GE; WORD_ADD; WORD_SUB; LT_IMP_LE] ; ALL_TAC ] THEN *) (* Will I need the following to have (0x10 - i) in the assumptions? - SUBGOAL_THEN `word_sub ((word (curr_len:num)):int64) (word (0x10 - i)) - = word (curr_len - (0x10 - i))` ASSUME_TAC THENL - [ UNDISCH_TAC `curr_len >= 0x10` THEN + SUBGOAL_THEN `word_sub ((word (l1_curr_len:num)):int64) (word (0x10 - i)) + = word (l1_curr_len - (0x10 - i))` ASSUME_TAC THENL + [ UNDISCH_TAC `l1_curr_len >= 0x10` THEN SIMP_TAC[WORD_SUB; GE] THEN - SIMP_TAC[ARITH_RULE `0x10 <= curr_len ==> (0x10 - i) <= curr_len`] + SIMP_TAC[ARITH_RULE `0x10 <= l1_curr_len ==> (0x10 - i) <= l1_curr_len`] ; ALL_TAC ] THEN - SUBGOAL_THEN `curr_len - (0x10 - i) = curr_len - 0x10 + i` SUBST_ALL_TAC THENL - [ UNDISCH_TAC `curr_len >= 0x10` THEN + SUBGOAL_THEN `l1_curr_len - (0x10 - i) = l1_curr_len - 0x10 + i` SUBST_ALL_TAC THENL + [ UNDISCH_TAC `l1_curr_len >= 0x10` THEN UNDISCH_TAC `i < 0x10` THEN ARITH_TAC ; ALL_TAC ] THEN *) - (* (word_add (word_add ctxt_p (word_sub (word curr_len) (word 0x10))) (word 0xi)))*) + (* (word_add (word_add ctxt_p (word_sub (word l1_curr_len) (word 0x10))) (word 0xi)))*) - SUBGOAL_THEN `word_sub (word_add ctxt_p (word curr_len)) (word 0x10):int64 = - word_add ctxt_p (word(curr_len - 0x10))` SUBST_ALL_TAC THENL + SUBGOAL_THEN `word_sub (word_add ctxt_p (word l1_curr_len)) (word 0x10):int64 = + word_add ctxt_p (word(l1_curr_len - 0x10))` SUBST_ALL_TAC THENL [ RULE_ASSUM_TAC(REWRITE_RULE[GE]) THEN ASM_SIMP_TAC[WORD_SUB] THEN CONV_TAC WORD_RULE; (* From John, it put all addresses in the read memory assumptions in canonical form *) CHANGED_TAC(RULE_ASSUM_TAC(CONV_RULE(ONCE_DEPTH_CONV NORMALIZE_RELATIVE_ADDRESS_CONV)))] THEN (*(* Is this needed for nonoverlapping machinery in symbolic simulation? *) - SUBGOAL_THEN `curr_len - 0x10 + i < val (len:int64)` ASSUME_TAC THENL + SUBGOAL_THEN `l1_curr_len - 0x10 + i < val (len:int64)` ASSUME_TAC THENL (* word_ult () () *) - [ UNDISCH_TAC `curr_len + i < val (len:int64)` THEN ARITH_TAC; ALL_TAC ] THEN *) + [ UNDISCH_TAC `l1_curr_len + i < val (len:int64)` THEN ARITH_TAC; ALL_TAC ] THEN *) (* Went back on this suggestion (* l1_curr_len is curr_len less 1 block*) @@ -4303,7 +4228,7 @@ SUBGOAL_THEN `curr_len = short_len + 0x10` SUBST_ALL_TAC THENL ==> read (memory :> bytes8 (word_add ctxt_p (word i))) s5 = EL i (aes256_xts_encrypt pt_in curr_len iv key1_lst key2_lst)` *) ] - + ] );; (* Proof: Less than 2 blocks *) From 3d0374bc45ef20a0aebcb9cd42b5a0566cf692f9 Mon Sep 17 00:00:00 2001 From: Nevine Ebeid Date: Thu, 27 Nov 2025 18:00:46 -0500 Subject: [PATCH 095/132] Cipher-stealing: case tail != 0, loop invariant: Subgoal 3: case i=3 working, now case i = 0 is wip. Subgoal 2 new lemma from Yan working --- arm/proofs/aes-xts-armv8.ml | 568 +++++++++++++++++++----------------- 1 file changed, 296 insertions(+), 272 deletions(-) diff --git a/arm/proofs/aes-xts-armv8.ml b/arm/proofs/aes-xts-armv8.ml index 99096382e..aa88f0d24 100644 --- a/arm/proofs/aes-xts-armv8.ml +++ b/arm/proofs/aes-xts-armv8.ml @@ -1637,6 +1637,12 @@ let TL_SUB_LIST_CONS_GENERAL = prove( ] );; +let EL_SUB_LIST_TRIVIAL = prove( + `!i n (l:A list). i < LENGTH l /\ 0 < n ==> EL 0x0 (SUB_LIST (i, n) l) = EL i l`, + REWRITE_TAC[EL] THEN + SIMP_TAC[HD_SUB_LIST_CONS_GENERAL] +);; + let EL_SUB_LIST = prove( `!(i:num) n (l:A list). i < n /\ n <= LENGTH l ==> EL i (SUB_LIST (0, n) l) = EL i l`, @@ -1698,6 +1704,43 @@ let EL_SUB_LIST_SHIFT = prove( ASM_ARITH_TAC );; +(* Differs from Encrypt in that the address is written in a canonical form *) + let BYTE_LIST_AT_SPLIT_BACKWARDS = prove( + `!(pt_ptr:int64) i len curr_len bl s. + 0 <= i ==> i < len ==> len < 16 ==> LENGTH bl >= 16 ==> + (forall j. + j < len - (i + 1) + ==> read (memory :> bytes8 + (word_add pt_ptr (word (curr_len + 16 + i + 1 + j)))) s = + EL j (SUB_LIST (i + 1, len - (i + 1)) bl)) ==> + read (memory :> bytes8 (word_add pt_ptr (word (curr_len + 16 + i)))) s = (EL i bl) ==> + forall j. + j < len - i + ==> read (memory :> bytes8 + (word_add pt_ptr (word (curr_len + 16 + i + j)))) s = + EL j (SUB_LIST (i, len - i) bl) + `, + REPEAT GEN_TAC THEN + REPEAT STRIP_TAC THEN + ASM_CASES_TAC `j > 0` THENL + [ + FIRST_X_ASSUM(MP_TAC o SPEC `j - 1`) THEN + ANTS_TAC THENL[ ASM_ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[ADD_ASSOC; ARITH_RULE `j > 0 ==> curr_len + 0x10 + i + 0x1 + j - 0x1 = curr_len + 0x10 + i + j`] THEN + SIMP_TAC[] THEN DISCH_TAC THEN + IMP_REWRITE_TAC[ARITH_RULE `len - (i + 1) = len - i - 1`; + EL_SUB_LIST_SHIFT] THEN + ASM_ARITH_TAC; + ALL_TAC + ] THEN + + SUBGOAL_THEN `j = 0` SUBST_ALL_TAC THENL[ASM_ARITH_TAC;ALL_TAC] THEN + REWRITE_TAC[ADD_0] THEN + ASM_REWRITE_TAC[] THEN + IMP_REWRITE_TAC[EL_SUB_LIST_TRIVIAL] THEN + ASM_ARITH_TAC +);; + let MEMORY_READ_BYTES_SUBSET_LEMMA = prove( `!len (ptr:int64) (bl:byte list) s. SUC len <= LENGTH bl ==> @@ -1963,8 +2006,72 @@ let READ_BYTES_AND_BYTE128_MERGE = prove( `!(pt_ptr:int64) (sz:num) (x:byte list) (s:armstate). sz + 16 <= LENGTH x ==> read (memory :> bytes (pt_ptr,sz + 0x10)) s = num_of_bytelist (SUB_LIST (0, sz + 0x10) x) - ==> read (memory :> bytes (pt_ptr, sz)) s = num_of_bytelist (SUB_LIST (0, sz) x)`, - CHEAT_TAC);; + ==> (read (memory :> bytes (pt_ptr, sz)) s = num_of_bytelist (SUB_LIST (0, sz) x) /\ + read (memory :> bytes128 (word_add pt_ptr (word sz))) s = bytes_to_int128 (SUB_LIST (sz, 0x10) x))`, + REPEAT GEN_TAC THEN + STRIP_TAC THEN + REWRITE_TAC[READ_MEMORY_BYTES128_BYTES] THEN + + SUBGOAL_THEN `sz <= LENGTH (x:byte list)` ASSUME_TAC THENL + [ UNDISCH_TAC `sz + 16 <= LENGTH (x:byte list)` THEN ARITH_TAC; ALL_TAC ] THEN + + SUBGOAL_THEN `16 <= LENGTH (x:byte list) - sz` ASSUME_TAC THENL + [ UNDISCH_TAC `sz + 16 <= LENGTH (x:byte list)` THEN ARITH_TAC; ALL_TAC ] THEN + + SUBGOAL_THEN `read (memory :> bytes (pt_ptr, sz + 16)) s = + read (memory :> bytes (pt_ptr, sz)) s + + 2 EXP (8 * sz) * (read (memory :> bytes (word_add pt_ptr (word sz), 16)) s)` SUBST1_TAC THENL + [ REWRITE_TAC[READ_COMPONENT_COMPOSE] THEN + REWRITE_TAC[READ_BYTES_COMBINE]; ALL_TAC] THEN + + IMP_REWRITE_TAC[NUM_OF_BYTELIST_OF_SUB_LIST] THEN + REWRITE_TAC[READ_COMPONENT_COMPOSE] THEN + + DISCH_TAC THEN + CONJ_TAC THENL + [ (* First part: `read (bytes (pt_ptr,sz)) (read memory s) = + num_of_bytelist (SUB_LIST (0x0,sz) x)`*) + FIRST_X_ASSUM(MP_TAC o AP_TERM `\x. x MOD 2 EXP (8 * sz)`) THEN + ASM_REWRITE_TAC[] THEN + REWRITE_TAC[MOD_MULT_ADD; MOD_LT] THEN + REWRITE_TAC[READ_BYTES_MOD; MIN] THEN + SIMP_TAC[ARITH_RULE `len <= len`] THEN + DISCH_TAC THEN + IMP_REWRITE_TAC[MOD_LT] THEN + MP_TAC (SPEC `(SUB_LIST (0,sz) x:byte list)` NUM_OF_BYTELIST_BOUND) THEN + IMP_REWRITE_TAC[LENGTH_SUB_LIST; SUB_0; MIN] THEN + SUBGOAL_THEN `256 EXP sz = 2 EXP (8 * sz)` SUBST1_TAC THENL + [ REWRITE_TAC[ARITH_RULE `256 = 2 EXP 8`; EXP_EXP]; ALL_TAC] THEN + SIMP_TAC[]; + ALL_TAC + ] THEN + (* Second part: word (read (bytes (word_add pt_ptr (word sz),0x10)) (read memory s)) = + bytes_to_int128 (SUB_LIST (sz,0x10) x) *) + FIRST_X_ASSUM(MP_TAC o AP_TERM `\x. x DIV 2 EXP (8 * sz)`) THEN + ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN `~(0x2 EXP (0x8 * sz) = 0x0)` ASSUME_TAC THENL + [ REWRITE_TAC[EXP_EQ_0; ARITH_EQ]; ALL_TAC] THEN + IMP_REWRITE_TAC[DIV_MULT_ADD] THEN + SUBGOAL_THEN `read (bytes (pt_ptr,sz)) (read memory s) < 0x2 EXP (0x8 * sz)` ASSUME_TAC THENL + [ REWRITE_TAC[READ_BYTES_BOUND]; ALL_TAC] THEN + SUBGOAL_THEN `num_of_bytelist (SUB_LIST (0x0,sz) x) < 0x2 EXP (0x8 * sz)` ASSUME_TAC THENL + [ MP_TAC (SPEC `(SUB_LIST (0,sz) x:byte list)` NUM_OF_BYTELIST_BOUND) THEN + IMP_REWRITE_TAC[LENGTH_SUB_LIST; SUB_0; MIN] THEN + SUBGOAL_THEN `256 EXP sz = 2 EXP (8 * sz)` SUBST1_TAC THENL + [ REWRITE_TAC[ARITH_RULE `256 = 2 EXP 8`; EXP_EXP]; ALL_TAC] THEN SIMP_TAC[]; ALL_TAC] THEN + IMP_REWRITE_TAC[DIV_LT; ADD] THEN + DISCH_TAC THEN + + ONCE_REWRITE_TAC[GSYM VAL_EQ] THEN + IMP_REWRITE_TAC[VAL_OF_BYTES_TO_INT128_EQ_NUM_OF_BYTELIST] THEN + REWRITE_TAC[LENGTH_SUB_LIST; MIN] THEN ASM_SIMP_TAC[] THEN + REWRITE_TAC[VAL_WORD; DIMINDEX_128] THEN + SUBGOAL_THEN `num_of_bytelist (SUB_LIST (sz,0x10) x) < 2 EXP 0x80` ASSUME_TAC THENL + [ MP_TAC (SPEC `(SUB_LIST (sz,0x10) x:byte list)` NUM_OF_BYTELIST_BOUND) THEN + IMP_REWRITE_TAC[LENGTH_SUB_LIST; SUB_0; MIN] THEN + ARITH_TAC; ALL_TAC] THEN + IMP_REWRITE_TAC[MOD_LT] + );; let READ_BYTES_AND_BYTE128_SPLIT = prove( `!(pt_ptr:int64) (sz:num) (x:byte list) (s:armstate). @@ -3207,37 +3314,35 @@ let CIPHER_STEALING_INV_SIMP_TAC i = IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN ASM_ARITH_TAC);; -(* TODO: change to match encrypt *) -let TAIL_SWAP_CASE_TAC case = +let ENC_TAIL_SWAP_CASE_TAC case = let c_tm = `case:num` in let v_tm = `v:num` in let v = rand (concl (NUM_RED_CONV (subst [case,c_tm] `0x10 + case`))) in - let r1 = subst [case,c_tm; v,v_tm] `curr_len + 0x10 + case = curr_len + v` in - let t1 = subst [case,c_tm] `(cipher_stealing_enc_inv case curr_len (val (tail_len:int64)) CC pt):int128` in - POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th]) THEN REWRITE_TAC[th]) THEN - (* Simplify so that symbolic execution could match up, but couldn't use - CONV_TAC NUM_REDUCE_CONV because of non-overlapping *) - RULE_ASSUM_TAC(REWRITE_RULE[ARITH_RULE r1]) THEN - ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (1--5) THEN + let r1 = subst [case,c_tm; v,v_tm] `((l1_curr_len + 0x10) + case) = (l1_curr_len + v)` in + let t1 = subst [case,c_tm] `(cipher_stealing_inv case l1_curr_len (val (tail_len:int64)) CC pt_in):int128` in + + POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th]) THEN REWRITE_TAC[th]) THEN (* pop assum: i = case *) + + ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (1--5) THEN RULE_ASSUM_TAC(REWRITE_RULE[GSYM ADD_ASSOC]) THEN RULE_ASSUM_TAC (CONV_RULE NUM_REDUCE_CONV) THEN ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN - REPEAT CONJ_TAC THENL - [ - REWRITE_TAC[ - WORD_RULE `!(a:int64) b c. word_add (word_add a b) c = word_add a (word_add b c)`; - WORD_RULE `!a b. word_add ((word a):int64) (word b) = word (a + b)`]; - - MATCH_MP_TAC (snd (EQ_IMP_RULE (SPECL [`(word_add pt_ptr (word curr_len)):int64`; + (* For case = 0x3 + `read (memory :> bytes128 (word_add ctxt_p (word l1_curr_len))) s5 = + cipher_stealing_inv 0x3 l1_curr_len (val tail_len) CC pt_in /\ + (forall i'. + i' < val tail_len - 0x3 + ==> read (memory :> bytes8 (word_add (word_add ctxt_p (word (l1_curr_len + 0x10 + 0x3))) (word i'))) + s5 = EL i' (SUB_LIST (0x3,val tail_len - 0x3) (int128_to_bytes CC))) /\ + ~(0x3 = 0x0) /\ ~(ival (word 0x3) < &0x0) /\ ival (word (0x3 + 0x1)) - &0x1 = ival (word 0x3)` *) + REPEAT CONJ_TAC THENL (* 5 subgoals *) + [ MATCH_MP_TAC (snd (EQ_IMP_RULE (SPECL [`(word_add ctxt_p (word l1_curr_len)):int64`; `s5:armstate`; t1] BREAK_ONE_BLOCK_INTO_BYTES))) THEN - REWRITE_TAC[ - WORD_RULE `!(a:int64) b c. word_add (word_add a b) c = word_add a (word_add b c)`; - WORD_RULE `!a b. word_add ((word a):int64) (word b) = word (a + b)`] THEN + CONV_TAC(ONCE_DEPTH_CONV NORMALIZE_RELATIVE_ADDRESS_CONV) THEN ASM_REWRITE_TAC[] THEN - CONV_TAC NUM_REDUCE_CONV THEN - MP_TAC (SPECL [case; `curr_len:num`; `tail_len:int64`; `CC:int128`; `pt:byte list`] - CIPHER_STEALING_ENC_BYTE_EQUAL) THEN + MP_TAC (SPECL [case; `l1_curr_len:num`; `tail_len:int64`; `CC:int128`; `pt_in:byte list`] + CIPHER_STEALING_BYTE_EQUAL) THEN CONV_TAC NUM_REDUCE_CONV THEN REWRITE_TAC[LET_DEF; LET_END_DEF] THEN ANTS_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN @@ -3245,34 +3350,35 @@ let TAIL_SWAP_CASE_TAC case = STRIP_TAC THEN MAP_EVERY (fun i -> CONJ_TAC THENL - [CIPHER_STEALING_ENC_INV_SIMP_TAC (mk_numeral (num i)); ALL_TAC]) + [CIPHER_STEALING_INV_SIMP_TAC (mk_numeral (num i)); ALL_TAC]) (0--0xe) THEN - CIPHER_STEALING_ENC_INV_SIMP_TAC `0xf:num`; + CIPHER_STEALING_INV_SIMP_TAC `0xf:num`; - MP_TAC (SPECL [`pt_ptr:int64`; case; `val (tail_len:int64)`; - `curr_len:num`; `(int128_to_bytes CC):byte list`; `s5:armstate`] - BYTE_LIST_AT_SPLIT_BACKWARDS) THEN + MP_TAC (SPECL [`ctxt_p:int64`; case; `val (tail_len:int64)`; + `l1_curr_len:num`; `(int128_to_bytes CC):byte list`; `s5:armstate`] + BYTE_LIST_AT_SPLIT_BACKWARDS) THEN REWRITE_TAC[LENGTH_OF_INT128_TO_BYTES] THEN CONV_TAC NUM_REDUCE_CONV THEN + CONV_TAC(ONCE_DEPTH_CONV NORMALIZE_RELATIVE_ADDRESS_CONV) THEN ASM_SIMP_TAC[] THEN ANTS_TAC THENL [ IMP_REWRITE_TAC[WORD_ZX_ZX] THEN REWRITE_TAC[DIMINDEX_8; DIMINDEX_32; DIMINDEX_64] THEN - MP_TAC (SPECL [case; `curr_len:num`; `tail_len:int64`; `CC:int128`; `pt:byte list`] - CIPHER_STEALING_ENC_INV_SELECT) THEN + MP_TAC (SPECL [case; `l1_curr_len:num`; `tail_len:int64`; `CC:int128`; `pt_in:byte list`] + CIPHER_STEALING_INV_SELECT) THEN CONV_TAC NUM_REDUCE_CONV THEN - ASM_SIMP_TAC[] - ; ALL_TAC ] THEN - MESON_TAC[]; + ASM_SIMP_TAC[] ; ALL_TAC ] THEN + REWRITE_TAC[ADD_ASSOC; ARITH_RULE r1]; + ARITH_TAC; WORD_ARITH_TAC; WORD_ARITH_TAC ];; -let TAIL_SWAP_ASM_CASES_TAC case = +let ENC_TAIL_SWAP_ASM_CASES_TAC case = let c_tm = `case:num` in let asm_case = subst [case, c_tm] `(i:num) = case` in - ASM_CASES_TAC asm_case THENL [ TAIL_SWAP_CASE_TAC case; ALL_TAC] THEN + ASM_CASES_TAC asm_case THENL [ ENC_TAIL_SWAP_CASE_TAC case; ALL_TAC] (* THEN MP_TAC (SPECL [case; `i:num`] LE_LT) THEN ASM_SIMP_TAC[] THEN DISCH_TAC THEN @@ -3280,7 +3386,7 @@ let TAIL_SWAP_ASM_CASES_TAC case = ASM_SIMP_TAC[] THEN CONV_TAC NUM_REDUCE_CONV THEN ASM_SIMP_TAC[] THEN - DISCH_TAC;; + DISCH_TAC*);; let BREAK_DATA_INTO_PARTS = prove( @@ -3566,6 +3672,21 @@ let CIPHER_STEALING_ENC_CORRECT = time prove( [ REWRITE_TAC[GSYM (ASSUME `(acc_len num_5blocks len_full_blocks) - 0x10 = l1_curr_len`)] THEN ASM_ARITH_TAC; ALL_TAC ] THEN + SUBGOAL_THEN `l1_curr_len + 0x10 + val (tail_len:int64) = val (len:int64)` ASSUME_TAC THENL + [ REWRITE_TAC[GSYM (ASSUME `acc_len num_5blocks len_full_blocks - 0x10 = l1_curr_len`)] THEN + + MP_TAC (SPECL [`num_5blocks:int64`; `len_full_blocks:int64`] VALUE_OF_ACC_LEN) THEN + REPEAT_N 3 (ANTS_TAC THENL [ASM_ARITH_TAC ORELSE ASM_SIMP_TAC[]; ALL_TAC]) THEN + SIMP_TAC[] THEN DISCH_TAC THEN + + ASM_SIMP_TAC[ADD_ASSOC; ARITH_RULE `~(val len_full_blocks < 0x10) ==> val len_full_blocks - 0x10 + 0x10 + = val len_full_blocks`] THEN (* add to tips doc, see My questions doc *) + REWRITE_TAC[GSYM (ASSUME `word_add (tail_len:int64) len_full_blocks = len`)] THEN + ASM_SIMP_TAC[VAL_WORD_ADD_CASES; DIMINDEX_64; + ARITH_RULE `val len_full_blocks <= 0x1000000 /\ val tail_len < 0x10 ==> + val tail_len + val len_full_blocks < 0x2 EXP 0x40`] THEN + ASM_ARITH_TAC; ALL_TAC ] THEN + SUBGOAL_THEN `word_add (ptxt_p:int64) (word (acc_len num_5blocks len_full_blocks)) = word_add ptxt_p (word (l1_curr_len + 0x10))` ASSUME_TAC THENL [ REPEAT AP_TERM_TAC THEN @@ -3668,28 +3789,19 @@ let CIPHER_STEALING_ENC_CORRECT = time prove( ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (3--5) THEN ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN -(* -`tail_len = word (val tail_len) /\ - read (memory :> bytes128 (word_sub (word_add ctxt_p (word curr_len)) (word 0x10))) s5 - = cipher_stealing_enc_inv (val tail_len) curr_len (val tail_len) CC pt_in /\ - (forall i. - i < val (word 0x0) - ==> read (memory :> bytes8 (word_add (word_add ctxt_p (word (curr_len + val tail_len))) - (word i))) s5 - = EL i (SUB_LIST (val tail_len,0x0) (int128_to_bytes CC)))` *) (* 4 total *) -(* -`tail_len = word (val tail_len) /\ - (forall i. - i < l1_curr_len - ==> read (memory :> bytes8 (word_add ctxt_p (word i))) s5 = - EL i (aes256_xts_encrypt pt_in l1_curr_len iv key1_lst key2_lst)) /\ - read (memory :> bytes128 (word_add ctxt_p (word l1_curr_len))) s5 = - cipher_stealing_inv (val tail_len) l1_curr_len (val tail_len) CC pt_in /\ - (forall i. - i < val (word 0x0) - ==> read (memory :> bytes8 (word_add (word_add ctxt_p (word (l1_curr_len + 0x10 + val tail_len))) - (word i))) s5 = - EL i (SUB_LIST (val tail_len,0x0) (int128_to_bytes CC)))`. *) + (* + `tail_len = word (val tail_len) /\ + (forall i. + i < l1_curr_len + ==> read (memory :> bytes8 (word_add ctxt_p (word i))) s5 = + EL i (aes256_xts_encrypt pt_in l1_curr_len iv key1_lst key2_lst)) /\ + read (memory :> bytes128 (word_add ctxt_p (word l1_curr_len))) s5 = + cipher_stealing_inv (val tail_len) l1_curr_len (val tail_len) CC pt_in /\ + (forall i. + i < val (word 0x0) + ==> read (memory :> bytes8 (word_add (word_add ctxt_p (word (l1_curr_len + 0x10 + val tail_len))) + (word i))) s5 = + EL i (SUB_LIST (val tail_len,0x0) (int128_to_bytes CC)))`. *) REPEAT CONJ_TAC THENL (* 4 subgoals (7 total) *) [ (* `tail_len = word (val tail_len)` *) @@ -3734,7 +3846,6 @@ let CIPHER_STEALING_ENC_CORRECT = time prove( ==> read (memory :> bytes (ctxt_p,l1_curr_len)) s5 = num_of_bytelist (aes256_xts_encrypt pt_in l1_curr_len iv key1_lst key2_lst)` *) - (* Prove one block equivalence *) DISCH_TAC THEN IMP_REWRITE_TAC[SPECL [`ctxt_p:int64`; `l1_curr_len:num`; `(aes256_xts_encrypt pt_in (l1_curr_len + 0x10) iv key1_lst key2_lst):byte list`; @@ -3775,8 +3886,8 @@ let CIPHER_STEALING_ENC_CORRECT = time prove( DISCH_TAC THEN IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES; LENGTH_OF_INT128_TO_BYTES] ; ALL_TAC] THEN REWRITE_TAC[BYTES_TO_INT128_OF_INT128_TO_BYTES] THEN - (* `read (memory :> bytes128 (word_sub (word_add ctxt_p (word curr_len)) (word 0x10))) s5 - = CC` *) + + (* `read (memory :> bytes128 (word_sub (word_add ctxt_p (word curr_len)) (word 0x10))) s5 = CC` *) (* Apply READ_CT_LAST_LEMMA with proper arguments *) MP_TAC (SPECL [`ctxt_p:int64`; `l1_curr_len:num`; `word (l1_curr_len+0x10):int64`; `aes256_xts_encrypt pt_in (l1_curr_len+0x10) iv key1_lst key2_lst:byte list`; `s5:armstate`] READ_CT_LAST_LEMMA) THEN @@ -3803,9 +3914,7 @@ let CIPHER_STEALING_ENC_CORRECT = time prove( DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN (* `bytes_to_int128 (SUB_LIST (l1_curr_len,0x10) - (aes256_xts_encrypt pt_in (l1_curr_len + 0x10) iv key1_lst key2_lst)) - = CC` *) - (* Try proving the subgoal by expanding out aes256_xts_encrypt and then apply related LENGTH_OF_xxx and SUB_LIST_xxx lemmas *) + (aes256_xts_encrypt pt_in (l1_curr_len + 0x10) iv key1_lst key2_lst)) = CC` *) REWRITE_TAC[aes256_xts_encrypt] THEN SIMP_TAC[ARITH_RULE `~(l1_curr_len + 0x10 < 0x10)`] THEN REWRITE_TAC[GSYM (ASSUME `0x10 * l1_curr_blocks = l1_curr_len`)] THEN @@ -3871,8 +3980,8 @@ let CIPHER_STEALING_ENC_CORRECT = time prove( REPEAT STRIP_TAC THEN (* For non-overlapping and MAYCHANGE address reasoning *) - SUBGOAL_THEN `l1_curr_len + i < val (len:int64)` ASSUME_TAC THENL - [ REWRITE_TAC[GSYM (ASSUME `acc_len num_5blocks len_full_blocks = l1_curr_len`)] THEN + SUBGOAL_THEN `(l1_curr_len + 0x10) + i < val (len:int64)` ASSUME_TAC THENL + [ REWRITE_TAC[GSYM (ASSUME `acc_len num_5blocks len_full_blocks - 0x10 = l1_curr_len`)] THEN MP_TAC (SPECL [`num_5blocks:int64`; `len_full_blocks:int64`] VALUE_OF_ACC_LEN) THEN REPEAT_N 3 (ANTS_TAC THENL [ASM_ARITH_TAC ORELSE ASM_SIMP_TAC[]; ALL_TAC]) THEN SIMP_TAC[] THEN DISCH_TAC THEN @@ -3886,32 +3995,11 @@ let CIPHER_STEALING_ENC_CORRECT = time prove( ASM_ARITH_TAC ; ALL_TAC ] THEN - SUBGOAL_THEN `l1_curr_len >= 16` ASSUME_TAC THENL - [ - REWRITE_TAC[GSYM (ASSUME `acc_len num_5blocks len_full_blocks = l1_curr_len`)] THEN - MP_TAC (SPECL [`num_5blocks:int64`; `len_full_blocks:int64`] VALUE_OF_ACC_LEN) THEN - REPEAT_N 3 (ANTS_TAC THENL [ASM_ARITH_TAC ORELSE ASM_SIMP_TAC[]; ALL_TAC]) THEN - SIMP_TAC[] THEN DISCH_TAC THEN - UNDISCH_TAC `word_add (tail_len:int64) (len_full_blocks:int64) = len` THEN - ONCE_REWRITE_TAC[GSYM VAL_EQ] THEN - REWRITE_TAC[VAL_WORD_ADD;DIMINDEX_64] THEN - IMP_REWRITE_TAC[MOD_LT] THEN - ASM_ARITH_TAC - ; ALL_TAC ] THEN - - SUBGOAL_THEN `(word_add (word_add (ctxt_p:int64) (word (l1_curr_len - 0x10))) (word i)) = - word_add (ctxt_p:int64) (word (l1_curr_len - 0x10 + i))` ASSUME_TAC THENL - [ REWRITE_TAC[GSYM WORD_ADD_ASSOC] THEN - AP_TERM_TAC THEN - REWRITE_TAC[WORD_ADD;WORD_SUB] THEN - ASM_ARITH_TAC - ; ALL_TAC ] THEN - MATCH_MP_TAC ENSURES_FRAME_SUBSUMED THEN EXISTS_TAC `MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI ,, MAYCHANGE [X19; X20; X21; X22],, MAYCHANGE [Q8; Q9; Q10; Q11; Q12; Q13; Q14; Q15],, - MAYCHANGE [memory :> bytes8 (word_add ctxt_p (word (l1_curr_len - 0x10 + i)))],, + MAYCHANGE [memory :> bytes8 (word_add ctxt_p (word (l1_curr_len + 0x10 + i)))],, MAYCHANGE [memory :> bytes8 (word_add ctxt_p (word (l1_curr_len + i)))]` THEN REWRITE_TAC[MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI] THEN CONJ_TAC THENL [ @@ -3960,10 +4048,9 @@ let CIPHER_STEALING_ENC_CORRECT = time prove( (* The symbolic simulation does not capture the LDR/STR at a byte level with i as the iterator, because it doesn't know which i. So the following steps are to break the cases for values of i *) -(****TODO: change it to _inv *) - (* Read a byte from Cm (at location l1_curr_len -16 + i into w15 *) - MP_TAC (SPECL [`(word_add ctxt_p (word (l1_curr_len - 0x10))):int64`; `word i:int64`; `s0:armstate`; - `(cipher_stealing_enc_inv (i + 0x1) l1_curr_len (val (tail_len:int64)) CC pt_in):int128`] + (* Read a byte from Cm (at location l1_curr_len + i into w15 *) + MP_TAC (SPECL [`(word_add ctxt_p (word l1_curr_len)):int64`; `word i:int64`; `s0:armstate`; + `(cipher_stealing_inv (i + 0x1) l1_curr_len (val (tail_len:int64)) CC pt_in):int128`] SELECT_ONE_BYTE_FROM_BLOCK) THEN SUBGOAL_THEN `val ((word i):int64) < 0x10` ASSUME_TAC THENL @@ -3973,41 +4060,39 @@ let CIPHER_STEALING_ENC_CORRECT = time prove( ASM_SIMP_TAC[] THEN REPEAT STRIP_TAC THEN (* Added assumption - 65 [`read (memory :> bytes8 (word_add (word_sub (word_add ctxt_p (word l1_curr_len)) (word 0x10)) - (word i))) s0 - = EL (val (word i)) - (int128_to_bytes (cipher_stealing_enc_inv (i + 0x1) l1_curr_len (val tail_len) CC pt_in))` *) + 69 [`read (memory :> bytes8 (word_add (word_add ctxt_p (word l1_curr_len)) (word i))) s0 = + EL (val (word i)) (int128_to_bytes (cipher_stealing_inv (i + 0x1) l1_curr_len (val tail_len) CC pt_in))` *) - (* Read a byte from Pm at location l1_curr_len + i into w14 *) - MP_TAC (SPECL [`ptxt_p:int64`; `len:int64`; `(word_add (word l1_curr_len) (word i)):int64`; + (* Read a byte from Pm at location l1_curr_len + 16 + i into w14 *) + MP_TAC (SPECL [`ptxt_p:int64`; `len:int64`; `(word_add (word (l1_curr_len + 0x10)) (word i)):int64`; `pt_in:byte list`; `s0:armstate`] SELECT_ONE_BYTE_FROM_FORALL) THEN - SUBGOAL_THEN `val (word_add ((word l1_curr_len):int64) (word i)) < val (len:int64)` ASSUME_TAC THENL + + SUBGOAL_THEN `val (word_add ((word (l1_curr_len+0x10)):int64) (word i)) < val (len:int64)` ASSUME_TAC THENL [ REWRITE_TAC[WORD_RULE `!a b. word_add ((word a):int64) (word b) = word (a + b)`] THEN IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN ASM_ARITH_TAC; ALL_TAC] THEN ASM_SIMP_TAC[] THEN STRIP_TAC THEN (* Added assumption - 67 [`read (memory :> bytes8 (word_add ptxt_p (word_add (word l1_curr_len) (word i)))) s0 - = EL (val (word_add (word l1_curr_len) (word i))) pt_in`]*) + 71 [`read (memory :> bytes8 (word_add ptxt_p (word_add (word (l1_curr_len + 0x10)) (word i)))) s0 = + EL (val (word_add (word (l1_curr_len + 0x10)) (word i))) pt_in`] *) -(****TODO: change it to _inv *) - (* Break the `read (memory :> bytes128 (word_sub (word_add ctxt_p (word l1_curr_len)) (word 0x10))) s0 + (* Break the assumption `read (memory :> bytes128 (word_add ctxt_p (word l1_curr_len))) s0`` into bytes using BREAK_ONE_BLOCK_INTO_BYTES *) - MP_TAC (SPECL [`(word_add ctxt_p (word (l1_curr_len - 0x10))):int64`; `s0:armstate`; - `(cipher_stealing_enc_inv (i + 0x1) l1_curr_len (val (tail_len:int64)) CC pt_in):int128`] + MP_TAC (SPECL [`(word_add ctxt_p (word l1_curr_len)):int64`; `s0:armstate`; + `(cipher_stealing_inv (i + 0x1) l1_curr_len (val (tail_len:int64)) CC pt_in):int128`] BREAK_ONE_BLOCK_INTO_BYTES) THEN ASM_SIMP_TAC[] THEN REPEAT STRIP_TAC THEN (* For address matching when symbolic simulation *) - SUBGOAL_THEN `word_add (ptxt_p:int64) (word_add (word l1_curr_len) (word i)) = - word_add ptxt_p (word (l1_curr_len + i))` SUBST_ALL_TAC THENL + + (* From John, changed all addresses to canonical form where the pointer is the first operand of word_add *) + CHANGED_TAC(RULE_ASSUM_TAC(CONV_RULE(ONCE_DEPTH_CONV NORMALIZE_RELATIVE_ADDRESS_CONV))) THEN + + SUBGOAL_THEN `word_add (ptxt_p:int64) (word_add (word (l1_curr_len+0x10)) (word i)) = + word_add ptxt_p (word ((l1_curr_len + 16) + i))` ASSUME_TAC THENL [ REWRITE_TAC[WORD_RULE `!a b. word_add ((word a):int64) (word b) = word (a + b)`; ADD_ASSOC] ; ALL_TAC] THEN - - SUBGOAL_THEN `word_add (word_add (ctxt_p:int64) (word (l1_curr_len - 0x10))) (word i) - = word_add ctxt_p (word (l1_curr_len - 0x10 + i))` ASSUME_TAC THENL - [ CONV_TAC WORD_RULE; ALL_TAC ] THEN POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th]) THEN ASSUME_TAC th) THEN SUBGOAL_THEN `val ((word i):int64) = i` MP_TAC THENL @@ -4016,90 +4101,28 @@ let CIPHER_STEALING_ENC_CORRECT = time prove( ; ALL_TAC] THEN DISCH_THEN(RULE_ASSUM_TAC o REWRITE_RULE o CONJUNCTS) THEN - -(*** - SUBGOAL_THEN `word_sub ((word (l1_curr_len:num)):int64) (word_sub (word 0x10) (word i)) - = word (l1_curr_len - 0x10 + i)` ASSUME_TAC THENL - [ UNDISCH_TAC `l1_curr_len >= 0x10` THEN - SIMP_TAC[GE; WORD_ADD; WORD_SUB; LT_IMP_LE] THEN - CONV_TAC WORD_RULE - ; ALL_TAC ] - - (* `word_add (word_sub (word_add (ctxt_p:int64) (word l1_curr_len)) (word 0x10)) (word i) = *) - SUBGOAL_THEN `word_add (ctxt_p:int64) (word_sub (word l1_curr_len) (word (0x10-i))) - = word_add ctxt_p (word (l1_curr_len - 0x10 + i))` ASSUME_TAC THENL - [ UNDISCH_TAC `l1_curr_len >= 0x10` THEN - ASM_SIMP_TAC[GE; WORD_ADD; WORD_SUB; LT_IMP_LE] - ; ALL_TAC ] THEN -*) - (* Will I need the following to have (0x10 - i) in the assumptions? - SUBGOAL_THEN `word_sub ((word (l1_curr_len:num)):int64) (word (0x10 - i)) - = word (l1_curr_len - (0x10 - i))` ASSUME_TAC THENL - [ UNDISCH_TAC `l1_curr_len >= 0x10` THEN - SIMP_TAC[WORD_SUB; GE] THEN - SIMP_TAC[ARITH_RULE `0x10 <= l1_curr_len ==> (0x10 - i) <= l1_curr_len`] - ; ALL_TAC ] THEN - SUBGOAL_THEN `l1_curr_len - (0x10 - i) = l1_curr_len - 0x10 + i` SUBST_ALL_TAC THENL - [ UNDISCH_TAC `l1_curr_len >= 0x10` THEN - UNDISCH_TAC `i < 0x10` THEN ARITH_TAC - ; ALL_TAC ] THEN - *) - - (* (word_add (word_add ctxt_p (word_sub (word l1_curr_len) (word 0x10))) (word 0xi)))*) - - SUBGOAL_THEN `word_sub (word_add ctxt_p (word l1_curr_len)) (word 0x10):int64 = - word_add ctxt_p (word(l1_curr_len - 0x10))` SUBST_ALL_TAC THENL - [ RULE_ASSUM_TAC(REWRITE_RULE[GE]) THEN - ASM_SIMP_TAC[WORD_SUB] THEN CONV_TAC WORD_RULE; - (* From John, it put all addresses in the read memory assumptions in canonical form *) - CHANGED_TAC(RULE_ASSUM_TAC(CONV_RULE(ONCE_DEPTH_CONV NORMALIZE_RELATIVE_ADDRESS_CONV)))] THEN - - (*(* Is this needed for nonoverlapping machinery in symbolic simulation? *) - SUBGOAL_THEN `l1_curr_len - 0x10 + i < val (len:int64)` ASSUME_TAC THENL - (* word_ult () () *) - [ UNDISCH_TAC `l1_curr_len + i < val (len:int64)` THEN ARITH_TAC; ALL_TAC ] THEN *) - - (* Went back on this suggestion - (* l1_curr_len is curr_len less 1 block*) - ABBREV_TAC `l1_curr_len = curr_len - 0x10` THEN - SUBGOAL_THEN `curr_len - 0x10 = l1_curr_len` SUBST_ALL_TAC THENL - [ EXPAND_TAC "l1_curr_len" THEN REFL_TAC; ALL_TAC ] - SUBGOAL_THEN `curr_len = l1_curr_len + 0x10` SUBST_ALL_TAC THENL - [ EXPAND_TAC "l1_curr_len" THEN - UNDISCH_TAC `curr_len >= 0x10` THEN ARITH_TAC; ALL_TAC ] - *) - - ASM_CASES_TAC `i:num = 3` THENL + (* case analysis based on i = 0 ... 14, because symbolic execution + needs to know which byte is being overwritten in pt_ptr to properly update the state. *) + ASM_CASES_TAC `i:num = 0` THENL [ POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th]) THEN REWRITE_TAC[th]) THEN (* Simplify so that symbolic execution could match up, but couldn't use CONV_TAC NUM_REDUCE_CONV because of non-overlapping *) - (* Went back on this suggestion - let v = rand (concl (NUM_RED_CONV (`0x10 + 0x3`))) in + (* let v = rand (concl (NUM_RED_CONV (`0x10 + 0x3`))) in let ith = ARITH_RULE (subst [v,`v:num`] `l1_curr_len + 0x10 + 0x3 = l1_curr_len + v`) in - let ith2 = ARITH_RULE (subst [v,`v:num`] `0x10 + 0x3 = v`) in - FIRST_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[MATCH_MP ith th; ith2])) THEN - *) -(*** - let v = rand (concl (NUM_RED_CONV (`0x10 - 0x3`))) in - let ith = ARITH_RULE (subst [v,`v:num`] `curr_len >= 0x10 ==> curr_len - 0x10 + 0x3 = curr_len - v`) in - let ith2 = ARITH_RULE (subst [v,`v:num`] `0x10 - 0x3 = v`) in - (* RULE_ASSUM_TAC(REWRITE_RULE[ith]) THEN // doesn't replace in assumptions *) - FIRST_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[MATCH_MP ith th; ith2])) THEN -*) - (* 34 [`word_add (word_add ctxt_p (word_sub (word curr_len) (word 0x10))) (word 0x3) - = word_add ctxt_p (word (curr_len - 0xd))`] - 65 [`read (memory :> bytes8 (word_add ctxt_p (word (curr_len - 0xd)))) s0 = - = EL (val (word 0x3)) (int128_to_bytes (cipher_stealing_enc_inv (0x3 + 0x1) curr_len (val tail_len) CC pt_in))`] - 71 [`read (memory :> bytes8 (word_add (word_sub (word_add ctxt_p (word curr_len)) (word 0x10)) - (word 0x3))) s0 - = EL 0x3 (int128_to_bytes (cipher_stealing_enc_inv (0x3 + 0x1) curr_len (val tail_len) CC pt_in))`] - 88 [`read X14 s3 = - word_zx (word_zx (EL (val (word_add (word curr_len) (word 0x3))) pt_in))`] - Info: assumption `read X15 s2 = - word_zx (word_zx (read (memory :> bytes8 (word_add ctxt_p (word_sub (word curr_len) (word 0xd)))) - s1))` is erased, but it might have contained useful information *) + let ith2 = ARITH_RULE (subst [v,`v:num`] `(l1_curr_len + 0x10) + 0x3 = l1_curr_len + v`) in + (*let ith2 = ARITH_RULE (subst [v,`v:num`] `0x10 + 0x3 = v`) in + FIRST_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[MATCH_MP ith th; ith2])) THEN*) + RULE_ASSUM_TAC(REWRITE_RULE[ith;ith2]) THEN *) + + (* From John: see if they will fix symbolic simulation even when + SUBGOAL_THEN `word_add (ptxt_p:int64) (word_add (word (l1_curr_len+0x10)) (word i)) = + word_add ptxt_p (word ((l1_curr_len + 16) + i))` doesn't have the () around l1_curr_len + 16 *) + (* + RULE_ASSUM_TAC(CONV_RULE(DEPTH_CONV NUM_ADD_CONV)) THEN + RULE_ASSUM_TAC(CONV_RULE(ONCE_DEPTH_CONV NORMALIZE_RELATIVE_ADDRESS_CONV)) THEN *) + RULE_ASSUM_TAC(REWRITE_RULE[ADD_0]) THEN (* let v = rand (concl (NUM_RED_CONV (`0x10 - 0x3`))) in let vreplace = subst [v,`v:num`] in @@ -4108,98 +4131,99 @@ let CIPHER_STEALING_ENC_CORRECT = time prove( SIMP_TAC[WORD_SUB; GE; ARITH_RULE (vreplace`0x10 <= curr_len ==> 0xd <= curr_len`)] ; ALL_TAC ] THEN *) + ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (1--5) THEN - ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (1--2) THEN - ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (3--3) THEN - - ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (4--4) THEN -(* 90 [`read (memory :> bytes8 (word_add ctxt_p (word (curr_len + 0x3)))) s4 = - word_zx - (word_zx - (word_zx - (word_zx - (EL 0x3 + (* Benign messages + Stepping to state s5 + Instruction at `pc + 2564 (0xa04)`: `arm_STRB W14 X1 (Register_Offset X21)` + Info: assumption `read (memory :> bytes128 (word_add ctxt_p (word l1_curr_len))) s4 = + cipher_stealing_inv (0x3 + 0x1) l1_curr_len (val tail_len) CC pt_in` is erased. + - Reason: NONOVERLAPPING_RULE: could not prove one of: + * `nonoverlapping (word_add ctxt_p (word l1_curr_len),0x10) + (word_add ctxt_p (word (l1_curr_len + 0x3)),0x1)` + Info: assumption `read (memory :> bytes8 (word_add ctxt_p (word (l1_curr_len + 0x3)))) s4 = + EL 0x3 (int128_to_bytes - (cipher_stealing_enc_inv 0x4 curr_len (val tail_len) CC pt_in))))))`]*) - - (* - CHANGED_TAC(UNDISCH_THEN `word_sub ((word curr_len):int64) (word 0xd) = word (curr_len - 0xd)` - (fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th]) THEN ASSUME_TAC th)) THEN - - SUBGOAL_THEN `curr_len - 0xd < val (len:int64)` ASSUME_TAC THENL - (* word_ult () () *) - [ UNDISCH_TAC `curr_len + 0x3 < val (len:int64)` THEN ARITH_TAC; ALL_TAC ] THEN - *) - ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (5--5) THEN - (* + (cipher_stealing_inv (0x3 + 0x1) l1_curr_len (val tail_len) CC pt_in))` is erased. - Reason: NONOVERLAPPING_RULE: could not prove one of: - * `nonoverlapping -(word_add (word_sub (word_add ctxt_p (word curr_len)) (word 0x10)) (word 0x3), 0x1) -(word_add ctxt_p (word_sub (word curr_len) (word 0xd)),0x1)` - - 34 [`word_add (word_add ctxt_p (word_sub (word curr_len) (word 0x10))) - (word 0x3) = - word_add ctxt_p (word (curr_len - 0xd))`] - 35 [`word_sub (word (0x3 + 0x1)) (word 0x1) = word 0x3`] - 36 [`0x3 < 0x10`] - 37 [`val (word_add (word curr_len) (word 0x3)) < val len`] - 38 [`word_add (word_sub (word_add ctxt_p (word curr_len)) (word 0x10)) - (word 0x3) = - word_add ctxt_p (word (curr_len - 0xd))`] - 39 [`word_sub (word curr_len) (word_sub (word 0x10) (word 0x3)) = - word (curr_len - 0xd)`] - 40 [`word_add ctxt_p (word_sub (word curr_len) (word 0xd)) = - word_add ctxt_p (word (curr_len - 0xd))`] - 41 [`curr_len - 0xd < val len`] - - Stepping to state s5 -Instruction at `pc + 2564 (0xa04)`: `arm_STRB W14 X1 (Register_Offset X21)` -Info: assumption `forall i. - i < curr_len - ==> read (memory :> bytes8 (word_add ctxt_p (word i))) s4 = - EL i (aes256_xts_encrypt pt_in curr_len iv key1_lst key2_lst)` is erased. -- Reason: NONOVERLAPPING_RULE: could not prove one of: - * `nonoverlapping (word_add ctxt_p (word _375691),0x1) -(word_add ctxt_p (word_sub (word curr_len) (word 0xd)),0x1)` -Info: assumption `read -(memory :> bytes128 (word_sub (word_add ctxt_p (word curr_len)) (word 0x10))) -s4 = -cipher_stealing_enc_inv (0x3 + 0x1) curr_len (val tail_len) CC pt_in` is erased. -- Reason: NONOVERLAPPING_RULE: could not prove one of: - * `nonoverlapping (word_sub (word_add ctxt_p (word curr_len)) (word 0x10),0x10) -(word_add ctxt_p (word_sub (word curr_len) (word 0xd)),0x1)` -Info: assumption `read (memory :> bytes8 (word_add ctxt_p (word (curr_len - 0xd)))) s4 = -EL 0x3 -(int128_to_bytes -(cipher_stealing_enc_inv (0x3 + 0x1) curr_len (val tail_len) CC pt_in))` is erased. -- Reason: NONOVERLAPPING_RULE: could not prove one of: - * `nonoverlapping (word_add ctxt_p (word (curr_len - 0xd)),0x1) -(word_add ctxt_p (word_sub (word curr_len) (word 0xd)),0x1)` -Info: assumption `read -(memory :> - bytes8 - (word_add (word_sub (word_add ctxt_p (word curr_len)) (word 0x10)) - (word 0x3))) -s4 = -EL 0x3 -(int128_to_bytes -(cipher_stealing_enc_inv (0x3 + 0x1) curr_len (val tail_len) CC pt_in))` is erased. -- Reason: NONOVERLAPPING_RULE: could not prove one of: - * `nonoverlapping -(word_add (word_sub (word_add ctxt_p (word curr_len)) (word 0x10)) (word 0x3), 0x1) -(word_add ctxt_p (word_sub (word curr_len) (word 0xd)),0x1)` - -ABBREV_TAC `short_len = curr_len - 0x10` -SUBGOAL_THEN `curr_len = short_len + 0x10` SUBST_ALL_TAC THENL -[EXPAND_TAC “short_len” THEN ARITH_TAC; ALL_TAC] + * `nonoverlapping (word_add ctxt_p (word (l1_curr_len + 0x3)),0x1) + (word_add ctxt_p (word (l1_curr_len + 0x3)),0x1)` + Info: assumption `read (memory :> bytes8 (word_add ctxt_p (word (l1_curr_len + 0x3)))) s4 = + EL 0x3 + (int128_to_bytes + (cipher_stealing_inv (0x3 + 0x1) l1_curr_len (val tail_len) CC pt_in))` is erased. + - Reason: NONOVERLAPPING_RULE: could not prove one of: + * `nonoverlapping (word_add ctxt_p (word (l1_curr_len + 0x3)),0x1) + (word_add ctxt_p (word (l1_curr_len + 0x3)),0x1)` + CPU time (user): 1.119391 + Info: assumption `read events s5 = + CONS + (EventStore (word_add (word_add ctxt_p (word l1_curr_len)) (word 0x3),0x1)) + (read events s4)` is erased, but it might have contained useful information *) + RULE_ASSUM_TAC(REWRITE_RULE[GSYM ADD_ASSOC]) THEN + RULE_ASSUM_TAC (CONV_RULE NUM_REDUCE_CONV) THEN + ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN + (*`read (memory :> bytes128 (word_add ctxt_p (word l1_curr_len))) s5 = + cipher_stealing_inv 0x3 l1_curr_len (val tail_len) CC pt_in /\ + (forall i'. + i' < val tail_len - 0x3 + ==> read + (memory :> + bytes8 + (word_add (word_add ctxt_p (word (l1_curr_len + 0x10 + 0x3))) + (word i'))) + s5 = + EL i' (SUB_LIST (0x3,val tail_len - 0x3) (int128_to_bytes CC))) /\ + ~(0x3 = 0x0) /\ + ~(ival (word 0x3) < &0x0) /\ + ival (word (0x3 + 0x1)) - &0x1 = ival (word 0x3)` *) + REPEAT CONJ_TAC THENL + [ let t1 = (*subst [case,c_tm] *) `(cipher_stealing_inv 0x0 l1_curr_len (val (tail_len:int64)) CC pt_in):int128` in + MATCH_MP_TAC (snd (EQ_IMP_RULE (SPECL [`(word_add ctxt_p (word l1_curr_len)):int64`; + `s5:armstate`; t1] BREAK_ONE_BLOCK_INTO_BYTES))) THEN + CONV_TAC(ONCE_DEPTH_CONV NORMALIZE_RELATIVE_ADDRESS_CONV) THEN + ASM_REWRITE_TAC[] THEN + + MP_TAC (SPECL [`0x0`; `l1_curr_len:num`; `tail_len:int64`; `CC:int128`; `pt_in:byte list`] + CIPHER_STEALING_BYTE_EQUAL) THEN + CHANGED_TAC(CONV_TAC NUM_REDUCE_CONV) THEN + REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + ANTS_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN + + ANTS_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN + STRIP_TAC THEN + + MAP_EVERY (fun i -> CONJ_TAC THENL + [CIPHER_STEALING_INV_SIMP_TAC (mk_numeral (num i)); ALL_TAC]) (0--0xe) THEN + CIPHER_STEALING_INV_SIMP_TAC `0xf:num`; + MP_TAC (SPECL [`ctxt_p:int64`; `0x0`; `val (tail_len:int64)`; + `l1_curr_len:num`; `(int128_to_bytes CC):byte list`; `s5:armstate`] + BYTE_LIST_AT_SPLIT_BACKWARDS) THEN + REWRITE_TAC[LENGTH_OF_INT128_TO_BYTES] THEN + CONV_TAC NUM_REDUCE_CONV THEN + CONV_TAC(ONCE_DEPTH_CONV NORMALIZE_RELATIVE_ADDRESS_CONV) THEN + ASM_SIMP_TAC[] THEN + ANTS_TAC THENL + [ IMP_REWRITE_TAC[WORD_ZX_ZX] THEN + REWRITE_TAC[DIMINDEX_8; DIMINDEX_32; DIMINDEX_64] THEN + MP_TAC (SPECL [`0x0`; `l1_curr_len:num`; `tail_len:int64`; `CC:int128`; `pt_in:byte list`] + CIPHER_STEALING_INV_SELECT) THEN + CONV_TAC NUM_REDUCE_CONV THEN + ASM_SIMP_TAC[] ; ALL_TAC ] THEN + REWRITE_TAC[ADD_ASSOC; ARITH_RULE `((l1_curr_len + 0x10) + 0x0) = (l1_curr_len + 0x10)`]; (* will need replacement with v *) + + ARITH_TAC; + WORD_ARITH_TAC; + WORD_ARITH_TAC; + ] ; ALL_TAC] (* case analysis based on i = 0 ... 14, because symbolic execution needs to know which byte is being overwritten in pt_ptr to properly update the state. *) - MAP_EVERY (fun i -> TAIL_SWAP_ASM_CASES_TAC (mk_numeral (num i))) (0--14) THEN + MAP_EVERY (fun i -> ENC_TAIL_SWAP_ASM_CASES_TAC (mk_numeral (num i))) (0--0) THEN UNDISCH_TAC `15 <= i` THEN UNDISCH_TAC `i < val (tail_len:int64)` THEN UNDISCH_TAC `val (tail_len:int64) < 16` THEN From e0c6afa7d34786445cf1ad5f03831b5a4f115034 Mon Sep 17 00:00:00 2001 From: Nevine Ebeid Date: Fri, 28 Nov 2025 12:22:34 -0500 Subject: [PATCH 096/132] Cipher-stealing: case tail != 0, loop invariant: Subgoal 3: complete. --- arm/proofs/aes-xts-armv8.ml | 239 +++++++++++++----------------------- 1 file changed, 86 insertions(+), 153 deletions(-) diff --git a/arm/proofs/aes-xts-armv8.ml b/arm/proofs/aes-xts-armv8.ml index aa88f0d24..a2525b3ac 100644 --- a/arm/proofs/aes-xts-armv8.ml +++ b/arm/proofs/aes-xts-armv8.ml @@ -3314,6 +3314,68 @@ let CIPHER_STEALING_INV_SIMP_TAC i = IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN ASM_ARITH_TAC);; +let ENC_TAIL_SWAP_CASE_0_TAC = + POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th]) THEN REWRITE_TAC[th]) THEN + (* Simplify so that symbolic execution could match up, but couldn't use + CONV_TAC NUM_REDUCE_CONV because of non-overlapping *) + + RULE_ASSUM_TAC(REWRITE_RULE[ADD_0]) THEN + + ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (1--5) THEN + + RULE_ASSUM_TAC(REWRITE_RULE[GSYM ADD_ASSOC]) THEN + RULE_ASSUM_TAC (CONV_RULE NUM_REDUCE_CONV) THEN + ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN + + REPEAT CONJ_TAC THENL + [ MATCH_MP_TAC (snd (EQ_IMP_RULE (SPECL [`(word_add ctxt_p (word l1_curr_len)):int64`; `s5:armstate`; + `(cipher_stealing_inv 0x0 l1_curr_len (val (tail_len:int64)) CC pt_in):int128`] + BREAK_ONE_BLOCK_INTO_BYTES))) THEN + CONV_TAC(ONCE_DEPTH_CONV NORMALIZE_RELATIVE_ADDRESS_CONV) THEN + ASM_REWRITE_TAC[] THEN + + MP_TAC (SPECL [`0x0`; `l1_curr_len:num`; `tail_len:int64`; `CC:int128`; `pt_in:byte list`] + CIPHER_STEALING_BYTE_EQUAL) THEN + CHANGED_TAC(CONV_TAC NUM_REDUCE_CONV) THEN + REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + ANTS_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN + + ANTS_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN + STRIP_TAC THEN + + (* The case for 0 needed to be separated out and simplified from CIPHER_STEALING_INV_SIMP_TAC *) + CONJ_TAC THENL + [ ASM_REWRITE_TAC[] THEN + IMP_REWRITE_TAC[WORD_ZX_ZX; WORD_ZX_TRIVIAL] THEN + REWRITE_TAC[DIMINDEX_8; DIMINDEX_32; DIMINDEX_64] THEN + ASM_ARITH_TAC ; ALL_TAC] THEN + + MAP_EVERY (fun i -> CONJ_TAC THENL + [CIPHER_STEALING_INV_SIMP_TAC (mk_numeral (num i)); ALL_TAC]) (1--0xe) THEN + CIPHER_STEALING_INV_SIMP_TAC `0xf:num`; + + MP_TAC (SPECL [`ctxt_p:int64`; `0x0`; `val (tail_len:int64)`; + `l1_curr_len:num`; `(int128_to_bytes CC):byte list`; `s5:armstate`] + BYTE_LIST_AT_SPLIT_BACKWARDS) THEN + REWRITE_TAC[LENGTH_OF_INT128_TO_BYTES] THEN + CONV_TAC NUM_REDUCE_CONV THEN + CONV_TAC(ONCE_DEPTH_CONV NORMALIZE_RELATIVE_ADDRESS_CONV) THEN + ASM_SIMP_TAC[] THEN + ANTS_TAC THENL + [ IMP_REWRITE_TAC[WORD_ZX_ZX] THEN + REWRITE_TAC[DIMINDEX_8; DIMINDEX_32; DIMINDEX_64] THEN + MP_TAC (SPECL [`0x0`; `l1_curr_len:num`; `tail_len:int64`; `CC:int128`; `pt_in:byte list`] + CIPHER_STEALING_INV_SELECT) THEN + CONV_TAC NUM_REDUCE_CONV THEN + ASM_SIMP_TAC[] ; ALL_TAC ] THEN + REWRITE_TAC[ADD_ASSOC; ARITH_RULE `((l1_curr_len + 0x10) + 0x0) = (l1_curr_len + 0x10)`]; (* will need replacement with v *) + + WORD_ARITH_TAC; + WORD_ARITH_TAC; +];; + + + let ENC_TAIL_SWAP_CASE_TAC case = let c_tm = `case:num` in let v_tm = `v:num` in @@ -3327,15 +3389,15 @@ let ENC_TAIL_SWAP_CASE_TAC case = RULE_ASSUM_TAC(REWRITE_RULE[GSYM ADD_ASSOC]) THEN RULE_ASSUM_TAC (CONV_RULE NUM_REDUCE_CONV) THEN ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN - (* For case = 0x3 - `read (memory :> bytes128 (word_add ctxt_p (word l1_curr_len))) s5 = - cipher_stealing_inv 0x3 l1_curr_len (val tail_len) CC pt_in /\ - (forall i'. - i' < val tail_len - 0x3 - ==> read (memory :> bytes8 (word_add (word_add ctxt_p (word (l1_curr_len + 0x10 + 0x3))) (word i'))) - s5 = EL i' (SUB_LIST (0x3,val tail_len - 0x3) (int128_to_bytes CC))) /\ - ~(0x3 = 0x0) /\ ~(ival (word 0x3) < &0x0) /\ ival (word (0x3 + 0x1)) - &0x1 = ival (word 0x3)` *) - REPEAT CONJ_TAC THENL (* 5 subgoals *) + (* For case = 0x1 + `read (memory :> bytes128 (word_add ctxt_p (word l1_curr_len))) s5 = + cipher_stealing_inv 0x1 l1_curr_len (val tail_len) CC pt_in /\ + (forall i'. + i' < val tail_len - 0x1 + ==> read (memory :> bytes8 (word_add (word_add ctxt_p (word (l1_curr_len + 0x10 + 0x1))) (word i'))) s5 = + EL i' (SUB_LIST (0x1,val tail_len - 0x1) (int128_to_bytes CC))) /\ + ~(ival (word 0x1) < &0x0) /\ ival (word (0x1 + 0x1)) - &0x1 = ival (word 0x1)` *) + REPEAT CONJ_TAC THENL (* 4 subgoals *) [ MATCH_MP_TAC (snd (EQ_IMP_RULE (SPECL [`(word_add ctxt_p (word l1_curr_len)):int64`; `s5:armstate`; t1] BREAK_ONE_BLOCK_INTO_BYTES))) THEN CONV_TAC(ONCE_DEPTH_CONV NORMALIZE_RELATIVE_ADDRESS_CONV) THEN @@ -3370,7 +3432,6 @@ let ENC_TAIL_SWAP_CASE_TAC case = ASM_SIMP_TAC[] ; ALL_TAC ] THEN REWRITE_TAC[ADD_ASSOC; ARITH_RULE r1]; - ARITH_TAC; WORD_ARITH_TAC; WORD_ARITH_TAC ];; @@ -3378,7 +3439,7 @@ let ENC_TAIL_SWAP_CASE_TAC case = let ENC_TAIL_SWAP_ASM_CASES_TAC case = let c_tm = `case:num` in let asm_case = subst [case, c_tm] `(i:num) = case` in - ASM_CASES_TAC asm_case THENL [ ENC_TAIL_SWAP_CASE_TAC case; ALL_TAC] (* THEN + ASM_CASES_TAC asm_case THENL [ ENC_TAIL_SWAP_CASE_TAC case; ALL_TAC] THEN MP_TAC (SPECL [case; `i:num`] LE_LT) THEN ASM_SIMP_TAC[] THEN DISCH_TAC THEN @@ -3386,7 +3447,7 @@ let ENC_TAIL_SWAP_ASM_CASES_TAC case = ASM_SIMP_TAC[] THEN CONV_TAC NUM_REDUCE_CONV THEN ASM_SIMP_TAC[] THEN - DISCH_TAC*);; + DISCH_TAC;; let BREAK_DATA_INTO_PARTS = prove( @@ -4101,157 +4162,29 @@ let CIPHER_STEALING_ENC_CORRECT = time prove( ; ALL_TAC] THEN DISCH_THEN(RULE_ASSUM_TAC o REWRITE_RULE o CONJUNCTS) THEN - (* case analysis based on i = 0 ... 14, because symbolic execution + (* case analysis based on i = 0 ... 14, because symbolic execution needs to know which byte is being overwritten in pt_ptr to properly update the state. *) + (* Case 0 needed its own tactic *) ASM_CASES_TAC `i:num = 0` THENL - [ - POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th]) THEN REWRITE_TAC[th]) THEN - (* Simplify so that symbolic execution could match up, but couldn't use - CONV_TAC NUM_REDUCE_CONV because of non-overlapping *) - - (* let v = rand (concl (NUM_RED_CONV (`0x10 + 0x3`))) in - let ith = ARITH_RULE (subst [v,`v:num`] `l1_curr_len + 0x10 + 0x3 = l1_curr_len + v`) in - let ith2 = ARITH_RULE (subst [v,`v:num`] `(l1_curr_len + 0x10) + 0x3 = l1_curr_len + v`) in - (*let ith2 = ARITH_RULE (subst [v,`v:num`] `0x10 + 0x3 = v`) in - FIRST_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[MATCH_MP ith th; ith2])) THEN*) - RULE_ASSUM_TAC(REWRITE_RULE[ith;ith2]) THEN *) + [ ENC_TAIL_SWAP_CASE_0_TAC; ALL_TAC ] THEN - (* From John: see if they will fix symbolic simulation even when - SUBGOAL_THEN `word_add (ptxt_p:int64) (word_add (word (l1_curr_len+0x10)) (word i)) = - word_add ptxt_p (word ((l1_curr_len + 16) + i))` doesn't have the () around l1_curr_len + 16 *) - (* - RULE_ASSUM_TAC(CONV_RULE(DEPTH_CONV NUM_ADD_CONV)) THEN - RULE_ASSUM_TAC(CONV_RULE(ONCE_DEPTH_CONV NORMALIZE_RELATIVE_ADDRESS_CONV)) THEN *) - RULE_ASSUM_TAC(REWRITE_RULE[ADD_0]) THEN - (* - let v = rand (concl (NUM_RED_CONV (`0x10 - 0x3`))) in - let vreplace = subst [v,`v:num`] in - SUBGOAL_THEN (vreplace`word_sub ((word (curr_len:num)):int64) (word v) = word (curr_len - v)`) ASSUME_TAC THENL - [ UNDISCH_TAC `curr_len >= 0x10` THEN - SIMP_TAC[WORD_SUB; GE; ARITH_RULE (vreplace`0x10 <= curr_len ==> 0xd <= curr_len`)] - ; ALL_TAC ] THEN - *) - ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (1--5) THEN - - (* Benign messages - Stepping to state s5 - Instruction at `pc + 2564 (0xa04)`: `arm_STRB W14 X1 (Register_Offset X21)` - Info: assumption `read (memory :> bytes128 (word_add ctxt_p (word l1_curr_len))) s4 = - cipher_stealing_inv (0x3 + 0x1) l1_curr_len (val tail_len) CC pt_in` is erased. - - Reason: NONOVERLAPPING_RULE: could not prove one of: - * `nonoverlapping (word_add ctxt_p (word l1_curr_len),0x10) - (word_add ctxt_p (word (l1_curr_len + 0x3)),0x1)` - Info: assumption `read (memory :> bytes8 (word_add ctxt_p (word (l1_curr_len + 0x3)))) s4 = - EL 0x3 - (int128_to_bytes - (cipher_stealing_inv (0x3 + 0x1) l1_curr_len (val tail_len) CC pt_in))` is erased. - - Reason: NONOVERLAPPING_RULE: could not prove one of: - * `nonoverlapping (word_add ctxt_p (word (l1_curr_len + 0x3)),0x1) - (word_add ctxt_p (word (l1_curr_len + 0x3)),0x1)` - Info: assumption `read (memory :> bytes8 (word_add ctxt_p (word (l1_curr_len + 0x3)))) s4 = - EL 0x3 - (int128_to_bytes - (cipher_stealing_inv (0x3 + 0x1) l1_curr_len (val tail_len) CC pt_in))` is erased. - - Reason: NONOVERLAPPING_RULE: could not prove one of: - * `nonoverlapping (word_add ctxt_p (word (l1_curr_len + 0x3)),0x1) - (word_add ctxt_p (word (l1_curr_len + 0x3)),0x1)` - CPU time (user): 1.119391 - Info: assumption `read events s5 = - CONS - (EventStore (word_add (word_add ctxt_p (word l1_curr_len)) (word 0x3),0x1)) - (read events s4)` is erased, but it might have contained useful information - *) - RULE_ASSUM_TAC(REWRITE_RULE[GSYM ADD_ASSOC]) THEN - RULE_ASSUM_TAC (CONV_RULE NUM_REDUCE_CONV) THEN - ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN - (*`read (memory :> bytes128 (word_add ctxt_p (word l1_curr_len))) s5 = - cipher_stealing_inv 0x3 l1_curr_len (val tail_len) CC pt_in /\ - (forall i'. - i' < val tail_len - 0x3 - ==> read - (memory :> - bytes8 - (word_add (word_add ctxt_p (word (l1_curr_len + 0x10 + 0x3))) - (word i'))) - s5 = - EL i' (SUB_LIST (0x3,val tail_len - 0x3) (int128_to_bytes CC))) /\ - ~(0x3 = 0x0) /\ - ~(ival (word 0x3) < &0x0) /\ - ival (word (0x3 + 0x1)) - &0x1 = ival (word 0x3)` *) - REPEAT CONJ_TAC THENL - [ let t1 = (*subst [case,c_tm] *) `(cipher_stealing_inv 0x0 l1_curr_len (val (tail_len:int64)) CC pt_in):int128` in - MATCH_MP_TAC (snd (EQ_IMP_RULE (SPECL [`(word_add ctxt_p (word l1_curr_len)):int64`; - `s5:armstate`; t1] BREAK_ONE_BLOCK_INTO_BYTES))) THEN - CONV_TAC(ONCE_DEPTH_CONV NORMALIZE_RELATIVE_ADDRESS_CONV) THEN - ASM_REWRITE_TAC[] THEN - - MP_TAC (SPECL [`0x0`; `l1_curr_len:num`; `tail_len:int64`; `CC:int128`; `pt_in:byte list`] - CIPHER_STEALING_BYTE_EQUAL) THEN - CHANGED_TAC(CONV_TAC NUM_REDUCE_CONV) THEN - REWRITE_TAC[LET_DEF; LET_END_DEF] THEN - ANTS_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN - - ANTS_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN - STRIP_TAC THEN - - MAP_EVERY (fun i -> CONJ_TAC THENL - [CIPHER_STEALING_INV_SIMP_TAC (mk_numeral (num i)); ALL_TAC]) (0--0xe) THEN - CIPHER_STEALING_INV_SIMP_TAC `0xf:num`; - - MP_TAC (SPECL [`ctxt_p:int64`; `0x0`; `val (tail_len:int64)`; - `l1_curr_len:num`; `(int128_to_bytes CC):byte list`; `s5:armstate`] - BYTE_LIST_AT_SPLIT_BACKWARDS) THEN - REWRITE_TAC[LENGTH_OF_INT128_TO_BYTES] THEN - CONV_TAC NUM_REDUCE_CONV THEN - CONV_TAC(ONCE_DEPTH_CONV NORMALIZE_RELATIVE_ADDRESS_CONV) THEN - ASM_SIMP_TAC[] THEN - ANTS_TAC THENL - [ IMP_REWRITE_TAC[WORD_ZX_ZX] THEN - REWRITE_TAC[DIMINDEX_8; DIMINDEX_32; DIMINDEX_64] THEN - MP_TAC (SPECL [`0x0`; `l1_curr_len:num`; `tail_len:int64`; `CC:int128`; `pt_in:byte list`] - CIPHER_STEALING_INV_SELECT) THEN - CONV_TAC NUM_REDUCE_CONV THEN - ASM_SIMP_TAC[] ; ALL_TAC ] THEN - REWRITE_TAC[ADD_ASSOC; ARITH_RULE `((l1_curr_len + 0x10) + 0x0) = (l1_curr_len + 0x10)`]; (* will need replacement with v *) - - ARITH_TAC; - WORD_ARITH_TAC; - WORD_ARITH_TAC; - ] - - ; ALL_TAC] + MP_TAC (SPECL [`0`; `i:num`] LE_LT) THEN + ASM_SIMP_TAC[] THEN + DISCH_TAC THEN + MP_TAC (SPECL [`0`; `i:num`] LE_SUC_LT) THEN + ASM_SIMP_TAC[] THEN + CONV_TAC NUM_REDUCE_CONV THEN + ASM_SIMP_TAC[] THEN + DISCH_TAC THEN - (* case analysis based on i = 0 ... 14, because symbolic execution - needs to know which byte is being overwritten in pt_ptr to properly update the state. *) - MAP_EVERY (fun i -> ENC_TAIL_SWAP_ASM_CASES_TAC (mk_numeral (num i))) (0--0) THEN + MAP_EVERY (fun i -> ENC_TAIL_SWAP_ASM_CASES_TAC (mk_numeral (num i))) (1--14) THEN UNDISCH_TAC `15 <= i` THEN UNDISCH_TAC `i < val (tail_len:int64)` THEN UNDISCH_TAC `val (tail_len:int64) < 16` THEN ARITH_TAC; + (* Subgoal 4: Prove backedge is taken when i > 0 *) - ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (1--2) THEN - ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN (* 3 total *) - (* `((forall i. - i < curr_len - ==> read (memory :> bytes8 (word_add ctxt_p (word i))) s5 - = EL i (aes256_xts_encrypt pt_in curr_len iv key1_lst key2_lst)) /\ - read (memory :> bytes128 (word_sub (word_add ctxt_p (word curr_len)) (word 0x10))) s5 - = cipher_stealing_enc_inv i curr_len (val tail_len) CC pt_in /\ - (forall i'. - i' < val tail_len - i - ==> read (memory :> bytes8 (word_add (word_add ctxt_p (word (curr_len + i))) (word i'))) s5 - = EL i' (SUB_LIST (i,val tail_len - i) (int128_to_bytes CC))) /\ - (val (word i) = 0x0 <=> i = 0x0)) /\ - ((MAYCHANGE [PC] ,, ...) s0 s5` - *) - REPEAT CONJ_TAC THENL (* 5 subgoals (7 total) *) - [ - (* `forall i. - i < curr_len - ==> read (memory :> bytes8 (word_add ctxt_p (word i))) s5 - = EL i (aes256_xts_encrypt pt_in curr_len iv key1_lst key2_lst)` *) - ] ] );; From 901206003cb12bc15bf26e68f7f091c8c2cf36fc Mon Sep 17 00:00:00 2001 From: Nevine Ebeid Date: Fri, 28 Nov 2025 12:29:15 -0500 Subject: [PATCH 097/132] Cipher-stealing: case tail != 0, loop invariant: Subgoal 4: complete. --- arm/proofs/aes-xts-armv8.ml | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/arm/proofs/aes-xts-armv8.ml b/arm/proofs/aes-xts-armv8.ml index a2525b3ac..60c823504 100644 --- a/arm/proofs/aes-xts-armv8.ml +++ b/arm/proofs/aes-xts-armv8.ml @@ -2549,6 +2549,19 @@ let SELECT_ONE_BYTE_FROM_FORALL = prove( REWRITE_TAC[WORD_VAL] );; +let IVAL_WORD_LT = prove( + `!i. i < 2 EXP 63 ==> ival ((word i):int64) = &i`, + GEN_TAC THEN DISCH_TAC THEN + REWRITE_TAC[ival; DIMINDEX_64; ARITH_RULE `64 - 1 = 63`] THEN + REWRITE_TAC[VAL_WORD; DIMINDEX_64] THEN + SUBGOAL_THEN `i < 2 EXP 64` ASSUME_TAC THENL + [ TRANS_TAC LT_TRANS `2 EXP 63` THEN + ASM_REWRITE_TAC[] THEN + CONV_TAC NUM_REDUCE_CONV; + ALL_TAC] THEN + ASM_SIMP_TAC[MOD_LT] +);; + (* ********************************************************** *) (* Properties that we prove about the specification functions *) (* Similar to the Decrypt ones but specified for Encrypt *) @@ -4184,7 +4197,28 @@ let CIPHER_STEALING_ENC_CORRECT = time prove( ARITH_TAC; (* Subgoal 4: Prove backedge is taken when i > 0 *) + REPEAT STRIP_TAC THEN + REWRITE_TAC[byte_list_at] THEN + ENSURES_INIT_TAC "s0" THEN + ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (1--1) THEN + SUBGOAL_THEN `ival ((word i):int64) < &0x0 <=> + ~(ival ((word (i + 0x1)):int64) - &0x1 = ival ((word i):int64))` ASSUME_TAC THENL + [ SUBGOAL_THEN `ival ((word i):int64) = &i` ASSUME_TAC THENL + [ MATCH_MP_TAC IVAL_WORD_LT THEN + UNDISCH_TAC `i < val (tail_len:int64)` THEN + UNDISCH_TAC `val (tail_len:int64) < 0x10` THEN + ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `ival ((word (i + 0x1)):int64) = &(i + 1)` ASSUME_TAC THENL + [ MATCH_MP_TAC IVAL_WORD_LT THEN + UNDISCH_TAC `i < val (tail_len:int64)` THEN + UNDISCH_TAC `val (tail_len:int64) < 0x10` THEN + ARITH_TAC; ALL_TAC] THEN + ASM_REWRITE_TAC[] THEN + ARITH_TAC; ALL_TAC] THEN + POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th])) THEN + ENSURES_FINAL_STATE_TAC THEN ASM_SIMP_TAC[]; + (* Subgoal 5: *) ] );; From bc7d0f43186fee1cc37d60a5cbcdcb4722ed6934 Mon Sep 17 00:00:00 2001 From: Nevine Ebeid Date: Fri, 28 Nov 2025 17:37:34 -0500 Subject: [PATCH 098/132] Cipher-stealing: case tail != 0, loop invariant: Subgoal 5, wip. --- arm/proofs/aes-xts-armv8.ml | 320 +++++++++++++++++++++++++++++++++++- 1 file changed, 317 insertions(+), 3 deletions(-) diff --git a/arm/proofs/aes-xts-armv8.ml b/arm/proofs/aes-xts-armv8.ml index 60c823504..6230b2117 100644 --- a/arm/proofs/aes-xts-armv8.ml +++ b/arm/proofs/aes-xts-armv8.ml @@ -1682,6 +1682,34 @@ let EL_SUB_LIST = prove( ] );; +let EL_SUB_LIST_GENERAL = prove( + `!p (l:A list) i n. i >= p /\ i < p + n /\ p + n <= LENGTH l ==> + EL (i - p) (SUB_LIST (p, n) l) = EL i l`, + INDUCT_TAC THENL + [ IMP_REWRITE_TAC[ADD; SUB_0; EL_SUB_LIST]; + ALL_TAC + ] THEN + LIST_INDUCT_TAC THENL + [ REWRITE_TAC[SUB_LIST_CLAUSES; LENGTH] THEN + REPEAT STRIP_TAC THEN + ASM_ARITH_TAC; + ALL_TAC + ] THEN + REWRITE_TAC[LENGTH] THEN + REPEAT STRIP_TAC THEN + REWRITE_TAC[SUB_LIST_CLAUSES] THEN + SUBGOAL_THEN `EL i (CONS h (t:A list)) = EL (i - 1) t` SUBST1_TAC THENL + [ SUBGOAL_THEN `i = SUC (i - 1)` SUBST1_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC] THEN + REWRITE_TAC[EL; TL] THEN + AP_THM_TAC THEN AP_TERM_TAC THEN + ARITH_TAC; ALL_TAC] THEN + REWRITE_TAC[ARITH_RULE `i - SUC p = i - 1 - p`] THEN + FIRST_X_ASSUM (fun th -> MP_TAC (SPECL [`t:A list`; `(i - 1):num`; `n:num`] th)) THEN + ANTS_TAC THENL [ ASM_ARITH_TAC; ALL_TAC ] THEN + SIMP_TAC[] +);; + let EL_SUB_LIST_SHIFT = prove( `!(i:num) p (l:A list) n. 0 < i /\ i < n /\ n <= LENGTH l - p ==> EL (i - 1) (SUB_LIST (p + 1, n - 1) l) = EL i (SUB_LIST (p, n) l)`, @@ -2699,6 +2727,61 @@ let LENGTH_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS = prove( ASM_ARITH_TAC );; +let LENGTH_OF_AES256_XTS_ENCRYPT = prove( + `! (i:num) (tail_len:num) (pt:byte list) (iv:int128) (key1:int128 list) (key2:int128 list). + ~(tail_len = 0) /\ tail_len < 16 ==> + LENGTH(aes256_xts_encrypt pt (16 * i + 16 + tail_len) iv key1 key2) = 16 * i + 16 + tail_len`, + REPEAT STRIP_TAC THEN + (* Case 1: i = 0 *) + ASM_CASES_TAC `i = 0` THENL + [ + ASM_SIMP_TAC[ADD_ASSOC] THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[aes256_xts_encrypt] THEN + SUBGOAL_THEN `~(0x10 + tail_len < 0x10)` ASSUME_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `(0x10 + tail_len) MOD 0x10 = tail_len` ASSUME_TAC THENL + [ REWRITE_TAC[ARITH_RULE `0x10 + tail_len = 1 * 16 + tail_len`] THEN + IMP_REWRITE_TAC[MOD_MULT_ADD; MOD_LT]; ALL_TAC] THEN + ASM_SIMP_TAC[] THEN + REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + SUBGOAL_THEN `((0x10 + tail_len) - tail_len) DIV 0x10 = 1` SUBST1_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC ] THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[LENGTH_OF_AES256_XTS_ENCRYPT_TAIL] THEN + ASM_ARITH_TAC; + ALL_TAC + ] THEN + + (* Case 2: i >= 1 *) + ASM_CASES_TAC `i >= 1` THENL + [ + REWRITE_TAC[aes256_xts_encrypt] THEN + SUBGOAL_THEN `(0x10 * i + 0x10 + tail_len) MOD 0x10 = tail_len` SUBST1_TAC THENL + [ REWRITE_TAC[ADD_ASSOC; ARITH_RULE `0x10 * i + 0x10 = 16 * (i + 1)`] THEN + IMP_REWRITE_TAC[MOD_MULT_ADD; MOD_LT]; ALL_TAC] THEN + SUBGOAL_THEN `~(0x10 * i + 0x10 + tail_len < 0x10)` ASSUME_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[] THEN + REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + SUBGOAL_THEN `((0x10 * i + 0x10 + tail_len) - tail_len) DIV 0x10 = i + 1` SUBST1_TAC THENL + [ REWRITE_TAC[ARITH_RULE `(0x10 * i + 0x10 + tail_len) - tail_len = 16 * (i + 1)`] THEN + IMP_REWRITE_TAC[DIV_MULT] THEN + ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `~(i + 1 < 2)` ASSUME_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[] THEN + IMP_REWRITE_TAC[ARITH_RULE `(i + 1) - 2 = i - 1`; ADD_SUB] THEN + REWRITE_TAC[LENGTH_APPEND] THEN + IMP_REWRITE_TAC[LENGTH_OF_AES256_XTS_ENCRYPT_REC] THEN + IMP_REWRITE_TAC[LENGTH_OF_AES256_XTS_ENCRYPT_TAIL] THEN + ASM_ARITH_TAC; + ALL_TAC + ] THEN + + ASM_ARITH_TAC +);; + let BYTES_TO_INT128_OF_INT128_TO_BYTES = prove( `!x. bytes_to_int128 (int128_to_bytes x) = x`, GEN_TAC THEN @@ -2820,6 +2903,93 @@ let SUB_LIST_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS = prove( ASM_ARITH_TAC );; +let SUB_LIST_OF_AES256_XTS_ENCRYPT = prove( + `!(i:num) (tail_len:num) (pt:byte list) (iv:int128) (key1:int128 list) (key2:int128 list). + ~(tail_len = 0) /\ tail_len < 16 ==> + (SUB_LIST (0,16 * i) + (aes256_xts_encrypt pt (16 * i + 16 + tail_len) iv key1 key2)) + = aes256_xts_encrypt pt (16 * i) iv key1 key2`, + REPEAT STRIP_TAC THEN + (* Case 1: i = 0 *) + ASM_CASES_TAC `i = 0` THENL + [ + ASM_REWRITE_TAC[] THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[ADD; SUB_LIST_CLAUSES; aes256_xts_encrypt] THEN + CONV_TAC NUM_REDUCE_CONV; + ALL_TAC + ] THEN + (* Case 2: i = 1 *) + ASM_CASES_TAC `i = 1` THENL + [ + ASM_REWRITE_TAC[] THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[aes256_xts_encrypt; ADD_ASSOC] THEN + CONV_TAC NUM_REDUCE_CONV THEN + SUBGOAL_THEN `~(0x20 + tail_len < 0x10)` ASSUME_TAC THENL [ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[] THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + CONV_TAC NUM_REDUCE_CONV THEN + SUBGOAL_THEN `(0x20 + tail_len) MOD 0x10 = tail_len` ASSUME_TAC THENL + [ ASM_SIMP_TAC[ARITH_RULE `32 = 2 * 16`; MOD_MULT_ADD] THEN + IMP_REWRITE_TAC[MOD_LT] + ; ALL_TAC] THEN + SUBGOAL_THEN `((0x20 + tail_len) - (0x20 + tail_len) MOD 0x10) DIV 0x10 = 0x2` ASSUME_TAC THENL + [ ASM_REWRITE_TAC[ADD_ASSOC; ADD_SUB] THEN + ARITH_TAC ; ALL_TAC] THEN + ASM_SIMP_TAC[] THEN + CONV_TAC NUM_REDUCE_CONV THEN + ASM_REWRITE_TAC[] THEN + MP_TAC (SPECL [`pt:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] LENGTH_OF_AES256_XTS_ENCRYPT_REC_TRIVIAL) THEN + DISCH_TAC THEN IMP_REWRITE_TAC[SUB_LIST_APPEND_LEFT] THEN + REWRITE_TAC[AES256_XTS_ENCRYPT_REC_EQ_TAIL_TRIVIAL] THEN + MP_TAC (SPECL [`pt:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] LENGTH_OF_AES256_XTS_ENCRYPT_TAIL_TRIVIAL) THEN + DISCH_TAC THEN IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN + ARITH_TAC; + ALL_TAC + ] THEN + + (* Case 3: i >= 2 *) + ASM_CASES_TAC `i >= 2` THENL + [ + ASM_REWRITE_TAC[ADD_ASSOC] THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[aes256_xts_encrypt] THEN + SUBGOAL_THEN `~(0x10 * i < 0x10)` ASSUME_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `~((0x10 * i + 0x10) + tail_len < 0x10)` ASSUME_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[LET_DEF; LET_END_DEF] THEN + SUBGOAL_THEN `((0x10 * i + 0x10) + tail_len) MOD 0x10 = tail_len` SUBST1_TAC THENL + [ REWRITE_TAC[ARITH_RULE `0x10 * i + 0x10 = 16 * (i + 1)`] THEN + IMP_REWRITE_TAC[MOD_MULT_ADD; MOD_LT] + ; ALL_TAC] THEN + REWRITE_TAC[ADD_SUB; MOD_MULT; SUB_0; + ARITH_RULE `0x10 * i + 0x10 = 16 * (i + 1)`] THEN + IMP_REWRITE_TAC[DIV_MULT] THEN + SUBGOAL_THEN `~(i + 1 < 2)` ASSUME_TAC THENL [ ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `~(i < 2)` ASSUME_TAC THENL [ ASM_ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[ADD_SUB; ARITH_RULE `(i + 1) - 2 = i - 1`] THEN + CONV_TAC NUM_REDUCE_CONV THEN + MP_TAC (SPECL [`0:num`; `(i - 1):num`; `pt:byte list`; `iv:int128`; + `key1:int128 list`; `key2:int128 list`] LENGTH_OF_AES256_XTS_ENCRYPT_REC) THEN + SUBGOAL_THEN `~((i - 1) < 0)` ASSUME_TAC THENL [ ASM_ARITH_TAC; ALL_TAC] THEN + IMP_REWRITE_TAC[ARITH_RULE `i >= 2 ==> i - 0x1 - 0x0 + 0x1 = i`] THEN + IMP_REWRITE_TAC[SUB_LIST_APPEND_LEFT] THEN + SIMP_TAC[ARITH_RULE `16 * i <= i * 16`] THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN + SIMP_TAC[ARITH_RULE `i * 16 = 16 * i`] THEN + DISCH_TAC THEN + MP_TAC (SPECL [`0`; `(i-2):num`; `pt:byte list`; `iv:int128`; + `key1:int128 list`; `key2:int128 list`] AES256_XTS_ENCRYPT_REC_EQ_TAIL) THEN + ANTS_TAC THENL [ ASM_ARITH_TAC; ALL_TAC ] THEN + IMP_REWRITE_TAC[ARITH_RULE `i >= 2 ==> i - 0x2 + 0x1 = i - 1`]; + ALL_TAC + ] THEN + + ASM_ARITH_TAC +);; let acc_len = new_definition `acc_len (i:int64) (len:int64) : num = @@ -3470,7 +3640,7 @@ let BREAK_DATA_INTO_PARTS = prove( ==> read (memory :> bytes8 (word_add pt_ptr (word i))) s = EL i bl) /\ (forall i. i < 16 ==> read (memory :> bytes8 (word_add (word_add pt_ptr (word curr_len)) (word i))) s = - EL i (SUB_LIST (curr_len, 16 + val tail_len) bl)) /\ + EL i (SUB_LIST (curr_len, 16) bl)) /\ (forall i. i < val tail_len ==> read (memory :> bytes8 (word_add (word_add pt_ptr (word (curr_len + 0x10))) (word i))) s = @@ -4218,8 +4388,152 @@ let CIPHER_STEALING_ENC_CORRECT = time prove( POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th])) THEN ENSURES_FINAL_STATE_TAC THEN ASM_SIMP_TAC[]; - (* Subgoal 5: *) - ] + (* Subgoal 5: *) + REPEAT STRIP_TAC THEN + REWRITE_TAC[byte_list_at] THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[cipher_stealing_inv; CONJUNCT1 SUB_LIST; CONJUNCT1 APPEND] THEN + REWRITE_TAC[SUB_0] THEN + ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN `val ((word (val (tail_len:int64))):int64) = val tail_len` SUBST1_TAC THENL + [ IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `(SUB_LIST (0x0,val (tail_len:int64)) (SUB_LIST (l1_curr_len + 16,val tail_len) (pt_in:byte list))) = + (SUB_LIST (l1_curr_len + 16,val tail_len) pt_in)` SUBST1_TAC THENL + [ IMP_REWRITE_TAC[SUB_LIST_REFL] THEN + ASM_REWRITE_TAC[LENGTH_SUB_LIST; MIN] THEN + ASM_ARITH_TAC; ALL_TAC] THEN + + MATCH_MP_TAC ENSURES_FRAME_SUBSUMED THEN + EXISTS_TAC `MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI ,, + MAYCHANGE [X19; X20; X21; X22],, + MAYCHANGE [Q8; Q9; Q10; Q11; Q12; Q13; Q14; Q15],, + MAYCHANGE [memory :> bytes128 (word_add ctxt_p (word l1_curr_len))]` THEN + REWRITE_TAC[MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI] THEN + CONJ_TAC THENL [ + REPEAT (GEN_REWRITE_TAC ONCE_DEPTH_CONV [GSYM SEQ_ASSOC] THEN + MATCH_MP_TAC SUBSUMED_SEQ THEN REWRITE_TAC[SUBSUMED_REFL]) THEN + ABBREV_TAC `vallen = val (len:int64)` THEN + SUBSUMED_MAYCHANGE_TAC; ALL_TAC] THEN + + ABBREV_TAC `curr_blocks = (acc_blocks (num_5blocks:int64) (len_full_blocks:int64) T):num` THEN + ENSURES_INIT_TAC "s0" THEN + ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (1--32) THEN + + ABBREV_TAC `combinedCC = bytes_to_int128 + (APPEND (SUB_LIST (l1_curr_len + 0x10,val (tail_len:int64)) (pt_in:byte list)) + (SUB_LIST (val tail_len,0x10 - val tail_len) + (int128_to_bytes (CC:int128))))` THEN + FIRST_X_ASSUM(MP_TAC o SPEC `aes256_xts_encrypt_round combinedCC + (calculate_tweak curr_blocks iv key2_lst) key1_lst` o MATCH_MP (MESON[] + `read (Q26:(armstate,int128)component) (s:armstate) = a ==> !a'. a = a' ==> read Q26 s = a'`)) THEN + ANTS_TAC THENL + [ EXPAND_TAC "key1_lst" THEN + CONV_TAC (RAND_CONV ( + REWRITE_CONV [aes256_xts_encrypt_round] THENC + DEPTH_CONV let_CONV)) THEN + GEN_REWRITE_TAC LAND_CONV [WORD_XOR_SYM] THEN + AP_THM_TAC THEN + REWRITE_TAC [aes256_encrypt] THEN + REWRITE_TAC EL_15_128_CLAUSES THEN + REWRITE_TAC [aes256_encrypt_round; aese; aesmc] THEN + CONV_TAC (TOP_DEPTH_CONV let_CONV) THEN + AP_TERM_TAC THEN + GEN_REWRITE_TAC LAND_CONV [WORD_XOR_SYM] THEN + REPEAT (AP_THM_TAC ORELSE AP_TERM_TAC) THEN + GEN_REWRITE_TAC LAND_CONV [WORD_XOR_SYM] THEN + REFL_TAC; DISCH_TAC ] THEN + + ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (33--33) THEN + ENSURES_FINAL_STATE_TAC THEN ASM_SIMP_TAC[] THEN + + UNDISCH_THEN `l1_curr_len + 16 + val (tail_len:int64) = val (len:int64)` + (fun th -> SUBST1_TAC (GSYM th)) THEN + REWRITE_TAC[GSYM (ASSUME `0x10 * l1_curr_blocks = l1_curr_len`)] THEN + + (* `forall i. + i < l1_curr_len + 0x10 + val tail_len + ==> read (memory :> bytes8 (word_add ctxt_p (word i))) s33 = + EL i (aes256_xts_encrypt pt_in (l1_curr_len + 0x10 + val tail_len) iv key1_lst key2_lst)`*) + MATCH_MP_TAC (SPECL [`l1_curr_len:num`; `tail_len:int64`; `ctxt_p:int64`; `s33:armstate`] + BREAK_DATA_INTO_PARTS) THEN + REPEAT CONJ_TAC THENL (* 4 subgoals *) + [ (* `0x10 * l1_curr_blocks + 0x10 + val tail_len <= + LENGTH (aes256_xts_encrypt pt_in (0x10 * l1_curr_blocks + 0x10 + val tail_len) iv key1_lst key2_lst)`*) + IMP_REWRITE_TAC[LENGTH_OF_AES256_XTS_ENCRYPT] THEN ARITH_TAC; + + (* `forall i. + i < 0x10 * l1_curr_blocks + ==> read (memory :> bytes8 (word_add ctxt_p (word i))) s33 = + EL i (aes256_xts_encrypt pt_in (0x10 * l1_curr_blocks + 0x10 + val tail_len) iv key1_lst key2_lst)` *) + UNDISCH_TAC `forall i. + i < l1_curr_len + ==> read (memory :> bytes8 (word_add ctxt_p (word i))) s33 = + EL i (aes256_xts_encrypt pt_in l1_curr_len iv key1_lst key2_lst)` THEN + REWRITE_TAC[GSYM (ASSUME `0x10 * l1_curr_blocks = l1_curr_len`)] THEN + MP_TAC (SPECL [`0x10 * l1_curr_blocks:num`; `ctxt_p:int64`; + `(aes256_xts_encrypt pt_in (0x10 * l1_curr_blocks + 0x10 + val (tail_len:int64)) iv key1_lst key2_lst):byte list`; + `s33:armstate`] BYTE_LIST_TO_NUM_THM) THEN + ANTS_TAC THENL [ + IMP_REWRITE_TAC[LENGTH_OF_AES256_XTS_ENCRYPT] THEN + ARITH_TAC; ALL_TAC] THEN + DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN + MP_TAC (SPECL [`0x10 * l1_curr_blocks:num`; `ctxt_p:int64`; + `(aes256_xts_encrypt pt_in (0x10 * l1_curr_blocks) iv key1_lst key2_lst):byte list`; + `s33:armstate`] BYTE_LIST_TO_NUM_THM) THEN + ANTS_TAC THENL [ + IMP_REWRITE_TAC[LENGTH_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS] THEN + ARITH_TAC; ALL_TAC] THEN + DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN + + DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN + AP_TERM_TAC THEN + MP_TAC(SPECL [`l1_curr_blocks:num`; `pt_in:byte list`; `iv:int128`; `key1_lst:int128 list`; `key2_lst:int128 list`] + LENGTH_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS) THEN + DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_OF_AES256_XTS_ENCRYPT] THEN + REWRITE_TAC[GSYM (ASSUME `0x10 * l1_curr_blocks = l1_curr_len`)] THEN + ASM_SIMP_TAC[SUB_LIST_LENGTH_IMPLIES]; + + (* `forall i. + i < 0x10 + ==> read (memory :> bytes8 (word_add (word_add ctxt_p (word (0x10 * l1_curr_blocks))) (word i))) + s33 = EL i (SUB_LIST (0x10 * l1_curr_blocks,0x10) + (aes256_xts_encrypt pt_in (0x10 * l1_curr_blocks + 0x10 + val tail_len) iv key1_lst key2_lst))` *) + MP_TAC (SPECL [`0x10:num`; `(word_add ctxt_p (word (0x10 * l1_curr_blocks))):int64`; + ` (SUB_LIST (0x10 * l1_curr_blocks,0x10) + (aes256_xts_encrypt pt_in (0x10 * l1_curr_blocks + 0x10 + val (tail_len:int64)) + iv key1_lst key2_lst)):byte list`; + `s33:armstate`] BYTE_LIST_TO_NUM_THM) THEN + ANTS_TAC THENL [ + REWRITE_TAC[LENGTH_SUB_LIST] THEN + IMP_REWRITE_TAC[LENGTH_OF_AES256_XTS_ENCRYPT] THEN + ARITH_TAC; ALL_TAC] THEN + REWRITE_TAC[SUB_LIST_MIN_RIGHT; MIN] THEN + DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN + + REWRITE_TAC[READ_MEMORY_BYTES_BYTES128] THEN + ASM_REWRITE_TAC[] THEN + SIMP_TAC[ARITH_RULE `0x10 <= 0x10`] THEN + REWRITE_TAC[aes256_xts_encrypt] THEN + SIMP_TAC[ARITH_RULE `!x y. ~(x + 16 + y < 16)`] THEN + REWRITE_TAC[GSYM (ASSUME `0x10 * l1_curr_blocks = l1_curr_len`); + ARITH_RULE `0x10 * l1_curr_blocks + 0x10 + val tail_len = + 0x10 * (l1_curr_blocks + 1) + val tail_len`] THEN + REWRITE_TAC[MOD_MULT_ADD] THEN + ASM_SIMP_TAC[MOD_LT] THEN + REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + REWRITE_TAC[ARITH_RULE + `((0x10 * (l1_curr_blocks + 0x1) + val tail_len) - val tail_len) DIV 0x10 = + (0x10 * (l1_curr_blocks + 0x1)) DIV 0x10`] THEN + IMP_REWRITE_TAC[DIV_MULT; ARITH_RULE `~(16 = 0)`] THEN + COND_CASES_TAC THENL + [ + ] + + ] + + + ] (* end of loop invariant proof. *) );; (* Proof: Less than 2 blocks *) From dd5e06f55b85e6ed8f08053bc5bc1e0517ccf932 Mon Sep 17 00:00:00 2001 From: Nevine Ebeid Date: Mon, 1 Dec 2025 13:29:12 -0500 Subject: [PATCH 099/132] Cipher-stealing: case tail != 0, loop invariant: Subgoal 5, wip (incomplete subgoals l. 3977 and l. 4485. --- arm/proofs/aes-xts-armv8.ml | 128 +++++++++++++++++++++++++++++++++--- 1 file changed, 119 insertions(+), 9 deletions(-) diff --git a/arm/proofs/aes-xts-armv8.ml b/arm/proofs/aes-xts-armv8.ml index 6230b2117..0e622244d 100644 --- a/arm/proofs/aes-xts-armv8.ml +++ b/arm/proofs/aes-xts-armv8.ml @@ -2350,6 +2350,64 @@ let LENGTH_OF_INT128_TO_BYTES = prove( CONV_TAC NUM_REDUCE_CONV );; +let SUB_LIST_OF_INT128_TO_BYTES = prove( + `!x. SUB_LIST (0, 16) (int128_to_bytes x) = int128_to_bytes x`, + GEN_TAC THEN + MP_TAC (SPEC `x:int128` LENGTH_OF_INT128_TO_BYTES) THEN + DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] +);; + +let ELEM_TAC i = + CONV_TAC (RAND_CONV (REWRITE_CONV [num_CONV i])) THEN + REWRITE_TAC[bytelist_of_num] THEN + REWRITE_TAC[CONS_11] THEN + CONJ_TAC THENL [ + REWRITE_TAC[word_subword] THEN + AP_TERM_TAC THEN + (ARITH_TAC ORELSE + ( ASM_REWRITE_TAC[CONJUNCT1 EXP; DIV_1; DIV_DIV] THEN + CONV_TAC NUM_REDUCE_CONV)); ALL_TAC];; + +let INT128_TO_BYTES_EQ_BYTELIST_OF_NUM = prove( + `!x. int128_to_bytes x = bytelist_of_num 16 (val x)`, + GEN_TAC THEN + REWRITE_TAC[int128_to_bytes] THEN + + MAP_EVERY (fun i -> ELEM_TAC (mk_numeral (num i))) (List.rev (2 -- 16)) THEN + CONV_TAC (RAND_CONV (REWRITE_CONV [num_CONV `1`])) THEN + REWRITE_TAC[bytelist_of_num] THEN + REWRITE_TAC[CONS_11] THEN + REWRITE_TAC[word_subword] THEN + AP_TERM_TAC THEN + ASM_REWRITE_TAC[DIV_DIV] THEN + CONV_TAC NUM_REDUCE_CONV +);; + +let NUM_OF_BYTELIST_OF_INT128_TO_BYTES = prove( + `!x. num_of_bytelist (int128_to_bytes x) = val x`, + GEN_TAC THEN + REWRITE_TAC[INT128_TO_BYTES_EQ_BYTELIST_OF_NUM] THEN + REWRITE_TAC[NUM_OF_BYTELIST_OF_NUM] THEN + SUBGOAL_THEN `val (x:int128) < 2 EXP 128` ASSUME_TAC THENL + [ MP_TAC (ISPEC `x:int128` VAL_BOUND) THEN + REWRITE_TAC[DIMINDEX_128] THEN + ARITH_TAC; ALL_TAC + ] THEN + IMP_REWRITE_TAC[MOD_LT] THEN + ASM_ARITH_TAC +);; + +let CALCULATE_TWEAK_EXPAND = prove( + `!x iv key. + GF_128_mult_by_primitive (calculate_tweak x iv key) = + calculate_tweak (x + 0x1) iv key`, + REPEAT GEN_TAC THEN + REWRITE_TAC[ARITH_RULE `x + 1 = SUC x`] THEN + CONV_TAC (RAND_CONV (REWRITE_CONV[CONJUNCT2 calculate_tweak])) THEN + REFL_TAC +);; + let DIVISION_BY_80_LEMMA = prove( `!(a:num) b. a DIV 0x50 = b /\ 0x10 divides a /\ @@ -2615,7 +2673,7 @@ let LENGTH_OF_AES256_XTS_ENCRYPT_REC = prove( [ASM_ARITH_TAC; ASM_ARITH_TAC]] );; -let LENGTH_OF_FST_OF_CIPHER_STEALING = prove( +let LENGTH_OF_FST_OF_ENC_CIPHER_STEALING = prove( `!(block:byte list) (tail:byte list) (tail_len:num) (iv:int128) (i:num) (key1:int128 list) (key2:int128 list). LENGTH (FST (cipher_stealing_encrypt block tail tail_len iv i key1 key2)) = 16`, @@ -2625,7 +2683,7 @@ let LENGTH_OF_FST_OF_CIPHER_STEALING = prove( REWRITE_TAC[LENGTH_OF_INT128_TO_BYTES] );; -let LENGTH_OF_SND_OF_CIPHER_STEALING = prove( +let LENGTH_OF_SND_OF_ENC_CIPHER_STEALING = prove( `!(block:byte list) (tail:byte list) (tail_len:num) (iv:int128) (i:num) (key1:int128 list) (key2:int128 list). LENGTH (SND (cipher_stealing_encrypt block tail tail_len iv i key1 key2)) = MIN tail_len 16`, @@ -2650,8 +2708,8 @@ let LENGTH_OF_AES256_XTS_ENCRYPT_TAIL = prove( CONV_TAC NUM_REDUCE_CONV; REWRITE_TAC[LET_DEF; LET_END_DEF; LENGTH_APPEND] THEN - REWRITE_TAC[LENGTH_OF_FST_OF_CIPHER_STEALING] THEN - REWRITE_TAC[LENGTH_OF_SND_OF_CIPHER_STEALING]] + REWRITE_TAC[LENGTH_OF_FST_OF_ENC_CIPHER_STEALING] THEN + REWRITE_TAC[LENGTH_OF_SND_OF_ENC_CIPHER_STEALING]] );; let LENGTH_OF_AES256_XTS_ENCRYPT_REC_TRIVIAL = prove( @@ -3885,13 +3943,13 @@ let CIPHER_STEALING_ENC_CORRECT = time prove( SUBGOAL_THEN `val ((word (l1_curr_len + 0x10)):int64) = l1_curr_len + 0x10` ASSUME_TAC THENL [ IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN ASM_ARITH_TAC; ALL_TAC] THEN - +(* SUBGOAL_THEN `l1_curr_len >= 0` ASSUME_TAC THENL [ REWRITE_TAC[GSYM (ASSUME `(acc_len num_5blocks len_full_blocks) - 0x10 = l1_curr_len`)] THEN MP_TAC (SPECL [`num_5blocks:int64`; `len_full_blocks:int64`] VALUE_OF_ACC_LEN) THEN REPEAT_N 3 (ANTS_TAC THENL [ASM_ARITH_TAC ORELSE ASM_SIMP_TAC[]; ALL_TAC]) THEN ASM_ARITH_TAC ; ALL_TAC ] THEN - +*) SUBGOAL_THEN `16 * l1_curr_blocks = l1_curr_len` ASSUME_TAC THENL [ REWRITE_TAC[GSYM (ASSUME `(acc_len num_5blocks len_full_blocks) - 0x10 = l1_curr_len`)] THEN (* put in tips doc*) (* or UNDISCH_THEN `acc_len (num_5blocks:int64) (len_full_blocks:int64) = curr_len` @@ -3916,6 +3974,14 @@ let CIPHER_STEALING_ENC_CORRECT = time prove( [ REWRITE_TAC[GSYM (ASSUME `(acc_len num_5blocks len_full_blocks) - 0x10 = l1_curr_len`)] THEN ASM_ARITH_TAC; ALL_TAC ] THEN + SUBGOAL_THEN `1 <= acc_blocks (num_5blocks:int64) (len_full_blocks:int64) true` ASSUME_TAC THENL + [ REWRITE_TAC[acc_blocks] THEN + REPEAT_N 4 (COND_CASES_TAC THENL [SIMP_TAC[] THEN ARITH_TAC; ALL_TAC] THEN SIMP_TAC[]) THEN + EXPAND_TAC "num_5blocks" THEN + REWRITE_TAC[VAL_WORD; DIMINDEX_64] THEN + + ] + SUBGOAL_THEN `l1_curr_len + 0x10 + val (tail_len:int64) = val (len:int64)` ASSUME_TAC THENL [ REWRITE_TAC[GSYM (ASSUME `acc_len num_5blocks len_full_blocks - 0x10 = l1_curr_len`)] THEN @@ -4416,6 +4482,19 @@ let CIPHER_STEALING_ENC_CORRECT = time prove( SUBSUMED_MAYCHANGE_TAC; ALL_TAC] THEN ABBREV_TAC `curr_blocks = (acc_blocks (num_5blocks:int64) (len_full_blocks:int64) T):num` THEN + SUBGOAL_THEN `curr_blocks = l1_curr_blocks + 0x1` ASSUME_TAC THENL + [ REWRITE_TAC[GSYM (ASSUME `curr_blocks - 0x1 = l1_curr_blocks`)] THEN + EXPAND_TAC "curr_blocks" THEN + REWRITE_TAC[acc_blocks] THEN + REPEAT_N 4 (COND_CASES_TAC THENL [SIMP_TAC[] THEN ARITH_TAC; ALL_TAC] THEN SIMP_TAC[]) THEN + EXPAND_TAC "num_5blocks" THEN + REWRITE_TAC[VAL_WORD; DIMINDEX_64] THEN + UNDISCH_TAC `val (len_full_blocks:int64) <= 0x2 EXP 0x18` THEN + ASM_SIMP_TAC[ MOD_LT; ARITH_RULE `~(val (len_full_blocks:int64) < 0x10) ==> val len_full_blocks <= 0x2 EXP 0x18 ==> + val len_full_blocks DIV 0x50 <= 0x2 EXP 0x40`] THEN + ASM_ARITH_TAC THEN + ] + ENSURES_INIT_TAC "s0" THEN ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (1--32) THEN @@ -4527,8 +4606,39 @@ let CIPHER_STEALING_ENC_CORRECT = time prove( (0x10 * (l1_curr_blocks + 0x1)) DIV 0x10`] THEN IMP_REWRITE_TAC[DIV_MULT; ARITH_RULE `~(16 = 0)`] THEN COND_CASES_TAC THENL - [ - ] + [ (* `l1_curr_blocks + 0x1 < 0x2` *) + REWRITE_TAC[GSYM (ASSUME `0x10 * l1_curr_blocks = l1_curr_len`)] THEN + SUBGOAL_THEN `l1_curr_blocks = 0` SUBST_ALL_TAC THENL + [ UNDISCH_TAC `l1_curr_blocks + 0x1 < 2` THEN ARITH_TAC ; ALL_TAC] THEN + EXPAND_TAC "combinedCC" THEN + REWRITE_TAC[aes256_xts_encrypt_tail] THEN + ASM_SIMP_TAC[LET_DEF; LET_END_DEF] THEN + REWRITE_TAC[GSYM (ASSUME `0x10 * 0 = l1_curr_len`)] THEN + CONV_TAC NUM_REDUCE_CONV THEN + + MP_TAC (SPECL [`(SUB_LIST (0,0x10) pt_in):byte list`; + `(SUB_LIST (0x10,val (tail_len:int64)) pt_in):byte list`; + `val (tail_len:int64)`; `iv:int128`; `0:num`; `key1_lst:int128 list`; + `key2_lst:int128 list`] LENGTH_OF_FST_OF_CIPHER_STEALING) THEN + DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_APPEND_LEFT; ARITH_RULE `16 <= 16`] THEN + + REWRITE_TAC[cipher_stealing_encrypt; LET_DEF; LET_END_DEF] THEN + REWRITE_TAC[SUB_LIST_OF_INT128_TO_BYTES; + NUM_OF_BYTELIST_OF_INT128_TO_BYTES; CALCULATE_TWEAK_EXPAND] THEN + EXPAND_TAC "combinedCC" THEN + EXPAND_TAC "CC" THEN + REWRITE_TAC[GSYM (ASSUME `0x10 * 0 = l1_curr_len`)] THEN + CONV_TAC NUM_REDUCE_CONV THEN + + SUBGOAL_THEN `curr_blocks = 0x1` SUBST1_TAC THENL + [ UNDISCH_TAC `curr_blocks - 0x1 = 0x0` THEN + ARITH_TAC THEN + ] + ALL_TAC + ] THEN + + ] @@ -4910,7 +5020,7 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( Up to the loop: - First 5 tweaks are calculated from the iv - X2 contains len_full_blocks - - X8 contains num_5_blocks + - X8 contains num_5blocks - key1 schedule is loaded in Q registers - X9 and X10 are not needed to be spelled out for the proof itself, but to be kept in the assumption list after the proof *) From 3e0a69f5c3ae11f524b3431c2c5a222dff99e436 Mon Sep 17 00:00:00 2001 From: Nevine Ebeid Date: Mon, 1 Dec 2025 14:41:10 -0500 Subject: [PATCH 100/132] Cipher-stealing: case tail != 0, loop invariant: Subgoal 5, proved subgoals of previous commit. --- arm/proofs/aes-xts-armv8.ml | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/arm/proofs/aes-xts-armv8.ml b/arm/proofs/aes-xts-armv8.ml index 0e622244d..afd3a7a9e 100644 --- a/arm/proofs/aes-xts-armv8.ml +++ b/arm/proofs/aes-xts-armv8.ml @@ -3977,10 +3977,20 @@ let CIPHER_STEALING_ENC_CORRECT = time prove( SUBGOAL_THEN `1 <= acc_blocks (num_5blocks:int64) (len_full_blocks:int64) true` ASSUME_TAC THENL [ REWRITE_TAC[acc_blocks] THEN REPEAT_N 4 (COND_CASES_TAC THENL [SIMP_TAC[] THEN ARITH_TAC; ALL_TAC] THEN SIMP_TAC[]) THEN - EXPAND_TAC "num_5blocks" THEN - REWRITE_TAC[VAL_WORD; DIMINDEX_64] THEN - - ] + SUBGOAL_THEN `val (num_5blocks:int64) * 0x50 = val (len_full_blocks:int64)` ASSUME_TAC THENL + [ MATCH_MP_TAC (SPECL [`val (len_full_blocks:int64)`; `val (num_5blocks:int64)`] DIVISION_BY_80_LEMMA) THEN + REPEAT CONJ_TAC THENL + [ + ASM_SIMP_TAC[]; + ASM_SIMP_TAC[]; + UNDISCH_TAC `~(val (num_5blocks:int64) * 0x50 + 0x10 = val (len_full_blocks:int64))` THEN ARITH_TAC; + UNDISCH_TAC `~(val (num_5blocks:int64) * 0x50 + 0x20 = val (len_full_blocks:int64))` THEN ARITH_TAC; + UNDISCH_TAC `~(val (num_5blocks:int64) * 0x50 + 0x30 = val (len_full_blocks:int64))` THEN ARITH_TAC; + UNDISCH_TAC `~(val (num_5blocks:int64) * 0x50 + 0x40 = val (len_full_blocks:int64))` THEN ARITH_TAC ] + ; ALL_TAC] THEN + SUBGOAL_THEN `0x10 <= val (num_5blocks:int64) * 0x50` ASSUME_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC ] THEN + ASM_ARITH_TAC; ALL_TAC ] SUBGOAL_THEN `l1_curr_len + 0x10 + val (tail_len:int64) = val (len:int64)` ASSUME_TAC THENL [ REWRITE_TAC[GSYM (ASSUME `acc_len num_5blocks len_full_blocks - 0x10 = l1_curr_len`)] THEN @@ -4482,18 +4492,11 @@ let CIPHER_STEALING_ENC_CORRECT = time prove( SUBSUMED_MAYCHANGE_TAC; ALL_TAC] THEN ABBREV_TAC `curr_blocks = (acc_blocks (num_5blocks:int64) (len_full_blocks:int64) T):num` THEN + SUBGOAL_THEN `curr_blocks = l1_curr_blocks + 0x1` ASSUME_TAC THENL [ REWRITE_TAC[GSYM (ASSUME `curr_blocks - 0x1 = l1_curr_blocks`)] THEN EXPAND_TAC "curr_blocks" THEN - REWRITE_TAC[acc_blocks] THEN - REPEAT_N 4 (COND_CASES_TAC THENL [SIMP_TAC[] THEN ARITH_TAC; ALL_TAC] THEN SIMP_TAC[]) THEN - EXPAND_TAC "num_5blocks" THEN - REWRITE_TAC[VAL_WORD; DIMINDEX_64] THEN - UNDISCH_TAC `val (len_full_blocks:int64) <= 0x2 EXP 0x18` THEN - ASM_SIMP_TAC[ MOD_LT; ARITH_RULE `~(val (len_full_blocks:int64) < 0x10) ==> val len_full_blocks <= 0x2 EXP 0x18 ==> - val len_full_blocks DIV 0x50 <= 0x2 EXP 0x40`] THEN - ASM_ARITH_TAC THEN - ] + ASM_ARITH_TAC; ALL_TAC ] ENSURES_INIT_TAC "s0" THEN ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (1--32) THEN From fc80078cbbe22373e289d7a62444b90261cdf8b7 Mon Sep 17 00:00:00 2001 From: Nevine Ebeid Date: Mon, 1 Dec 2025 17:17:55 -0500 Subject: [PATCH 101/132] Cipher-stealing: complete. --- arm/proofs/aes-xts-armv8.ml | 214 ++++++++++++++++++++++++++++++++---- 1 file changed, 195 insertions(+), 19 deletions(-) diff --git a/arm/proofs/aes-xts-armv8.ml b/arm/proofs/aes-xts-armv8.ml index afd3a7a9e..bfceb9a20 100644 --- a/arm/proofs/aes-xts-armv8.ml +++ b/arm/proofs/aes-xts-armv8.ml @@ -2151,6 +2151,52 @@ let SUB_LIST_APPEND_RIGHT_LEMMA = prove( SIMP_TAC[LENGTH_EQ_NIL] THEN REWRITE_TAC[APPEND]; ASM_SIMP_TAC[APPEND; LENGTH; SUB_LIST_CLAUSES; SUC_INJ]]]);; +let SUB_LIST_APPEND_RIGHT_GENERAL = prove( + `!(x:A list) y n m p. LENGTH x = p ==> n >= p ==> + SUB_LIST (n,m) (APPEND x y) = SUB_LIST (n - p,m) y`, + LIST_INDUCT_TAC THENL + [ + REPEAT GEN_TAC THEN + SIMP_TAC[CONJUNCT1 LENGTH; APPEND; SUB_LIST_CLAUSES] THEN + DISCH_THEN (fun th -> REWRITE_TAC[GSYM th]) THEN + REWRITE_TAC[SUB_0]; + + ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN + INDUCT_TAC THENL + [ + REPEAT STRIP_TAC THEN + SUBGOAL_THEN `p = 0` SUBST_ALL_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN + CONV_TAC NUM_REDUCE_CONV THEN + SUBGOAL_THEN `CONS h t = ([]:A list)` ASSUME_TAC THENL + [ UNDISCH_TAC `LENGTH (CONS h (t:A list)) = 0` THEN + SIMP_TAC[LENGTH_EQ_NIL]; ALL_TAC] THEN + ASM_REWRITE_TAC[] THEN + REWRITE_TAC[APPEND]; + + REPEAT STRIP_TAC THEN + SUBGOAL_THEN `p > 0` ASSUME_TAC THENL + [ UNDISCH_TAC `LENGTH (CONS h (t:A list)) = p` THEN + ASM_REWRITE_TAC[LENGTH] THEN + MP_TAC (SPEC `LENGTH (t:A list)` (ARITH_RULE `!x. SUC x > 0`)) THEN + ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `LENGTH (t:A list) = p - 1` ASSUME_TAC THENL + [ UNDISCH_TAC `LENGTH (CONS h (t:A list)) = p` THEN + ASM_REWRITE_TAC[LENGTH] THEN + MP_TAC (SPECL [`LENGTH (t:A list)`; `p:num`] (ARITH_RULE `!n m. SUC n = m ==> n = m - 1`)) THEN + SIMP_TAC[]; ALL_TAC] THEN + SUBGOAL_THEN `n >= p - 1` ASSUME_TAC THENL + [ MP_TAC (ARITH_RULE `SUC n >= p /\ p > 0 ==> n >= p - 1`) THEN + ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `SUC n - p = n - (p - 1)` ASSUME_TAC THENL + [ MP_TAC (ARITH_RULE `SUC n >= p /\ p > 0 ==> SUC n - p = n - (p - 1)`) THEN + ASM_ARITH_TAC; ALL_TAC] THEN + ASM_REWRITE_TAC[APPEND; LENGTH; SUB_LIST_CLAUSES; SUC_INJ] THEN + FIRST_X_ASSUM (fun th -> MP_TAC (SPECL [`y:A list`; `n:num`; `m:num`; `(p-1):num`] th)) THEN + ASM_SIMP_TAC[] + ] + ] +);; + let SUB_LIST_LENGTH_IMPLIES = prove( `!(l:A list) n. LENGTH l = n ==> SUB_LIST(0,n) l = l`, REPEAT STRIP_TAC THEN @@ -3990,7 +4036,7 @@ let CIPHER_STEALING_ENC_CORRECT = time prove( ; ALL_TAC] THEN SUBGOAL_THEN `0x10 <= val (num_5blocks:int64) * 0x50` ASSUME_TAC THENL [ ASM_ARITH_TAC; ALL_TAC ] THEN - ASM_ARITH_TAC; ALL_TAC ] + ASM_ARITH_TAC; ALL_TAC ] THEN SUBGOAL_THEN `l1_curr_len + 0x10 + val (tail_len:int64) = val (len:int64)` ASSUME_TAC THENL [ REWRITE_TAC[GSYM (ASSUME `acc_len num_5blocks len_full_blocks - 0x10 = l1_curr_len`)] THEN @@ -4170,8 +4216,6 @@ let CIPHER_STEALING_ENC_CORRECT = time prove( IMP_REWRITE_TAC[SPECL [`ctxt_p:int64`; `l1_curr_len:num`; `(aes256_xts_encrypt pt_in (l1_curr_len + 0x10) iv key1_lst key2_lst):byte list`; `s5:armstate`] READ_BYTES_AND_BYTE128_MERGE] THEN - (*DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o SPECL [`iv:int128`; `key1_lst:int128 list`; - `key2_lst:int128 list`; `pt_in:byte list`]) THEN *) EXISTS_TAC `iv:int128` THEN EXISTS_TAC `key1_lst:int128 list` THEN EXISTS_TAC `key2_lst:int128 list` THEN EXISTS_TAC `pt_in:byte list` THEN (* `num_of_bytelist (SUB_LIST (0x0,l1_curr_len) @@ -4496,7 +4540,7 @@ let CIPHER_STEALING_ENC_CORRECT = time prove( SUBGOAL_THEN `curr_blocks = l1_curr_blocks + 0x1` ASSUME_TAC THENL [ REWRITE_TAC[GSYM (ASSUME `curr_blocks - 0x1 = l1_curr_blocks`)] THEN EXPAND_TAC "curr_blocks" THEN - ASM_ARITH_TAC; ALL_TAC ] + ASM_ARITH_TAC; ALL_TAC ] THEN ENSURES_INIT_TAC "s0" THEN ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (1--32) THEN @@ -4508,6 +4552,7 @@ let CIPHER_STEALING_ENC_CORRECT = time prove( FIRST_X_ASSUM(MP_TAC o SPEC `aes256_xts_encrypt_round combinedCC (calculate_tweak curr_blocks iv key2_lst) key1_lst` o MATCH_MP (MESON[] `read (Q26:(armstate,int128)component) (s:armstate) = a ==> !a'. a = a' ==> read Q26 s = a'`)) THEN + REWRITE_TAC[ASSUME `curr_blocks = l1_curr_blocks + 0x1`] THEN ANTS_TAC THENL [ EXPAND_TAC "key1_lst" THEN CONV_TAC (RAND_CONV ( @@ -4533,17 +4578,19 @@ let CIPHER_STEALING_ENC_CORRECT = time prove( REWRITE_TAC[GSYM (ASSUME `0x10 * l1_curr_blocks = l1_curr_len`)] THEN (* `forall i. - i < l1_curr_len + 0x10 + val tail_len + i < 0x10 * l1_curr_blocks + 0x10 + val tail_len ==> read (memory :> bytes8 (word_add ctxt_p (word i))) s33 = - EL i (aes256_xts_encrypt pt_in (l1_curr_len + 0x10 + val tail_len) iv key1_lst key2_lst)`*) - MATCH_MP_TAC (SPECL [`l1_curr_len:num`; `tail_len:int64`; `ctxt_p:int64`; `s33:armstate`] + EL i (aes256_xts_encrypt pt_in (0x10 * l1_curr_blocks + 0x10 + val tail_len) iv key1_lst key2_lst)` *) + MATCH_MP_TAC (SPECL [`0x10 * l1_curr_blocks:num`; `tail_len:int64`; `ctxt_p:int64`; `s33:armstate`] BREAK_DATA_INTO_PARTS) THEN REPEAT CONJ_TAC THENL (* 4 subgoals *) - [ (* `0x10 * l1_curr_blocks + 0x10 + val tail_len <= + [ (* 1. + `0x10 * l1_curr_blocks + 0x10 + val tail_len <= LENGTH (aes256_xts_encrypt pt_in (0x10 * l1_curr_blocks + 0x10 + val tail_len) iv key1_lst key2_lst)`*) IMP_REWRITE_TAC[LENGTH_OF_AES256_XTS_ENCRYPT] THEN ARITH_TAC; - (* `forall i. + (* 2. + `forall i. i < 0x10 * l1_curr_blocks ==> read (memory :> bytes8 (word_add ctxt_p (word i))) s33 = EL i (aes256_xts_encrypt pt_in (0x10 * l1_curr_blocks + 0x10 + val tail_len) iv key1_lst key2_lst)` *) @@ -4576,7 +4623,8 @@ let CIPHER_STEALING_ENC_CORRECT = time prove( REWRITE_TAC[GSYM (ASSUME `0x10 * l1_curr_blocks = l1_curr_len`)] THEN ASM_SIMP_TAC[SUB_LIST_LENGTH_IMPLIES]; - (* `forall i. + (* 3. + `forall i. i < 0x10 ==> read (memory :> bytes8 (word_add (word_add ctxt_p (word (0x10 * l1_curr_blocks))) (word i))) s33 = EL i (SUB_LIST (0x10 * l1_curr_blocks,0x10) @@ -4611,12 +4659,13 @@ let CIPHER_STEALING_ENC_CORRECT = time prove( COND_CASES_TAC THENL [ (* `l1_curr_blocks + 0x1 < 0x2` *) REWRITE_TAC[GSYM (ASSUME `0x10 * l1_curr_blocks = l1_curr_len`)] THEN - SUBGOAL_THEN `l1_curr_blocks = 0` SUBST_ALL_TAC THENL + SUBGOAL_THEN `l1_curr_blocks = 0` ASSUME_TAC THENL [ UNDISCH_TAC `l1_curr_blocks + 0x1 < 2` THEN ARITH_TAC ; ALL_TAC] THEN + REWRITE_TAC[ASSUME `l1_curr_blocks = 0x0`] THEN EXPAND_TAC "combinedCC" THEN REWRITE_TAC[aes256_xts_encrypt_tail] THEN ASM_SIMP_TAC[LET_DEF; LET_END_DEF] THEN - REWRITE_TAC[GSYM (ASSUME `0x10 * 0 = l1_curr_len`)] THEN + ASM_REWRITE_TAC[GSYM (ASSUME `0 = l1_curr_len`)] THEN CONV_TAC NUM_REDUCE_CONV THEN MP_TAC (SPECL [`(SUB_LIST (0,0x10) pt_in):byte list`; @@ -4631,26 +4680,153 @@ let CIPHER_STEALING_ENC_CORRECT = time prove( NUM_OF_BYTELIST_OF_INT128_TO_BYTES; CALCULATE_TWEAK_EXPAND] THEN EXPAND_TAC "combinedCC" THEN EXPAND_TAC "CC" THEN - REWRITE_TAC[GSYM (ASSUME `0x10 * 0 = l1_curr_len`)] THEN + REWRITE_TAC[GSYM (ASSUME `0x10 * l1_curr_blocks = l1_curr_len`); ASSUME `l1_curr_blocks = 0x0`] THEN + CONV_TAC NUM_REDUCE_CONV; + ALL_TAC + ] THEN + + SUBGOAL_THEN `l1_curr_blocks >= 1` ASSUME_TAC THENL + [ UNDISCH_TAC `~(l1_curr_blocks + 0x1 < 0x2)` THEN ARITH_TAC; ALL_TAC] THEN + + IMP_REWRITE_TAC[ADD_SUB; ARITH_RULE `((l1_curr_blocks + 0x1) - 0x2) = l1_curr_blocks - 1`] THEN + + MP_TAC (SPECL [`0:num`; `(l1_curr_blocks - 1):num`; `pt_in:byte list`; `iv:int128`; + `key1_lst:int128 list`; `key2_lst:int128 list`] LENGTH_OF_AES256_XTS_ENCRYPT_REC) THEN + ASM_SIMP_TAC[ARITH_RULE `l1_curr_blocks >= 1 ==> ~(l1_curr_blocks - 1 < 0)`] THEN + IMP_REWRITE_TAC[SUB_0; ARITH_RULE `l1_curr_blocks >= 1 ==> l1_curr_blocks - 1 + 1 = l1_curr_blocks`] THEN + ONCE_REWRITE_TAC[ARITH_RULE `l1_curr_blocks * 16 = 16 * l1_curr_blocks`] THEN + DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_APPEND_RIGHT_LEMMA] THEN + + REWRITE_TAC[aes256_xts_encrypt_tail] THEN + ASM_SIMP_TAC[LET_DEF; LET_END_DEF] THEN + + MP_TAC (SPECL [`(SUB_LIST (l1_curr_blocks * 0x10,0x10) pt_in):byte list`; + `(SUB_LIST ((l1_curr_blocks + 0x1) * 0x10,val (tail_len:int64)) pt_in):byte list`; + `val (tail_len:int64)`; `iv:int128`; `l1_curr_blocks:num`; `key1_lst:int128 list`; + `key2_lst:int128 list`] LENGTH_OF_FST_OF_CIPHER_STEALING) THEN + DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_APPEND_LEFT; ARITH_RULE `16 <= 16`] THEN + + REWRITE_TAC[cipher_stealing_encrypt; LET_DEF; LET_END_DEF] THEN + REWRITE_TAC[SUB_LIST_OF_INT128_TO_BYTES; + NUM_OF_BYTELIST_OF_INT128_TO_BYTES; CALCULATE_TWEAK_EXPAND; + ARITH_RULE `l1_curr_blocks * 16 = 16 * l1_curr_blocks`; + ARITH_RULE `0x10 * (l1_curr_blocks + 0x1) = 16 * l1_curr_blocks + 16`] THEN + EXPAND_TAC "combinedCC" THEN + EXPAND_TAC "CC" THEN + REWRITE_TAC[GSYM (ASSUME `0x10 * l1_curr_blocks = l1_curr_len`)]; + + (* 4. Proving tail is correct + `forall i. + i < val tail_len + ==> read (memory :> bytes8 (word_add (word_add ctxt_p (word (0x10 * l1_curr_blocks + 0x10))) + (word i))) s33 = + EL i (SUB_LIST (0x10 * l1_curr_blocks + 0x10,val tail_len) + (aes256_xts_encrypt pt_in (0x10 * l1_curr_blocks + 0x10 + val tail_len) iv key1_lst key2_lst))` *) + UNDISCH_TAC + `forall i. i < val (tail_len:int64) + ==> read (memory :> bytes8 (word_add (word_add ctxt_p (word (l1_curr_len + 0x10))) + (word i))) s33 = + EL i (SUB_LIST (0x0,val tail_len) (int128_to_bytes CC))` THEN + REWRITE_TAC[GSYM (ASSUME `0x10 * l1_curr_blocks = l1_curr_len`)] THEN + + MP_TAC (SPECL [`val (tail_len:int64):num`; `(word_add ctxt_p (word (0x10 * l1_curr_blocks + 0x10))):int64`; + `(SUB_LIST (0x0,val (tail_len:int64)) (int128_to_bytes CC)):byte list`; + `s33:armstate`] BYTE_LIST_TO_NUM_THM) THEN + ANTS_TAC THENL[ + REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN CONV_TAC NUM_REDUCE_CONV THEN + UNDISCH_TAC `val (tail_len:int64) < 0x10` THEN + ARITH_TAC; ALL_TAC] THEN + DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN + MP_TAC (SPECL [`val (tail_len:int64):num`; `(word_add ctxt_p (word (0x10 * l1_curr_blocks + 0x10))):int64`; + `(SUB_LIST (0x10 * l1_curr_blocks + 0x10,val (tail_len:int64)) + (aes256_xts_encrypt pt_in (0x10 * l1_curr_blocks + 0x10 + val tail_len) iv key1_lst key2_lst)):byte list`; + `s33:armstate`] BYTE_LIST_TO_NUM_THM) THEN + ANTS_TAC THENL[ + REWRITE_TAC[LENGTH_SUB_LIST] THEN + IMP_REWRITE_TAC[LENGTH_OF_AES256_XTS_ENCRYPT] THEN + ARITH_TAC; ALL_TAC] THEN + DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN - SUBGOAL_THEN `curr_blocks = 0x1` SUBST1_TAC THENL - [ UNDISCH_TAC `curr_blocks - 0x1 = 0x0` THEN - ARITH_TAC THEN - ] + DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN + AP_TERM_TAC THEN + REWRITE_TAC[SUB_LIST_IDEMPOTENT] THEN + REWRITE_TAC[SUB_LIST_MIN_RIGHT; MIN; LE_REFL] THEN + + REWRITE_TAC[aes256_xts_encrypt; + ARITH_RULE `~(0x10 * l1_curr_blocks + 0x10 + val (tail_len:int64) < 0x10)`] THEN + REWRITE_TAC[ARITH_RULE `0x10 * l1_curr_blocks + 0x10 + val tail_len = + 0x10 * (l1_curr_blocks + 1) + val tail_len`] THEN + REWRITE_TAC[MOD_MULT_ADD] THEN + ASM_SIMP_TAC[MOD_LT] THEN + REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + REWRITE_TAC[ARITH_RULE + `((0x10 * (l1_curr_blocks + 0x1) + val tail_len) - val tail_len) DIV 0x10 = + (0x10 * (l1_curr_blocks + 0x1)) DIV 0x10`] THEN + IMP_REWRITE_TAC[DIV_MULT; ARITH_RULE `~(16 = 0)`] THEN + COND_CASES_TAC THENL + [ (* `l1_curr_blocks + 0x1 < 0x2` *) + SUBGOAL_THEN `l1_curr_blocks = 0` SUBST_ALL_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN + REWRITE_TAC[aes256_xts_encrypt_tail] THEN + ASM_SIMP_TAC[LET_DEF; LET_END_DEF] THEN + CONV_TAC NUM_REDUCE_CONV THEN + + MP_TAC (SPECL [`(SUB_LIST (0,0x10) pt_in):byte list`; + `(SUB_LIST (0x10,val (tail_len:int64)) pt_in):byte list`; + `val (tail_len:int64)`; `iv:int128`; `0:num`; `key1_lst:int128 list`; + `key2_lst:int128 list`] LENGTH_OF_FST_OF_CIPHER_STEALING) THEN + REWRITE_TAC[GSYM (ASSUME `0x10 * 0x0 = l1_curr_len`)] THEN + DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_APPEND_RIGHT_LEMMA; ARITH_RULE `16 <= 16`] THEN + + REWRITE_TAC[cipher_stealing_encrypt; LET_DEF; LET_END_DEF; SUB_LIST_IDEMPOTENT] THEN + EXPAND_TAC "CC" THEN + REWRITE_TAC[GSYM (ASSUME `0x10 * 0x0 = l1_curr_len`)] THEN + CONV_TAC NUM_REDUCE_CONV; ALL_TAC ] THEN + SUBGOAL_THEN `l1_curr_blocks >= 1` ASSUME_TAC THENL + [ UNDISCH_TAC `~(l1_curr_blocks + 0x1 < 0x2)` THEN ARITH_TAC; ALL_TAC] THEN + IMP_REWRITE_TAC[ADD_SUB; ARITH_RULE `((l1_curr_blocks + 0x1) - 0x2) = l1_curr_blocks - 1`] THEN + REWRITE_TAC[GSYM (ASSUME `0x10 * l1_curr_blocks = l1_curr_len`)] THEN - ] + MP_TAC (ISPECL [`(aes256_xts_encrypt_rec 0x0 (l1_curr_blocks - 0x1) pt_in iv key1_lst key2_lst):byte list`; + `(aes256_xts_encrypt_tail l1_curr_blocks (val (tail_len:int64)) pt_in iv key1_lst key2_lst):byte list`; + `0x10 * l1_curr_blocks + 0x10:num`; `val (tail_len:int64)`; `0x10 * l1_curr_blocks:num` + ] SUB_LIST_APPEND_RIGHT_GENERAL) THEN + ANTS_TAC THENL + [ REWRITE_TAC[LENGTH_OF_AES256_XTS_ENCRYPT_REC] THEN + UNDISCH_TAC `l1_curr_blocks >= 1` THEN + ARITH_TAC; ALL_TAC] THEN + ANTS_TAC THENL [ ARITH_TAC; ALL_TAC] THEN + DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN + + REWRITE_TAC[ARITH_RULE `(0x10 * l1_curr_blocks + 0x10) - 0x10 * l1_curr_blocks = 0x10`] THEN + REWRITE_TAC[aes256_xts_encrypt_tail] THEN + ASM_SIMP_TAC[LET_DEF; LET_END_DEF] THEN + MP_TAC (SPECL [`(SUB_LIST (l1_curr_blocks * 0x10,0x10) pt_in):byte list`; + `(SUB_LIST ((l1_curr_blocks + 0x1) * 0x10,val (tail_len:int64)) pt_in):byte list`; + `val (tail_len:int64)`; `iv:int128`; `l1_curr_blocks:num`; `key1_lst:int128 list`; + `key2_lst:int128 list`] LENGTH_OF_FST_OF_CIPHER_STEALING) THEN + DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_APPEND_RIGHT_LEMMA; ARITH_RULE `16 <= 16`] THEN + + REWRITE_TAC[cipher_stealing_encrypt; LET_DEF; LET_END_DEF; SUB_LIST_IDEMPOTENT] THEN + EXPAND_TAC "CC" THEN + REWRITE_TAC[GSYM (ASSUME `0x10 * l1_curr_blocks = l1_curr_len`)] THEN + REWRITE_TAC[ARITH_RULE `l1_curr_blocks * 0x10 = 0x10 * l1_curr_blocks`] + ] ] (* end of loop invariant proof. *) );; (* Proof: Less than 2 blocks *) -let AES_XTS_DECRYPT_LT_2BLOCK_CORRECT = time prove( +let AES_XTS_DECRYPT_LT_2BLOCK_CORREpt_in = time prove( `!ptxt_p ctxt_p len key1_p key2_p iv_p pt_in iv k1_0 k1_1 k1_2 k1_3 k1_4 k1_5 k1_6 k1_7 k1_8 k1_9 k1_10 k1_11 k1_12 k1_13 k1_14 From 8aa0c5011f07cf98f5dba4d0545176c8663e36bf Mon Sep 17 00:00:00 2001 From: Nevine Ebeid Date: Tue, 2 Dec 2025 16:30:03 -0500 Subject: [PATCH 102/132] Less than 2 blocks: with the late W19 setting bug, assumptions are erased in symbolic simulation and cannot match them in TWEAK_TAC. --- arm/proofs/aes-xts-armv8.ml | 359 +++++++++++++++++++----------------- 1 file changed, 194 insertions(+), 165 deletions(-) diff --git a/arm/proofs/aes-xts-armv8.ml b/arm/proofs/aes-xts-armv8.ml index bfceb9a20..fbb19c744 100644 --- a/arm/proofs/aes-xts-armv8.ml +++ b/arm/proofs/aes-xts-armv8.ml @@ -4825,8 +4825,95 @@ let CIPHER_STEALING_ENC_CORRECT = time prove( ] (* end of loop invariant proof. *) );; +let READ_LT_2BLOCK = prove( + `!(ptr:int64) (len:int64) (bl:byte list) (s:armstate). + LENGTH bl = val len ==> + val len >= 0x10 ==> + val len < 0x20 ==> + (forall i. i < val len + ==> read (memory :> bytes8 (word_add ptr (word i))) s = EL i bl) + ==> read (memory :> bytes128 ptr) s = bytes_to_int128 (SUB_LIST (0, 16) bl)`, + REPEAT STRIP_TAC THEN + MP_TAC (SPECL [`0:num`; `bl:byte list`; `ptr:int64`; + `len:int64`; `s:armstate`] BYTE_LIST_AT_1BLOCKS) THEN + REWRITE_TAC[byte_list_at] THEN + ANTS_TAC THENL[ ASM_SIMP_TAC[]; ALL_TAC] THEN + ANTS_TAC THENL[ ASM_SIMP_TAC[]; ALL_TAC] THEN + ANTS_TAC THENL[ ASM_ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[WORD_ADD_0] +);; + +let READ_LT_3BLOCK = prove( + `!(ptr:int64) (len:int64) (bl:byte list) (s:armstate). + LENGTH bl = val len ==> + ~(val len < 0x20) ==> + val len < 0x30 ==> + (forall i. i < val len + ==> read (memory :> bytes8 (word_add ptr (word i))) s = EL i bl) + ==> read (memory :> bytes128 ptr) s = bytes_to_int128 (SUB_LIST (0, 16) bl) /\ + read (memory :> bytes128 (word_add ptr (word 16))) s = + bytes_to_int128 (SUB_LIST (16, 16) bl)`, + REPEAT GEN_TAC THEN REPEAT_N 4 STRIP_TAC THEN + MP_TAC (SPECL [`0:num`; `bl:byte list`; `ptr:int64`; + `len:int64`; `s:armstate`] BYTE_LIST_AT_2BLOCKS) THEN + REWRITE_TAC[byte_list_at] THEN + ANTS_TAC THENL[ ASM_SIMP_TAC[]; ALL_TAC] THEN + ANTS_TAC THENL[ ASM_SIMP_TAC[]; ALL_TAC] THEN + ANTS_TAC THENL[ ASM_ARITH_TAC; ALL_TAC] THEN + CONV_TAC NUM_REDUCE_CONV THEN + ASM_SIMP_TAC[WORD_ADD_0] +);; + +let READ_LT_4BLOCK = prove( + `!(ptr:int64) (len:int64) (bl:byte list) (s:armstate). + LENGTH bl = val len ==> + ~(val len < 0x30) ==> + val len < 0x40 ==> + (forall i. i < val len + ==> read (memory :> bytes8 (word_add ptr (word i))) s = EL i bl) + ==> read (memory :> bytes128 ptr) s = bytes_to_int128 (SUB_LIST (0, 16) bl) /\ + read (memory :> bytes128 (word_add ptr (word 16))) s = + bytes_to_int128 (SUB_LIST (16, 16) bl) /\ + read (memory :> bytes128 (word_add ptr (word 32))) s = + bytes_to_int128 (SUB_LIST (32, 16) bl)`, + REPEAT GEN_TAC THEN REPEAT_N 4 STRIP_TAC THEN + MP_TAC (SPECL [`0:num`; `bl:byte list`; `ptr:int64`; + `len:int64`; `s:armstate`] BYTE_LIST_AT_3BLOCKS) THEN + REWRITE_TAC[byte_list_at] THEN + ANTS_TAC THENL[ ASM_SIMP_TAC[]; ALL_TAC] THEN + ANTS_TAC THENL[ ASM_SIMP_TAC[]; ALL_TAC] THEN + ANTS_TAC THENL[ ASM_ARITH_TAC; ALL_TAC] THEN + CONV_TAC NUM_REDUCE_CONV THEN + ASM_SIMP_TAC[WORD_ADD_0] +);; + +let READ_LT_5BLOCK = prove( + `!(ptr:int64) (len:int64) (bl:byte list) (s:armstate). + LENGTH bl = val len ==> + ~(val len < 0x40) ==> + val len < 0x50 ==> + (forall i. i < val len + ==> read (memory :> bytes8 (word_add ptr (word i))) s = EL i bl) + ==> read (memory :> bytes128 ptr) s = bytes_to_int128 (SUB_LIST (0, 16) bl) /\ + read (memory :> bytes128 (word_add ptr (word 16))) s = + bytes_to_int128 (SUB_LIST (16, 16) bl) /\ + read (memory :> bytes128 (word_add ptr (word 32))) s = + bytes_to_int128 (SUB_LIST (32, 16) bl) /\ + read (memory :> bytes128 (word_add ptr (word 48))) s = + bytes_to_int128 (SUB_LIST (48, 16) bl)`, + REPEAT GEN_TAC THEN REPEAT_N 4 STRIP_TAC THEN + MP_TAC (SPECL [`0:num`; `bl:byte list`; `ptr:int64`; + `len:int64`; `s:armstate`] BYTE_LIST_AT_4BLOCKS) THEN + REWRITE_TAC[byte_list_at] THEN + ANTS_TAC THENL[ ASM_SIMP_TAC[]; ALL_TAC] THEN + ANTS_TAC THENL[ ASM_SIMP_TAC[]; ALL_TAC] THEN + ANTS_TAC THENL[ ASM_ARITH_TAC; ALL_TAC] THEN + CONV_TAC NUM_REDUCE_CONV THEN + ASM_SIMP_TAC[WORD_ADD_0] +);; + (* Proof: Less than 2 blocks *) -let AES_XTS_DECRYPT_LT_2BLOCK_CORREpt_in = time prove( +let AES_XTS_DECRYPT_LT_2BLOCK_CORRECT = time prove( `!ptxt_p ctxt_p len key1_p key2_p iv_p pt_in iv k1_0 k1_1 k1_2 k1_3 k1_4 k1_5 k1_6 k1_7 k1_8 k1_9 k1_10 k1_11 k1_12 k1_13 k1_14 @@ -4857,7 +4944,7 @@ let AES_XTS_DECRYPT_LT_2BLOCK_CORREpt_in = time prove( (MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI,, MAYCHANGE [X19; X20; X21; X22],, MAYCHANGE [Q8; Q9; Q10; Q11; Q12; Q13; Q14; Q15],, - MAYCHANGE [memory :> bytes(pt_ptr, val len)]) + MAYCHANGE [memory :> bytes(ctxt_p, val len)]) `, REWRITE_TAC [(REWRITE_CONV [aes256_xts_encrypt_mc] THENC LENGTH_CONV) `LENGTH aes256_xts_encrypt_mc`] THEN REWRITE_TAC[set_key_schedule; byte_list_at; C_ARGUMENTS; SOME_FLAGS; @@ -4886,17 +4973,17 @@ let AES_XTS_DECRYPT_LT_2BLOCK_CORREpt_in = time prove( (* Prove property until start of cipher stealing. *) ENSURES_SEQUENCE_TAC `pc + 0x9e0` `\s. - read X0 s = word_add ct_ptr (word (acc_len num_5blocks_adjusted len_full_blocks_adjusted)) /\ - read X1 s = word_add pt_ptr (word (acc_len num_5blocks_adjusted len_full_blocks_adjusted)) /\ - read X3 s = key1_ptr /\ + read X0 s = word_add ptxt_p (word (acc_len num_5blocks len_full_blocks)) /\ + read X1 s = word_add ctxt_p (word (acc_len num_5blocks len_full_blocks)) /\ + read X3 s = key1_p /\ read X21 s = tail_len /\ - read Q6 s = calculate_tweak (acc_blocks num_5blocks_adjusted len_full_blocks_adjusted T) iv key2 /\ + read Q6 s = calculate_tweak (acc_blocks num_5blocks len_full_blocks T) iv key2_lst /\ read X19 s = word 0x87 /\ - read Q16 s = k00 /\ read Q17 s = k01 /\ read Q12 s = k02 /\ read Q13 s = k03 /\ - read Q14 s = k04 /\ read Q15 s = k05 /\ read Q4 s = k06 /\ read Q5 s = k07 /\ - read Q18 s = k08 /\ read Q19 s = k09 /\ read Q20 s = k0a /\ read Q21 s = k0b /\ - read Q22 s = k0c /\ read Q23 s = k0d /\ read Q7 s = k0e /\ - byte_list_at ct ct_ptr len s /\ + read Q16 s = k1_0 /\ read Q17 s = k1_1 /\ read Q12 s = k1_2 /\ read Q13 s = k1_3 /\ + read Q14 s = k1_4 /\ read Q15 s = k1_5 /\ read Q4 s = k1_6 /\ read Q5 s = k1_7 /\ + read Q18 s = k1_8 /\ read Q19 s = k1_9 /\ read Q20 s = k1_10 /\ read Q21 s = k1_11 /\ + read Q22 s = k1_12 /\ read Q23 s = k1_13 /\ read Q7 s = k1_14 /\ + byte_list_at pt_in ptxt_p len s /\ byte_list_at (aes256_xts_encrypt pt_in (acc_len num_5blocks len_full_blocks) iv key1_lst key2_lst) ctxt_p (word (acc_len num_5blocks len_full_blocks)) s` THEN CONJ_TAC THENL @@ -4905,7 +4992,7 @@ let AES_XTS_DECRYPT_LT_2BLOCK_CORREpt_in = time prove( EXISTS_TAC `MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI ,, MAYCHANGE [X19; X20; X21; X22],, MAYCHANGE [Q8; Q9; Q10; Q11; Q12; Q13; Q14; Q15],, - MAYCHANGE [memory :> bytes128 pt_ptr]` THEN + MAYCHANGE [memory :> bytes128 ctxt_p]` THEN REWRITE_TAC[MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI] THEN CONJ_TAC THENL [ REPEAT (GEN_REWRITE_TAC ONCE_DEPTH_CONV [GSYM SEQ_ASSOC] THEN @@ -4915,13 +5002,13 @@ let AES_XTS_DECRYPT_LT_2BLOCK_CORREpt_in = time prove( REWRITE_TAC[byte_list_at] THEN ENSURES_INIT_TAC "s0" THEN - ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (1--2) THEN + ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (1--2) THEN (* Discharge if condition *) SUBGOAL_THEN `ival (word_sub (len:int64) (word 0x10)) < &0x0 <=> ~(ival (len:int64) - &0x10 = ival (word_sub (len:int64) (word 0x10)))` MP_TAC THENL - [ MP_TAC (BITBLAST_RULE + [ MP_TAC (BITBLAST_RULE. (* put in tips doc. Q: When to use it vs. ARITH_RULE? *) `val (len:int64) >= 0x10 ==> val len < 0x20 ==> ival (word_sub len (word 0x10)) >= &0x0`) THEN ASM_REWRITE_TAC[] THEN @@ -4934,163 +5021,106 @@ let AES_XTS_DECRYPT_LT_2BLOCK_CORREpt_in = time prove( ASM_REWRITE_TAC[] THEN DISCH_TAC THEN POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th])) THEN - MP_TAC (SPECL [`ct_ptr:int64`; `len:int64`; `ct:byte list`; `s2:armstate`] READ_LT_2BLOCK) THEN + MP_TAC (SPECL [`ptxt_p:int64`; `len:int64`; `pt_in:byte list`; `s2:armstate`] READ_LT_2BLOCK) THEN ASM_SIMP_TAC[] THEN DISCH_TAC THEN - ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (3--69) THEN + ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (3--65) THEN (* Prove Q6 stores initial tweak *) - FIRST_X_ASSUM(MP_TAC o SPEC `(calculate_tweak 0 iv key2)` + FIRST_X_ASSUM(MP_TAC o SPEC `(calculate_tweak 0 iv key2_lst)` o MATCH_MP (MESON[] `read Q6 s = a ==> !a'. a = a' ==> read Q6 s = a'`)) THEN ANTS_TAC THENL [ REWRITE_TAC[CONJUNCT1 calculate_tweak; xts_init_tweak] THEN - EXPAND_TAC "key2" THEN AESENC_TAC; DISCH_TAC] THEN - - (* Simulating until branch for len_full_blocks adjustment *) - ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (70--89) THEN - - (* Case split on whether there is a tail *) - FIRST_X_ASSUM MP_TAC THEN - COND_CASES_TAC THENL - [ - DISCH_TAC THEN - - SUBGOAL_THEN `val (tail_len:int64) = 0` SUBST_ALL_TAC THENL - [ UNDISCH_TAC `val (word_and (tail_len:int64) (word 0xf)) = 0x0` THEN - MP_TAC (SPECL [`len:int64`; `tail_len:int64`] TAIL_LEN_BOUND_THM) THEN - ASM_SIMP_TAC[] THEN DISCH_TAC THEN - SUBGOAL_THEN `val (word_and (tail_len:int64) (word 15)) = val tail_len` SUBST1_TAC THENL - [ REWRITE_TAC[VAL_WORD_AND_MASK_WORD; ARITH_RULE `15 = 2 EXP 4 - 1`] THEN - CONV_TAC NUM_REDUCE_CONV THEN ASM_REWRITE_TAC[] THEN - IMP_REWRITE_TAC[MOD_LT]; - ALL_TAC] THEN - SIMP_TAC[]; ALL_TAC] THEN - CONV_TAC NUM_REDUCE_CONV THEN - - SUBGOAL_THEN `val (len_full_blocks_adjusted:int64) = 16` ASSUME_TAC THENL - [ EXPAND_TAC "len_full_blocks_adjusted" THEN - CONV_TAC NUM_REDUCE_CONV THEN - ASM_REWRITE_TAC[] - ; ALL_TAC ] THEN - SUBGOAL_THEN `val (num_5blocks_adjusted:int64) = 0` ASSUME_TAC THENL - [ EXPAND_TAC "num_5blocks_adjusted" THEN - UNDISCH_TAC `val (len_full_blocks_adjusted:int64) = 16` THEN - SIMP_TAC[] THEN DISCH_TAC THEN - CONV_TAC NUM_REDUCE_CONV THEN - REWRITE_TAC[VAL_WORD_0] - ; ALL_TAC ] THEN - - TWEAK_TAC `Q8:(armstate,int128)component` `1:num` `0:num` THEN - ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (90--126) THEN - XTSDEC_TAC `Q0:(armstate,int128)component` `0` `0` THEN - ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (127--136) THEN - TWEAK_TAC `Q6:(armstate,int128)component` `1:num` `0:num` THEN - - ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN - REPEAT CONJ_TAC THENL - [ - ASM_REWRITE_TAC[acc_len] THEN CONV_TAC NUM_REDUCE_CONV; - ASM_REWRITE_TAC[acc_len] THEN CONV_TAC NUM_REDUCE_CONV; - ASM_REWRITE_TAC[acc_blocks] THEN CONV_TAC NUM_REDUCE_CONV; - - ASM_REWRITE_TAC[acc_len] THEN - CONV_TAC NUM_REDUCE_CONV THEN - IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN - CONV_TAC NUM_REDUCE_CONV THEN - MP_TAC (SPECL [`16:num`; `pt_ptr:int64`; `(aes256_xts_decrypt ct 16 iv key1 key2):byte list`; `s136:armstate`] BYTE_LIST_TO_NUM_THM) THEN - ANTS_TAC THENL[ - MP_TAC (SPECL [`1`; `ct:byte list`; `iv:int128`; - `key1:int128 list`; `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN - ARITH_TAC; ALL_TAC] THEN - DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN - ASM_REWRITE_TAC[] THEN - IMP_REWRITE_TAC[READ_BYTES_EQ_READ_BYTE128_1BLOCK] - ] - ; ALL_TAC] THEN + EXPAND_TAC "key2_lst" THEN AESENC_TAC; DISCH_TAC] THEN - (* There is a tail *) - DISCH_TAC THEN - (* Prove ~ tail_len = 0 *) - SUBGOAL_THEN `~(val (tail_len:int64) = 0)` ASSUME_TAC THENL - [ UNDISCH_TAC `~(val (word_and (tail_len:int64) (word 0xf)) = 0x0)` THEN - MP_TAC (SPECL [`len:int64`; `tail_len:int64`] TAIL_LEN_BOUND_THM) THEN - ASM_REWRITE_TAC[] THEN - SUBST1_TAC(ARITH_RULE `0xf = 2 EXP 4 - 1`) THEN - REWRITE_TAC[VAL_WORD_AND_MASK_WORD] THEN - NUM_REDUCE_TAC THEN IMP_REWRITE_TAC[MOD_LT] - ; ALL_TAC] THEN - (* Prove len_full_blocks_adjusted = word_sub len_full_blocks (word 0x10) *) - SUBGOAL_THEN `word_sub len_full_blocks (word 0x10) = len_full_blocks_adjusted:int64` ASSUME_TAC THENL - [ UNDISCH_TAC `(if val (tail_len:int64) = 0x0 - then (len_full_blocks:int64) - else word_sub len_full_blocks (word 0x10)) = len_full_blocks_adjusted` THEN - ASM_REWRITE_TAC[]; ALL_TAC] THEN - SUBGOAL_THEN `val (len_full_blocks_adjusted:int64) = 0` ASSUME_TAC THENL - [ EXPAND_TAC "len_full_blocks_adjusted" THEN - UNDISCH_TAC `val (len_full_blocks:int64) = 16` THEN - WORD_ARITH_TAC - ; ALL_TAC ] THEN - SUBGOAL_THEN `val (num_5blocks_adjusted:int64) = 0` ASSUME_TAC THENL - [ EXPAND_TAC "num_5blocks_adjusted" THEN - REWRITE_TAC[ASSUME `val (len_full_blocks_adjusted:int64) = 0`] THEN - WORD_ARITH_TAC - ; ALL_TAC ] THEN + (* Simulating until branching into tail1x *) + ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (66--76) THEN + (* Simulate AES-XTS encryption of block in Q0 *) + ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (77--107) THEN + XTSENC_TAC `Q0:(armstate,int128)component` `0` `0` THEN - TWEAK_TAC `Q8:(armstate,int128)component` `1:num` `0:num` THEN - ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (90--92) THEN - (* Discharge if condition *) - SUBGOAL_THEN - `~(ival (word_sub (len_full_blocks_adjusted:int64) (word 0x10)) < &0x0 <=> - ~(ival (len_full_blocks_adjusted:int64) - &0x10 = - ival (word_sub (len_full_blocks_adjusted:int64) (word 0x10))))` MP_TAC THENL - [ SUBGOAL_THEN `len_full_blocks_adjusted:int64 = (word 0)` SUBST1_TAC THENL - [ UNDISCH_TAC `val (len_full_blocks_adjusted:int64) = 0` THEN - WORD_ARITH_TAC; ALL_TAC] THEN - WORD_ARITH_TAC - ; ALL_TAC] THEN - DISCH_TAC THEN - POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th])) THEN + ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (108--116) THEN + TWEAK_TAC `Q6:(armstate,int128)component` `1:num` `0:num` THEN (* Fails *) + FIRST_X_ASSUM(MP_TAC o SPEC `(word_zx:int128->int64) (calculate_tweak 0 iv key2_lst)` + o MATCH_MP (MESON[] `read X9 s = a ==> !a'. a = a' ==> read X9 s = a'`)) THEN (* Fails *) - ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN - REPEAT CONJ_TAC THENL - [ - ASM_REWRITE_TAC[acc_len] THEN - CONV_TAC NUM_REDUCE_CONV THEN - REWRITE_TAC[WORD_ADD_0]; - ASM_REWRITE_TAC[acc_len] THEN - CONV_TAC NUM_REDUCE_CONV THEN - REWRITE_TAC[WORD_ADD_0]; - ASM_REWRITE_TAC[acc_blocks] THEN CONV_TAC NUM_REDUCE_CONV; - - ASM_REWRITE_TAC[acc_len] THEN - CONV_TAC NUM_REDUCE_CONV THEN - IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN - CONV_TAC NUM_REDUCE_CONV THEN - MESON_TAC[ARITH_RULE `~(i < 0)`] - ] - ; ALL_TAC] THEN - - (* Reuse the cipher stealing proof *) - MP_TAC CIPHER_STEALING_CORRECT THEN - REWRITE_TAC [(REWRITE_CONV [aes_xts_decrypt_mc] THENC LENGTH_CONV) `LENGTH aes_xts_decrypt_mc`] THEN - REWRITE_TAC[set_key_schedule; C_ARGUMENTS; SOME_FLAGS; - NONOVERLAPPING_CLAUSES; byte_list_at; - MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI] THEN - DISCH_THEN MATCH_MP_TAC THEN - EXISTS_TAC `(word 16):int64` THEN - ASM_SIMP_TAC[] THEN - SUBGOAL_THEN `len_full_blocks:int64 = word 0x10` ASSUME_TAC THENL - [ UNDISCH_TAC `val (len_full_blocks:int64) = 16` THEN - WORD_ARITH_TAC; ALL_TAC] THEN - REPEAT CONJ_TAC THENL [ - ASM_ARITH_TAC; - EXPAND_TAC "len" THEN AP_TERM_TAC THEN - UNDISCH_TAC `val (len_full_blocks:int64) = 16` THEN - WORD_ARITH_TAC; - ASM_SIMP_TAC[]; - EXPAND_TAC "len_full_blocks_adjusted" THEN - REWRITE_TAC[ASSUME `len_full_blocks:int64 = word 16`] - ] -);; +(* +With the misplaced `mov w19, #0x87` bug (being after `b.lo .Lxts_enc_tail1x` rather than before it), +fixed in https://github.com/aws/aws-lc/commit/3f282aa6fd16f6afce9e7d0d10ed5d9fdb713efa +trying to calculate the tweak for the tail in tail1x assumptions are erased starting from state s113 +which contains read X19 s112, because the contents of X19 are not know, +hence read X19 s112 is not in the assumptions. The following is the output of the symbolic simulation: + +1 subgoal (2 total) # e(ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (108--116));; +Stepping to state s108 +Instruction at `pc + 2484 (0x9b4)`: `arm_STR Q0 X1 (Postimmediate_Offset (word 0x10))` +Info: assumption `read (memory :> bytes128 iv_p) s107 = iv` is erased. +- Reason: NONOVERLAPPING_RULE: could not prove one of: + * `nonoverlapping (iv_p,0x10) (ctxt_p,0x10)` +CPU time (user): 0.472655 +Info: assumption `read events s108 = CONS (EventStore (ctxt_p,0x10)) (read events s107)` is erased, but it might have contained useful information +Stepping to state s109 +Instruction at `pc + 2488 (0x9b8)`: `arm_FMOV_FtoI X9 Q6 0x0 0x40` +CPU time (user): 0.0751340000002 +Stepping to state s110 +Instruction at `pc + 2492 (0x9bc)`: `arm_FMOV_FtoI X10 Q6 0x1 0x40` +CPU time (user): 0.0737959999997 +Stepping to state s111 +Instruction at `pc + 2496 (0x9c0)`: `arm_EXTR X22 X10 X10 0x20` +CPU time (user): 0.0790890000003 +Stepping to state s112 +Instruction at `pc + 2500 (0x9c4)`: `arm_EXTR X10 X10 X9 0x3f` +CPU time (user): 0.0734319999997 +Stepping to state s113 +Instruction at `pc + 2504 (0x9c8)`: `arm_AND W11 W19 (Shiftedreg W22 ASR 0x1f)` +CPU time (user): 0.078387 +Info: assumption `read X11 s113 = +word_zx +(word_and (word_zx (read X19 s112)) +(word_ishr + (word_zx + (word_subword + (word_join (word_subword (calculate_tweak 0x0 iv key2_lst) (0x40,0x40)) + (word_subword (calculate_tweak 0x0 iv key2_lst) (0x40,0x40))) + (0x20,0x40))) +0x1f))` is erased, but it might have contained useful information +Stepping to state s114 +Instruction at `pc + 2508 (0x9cc)`: `arm_EOR X9 X11 (Shiftedreg X9 LSL 0x1)` +CPU time (user): 0.0678280000006 +Info: assumption `read X9 s114 = +word_xor (read X11 s113) +(word_shl (word_subword (calculate_tweak 0x0 iv key2_lst) (0x0,0x40)) 0x1)` is erased, but it might have contained useful information +Stepping to state s115 +Instruction at `pc + 2512 (0x9d0)`: `arm_FMOV_ItoF Q6 X9 0x0` +CPU time (user): 0.0701379999996 +Info: assumption `read Q6 s115 = word_zx (read X9 s114)` is erased, but it might have contained useful information +Stepping to state s116 +Instruction at `pc + 2516 (0x9d4)`: `arm_FMOV_ItoF Q6 X10 0x1` +CPU time (user): 0.0717420000005 +Info: assumption `read Q6 s116 = +word_insert (read Q6 s115) (0x40,0x40) +(word_subword + (word_join (word_subword (calculate_tweak 0x0 iv key2_lst) (0x40,0x40)) + (word_subword (calculate_tweak 0x0 iv key2_lst) (0x0,0x40))) +(0x3f,0x40))` is erased, but it might have contained useful information +*) +(* +The following tactics fail: + +1 subgoal (2 total) # e(TWEAK_TAC `Q6:(armstate,int128)component` `1:num` `0:num`);; +0..0..solved at 2 +0..0..solved at 2 +0..0..solved at 2 + +Exception: Failure "tryfind". +1 subgoal (2 total) # e(FIRST_X_ASSUM(MP_TAC o SPEC `(word_zx:int128->int64) (calculate_tweak 1 iv key2_lst)` + o MATCH_MP (MESON[] `read X9 s = a ==> !a'. a = a' ==> read X9 s = a'`)));; +0..0..solved at 2 + +Exception: Failure "tryfind". +1 subgoal (2 total) # e(FIRST_X_ASSUM(MP_TAC o SPEC `(word_zx:int128->int64) (calculate_tweak 0 iv key2_lst)` + o MATCH_MP (MESON[] `read X9 s = a ==> !a'. a = a' ==> read X9 s = a'`)));; +0..0..solved at 2 +*) (* void aes_hw_xts_encrypt(const uint8_t *in, uint8_t *out, size_t length, @@ -5281,7 +5311,7 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( [ UNDISCH_TAC `~(val (len_full_blocks:int64) < 0x50)` THEN ARITH_TAC; DISCH_THEN(RULE_ASSUM_TAC o REWRITE_RULE o CONJUNCTS)] THEN (* prove Q9 stores tweak of 3rd block (index 2) *) - ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (88--93) THEN + ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (88--93) THEN (* TODO: How is the last parameter in TWEAK_TAC `0` in the upcoming ones? *) TWEAK_TAC `Q9:(armstate,int128)component` `2:num` `0:num` THEN (* Eliminate 3 blocks case *) ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (94--95) THEN @@ -5338,8 +5368,7 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( ctxt_p (word (acc_len num_5blocks len_full_blocks)) s` THEN CONJ_TAC THENL [ - - (* Main Loop invariant *) + (* Loop invariant of main loop *) ENSURES_WHILE_PAUP_TAC `0` (* counter begin number *) `val (num_5blocks:int64)` (* counter end number *) From 047b301f4abd90552d58d601d0e13c30fff0c299 Mon Sep 17 00:00:00 2001 From: Nevine Ebeid Date: Tue, 2 Dec 2025 17:06:27 -0500 Subject: [PATCH 103/132] Less than 2 blocks: with the fix setting W19 before branching, no assumptions are erased in symbolic simulation and TWEAK_TAC succeeds. --- arm/aes-xts/aes-xts-armv8.S | 2 +- arm/aes-xts/aes-xts-armv8.txt | 4 +- arm/proofs/aes-xts-armv8.ml | 106 +++++++++++++--------------------- 3 files changed, 42 insertions(+), 70 deletions(-) diff --git a/arm/aes-xts/aes-xts-armv8.S b/arm/aes-xts/aes-xts-armv8.S index d53d44b09..9a87b2de3 100644 --- a/arm/aes-xts/aes-xts-armv8.S +++ b/arm/aes-xts/aes-xts-armv8.S @@ -104,6 +104,7 @@ S2N_BN_SYMBOL(aes_hw_xts_encrypt): // Encryption .Lxts_enc: + mov w19, #0x87 cmp x2, #0x20 b.lo .Lxts_enc_tail1x // when input = 1 with tail @@ -112,7 +113,6 @@ S2N_BN_SYMBOL(aes_hw_xts_encrypt): // the five ivs stored into, v6.16b,v8.16b,v9.16b,v10.16b,v11.16b fmov x9, d6 fmov x10, v6.d[1] - mov w19, #0x87 tweak(d8, v8.d[1]) cmp x2, #0x30 diff --git a/arm/aes-xts/aes-xts-armv8.txt b/arm/aes-xts/aes-xts-armv8.txt index 3c82bd3d7..f1c626320 100644 --- a/arm/aes-xts/aes-xts-armv8.txt +++ b/arm/aes-xts/aes-xts-armv8.txt @@ -40,11 +40,11 @@ 0x4cdfa8f4; (* arm_LDP Q20 Q21 X7 (Postimmediate_Offset (word 0x20)) *) 0x4cdfa8f6; (* arm_LDP Q22 Q23 X7 (Postimmediate_Offset (word 0x20)) *) 0x4c4078e7; (* arm_LDR Q7 X7 No_Offset *) + 0x528010f3; (* arm_MOV W19 (rvalue (word 0x87)) *) 0xf100805f; (* arm_CMP X2 (rvalue (word 0x20)) *) - 0x54004483; (* arm_BCC (word 0x890) *) + 0x54004463; (* arm_BCC (word 0x88c) *) 0x9e6600c9; (* arm_FMOV_FtoI X9 Q6 0x0 0x40 *) 0x9eae00ca; (* arm_FMOV_FtoI X10 Q6 0x1 0x40 *) - 0x528010f3; (* arm_MOV W19 (rvalue (word 0x87)) *) 0x93ca8156; (* arm_ROR X22 X10 0x20 *) 0x93c9fd4a; (* arm_EXTR X10 X10 X9 0x3f *) 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 0x1f) *) diff --git a/arm/proofs/aes-xts-armv8.ml b/arm/proofs/aes-xts-armv8.ml index fbb19c744..df1a6758a 100644 --- a/arm/proofs/aes-xts-armv8.ml +++ b/arm/proofs/aes-xts-armv8.ml @@ -80,11 +80,11 @@ let aes256_xts_encrypt_mc = define_assert_from_elf "aes256_xts_encrypt_mc" "arm/ (* Lxts_enc: *) (* pc + 0xa4 *) + 0x528010f3; (* arm_MOV W19 (rvalue (word 0x87)) *) 0xf100805f; (* arm_CMP X2 (rvalue (word 0x20)) *) - 0x54004483; (* arm_BCC (word 0x890) *) + 0x54004463; (* arm_BCC (word 0x88c) *) 0x9e6600c9; (* arm_FMOV_FtoI X9 Q6 0x0 0x40 *) 0x9eae00ca; (* arm_FMOV_FtoI X10 Q6 0x1 0x40 *) - 0x528010f3; (* arm_MOV W19 (rvalue (word 0x87)) *) 0x93ca8156; (* arm_ROR X22 X10 0x20 *) 0x93c9fd4a; (* arm_EXTR X10 X10 X9 0x3f *) 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 0x1f) *) @@ -5008,7 +5008,7 @@ let AES_XTS_DECRYPT_LT_2BLOCK_CORRECT = time prove( SUBGOAL_THEN `ival (word_sub (len:int64) (word 0x10)) < &0x0 <=> ~(ival (len:int64) - &0x10 = ival (word_sub (len:int64) (word 0x10)))` MP_TAC THENL - [ MP_TAC (BITBLAST_RULE. (* put in tips doc. Q: When to use it vs. ARITH_RULE? *) + [ MP_TAC (BITBLAST_RULE (* put in tips doc. Q: When to use it vs. ARITH_RULE? *) `val (len:int64) >= 0x10 ==> val len < 0x20 ==> ival (word_sub len (word 0x10)) >= &0x0`) THEN ASM_REWRITE_TAC[] THEN @@ -5033,93 +5033,65 @@ let AES_XTS_DECRYPT_LT_2BLOCK_CORRECT = time prove( EXPAND_TAC "key2_lst" THEN AESENC_TAC; DISCH_TAC] THEN (* Simulating until branching into tail1x *) - ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (66--76) THEN + ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (66--77) THEN (* Simulate AES-XTS encryption of block in Q0 *) - ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (77--107) THEN + ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (78--108) THEN XTSENC_TAC `Q0:(armstate,int128)component` `0` `0` THEN - ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (108--116) THEN - TWEAK_TAC `Q6:(armstate,int128)component` `1:num` `0:num` THEN (* Fails *) - FIRST_X_ASSUM(MP_TAC o SPEC `(word_zx:int128->int64) (calculate_tweak 0 iv key2_lst)` - o MATCH_MP (MESON[] `read X9 s = a ==> !a'. a = a' ==> read X9 s = a'`)) THEN (* Fails *) + ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (109--117) THEN + TWEAK_TAC `Q6:(armstate,int128)component` `1:num` `0:num` THEN (* -With the misplaced `mov w19, #0x87` bug (being after `b.lo .Lxts_enc_tail1x` rather than before it), -fixed in https://github.com/aws/aws-lc/commit/3f282aa6fd16f6afce9e7d0d10ed5d9fdb713efa -trying to calculate the tweak for the tail in tail1x assumptions are erased starting from state s113 -which contains read X19 s112, because the contents of X19 are not know, -hence read X19 s112 is not in the assumptions. The following is the output of the symbolic simulation: - -1 subgoal (2 total) # e(ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (108--116));; -Stepping to state s108 +# With `mov w19, #0x87` before `b.lo .Lxts_enc_tail1x` rather than after it, +# fixed in https://github.com/aws/aws-lc/commit/3f282aa6fd16f6afce9e7d0d10ed5d9fdb713efa +# The assumptions contain: + 21 [`read X19 s108 = word 0x87`] + +# The following is the output of the symbolic simulation: + +1 subgoal (2 total) # e(ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (109--117));; +Stepping to state s109 Instruction at `pc + 2484 (0x9b4)`: `arm_STR Q0 X1 (Postimmediate_Offset (word 0x10))` -Info: assumption `read (memory :> bytes128 iv_p) s107 = iv` is erased. +Info: assumption `read (memory :> bytes128 iv_p) s108 = iv` is erased. - Reason: NONOVERLAPPING_RULE: could not prove one of: * `nonoverlapping (iv_p,0x10) (ctxt_p,0x10)` -CPU time (user): 0.472655 -Info: assumption `read events s108 = CONS (EventStore (ctxt_p,0x10)) (read events s107)` is erased, but it might have contained useful information -Stepping to state s109 -Instruction at `pc + 2488 (0x9b8)`: `arm_FMOV_FtoI X9 Q6 0x0 0x40` -CPU time (user): 0.0751340000002 +CPU time (user): 0.471508000001 +Info: assumption `read events s109 = CONS (EventStore (ctxt_p,0x10)) (read events s108)` is erased, but it might have contained useful information Stepping to state s110 -Instruction at `pc + 2492 (0x9bc)`: `arm_FMOV_FtoI X10 Q6 0x1 0x40` -CPU time (user): 0.0737959999997 +Instruction at `pc + 2488 (0x9b8)`: `arm_FMOV_FtoI X9 Q6 0x0 0x40` +CPU time (user): 0.0778439999999 Stepping to state s111 -Instruction at `pc + 2496 (0x9c0)`: `arm_EXTR X22 X10 X10 0x20` -CPU time (user): 0.0790890000003 +Instruction at `pc + 2492 (0x9bc)`: `arm_FMOV_FtoI X10 Q6 0x1 0x40` +CPU time (user): 0.0805559999999 Stepping to state s112 -Instruction at `pc + 2500 (0x9c4)`: `arm_EXTR X10 X10 X9 0x3f` -CPU time (user): 0.0734319999997 +Instruction at `pc + 2496 (0x9c0)`: `arm_EXTR X22 X10 X10 0x20` +CPU time (user): 0.0796230000001 Stepping to state s113 -Instruction at `pc + 2504 (0x9c8)`: `arm_AND W11 W19 (Shiftedreg W22 ASR 0x1f)` -CPU time (user): 0.078387 -Info: assumption `read X11 s113 = -word_zx -(word_and (word_zx (read X19 s112)) -(word_ishr - (word_zx - (word_subword - (word_join (word_subword (calculate_tweak 0x0 iv key2_lst) (0x40,0x40)) - (word_subword (calculate_tweak 0x0 iv key2_lst) (0x40,0x40))) - (0x20,0x40))) -0x1f))` is erased, but it might have contained useful information +Instruction at `pc + 2500 (0x9c4)`: `arm_EXTR X10 X10 X9 0x3f` +CPU time (user): 0.0763620000002 Stepping to state s114 -Instruction at `pc + 2508 (0x9cc)`: `arm_EOR X9 X11 (Shiftedreg X9 LSL 0x1)` -CPU time (user): 0.0678280000006 -Info: assumption `read X9 s114 = -word_xor (read X11 s113) -(word_shl (word_subword (calculate_tweak 0x0 iv key2_lst) (0x0,0x40)) 0x1)` is erased, but it might have contained useful information +Instruction at `pc + 2504 (0x9c8)`: `arm_AND W11 W19 (Shiftedreg W22 ASR 0x1f)` +CPU time (user): 0.0847099999996 Stepping to state s115 -Instruction at `pc + 2512 (0x9d0)`: `arm_FMOV_ItoF Q6 X9 0x0` -CPU time (user): 0.0701379999996 -Info: assumption `read Q6 s115 = word_zx (read X9 s114)` is erased, but it might have contained useful information +Instruction at `pc + 2508 (0x9cc)`: `arm_EOR X9 X11 (Shiftedreg X9 LSL 0x1)` +CPU time (user): 0.0757570000001 Stepping to state s116 +Instruction at `pc + 2512 (0x9d0)`: `arm_FMOV_ItoF Q6 X9 0x0` +CPU time (user): 0.0816250000003 +Stepping to state s117 Instruction at `pc + 2516 (0x9d4)`: `arm_FMOV_ItoF Q6 X10 0x1` -CPU time (user): 0.0717420000005 -Info: assumption `read Q6 s116 = -word_insert (read Q6 s115) (0x40,0x40) -(word_subword - (word_join (word_subword (calculate_tweak 0x0 iv key2_lst) (0x40,0x40)) - (word_subword (calculate_tweak 0x0 iv key2_lst) (0x0,0x40))) -(0x3f,0x40))` is erased, but it might have contained useful information -*) -(* -The following tactics fail: +CPU time (user): 0.082042 +# The following tactic succeeds: 1 subgoal (2 total) # e(TWEAK_TAC `Q6:(armstate,int128)component` `1:num` `0:num`);; 0..0..solved at 2 0..0..solved at 2 0..0..solved at 2 -Exception: Failure "tryfind". -1 subgoal (2 total) # e(FIRST_X_ASSUM(MP_TAC o SPEC `(word_zx:int128->int64) (calculate_tweak 1 iv key2_lst)` - o MATCH_MP (MESON[] `read X9 s = a ==> !a'. a = a' ==> read X9 s = a'`)));; -0..0..solved at 2 +val it : goalstack = 1 subgoal (2 total) -Exception: Failure "tryfind". -1 subgoal (2 total) # e(FIRST_X_ASSUM(MP_TAC o SPEC `(word_zx:int128->int64) (calculate_tweak 0 iv key2_lst)` - o MATCH_MP (MESON[] `read X9 s = a ==> !a'. a = a' ==> read X9 s = a'`)));; -0..0..solved at 2 +# and adds the following assumption: + 93 [`read Q6 s117 = calculate_tweak 0x1 iv key2_lst`] *) (* From f714f88ecaaad86a9d10d2626d97404ba2f743c6 Mon Sep 17 00:00:00 2001 From: Nevine Ebeid Date: Wed, 3 Dec 2025 12:21:00 -0500 Subject: [PATCH 104/132] Less than 2 blocks: proof done. --- arm/proofs/aes-xts-armv8.ml | 347 ++++++++---------------------------- 1 file changed, 73 insertions(+), 274 deletions(-) diff --git a/arm/proofs/aes-xts-armv8.ml b/arm/proofs/aes-xts-armv8.ml index df1a6758a..5d08e628a 100644 --- a/arm/proofs/aes-xts-armv8.ml +++ b/arm/proofs/aes-xts-armv8.ml @@ -3170,222 +3170,6 @@ let acc_blocks = new_definition else if last then val i * 0x5 else val i * 0x5 + 4`;; -(* The cipher-stealing invariant is the block read at ctxt_p + curr_len - 16 where Cm is being replaced by Pm - one byte at a time with a decreasing offset i from the beginning of the block. - Differs from decrypt in that, there, it's curr_len *) -(* -let cipher_stealing_enc_inv = new_definition -`cipher_stealing_enc_inv (i:num) (curr_len:num) (tail_len:num) (CC:int128) (pt:byte list): int128 = - bytes_to_int128( - APPEND (SUB_LIST (0, i) (int128_to_bytes CC)) - (APPEND (SUB_LIST (i, tail_len - i) (SUB_LIST (curr_len, tail_len) pt)) - (SUB_LIST (tail_len, 16 - tail_len) (int128_to_bytes CC))))`;; - -(* In the cipher-stealing loop invariant, all bytes remain the same between iterations - except the current byte i, which is from the corresponding location i in the tail of pt *) -let CIPHER_STEALING_ENC_BYTE_EQUAL = prove( - `!(i:num) (curr_len:num) (tail_len:int64) (CC:int128) (pt:byte list). - i < val tail_len /\ val tail_len < 16 ==> - curr_len + val tail_len = LENGTH pt ==> - let InvCC = cipher_stealing_enc_inv (i + 1) curr_len (val tail_len) CC pt - and InvCC' = cipher_stealing_enc_inv i curr_len (val tail_len) CC pt in - (!j. 0 <= j /\ j < 16 /\ ~(j = i) ==> EL j (int128_to_bytes InvCC) = EL j (int128_to_bytes InvCC')) /\ - EL i (int128_to_bytes InvCC') = word_zx (EL (curr_len + i) pt)`, - REPEAT STRIP_TAC THEN - REWRITE_TAC[LET_DEF; LET_END_DEF] THEN - CONJ_TAC THENL - [ - REPEAT STRIP_TAC THEN - REWRITE_TAC[cipher_stealing_enc_inv] THEN - IMP_REWRITE_TAC[INT128_TO_BYTES_OF_BYTES_TO_INT128] THEN - REPEAT CONJ_TAC THENL - [ - (* Three cases: 0 <= j < i, i < j < val tail_len, val tail_len <= j < 16 *) - ASM_CASES_TAC `j < i` THENL - [ - SUBGOAL_THEN `j < LENGTH (SUB_LIST (0x0,i + 0x1) (int128_to_bytes CC))` ASSUME_TAC THENL - [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN - ASM_ARITH_TAC; ALL_TAC] THEN - SUBGOAL_THEN `j < LENGTH (SUB_LIST (0x0,i) (int128_to_bytes CC))` ASSUME_TAC THENL - [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN - ASM_ARITH_TAC ; ALL_TAC] THEN - REWRITE_TAC[EL_APPEND] THEN - ASM_SIMP_TAC[] THEN - MP_TAC (ISPECL [`j:num`; `i:num`; `(int128_to_bytes CC):byte list`] EL_SUB_LIST) THEN - ANTS_TAC THENL - [ REWRITE_TAC[LENGTH_OF_INT128_TO_BYTES] THEN - ASM_ARITH_TAC; ALL_TAC ] THEN - MP_TAC (ISPECL [`j:num`; `(i + 1):num`; `(int128_to_bytes CC):byte list`] EL_SUB_LIST) THEN - ANTS_TAC THENL - [ REWRITE_TAC[LENGTH_OF_INT128_TO_BYTES] THEN - ASM_ARITH_TAC; ALL_TAC ] THEN - SIMP_TAC[]; ALL_TAC - ] THEN - ASM_CASES_TAC `j < val (tail_len:int64)` THENL - [ - SUBGOAL_THEN `j > i` ASSUME_TAC THENL[ASM_ARITH_TAC; ALL_TAC] THEN - REWRITE_TAC[EL_APPEND] THEN - SUBGOAL_THEN `LENGTH (SUB_LIST (0x0,i + 0x1) (int128_to_bytes CC)) = i + 1` SUBST1_TAC THENL - [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN - ASM_ARITH_TAC; ALL_TAC] THEN - SUBGOAL_THEN `LENGTH (SUB_LIST (0x0,i) (int128_to_bytes CC)) = i` SUBST1_TAC THENL - [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN - ASM_ARITH_TAC; ALL_TAC] THEN - SUBGOAL_THEN `LENGTH (SUB_LIST (i + 0x1,val (tail_len:int64) - (i + 0x1)) - (SUB_LIST (curr_len,val tail_len) (pt:byte list))) - = val tail_len - (i + 1)` SUBST1_TAC THENL - [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN - ASM_ARITH_TAC; ALL_TAC] THEN - SUBGOAL_THEN `LENGTH (SUB_LIST (i,val (tail_len:int64) - i) - (SUB_LIST (curr_len,val tail_len) (pt:byte list))) - = val tail_len - i` SUBST1_TAC THENL - [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN - ASM_ARITH_TAC; ALL_TAC] THEN - SUBGOAL_THEN `~(j < i)` ASSUME_TAC THENL - [ ASM_ARITH_TAC; ALL_TAC] THEN - SUBGOAL_THEN `~(j < i + 1)` ASSUME_TAC THENL - [ ASM_ARITH_TAC; ALL_TAC] THEN - SUBGOAL_THEN `j - i < val (tail_len:int64) - i` ASSUME_TAC THENL - [ ASM_ARITH_TAC; ALL_TAC] THEN - SUBGOAL_THEN `j - (i + 1) < val (tail_len:int64) - (i + 1)` ASSUME_TAC THENL - [ ASM_ARITH_TAC; ALL_TAC] THEN - ASM_SIMP_TAC[] THEN - MP_TAC (ISPECL [`(j - i):num`; `i:num`; - `(SUB_LIST (curr_len,val (tail_len:int64)) (pt:byte list)):byte list`; - `(val (tail_len:int64) - i):num`] EL_SUB_LIST_SHIFT) THEN - ASM_SIMP_TAC[] THEN - ANTS_TAC THENL [ REWRITE_TAC[LENGTH_SUB_LIST] THEN ASM_ARITH_TAC; ALL_TAC] THEN - IMP_REWRITE_TAC[ARITH_RULE `!i j. j > i ==> j - i - 1 = j - (i + 1)`] THEN - ASM_ARITH_TAC; ALL_TAC - ] THEN - (* j >= val tail_len *) - REWRITE_TAC[EL_APPEND] THEN - SUBGOAL_THEN `LENGTH (SUB_LIST (0x0,i + 0x1) (int128_to_bytes CC)) = i + 1` SUBST1_TAC THENL - [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN - ASM_ARITH_TAC; ALL_TAC] THEN - SUBGOAL_THEN `LENGTH (SUB_LIST (0x0,i) (int128_to_bytes CC)) = i` SUBST1_TAC THENL - [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN - ASM_ARITH_TAC; ALL_TAC] THEN - SUBGOAL_THEN `LENGTH (SUB_LIST (i + 0x1,val (tail_len:int64) - (i + 0x1)) - (SUB_LIST (curr_len,val tail_len) (pt:byte list))) - = val tail_len - (i + 1)` SUBST1_TAC THENL - [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN - ASM_ARITH_TAC; ALL_TAC] THEN - SUBGOAL_THEN `LENGTH (SUB_LIST (i,val (tail_len:int64) - i) - (SUB_LIST (curr_len,val tail_len) (pt:byte list))) - = val tail_len - i` SUBST1_TAC THENL - [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN - ASM_ARITH_TAC; ALL_TAC] THEN - SUBGOAL_THEN `~(j < i)` ASSUME_TAC THENL - [ ASM_ARITH_TAC; ALL_TAC] THEN - SUBGOAL_THEN `~(j < i + 1)` ASSUME_TAC THENL - [ ASM_ARITH_TAC; ALL_TAC] THEN - SUBGOAL_THEN `~(j - i < val (tail_len:int64) - i)` ASSUME_TAC THENL - [ ASM_ARITH_TAC; ALL_TAC] THEN - SUBGOAL_THEN `~(j - (i + 1) < val (tail_len:int64) - (i + 1))` ASSUME_TAC THENL - [ ASM_ARITH_TAC; ALL_TAC] THEN - ASM_SIMP_TAC[] THEN - AP_THM_TAC THEN AP_TERM_TAC THEN - ASM_ARITH_TAC; - - REWRITE_TAC[LENGTH_APPEND] THEN - REWRITE_TAC[LENGTH_SUB_LIST] THEN - REWRITE_TAC[LENGTH_OF_INT128_TO_BYTES] THEN - CONV_TAC NUM_REDUCE_CONV THEN - IMP_REWRITE_TAC[ARITH_RULE `i < 16 ==> MIN i 16 = i`] THEN - SUBGOAL_THEN `LENGTH (pt:byte list) - (curr_len) = val (tail_len:int64)` SUBST1_TAC THENL - [ ASM_ARITH_TAC; ALL_TAC ] THEN - REWRITE_TAC[ARITH_RULE `!x. MIN x x = x`] THEN - ASM_ARITH_TAC; - - REWRITE_TAC[LENGTH_APPEND] THEN - REWRITE_TAC[LENGTH_SUB_LIST] THEN - REWRITE_TAC[LENGTH_OF_INT128_TO_BYTES] THEN - CONV_TAC NUM_REDUCE_CONV THEN - IMP_REWRITE_TAC[ARITH_RULE `i < 16 ==> MIN (i + 1) 16 = i + 1`] THEN - SUBGOAL_THEN `LENGTH (pt:byte list) - (curr_len) = val (tail_len:int64)` SUBST1_TAC THENL - [ ASM_ARITH_TAC; ALL_TAC ] THEN - REWRITE_TAC[ARITH_RULE `!x. MIN x x = x`] THEN - ASM_ARITH_TAC - ] ; ALL_TAC - ] THEN - - REWRITE_TAC[cipher_stealing_enc_inv] THEN - IMP_REWRITE_TAC[INT128_TO_BYTES_OF_BYTES_TO_INT128] THEN - CONJ_TAC THENL [ - REWRITE_TAC[EL_APPEND] THEN - SUBGOAL_THEN `LENGTH (SUB_LIST (0x0,i) (int128_to_bytes CC)) = i` SUBST1_TAC THENL - [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN - ASM_ARITH_TAC; ALL_TAC] THEN - SUBGOAL_THEN `LENGTH (SUB_LIST (i,val (tail_len:int64) - i) - (SUB_LIST (curr_len,val tail_len) (pt:byte list))) - = val tail_len - i` SUBST1_TAC THENL - [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN - ASM_ARITH_TAC; ALL_TAC] THEN - SIMP_TAC[ARITH_RULE `~(i < i)`; SUB_REFL] THEN - SUBGOAL_THEN `0 < val (tail_len:int64) - i` ASSUME_TAC THENL - [ ASM_ARITH_TAC; ALL_TAC] THEN - ASM_SIMP_TAC[] THEN - MP_TAC (ISPECL [`curr_len:num`; `i:num`; `pt:byte list`; - `val (tail_len:int64) - i:num`; `val (tail_len:int64)`] SUB_LIST_MIN_GENERAL) THEN - REWRITE_TAC[ARITH_RULE `!a. MIN a a = a`; GSYM ADD_ASSOC] THEN - DISCH_THEN (fun th -> (REWRITE_TAC [th])) THEN - REWRITE_TAC[WORD_ZX_TRIVIAL; EL] THEN - MATCH_MP_TAC HD_SUB_LIST_CONS_GENERAL THEN - ASM_ARITH_TAC; ALL_TAC] THEN - REWRITE_TAC[LENGTH_APPEND] THEN - REWRITE_TAC[LENGTH_SUB_LIST] THEN - REWRITE_TAC[LENGTH_OF_INT128_TO_BYTES] THEN - CONV_TAC NUM_REDUCE_CONV THEN - ASM_ARITH_TAC -);; - -let CIPHER_STEALING_ENC_INV_SELECT = prove( - `!(i:num) (curr_len:num) (tail_len:int64) (CC:int128) (pt:byte list). - i < val tail_len ==> val tail_len < 16 ==> - curr_len + 16 + (val tail_len) = LENGTH pt ==> - EL i (int128_to_bytes (cipher_stealing_enc_inv (i + 1) curr_len (val tail_len) CC pt)) = - EL i (int128_to_bytes CC)`, - REPEAT STRIP_TAC THEN - REWRITE_TAC[cipher_stealing_enc_inv] THEN - IMP_REWRITE_TAC[INT128_TO_BYTES_OF_BYTES_TO_INT128] THEN - CONJ_TAC THENL [ - SUBGOAL_THEN `LENGTH (SUB_LIST (0x0,i + 1) (int128_to_bytes CC)) <= i + 1` ASSUME_TAC THENL - [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN - ARITH_TAC; ALL_TAC] THEN - REWRITE_TAC[EL_APPEND] THEN - SUBGOAL_THEN `i < LENGTH (SUB_LIST (0x0,i + 0x1) (int128_to_bytes CC))` ASSUME_TAC THENL - [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN - ASM_ARITH_TAC; ALL_TAC] THEN - ASM_SIMP_TAC[] THEN - MATCH_MP_TAC EL_SUB_LIST THEN - REWRITE_TAC[LENGTH_OF_INT128_TO_BYTES] THEN - ASM_ARITH_TAC; ALL_TAC - ] THEN - - REWRITE_TAC[LENGTH_APPEND] THEN - REWRITE_TAC[LENGTH_SUB_LIST] THEN - REWRITE_TAC[LENGTH_OF_INT128_TO_BYTES] THEN - CONV_TAC NUM_REDUCE_CONV THEN - IMP_REWRITE_TAC[ARITH_RULE `i < 16 ==> MIN (i + 1) 16 = i + 1`] THEN - SUBGOAL_THEN `LENGTH (pt:byte list) - (curr_len + 16) = val (tail_len:int64)` SUBST1_TAC THENL - [ ASM_ARITH_TAC; ALL_TAC ] THEN - REWRITE_TAC[ARITH_RULE `!x. MIN x x = x`] THEN - ASM_ARITH_TAC -);; - -let CIPHER_STEALING_ENC_INV_SIMP_TAC i = - ( FIRST_ASSUM (fun th -> MATCH_MP_TAC(SPEC i th)) THEN CONV_TAC NUM_REDUCE_CONV) ORELSE - ( ASM_REWRITE_TAC[] THEN - REWRITE_TAC[WORD_RULE `!a b. word_add ((word a):int64) (word b) = word (a + b)`] THEN - REWRITE_TAC[GSYM ADD_ASSOC] THEN - CONV_TAC NUM_REDUCE_CONV THEN - IMP_REWRITE_TAC[WORD_ZX_ZX; WORD_ZX_TRIVIAL] THEN - REWRITE_TAC[DIMINDEX_8; DIMINDEX_32; DIMINDEX_64] THEN - IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN - ASM_ARITH_TAC);; -*) - (* The cipher-stealing invariant is the block read at ctxt_p + curr_len - 16 where Cm is being replaced by Pm one byte at a time with a decreasing offset i from the beginning of the block. Differs from decrypt in that, there, it's curr_len. @@ -3843,7 +3627,7 @@ let CIPHER_STEALING_ENC_CORRECT = time prove( read PC s = word (pc + 0x9e0) /\ read X0 s = word_add ptxt_p (word (acc_len num_5blocks len_full_blocks)) /\ read X1 s = word_add ctxt_p (word (acc_len num_5blocks len_full_blocks)) /\ - // read X3 s = key1_p /\ + read X3 s = key1_p /\ read X21 s = tail_len /\ read Q6 s = calculate_tweak (acc_blocks num_5blocks len_full_blocks true) iv key2_lst /\ read X19 s = word 0x87 /\ @@ -4912,8 +4696,30 @@ let READ_LT_5BLOCK = prove( ASM_SIMP_TAC[WORD_ADD_0] );; +let READ_BYTES_EQ_READ_BYTE128_1BLOCK_ENC = prove( + `!(ptr:int64) (ct:byte list) (iv:int128) (key1:int128 list) (key2:int128 list) s. + (read (memory :> bytes128 pt_ptr) s = + aes256_xts_encrypt_round (bytes_to_int128 (SUB_LIST (0x0,0x10) ct)) + (calculate_tweak 0x0 iv key2) + key1) ==> + read (memory :> bytes (pt_ptr,0x10)) s = + num_of_bytelist (SUB_LIST (0x0,0x10) (aes256_xts_encrypt ct 0x10 iv key1 key2))`, + REPEAT STRIP_TAC THEN + REWRITE_TAC[READ_MEMORY_BYTES_BYTES128] THEN + ASM_REWRITE_TAC[] THEN + REWRITE_TAC[aes256_xts_encrypt] THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[aes256_xts_encrypt_tail] THEN + REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[SUB_LIST_OF_INT128_TO_BYTES] THEN + REWRITE_TAC[NUM_OF_BYTELIST_OF_INT128_TO_BYTES] +);; + (* Proof: Less than 2 blocks *) -let AES_XTS_DECRYPT_LT_2BLOCK_CORRECT = time prove( +let AES_XTS_ENCRYPT_LT_2BLOCK_CORRECT = time prove( `!ptxt_p ctxt_p len key1_p key2_p iv_p pt_in iv k1_0 k1_1 k1_2 k1_3 k1_4 k1_5 k1_6 k1_7 k1_8 k1_9 k1_10 k1_11 k1_12 k1_13 k1_14 @@ -4947,8 +4753,7 @@ let AES_XTS_DECRYPT_LT_2BLOCK_CORRECT = time prove( MAYCHANGE [memory :> bytes(ctxt_p, val len)]) `, REWRITE_TAC [(REWRITE_CONV [aes256_xts_encrypt_mc] THENC LENGTH_CONV) `LENGTH aes256_xts_encrypt_mc`] THEN - REWRITE_TAC[set_key_schedule; byte_list_at; C_ARGUMENTS; SOME_FLAGS; - NONOVERLAPPING_CLAUSES; PAIRWISE; ALL; + REWRITE_TAC[set_key_schedule; byte_list_at; C_ARGUMENTS; SOME_FLAGS; PAIRWISE; ALL; MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI] THEN REPEAT STRIP_TAC THEN @@ -5038,61 +4843,55 @@ let AES_XTS_DECRYPT_LT_2BLOCK_CORRECT = time prove( ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (78--108) THEN XTSENC_TAC `Q0:(armstate,int128)component` `0` `0` THEN - ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (109--117) THEN + ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (109--118) THEN (* until b .Lxts_enc_done = arm_B (word 0x8) *) TWEAK_TAC `Q6:(armstate,int128)component` `1:num` `0:num` THEN -(* -# With `mov w19, #0x87` before `b.lo .Lxts_enc_tail1x` rather than after it, -# fixed in https://github.com/aws/aws-lc/commit/3f282aa6fd16f6afce9e7d0d10ed5d9fdb713efa -# The assumptions contain: - 21 [`read X19 s108 = word 0x87`] - -# The following is the output of the symbolic simulation: - -1 subgoal (2 total) # e(ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (109--117));; -Stepping to state s109 -Instruction at `pc + 2484 (0x9b4)`: `arm_STR Q0 X1 (Postimmediate_Offset (word 0x10))` -Info: assumption `read (memory :> bytes128 iv_p) s108 = iv` is erased. -- Reason: NONOVERLAPPING_RULE: could not prove one of: - * `nonoverlapping (iv_p,0x10) (ctxt_p,0x10)` -CPU time (user): 0.471508000001 -Info: assumption `read events s109 = CONS (EventStore (ctxt_p,0x10)) (read events s108)` is erased, but it might have contained useful information -Stepping to state s110 -Instruction at `pc + 2488 (0x9b8)`: `arm_FMOV_FtoI X9 Q6 0x0 0x40` -CPU time (user): 0.0778439999999 -Stepping to state s111 -Instruction at `pc + 2492 (0x9bc)`: `arm_FMOV_FtoI X10 Q6 0x1 0x40` -CPU time (user): 0.0805559999999 -Stepping to state s112 -Instruction at `pc + 2496 (0x9c0)`: `arm_EXTR X22 X10 X10 0x20` -CPU time (user): 0.0796230000001 -Stepping to state s113 -Instruction at `pc + 2500 (0x9c4)`: `arm_EXTR X10 X10 X9 0x3f` -CPU time (user): 0.0763620000002 -Stepping to state s114 -Instruction at `pc + 2504 (0x9c8)`: `arm_AND W11 W19 (Shiftedreg W22 ASR 0x1f)` -CPU time (user): 0.0847099999996 -Stepping to state s115 -Instruction at `pc + 2508 (0x9cc)`: `arm_EOR X9 X11 (Shiftedreg X9 LSL 0x1)` -CPU time (user): 0.0757570000001 -Stepping to state s116 -Instruction at `pc + 2512 (0x9d0)`: `arm_FMOV_ItoF Q6 X9 0x0` -CPU time (user): 0.0816250000003 -Stepping to state s117 -Instruction at `pc + 2516 (0x9d4)`: `arm_FMOV_ItoF Q6 X10 0x1` -CPU time (user): 0.082042 - -# The following tactic succeeds: -1 subgoal (2 total) # e(TWEAK_TAC `Q6:(armstate,int128)component` `1:num` `0:num`);; -0..0..solved at 2 -0..0..solved at 2 -0..0..solved at 2 - -val it : goalstack = 1 subgoal (2 total) - -# and adds the following assumption: - 93 [`read Q6 s117 = calculate_tweak 0x1 iv key2_lst`] -*) + SUBGOAL_THEN `val (num_5blocks:int64) = 0` ASSUME_TAC THENL + [ EXPAND_TAC "num_5blocks" THEN + UNDISCH_TAC `val (len_full_blocks:int64) = 0x10` THEN + SIMP_TAC[] THEN DISCH_TAC THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[VAL_WORD_0]; ALL_TAC ] THEN + + ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN + (* `word_add ptxt_p (word 0x10) = word_add ptxt_p (word (acc_len num_5blocks len_full_blocks)) /\ + word_add ctxt_p (word 0x10) = word_add ctxt_p (word (acc_len num_5blocks len_full_blocks)) /\ + calculate_tweak 0x1 iv key2_lst = calculate_tweak (acc_blocks num_5blocks len_full_blocks true) iv key2_lst /\ + (forall i. + i < val (word (acc_len num_5blocks len_full_blocks)) + ==> read (memory :> bytes8 (word_add ctxt_p (word i))) s118 = + EL i (aes256_xts_encrypt pt_in (acc_len num_5blocks len_full_blocks) iv key1_lst key2_lst))` *) + REPEAT CONJ_TAC THENL + [ + ASM_REWRITE_TAC[acc_len] THEN CONV_TAC NUM_REDUCE_CONV; + + ASM_REWRITE_TAC[acc_len] THEN CONV_TAC NUM_REDUCE_CONV; + + ASM_REWRITE_TAC[acc_blocks] THEN CONV_TAC NUM_REDUCE_CONV; + + ASM_REWRITE_TAC[acc_len] THEN + CONV_TAC NUM_REDUCE_CONV THEN + IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN + CONV_TAC NUM_REDUCE_CONV THEN + MP_TAC (SPECL [`0x10`; `ctxt_p:int64`; `(aes256_xts_encrypt pt_in 0x10 iv key1_lst key2_lst):byte list`; + `s118:armstate`] BYTE_LIST_TO_NUM_THM) THEN + ANTS_TAC THENL [ + MP_TAC (SPECL [`1`; `pt_in:byte list`; `iv:int128`; `key1_lst:int128 list`; `key2_lst:int128 list`] + LENGTH_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS) THEN + ARITH_TAC; ALL_TAC] THEN + DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN + IMP_REWRITE_TAC[READ_BYTES_EQ_READ_BYTE128_1BLOCK_ENC] + ] + ; ALL_TAC] THEN + + (* Reuse the cipher stealing proof *) + MP_TAC CIPHER_STEALING_ENC_CORRECT THEN + REWRITE_TAC [(REWRITE_CONV [aes256_xts_encrypt_mc] THENC LENGTH_CONV) `LENGTH aes256_xts_encrypt_mc`] THEN + REWRITE_TAC[byte_list_at; PAIRWISE; ALL; MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI] THEN + DISCH_THEN MATCH_MP_TAC THEN + ASM_SIMP_TAC[] THEN + ASM_ARITH_TAC +);; (* void aes_hw_xts_encrypt(const uint8_t *in, uint8_t *out, size_t length, @@ -5138,7 +4937,7 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( MAYCHANGE [memory :> bytes(ctxt_p, val len)])`, REWRITE_TAC [(REWRITE_CONV [aes256_xts_encrypt_mc] THENC LENGTH_CONV) `LENGTH aes256_xts_encrypt_mc`] THEN - REWRITE_TAC[byte_list_at; set_key_schedule; NONOVERLAPPING_CLAUSES; C_ARGUMENTS; SOME_FLAGS; PAIRWISE; ALL] THEN + REWRITE_TAC[byte_list_at; set_key_schedule; C_ARGUMENTS; SOME_FLAGS; PAIRWISE; ALL] THEN REPEAT STRIP_TAC THEN (* Break len into full blocks and tail *) From 5c17ac8a60cfdb48e91b12cf190d96f437fa9d14 Mon Sep 17 00:00:00 2001 From: Nevine Ebeid Date: Thu, 4 Dec 2025 11:29:56 -0500 Subject: [PATCH 105/132] Less than 3 blocks: proof done. --- arm/proofs/aes-xts-armv8.ml | 338 +++++++++++++++++++++++++++++++++++- 1 file changed, 335 insertions(+), 3 deletions(-) diff --git a/arm/proofs/aes-xts-armv8.ml b/arm/proofs/aes-xts-armv8.ml index 5d08e628a..cd361ab4d 100644 --- a/arm/proofs/aes-xts-armv8.ml +++ b/arm/proofs/aes-xts-armv8.ml @@ -805,7 +805,8 @@ let TWEAK_UPDATE_CONV = REWRITE_CONV [CONJUNCT2 calculate_tweak] THENC GF_128_MULT_BY_PRIMITIVE_CONV;; -(* differs from the Decrypt definition in using key2_lst instead of key2 *) +(* differs from the Decrypt definition in using key2_lst instead of key2 + TODO: it seems that value of indm1 doesn't matter to the tactic, can it be removed? *) let TWEAK_TAC reg ind indm1 = let lower_term = subst [ind,`ind:num`] `(word_zx:int128->int64) (calculate_tweak ind iv key2_lst)` in let upper_term = subst [ind,`ind:num`] `(word_subword:int128->num#num->int64) (calculate_tweak ind iv key2_lst) (64,64)` in @@ -4718,6 +4719,166 @@ let READ_BYTES_EQ_READ_BYTE128_1BLOCK_ENC = prove( REWRITE_TAC[NUM_OF_BYTELIST_OF_INT128_TO_BYTES] );; +let READ_BYTES_EQ_READ_BYTE128_2BLOCKS_ENC = prove( + `!(ptr:int64) (ct:byte list) (iv:int128) (key1:int128 list) (key2:int128 list) s. + (read (memory :> bytes128 pt_ptr) s = + aes256_xts_encrypt_round (bytes_to_int128 (SUB_LIST (0x0,0x10) ct)) + (calculate_tweak 0x0 iv key2) + key1) ==> + (read (memory :> bytes128 (word_add pt_ptr (word 0x10))) s = + aes256_xts_encrypt_round (bytes_to_int128 (SUB_LIST (0x10,0x10) ct)) + (calculate_tweak 0x1 iv key2) + key1) ==> + read (memory :> bytes (pt_ptr,0x20)) s = + num_of_bytelist (SUB_LIST (0x0,0x20) (aes256_xts_encrypt ct 0x20 iv key1 key2))`, + REPEAT STRIP_TAC THEN + IMP_REWRITE_TAC[ARITH_RULE `0x20 = 0x10 + 0x10`; READ_BYTES_AND_BYTE128_SPLIT] THEN + EXISTS_TAC `aes256_xts_encrypt ct 0x20 iv key1 key2` THEN + REPEAT CONJ_TAC THENL + [ + CONV_TAC NUM_REDUCE_CONV; + + MP_TAC (SPECL [`2:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + LENGTH_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS) THEN + ARITH_TAC; + + REWRITE_TAC[aes256_xts_encrypt] THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + CONV_TAC NUM_REDUCE_CONV THEN + MP_TAC (SPECL [`ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + LENGTH_OF_AES256_XTS_ENCRYPT_REC_TRIVIAL) THEN + IMP_REWRITE_TAC[SUB_LIST_APPEND_RIGHT_LEMMA] THEN DISCH_TAC THEN + REWRITE_TAC[aes256_xts_encrypt_tail] THEN + REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + REWRITE_TAC[SUB_LIST_OF_INT128_TO_BYTES] THEN + REWRITE_TAC[NUM_OF_BYTELIST_OF_INT128_TO_BYTES] THEN + REWRITE_TAC[BYTES_TO_INT128_OF_INT128_TO_BYTES] THEN + CONV_TAC NUM_REDUCE_CONV; + + MP_TAC (SPECL [`1:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + SUB_LIST_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS) THEN + CONV_TAC NUM_REDUCE_CONV THEN + SIMP_TAC[] THEN DISCH_TAC THEN + IMP_REWRITE_TAC[READ_BYTES_EQ_READ_BYTE128_1BLOCK_ENC] THEN + MP_TAC (SPECL [`1:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + LENGTH_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS) THEN + CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] + ] +);; + +let READ_BYTES_EQ_READ_BYTE128_3BLOCKS_ENC = prove( + `!(ptr:int64) (ct:byte list) (iv:int128) (key1:int128 list) (key2:int128 list) s. + (read (memory :> bytes128 pt_ptr) s = + aes256_xts_encrypt_round (bytes_to_int128 (SUB_LIST (0x0,0x10) ct)) + (calculate_tweak 0x0 iv key2) + key1) ==> + (read (memory :> bytes128 (word_add pt_ptr (word 0x10))) s = + aes256_xts_encrypt_round (bytes_to_int128 (SUB_LIST (0x10,0x10) ct)) + (calculate_tweak 0x1 iv key2) + key1) ==> + (read (memory :> bytes128 (word_add pt_ptr (word 0x20))) s = + aes256_xts_encrypt_round (bytes_to_int128 (SUB_LIST (0x20,0x10) ct)) + (calculate_tweak 0x2 iv key2) + key1) ==> + read (memory :> bytes (pt_ptr,0x30)) s = + num_of_bytelist (SUB_LIST (0x0,0x30) (aes256_xts_encrypt ct 0x30 iv key1 key2))`, + REPEAT STRIP_TAC THEN + IMP_REWRITE_TAC[ARITH_RULE `0x30 = 0x20 + 0x10`; READ_BYTES_AND_BYTE128_SPLIT] THEN + EXISTS_TAC `aes256_xts_encrypt ct 0x30 iv key1 key2` THEN + REPEAT CONJ_TAC THENL + [ + CONV_TAC NUM_REDUCE_CONV; + + MP_TAC (SPECL [`3:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + LENGTH_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS) THEN + ARITH_TAC; + + REWRITE_TAC[aes256_xts_encrypt] THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + CONV_TAC NUM_REDUCE_CONV THEN + MP_TAC (SPECL [`0:num`; `1:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + LENGTH_OF_AES256_XTS_ENCRYPT_REC) THEN + CONV_TAC NUM_REDUCE_CONV THEN + IMP_REWRITE_TAC[SUB_LIST_APPEND_RIGHT_LEMMA] THEN DISCH_TAC THEN + REWRITE_TAC[aes256_xts_encrypt_tail] THEN + REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + REWRITE_TAC[SUB_LIST_OF_INT128_TO_BYTES] THEN + REWRITE_TAC[NUM_OF_BYTELIST_OF_INT128_TO_BYTES] THEN + REWRITE_TAC[BYTES_TO_INT128_OF_INT128_TO_BYTES] THEN + CONV_TAC NUM_REDUCE_CONV; + ALL_TAC] THEN + + MP_TAC (SPECL [`2:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + SUB_LIST_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS) THEN + CONV_TAC NUM_REDUCE_CONV THEN + SIMP_TAC[] THEN DISCH_TAC THEN + IMP_REWRITE_TAC[READ_BYTES_EQ_READ_BYTE128_2BLOCKS_ENC] THEN + MP_TAC (SPECL [`2:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + LENGTH_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS) THEN + CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] +);; + +let READ_BYTES_EQ_READ_BYTE128_4BLOCKS_ENC = prove( + `!(ptr:int64) (ct:byte list) (iv:int128) (key1:int128 list) (key2:int128 list) s. + (read (memory :> bytes128 pt_ptr) s = + aes256_xts_encrypt_round (bytes_to_int128 (SUB_LIST (0x0,0x10) ct)) + (calculate_tweak 0x0 iv key2) + key1) ==> + (read (memory :> bytes128 (word_add pt_ptr (word 0x10))) s = + aes256_xts_encrypt_round (bytes_to_int128 (SUB_LIST (0x10,0x10) ct)) + (calculate_tweak 0x1 iv key2) + key1) ==> + (read (memory :> bytes128 (word_add pt_ptr (word 0x20))) s = + aes256_xts_encrypt_round (bytes_to_int128 (SUB_LIST (0x20,0x10) ct)) + (calculate_tweak 0x2 iv key2) + key1) ==> + (read (memory :> bytes128 (word_add pt_ptr (word 0x30))) s = + aes256_xts_encrypt_round (bytes_to_int128 (SUB_LIST (0x30,0x10) ct)) + (calculate_tweak 0x3 iv key2) + key1) ==> + read (memory :> bytes (pt_ptr,0x40)) s = + num_of_bytelist (SUB_LIST (0x0,0x40) (aes256_xts_encrypt ct 0x40 iv key1 key2))`, + REPEAT STRIP_TAC THEN + IMP_REWRITE_TAC[ARITH_RULE `0x40 = 0x30 + 0x10`; READ_BYTES_AND_BYTE128_SPLIT] THEN + EXISTS_TAC `aes256_xts_encrypt ct 0x40 iv key1 key2` THEN + REPEAT CONJ_TAC THENL + [ + CONV_TAC NUM_REDUCE_CONV; + + MP_TAC (SPECL [`4:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + LENGTH_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS) THEN + ARITH_TAC; + + REWRITE_TAC[aes256_xts_encrypt] THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + CONV_TAC NUM_REDUCE_CONV THEN + MP_TAC (SPECL [`0:num`; `2:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + LENGTH_OF_AES256_XTS_ENCRYPT_REC) THEN + CONV_TAC NUM_REDUCE_CONV THEN + IMP_REWRITE_TAC[SUB_LIST_APPEND_RIGHT_LEMMA] THEN DISCH_TAC THEN + REWRITE_TAC[aes256_xts_encrypt_tail] THEN + REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + REWRITE_TAC[SUB_LIST_OF_INT128_TO_BYTES] THEN + REWRITE_TAC[BYTES_TO_INT128_OF_INT128_TO_BYTES] THEN + CONV_TAC NUM_REDUCE_CONV; + ALL_TAC] THEN + + MP_TAC (SPECL [`3:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + SUB_LIST_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS) THEN + CONV_TAC NUM_REDUCE_CONV THEN + SIMP_TAC[] THEN DISCH_TAC THEN + IMP_REWRITE_TAC[READ_BYTES_EQ_READ_BYTE128_3BLOCKS_ENC] THEN + MP_TAC (SPECL [`3:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + LENGTH_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS) THEN + CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] +);; + (* Proof: Less than 2 blocks *) let AES_XTS_ENCRYPT_LT_2BLOCK_CORRECT = time prove( `!ptxt_p ctxt_p len key1_p key2_p iv_p @@ -4814,11 +4975,11 @@ let AES_XTS_ENCRYPT_LT_2BLOCK_CORRECT = time prove( `ival (word_sub (len:int64) (word 0x10)) < &0x0 <=> ~(ival (len:int64) - &0x10 = ival (word_sub (len:int64) (word 0x10)))` MP_TAC THENL [ MP_TAC (BITBLAST_RULE (* put in tips doc. Q: When to use it vs. ARITH_RULE? *) - `val (len:int64) >= 0x10 ==> val len < 0x20 ==> + `val (len:int64) >= 0x10 ==> val len < 0x20 ==> ival (word_sub len (word 0x10)) >= &0x0`) THEN ASM_REWRITE_TAC[] THEN MP_TAC (BITBLAST_RULE - `val (len:int64) >= 0x10 ==> val len < 0x20 ==> + `val (len:int64) >= 0x10 ==> val len < 0x20 ==> ival (len:int64) - &0x10 = ival (word_sub len (word 0x10))`) THEN ASM_REWRITE_TAC[] THEN ARITH_TAC; @@ -4893,6 +5054,177 @@ let AES_XTS_ENCRYPT_LT_2BLOCK_CORRECT = time prove( ASM_ARITH_TAC );; +(* Proof: Less than 3 blocks *) +let AES_XTS_ENCRYPT_LT_3BLOCK_CORRECT = time prove( + `!ptxt_p ctxt_p len key1_p key2_p iv_p + pt_in iv + k1_0 k1_1 k1_2 k1_3 k1_4 k1_5 k1_6 k1_7 k1_8 k1_9 k1_10 k1_11 k1_12 k1_13 k1_14 + k2_0 k2_1 k2_2 k2_3 k2_4 k2_5 k2_6 k2_7 k2_8 k2_9 k2_10 k2_11 k2_12 k2_13 k2_14 + pc. + PAIRWISE nonoverlapping + [(word pc, LENGTH aes256_xts_encrypt_mc); + (ptxt_p, val len); + (ctxt_p, val len); + (key1_p, 244); + (key2_p, 244)] /\ + ~(val len < 0x20) /\ val len < 0x30 /\ LENGTH pt_in = val len /\ + [k1_0; k1_1; k1_2; k1_3; k1_4; k1_5; k1_6; k1_7; k1_8; k1_9; k1_10; + k1_11; k1_12; k1_13; k1_14] = key1_lst /\ + [k2_0; k2_1; k2_2; k2_3; k2_4; k2_5; k2_6; k2_7; k2_8; k2_9; k2_10; + k2_11; k2_12; k2_13; k2_14] = key2_lst + ==> ensures arm + (\s. aligned_bytes_loaded s (word pc) aes256_xts_encrypt_mc /\ + read PC s = word (pc + 0x1c) /\ + C_ARGUMENTS [ptxt_p; ctxt_p; len; key1_p; key2_p; iv_p] s /\ + byte_list_at pt_in ptxt_p len s /\ + read(memory :> bytes128 iv_p) s = iv /\ + set_key_schedule s key1_p k1_0 k1_1 k1_2 k1_3 k1_4 k1_5 k1_6 k1_7 k1_8 k1_9 k1_10 k1_11 k1_12 k1_13 k1_14 /\ + set_key_schedule s key2_p k2_0 k2_1 k2_2 k2_3 k2_4 k2_5 k2_6 k2_7 k2_8 k2_9 k2_10 k2_11 k2_12 k2_13 k2_14) + (\s. read PC s = word (pc + LENGTH aes256_xts_encrypt_mc - 8*4) /\ + byte_list_at (aes256_xts_encrypt pt_in (val len) iv key1_lst key2_lst) ctxt_p len s + ) + (MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI,, + MAYCHANGE [X19; X20; X21; X22],, + MAYCHANGE [Q8; Q9; Q10; Q11; Q12; Q13; Q14; Q15],, + MAYCHANGE [memory :> bytes(ctxt_p, val len)]) + `, + REWRITE_TAC [(REWRITE_CONV [aes256_xts_encrypt_mc] THENC LENGTH_CONV) `LENGTH aes256_xts_encrypt_mc`] THEN + REWRITE_TAC[set_key_schedule; byte_list_at; C_ARGUMENTS; SOME_FLAGS; PAIRWISE; ALL; + MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI] THEN + REPEAT STRIP_TAC THEN + + SUBGOAL_THEN `word_add (word_and len (word 0xf)) + (word_and len (word 0xfffffffffffffff0)) = len:int64` ASSUME_TAC THENL + [REWRITE_TAC[word_split_lemma]; ALL_TAC] THEN + ABBREV_TAC `len_full_blocks:int64 = word_and len (word 0xfffffffffffffff0)` THEN + ABBREV_TAC `tail_len:int64 = word_and len (word 0xf)` THEN + ABBREV_TAC `num_5blocks = (word (val (len_full_blocks:int64) DIV 0x50)):int64` THEN + + SUBGOAL_THEN `val (len_full_blocks:int64) = 0x20` ASSUME_TAC THENL + [ EXPAND_TAC "len_full_blocks" THEN + REWRITE_TAC[LEN_FULL_BLOCKS_TO_VAL] THEN + IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN + CONV_TAC NUM_REDUCE_CONV THEN + SUBGOAL_THEN `val (len:int64) DIV 16 = 2` SUBST1_TAC THENL + [ MATCH_MP_TAC(MESON[LE_ANTISYM] `m <= n /\ n <= m ==> m = n`) THEN + CONJ_TAC THENL [ ASM_ARITH_TAC; ASM_ARITH_TAC]; + ALL_TAC] THEN + ARITH_TAC; ALL_TAC] THEN + + SUBGOAL_THEN `val (num_5blocks:int64) = 0` ASSUME_TAC THENL + [ EXPAND_TAC "num_5blocks" THEN + UNDISCH_TAC `val (len_full_blocks:int64) = 0x20` THEN + SIMP_TAC[] THEN DISCH_TAC THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[VAL_WORD_0]; ALL_TAC ] THEN + + ENSURES_SEQUENCE_TAC `pc + 0x9e0` + `\s. + read X0 s = word_add ptxt_p (word (acc_len num_5blocks len_full_blocks)) /\ + read X1 s = word_add ctxt_p (word (acc_len num_5blocks len_full_blocks)) /\ + read X3 s = key1_p /\ + read X21 s = tail_len /\ + read Q6 s = calculate_tweak (acc_blocks num_5blocks len_full_blocks T) iv key2_lst /\ + read X19 s = word 0x87 /\ + read Q16 s = k1_0 /\ read Q17 s = k1_1 /\ read Q12 s = k1_2 /\ read Q13 s = k1_3 /\ + read Q14 s = k1_4 /\ read Q15 s = k1_5 /\ read Q4 s = k1_6 /\ read Q5 s = k1_7 /\ + read Q18 s = k1_8 /\ read Q19 s = k1_9 /\ read Q20 s = k1_10 /\ read Q21 s = k1_11 /\ + read Q22 s = k1_12 /\ read Q23 s = k1_13 /\ read Q7 s = k1_14 /\ + byte_list_at pt_in ptxt_p len s /\ + byte_list_at (aes256_xts_encrypt pt_in (acc_len num_5blocks len_full_blocks) iv key1_lst key2_lst) + ctxt_p (word (acc_len num_5blocks len_full_blocks)) s` THEN + CONJ_TAC THENL + [ + MATCH_MP_TAC ENSURES_FRAME_SUBSUMED THEN + EXISTS_TAC `MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI ,, + MAYCHANGE [X19; X20; X21; X22],, + MAYCHANGE [Q8; Q9; Q10; Q11; Q12; Q13; Q14; Q15],, + MAYCHANGE [memory :> bytes128 ctxt_p; + memory :> bytes128 (word_add ctxt_p (word 0x10))]` THEN + REWRITE_TAC[MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI] THEN + CONJ_TAC THENL [ + REPEAT (GEN_REWRITE_TAC ONCE_DEPTH_CONV [GSYM SEQ_ASSOC] THEN + MATCH_MP_TAC SUBSUMED_SEQ THEN REWRITE_TAC[SUBSUMED_REFL]) THEN + ABBREV_TAC `vallen = val (len:int64)` THEN + SUBSUMED_MAYCHANGE_TAC; ALL_TAC] THEN + + REWRITE_TAC[byte_list_at] THEN + ENSURES_INIT_TAC "s0" THEN + ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (1--2) THEN + + (* Discharge if condition *) + SUBGOAL_THEN + `ival (word_sub (len:int64) (word 0x10)) < &0x0 + <=> ~(ival (len:int64) - &0x10 = ival (word_sub (len:int64) (word 0x10)))` MP_TAC THENL + [ MP_TAC (BITBLAST_RULE (* put in tips doc. Q: When to use it vs. ARITH_RULE? *) + `~(val (len:int64) < 0x20) ==> val len < 0x30 ==> + ival (word_sub len (word 0x10)) >= &0x0`) THEN + ASM_REWRITE_TAC[] THEN + MP_TAC (BITBLAST_RULE + `~(val (len:int64) < 0x20) ==> val len < 0x30 ==> + ival (len:int64) - &0x10 = ival (word_sub len (word 0x10))`) THEN + ASM_REWRITE_TAC[] THEN + ARITH_TAC; + ALL_TAC] THEN + ASM_REWRITE_TAC[] THEN DISCH_TAC THEN + POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th])) THEN + + MP_TAC (SPECL [`ptxt_p:int64`; `len:int64`; `pt_in:byte list`; `s2:armstate`] READ_LT_3BLOCK) THEN + ASM_SIMP_TAC[] THEN REPEAT STRIP_TAC THEN + + ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (3--65) THEN + (* Prove Q6 stores initial tweak *) + FIRST_X_ASSUM(MP_TAC o SPEC `(calculate_tweak 0 iv key2_lst)` + o MATCH_MP (MESON[] `read Q6 s = a ==> !a'. a = a' ==> read Q6 s = a'`)) THEN + ANTS_TAC THENL + [ REWRITE_TAC[CONJUNCT1 calculate_tweak; xts_init_tweak] THEN + EXPAND_TAC "key2_lst" THEN AESENC_TAC; DISCH_TAC] THEN + + (* Simulating until branching into tail2x *) + ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (66--87) THEN + TWEAK_TAC `Q8:(armstate,int128)component` `1:num` `0:num` THEN + (* Simulate AES-XTS encryption of block in Q0 *) + ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (88--148) THEN + XTSENC_TAC `Q0:(armstate,int128)component` `0` `0` THEN + XTSENC_TAC `Q1:(armstate,int128)component` `0x10` `1` THEN + (* until b .Lxts_enc_done = arm_B (word xxx) *) + ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (149--158) THEN + TWEAK_TAC `Q6:(armstate,int128)component` `2:num` `1:num` THEN + ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN + + REPEAT CONJ_TAC THENL + [ + ASM_REWRITE_TAC[acc_len] THEN CONV_TAC NUM_REDUCE_CONV; + + ASM_REWRITE_TAC[acc_len] THEN CONV_TAC NUM_REDUCE_CONV; + + ASM_REWRITE_TAC[acc_blocks] THEN CONV_TAC NUM_REDUCE_CONV; + + ASM_REWRITE_TAC[acc_len] THEN + CONV_TAC NUM_REDUCE_CONV THEN + IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN + CONV_TAC NUM_REDUCE_CONV THEN + MP_TAC (SPECL [`0x20`; `ctxt_p:int64`; `(aes256_xts_encrypt pt_in 0x20 iv key1_lst key2_lst):byte list`; + `s158:armstate`] BYTE_LIST_TO_NUM_THM) THEN + ANTS_TAC THENL [ + MP_TAC (SPECL [`2`; `pt_in:byte list`; `iv:int128`; `key1_lst:int128 list`; `key2_lst:int128 list`] + LENGTH_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS) THEN + ARITH_TAC; ALL_TAC] THEN + DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN + IMP_REWRITE_TAC[READ_BYTES_EQ_READ_BYTE128_2BLOCKS_ENC] + ] + ; ALL_TAC] THEN + + (* Reuse the cipher stealing proof *) + MP_TAC CIPHER_STEALING_ENC_CORRECT THEN + REWRITE_TAC [(REWRITE_CONV [aes256_xts_encrypt_mc] THENC LENGTH_CONV) `LENGTH aes256_xts_encrypt_mc`] THEN + REWRITE_TAC[byte_list_at; PAIRWISE; ALL; MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI] THEN + DISCH_THEN MATCH_MP_TAC THEN + ASM_SIMP_TAC[] THEN + ASM_ARITH_TAC +);; + + (* void aes_hw_xts_encrypt(const uint8_t *in, uint8_t *out, size_t length, const AES_KEY *key1, const AES_KEY *key2, From 2c9d89f1eac0a9e1da70736e194404d36816ab0e Mon Sep 17 00:00:00 2001 From: Nevine Ebeid Date: Thu, 4 Dec 2025 12:02:09 -0500 Subject: [PATCH 106/132] Less than 4 blocks, less than 5 blocks: proofs done. --- arm/proofs/aes-xts-armv8.ml | 355 +++++++++++++++++++++++++++++++++++- 1 file changed, 352 insertions(+), 3 deletions(-) diff --git a/arm/proofs/aes-xts-armv8.ml b/arm/proofs/aes-xts-armv8.ml index cd361ab4d..1ab522a62 100644 --- a/arm/proofs/aes-xts-armv8.ml +++ b/arm/proofs/aes-xts-armv8.ml @@ -5118,6 +5118,7 @@ let AES_XTS_ENCRYPT_LT_3BLOCK_CORRECT = time prove( CONV_TAC NUM_REDUCE_CONV THEN REWRITE_TAC[VAL_WORD_0]; ALL_TAC ] THEN + (* Prove property until start of cipher stealing. *) ENSURES_SEQUENCE_TAC `pc + 0x9e0` `\s. read X0 s = word_add ptxt_p (word (acc_len num_5blocks len_full_blocks)) /\ @@ -5183,7 +5184,7 @@ let AES_XTS_ENCRYPT_LT_3BLOCK_CORRECT = time prove( (* Simulating until branching into tail2x *) ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (66--87) THEN TWEAK_TAC `Q8:(armstate,int128)component` `1:num` `0:num` THEN - (* Simulate AES-XTS encryption of block in Q0 *) + (* Simulate AES-XTS encryption of blocks in Q0, Q1 *) ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (88--148) THEN XTSENC_TAC `Q0:(armstate,int128)component` `0` `0` THEN XTSENC_TAC `Q1:(armstate,int128)component` `0x10` `1` THEN @@ -5195,9 +5196,7 @@ let AES_XTS_ENCRYPT_LT_3BLOCK_CORRECT = time prove( REPEAT CONJ_TAC THENL [ ASM_REWRITE_TAC[acc_len] THEN CONV_TAC NUM_REDUCE_CONV; - ASM_REWRITE_TAC[acc_len] THEN CONV_TAC NUM_REDUCE_CONV; - ASM_REWRITE_TAC[acc_blocks] THEN CONV_TAC NUM_REDUCE_CONV; ASM_REWRITE_TAC[acc_len] THEN @@ -5224,6 +5223,356 @@ let AES_XTS_ENCRYPT_LT_3BLOCK_CORRECT = time prove( ASM_ARITH_TAC );; +(* Proof: Less than 4 blocks *) +let AES_XTS_ENCRYPT_LT_4BLOCK_CORRECT = time prove( + `!ptxt_p ctxt_p len key1_p key2_p iv_p + pt_in iv + k1_0 k1_1 k1_2 k1_3 k1_4 k1_5 k1_6 k1_7 k1_8 k1_9 k1_10 k1_11 k1_12 k1_13 k1_14 + k2_0 k2_1 k2_2 k2_3 k2_4 k2_5 k2_6 k2_7 k2_8 k2_9 k2_10 k2_11 k2_12 k2_13 k2_14 + pc. + PAIRWISE nonoverlapping + [(word pc, LENGTH aes256_xts_encrypt_mc); + (ptxt_p, val len); + (ctxt_p, val len); + (key1_p, 244); + (key2_p, 244)] /\ + ~(val len < 0x30) /\ val len < 0x40 /\ LENGTH pt_in = val len /\ + [k1_0; k1_1; k1_2; k1_3; k1_4; k1_5; k1_6; k1_7; k1_8; k1_9; k1_10; + k1_11; k1_12; k1_13; k1_14] = key1_lst /\ + [k2_0; k2_1; k2_2; k2_3; k2_4; k2_5; k2_6; k2_7; k2_8; k2_9; k2_10; + k2_11; k2_12; k2_13; k2_14] = key2_lst + ==> ensures arm + (\s. aligned_bytes_loaded s (word pc) aes256_xts_encrypt_mc /\ + read PC s = word (pc + 0x1c) /\ + C_ARGUMENTS [ptxt_p; ctxt_p; len; key1_p; key2_p; iv_p] s /\ + byte_list_at pt_in ptxt_p len s /\ + read(memory :> bytes128 iv_p) s = iv /\ + set_key_schedule s key1_p k1_0 k1_1 k1_2 k1_3 k1_4 k1_5 k1_6 k1_7 k1_8 k1_9 k1_10 k1_11 k1_12 k1_13 k1_14 /\ + set_key_schedule s key2_p k2_0 k2_1 k2_2 k2_3 k2_4 k2_5 k2_6 k2_7 k2_8 k2_9 k2_10 k2_11 k2_12 k2_13 k2_14) + (\s. read PC s = word (pc + LENGTH aes256_xts_encrypt_mc - 8*4) /\ + byte_list_at (aes256_xts_encrypt pt_in (val len) iv key1_lst key2_lst) ctxt_p len s + ) + (MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI,, + MAYCHANGE [X19; X20; X21; X22],, + MAYCHANGE [Q8; Q9; Q10; Q11; Q12; Q13; Q14; Q15],, + MAYCHANGE [memory :> bytes(ctxt_p, val len)]) + `, + REWRITE_TAC [(REWRITE_CONV [aes256_xts_encrypt_mc] THENC LENGTH_CONV) `LENGTH aes256_xts_encrypt_mc`] THEN + REWRITE_TAC[set_key_schedule; byte_list_at; C_ARGUMENTS; SOME_FLAGS; PAIRWISE; ALL; + MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI] THEN + REPEAT STRIP_TAC THEN + + SUBGOAL_THEN `word_add (word_and len (word 0xf)) + (word_and len (word 0xfffffffffffffff0)) = len:int64` ASSUME_TAC THENL + [REWRITE_TAC[word_split_lemma]; ALL_TAC] THEN + ABBREV_TAC `len_full_blocks:int64 = word_and len (word 0xfffffffffffffff0)` THEN + ABBREV_TAC `tail_len:int64 = word_and len (word 0xf)` THEN + ABBREV_TAC `num_5blocks = (word (val (len_full_blocks:int64) DIV 0x50)):int64` THEN + + SUBGOAL_THEN `val (len_full_blocks:int64) = 0x30` ASSUME_TAC THENL + [ EXPAND_TAC "len_full_blocks" THEN + REWRITE_TAC[LEN_FULL_BLOCKS_TO_VAL] THEN + IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN + CONV_TAC NUM_REDUCE_CONV THEN + SUBGOAL_THEN `val (len:int64) DIV 16 = 3` SUBST1_TAC THENL + [ MATCH_MP_TAC(MESON[LE_ANTISYM] `m <= n /\ n <= m ==> m = n`) THEN + CONJ_TAC THENL [ ASM_ARITH_TAC; ASM_ARITH_TAC]; + ALL_TAC] THEN + ARITH_TAC; ALL_TAC] THEN + + SUBGOAL_THEN `val (num_5blocks:int64) = 0` ASSUME_TAC THENL + [ EXPAND_TAC "num_5blocks" THEN + UNDISCH_TAC `val (len_full_blocks:int64) = 0x30` THEN + SIMP_TAC[] THEN DISCH_TAC THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[VAL_WORD_0]; ALL_TAC ] THEN + + (* Prove property until start of cipher stealing. *) + ENSURES_SEQUENCE_TAC `pc + 0x9e0` + `\s. + read X0 s = word_add ptxt_p (word (acc_len num_5blocks len_full_blocks)) /\ + read X1 s = word_add ctxt_p (word (acc_len num_5blocks len_full_blocks)) /\ + read X3 s = key1_p /\ + read X21 s = tail_len /\ + read Q6 s = calculate_tweak (acc_blocks num_5blocks len_full_blocks T) iv key2_lst /\ + read X19 s = word 0x87 /\ + read Q16 s = k1_0 /\ read Q17 s = k1_1 /\ read Q12 s = k1_2 /\ read Q13 s = k1_3 /\ + read Q14 s = k1_4 /\ read Q15 s = k1_5 /\ read Q4 s = k1_6 /\ read Q5 s = k1_7 /\ + read Q18 s = k1_8 /\ read Q19 s = k1_9 /\ read Q20 s = k1_10 /\ read Q21 s = k1_11 /\ + read Q22 s = k1_12 /\ read Q23 s = k1_13 /\ read Q7 s = k1_14 /\ + byte_list_at pt_in ptxt_p len s /\ + byte_list_at (aes256_xts_encrypt pt_in (acc_len num_5blocks len_full_blocks) iv key1_lst key2_lst) + ctxt_p (word (acc_len num_5blocks len_full_blocks)) s` THEN + CONJ_TAC THENL + [ + MATCH_MP_TAC ENSURES_FRAME_SUBSUMED THEN + EXISTS_TAC `MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI ,, + MAYCHANGE [X19; X20; X21; X22],, + MAYCHANGE [Q8; Q9; Q10; Q11; Q12; Q13; Q14; Q15],, + MAYCHANGE [memory :> bytes128 ctxt_p; + memory :> bytes128 (word_add ctxt_p (word 0x10)); + memory :> bytes128 (word_add ctxt_p (word 0x20))]` THEN + REWRITE_TAC[MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI] THEN + CONJ_TAC THENL [ + REPEAT (GEN_REWRITE_TAC ONCE_DEPTH_CONV [GSYM SEQ_ASSOC] THEN + MATCH_MP_TAC SUBSUMED_SEQ THEN REWRITE_TAC[SUBSUMED_REFL]) THEN + ABBREV_TAC `vallen = val (len:int64)` THEN + SUBSUMED_MAYCHANGE_TAC; ALL_TAC] THEN + + REWRITE_TAC[byte_list_at] THEN + ENSURES_INIT_TAC "s0" THEN + ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (1--2) THEN + + (* Discharge if condition *) + SUBGOAL_THEN + `ival (word_sub (len:int64) (word 0x10)) < &0x0 + <=> ~(ival (len:int64) - &0x10 = ival (word_sub (len:int64) (word 0x10)))` MP_TAC THENL + [ MP_TAC (BITBLAST_RULE (* put in tips doc. Q: When to use it vs. ARITH_RULE? *) + `~(val (len:int64) < 0x30) ==> val len < 0x40 ==> + ival (word_sub len (word 0x10)) >= &0x0`) THEN + ASM_REWRITE_TAC[] THEN + MP_TAC (BITBLAST_RULE + `~(val (len:int64) < 0x30) ==> val len < 0x40 ==> + ival (len:int64) - &0x10 = ival (word_sub len (word 0x10))`) THEN + ASM_REWRITE_TAC[] THEN + ARITH_TAC; + ALL_TAC] THEN + ASM_REWRITE_TAC[] THEN DISCH_TAC THEN + POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th])) THEN + + MP_TAC (SPECL [`ptxt_p:int64`; `len:int64`; `pt_in:byte list`; `s2:armstate`] READ_LT_4BLOCK) THEN + ASM_SIMP_TAC[] THEN REPEAT STRIP_TAC THEN + + ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (3--65) THEN + (* Prove Q6 stores initial tweak *) + FIRST_X_ASSUM(MP_TAC o SPEC `(calculate_tweak 0 iv key2_lst)` + o MATCH_MP (MESON[] `read Q6 s = a ==> !a'. a = a' ==> read Q6 s = a'`)) THEN + ANTS_TAC THENL + [ REWRITE_TAC[CONJUNCT1 calculate_tweak; xts_init_tweak] THEN + EXPAND_TAC "key2_lst" THEN AESENC_TAC; DISCH_TAC] THEN + + (* Simulating until branching into tail3x *) + ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (66--87) THEN + TWEAK_TAC `Q8:(armstate,int128)component` `1:num` `0:num` THEN + ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (88--95) THEN + TWEAK_TAC `Q9:(armstate,int128)component` `2:num` `1:num` THEN + (* Simulate AES-XTS encryption of block in Q0, Q1, Q24 *) + ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (96--187) THEN + XTSENC_TAC `Q0:(armstate,int128)component` `0` `0` THEN + XTSENC_TAC `Q1:(armstate,int128)component` `0x10` `1` THEN + XTSENC_TAC `Q24:(armstate,int128)component` `0x20` `2` THEN + (* until b .Lxts_enc_done = arm_B (word xxx) *) + ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (188--198) THEN + TWEAK_TAC `Q6:(armstate,int128)component` `3:num` `2:num` THEN + ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN + + REPEAT CONJ_TAC THENL + [ + ASM_REWRITE_TAC[acc_len] THEN CONV_TAC NUM_REDUCE_CONV; + ASM_REWRITE_TAC[acc_len] THEN CONV_TAC NUM_REDUCE_CONV; + ASM_REWRITE_TAC[acc_blocks] THEN CONV_TAC NUM_REDUCE_CONV; + + ASM_REWRITE_TAC[acc_len] THEN + CONV_TAC NUM_REDUCE_CONV THEN + IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN + CONV_TAC NUM_REDUCE_CONV THEN + MP_TAC (SPECL [`0x30`; `ctxt_p:int64`; `(aes256_xts_encrypt pt_in 0x30 iv key1_lst key2_lst):byte list`; + `s198:armstate`] BYTE_LIST_TO_NUM_THM) THEN + ANTS_TAC THENL [ + MP_TAC (SPECL [`3`; `pt_in:byte list`; `iv:int128`; `key1_lst:int128 list`; `key2_lst:int128 list`] + LENGTH_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS) THEN + ARITH_TAC; ALL_TAC] THEN + DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN + IMP_REWRITE_TAC[READ_BYTES_EQ_READ_BYTE128_3BLOCKS_ENC] + ] + ; ALL_TAC] THEN + + (* Reuse the cipher stealing proof *) + MP_TAC CIPHER_STEALING_ENC_CORRECT THEN + REWRITE_TAC [(REWRITE_CONV [aes256_xts_encrypt_mc] THENC LENGTH_CONV) `LENGTH aes256_xts_encrypt_mc`] THEN + REWRITE_TAC[byte_list_at; PAIRWISE; ALL; MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI] THEN + DISCH_THEN MATCH_MP_TAC THEN + ASM_SIMP_TAC[] THEN + ASM_ARITH_TAC +);; + +(* Proof: Less than 5 blocks *) +let AES_XTS_ENCRYPT_LT_5BLOCK_CORRECT = time prove( + `!ptxt_p ctxt_p len key1_p key2_p iv_p + pt_in iv + k1_0 k1_1 k1_2 k1_3 k1_4 k1_5 k1_6 k1_7 k1_8 k1_9 k1_10 k1_11 k1_12 k1_13 k1_14 + k2_0 k2_1 k2_2 k2_3 k2_4 k2_5 k2_6 k2_7 k2_8 k2_9 k2_10 k2_11 k2_12 k2_13 k2_14 + pc. + PAIRWISE nonoverlapping + [(word pc, LENGTH aes256_xts_encrypt_mc); + (ptxt_p, val len); + (ctxt_p, val len); + (key1_p, 244); + (key2_p, 244)] /\ + ~(val len < 0x40) /\ val len < 0x50 /\ LENGTH pt_in = val len /\ + [k1_0; k1_1; k1_2; k1_3; k1_4; k1_5; k1_6; k1_7; k1_8; k1_9; k1_10; + k1_11; k1_12; k1_13; k1_14] = key1_lst /\ + [k2_0; k2_1; k2_2; k2_3; k2_4; k2_5; k2_6; k2_7; k2_8; k2_9; k2_10; + k2_11; k2_12; k2_13; k2_14] = key2_lst + ==> ensures arm + (\s. aligned_bytes_loaded s (word pc) aes256_xts_encrypt_mc /\ + read PC s = word (pc + 0x1c) /\ + C_ARGUMENTS [ptxt_p; ctxt_p; len; key1_p; key2_p; iv_p] s /\ + byte_list_at pt_in ptxt_p len s /\ + read(memory :> bytes128 iv_p) s = iv /\ + set_key_schedule s key1_p k1_0 k1_1 k1_2 k1_3 k1_4 k1_5 k1_6 k1_7 k1_8 k1_9 k1_10 k1_11 k1_12 k1_13 k1_14 /\ + set_key_schedule s key2_p k2_0 k2_1 k2_2 k2_3 k2_4 k2_5 k2_6 k2_7 k2_8 k2_9 k2_10 k2_11 k2_12 k2_13 k2_14) + (\s. read PC s = word (pc + LENGTH aes256_xts_encrypt_mc - 8*4) /\ + byte_list_at (aes256_xts_encrypt pt_in (val len) iv key1_lst key2_lst) ctxt_p len s + ) + (MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI,, + MAYCHANGE [X19; X20; X21; X22],, + MAYCHANGE [Q8; Q9; Q10; Q11; Q12; Q13; Q14; Q15],, + MAYCHANGE [memory :> bytes(ctxt_p, val len)]) + `, + REWRITE_TAC [(REWRITE_CONV [aes256_xts_encrypt_mc] THENC LENGTH_CONV) `LENGTH aes256_xts_encrypt_mc`] THEN + REWRITE_TAC[set_key_schedule; byte_list_at; C_ARGUMENTS; SOME_FLAGS; PAIRWISE; ALL; + MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI] THEN + REPEAT STRIP_TAC THEN + + SUBGOAL_THEN `word_add (word_and len (word 0xf)) + (word_and len (word 0xfffffffffffffff0)) = len:int64` ASSUME_TAC THENL + [REWRITE_TAC[word_split_lemma]; ALL_TAC] THEN + ABBREV_TAC `len_full_blocks:int64 = word_and len (word 0xfffffffffffffff0)` THEN + ABBREV_TAC `tail_len:int64 = word_and len (word 0xf)` THEN + ABBREV_TAC `num_5blocks = (word (val (len_full_blocks:int64) DIV 0x50)):int64` THEN + + SUBGOAL_THEN `val (len_full_blocks:int64) = 0x40` ASSUME_TAC THENL + [ EXPAND_TAC "len_full_blocks" THEN + REWRITE_TAC[LEN_FULL_BLOCKS_TO_VAL] THEN + IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN + CONV_TAC NUM_REDUCE_CONV THEN + SUBGOAL_THEN `val (len:int64) DIV 16 = 4` SUBST1_TAC THENL + [ MATCH_MP_TAC(MESON[LE_ANTISYM] `m <= n /\ n <= m ==> m = n`) THEN + CONJ_TAC THENL [ ASM_ARITH_TAC; ASM_ARITH_TAC]; + ALL_TAC] THEN + ARITH_TAC; ALL_TAC] THEN + + SUBGOAL_THEN `val (num_5blocks:int64) = 0` ASSUME_TAC THENL + [ EXPAND_TAC "num_5blocks" THEN + UNDISCH_TAC `val (len_full_blocks:int64) = 0x40` THEN + SIMP_TAC[] THEN DISCH_TAC THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[VAL_WORD_0]; ALL_TAC ] THEN + + (* Prove property until start of cipher stealing. *) + ENSURES_SEQUENCE_TAC `pc + 0x9e0` + `\s. + read X0 s = word_add ptxt_p (word (acc_len num_5blocks len_full_blocks)) /\ + read X1 s = word_add ctxt_p (word (acc_len num_5blocks len_full_blocks)) /\ + read X3 s = key1_p /\ + read X21 s = tail_len /\ + read Q6 s = calculate_tweak (acc_blocks num_5blocks len_full_blocks T) iv key2_lst /\ + read X19 s = word 0x87 /\ + read Q16 s = k1_0 /\ read Q17 s = k1_1 /\ read Q12 s = k1_2 /\ read Q13 s = k1_3 /\ + read Q14 s = k1_4 /\ read Q15 s = k1_5 /\ read Q4 s = k1_6 /\ read Q5 s = k1_7 /\ + read Q18 s = k1_8 /\ read Q19 s = k1_9 /\ read Q20 s = k1_10 /\ read Q21 s = k1_11 /\ + read Q22 s = k1_12 /\ read Q23 s = k1_13 /\ read Q7 s = k1_14 /\ + byte_list_at pt_in ptxt_p len s /\ + byte_list_at (aes256_xts_encrypt pt_in (acc_len num_5blocks len_full_blocks) iv key1_lst key2_lst) + ctxt_p (word (acc_len num_5blocks len_full_blocks)) s` THEN + CONJ_TAC THENL + [ + MATCH_MP_TAC ENSURES_FRAME_SUBSUMED THEN + EXISTS_TAC `MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI ,, + MAYCHANGE [X19; X20; X21; X22],, + MAYCHANGE [Q8; Q9; Q10; Q11; Q12; Q13; Q14; Q15],, + MAYCHANGE [memory :> bytes128 ctxt_p; + memory :> bytes128 (word_add ctxt_p (word 0x10)); + memory :> bytes128 (word_add ctxt_p (word 0x20)); + memory :> bytes128 (word_add ctxt_p (word 0x30))]` THEN + REWRITE_TAC[MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI] THEN + CONJ_TAC THENL [ + REPEAT (GEN_REWRITE_TAC ONCE_DEPTH_CONV [GSYM SEQ_ASSOC] THEN + MATCH_MP_TAC SUBSUMED_SEQ THEN REWRITE_TAC[SUBSUMED_REFL]) THEN + ABBREV_TAC `vallen = val (len:int64)` THEN + SUBSUMED_MAYCHANGE_TAC; ALL_TAC] THEN + + REWRITE_TAC[byte_list_at] THEN + ENSURES_INIT_TAC "s0" THEN + ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (1--2) THEN + + (* Discharge if condition *) + SUBGOAL_THEN + `ival (word_sub (len:int64) (word 0x10)) < &0x0 + <=> ~(ival (len:int64) - &0x10 = ival (word_sub (len:int64) (word 0x10)))` MP_TAC THENL + [ MP_TAC (BITBLAST_RULE (* put in tips doc. Q: When to use it vs. ARITH_RULE? *) + `~(val (len:int64) < 0x40) ==> val len < 0x50 ==> + ival (word_sub len (word 0x10)) >= &0x0`) THEN + ASM_REWRITE_TAC[] THEN + MP_TAC (BITBLAST_RULE + `~(val (len:int64) < 0x40) ==> val len < 0x50 ==> + ival (len:int64) - &0x10 = ival (word_sub len (word 0x10))`) THEN + ASM_REWRITE_TAC[] THEN + ARITH_TAC; + ALL_TAC] THEN + ASM_REWRITE_TAC[] THEN DISCH_TAC THEN + POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th])) THEN + + MP_TAC (SPECL [`ptxt_p:int64`; `len:int64`; `pt_in:byte list`; `s2:armstate`] READ_LT_5BLOCK) THEN + ASM_SIMP_TAC[] THEN REPEAT STRIP_TAC THEN + + ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (3--65) THEN + (* Prove Q6 stores initial tweak *) + FIRST_X_ASSUM(MP_TAC o SPEC `(calculate_tweak 0 iv key2_lst)` + o MATCH_MP (MESON[] `read Q6 s = a ==> !a'. a = a' ==> read Q6 s = a'`)) THEN + ANTS_TAC THENL + [ REWRITE_TAC[CONJUNCT1 calculate_tweak; xts_init_tweak] THEN + EXPAND_TAC "key2_lst" THEN AESENC_TAC; DISCH_TAC] THEN + + (* Simulating until branching into tail4x *) + ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (66--87) THEN + TWEAK_TAC `Q8:(armstate,int128)component` `1:num` `0:num` THEN + ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (88--95) THEN + TWEAK_TAC `Q9:(armstate,int128)component` `2:num` `1:num` THEN + ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (96--103) THEN + TWEAK_TAC `Q10:(armstate,int128)component` `3:num` `2:num` THEN + (* Simulate AES-XTS encryption of block in Q0, Q1, Q24, Q25 *) + ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (104--227) THEN + XTSENC_TAC `Q0:(armstate,int128)component` `0` `0` THEN + XTSENC_TAC `Q1:(armstate,int128)component` `0x10` `1` THEN + XTSENC_TAC `Q24:(armstate,int128)component` `0x20` `2` THEN + XTSENC_TAC `Q25:(armstate,int128)component` `0x30` `3` THEN + (* until b .Lxts_enc_done = arm_B (word xxx) *) + ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (228--238) THEN + TWEAK_TAC `Q6:(armstate,int128)component` `4:num` `3:num` THEN + ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN + + REPEAT CONJ_TAC THENL + [ + ASM_REWRITE_TAC[acc_len] THEN CONV_TAC NUM_REDUCE_CONV; + ASM_REWRITE_TAC[acc_len] THEN CONV_TAC NUM_REDUCE_CONV; + ASM_REWRITE_TAC[acc_blocks] THEN CONV_TAC NUM_REDUCE_CONV; + + ASM_REWRITE_TAC[acc_len] THEN + CONV_TAC NUM_REDUCE_CONV THEN + IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN + CONV_TAC NUM_REDUCE_CONV THEN + MP_TAC (SPECL [`0x40`; `ctxt_p:int64`; `(aes256_xts_encrypt pt_in 0x40 iv key1_lst key2_lst):byte list`; + `s238:armstate`] BYTE_LIST_TO_NUM_THM) THEN + ANTS_TAC THENL [ + MP_TAC (SPECL [`4`; `pt_in:byte list`; `iv:int128`; `key1_lst:int128 list`; `key2_lst:int128 list`] + LENGTH_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS) THEN + ARITH_TAC; ALL_TAC] THEN + DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN + IMP_REWRITE_TAC[READ_BYTES_EQ_READ_BYTE128_4BLOCKS_ENC] + ] + ; ALL_TAC] THEN + + (* Reuse the cipher stealing proof *) + MP_TAC CIPHER_STEALING_ENC_CORRECT THEN + REWRITE_TAC [(REWRITE_CONV [aes256_xts_encrypt_mc] THENC LENGTH_CONV) `LENGTH aes256_xts_encrypt_mc`] THEN + REWRITE_TAC[byte_list_at; PAIRWISE; ALL; MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI] THEN + DISCH_THEN MATCH_MP_TAC THEN + ASM_SIMP_TAC[] THEN + ASM_ARITH_TAC +);; + (* void aes_hw_xts_encrypt(const uint8_t *in, uint8_t *out, size_t length, From df435d5252a9e70d0ff5188fdba86cd0bbd4214e Mon Sep 17 00:00:00 2001 From: Nevine Ebeid Date: Thu, 4 Dec 2025 17:44:26 -0500 Subject: [PATCH 107/132] AES256-XTS encrypt proof: complete. --- arm/proofs/aes-xts-armv8.ml | 336 +++++++++++++++++------------------- 1 file changed, 161 insertions(+), 175 deletions(-) diff --git a/arm/proofs/aes-xts-armv8.ml b/arm/proofs/aes-xts-armv8.ml index 1ab522a62..d2725d57a 100644 --- a/arm/proofs/aes-xts-armv8.ml +++ b/arm/proofs/aes-xts-armv8.ml @@ -1399,7 +1399,6 @@ let READ_CT_TAIL1_LEMMA = prove( REWRITE_TAC[byte_list_at] THEN ASM_SIMP_TAC[] );; -(* TODO: do I need this in encrypt? *) let READ_CT_LAST_LEMMA = prove( `!ct_ptr (curr_len:num) (len:int64) (ct:byte list) s. (forall j. j < val len ==> read (memory :> bytes8 (word_add ct_ptr (word j))) s = EL j ct) @@ -2587,8 +2586,6 @@ let LEN_FULL_BLOCKS_TO_VAL = prove( CONV_TAC NUM_REDUCE_CONV );; -(* TODO: do I need NUM_BLOCKS_MINUS1_TO_VAL ? *) - let BREAK_ONE_BLOCK_INTO_BYTES = prove( `!(addr:int64) (s:armstate) (p:int128). read (memory :> bytes128 addr) s = p <=> @@ -3158,7 +3155,7 @@ let BOUND_OF_ACC_LEN = prove( ASM_ARITH_TAC );; -(* For X9 and X10, they stand for i * 0x5 + 4 when number of blocks is divisible by 5. TODO: check for enrypt *) +(* For X9 and X10, they stand for i * 0x5 + 4 when number of blocks is divisible by 5. *) let acc_blocks = new_definition `acc_blocks (i:int64) (len:int64) (last:bool) : num = if val i * 0x50 + 0x40 = val len then val i * 0x5 + 4 @@ -3615,7 +3612,7 @@ let CIPHER_STEALING_ENC_CORRECT = time prove( (ptxt_p, val len); (ctxt_p, val len); (key1_p, 244)] /\ - val len >= 16 /\ val len <= 2 EXP 24 /\ LENGTH pt_in = val len /\ + val len >= 16 /\ val len <= 2 EXP 24 /\ LENGTH pt_in = val len /\ word_and len (word 0xfffffffffffffff0) = len_full_blocks /\ word_and len (word 0xf) = tail_len /\ @@ -5597,7 +5594,6 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( // precondition (\s. aligned_bytes_loaded s (word pc) aes256_xts_encrypt_mc /\ read PC s = word (pc + 28) /\ - read SP s = stackpointer /\ C_ARGUMENTS [ptxt_p; ctxt_p; len; key1_p; key2_p; iv_p] s /\ byte_list_at pt_in ptxt_p len s /\ read(memory :> bytes128 iv_p) s = iv /\ @@ -5611,14 +5607,14 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( [k2_0; k2_1; k2_2; k2_3; k2_4; k2_5; k2_6; k2_7; k2_8; k2_9; k2_10; k2_11; k2_12; k2_13; k2_14]) ctxt_p len s ) - (MAYCHANGE [PC;X0;X1;X2;X4;X6;X7;X8;X9;X10;X11;X19;X20;X21;X22],, - MAYCHANGE [Q0;Q1;Q4;Q5;Q6;Q7;Q8;Q9;Q10;Q11;Q12;Q13;Q14;Q15;Q16;Q17;Q18;Q19;Q20;Q21;Q22;Q23;Q24;Q25;Q26],, - MAYCHANGE SOME_FLAGS,, - MAYCHANGE [events],, - MAYCHANGE [memory :> bytes(ctxt_p, val len)])`, + (MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI,, + MAYCHANGE [X19; X20; X21; X22],, + MAYCHANGE [Q8; Q9; Q10; Q11; Q12; Q13; Q14; Q15],, + MAYCHANGE [memory :> bytes(ctxt_p, val len)])`, REWRITE_TAC [(REWRITE_CONV [aes256_xts_encrypt_mc] THENC LENGTH_CONV) `LENGTH aes256_xts_encrypt_mc`] THEN - REWRITE_TAC[byte_list_at; set_key_schedule; C_ARGUMENTS; SOME_FLAGS; PAIRWISE; ALL] THEN + REWRITE_TAC[set_key_schedule; byte_list_at; C_ARGUMENTS; SOME_FLAGS; PAIRWISE; ALL; + MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI] THEN REPEAT STRIP_TAC THEN (* Break len into full blocks and tail *) @@ -5644,7 +5640,45 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( tweak is available from prior calculations. The order of the tweaks is not flipped, as in the case of decrypt, between the last block and the tail. *) - ASM_CASES_TAC `val (len:int64) < 0x50` THENL [CHEAT_TAC; ALL_TAC] THEN + ASM_CASES_TAC `val (len:int64) < 0x50` THENL [ + ASM_CASES_TAC `val (len:int64) < 0x20` THENL + [ + MP_TAC AES_XTS_ENCRYPT_LT_2BLOCK_CORRECT THEN + REWRITE_TAC [(REWRITE_CONV [aes256_xts_encrypt_mc] THENC LENGTH_CONV) `LENGTH aes256_xts_encrypt_mc`] THEN + REWRITE_TAC[set_key_schedule; byte_list_at; C_ARGUMENTS; SOME_FLAGS; PAIRWISE; ALL; + MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI] THEN + DISCH_THEN MATCH_MP_TAC THEN + ASM_SIMP_TAC[] ; ALL_TAC ] THEN + + ASM_CASES_TAC `val (len:int64) < 0x30` THENL + [ + MP_TAC AES_XTS_ENCRYPT_LT_3BLOCK_CORRECT THEN + REWRITE_TAC [(REWRITE_CONV [aes256_xts_encrypt_mc] THENC LENGTH_CONV) `LENGTH aes256_xts_encrypt_mc`] THEN + REWRITE_TAC[set_key_schedule; byte_list_at; C_ARGUMENTS; SOME_FLAGS; PAIRWISE; ALL; + MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI] THEN + DISCH_THEN MATCH_MP_TAC THEN + ASM_SIMP_TAC[] ; ALL_TAC ] THEN + + ASM_CASES_TAC `val (len:int64) < 0x40` THENL + [ + MP_TAC AES_XTS_ENCRYPT_LT_4BLOCK_CORRECT THEN + REWRITE_TAC [(REWRITE_CONV [aes256_xts_encrypt_mc] THENC LENGTH_CONV) `LENGTH aes256_xts_encrypt_mc`] THEN + REWRITE_TAC[set_key_schedule; byte_list_at; C_ARGUMENTS; SOME_FLAGS; PAIRWISE; ALL; + MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI] THEN + DISCH_THEN MATCH_MP_TAC THEN + ASM_SIMP_TAC[] ; ALL_TAC ] THEN + + ASM_CASES_TAC `val (len:int64) < 0x50` THENL + [ + MP_TAC AES_XTS_ENCRYPT_LT_5BLOCK_CORRECT THEN + REWRITE_TAC [(REWRITE_CONV [aes256_xts_encrypt_mc] THENC LENGTH_CONV) `LENGTH aes256_xts_encrypt_mc`] THEN + REWRITE_TAC[set_key_schedule; byte_list_at; C_ARGUMENTS; SOME_FLAGS; PAIRWISE; ALL; + MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI] THEN + DISCH_THEN MATCH_MP_TAC THEN + ASM_SIMP_TAC[] ; ALL_TAC ] THEN + + ASM_ARITH_TAC + ; ALL_TAC] THEN (* Prove the bounds on len_full_blocks, num_5blocks and len and their relationships *) SUBGOAL_THEN `~(val (len_full_blocks:int64) < 0x50)` ASSUME_TAC THENL @@ -5691,6 +5725,7 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( read X0 s = ptxt_p /\ read X1 s = ctxt_p /\ read X2 s = len_full_blocks /\ + read X3 s = key1_p /\ read X21 s = tail_len /\ read X8 s = num_5blocks /\ read X9 s = word_zx (calculate_tweak 4 iv key2_lst) /\ @@ -5746,7 +5781,7 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( (* ===> Symbolic Simulation: Symbolic simulating untill next branch: - iv for second block - load key schedule *) - ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (66--76) THEN + ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (66--77) THEN (* Branching on x2 *) (* Eliminate 1 block case *) SUBGOAL_THEN `~(val (len_full_blocks:int64) < 0x20)` MP_TAC THENL @@ -5754,27 +5789,24 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( DISCH_THEN(RULE_ASSUM_TAC o REWRITE_RULE o CONJUNCTS)] THEN (* Prove x9, x10 store lower and upper halves of tweak 1 and Q8 stores the full tweak 1 *) - ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (77--85) THEN + ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (78--87) THEN TWEAK_TAC `Q8:(armstate,int128)component` `1:num` `0:num` THEN (* Eliminate 2 blocks case *) - ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (86--87) THEN SUBGOAL_THEN `~(val (len_full_blocks:int64) < 0x30)` MP_TAC THENL [ UNDISCH_TAC `~(val (len_full_blocks:int64) < 0x50)` THEN ARITH_TAC; DISCH_THEN(RULE_ASSUM_TAC o REWRITE_RULE o CONJUNCTS)] THEN (* prove Q9 stores tweak of 3rd block (index 2) *) - ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (88--93) THEN (* TODO: How is the last parameter in TWEAK_TAC `0` in the upcoming ones? *) + ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (88--95) THEN (* TODO: How is the last parameter in TWEAK_TAC `0` in the upcoming ones? *) TWEAK_TAC `Q9:(armstate,int128)component` `2:num` `0:num` THEN (* Eliminate 3 blocks case *) - ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (94--95) THEN SUBGOAL_THEN `~(val (len_full_blocks:int64) < 0x40)` MP_TAC THENL [ UNDISCH_TAC `~(val (len_full_blocks:int64) < 0x50)` THEN ARITH_TAC; DISCH_THEN(RULE_ASSUM_TAC o REWRITE_RULE o CONJUNCTS)] THEN (* prove Q10 stores tweak of 4th block (index 3) *) - ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (96--101) THEN + ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (96--103) THEN TWEAK_TAC `Q10:(armstate,int128)component` `3:num` `0:num` THEN (* Eliminate 4 blocks case, proven by the assumption ~(len_full_blocks < 0x50)*) - ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (102--103) THEN (* prove Q11 stores tweak of 5th block (index 4) *) ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (105--110) THEN TWEAK_TAC `Q11:(armstate,int128)component` `4:num` `0:num` THEN @@ -5806,11 +5838,10 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( `\s. read X0 s = word_add ptxt_p (word (acc_len num_5blocks len_full_blocks)) /\ read X1 s = word_add ctxt_p (word (acc_len num_5blocks len_full_blocks)) /\ + read X3 s = key1_p /\ read X21 s = tail_len /\ read Q6 s = calculate_tweak (acc_blocks num_5blocks len_full_blocks T) iv key2_lst /\ read X19 s = word 0x87 /\ - read X10 s = word_subword (calculate_tweak (acc_blocks num_5blocks len_full_blocks F) iv key2_lst) (64,64) /\ - read X9 s = word_zx (calculate_tweak (acc_blocks num_5blocks len_full_blocks F) iv key2_lst) /\ read Q16 s = k1_0 /\ read Q17 s = k1_1 /\ read Q12 s = k1_2 /\ read Q13 s = k1_3 /\ read Q14 s = k1_4 /\ read Q15 s = k1_5 /\ read Q4 s = k1_6 /\ read Q5 s = k1_7 /\ read Q18 s = k1_8 /\ read Q19 s = k1_9 /\ read Q20 s = k1_10 /\ read Q21 s = k1_11 /\ @@ -5831,6 +5862,7 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( (read X0 s = word_add ptxt_p (word_mul (word 0x50) (word i)) /\ read X1 s = word_add ctxt_p (word_mul (word 0x50) (word i)) /\ read X21 s = tail_len /\ + read X3 s = key1_p /\ read X2 s = word_sub len_full_blocks (word_mul (word 0x50) (word i)) /\ read X8 s = word_sub num_5blocks (word i) /\ read X19 s = word 0x87 /\ @@ -5891,17 +5923,15 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( ] THEN MATCH_MP_TAC ENSURES_FRAME_SUBSUMED THEN - EXISTS_TAC `MAYCHANGE - [PC; X0; X1; X2; X4; X6; X7; X8; X9; X10; X11; X19; X20; X21; X22] ,, - MAYCHANGE [Q0; Q1; Q4; Q5; Q6; Q7; Q8; Q9; Q10; Q11; Q12; Q13; Q14; Q15; Q16; Q17; - Q18; Q19; Q20; Q21; Q22; Q23; Q24; Q25; Q26] ,, - MAYCHANGE [NF; ZF; CF; VF] ,, - MAYCHANGE [events] ,, + EXISTS_TAC `MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI ,, + MAYCHANGE [X19; X20; X21; X22],, + MAYCHANGE [Q8; Q9; Q10; Q11; Q12; Q13; Q14; Q15],, MAYCHANGE [memory :> bytes128 (word_add ctxt_p (word (0x50 * i))); - memory :> bytes128 (word_add ctxt_p (word (0x50 * i + 0x10))); - memory :> bytes128 (word_add ctxt_p (word (0x50 * i + 0x20))); - memory :> bytes128 (word_add ctxt_p (word (0x50 * i + 0x30))); - memory :> bytes128 (word_add ctxt_p (word (0x50 * i + 0x40)))]` THEN + memory :> bytes128 (word_add ctxt_p (word (0x50 * i + 0x10))); + memory :> bytes128 (word_add ctxt_p (word (0x50 * i + 0x20))); + memory :> bytes128 (word_add ctxt_p (word (0x50 * i + 0x30))); + memory :> bytes128 (word_add ctxt_p (word (0x50 * i + 0x40)))]` THEN + REWRITE_TAC[MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI] THEN CONJ_TAC THENL[ REPEAT (GEN_REWRITE_TAC ONCE_DEPTH_CONV [GSYM SEQ_ASSOC] THEN MATCH_MP_TAC SUBSUMED_SEQ THEN REWRITE_TAC[SUBSUMED_REFL]) THEN @@ -6409,39 +6439,34 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( SUBST_ALL_TAC (WORD_RULE `(word (val (num_5blocks:int64))):int64 = num_5blocks`) THEN MATCH_MP_TAC ENSURES_FRAME_SUBSUMED THEN - EXISTS_TAC `//MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI ,, - //MAYCHANGE [X19; X20; X21; X22],, - //MAYCHANGE [Q8; Q9; Q10; Q11; Q12; Q13; Q14; Q15],, - MAYCHANGE [PC; X0; X1; X2; X4; X6; X7; X8; X9; X10; X11; X19; X20; X21; X22] ,, - MAYCHANGE [Q0; Q1; Q4; Q5; Q6; Q7; Q8; Q9; Q10; Q11; Q12; Q13; Q14; Q15; Q16; Q17; - Q18; Q19; Q20; Q21; Q22; Q23; Q24; Q25; Q26] ,, - MAYCHANGE [NF; ZF; CF; VF] ,, - MAYCHANGE [events] ,, - if val (num_5blocks:int64) * 0x50 + 0x40 = val (len_full_blocks:int64) + EXISTS_TAC `MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI ,, + MAYCHANGE [X19; X20; X21; X22],, + MAYCHANGE [Q8; Q9; Q10; Q11; Q12; Q13; Q14; Q15],, + if val (num_5blocks:int64) * 0x50 + 0x40 = val (len_full_blocks:int64) + then + MAYCHANGE [memory :> bytes128 (word_add ctxt_p (word (0x50 * val (num_5blocks:int64)))); + memory :> bytes128 (word_add ctxt_p (word (0x50 * val num_5blocks + 0x10))); + memory :> bytes128 (word_add ctxt_p (word (0x50 * val num_5blocks + 0x20))); + memory :> bytes128 (word_add ctxt_p (word (0x50 * val num_5blocks + 0x30)))] + else + (if val (num_5blocks:int64) * 0x50 + 0x30 = val (len_full_blocks:int64) then MAYCHANGE [memory :> bytes128 (word_add ctxt_p (word (0x50 * val (num_5blocks:int64)))); - memory :> bytes128 (word_add ctxt_p (word (0x50 * val num_5blocks + 0x10))); - memory :> bytes128 (word_add ctxt_p (word (0x50 * val num_5blocks + 0x20))); - memory :> bytes128 (word_add ctxt_p (word (0x50 * val num_5blocks + 0x30)))] + memory :> bytes128 (word_add ctxt_p (word (0x50 * val num_5blocks + 0x10))); + memory :> bytes128 (word_add ctxt_p (word (0x50 * val num_5blocks + 0x20)))] else - (if val (num_5blocks:int64) * 0x50 + 0x30 = val (len_full_blocks:int64) - then - MAYCHANGE [memory :> bytes128 (word_add ctxt_p (word (0x50 * val (num_5blocks:int64)))); - memory :> bytes128 (word_add ctxt_p (word (0x50 * val num_5blocks + 0x10))); - memory :> bytes128 (word_add ctxt_p (word (0x50 * val num_5blocks + 0x20)))] - else - (if val (num_5blocks:int64) * 0x50 + 0x20 = val (len_full_blocks:int64) + (if val (num_5blocks:int64) * 0x50 + 0x20 = val (len_full_blocks:int64) + then + MAYCHANGE [memory :> bytes128 (word_add ctxt_p (word (0x50 * val (num_5blocks:int64)))); + memory :> bytes128 (word_add ctxt_p (word (0x50 * val num_5blocks + 0x10)))] + else + (if val (num_5blocks:int64) * 0x50 + 0x10 = val (len_full_blocks:int64) then - MAYCHANGE [memory :> bytes128 (word_add ctxt_p (word (0x50 * val (num_5blocks:int64)))); - memory :> bytes128 (word_add ctxt_p (word (0x50 * val num_5blocks + 0x10)))] + MAYCHANGE [memory :> bytes128 (word_add ctxt_p (word (0x50 * val (num_5blocks:int64))))] else - (if val (num_5blocks:int64) * 0x50 + 0x10 = val (len_full_blocks:int64) - then - MAYCHANGE [memory :> bytes128 (word_add ctxt_p (word (0x50 * val (num_5blocks:int64))))] - else - MAYCHANGE []))) - ` THEN - (* REWRITE_TAC[MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI] THEN *) + MAYCHANGE []))) + ` THEN + REWRITE_TAC[MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI] THEN CONJ_TAC THENL [ REPEAT (GEN_REWRITE_TAC ONCE_DEPTH_CONV [GSYM SEQ_ASSOC] THEN MATCH_MP_TAC SUBSUMED_SEQ THEN REWRITE_TAC[SUBSUMED_REFL]) THEN @@ -6516,17 +6541,6 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( MP_TAC (SPECL [`ptxt_p:int64`; `num_5blocks:int64`; `len:int64`; `pt_in:byte list`; `s3:armstate`] READ_CT_TAIL4_LEMMA) THEN ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN - (* Assumptions that help with reasoning about nonoverlapping - so that the universally quantified assumption stays. - See: https://hol-light.zulipchat.com/#narrow/channel/474190-s2n-bignum/topic/.E2.9C.94.20Symbolic.20simulation.20removed.20assumption/with/541554894 *) - (*SUBGOAL_THEN `0x50 * (val (num_5blocks:int64)) < 0x2 EXP 0x40` ASSUME_TAC THENL - [ UNDISCH_TAC `val (num_5blocks:int64) * 0x50 <= val (len_full_blocks:int64)` THEN - UNDISCH_TAC `val (len_full_blocks:int64) <= 0x2 EXP 0x18` THEN - ARITH_TAC; ALL_TAC] THEN - SUBGOAL_THEN `val ((word (0x50 * val (num_5blocks:int64))):int64) = 0x50 * val num_5blocks` ASSUME_TAC THENL [ - IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN ASM_ARITH_TAC; ALL_TAC] THEN - POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th])) THEN *) - ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (4--127) THEN XTSENC_TAC `Q0:(armstate,int128)component` `val (num_5blocks:int64) * 0x50` `val (num_5blocks:int64) * 0x5` THEN @@ -6545,29 +6559,32 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( CHANGED_TAC (RULE_ASSUM_TAC(REWRITE_RULE [WORD_RULE `!base m n. word_add (word_add base (word m)) (word n) = word_add base (word(m + n))`])) THEN - ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (128--129) THEN (* Store 4 blocks in ctxt_p *) - ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (130--137) THEN (* Calculate tweak *) + ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (128--128) THEN (* Store 2 blocks in ctxt_p *) + (* Need to simplify the expression for X1 after the first store instruction *) + CHANGED_TAC (RULE_ASSUM_TAC(REWRITE_RULE + [WORD_RULE `!base m n. word_add (word_add base (word m)) (word n) = word_add base (word(m + n))`])) THEN + + ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (129--137) THEN (* Store 2 blocks and calculate tweak *) TWEAK_TAC `Q6:(armstate,int128)component` `val (num_5blocks:int64) * 0x5 + 0x4` `val (num_5blocks:int64) * 0x5 + 0x3` THEN - (* TODO: Still have the same problem *) ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (138--138) THEN ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN - REPEAT CONJ_TAC THENL (* 7 subgoals (9 total) *) + (*` word_add ptxt_p (word (0x50 * val num_5blocks + 0x40)) = + word_add ptxt_p (word (acc_len num_5blocks len_full_blocks)) /\ + word_add (word_add ctxt_p (word (0x50 * val num_5blocks))) (word 0x40) = + word_add ctxt_p (word (acc_len num_5blocks len_full_blocks)) /\ + calculate_tweak (val num_5blocks * 0x5 + 0x4) iv key2_lst = + calculate_tweak (acc_blocks num_5blocks len_full_blocks true) iv key2_lst /\ + (forall i. + i < val (word (acc_len num_5blocks len_full_blocks)) + ==> read (memory :> bytes8 (word_add ctxt_p (word i))) s138 = + EL i (aes256_xts_encrypt pt_in (acc_len num_5blocks len_full_blocks) iv key1_lst key2_lst))` *) + REPEAT CONJ_TAC THENL (* 4 subgoals (6 total) *) [ REWRITE_TAC[acc_len] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; REWRITE_TAC[acc_len] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; REWRITE_TAC[acc_blocks] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; - REWRITE_TAC[acc_blocks] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; - REWRITE_TAC[acc_blocks] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; (* 4 total *) -(* -`forall i. - i < val (word (acc_len num_5blocks len_full_blocks)) - ==> read (memory :> bytes8 (word_add ctxt_p (word i))) s138 = - EL i - (aes256_xts_encrypt pt_in (acc_len num_5blocks len_full_blocks) iv - key1_lst - key2_lst)` -*) + REWRITE_TAC[acc_len] THEN ASM_SIMP_TAC[LE_REFL] THEN SUBGOAL_THEN `val ((word (0x50 * val (num_5blocks:int64) + 0x40)):int64) = 0x50 * val num_5blocks + 0x40` ASSUME_TAC THENL @@ -6576,48 +6593,20 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( UNDISCH_TAC `val (len:int64) <= 0x2 EXP 0x18` THEN ARITH_TAC; ALL_TAC] THEN CHANGED_TAC (POP_ASSUM(fun th -> REWRITE_TAC[th])) THEN -(* -`forall i. - i < 0x50 * val num_5blocks + 0x40 - ==> read (memory :> bytes8 (word_add ctxt_p (word i))) s138 = - EL i - (aes256_xts_encrypt pt_in (0x50 * val num_5blocks + 0x40) iv - key1_lst - key2_lst)` -*) - (* TODO: Manually add the assumption as a temporary fix to: - the symbolic simulation only contained results for 0th 1st and 3rd blocks, - but doesn't have 2nd *) - SUBGOAL_THEN `read - (memory :> - bytes128 - (word_add (ctxt_p:int64) (word (0x50 * val (num_5blocks:int64) + 0x20)))) - s138 = - aes256_xts_encrypt_round - (bytes_to_int128 - (SUB_LIST (val num_5blocks * 0x50 + 0x20,0x10) pt_in)) - (calculate_tweak (val num_5blocks * 0x5 + 0x2) iv key2_lst) - key1_lst` ASSUME_TAC THENL [CHEAT_TAC; ALL_TAC] THEN - (* TODO: ??? *) - CHANGED_TAC(RULE_ASSUM_TAC(REWRITE_RULE - [WORD_RULE `(word_add (word_add ctxt_p (word (0x50 * val num_5blocks))) - (word 0x30)) = (word_add (ctxt_p:int64) (word (0x50 * val (num_5blocks:int64) + 0x30)))`])) THEN + (* `forall i. + i < 0x50 * val num_5blocks + 0x40 + ==> read (memory :> bytes8 (word_add ctxt_p (word i))) s138 = + EL i (aes256_xts_encrypt pt_in (0x50 * val num_5blocks + 0x40) iv key1_lst key2_lst)` *) (* Remove quantifier in conclusion then in antecedent of the goal: ==> (forall i. i < 0x50 * val num_5blocks ==> read (memory :> bytes8 (word_add ctxt_p (word i))) s138 = - EL i - (aes256_xts_encrypt pt_in (val num_5blocks * 0x50) iv key1_lst - key2_lst)) + EL i (aes256_xts_encrypt pt_in (val num_5blocks * 0x50) iv key1_lst key2_lst)) ==> (forall i. i < 0x50 * val num_5blocks + 0x40 ==> read (memory :> bytes8 (word_add ctxt_p (word i))) s138 = - EL i - (aes256_xts_encrypt pt_in (0x50 * val num_5blocks + 0x40) iv - key1_lst - key2_lst))` - *) + EL i (aes256_xts_encrypt pt_in (0x50 * val num_5blocks + 0x40) iv key1_lst key2_lst))` *) UNDISCH_TAC `forall i. i < 0x50 * val (num_5blocks:int64) @@ -6632,19 +6621,7 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( ARITH_TAC ; ALL_TAC] THEN DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN -(* -`(forall i. - i < 0x50 * val num_5blocks - ==> read (memory :> bytes8 (word_add ctxt_p (word i))) s138 = - EL i - (aes256_xts_encrypt pt_in (val num_5blocks * 0x50) iv key1_lst - key2_lst)) - ==> read (memory :> bytes (ctxt_p,0x50 * val num_5blocks + 0x40)) s138 = - num_of_bytelist - (SUB_LIST (0x0,0x50 * val num_5blocks + 0x40) - (aes256_xts_encrypt pt_in (0x50 * val num_5blocks + 0x40) iv key1_lst - key2_lst))` -*) + MP_TAC (SPECL [`0x50 * val (num_5blocks:int64):num`; `ctxt_p:int64`; `(aes256_xts_encrypt pt_in (val (num_5blocks:int64) * 0x50) iv key1_lst key2_lst):byte list`; `s138:armstate`] BYTE_LIST_TO_NUM_THM) THEN @@ -6654,35 +6631,51 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( ARITH_TAC ; ALL_TAC] THEN DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN -(* -`read (memory :> bytes (ctxt_p,0x50 * val num_5blocks)) s138 = - num_of_bytelist - (SUB_LIST (0x0,0x50 * val num_5blocks) - (aes256_xts_encrypt pt_in (val num_5blocks * 0x50) iv key1_lst key2_lst)) - ==> read (memory :> bytes (ctxt_p,0x50 * val num_5blocks + 0x40)) s138 = - num_of_bytelist - (SUB_LIST (0x0,0x50 * val num_5blocks + 0x40) - (aes256_xts_encrypt pt_in (0x50 * val num_5blocks + 0x40) iv key1_lst - key2_lst))` -*) +(* `read (memory :> bytes (ctxt_p,0x50 * val num_5blocks)) s138 = + num_of_bytelist + (SUB_LIST (0x0,0x50 * val num_5blocks) + (aes256_xts_encrypt pt_in (val num_5blocks * 0x50) iv key1_lst key2_lst)) + ==> read (memory :> bytes (ctxt_p,0x50 * val num_5blocks + 0x40)) s138 = + num_of_bytelist + (SUB_LIST (0x0,0x50 * val num_5blocks + 0x40) + (aes256_xts_encrypt pt_in (0x50 * val num_5blocks + 0x40) iv key1_lst + key2_lst))` *) DISCH_TAC THEN IMP_REWRITE_TAC[ARITH_RULE `0x50 * i + 0x40 = (0x50 * i + 0x30) + 0x10`; READ_BYTES_AND_BYTE128_SPLIT] THEN EXISTS_TAC `(aes256_xts_encrypt pt_in (0x50 * val (num_5blocks:int64) + 0x40) iv key1_lst key2_lst)` THEN - REPEAT CONJ_TAC THENL [ + (*`num_of_bytelist + (SUB_LIST (0x0,(0x50 * val num_5blocks + 0x30) + 0x10) + (aes256_xts_encrypt pt_in (0x50 * val num_5blocks + 0x40) iv key1_lst key2_lst)) = + num_of_bytelist (SUB_LIST (0x0,(0x50 * val num_5blocks + 0x30) + 0x10) + (aes256_xts_encrypt pt_in ((0x50 * val num_5blocks + 0x30) + 0x10) iv key1_lst key2_lst)) /\ + (0x50 * val num_5blocks + 0x30) + 0x10 <= + LENGTH (aes256_xts_encrypt pt_in (0x50 * val num_5blocks + 0x40) iv key1_lst key2_lst) /\ + read (memory :> bytes128 (word_add ctxt_p (word (0x50 * val num_5blocks + 0x30)))) s138 = + bytes_to_int128 (SUB_LIST (0x50 * val num_5blocks + 0x30,0x10) + (aes256_xts_encrypt pt_in (0x50 * val num_5blocks + 0x40) iv key1_lst key2_lst)) /\ + read (memory :> bytes (ctxt_p,0x50 * val num_5blocks + 0x30)) s138 = + num_of_bytelist (SUB_LIST (0x0,0x50 * val num_5blocks + 0x30) + (aes256_xts_encrypt pt_in (0x50 * val num_5blocks + 0x40) iv key1_lst key2_lst))`*) + REPEAT CONJ_TAC THENL [ (* 4 subgoals *) REWRITE_TAC [ARITH_RULE `(0x50 * i + 0x30) + 0x10 = 0x50 * i + 0x40`]; -(* -`(0x50 * val num_5blocks + 0x30) + 0x10 <= - LENGTH - (aes256_xts_encrypt pt_in (0x50 * val num_5blocks + 0x40) iv key1_lst - key2_lst)` -*) +(* `(0x50 * val num_5blocks + 0x30) + 0x10 <= + LENGTH (aes256_xts_encrypt pt_in (0x50 * val num_5blocks + 0x40) iv key1_lst key2_lst)` *) MP_TAC (SPECL [`0x5 * val (num_5blocks:int64) + 0x4:num`; `pt_in:byte list`; `iv:int128`; `key1_lst:int128 list`; `key2_lst:int128 list`] LENGTH_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS) THEN REWRITE_TAC[LEFT_ADD_DISTRIB; MULT_ASSOC; GSYM ADD_ASSOC] THEN CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC THEN - ASM_REWRITE_TAC[] THEN ARITH_TAC; (* 4 total *) + ASM_REWRITE_TAC[] THEN ARITH_TAC; +(* `read (memory :> bytes128 (word_add ctxt_p (word (0x50 * val num_5blocks + 0x30)))) s138 = + bytes_to_int128 (SUB_LIST (0x50 * val num_5blocks + 0x30,0x10) + (aes256_xts_encrypt pt_in (0x50 * val num_5blocks + 0x40) iv key1_lst key2_lst))` *) + + (* Establish that one xts encrypt round is the same as + selecting one block of bytes from calling the top-level function. *) + CHANGED_TAC(RULE_ASSUM_TAC(REWRITE_RULE + [ARITH_RULE `(0x50 * val (num_5blocks:int64) + 0x20) + 0x10 = 0x50 * val num_5blocks + 0x30`])) THEN + ASM_REWRITE_TAC[] THEN (* `aes256_xts_encrypt_round (bytes_to_int128 (SUB_LIST (val num_5blocks * 0x50 + 0x30,0x10) pt_in)) @@ -6693,8 +6686,6 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( (aes256_xts_encrypt pt_in (0x50 * val num_5blocks + 0x40) iv key1_lst key2_lst))` *) - (* Establish that one xts encrypt round is the same as - selecting one block of bytes from calling the top-level function. *) REWRITE_TAC[aes256_xts_encrypt] THEN SIMP_TAC[ARITH_RULE `~(0x50 * val (num_5blocks:int64) + 0x40 < 0x10)`] THEN SUBGOAL_THEN `(0x50 * val (num_5blocks:int64) + 0x40) MOD 0x10 = 0` SUBST1_TAC THENL @@ -6782,13 +6773,9 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( REWRITE_TAC[AES256_XTS_ENCRYPT_TAIL_WHEN_1BLOCK] THEN ASM_SIMP_TAC[ARITH_RULE `(i * 0x5 + 0x3) * 0x10 = i * 0x50 + 0x30`; ARITH_RULE `5 * i + 3 = i * 5 + 3`]; (* 3 total *) -(* -`read (memory :> bytes (ctxt_p,0x50 * val num_5blocks + 0x30)) s138 = - num_of_bytelist - (SUB_LIST (0x0,0x50 * val num_5blocks + 0x30) - (aes256_xts_encrypt pt_in (0x50 * val num_5blocks + 0x40) iv key1_lst - key2_lst))` -*) +(*`read (memory :> bytes (ctxt_p,0x50 * val num_5blocks + 0x30)) s138 = + num_of_bytelist (SUB_LIST (0x0,0x50 * val num_5blocks + 0x30) + (aes256_xts_encrypt pt_in (0x50 * val num_5blocks + 0x40) iv key1_lst key2_lst))` *) (* Proving that reading previous bytes is the same as the spec *) REWRITE_TAC[ARITH_RULE `0x50 * i + 0x30 = 0x10 * (5 * i + 3)`; ARITH_RULE `0x50 * i + 0x40 = 0x10 * (5 * i + 3) + 0x10`] THEN @@ -7046,8 +7033,7 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( [ REWRITE_TAC[acc_len] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; REWRITE_TAC[acc_len] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; - REWRITE_TAC[acc_blocks] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; - REWRITE_TAC[acc_blocks] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; + REWRITE_TAC[acc_blocks] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; (* 3 total *) REWRITE_TAC[acc_len] THEN ASM_SIMP_TAC[LE_REFL] THEN @@ -7282,8 +7268,8 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN REWRITE_TAC[LENGTH_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS] ] - ] ; ALL_TAC - ] THEN (* 2 total *) + ] ; ALL_TAC (* 2 total *) + ] THEN DISCH_TAC THEN ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (6--7) THEN @@ -7342,8 +7328,6 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( [ REWRITE_TAC[acc_len] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; REWRITE_TAC[acc_len] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; - REWRITE_TAC[acc_blocks] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; - REWRITE_TAC[acc_blocks] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; REWRITE_TAC[acc_blocks] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; (* 3 total *) REWRITE_TAC[acc_len] THEN ASM_SIMP_TAC[LE_REFL] THEN @@ -7514,8 +7498,8 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN REWRITE_TAC[LENGTH_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS] ] - ] ; ALL_TAC - ] THEN (* 2 total *) + ] ; ALL_TAC (* 2 total *) + ] THEN DISCH_TAC THEN ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (8--9) THEN @@ -7576,8 +7560,6 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( [ REWRITE_TAC[acc_len] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; REWRITE_TAC[acc_len] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; - REWRITE_TAC[acc_blocks] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; - REWRITE_TAC[acc_blocks] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; REWRITE_TAC[acc_blocks] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; (* 3 total *) REWRITE_TAC[acc_len] THEN ASM_SIMP_TAC[LE_REFL] THEN @@ -7689,8 +7671,8 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN REWRITE_TAC[LENGTH_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS] ] - ] ; ALL_TAC - ] THEN (* 2 total *) + ] ; ALL_TAC (* 2 total *) + ] THEN (* Case: len % 0x50 = 0 *) DISCH_TAC THEN @@ -7879,8 +7861,6 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( REWRITE_TAC[acc_len] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; REWRITE_TAC[acc_len] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; REWRITE_TAC[acc_blocks] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; - REWRITE_TAC[acc_blocks] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; - REWRITE_TAC[acc_blocks] THEN ASM_SIMP_TAC[] THEN CONV_TAC WORD_RULE; REWRITE_TAC[acc_len] THEN ASM_SIMP_TAC[] THEN @@ -7906,6 +7886,12 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( ; ALL_TAC ] THEN + (* Reuse the cipher stealing proof *) + MP_TAC CIPHER_STEALING_ENC_CORRECT THEN + REWRITE_TAC [(REWRITE_CONV [aes256_xts_encrypt_mc] THENC LENGTH_CONV) `LENGTH aes256_xts_encrypt_mc`] THEN + REWRITE_TAC[byte_list_at; PAIRWISE; ALL; MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI] THEN + DISCH_THEN MATCH_MP_TAC THEN + ASM_SIMP_TAC[] );; From 0e7e6df215a2c0b7fb498d1ed8780429d52ac254 Mon Sep 17 00:00:00 2001 From: Nevine Ebeid Date: Thu, 4 Dec 2025 21:12:18 -0500 Subject: [PATCH 108/132] AES256-XTS encrypt proof including stack management: complete. --- arm/proofs/aes-xts-armv8.ml | 60 +++++++++++++++++++++++++++++++------ 1 file changed, 51 insertions(+), 9 deletions(-) diff --git a/arm/proofs/aes-xts-armv8.ml b/arm/proofs/aes-xts-armv8.ml index d2725d57a..2ff66a220 100644 --- a/arm/proofs/aes-xts-armv8.ml +++ b/arm/proofs/aes-xts-armv8.ml @@ -3637,7 +3637,7 @@ let CIPHER_STEALING_ENC_CORRECT = time prove( byte_list_at (aes256_xts_encrypt pt_in (acc_len num_5blocks len_full_blocks) iv key1_lst key2_lst) ctxt_p (word (acc_len num_5blocks len_full_blocks)) s) (\s. - read PC s = word (pc + LENGTH aes256_xts_encrypt_mc - 8*4) /\ + read PC s = word (pc + 0xa8c) /\ //LENGTH aes256_xts_encrypt_mc - 8*4 = 0xaac - 0x8 * 0x4 byte_list_at (aes256_xts_encrypt pt_in (val len) iv key1_lst key2_lst) ctxt_p len s ) ( MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI,, MAYCHANGE [X19; X20; X21; X22] ,, @@ -4603,7 +4603,6 @@ let CIPHER_STEALING_ENC_CORRECT = time prove( REWRITE_TAC[GSYM (ASSUME `0x10 * l1_curr_blocks = l1_curr_len`)] THEN REWRITE_TAC[ARITH_RULE `l1_curr_blocks * 0x10 = 0x10 * l1_curr_blocks`] ] - ] (* end of loop invariant proof. *) );; @@ -4902,7 +4901,7 @@ let AES_XTS_ENCRYPT_LT_2BLOCK_CORRECT = time prove( read(memory :> bytes128 iv_p) s = iv /\ set_key_schedule s key1_p k1_0 k1_1 k1_2 k1_3 k1_4 k1_5 k1_6 k1_7 k1_8 k1_9 k1_10 k1_11 k1_12 k1_13 k1_14 /\ set_key_schedule s key2_p k2_0 k2_1 k2_2 k2_3 k2_4 k2_5 k2_6 k2_7 k2_8 k2_9 k2_10 k2_11 k2_12 k2_13 k2_14) - (\s. read PC s = word (pc + LENGTH aes256_xts_encrypt_mc - 8*4) /\ + (\s. read PC s = word (pc + 0xa8c) /\ //LENGTH aes256_xts_encrypt_mc - 8*4 = 0xaac - 0x8 * 0x4 byte_list_at (aes256_xts_encrypt pt_in (val len) iv key1_lst key2_lst) ctxt_p len s ) (MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI,, @@ -5077,7 +5076,7 @@ let AES_XTS_ENCRYPT_LT_3BLOCK_CORRECT = time prove( read(memory :> bytes128 iv_p) s = iv /\ set_key_schedule s key1_p k1_0 k1_1 k1_2 k1_3 k1_4 k1_5 k1_6 k1_7 k1_8 k1_9 k1_10 k1_11 k1_12 k1_13 k1_14 /\ set_key_schedule s key2_p k2_0 k2_1 k2_2 k2_3 k2_4 k2_5 k2_6 k2_7 k2_8 k2_9 k2_10 k2_11 k2_12 k2_13 k2_14) - (\s. read PC s = word (pc + LENGTH aes256_xts_encrypt_mc - 8*4) /\ + (\s. read PC s = word (pc + 0xa8c) /\ //LENGTH aes256_xts_encrypt_mc - 8*4 = 0xaac - 0x8 * 0x4 byte_list_at (aes256_xts_encrypt pt_in (val len) iv key1_lst key2_lst) ctxt_p len s ) (MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI,, @@ -5246,7 +5245,7 @@ let AES_XTS_ENCRYPT_LT_4BLOCK_CORRECT = time prove( read(memory :> bytes128 iv_p) s = iv /\ set_key_schedule s key1_p k1_0 k1_1 k1_2 k1_3 k1_4 k1_5 k1_6 k1_7 k1_8 k1_9 k1_10 k1_11 k1_12 k1_13 k1_14 /\ set_key_schedule s key2_p k2_0 k2_1 k2_2 k2_3 k2_4 k2_5 k2_6 k2_7 k2_8 k2_9 k2_10 k2_11 k2_12 k2_13 k2_14) - (\s. read PC s = word (pc + LENGTH aes256_xts_encrypt_mc - 8*4) /\ + (\s. read PC s = word (pc + 0xa8c) /\ //LENGTH aes256_xts_encrypt_mc - 8*4 = 0xaac - 0x8 * 0x4 byte_list_at (aes256_xts_encrypt pt_in (val len) iv key1_lst key2_lst) ctxt_p len s ) (MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI,, @@ -5419,7 +5418,7 @@ let AES_XTS_ENCRYPT_LT_5BLOCK_CORRECT = time prove( read(memory :> bytes128 iv_p) s = iv /\ set_key_schedule s key1_p k1_0 k1_1 k1_2 k1_3 k1_4 k1_5 k1_6 k1_7 k1_8 k1_9 k1_10 k1_11 k1_12 k1_13 k1_14 /\ set_key_schedule s key2_p k2_0 k2_1 k2_2 k2_3 k2_4 k2_5 k2_6 k2_7 k2_8 k2_9 k2_10 k2_11 k2_12 k2_13 k2_14) - (\s. read PC s = word (pc + LENGTH aes256_xts_encrypt_mc - 8*4) /\ + (\s. read PC s = word (pc + 0xa8c) /\ //LENGTH aes256_xts_encrypt_mc - 8*4 = 0xaac - 0x8 * 0x4 byte_list_at (aes256_xts_encrypt pt_in (val len) iv key1_lst key2_lst) ctxt_p len s ) (MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI,, @@ -5576,7 +5575,6 @@ void aes_hw_xts_encrypt(const uint8_t *in, uint8_t *out, size_t length, const AES_KEY *key1, const AES_KEY *key2, const uint8_t iv[16]) *) - let AES256_XTS_ENCRYPT_CORRECT = prove( `!ptxt_p ctxt_p len key1_p key2_p iv_p pt_in iv @@ -5601,7 +5599,7 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( set_key_schedule s key2_p k2_0 k2_1 k2_2 k2_3 k2_4 k2_5 k2_6 k2_7 k2_8 k2_9 k2_10 k2_11 k2_12 k2_13 k2_14 ) // postcondition - (\s. read PC s = word (pc + LENGTH aes256_xts_encrypt_mc - 8*4) /\ + (\s. read PC s = word (pc + 0xa8c) /\ //LENGTH aes256_xts_encrypt_mc - 8*4 = 0xaac - 0x8 * 0x4 byte_list_at (aes256_xts_encrypt pt_in (val len) iv [k1_0; k1_1; k1_2; k1_3; k1_4; k1_5; k1_6; k1_7; k1_8; k1_9; k1_10; k1_11; k1_12; k1_13; k1_14] [k2_0; k2_1; k2_2; k2_3; k2_4; k2_5; k2_6; k2_7; k2_8; k2_9; k2_10; k2_11; k2_12; k2_13; k2_14]) @@ -7894,7 +7892,51 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( ASM_SIMP_TAC[] );; - +let AES256_XTS_ENCRYPT_SUBROUTINE_CORRECT = prove( + `!ptxt_p ctxt_p len key1_p key2_p iv_p + pt_in iv + k1_0 k1_1 k1_2 k1_3 k1_4 k1_5 k1_6 k1_7 k1_8 k1_9 k1_10 k1_11 k1_12 k1_13 k1_14 + k2_0 k2_1 k2_2 k2_3 k2_4 k2_5 k2_6 k2_7 k2_8 k2_9 k2_10 k2_11 k2_12 k2_13 k2_14 + pc stackpointer returnaddress. + aligned 16 stackpointer /\ + PAIRWISE nonoverlapping + [(word_sub stackpointer (word 96), 96); + (word pc, LENGTH aes256_xts_encrypt_mc); + (ptxt_p, val len); + (ctxt_p, val len); + (iv_p, 16); + (key1_p, 244); + (key2_p, 244)] /\ + val len >= 16 /\ val len <= 2 EXP 24 /\ LENGTH pt_in = val len + ==> ensures arm + (\s. aligned_bytes_loaded s (word pc) aes256_xts_encrypt_mc /\ + read PC s = word pc /\ + read SP s = stackpointer /\ + read X30 s = returnaddress /\ + C_ARGUMENTS [ptxt_p; ctxt_p; len; key1_p; key2_p; iv_p] s /\ + byte_list_at pt_in ptxt_p len s /\ + read(memory :> bytes128 iv_p) s = iv /\ + set_key_schedule s key1_p k1_0 k1_1 k1_2 k1_3 k1_4 k1_5 k1_6 k1_7 k1_8 k1_9 k1_10 k1_11 k1_12 k1_13 k1_14 /\ + set_key_schedule s key2_p k2_0 k2_1 k2_2 k2_3 k2_4 k2_5 k2_6 k2_7 k2_8 k2_9 k2_10 k2_11 k2_12 k2_13 k2_14 ) + (\s. read PC s = returnaddress /\ + byte_list_at (aes256_xts_encrypt pt_in (val len) iv + [k1_0; k1_1; k1_2; k1_3; k1_4; k1_5; k1_6; k1_7; k1_8; k1_9; k1_10; k1_11; k1_12; k1_13; k1_14] + [k2_0; k2_1; k2_2; k2_3; k2_4; k2_5; k2_6; k2_7; k2_8; k2_9; k2_10; k2_11; k2_12; k2_13; k2_14]) + ctxt_p len s ) + (MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI,, + MAYCHANGE [memory :> bytes(ctxt_p, val len); + memory :> bytes(word_sub stackpointer (word 96), 96)])`, + REWRITE_TAC[byte_list_at; set_key_schedule; + fst AES256_XTS_ENCRYPT_EXEC] THEN + (* ~pre_post_nsteps:(7,7): 7 instructions before and after program body + for handling stack. + 96: the byte size occupied on stack for storing preserved registers *) + ARM_ADD_RETURN_STACK_TAC + ~pre_post_nsteps:(7,7) AES256_XTS_ENCRYPT_EXEC + (REWRITE_RULE[byte_list_at; set_key_schedule; + fst AES256_XTS_ENCRYPT_EXEC] AES256_XTS_ENCRYPT_CORRECT) + `[X19; X20; X21; X22; D8; D9; D10; D11; D12; D13; D14; D15]` 96 + );; (* val it : goalstack = 1 subgoal (1 total) From f13b9fe1a4720b1c0d69e9c3bc30ead093313ef1 Mon Sep 17 00:00:00 2001 From: Nevine Ebeid Date: Wed, 10 Dec 2025 18:09:21 -0500 Subject: [PATCH 109/132] Adjust 1-block proof to the code after the W19 fix. --- arm/proofs/aes-xts-armv8.ml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arm/proofs/aes-xts-armv8.ml b/arm/proofs/aes-xts-armv8.ml index 2ff66a220..de939f943 100644 --- a/arm/proofs/aes-xts-armv8.ml +++ b/arm/proofs/aes-xts-armv8.ml @@ -906,7 +906,7 @@ let AES256_ENCRYPT_ONE_BLOCK_CORRECT = prove( ANTS_TAC THENL [ASM_REWRITE_TAC[] THEN AESENC_TAC; DISCH_TAC] THEN (* Simulate until the one-block input encryption until before XORing the iv with the output. *) - ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (66--106) THEN + ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (66--107) THEN (* FIRST_X_ASSUM(MP_TAC o MATCH_MP (MESON[] `read Q0 s = a ==> !a'. a = a' ==> read Q0 s = a'`)) THEN *) FIRST_X_ASSUM(MP_TAC o SPEC @@ -922,10 +922,10 @@ let AES256_ENCRYPT_ONE_BLOCK_CORRECT = prove( ANTS_TAC THENL [ASM_REWRITE_TAC[] THEN AESENC_TAC; DISCH_TAC] THEN (* XOR the tweak with the output in Q0 *) - ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (107--107) THEN + ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (108--108) THEN (* Write it to the ciphertext output *) - ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (108--108) THEN + ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (109--109) THEN FIRST_X_ASSUM(MP_TAC o SPEC `(aes256_xts_encrypt_1block (pt_in:int128) @@ -938,7 +938,7 @@ let AES256_ENCRYPT_ONE_BLOCK_CORRECT = prove( ==> read (memory :> bytes128 ctxt_p) s = a'`)) THEN ANTS_TAC THENL [ASM_REWRITE_TAC[] THEN AESXTS_ENC_ONE_BLOCK_TAC; DISCH_TAC] THEN - ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (109--119) THEN + ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (110--120) THEN ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN From 9f8f791d1d47b11dda516ede97ee1b6538029338 Mon Sep 17 00:00:00 2001 From: Nevine Ebeid Date: Wed, 10 Dec 2025 18:10:30 -0500 Subject: [PATCH 110/132] Use the updated tactic name. --- arm/proofs/aes-xts-armv8.ml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arm/proofs/aes-xts-armv8.ml b/arm/proofs/aes-xts-armv8.ml index de939f943..2fcafa664 100644 --- a/arm/proofs/aes-xts-armv8.ml +++ b/arm/proofs/aes-xts-armv8.ml @@ -4453,7 +4453,7 @@ let CIPHER_STEALING_ENC_CORRECT = time prove( MP_TAC (SPECL [`(SUB_LIST (0,0x10) pt_in):byte list`; `(SUB_LIST (0x10,val (tail_len:int64)) pt_in):byte list`; `val (tail_len:int64)`; `iv:int128`; `0:num`; `key1_lst:int128 list`; - `key2_lst:int128 list`] LENGTH_OF_FST_OF_CIPHER_STEALING) THEN + `key2_lst:int128 list`] LENGTH_OF_FST_OF_ENC_CIPHER_STEALING) THEN DISCH_TAC THEN IMP_REWRITE_TAC[SUB_LIST_APPEND_LEFT; ARITH_RULE `16 <= 16`] THEN @@ -4486,7 +4486,7 @@ let CIPHER_STEALING_ENC_CORRECT = time prove( MP_TAC (SPECL [`(SUB_LIST (l1_curr_blocks * 0x10,0x10) pt_in):byte list`; `(SUB_LIST ((l1_curr_blocks + 0x1) * 0x10,val (tail_len:int64)) pt_in):byte list`; `val (tail_len:int64)`; `iv:int128`; `l1_curr_blocks:num`; `key1_lst:int128 list`; - `key2_lst:int128 list`] LENGTH_OF_FST_OF_CIPHER_STEALING) THEN + `key2_lst:int128 list`] LENGTH_OF_FST_OF_ENC_CIPHER_STEALING) THEN DISCH_TAC THEN IMP_REWRITE_TAC[SUB_LIST_APPEND_LEFT; ARITH_RULE `16 <= 16`] THEN @@ -4558,7 +4558,7 @@ let CIPHER_STEALING_ENC_CORRECT = time prove( MP_TAC (SPECL [`(SUB_LIST (0,0x10) pt_in):byte list`; `(SUB_LIST (0x10,val (tail_len:int64)) pt_in):byte list`; `val (tail_len:int64)`; `iv:int128`; `0:num`; `key1_lst:int128 list`; - `key2_lst:int128 list`] LENGTH_OF_FST_OF_CIPHER_STEALING) THEN + `key2_lst:int128 list`] LENGTH_OF_FST_OF_ENC_CIPHER_STEALING) THEN REWRITE_TAC[GSYM (ASSUME `0x10 * 0x0 = l1_curr_len`)] THEN DISCH_TAC THEN IMP_REWRITE_TAC[SUB_LIST_APPEND_RIGHT_LEMMA; ARITH_RULE `16 <= 16`] THEN @@ -4594,7 +4594,7 @@ let CIPHER_STEALING_ENC_CORRECT = time prove( MP_TAC (SPECL [`(SUB_LIST (l1_curr_blocks * 0x10,0x10) pt_in):byte list`; `(SUB_LIST ((l1_curr_blocks + 0x1) * 0x10,val (tail_len:int64)) pt_in):byte list`; `val (tail_len:int64)`; `iv:int128`; `l1_curr_blocks:num`; `key1_lst:int128 list`; - `key2_lst:int128 list`] LENGTH_OF_FST_OF_CIPHER_STEALING) THEN + `key2_lst:int128 list`] LENGTH_OF_FST_OF_ENC_CIPHER_STEALING) THEN DISCH_TAC THEN IMP_REWRITE_TAC[SUB_LIST_APPEND_RIGHT_LEMMA; ARITH_RULE `16 <= 16`] THEN From 706738634114718dd28d4a771d068edebce0d76c Mon Sep 17 00:00:00 2001 From: Yan Peng Date: Fri, 19 Dec 2025 12:46:02 -0800 Subject: [PATCH 111/132] Clean up Makefiles and rename files to keep consistency --- arm/Makefile | 9 +- arm/aes-xts/Makefile | 4 +- arm/aes-xts/aes-xts-armv8.txt | 685 ------------------ ...es-xts-armv8.S => aes_xts_encrypt_armv8.S} | 0 .../{aes-xts-armv8.ml => aes_xts_encrypt.ml} | 117 +-- 5 files changed, 10 insertions(+), 805 deletions(-) delete mode 100644 arm/aes-xts/aes-xts-armv8.txt rename arm/aes-xts/{aes-xts-armv8.S => aes_xts_encrypt_armv8.S} (100%) rename arm/proofs/{aes-xts-armv8.ml => aes_xts_encrypt.ml} (98%) diff --git a/arm/Makefile b/arm/Makefile index 950088fe5..794bbe919 100644 --- a/arm/Makefile +++ b/arm/Makefile @@ -403,10 +403,13 @@ UNOPT_OBJ = p256/unopt/bignum_montmul_p256_base.o \ fastmul/unopt/bignum_mul_8_16_base.o \ fastmul/unopt/bignum_sqr_8_16_base.o -AES_XTS_OBJ = aes-xts/aes-xts-armv8.o +AES_XTS_OBJ = aes-xts/aes256_encrypt.o \ + aes-xts/aes256_decrypt.o \ + aes-xts/aes_xts_encrypt_armv8.o \ + aes-xts/aes_xts_decrypt_armv8.o -# OBJ = $(POINT_OBJ) $(BIGNUM_OBJ) $(AES_XTS_OBJ) -OBJ = $(AES_XTS_OBJ) +OBJ = $(POINT_OBJ) $(BIGNUM_OBJ) $(AES_XTS_OBJ) +# OBJ = $(AES_XTS_OBJ) # Tutorial assembly files diff --git a/arm/aes-xts/Makefile b/arm/aes-xts/Makefile index fd79d8372..14d4f0b21 100644 --- a/arm/aes-xts/Makefile +++ b/arm/aes-xts/Makefile @@ -30,8 +30,8 @@ endif OBJ = aes256_encrypt.o \ aes256_decrypt.o \ - aes_xts_decrypt_armv8.o \ - aes-xts-armv8.o + aes_xts_encrypt_armv8.o \ + aes_xts_decrypt_armv8.o %.o : %.S ; $(CC) -E -I../../include $< | $(GAS) -o $@ - diff --git a/arm/aes-xts/aes-xts-armv8.txt b/arm/aes-xts/aes-xts-armv8.txt deleted file mode 100644 index f1c626320..000000000 --- a/arm/aes-xts/aes-xts-armv8.txt +++ /dev/null @@ -1,685 +0,0 @@ -[ - 0xd10183ff; (* arm_SUB SP SP (rvalue (word 0x60)) *) - 0x6d0227e8; (* arm_STP D8 D9 SP (Immediate_Offset (iword (&0x20))) *) - 0x6d032fea; (* arm_STP D10 D11 SP (Immediate_Offset (iword (&0x30))) *) - 0x6d0437ec; (* arm_STP D12 D13 SP (Immediate_Offset (iword (&0x40))) *) - 0x6d053fee; (* arm_STP D14 D15 SP (Immediate_Offset (iword (&0x50))) *) - 0xa90053f3; (* arm_STP X19 X20 SP (Immediate_Offset (iword (&0x0))) *) - 0xa9015bf5; (* arm_STP X21 X22 SP (Immediate_Offset (iword (&0x10))) *) - 0xf100405f; (* arm_CMP X2 (rvalue (word 0x10)) *) - 0x5400536b; (* arm_BLT (word 0xa6c) *) - 0xd503201f; (* arm_NOP *) - 0xd503201f; (* arm_NOP *) - 0xd503201f; (* arm_NOP *) - 0x92400c55; (* arm_AND X21 X2 (rvalue (word 0xf)) *) - 0x927cec42; (* arm_AND X2 X2 (rvalue (word 0xfffffffffffffff0)) *) - 0xb940f086; (* arm_LDR W6 X4 (Immediate_Offset (word 0xf0)) *) - 0x4cdf7880; (* arm_LDR Q0 X4 (Postimmediate_Offset (word 0x10)) *) - 0x4c4070a6; (* arm_LDR Q6 X5 No_Offset *) - 0x510008c6; (* arm_SUB W6 W6 (rvalue (word 0x2)) *) - 0x4cdf7881; (* arm_LDR Q1 X4 (Postimmediate_Offset (word 0x10)) *) - 0x4e284806; (* arm_AESE Q6 Q0 *) - 0x4e2868c6; (* arm_AESMC Q6 Q6 *) - 0x4cdf7880; (* arm_LDR Q0 X4 (Postimmediate_Offset (word 0x10)) *) - 0x710008c6; (* arm_SUBS W6 W6 (rvalue (word 0x2)) *) - 0x4e284826; (* arm_AESE Q6 Q1 *) - 0x4e2868c6; (* arm_AESMC Q6 Q6 *) - 0x4cdf7881; (* arm_LDR Q1 X4 (Postimmediate_Offset (word 0x10)) *) - 0x54ffff2c; (* arm_BGT (word 0x1fffe4) *) - 0x4e284806; (* arm_AESE Q6 Q0 *) - 0x4e2868c6; (* arm_AESMC Q6 Q6 *) - 0x4c407880; (* arm_LDR Q0 X4 No_Offset *) - 0x4e284826; (* arm_AESE Q6 Q1 *) - 0x6e201cc6; (* arm_EOR_VEC Q6 Q6 Q0 0x80 *) - 0xaa0303e7; (* arm_MOV X7 X3 *) - 0x4cdfa8f0; (* arm_LDP Q16 Q17 X7 (Postimmediate_Offset (word 0x20)) *) - 0x4cdfa8ec; (* arm_LDP Q12 Q13 X7 (Postimmediate_Offset (word 0x20)) *) - 0x4cdfa8ee; (* arm_LDP Q14 Q15 X7 (Postimmediate_Offset (word 0x20)) *) - 0x4cdfa8e4; (* arm_LDP Q4 Q5 X7 (Postimmediate_Offset (word 0x20)) *) - 0x4cdfa8f2; (* arm_LDP Q18 Q19 X7 (Postimmediate_Offset (word 0x20)) *) - 0x4cdfa8f4; (* arm_LDP Q20 Q21 X7 (Postimmediate_Offset (word 0x20)) *) - 0x4cdfa8f6; (* arm_LDP Q22 Q23 X7 (Postimmediate_Offset (word 0x20)) *) - 0x4c4078e7; (* arm_LDR Q7 X7 No_Offset *) - 0x528010f3; (* arm_MOV W19 (rvalue (word 0x87)) *) - 0xf100805f; (* arm_CMP X2 (rvalue (word 0x20)) *) - 0x54004463; (* arm_BCC (word 0x88c) *) - 0x9e6600c9; (* arm_FMOV_FtoI X9 Q6 0x0 0x40 *) - 0x9eae00ca; (* arm_FMOV_FtoI X10 Q6 0x1 0x40 *) - 0x93ca8156; (* arm_ROR X22 X10 0x20 *) - 0x93c9fd4a; (* arm_EXTR X10 X10 X9 0x3f *) - 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 0x1f) *) - 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 0x1) *) - 0x9e670128; (* arm_FMOV_ItoF Q8 X9 0x0 *) - 0x9eaf0148; (* arm_FMOV_ItoF Q8 X10 0x1 *) - 0xf100c05f; (* arm_CMP X2 (rvalue (word 0x30)) *) - 0x54003a43; (* arm_BCC (word 0x748) *) - 0x93ca8156; (* arm_ROR X22 X10 0x20 *) - 0x93c9fd4a; (* arm_EXTR X10 X10 X9 0x3f *) - 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 0x1f) *) - 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 0x1) *) - 0x9e670129; (* arm_FMOV_ItoF Q9 X9 0x0 *) - 0x9eaf0149; (* arm_FMOV_ItoF Q9 X10 0x1 *) - 0xf101005f; (* arm_CMP X2 (rvalue (word 0x40)) *) - 0x54002c63; (* arm_BCC (word 0x58c) *) - 0x93ca8156; (* arm_ROR X22 X10 0x20 *) - 0x93c9fd4a; (* arm_EXTR X10 X10 X9 0x3f *) - 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 0x1f) *) - 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 0x1) *) - 0x9e67012a; (* arm_FMOV_ItoF Q10 X9 0x0 *) - 0x9eaf014a; (* arm_FMOV_ItoF Q10 X10 0x1 *) - 0xf101405f; (* arm_CMP X2 (rvalue (word 0x50)) *) - 0x54001a63; (* arm_BCC (word 0x34c) *) - 0x93ca8156; (* arm_ROR X22 X10 0x20 *) - 0x93c9fd4a; (* arm_EXTR X10 X10 X9 0x3f *) - 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 0x1f) *) - 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 0x1) *) - 0x9e67012b; (* arm_FMOV_ItoF Q11 X9 0x0 *) - 0x9eaf014b; (* arm_FMOV_ItoF Q11 X10 0x1 *) - 0xb202e7e8; (* arm_MOV X8 (rvalue (word 0xcccccccccccccccc)) *) - 0xf29999a8; (* arm_MOVK X8 (word 0xcccd) 0x0 *) - 0x9bc87c48; (* arm_UMULH X8 X2 X8 *) - 0xd346fd08; (* arm_LSR X8 X8 0x6 *) - 0xacc28400; (* arm_LDP Q0 Q1 X0 (Postimmediate_Offset (iword (&0x50))) *) - 0xad7ee418; (* arm_LDP Q24 Q25 X0 (Immediate_Offset (iword (-- &0x30))) *) - 0x3cdf001a; (* arm_LDR Q26 X0 (Immediate_Offset (word 0xfffffffffffffff0)) *) - 0x6e261c00; (* arm_EOR_VEC Q0 Q0 Q6 0x80 *) - 0x6e281c21; (* arm_EOR_VEC Q1 Q1 Q8 0x80 *) - 0x6e291f18; (* arm_EOR_VEC Q24 Q24 Q9 0x80 *) - 0x6e2a1f39; (* arm_EOR_VEC Q25 Q25 Q10 0x80 *) - 0x6e2b1f5a; (* arm_EOR_VEC Q26 Q26 Q11 0x80 *) - 0x4e284a00; (* arm_AESE Q0 Q16 *) - 0x4e286800; (* arm_AESMC Q0 Q0 *) - 0x4e284a01; (* arm_AESE Q1 Q16 *) - 0x4e286821; (* arm_AESMC Q1 Q1 *) - 0x4e284a18; (* arm_AESE Q24 Q16 *) - 0x4e286b18; (* arm_AESMC Q24 Q24 *) - 0x4e284a19; (* arm_AESE Q25 Q16 *) - 0x4e286b39; (* arm_AESMC Q25 Q25 *) - 0x4e284a1a; (* arm_AESE Q26 Q16 *) - 0x4e286b5a; (* arm_AESMC Q26 Q26 *) - 0x4e284a20; (* arm_AESE Q0 Q17 *) - 0x4e286800; (* arm_AESMC Q0 Q0 *) - 0x4e284a21; (* arm_AESE Q1 Q17 *) - 0x4e286821; (* arm_AESMC Q1 Q1 *) - 0x4e284a38; (* arm_AESE Q24 Q17 *) - 0x4e286b18; (* arm_AESMC Q24 Q24 *) - 0x4e284a39; (* arm_AESE Q25 Q17 *) - 0x4e286b39; (* arm_AESMC Q25 Q25 *) - 0x4e284a3a; (* arm_AESE Q26 Q17 *) - 0x4e286b5a; (* arm_AESMC Q26 Q26 *) - 0x4e284980; (* arm_AESE Q0 Q12 *) - 0x4e286800; (* arm_AESMC Q0 Q0 *) - 0x4e284981; (* arm_AESE Q1 Q12 *) - 0x4e286821; (* arm_AESMC Q1 Q1 *) - 0x4e284998; (* arm_AESE Q24 Q12 *) - 0x4e286b18; (* arm_AESMC Q24 Q24 *) - 0x4e284999; (* arm_AESE Q25 Q12 *) - 0x4e286b39; (* arm_AESMC Q25 Q25 *) - 0x4e28499a; (* arm_AESE Q26 Q12 *) - 0x4e286b5a; (* arm_AESMC Q26 Q26 *) - 0x4e2849a0; (* arm_AESE Q0 Q13 *) - 0x4e286800; (* arm_AESMC Q0 Q0 *) - 0x4e2849a1; (* arm_AESE Q1 Q13 *) - 0x4e286821; (* arm_AESMC Q1 Q1 *) - 0x4e2849b8; (* arm_AESE Q24 Q13 *) - 0x4e286b18; (* arm_AESMC Q24 Q24 *) - 0x4e2849b9; (* arm_AESE Q25 Q13 *) - 0x4e286b39; (* arm_AESMC Q25 Q25 *) - 0x4e2849ba; (* arm_AESE Q26 Q13 *) - 0x4e286b5a; (* arm_AESMC Q26 Q26 *) - 0x4e2849c0; (* arm_AESE Q0 Q14 *) - 0x4e286800; (* arm_AESMC Q0 Q0 *) - 0x4e2849c1; (* arm_AESE Q1 Q14 *) - 0x4e286821; (* arm_AESMC Q1 Q1 *) - 0x4e2849d8; (* arm_AESE Q24 Q14 *) - 0x4e286b18; (* arm_AESMC Q24 Q24 *) - 0x4e2849d9; (* arm_AESE Q25 Q14 *) - 0x4e286b39; (* arm_AESMC Q25 Q25 *) - 0x4e2849da; (* arm_AESE Q26 Q14 *) - 0x4e286b5a; (* arm_AESMC Q26 Q26 *) - 0x4e2849e0; (* arm_AESE Q0 Q15 *) - 0x4e286800; (* arm_AESMC Q0 Q0 *) - 0x4e2849e1; (* arm_AESE Q1 Q15 *) - 0x4e286821; (* arm_AESMC Q1 Q1 *) - 0x4e2849f8; (* arm_AESE Q24 Q15 *) - 0x4e286b18; (* arm_AESMC Q24 Q24 *) - 0x4e2849f9; (* arm_AESE Q25 Q15 *) - 0x4e286b39; (* arm_AESMC Q25 Q25 *) - 0x4e2849fa; (* arm_AESE Q26 Q15 *) - 0x4e286b5a; (* arm_AESMC Q26 Q26 *) - 0x4e284880; (* arm_AESE Q0 Q4 *) - 0x4e286800; (* arm_AESMC Q0 Q0 *) - 0x4e284881; (* arm_AESE Q1 Q4 *) - 0x4e286821; (* arm_AESMC Q1 Q1 *) - 0x4e284898; (* arm_AESE Q24 Q4 *) - 0x4e286b18; (* arm_AESMC Q24 Q24 *) - 0x4e284899; (* arm_AESE Q25 Q4 *) - 0x4e286b39; (* arm_AESMC Q25 Q25 *) - 0x4e28489a; (* arm_AESE Q26 Q4 *) - 0x4e286b5a; (* arm_AESMC Q26 Q26 *) - 0x4e2848a0; (* arm_AESE Q0 Q5 *) - 0x4e286800; (* arm_AESMC Q0 Q0 *) - 0x4e2848a1; (* arm_AESE Q1 Q5 *) - 0x4e286821; (* arm_AESMC Q1 Q1 *) - 0x4e2848b8; (* arm_AESE Q24 Q5 *) - 0x4e286b18; (* arm_AESMC Q24 Q24 *) - 0x4e2848b9; (* arm_AESE Q25 Q5 *) - 0x4e286b39; (* arm_AESMC Q25 Q25 *) - 0x4e2848ba; (* arm_AESE Q26 Q5 *) - 0x4e286b5a; (* arm_AESMC Q26 Q26 *) - 0x4e284a40; (* arm_AESE Q0 Q18 *) - 0x4e286800; (* arm_AESMC Q0 Q0 *) - 0x4e284a41; (* arm_AESE Q1 Q18 *) - 0x4e286821; (* arm_AESMC Q1 Q1 *) - 0x4e284a58; (* arm_AESE Q24 Q18 *) - 0x4e286b18; (* arm_AESMC Q24 Q24 *) - 0x4e284a59; (* arm_AESE Q25 Q18 *) - 0x4e286b39; (* arm_AESMC Q25 Q25 *) - 0x4e284a5a; (* arm_AESE Q26 Q18 *) - 0x4e286b5a; (* arm_AESMC Q26 Q26 *) - 0x4e284a60; (* arm_AESE Q0 Q19 *) - 0x4e286800; (* arm_AESMC Q0 Q0 *) - 0x4e284a61; (* arm_AESE Q1 Q19 *) - 0x4e286821; (* arm_AESMC Q1 Q1 *) - 0x4e284a78; (* arm_AESE Q24 Q19 *) - 0x4e286b18; (* arm_AESMC Q24 Q24 *) - 0x4e284a79; (* arm_AESE Q25 Q19 *) - 0x4e286b39; (* arm_AESMC Q25 Q25 *) - 0x4e284a7a; (* arm_AESE Q26 Q19 *) - 0x4e286b5a; (* arm_AESMC Q26 Q26 *) - 0x4e284a80; (* arm_AESE Q0 Q20 *) - 0x4e286800; (* arm_AESMC Q0 Q0 *) - 0x4e284a81; (* arm_AESE Q1 Q20 *) - 0x4e286821; (* arm_AESMC Q1 Q1 *) - 0x4e284a98; (* arm_AESE Q24 Q20 *) - 0x4e286b18; (* arm_AESMC Q24 Q24 *) - 0x4e284a99; (* arm_AESE Q25 Q20 *) - 0x4e286b39; (* arm_AESMC Q25 Q25 *) - 0x4e284a9a; (* arm_AESE Q26 Q20 *) - 0x4e286b5a; (* arm_AESMC Q26 Q26 *) - 0x4e284aa0; (* arm_AESE Q0 Q21 *) - 0x4e286800; (* arm_AESMC Q0 Q0 *) - 0x4e284aa1; (* arm_AESE Q1 Q21 *) - 0x4e286821; (* arm_AESMC Q1 Q1 *) - 0x4e284ab8; (* arm_AESE Q24 Q21 *) - 0x4e286b18; (* arm_AESMC Q24 Q24 *) - 0x4e284ab9; (* arm_AESE Q25 Q21 *) - 0x4e286b39; (* arm_AESMC Q25 Q25 *) - 0x4e284aba; (* arm_AESE Q26 Q21 *) - 0x4e286b5a; (* arm_AESMC Q26 Q26 *) - 0x4e284ac0; (* arm_AESE Q0 Q22 *) - 0x4e286800; (* arm_AESMC Q0 Q0 *) - 0x4e284ac1; (* arm_AESE Q1 Q22 *) - 0x4e286821; (* arm_AESMC Q1 Q1 *) - 0x4e284ad8; (* arm_AESE Q24 Q22 *) - 0x4e286b18; (* arm_AESMC Q24 Q24 *) - 0x4e284ad9; (* arm_AESE Q25 Q22 *) - 0x4e286b39; (* arm_AESMC Q25 Q25 *) - 0x4e284ada; (* arm_AESE Q26 Q22 *) - 0x4e286b5a; (* arm_AESMC Q26 Q26 *) - 0x4e284ae0; (* arm_AESE Q0 Q23 *) - 0x4e284ae1; (* arm_AESE Q1 Q23 *) - 0x4e284af8; (* arm_AESE Q24 Q23 *) - 0x4e284af9; (* arm_AESE Q25 Q23 *) - 0x4e284afa; (* arm_AESE Q26 Q23 *) - 0x6e271c00; (* arm_EOR_VEC Q0 Q0 Q7 0x80 *) - 0x6e261c00; (* arm_EOR_VEC Q0 Q0 Q6 0x80 *) - 0x93ca8156; (* arm_ROR X22 X10 0x20 *) - 0x93c9fd4a; (* arm_EXTR X10 X10 X9 0x3f *) - 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 0x1f) *) - 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 0x1) *) - 0x9e670126; (* arm_FMOV_ItoF Q6 X9 0x0 *) - 0x9eaf0146; (* arm_FMOV_ItoF Q6 X10 0x1 *) - 0x6e271c21; (* arm_EOR_VEC Q1 Q1 Q7 0x80 *) - 0x6e281c21; (* arm_EOR_VEC Q1 Q1 Q8 0x80 *) - 0x93ca8156; (* arm_ROR X22 X10 0x20 *) - 0x93c9fd4a; (* arm_EXTR X10 X10 X9 0x3f *) - 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 0x1f) *) - 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 0x1) *) - 0x9e670128; (* arm_FMOV_ItoF Q8 X9 0x0 *) - 0x9eaf0148; (* arm_FMOV_ItoF Q8 X10 0x1 *) - 0x6e271f18; (* arm_EOR_VEC Q24 Q24 Q7 0x80 *) - 0x6e291f18; (* arm_EOR_VEC Q24 Q24 Q9 0x80 *) - 0x93ca8156; (* arm_ROR X22 X10 0x20 *) - 0x93c9fd4a; (* arm_EXTR X10 X10 X9 0x3f *) - 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 0x1f) *) - 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 0x1) *) - 0x9e670129; (* arm_FMOV_ItoF Q9 X9 0x0 *) - 0x9eaf0149; (* arm_FMOV_ItoF Q9 X10 0x1 *) - 0x6e271f39; (* arm_EOR_VEC Q25 Q25 Q7 0x80 *) - 0x6e2a1f39; (* arm_EOR_VEC Q25 Q25 Q10 0x80 *) - 0x93ca8156; (* arm_ROR X22 X10 0x20 *) - 0x93c9fd4a; (* arm_EXTR X10 X10 X9 0x3f *) - 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 0x1f) *) - 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 0x1) *) - 0x9e67012a; (* arm_FMOV_ItoF Q10 X9 0x0 *) - 0x9eaf014a; (* arm_FMOV_ItoF Q10 X10 0x1 *) - 0x6e271f5a; (* arm_EOR_VEC Q26 Q26 Q7 0x80 *) - 0x6e2b1f5a; (* arm_EOR_VEC Q26 Q26 Q11 0x80 *) - 0x93ca8156; (* arm_ROR X22 X10 0x20 *) - 0x93c9fd4a; (* arm_EXTR X10 X10 X9 0x3f *) - 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 0x1f) *) - 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 0x1) *) - 0x9e67012b; (* arm_FMOV_ItoF Q11 X9 0x0 *) - 0x9eaf014b; (* arm_FMOV_ItoF Q11 X10 0x1 *) - 0xac828420; (* arm_STP Q0 Q1 X1 (Postimmediate_Offset (iword (&0x50))) *) - 0xad3ee438; (* arm_STP Q24 Q25 X1 (Immediate_Offset (iword (-- &0x30))) *) - 0x3c9f003a; (* arm_STR Q26 X1 (Immediate_Offset (word 0xfffffffffffffff0)) *) - 0xd1014042; (* arm_SUB X2 X2 (rvalue (word 0x50)) *) - 0xf1000508; (* arm_SUBS X8 X8 (rvalue (word 0x1)) *) - 0xb5ffe888; (* arm_CBNZ X8 (word 0x1ffd10) *) - 0xf101005f; (* arm_CMP X2 (rvalue (word 0x40)) *) - 0x54000140; (* arm_BEQ (word 0x28) *) - 0xf100c05f; (* arm_CMP X2 (rvalue (word 0x30)) *) - 0x54001200; (* arm_BEQ (word 0x240) *) - 0xf100805f; (* arm_CMP X2 (rvalue (word 0x20)) *) - 0x54001ea0; (* arm_BEQ (word 0x3d4) *) - 0xf100405f; (* arm_CMP X2 (rvalue (word 0x10)) *) - 0x54002740; (* arm_BEQ (word 0x4e8) *) - 0x14000163; (* arm_B (word 0x58c) *) - 0xd503201f; (* arm_NOP *) - 0xd503201f; (* arm_NOP *) - 0x4cdf7000; (* arm_LDR Q0 X0 (Postimmediate_Offset (word 0x10)) *) - 0x4cdf7001; (* arm_LDR Q1 X0 (Postimmediate_Offset (word 0x10)) *) - 0x4cdf7018; (* arm_LDR Q24 X0 (Postimmediate_Offset (word 0x10)) *) - 0x4cdf7019; (* arm_LDR Q25 X0 (Postimmediate_Offset (word 0x10)) *) - 0x6e261c00; (* arm_EOR_VEC Q0 Q0 Q6 0x80 *) - 0x6e281c21; (* arm_EOR_VEC Q1 Q1 Q8 0x80 *) - 0x6e291f18; (* arm_EOR_VEC Q24 Q24 Q9 0x80 *) - 0x6e2a1f39; (* arm_EOR_VEC Q25 Q25 Q10 0x80 *) - 0x4e284a00; (* arm_AESE Q0 Q16 *) - 0x4e286800; (* arm_AESMC Q0 Q0 *) - 0x4e284a01; (* arm_AESE Q1 Q16 *) - 0x4e286821; (* arm_AESMC Q1 Q1 *) - 0x4e284a18; (* arm_AESE Q24 Q16 *) - 0x4e286b18; (* arm_AESMC Q24 Q24 *) - 0x4e284a19; (* arm_AESE Q25 Q16 *) - 0x4e286b39; (* arm_AESMC Q25 Q25 *) - 0x4e284a20; (* arm_AESE Q0 Q17 *) - 0x4e286800; (* arm_AESMC Q0 Q0 *) - 0x4e284a21; (* arm_AESE Q1 Q17 *) - 0x4e286821; (* arm_AESMC Q1 Q1 *) - 0x4e284a38; (* arm_AESE Q24 Q17 *) - 0x4e286b18; (* arm_AESMC Q24 Q24 *) - 0x4e284a39; (* arm_AESE Q25 Q17 *) - 0x4e286b39; (* arm_AESMC Q25 Q25 *) - 0x4e284980; (* arm_AESE Q0 Q12 *) - 0x4e286800; (* arm_AESMC Q0 Q0 *) - 0x4e284981; (* arm_AESE Q1 Q12 *) - 0x4e286821; (* arm_AESMC Q1 Q1 *) - 0x4e284998; (* arm_AESE Q24 Q12 *) - 0x4e286b18; (* arm_AESMC Q24 Q24 *) - 0x4e284999; (* arm_AESE Q25 Q12 *) - 0x4e286b39; (* arm_AESMC Q25 Q25 *) - 0x4e2849a0; (* arm_AESE Q0 Q13 *) - 0x4e286800; (* arm_AESMC Q0 Q0 *) - 0x4e2849a1; (* arm_AESE Q1 Q13 *) - 0x4e286821; (* arm_AESMC Q1 Q1 *) - 0x4e2849b8; (* arm_AESE Q24 Q13 *) - 0x4e286b18; (* arm_AESMC Q24 Q24 *) - 0x4e2849b9; (* arm_AESE Q25 Q13 *) - 0x4e286b39; (* arm_AESMC Q25 Q25 *) - 0x4e2849c0; (* arm_AESE Q0 Q14 *) - 0x4e286800; (* arm_AESMC Q0 Q0 *) - 0x4e2849c1; (* arm_AESE Q1 Q14 *) - 0x4e286821; (* arm_AESMC Q1 Q1 *) - 0x4e2849d8; (* arm_AESE Q24 Q14 *) - 0x4e286b18; (* arm_AESMC Q24 Q24 *) - 0x4e2849d9; (* arm_AESE Q25 Q14 *) - 0x4e286b39; (* arm_AESMC Q25 Q25 *) - 0x4e2849e0; (* arm_AESE Q0 Q15 *) - 0x4e286800; (* arm_AESMC Q0 Q0 *) - 0x4e2849e1; (* arm_AESE Q1 Q15 *) - 0x4e286821; (* arm_AESMC Q1 Q1 *) - 0x4e2849f8; (* arm_AESE Q24 Q15 *) - 0x4e286b18; (* arm_AESMC Q24 Q24 *) - 0x4e2849f9; (* arm_AESE Q25 Q15 *) - 0x4e286b39; (* arm_AESMC Q25 Q25 *) - 0x4e284880; (* arm_AESE Q0 Q4 *) - 0x4e286800; (* arm_AESMC Q0 Q0 *) - 0x4e284881; (* arm_AESE Q1 Q4 *) - 0x4e286821; (* arm_AESMC Q1 Q1 *) - 0x4e284898; (* arm_AESE Q24 Q4 *) - 0x4e286b18; (* arm_AESMC Q24 Q24 *) - 0x4e284899; (* arm_AESE Q25 Q4 *) - 0x4e286b39; (* arm_AESMC Q25 Q25 *) - 0x4e2848a0; (* arm_AESE Q0 Q5 *) - 0x4e286800; (* arm_AESMC Q0 Q0 *) - 0x4e2848a1; (* arm_AESE Q1 Q5 *) - 0x4e286821; (* arm_AESMC Q1 Q1 *) - 0x4e2848b8; (* arm_AESE Q24 Q5 *) - 0x4e286b18; (* arm_AESMC Q24 Q24 *) - 0x4e2848b9; (* arm_AESE Q25 Q5 *) - 0x4e286b39; (* arm_AESMC Q25 Q25 *) - 0x4e284a40; (* arm_AESE Q0 Q18 *) - 0x4e286800; (* arm_AESMC Q0 Q0 *) - 0x4e284a41; (* arm_AESE Q1 Q18 *) - 0x4e286821; (* arm_AESMC Q1 Q1 *) - 0x4e284a58; (* arm_AESE Q24 Q18 *) - 0x4e286b18; (* arm_AESMC Q24 Q24 *) - 0x4e284a59; (* arm_AESE Q25 Q18 *) - 0x4e286b39; (* arm_AESMC Q25 Q25 *) - 0x4e284a60; (* arm_AESE Q0 Q19 *) - 0x4e286800; (* arm_AESMC Q0 Q0 *) - 0x4e284a61; (* arm_AESE Q1 Q19 *) - 0x4e286821; (* arm_AESMC Q1 Q1 *) - 0x4e284a78; (* arm_AESE Q24 Q19 *) - 0x4e286b18; (* arm_AESMC Q24 Q24 *) - 0x4e284a79; (* arm_AESE Q25 Q19 *) - 0x4e286b39; (* arm_AESMC Q25 Q25 *) - 0x4e284a80; (* arm_AESE Q0 Q20 *) - 0x4e286800; (* arm_AESMC Q0 Q0 *) - 0x4e284a81; (* arm_AESE Q1 Q20 *) - 0x4e286821; (* arm_AESMC Q1 Q1 *) - 0x4e284a98; (* arm_AESE Q24 Q20 *) - 0x4e286b18; (* arm_AESMC Q24 Q24 *) - 0x4e284a99; (* arm_AESE Q25 Q20 *) - 0x4e286b39; (* arm_AESMC Q25 Q25 *) - 0x4e284aa0; (* arm_AESE Q0 Q21 *) - 0x4e286800; (* arm_AESMC Q0 Q0 *) - 0x4e284aa1; (* arm_AESE Q1 Q21 *) - 0x4e286821; (* arm_AESMC Q1 Q1 *) - 0x4e284ab8; (* arm_AESE Q24 Q21 *) - 0x4e286b18; (* arm_AESMC Q24 Q24 *) - 0x4e284ab9; (* arm_AESE Q25 Q21 *) - 0x4e286b39; (* arm_AESMC Q25 Q25 *) - 0x4e284ac0; (* arm_AESE Q0 Q22 *) - 0x4e286800; (* arm_AESMC Q0 Q0 *) - 0x4e284ac1; (* arm_AESE Q1 Q22 *) - 0x4e286821; (* arm_AESMC Q1 Q1 *) - 0x4e284ad8; (* arm_AESE Q24 Q22 *) - 0x4e286b18; (* arm_AESMC Q24 Q24 *) - 0x4e284ad9; (* arm_AESE Q25 Q22 *) - 0x4e286b39; (* arm_AESMC Q25 Q25 *) - 0x4e284ae0; (* arm_AESE Q0 Q23 *) - 0x4e284ae1; (* arm_AESE Q1 Q23 *) - 0x4e284af8; (* arm_AESE Q24 Q23 *) - 0x4e284af9; (* arm_AESE Q25 Q23 *) - 0x6e271c00; (* arm_EOR_VEC Q0 Q0 Q7 0x80 *) - 0x6e261c00; (* arm_EOR_VEC Q0 Q0 Q6 0x80 *) - 0x6e271c21; (* arm_EOR_VEC Q1 Q1 Q7 0x80 *) - 0x6e281c21; (* arm_EOR_VEC Q1 Q1 Q8 0x80 *) - 0x6e271f18; (* arm_EOR_VEC Q24 Q24 Q7 0x80 *) - 0x6e291f18; (* arm_EOR_VEC Q24 Q24 Q9 0x80 *) - 0x6e271f39; (* arm_EOR_VEC Q25 Q25 Q7 0x80 *) - 0x6e2a1f39; (* arm_EOR_VEC Q25 Q25 Q10 0x80 *) - 0x4c9fa020; (* arm_STP Q0 Q1 X1 (Postimmediate_Offset (word 0x20)) *) - 0x4c9fa038; (* arm_STP Q24 Q25 X1 (Postimmediate_Offset (word 0x20)) *) - 0x9e660149; (* arm_FMOV_FtoI X9 Q10 0x0 0x40 *) - 0x9eae014a; (* arm_FMOV_FtoI X10 Q10 0x1 0x40 *) - 0x93ca8156; (* arm_ROR X22 X10 0x20 *) - 0x93c9fd4a; (* arm_EXTR X10 X10 X9 0x3f *) - 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 0x1f) *) - 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 0x1) *) - 0x9e670126; (* arm_FMOV_ItoF Q6 X9 0x0 *) - 0x9eaf0146; (* arm_FMOV_ItoF Q6 X10 0x1 *) - 0x140000da; (* arm_B (word 0x368) *) - 0xd503201f; (* arm_NOP *) - 0x4cdfa000; (* arm_LDP Q0 Q1 X0 (Postimmediate_Offset (word 0x20)) *) - 0x4cdf7018; (* arm_LDR Q24 X0 (Postimmediate_Offset (word 0x10)) *) - 0x6e261c00; (* arm_EOR_VEC Q0 Q0 Q6 0x80 *) - 0x6e281c21; (* arm_EOR_VEC Q1 Q1 Q8 0x80 *) - 0x6e291f18; (* arm_EOR_VEC Q24 Q24 Q9 0x80 *) - 0x4e284a00; (* arm_AESE Q0 Q16 *) - 0x4e286800; (* arm_AESMC Q0 Q0 *) - 0x4e284a01; (* arm_AESE Q1 Q16 *) - 0x4e286821; (* arm_AESMC Q1 Q1 *) - 0x4e284a18; (* arm_AESE Q24 Q16 *) - 0x4e286b18; (* arm_AESMC Q24 Q24 *) - 0x4e284a20; (* arm_AESE Q0 Q17 *) - 0x4e286800; (* arm_AESMC Q0 Q0 *) - 0x4e284a21; (* arm_AESE Q1 Q17 *) - 0x4e286821; (* arm_AESMC Q1 Q1 *) - 0x4e284a38; (* arm_AESE Q24 Q17 *) - 0x4e286b18; (* arm_AESMC Q24 Q24 *) - 0x4e284980; (* arm_AESE Q0 Q12 *) - 0x4e286800; (* arm_AESMC Q0 Q0 *) - 0x4e284981; (* arm_AESE Q1 Q12 *) - 0x4e286821; (* arm_AESMC Q1 Q1 *) - 0x4e284998; (* arm_AESE Q24 Q12 *) - 0x4e286b18; (* arm_AESMC Q24 Q24 *) - 0x4e2849a0; (* arm_AESE Q0 Q13 *) - 0x4e286800; (* arm_AESMC Q0 Q0 *) - 0x4e2849a1; (* arm_AESE Q1 Q13 *) - 0x4e286821; (* arm_AESMC Q1 Q1 *) - 0x4e2849b8; (* arm_AESE Q24 Q13 *) - 0x4e286b18; (* arm_AESMC Q24 Q24 *) - 0x4e2849c0; (* arm_AESE Q0 Q14 *) - 0x4e286800; (* arm_AESMC Q0 Q0 *) - 0x4e2849c1; (* arm_AESE Q1 Q14 *) - 0x4e286821; (* arm_AESMC Q1 Q1 *) - 0x4e2849d8; (* arm_AESE Q24 Q14 *) - 0x4e286b18; (* arm_AESMC Q24 Q24 *) - 0x4e2849e0; (* arm_AESE Q0 Q15 *) - 0x4e286800; (* arm_AESMC Q0 Q0 *) - 0x4e2849e1; (* arm_AESE Q1 Q15 *) - 0x4e286821; (* arm_AESMC Q1 Q1 *) - 0x4e2849f8; (* arm_AESE Q24 Q15 *) - 0x4e286b18; (* arm_AESMC Q24 Q24 *) - 0x4e284880; (* arm_AESE Q0 Q4 *) - 0x4e286800; (* arm_AESMC Q0 Q0 *) - 0x4e284881; (* arm_AESE Q1 Q4 *) - 0x4e286821; (* arm_AESMC Q1 Q1 *) - 0x4e284898; (* arm_AESE Q24 Q4 *) - 0x4e286b18; (* arm_AESMC Q24 Q24 *) - 0x4e2848a0; (* arm_AESE Q0 Q5 *) - 0x4e286800; (* arm_AESMC Q0 Q0 *) - 0x4e2848a1; (* arm_AESE Q1 Q5 *) - 0x4e286821; (* arm_AESMC Q1 Q1 *) - 0x4e2848b8; (* arm_AESE Q24 Q5 *) - 0x4e286b18; (* arm_AESMC Q24 Q24 *) - 0x4e284a40; (* arm_AESE Q0 Q18 *) - 0x4e286800; (* arm_AESMC Q0 Q0 *) - 0x4e284a41; (* arm_AESE Q1 Q18 *) - 0x4e286821; (* arm_AESMC Q1 Q1 *) - 0x4e284a58; (* arm_AESE Q24 Q18 *) - 0x4e286b18; (* arm_AESMC Q24 Q24 *) - 0x4e284a60; (* arm_AESE Q0 Q19 *) - 0x4e286800; (* arm_AESMC Q0 Q0 *) - 0x4e284a61; (* arm_AESE Q1 Q19 *) - 0x4e286821; (* arm_AESMC Q1 Q1 *) - 0x4e284a78; (* arm_AESE Q24 Q19 *) - 0x4e286b18; (* arm_AESMC Q24 Q24 *) - 0x4e284a80; (* arm_AESE Q0 Q20 *) - 0x4e286800; (* arm_AESMC Q0 Q0 *) - 0x4e284a81; (* arm_AESE Q1 Q20 *) - 0x4e286821; (* arm_AESMC Q1 Q1 *) - 0x4e284a98; (* arm_AESE Q24 Q20 *) - 0x4e286b18; (* arm_AESMC Q24 Q24 *) - 0x4e284aa0; (* arm_AESE Q0 Q21 *) - 0x4e286800; (* arm_AESMC Q0 Q0 *) - 0x4e284aa1; (* arm_AESE Q1 Q21 *) - 0x4e286821; (* arm_AESMC Q1 Q1 *) - 0x4e284ab8; (* arm_AESE Q24 Q21 *) - 0x4e286b18; (* arm_AESMC Q24 Q24 *) - 0x4e284ac0; (* arm_AESE Q0 Q22 *) - 0x4e286800; (* arm_AESMC Q0 Q0 *) - 0x4e284ac1; (* arm_AESE Q1 Q22 *) - 0x4e286821; (* arm_AESMC Q1 Q1 *) - 0x4e284ad8; (* arm_AESE Q24 Q22 *) - 0x4e286b18; (* arm_AESMC Q24 Q24 *) - 0x4e284ae0; (* arm_AESE Q0 Q23 *) - 0x4e284ae1; (* arm_AESE Q1 Q23 *) - 0x4e284af8; (* arm_AESE Q24 Q23 *) - 0x6e271c00; (* arm_EOR_VEC Q0 Q0 Q7 0x80 *) - 0x6e261c00; (* arm_EOR_VEC Q0 Q0 Q6 0x80 *) - 0x6e271c21; (* arm_EOR_VEC Q1 Q1 Q7 0x80 *) - 0x6e281c21; (* arm_EOR_VEC Q1 Q1 Q8 0x80 *) - 0x6e271f18; (* arm_EOR_VEC Q24 Q24 Q7 0x80 *) - 0x6e291f18; (* arm_EOR_VEC Q24 Q24 Q9 0x80 *) - 0x4c9fa020; (* arm_STP Q0 Q1 X1 (Postimmediate_Offset (word 0x20)) *) - 0x4c9f7038; (* arm_STR Q24 X1 (Postimmediate_Offset (word 0x10)) *) - 0x9e660129; (* arm_FMOV_FtoI X9 Q9 0x0 0x40 *) - 0x9eae012a; (* arm_FMOV_FtoI X10 Q9 0x1 0x40 *) - 0x93ca8156; (* arm_ROR X22 X10 0x20 *) - 0x93c9fd4a; (* arm_EXTR X10 X10 X9 0x3f *) - 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 0x1f) *) - 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 0x1) *) - 0x9e670126; (* arm_FMOV_ItoF Q6 X9 0x0 *) - 0x9eaf0146; (* arm_FMOV_ItoF Q6 X10 0x1 *) - 0x14000072; (* arm_B (word 0x1c8) *) - 0x4cdfa000; (* arm_LDP Q0 Q1 X0 (Postimmediate_Offset (word 0x20)) *) - 0x6e261c00; (* arm_EOR_VEC Q0 Q0 Q6 0x80 *) - 0x6e281c21; (* arm_EOR_VEC Q1 Q1 Q8 0x80 *) - 0x4e284a00; (* arm_AESE Q0 Q16 *) - 0x4e286800; (* arm_AESMC Q0 Q0 *) - 0x4e284a01; (* arm_AESE Q1 Q16 *) - 0x4e286821; (* arm_AESMC Q1 Q1 *) - 0x4e284a20; (* arm_AESE Q0 Q17 *) - 0x4e286800; (* arm_AESMC Q0 Q0 *) - 0x4e284a21; (* arm_AESE Q1 Q17 *) - 0x4e286821; (* arm_AESMC Q1 Q1 *) - 0x4e284980; (* arm_AESE Q0 Q12 *) - 0x4e286800; (* arm_AESMC Q0 Q0 *) - 0x4e284981; (* arm_AESE Q1 Q12 *) - 0x4e286821; (* arm_AESMC Q1 Q1 *) - 0x4e2849a0; (* arm_AESE Q0 Q13 *) - 0x4e286800; (* arm_AESMC Q0 Q0 *) - 0x4e2849a1; (* arm_AESE Q1 Q13 *) - 0x4e286821; (* arm_AESMC Q1 Q1 *) - 0x4e2849c0; (* arm_AESE Q0 Q14 *) - 0x4e286800; (* arm_AESMC Q0 Q0 *) - 0x4e2849c1; (* arm_AESE Q1 Q14 *) - 0x4e286821; (* arm_AESMC Q1 Q1 *) - 0x4e2849e0; (* arm_AESE Q0 Q15 *) - 0x4e286800; (* arm_AESMC Q0 Q0 *) - 0x4e2849e1; (* arm_AESE Q1 Q15 *) - 0x4e286821; (* arm_AESMC Q1 Q1 *) - 0x4e284880; (* arm_AESE Q0 Q4 *) - 0x4e286800; (* arm_AESMC Q0 Q0 *) - 0x4e284881; (* arm_AESE Q1 Q4 *) - 0x4e286821; (* arm_AESMC Q1 Q1 *) - 0x4e2848a0; (* arm_AESE Q0 Q5 *) - 0x4e286800; (* arm_AESMC Q0 Q0 *) - 0x4e2848a1; (* arm_AESE Q1 Q5 *) - 0x4e286821; (* arm_AESMC Q1 Q1 *) - 0x4e284a40; (* arm_AESE Q0 Q18 *) - 0x4e286800; (* arm_AESMC Q0 Q0 *) - 0x4e284a41; (* arm_AESE Q1 Q18 *) - 0x4e286821; (* arm_AESMC Q1 Q1 *) - 0x4e284a60; (* arm_AESE Q0 Q19 *) - 0x4e286800; (* arm_AESMC Q0 Q0 *) - 0x4e284a61; (* arm_AESE Q1 Q19 *) - 0x4e286821; (* arm_AESMC Q1 Q1 *) - 0x4e284a80; (* arm_AESE Q0 Q20 *) - 0x4e286800; (* arm_AESMC Q0 Q0 *) - 0x4e284a81; (* arm_AESE Q1 Q20 *) - 0x4e286821; (* arm_AESMC Q1 Q1 *) - 0x4e284aa0; (* arm_AESE Q0 Q21 *) - 0x4e286800; (* arm_AESMC Q0 Q0 *) - 0x4e284aa1; (* arm_AESE Q1 Q21 *) - 0x4e286821; (* arm_AESMC Q1 Q1 *) - 0x4e284ac0; (* arm_AESE Q0 Q22 *) - 0x4e286800; (* arm_AESMC Q0 Q0 *) - 0x4e284ac1; (* arm_AESE Q1 Q22 *) - 0x4e286821; (* arm_AESMC Q1 Q1 *) - 0x4e284ae0; (* arm_AESE Q0 Q23 *) - 0x4e284ae1; (* arm_AESE Q1 Q23 *) - 0x6e271c00; (* arm_EOR_VEC Q0 Q0 Q7 0x80 *) - 0x6e261c00; (* arm_EOR_VEC Q0 Q0 Q6 0x80 *) - 0x6e271c21; (* arm_EOR_VEC Q1 Q1 Q7 0x80 *) - 0x6e281c21; (* arm_EOR_VEC Q1 Q1 Q8 0x80 *) - 0x4c9fa020; (* arm_STP Q0 Q1 X1 (Postimmediate_Offset (word 0x20)) *) - 0x9e660109; (* arm_FMOV_FtoI X9 Q8 0x0 0x40 *) - 0x9eae010a; (* arm_FMOV_FtoI X10 Q8 0x1 0x40 *) - 0x93ca8156; (* arm_ROR X22 X10 0x20 *) - 0x93c9fd4a; (* arm_EXTR X10 X10 X9 0x3f *) - 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 0x1f) *) - 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 0x1) *) - 0x9e670126; (* arm_FMOV_ItoF Q6 X9 0x0 *) - 0x9eaf0146; (* arm_FMOV_ItoF Q6 X10 0x1 *) - 0x1400002b; (* arm_B (word 0xac) *) - 0x4cdf7000; (* arm_LDR Q0 X0 (Postimmediate_Offset (word 0x10)) *) - 0x6e261c00; (* arm_EOR_VEC Q0 Q0 Q6 0x80 *) - 0x4e284a00; (* arm_AESE Q0 Q16 *) - 0x4e286800; (* arm_AESMC Q0 Q0 *) - 0x4e284a20; (* arm_AESE Q0 Q17 *) - 0x4e286800; (* arm_AESMC Q0 Q0 *) - 0x4e284980; (* arm_AESE Q0 Q12 *) - 0x4e286800; (* arm_AESMC Q0 Q0 *) - 0x4e2849a0; (* arm_AESE Q0 Q13 *) - 0x4e286800; (* arm_AESMC Q0 Q0 *) - 0x4e2849c0; (* arm_AESE Q0 Q14 *) - 0x4e286800; (* arm_AESMC Q0 Q0 *) - 0x4e2849e0; (* arm_AESE Q0 Q15 *) - 0x4e286800; (* arm_AESMC Q0 Q0 *) - 0x4e284880; (* arm_AESE Q0 Q4 *) - 0x4e286800; (* arm_AESMC Q0 Q0 *) - 0x4e2848a0; (* arm_AESE Q0 Q5 *) - 0x4e286800; (* arm_AESMC Q0 Q0 *) - 0x4e284a40; (* arm_AESE Q0 Q18 *) - 0x4e286800; (* arm_AESMC Q0 Q0 *) - 0x4e284a60; (* arm_AESE Q0 Q19 *) - 0x4e286800; (* arm_AESMC Q0 Q0 *) - 0x4e284a80; (* arm_AESE Q0 Q20 *) - 0x4e286800; (* arm_AESMC Q0 Q0 *) - 0x4e284aa0; (* arm_AESE Q0 Q21 *) - 0x4e286800; (* arm_AESMC Q0 Q0 *) - 0x4e284ac0; (* arm_AESE Q0 Q22 *) - 0x4e286800; (* arm_AESMC Q0 Q0 *) - 0x4e284ae0; (* arm_AESE Q0 Q23 *) - 0x6e271c00; (* arm_EOR_VEC Q0 Q0 Q7 0x80 *) - 0x6e261c00; (* arm_EOR_VEC Q0 Q0 Q6 0x80 *) - 0x4c9f7020; (* arm_STR Q0 X1 (Postimmediate_Offset (word 0x10)) *) - 0x9e6600c9; (* arm_FMOV_FtoI X9 Q6 0x0 0x40 *) - 0x9eae00ca; (* arm_FMOV_FtoI X10 Q6 0x1 0x40 *) - 0x93ca8156; (* arm_ROR X22 X10 0x20 *) - 0x93c9fd4a; (* arm_EXTR X10 X10 X9 0x3f *) - 0x0a967e6b; (* arm_AND W11 W19 (Shiftedreg W22 ASR 0x1f) *) - 0xca090569; (* arm_EOR X9 X11 (Shiftedreg X9 LSL 0x1) *) - 0x9e670126; (* arm_FMOV_ItoF Q6 X9 0x0 *) - 0x9eaf0146; (* arm_FMOV_ItoF Q6 X10 0x1 *) - 0x14000002; (* arm_B (word 0x8) *) - 0xd503201f; (* arm_NOP *) - 0xf2400ebf; (* arm_TST X21 (rvalue (word 0xf)) *) - 0x54000540; (* arm_BEQ (word 0xa8) *) - 0xaa0003f4; (* arm_MOV X20 X0 *) - 0xaa0103ed; (* arm_MOV X13 X1 *) - 0xd1004021; (* arm_SUB X1 X1 (rvalue (word 0x10)) *) - 0xf10006b5; (* arm_SUBS X21 X21 (rvalue (word 0x1)) *) - 0x3875682f; (* arm_LDRB W15 X1 (Register_Offset X21) *) - 0x38756a8e; (* arm_LDRB W14 X20 (Register_Offset X21) *) - 0x383569af; (* arm_STRB W15 X13 (Register_Offset X21) *) - 0x3835682e; (* arm_STRB W14 X1 (Register_Offset X21) *) - 0x54ffff6c; (* arm_BGT (word 0x1fffec) *) - 0x4c40703a; (* arm_LDR Q26 X1 No_Offset *) - 0x6e261f5a; (* arm_EOR_VEC Q26 Q26 Q6 0x80 *) - 0x4e284a1a; (* arm_AESE Q26 Q16 *) - 0x4e286b5a; (* arm_AESMC Q26 Q26 *) - 0x4e284a3a; (* arm_AESE Q26 Q17 *) - 0x4e286b5a; (* arm_AESMC Q26 Q26 *) - 0x4e28499a; (* arm_AESE Q26 Q12 *) - 0x4e286b5a; (* arm_AESMC Q26 Q26 *) - 0x4e2849ba; (* arm_AESE Q26 Q13 *) - 0x4e286b5a; (* arm_AESMC Q26 Q26 *) - 0x4e2849da; (* arm_AESE Q26 Q14 *) - 0x4e286b5a; (* arm_AESMC Q26 Q26 *) - 0x4e2849fa; (* arm_AESE Q26 Q15 *) - 0x4e286b5a; (* arm_AESMC Q26 Q26 *) - 0x4e28489a; (* arm_AESE Q26 Q4 *) - 0x4e286b5a; (* arm_AESMC Q26 Q26 *) - 0x4e2848ba; (* arm_AESE Q26 Q5 *) - 0x4e286b5a; (* arm_AESMC Q26 Q26 *) - 0x4e284a5a; (* arm_AESE Q26 Q18 *) - 0x4e286b5a; (* arm_AESMC Q26 Q26 *) - 0x4e284a7a; (* arm_AESE Q26 Q19 *) - 0x4e286b5a; (* arm_AESMC Q26 Q26 *) - 0x4e284a9a; (* arm_AESE Q26 Q20 *) - 0x4e286b5a; (* arm_AESMC Q26 Q26 *) - 0x4e284aba; (* arm_AESE Q26 Q21 *) - 0x4e286b5a; (* arm_AESMC Q26 Q26 *) - 0x4e284ada; (* arm_AESE Q26 Q22 *) - 0x4e286b5a; (* arm_AESMC Q26 Q26 *) - 0x4e284afa; (* arm_AESE Q26 Q23 *) - 0x6e271f5a; (* arm_EOR_VEC Q26 Q26 Q7 0x80 *) - 0x6e261f5a; (* arm_EOR_VEC Q26 Q26 Q6 0x80 *) - 0x4c00703a; (* arm_STR Q26 X1 No_Offset *) - 0xa94053f3; (* arm_LDP X19 X20 SP (Immediate_Offset (iword (&0x0))) *) - 0xa9415bf5; (* arm_LDP X21 X22 SP (Immediate_Offset (iword (&0x10))) *) - 0x6d4227e8; (* arm_LDP D8 D9 SP (Immediate_Offset (iword (&0x20))) *) - 0x6d432fea; (* arm_LDP D10 D11 SP (Immediate_Offset (iword (&0x30))) *) - 0x6d4437ec; (* arm_LDP D12 D13 SP (Immediate_Offset (iword (&0x40))) *) - 0x6d453fee; (* arm_LDP D14 D15 SP (Immediate_Offset (iword (&0x50))) *) - 0x910183ff; (* arm_ADD SP SP (rvalue (word 0x60)) *) - 0xd65f03c0 (* arm_RET X30 *) -];; diff --git a/arm/aes-xts/aes-xts-armv8.S b/arm/aes-xts/aes_xts_encrypt_armv8.S similarity index 100% rename from arm/aes-xts/aes-xts-armv8.S rename to arm/aes-xts/aes_xts_encrypt_armv8.S diff --git a/arm/proofs/aes-xts-armv8.ml b/arm/proofs/aes_xts_encrypt.ml similarity index 98% rename from arm/proofs/aes-xts-armv8.ml rename to arm/proofs/aes_xts_encrypt.ml index 2fcafa664..a1cdfcc0f 100644 --- a/arm/proofs/aes-xts-armv8.ml +++ b/arm/proofs/aes_xts_encrypt.ml @@ -12,22 +12,8 @@ needs "arm/proofs/aes_xts_encrypt_spec.ml";; arm_print_log := true;; components_print_log := true;; -(* print_literal_from_elf "arm/aes-xts/aes-xts-armv8.o";; *) -(* save_literal_from_elf "arm/aes-xts/aes-xts-armv8.txt" "arm/aes-xts/aes-xts-armv8.o";; *) - -(* let aes_xts_armv8 = define_assert_from_elf "aes_xts_armv8" "arm/aes-xts/aes-xts-armv8.o" ..*) - -(* Missing instructions that were added in PR#211 -4c4070a6 10: 4c4070a6 ld1.16b { v6 }, [x5] -4cdfa87c 5c: 4cdfa87c ld1.4s { v28, v29 }, [x3], #32 -d503201f f8: d503201f nop -4cc87000 198: 4cc87000 ld1.16b { v0 }, [x0], x8 -4c40a870 19c: 4c40a870 ld1.4s { v16, v17 }, [x3] -3875682f 818: 3875682f ldrb w15, [x1, x21] -Also LDP/STP pre-index and post-index -*) - -let aes256_xts_encrypt_mc = define_assert_from_elf "aes256_xts_encrypt_mc" "arm/aes-xts/aes-xts-armv8.o" +(* print_literal_from_elf "arm/aes-xts/aes_xts_encrypt_armv8.o";; *) +let aes256_xts_encrypt_mc = define_assert_from_elf "aes256_xts_encrypt_mc" "arm/aes-xts/aes_xts_encrypt_armv8.o" [ 0xd10183ff; (* arm_SUB SP SP (rvalue (word 0x60)) *) 0x6d0227e8; (* arm_STP D8 D9 SP (Immediate_Offset (iword (&0x20))) *) @@ -7937,102 +7923,3 @@ let AES256_XTS_ENCRYPT_SUBROUTINE_CORRECT = prove( fst AES256_XTS_ENCRYPT_EXEC] AES256_XTS_ENCRYPT_CORRECT) `[X19; X20; X21; X22; D8; D9; D10; D11; D12; D13; D14; D15]` 96 );; -(* -val it : goalstack = 1 subgoal (1 total) - - 0 [`nonoverlapping_modulo (0x2 EXP 0x40) (pc,0xaac) (val ptxt_p,val len)`] - 1 [`nonoverlapping_modulo (0x2 EXP 0x40) (pc,0xaac) (val ctxt_p,val len)`] - 2 [`nonoverlapping_modulo (0x2 EXP 0x40) (pc,0xaac) (val key1_p,0xf4)`] - 3 [`nonoverlapping_modulo (0x2 EXP 0x40) (pc,0xaac) (val key2_p,0xf4)`] - 4 [`nonoverlapping_modulo (0x2 EXP 0x40) (val ptxt_p,val len) - (val ctxt_p,val len)`] - 5 [`nonoverlapping_modulo (0x2 EXP 0x40) (val ptxt_p,val len) - (val key1_p,0xf4)`] - 6 [`nonoverlapping_modulo (0x2 EXP 0x40) (val ptxt_p,val len) - (val key2_p,0xf4)`] - 7 [`nonoverlapping_modulo (0x2 EXP 0x40) (val ctxt_p,val len) - (val key1_p,0xf4)`] - 8 [`nonoverlapping_modulo (0x2 EXP 0x40) (val ctxt_p,val len) - (val key2_p,0xf4)`] - 9 [`nonoverlapping_modulo (0x2 EXP 0x40) (val key1_p,0xf4) - (val key2_p,0xf4)`] - 10 [`val len >= 0x10`] - 11 [`val len <= 0x2 EXP 0x18`] - 12 [`LENGTH pt_in = val len`] - 13 [`word_add tail_len len_full_blocks = len`] - 14 [`word_and len (word 0xfffffffffffffff0) = len_full_blocks`] - 15 [`word (val len_full_blocks DIV 0x50) = num_5blocks`] - 16 [`word_and len (word 0xf) = tail_len`] - 17 [`[k1_0; k1_1; k1_2; k1_3; k1_4; k1_5; k1_6; k1_7; k1_8; k1_9; k1_10; - k1_11; k1_12; k1_13; k1_14] = - key1_lst`] - 18 [`[k2_0; k2_1; k2_2; k2_3; k2_4; k2_5; k2_6; k2_7; k2_8; k2_9; k2_10; - k2_11; k2_12; k2_13; k2_14] = - key2_lst`] - 19 [`~(val len < 0x50)`] - 20 [`~(val len_full_blocks < 0x50)`] - 21 [`val len_full_blocks <= 0x2 EXP 0x18`] - 22 [`0x0 < val num_5blocks`] - 23 [`val len_full_blocks <= val len`] - 24 [`val num_5blocks * 0x50 <= val len_full_blocks`] - -`ensures arm - (\s. - aligned_bytes_loaded s (word pc) aes256_xts_encrypt_mc /\ - read PC s = word (pc + 0x9e0) /\ - read X0 s = - word_add ptxt_p (word (acc_len num_5blocks len_full_blocks)) /\ - read X1 s = - word_add ctxt_p (word (acc_len num_5blocks len_full_blocks)) /\ - read X21 s = tail_len /\ - read Q6 s = - calculate_tweak (acc_blocks num_5blocks len_full_blocks true) iv - key2_lst /\ - read X19 s = word 0x87 /\ - read X10 s = - word_subword - (calculate_tweak (acc_blocks num_5blocks len_full_blocks false) iv - key2_lst) - (0x40,0x40) /\ - read X9 s = - word_zx - (calculate_tweak (acc_blocks num_5blocks len_full_blocks false) iv - key2_lst) /\ - read Q16 s = k1_0 /\ - read Q17 s = k1_1 /\ - read Q12 s = k1_2 /\ - read Q13 s = k1_3 /\ - read Q14 s = k1_4 /\ - read Q15 s = k1_5 /\ - read Q4 s = k1_6 /\ - read Q5 s = k1_7 /\ - read Q18 s = k1_8 /\ - read Q19 s = k1_9 /\ - read Q20 s = k1_10 /\ - read Q21 s = k1_11 /\ - read Q22 s = k1_12 /\ - read Q23 s = k1_13 /\ - read Q7 s = k1_14 /\ - byte_list_at pt_in ptxt_p len s /\ - byte_list_at - (aes256_xts_encrypt pt_in (acc_len num_5blocks len_full_blocks) iv - key1_lst - key2_lst) - ctxt_p - (word (acc_len num_5blocks len_full_blocks)) - s) - (\s. - read PC s = word (pc + 0xaac - 0x8 * 0x4) /\ - (forall i. - i < val len - ==> read (memory :> bytes8 (word_add ctxt_p (word i))) s = - EL i (aes256_xts_encrypt pt_in (val len) iv key1_lst key2_lst))) - (MAYCHANGE - [PC; X0; X1; X2; X4; X6; X7; X8; X9; X10; X11; X19; X20; X21; X22] ,, - MAYCHANGE - [Q0; Q1; Q4; Q5; Q6; Q7; Q8; Q9; Q10; Q11; Q12; Q13; Q14; Q15; Q16; Q17; - Q18; Q19; Q20; Q21; Q22; Q23; Q24; Q25; Q26] ,, - MAYCHANGE [NF; ZF; CF; VF] ,, - MAYCHANGE [events] ,, - MAYCHANGE [memory :> bytes (ctxt_p,val len)])` -*) From 9d646700e2eaaf6eb99916aec80137baea79967b Mon Sep 17 00:00:00 2001 From: Yan Peng Date: Fri, 19 Dec 2025 12:55:39 -0800 Subject: [PATCH 112/132] Refactor the structure of files --- arm/proofs/aes-xts.ml | 8 - arm/proofs/aes_decrypt.ml | 9 +- arm/proofs/aes_encrypt.ml | 12 +- arm/proofs/aes_xts_decrypt.ml | 3724 ++++------------- arm/proofs/aes_xts_encrypt.ml | 3389 +++------------ arm/proofs/base.ml | 2 +- arm/proofs/{ => utils}/aes.ml | 0 arm/proofs/{ => utils}/aes_decrypt_spec.ml | 11 +- arm/proofs/{ => utils}/aes_encrypt_spec.ml | 11 +- arm/proofs/utils/aes_xts_common.ml | 2443 +++++++++++ .../{ => utils}/aes_xts_decrypt_spec.ml | 12 +- .../{ => utils}/aes_xts_encrypt_spec.ml | 9 +- 12 files changed, 3807 insertions(+), 5823 deletions(-) delete mode 100644 arm/proofs/aes-xts.ml rename arm/proofs/{ => utils}/aes.ml (100%) rename arm/proofs/{ => utils}/aes_decrypt_spec.ml (95%) rename arm/proofs/{ => utils}/aes_encrypt_spec.ml (96%) create mode 100644 arm/proofs/utils/aes_xts_common.ml rename arm/proofs/{ => utils}/aes_xts_decrypt_spec.ml (98%) rename arm/proofs/{ => utils}/aes_xts_encrypt_spec.ml (99%) diff --git a/arm/proofs/aes-xts.ml b/arm/proofs/aes-xts.ml deleted file mode 100644 index 8a245be7a..000000000 --- a/arm/proofs/aes-xts.ml +++ /dev/null @@ -1,8 +0,0 @@ -(* - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT-0 - *) - -needs "arm/proofs/base.ml";; - -print_literal_from_elf "arm/aes-xts/aes-xts-armv8.o";; diff --git a/arm/proofs/aes_decrypt.ml b/arm/proofs/aes_decrypt.ml index 4d96fb2ea..213e306d7 100644 --- a/arm/proofs/aes_decrypt.ml +++ b/arm/proofs/aes_decrypt.ml @@ -3,14 +3,10 @@ * SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT-0 *) -use_file_raise_failure := true;; -arm_print_log := true;; - needs "arm/proofs/base.ml";; -loadt "arm/proofs/aes_decrypt_spec.ml";; - -print_literal_from_elf "arm/aes-xts/aes256_decrypt.o";; +needs "arm/proofs/utils/aes_decrypt_spec.ml";; +(* print_literal_from_elf "arm/aes-xts/aes256_decrypt.o";; *) let aes256_decrypt_mc = define_assert_from_elf "aes256_decrypt_mc" "arm/aes-xts/aes256_decrypt.o" [ 0xb940f046; (* arm_LDR W6 X2 (Immediate_Offset (word 0xf0)) *) @@ -36,7 +32,6 @@ let aes256_decrypt_mc = define_assert_from_elf "aes256_decrypt_mc" "arm/aes-xts/ let AES256_DECRYPT_EXEC = ARM_MK_EXEC_RULE aes256_decrypt_mc;; -(* TODO: Could this be better? read(memory :> bytes(key, 240) = all_k) *) let AES256_DECRYPT_CORRECT = prove( `!plaintext ciphertext key ib k0 k1 k2 k3 k4 k5 k6 k7 k8 k9 k10 k11 k12 k13 k14 pc. nonoverlapping (word pc,LENGTH aes256_decrypt_mc) (plaintext,16) diff --git a/arm/proofs/aes_encrypt.ml b/arm/proofs/aes_encrypt.ml index 8b961859d..0daaf069f 100644 --- a/arm/proofs/aes_encrypt.ml +++ b/arm/proofs/aes_encrypt.ml @@ -1,8 +1,12 @@ -needs "arm/proofs/base.ml";; -needs "arm/proofs/aes_encrypt_spec.ml";; +(* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT-0 + *) -print_literal_from_elf "arm/aes-xts/aes256_encrypt.o";; +needs "arm/proofs/base.ml";; +needs "arm/proofs/utils/aes_encrypt_spec.ml";; +(* print_literal_from_elf "arm/aes-xts/aes256_encrypt.o";; *) let aes256_encrypt_mc = define_assert_from_elf "aes256_encrypt_mc" "arm/aes-xts/aes256_encrypt.o" [ 0xb940f046; (* arm_LDR W6 X2 (Immediate_Offset (word 240)) *) @@ -28,8 +32,6 @@ let aes256_encrypt_mc = define_assert_from_elf "aes256_encrypt_mc" "arm/aes-xts/ let AES256_ENCRYPT_EXEC = ARM_MK_EXEC_RULE aes256_encrypt_mc;; -(* TODO: Could this be better? read(memory :> bytes(key, 240) = all_k) *) - let AES256_ENCRYPT_CORRECT = prove( `!ciphertext plaintext key ib k0 k1 k2 k3 k4 k5 k6 k7 k8 k9 k10 k11 k12 k13 k14 pc. nonoverlapping (word pc,LENGTH aes256_encrypt_mc) (ciphertext,16) diff --git a/arm/proofs/aes_xts_decrypt.ml b/arm/proofs/aes_xts_decrypt.ml index 81decffeb..a091ea6a9 100644 --- a/arm/proofs/aes_xts_decrypt.ml +++ b/arm/proofs/aes_xts_decrypt.ml @@ -2,13 +2,9 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT-0 *) - use_file_raise_failure := true;; -arm_print_log := true;; -components_print_log := true;; -needs "arm/proofs/base.ml";; -loadt "arm/proofs/aes_xts_decrypt_spec.ml";; +needs "arm/proofs/utils/aes_xts_common.ml";; (* print_literal_from_elf "arm/aes-xts/aes_xts_decrypt_armv8.o";; *) let aes_xts_decrypt_mc = define_assert_from_elf "aes_xts_decrypt_mc" "arm/aes-xts/aes_xts_decrypt_armv8.o" @@ -751,118 +747,6 @@ let aes_xts_decrypt_mc = define_assert_from_elf "aes_xts_decrypt_mc" "arm/aes-xt let AES_XTS_DECRYPT_EXEC = ARM_MK_EXEC_RULE aes_xts_decrypt_mc;; -(** Definitions **) - -let set_key_schedule = new_definition - `set_key_schedule (s:armstate) (key_ptr:int64) (k0:int128) - (k1:int128) (k2:int128) (k3:int128) (k4:int128) (k5:int128) - (k6:int128) (k7:int128) (k8:int128) (k9:int128) (ka:int128) - (kb:int128) (kc:int128) (kd:int128) (ke:int128) : bool = - (read(memory :> bytes128 key_ptr) s = k0 /\ - read(memory :> bytes128 (word_add key_ptr (word 16))) s = k1 /\ - read(memory :> bytes128 (word_add key_ptr (word 32))) s = k2 /\ - read(memory :> bytes128 (word_add key_ptr (word 48))) s = k3 /\ - read(memory :> bytes128 (word_add key_ptr (word 64))) s = k4 /\ - read(memory :> bytes128 (word_add key_ptr (word 80))) s = k5 /\ - read(memory :> bytes128 (word_add key_ptr (word 96))) s = k6 /\ - read(memory :> bytes128 (word_add key_ptr (word 112))) s = k7 /\ - read(memory :> bytes128 (word_add key_ptr (word 128))) s = k8 /\ - read(memory :> bytes128 (word_add key_ptr (word 144))) s = k9 /\ - read(memory :> bytes128 (word_add key_ptr (word 160))) s = ka /\ - read(memory :> bytes128 (word_add key_ptr (word 176))) s = kb /\ - read(memory :> bytes128 (word_add key_ptr (word 192))) s = kc /\ - read(memory :> bytes128 (word_add key_ptr (word 208))) s = kd /\ - read(memory :> bytes128 (word_add key_ptr (word 224))) s = ke /\ - read(memory :> bytes32 (word_add key_ptr (word 240))) s = word 14)`;; - -(** Tactics **) - -let AESENC_TAC = - REWRITE_TAC [aes256_encrypt] THEN - REWRITE_TAC EL_15_128_CLAUSES THEN - REWRITE_TAC [aes256_encrypt_round] THEN - CONV_TAC(TOP_DEPTH_CONV let_CONV) THEN - REWRITE_TAC [aese;aesmc] THEN - GEN_REWRITE_TAC LAND_CONV [WORD_XOR_SYM] THEN - REFL_TAC;; - -let AESDEC_TAC = - REWRITE_TAC [aes256_decrypt] THEN - REWRITE_TAC EL_15_128_CLAUSES THEN - CONV_TAC(TOP_DEPTH_CONV let_CONV) THEN - REWRITE_TAC [aes256_decrypt_round] THEN - CONV_TAC(TOP_DEPTH_CONV let_CONV) THEN - REWRITE_TAC [aesd;aesimc] THEN - (* NOTE: BITBLAST_TAC couldn't handle this goal *) - GEN_REWRITE_TAC LAND_CONV [WORD_XOR_SYM] THEN - AP_THM_TAC THEN AP_TERM_TAC THEN - GEN_REWRITE_TAC LAND_CONV [WORD_XOR_SYM] THEN - AP_THM_TAC THEN AP_TERM_TAC THEN AP_TERM_TAC THEN AP_TERM_TAC THEN - REPLICATE_TAC 13 (AP_THM_TAC THEN (REPLICATE_TAC 4 AP_TERM_TAC)) THEN - AP_THM_TAC THEN AP_TERM_TAC THEN - GEN_REWRITE_TAC LAND_CONV [WORD_XOR_SYM] THEN REFL_TAC;; - -let TWEAK_UPDATE_CONV = - let ADD_SUC_1 = ARITH_RULE `!n. n + 1 = SUC(n)` in - let ADD_SUC_2 = ARITH_RULE `!n. n + 2 = SUC(n + 1)` in - let ADD_SUC_3 = ARITH_RULE `!n. n + 3 = SUC(n + 2)` in - let ADD_SUC_4 = ARITH_RULE `!n. n + 4 = SUC(n + 3)` in - let ADD_SUC_5 = ARITH_RULE `!n. n + 5 = SUC(n + 4)` in - let ADD_SUC_6 = ARITH_RULE `!n. n + 6 = SUC(n + 5)` in - let ADD_SUC_7 = ARITH_RULE `!n. n + 7 = SUC(n + 6)` in - let ADD_SUC_8 = ARITH_RULE `!n. n + 8 = SUC(n + 7)` in - let ADD_SUC_9 = ARITH_RULE `!n. n + 9 = SUC(n + 8)` in - NUM_REDUCE_CONV THENC - RATOR_CONV (LAND_CONV (num_CONV ORELSEC - FIRST_CONV - [ CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_1]); - CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_2]); - CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_3]); - CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_4]); - CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_5]); - CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_6]); - CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_7]); - CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_8]); - CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_9]);])) THENC - REWRITE_CONV [CONJUNCT2 calculate_tweak] THENC - GF_128_MULT_BY_PRIMITIVE_CONV;; - -let TWEAK_TAC reg ind indm1 = - let lower_term = subst [ind,`ind:num`] `(word_zx:int128->int64) (calculate_tweak ind iv key2)` in - let upper_term = subst [ind,`ind:num`] `(word_subword:int128->num#num->int64) (calculate_tweak ind iv key2) (64,64)` in - let full_term = subst [ind,`ind:num`] `calculate_tweak ind iv key2` in - let full_lemma = subst [reg,`reg:(armstate,int128)component`] `read (reg:(armstate,int128)component) (s:armstate) = a ==> !a'. a = a' ==> read reg s = a'` in - let abbrev_term = subst [indm1,`indm1:num`] `tweak_pre:int128 = (calculate_tweak indm1 iv key2)` in - FIRST_X_ASSUM(MP_TAC o SPEC lower_term - o MATCH_MP (MESON[] `read X9 s = a ==> !a'. a = a' ==> read X9 s = a'`)) THEN - ANTS_TAC THENL [CONV_TAC (RAND_CONV (RAND_CONV TWEAK_UPDATE_CONV)) THEN - ABBREV_TAC abbrev_term THEN - BITBLAST_TAC; DISCH_TAC] THEN - FIRST_X_ASSUM(MP_TAC o SPEC upper_term - o MATCH_MP (MESON[] `read X10 s = a ==> !a'. a = a' ==> read X10 s = a'`)) THEN - ANTS_TAC THENL [CONV_TAC (RAND_CONV (RATOR_CONV (RAND_CONV TWEAK_UPDATE_CONV))) THEN - ABBREV_TAC abbrev_term THEN - BITBLAST_TAC; DISCH_TAC] THEN - FIRST_X_ASSUM(MP_TAC o SPEC full_term - o MATCH_MP (MESON[] full_lemma)) THEN - ANTS_TAC THENL [CONV_TAC (RAND_CONV TWEAK_UPDATE_CONV) THEN - ABBREV_TAC abbrev_term THEN - BITBLAST_TAC; DISCH_TAC];; - -let XTSDEC_TAC reg ind ind_tweak = - let tm = subst [ind, `ind:num`; ind_tweak, `ind_tweak:num`] - `aes256_xts_decrypt_round (bytes_to_int128 (SUB_LIST (ind,0x10) (ct:byte list))) - (calculate_tweak ind_tweak iv key2) key1` in - let lemma = subst [reg, `reg:(armstate,int128)component`] - `read (reg:(armstate,int128)component) (s:armstate) = a ==> !a'. a = a' ==> read reg s = a'` in - FIRST_X_ASSUM(MP_TAC o SPEC tm o MATCH_MP (MESON[] lemma)) THEN - ANTS_TAC THENL - [ EXPAND_TAC "key1" THEN - CONV_TAC (RAND_CONV ( - REWRITE_CONV [aes256_xts_decrypt_round] THENC - DEPTH_CONV let_CONV)) THEN - AESDEC_TAC; DISCH_TAC ];; - (** Proof **) (* let AES_XTS_DECRYPT_1BLOCK_CORRECT = prove( @@ -924,2421 +808,731 @@ let AES_XTS_DECRYPT_1BLOCK_CORRECT = prove( );; *) -(*******************************************) -(* Full proof *) - -(* byte_list_at is adapted from Amanda's code at - https://github.com/amanda-zx/s2n-bignum/blob/ed25519/arm/sha512/utils.ml *) -let byte_list_at = define - `byte_list_at (m : byte list) (m_p : int64) (len: int64) s = - ! i. i < val len ==> read (memory :> bytes8(word_add m_p (word i))) s = EL i m`;; - -let word_split_lemma = prove( - `!len:int64. word_add (word_and len (word 0xf)) - (word_and len (word 0xfffffffffffffff0)) = len`, - BITBLAST_TAC);; - -let BYTE_LIST_AT_ADD_ASSUM_TAC new_pos bound = - let rule = subst [new_pos, `new_pos:num`; bound, `bound:num`] - `(pos:num) + bound <= LENGTH (bl:byte list) ==> new_pos < LENGTH bl` in - let p = subst [new_pos, `new_pos:num`] `new_pos:num` in - MP_TAC (ARITH_RULE rule) THEN - ASM_REWRITE_TAC[] THEN DISCH_THEN (LABEL_TAC "tmp") THEN - FIRST_ASSUM(fun th -> MP_TAC(SPEC p th)) THEN - USE_THEN "tmp" (fun th -> REWRITE_TAC[th]) THEN - POP_ASSUM (K ALL_TAC);; - -let WORD_JOIN_ASSOC_16_8 = WORD_BLAST - `!(x0:byte) (x1:byte) (x2:byte) (x3:byte). - word_join (word_join x3 x2:int16) - (word_join x1 x0:int16):int32 = - word_join (word_join (word_join x3 x2:int32) x1:int32) x0`;; - -let BYTES128_TO_BYTES8_THM = prove( - `!pos bl_ptr s. - read (memory :> bytes128 (word_add bl_ptr (word pos))) s = - bytes_to_int128 - [read (memory :> bytes8 (word_add bl_ptr (word (pos + 0x0)))) s; - read (memory :> bytes8 (word_add bl_ptr (word (pos + 0x1)))) s; - read (memory :> bytes8 (word_add bl_ptr (word (pos + 0x2)))) s; - read (memory :> bytes8 (word_add bl_ptr (word (pos + 0x3)))) s; - read (memory :> bytes8 (word_add bl_ptr (word (pos + 0x4)))) s; - read (memory :> bytes8 (word_add bl_ptr (word (pos + 0x5)))) s; - read (memory :> bytes8 (word_add bl_ptr (word (pos + 0x6)))) s; - read (memory :> bytes8 (word_add bl_ptr (word (pos + 0x7)))) s; - read (memory :> bytes8 (word_add bl_ptr (word (pos + 0x8)))) s; - read (memory :> bytes8 (word_add bl_ptr (word (pos + 0x9)))) s; - read (memory :> bytes8 (word_add bl_ptr (word (pos + 0xa)))) s; - read (memory :> bytes8 (word_add bl_ptr (word (pos + 0xb)))) s; - read (memory :> bytes8 (word_add bl_ptr (word (pos + 0xc)))) s; - read (memory :> bytes8 (word_add bl_ptr (word (pos + 0xd)))) s; - read (memory :> bytes8 (word_add bl_ptr (word (pos + 0xe)))) s; - read (memory :> bytes8 (word_add bl_ptr (word (pos + 0xf)))) s]`, - REPEAT STRIP_TAC THEN - REWRITE_TAC[bytes_to_int128] THEN - REWRITE_TAC EL_16_8_CLAUSES THEN - GEN_REWRITE_TAC TOP_DEPTH_CONV [READ_MEMORY_BYTESIZED_SPLIT; WORD_ADD_ASSOC_CONSTS] THEN - CONV_TAC(DEPTH_CONV WORD_NUM_RED_CONV) THEN - ONCE_REWRITE_TAC [ARITH_RULE `pos + 0 = (pos:num)`] THEN - REFL_TAC -);; +(**********************************************************************) +(** Decrypt-specific lemmas **) -let SUB_LIST_SUCSPLIT = prove( - `!(l:A list) n p. SUB_LIST(p,SUC n) l = APPEND (SUB_LIST(p,1) l) (SUB_LIST(p+1,n) l)`, - REPEAT STRIP_TAC THEN - REWRITE_TAC [ARITH_RULE `SUC n = 1 + n`] THEN - REWRITE_TAC [SUB_LIST_SPLIT] +let LENGTH_OF_AES256_XTS_DECRYPT_REC = prove( + `!(i:num) (m:num) (C:byte list) (iv:int128) (key1:int128 list) (key2:int128 list). + LENGTH(aes256_xts_decrypt_rec i m C iv key1 key2) = (if m < i then 0 else (m - i + 1) * 0x10)`, + REPEAT GEN_TAC THEN + (* Wellfounded induction with measure (m + 1) - i + Note that the parentheses are essential because of the precedence of + and - *) + WF_INDUCT_TAC `(m + 1) - i` THEN + ONCE_REWRITE_TAC[aes256_xts_decrypt_rec] THEN + COND_CASES_TAC THENL + [ SIMP_TAC[LENGTH_EQ_NIL]; + SIMP_TAC[] THEN + REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + REWRITE_TAC[LENGTH_APPEND] THEN + SUBGOAL_THEN `~(m < i) ==> (m + 1) - (i + 1) < (m + 1) - i` ASSUME_TAC THENL + [ ASM_ARITH_TAC ; ALL_TAC ] THEN + ASM_SIMP_TAC[] THEN + REWRITE_TAC[LENGTH_OF_INT128_TO_BYTES] THEN + COND_CASES_TAC THENL + [ASM_ARITH_TAC; ASM_ARITH_TAC]] );; -let SUB_LIST_16_TAC n exp = - let subgoal = subst [exp, `exp:num`] `exp < LENGTH (l:A list)` in - CONV_TAC(RAND_CONV (REWRITE_CONV[num_CONV n; SUB_LIST_SUCSPLIT])) THEN - SUBGOAL_THEN subgoal ASSUME_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN - REWRITE_TAC[SUB_LIST_1] THEN ASM_SIMP_TAC[GSYM ADD_ASSOC] THEN NUM_REDUCE_TAC;; - -let SUB_LIST_16 = prove( - `!(l:A list) n. n + 16 <= LENGTH l ==> - [ EL (n + 0) l; EL (n + 1) l; EL (n + 2) l; EL (n + 3) l; - EL (n + 4) l; EL (n + 5) l; EL (n + 6) l; EL (n + 7) l; - EL (n + 8) l; EL (n + 9) l; EL (n + 10) l; EL (n + 11) l; - EL (n + 12) l; EL (n + 13) l; EL (n + 14) l; EL (n + 15) l - ] = SUB_LIST (n,16) l`, +let LENGTH_OF_FST_OF_CIPHER_STEALING = prove( + `!(block:byte list) (tail:byte list) (tail_len:num) + (iv:int128) (i:num) (key1:int128 list) (key2:int128 list). + LENGTH (FST (cipher_stealing block tail tail_len iv i key1 key2)) = 16`, REPEAT STRIP_TAC THEN - MAP_EVERY (fun i -> - if i == 0 - then SUB_LIST_16_TAC `0x10` `n:num` - else SUB_LIST_16_TAC (mk_numeral (num (16 - i))) - (mk_binop (mk_const("+", [`:num`, `:A`])) (mk_var("n", `:num`)) - (mk_numeral (num i)))) (0--14) THEN - SUBGOAL_THEN `n + 15 < LENGTH (l:A list)` ASSUME_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN - ASM_SIMP_TAC[APPEND; ARITH_RULE `n + 0 = n`] -);; - -let BYTE_LIST_AT_5BLOCKS = prove( - `! pos bl bl_ptr len s. - byte_list_at bl bl_ptr len s - ==> LENGTH bl = val len - ==> pos + 0x50 <= LENGTH bl - ==> (read (memory :> bytes128 (word_add bl_ptr (word pos))) s = - bytes_to_int128 (SUB_LIST (pos, 0x10) bl) /\ - read (memory :> bytes128 (word_add (word_add bl_ptr (word pos)) (word 0x10))) s = - bytes_to_int128 (SUB_LIST (pos + 0x10, 0x10) bl) /\ - read (memory :> bytes128 (word_add (word_add bl_ptr (word pos)) (word 0x20))) s = - bytes_to_int128 (SUB_LIST (pos + 0x20, 0x10) bl) /\ - read (memory :> bytes128 (word_add (word_add bl_ptr (word pos)) (word 0x30))) s = - bytes_to_int128 (SUB_LIST (pos + 0x30, 0x10) bl) /\ - read (memory :> bytes128 (word_add (word_add bl_ptr (word pos)) (word 0x40))) s = - bytes_to_int128 (SUB_LIST (pos + 0x40, 0x10) bl))`, - REWRITE_TAC[byte_list_at] THEN - REPEAT STRIP_TAC THENL - [ (* Subgoal1 *) - MAP_EVERY (fun i -> BYTE_LIST_AT_ADD_ASSUM_TAC - (mk_binop (mk_const("+", [`:num`, `:A`])) (mk_var("pos", `:num`)) - (mk_numeral (num i))) `0x50`) (0--15) THEN - REWRITE_TAC[WORD_ADD_ASSOC_CONSTS] THEN - REPEAT STRIP_TAC THEN - ASM_REWRITE_TAC[BYTES128_TO_BYTES8_THM; GSYM ADD_ASSOC] THEN - NUM_REDUCE_TAC THEN ASM_REWRITE_TAC[] THEN AP_TERM_TAC THEN - MP_TAC (ISPECL [`bl:byte list`; `pos:num`] SUB_LIST_16) THEN - REWRITE_TAC[GSYM ADD_ASSOC] THEN NUM_REDUCE_TAC THEN - DISCH_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_ARITH_TAC; - (* Subgoal2 *) - MAP_EVERY (fun i -> BYTE_LIST_AT_ADD_ASSUM_TAC - (mk_binop (mk_const("+", [`:num`, `:A`])) (mk_var("pos", `:num`)) - (mk_numeral (num i))) `0x50`) (16--31) THEN - REWRITE_TAC[WORD_ADD_ASSOC_CONSTS] THEN - REPEAT STRIP_TAC THEN - ASM_REWRITE_TAC[BYTES128_TO_BYTES8_THM; GSYM ADD_ASSOC] THEN - NUM_REDUCE_TAC THEN ASM_REWRITE_TAC[] THEN AP_TERM_TAC THEN - MP_TAC (ISPECL [`bl:byte list`; `(pos+0x10):num`] SUB_LIST_16) THEN - REWRITE_TAC[GSYM ADD_ASSOC] THEN NUM_REDUCE_TAC THEN - DISCH_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_ARITH_TAC; - (* Subgoal3 *) - MAP_EVERY (fun i -> BYTE_LIST_AT_ADD_ASSUM_TAC - (mk_binop (mk_const("+", [`:num`, `:A`])) (mk_var("pos", `:num`)) - (mk_numeral (num i))) `0x50`) (32--47) THEN - REWRITE_TAC[WORD_ADD_ASSOC_CONSTS] THEN - REPEAT STRIP_TAC THEN - ASM_REWRITE_TAC[BYTES128_TO_BYTES8_THM; GSYM ADD_ASSOC] THEN - NUM_REDUCE_TAC THEN ASM_REWRITE_TAC[] THEN AP_TERM_TAC THEN - MP_TAC (ISPECL [`bl:byte list`; `(pos+0x20):num`] SUB_LIST_16) THEN - REWRITE_TAC[GSYM ADD_ASSOC] THEN NUM_REDUCE_TAC THEN - DISCH_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_ARITH_TAC; - (* Subgoal4 *) - MAP_EVERY (fun i -> BYTE_LIST_AT_ADD_ASSUM_TAC - (mk_binop (mk_const("+", [`:num`, `:A`])) (mk_var("pos", `:num`)) - (mk_numeral (num i))) `0x50`) (48--63) THEN - REWRITE_TAC[WORD_ADD_ASSOC_CONSTS] THEN - REPEAT STRIP_TAC THEN - ASM_REWRITE_TAC[BYTES128_TO_BYTES8_THM; GSYM ADD_ASSOC] THEN - NUM_REDUCE_TAC THEN ASM_REWRITE_TAC[] THEN AP_TERM_TAC THEN - MP_TAC (ISPECL [`bl:byte list`; `(pos+0x30):num`] SUB_LIST_16) THEN - REWRITE_TAC[GSYM ADD_ASSOC] THEN NUM_REDUCE_TAC THEN - DISCH_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_ARITH_TAC; - (* Subgoal 5 *) - MAP_EVERY (fun i -> BYTE_LIST_AT_ADD_ASSUM_TAC - (mk_binop (mk_const("+", [`:num`, `:A`])) (mk_var("pos", `:num`)) - (mk_numeral (num i))) `0x50`) (64--79) THEN - REWRITE_TAC[WORD_ADD_ASSOC_CONSTS] THEN - REPEAT STRIP_TAC THEN - ASM_REWRITE_TAC[BYTES128_TO_BYTES8_THM; GSYM ADD_ASSOC] THEN - NUM_REDUCE_TAC THEN ASM_REWRITE_TAC[] THEN AP_TERM_TAC THEN - MP_TAC (ISPECL [`bl:byte list`; `(pos+0x40):num`] SUB_LIST_16) THEN - REWRITE_TAC[GSYM ADD_ASSOC] THEN NUM_REDUCE_TAC THEN - DISCH_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_ARITH_TAC - ] -);; - -let BYTE_LIST_AT_4BLOCKS = prove( - `! pos bl bl_ptr len s. - byte_list_at bl bl_ptr len s - ==> LENGTH bl = val len - ==> pos + 0x40 <= LENGTH bl - ==> (read (memory :> bytes128 (word_add bl_ptr (word pos))) s = - bytes_to_int128 (SUB_LIST (pos, 0x10) bl) /\ - read (memory :> bytes128 (word_add (word_add bl_ptr (word pos)) (word 0x10))) s = - bytes_to_int128 (SUB_LIST (pos + 0x10, 0x10) bl) /\ - read (memory :> bytes128 (word_add (word_add bl_ptr (word pos)) (word 0x20))) s = - bytes_to_int128 (SUB_LIST (pos + 0x20, 0x10) bl) /\ - read (memory :> bytes128 (word_add (word_add bl_ptr (word pos)) (word 0x30))) s = - bytes_to_int128 (SUB_LIST (pos + 0x30, 0x10) bl))`, - REWRITE_TAC[byte_list_at] THEN - REPEAT STRIP_TAC THENL - [ (* Subgoal1 *) - MAP_EVERY (fun i -> BYTE_LIST_AT_ADD_ASSUM_TAC - (mk_binop (mk_const("+", [`:num`, `:A`])) (mk_var("pos", `:num`)) - (mk_numeral (num i))) `0x40`) (0--15) THEN - REWRITE_TAC[WORD_ADD_ASSOC_CONSTS] THEN - REPEAT STRIP_TAC THEN - ASM_REWRITE_TAC[BYTES128_TO_BYTES8_THM; GSYM ADD_ASSOC] THEN - NUM_REDUCE_TAC THEN ASM_REWRITE_TAC[] THEN AP_TERM_TAC THEN - MP_TAC (ISPECL [`bl:byte list`; `pos:num`] SUB_LIST_16) THEN - REWRITE_TAC[GSYM ADD_ASSOC] THEN NUM_REDUCE_TAC THEN - DISCH_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_ARITH_TAC; - (* Subgoal2 *) - MAP_EVERY (fun i -> BYTE_LIST_AT_ADD_ASSUM_TAC - (mk_binop (mk_const("+", [`:num`, `:A`])) (mk_var("pos", `:num`)) - (mk_numeral (num i))) `0x40`) (16--31) THEN - REWRITE_TAC[WORD_ADD_ASSOC_CONSTS] THEN - REPEAT STRIP_TAC THEN - ASM_REWRITE_TAC[BYTES128_TO_BYTES8_THM; GSYM ADD_ASSOC] THEN - NUM_REDUCE_TAC THEN ASM_REWRITE_TAC[] THEN AP_TERM_TAC THEN - MP_TAC (ISPECL [`bl:byte list`; `(pos+0x10):num`] SUB_LIST_16) THEN - REWRITE_TAC[GSYM ADD_ASSOC] THEN NUM_REDUCE_TAC THEN - DISCH_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_ARITH_TAC; - (* Subgoal3 *) - MAP_EVERY (fun i -> BYTE_LIST_AT_ADD_ASSUM_TAC - (mk_binop (mk_const("+", [`:num`, `:A`])) (mk_var("pos", `:num`)) - (mk_numeral (num i))) `0x40`) (32--47) THEN - REWRITE_TAC[WORD_ADD_ASSOC_CONSTS] THEN - REPEAT STRIP_TAC THEN - ASM_REWRITE_TAC[BYTES128_TO_BYTES8_THM; GSYM ADD_ASSOC] THEN - NUM_REDUCE_TAC THEN ASM_REWRITE_TAC[] THEN AP_TERM_TAC THEN - MP_TAC (ISPECL [`bl:byte list`; `(pos+0x20):num`] SUB_LIST_16) THEN - REWRITE_TAC[GSYM ADD_ASSOC] THEN NUM_REDUCE_TAC THEN - DISCH_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_ARITH_TAC; - (* Subgoal4 *) - MAP_EVERY (fun i -> BYTE_LIST_AT_ADD_ASSUM_TAC - (mk_binop (mk_const("+", [`:num`, `:A`])) (mk_var("pos", `:num`)) - (mk_numeral (num i))) `0x40`) (48--63) THEN - REWRITE_TAC[WORD_ADD_ASSOC_CONSTS] THEN - REPEAT STRIP_TAC THEN - ASM_REWRITE_TAC[BYTES128_TO_BYTES8_THM; GSYM ADD_ASSOC] THEN - NUM_REDUCE_TAC THEN ASM_REWRITE_TAC[] THEN AP_TERM_TAC THEN - MP_TAC (ISPECL [`bl:byte list`; `(pos+0x30):num`] SUB_LIST_16) THEN - REWRITE_TAC[GSYM ADD_ASSOC] THEN NUM_REDUCE_TAC THEN - DISCH_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_ARITH_TAC - ] -);; - -let BYTE_LIST_AT_3BLOCKS = prove( - `! pos bl bl_ptr len s. - byte_list_at bl bl_ptr len s - ==> LENGTH bl = val len - ==> pos + 0x30 <= LENGTH bl - ==> (read (memory :> bytes128 (word_add bl_ptr (word pos))) s = - bytes_to_int128 (SUB_LIST (pos, 0x10) bl) /\ - read (memory :> bytes128 (word_add (word_add bl_ptr (word pos)) (word 0x10))) s = - bytes_to_int128 (SUB_LIST (pos + 0x10, 0x10) bl) /\ - read (memory :> bytes128 (word_add (word_add bl_ptr (word pos)) (word 0x20))) s = - bytes_to_int128 (SUB_LIST (pos + 0x20, 0x10) bl))`, - REWRITE_TAC[byte_list_at] THEN - REPEAT STRIP_TAC THENL - [ (* Subgoal1 *) - MAP_EVERY (fun i -> BYTE_LIST_AT_ADD_ASSUM_TAC - (mk_binop (mk_const("+", [`:num`, `:A`])) (mk_var("pos", `:num`)) - (mk_numeral (num i))) `0x30`) (0--15) THEN - REWRITE_TAC[WORD_ADD_ASSOC_CONSTS] THEN - REPEAT STRIP_TAC THEN - ASM_REWRITE_TAC[BYTES128_TO_BYTES8_THM; GSYM ADD_ASSOC] THEN - NUM_REDUCE_TAC THEN ASM_REWRITE_TAC[] THEN AP_TERM_TAC THEN - MP_TAC (ISPECL [`bl:byte list`; `pos:num`] SUB_LIST_16) THEN - REWRITE_TAC[GSYM ADD_ASSOC] THEN NUM_REDUCE_TAC THEN - DISCH_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_ARITH_TAC; - (* Subgoal2 *) - MAP_EVERY (fun i -> BYTE_LIST_AT_ADD_ASSUM_TAC - (mk_binop (mk_const("+", [`:num`, `:A`])) (mk_var("pos", `:num`)) - (mk_numeral (num i))) `0x30`) (16--31) THEN - REWRITE_TAC[WORD_ADD_ASSOC_CONSTS] THEN - REPEAT STRIP_TAC THEN - ASM_REWRITE_TAC[BYTES128_TO_BYTES8_THM; GSYM ADD_ASSOC] THEN - NUM_REDUCE_TAC THEN ASM_REWRITE_TAC[] THEN AP_TERM_TAC THEN - MP_TAC (ISPECL [`bl:byte list`; `(pos+0x10):num`] SUB_LIST_16) THEN - REWRITE_TAC[GSYM ADD_ASSOC] THEN NUM_REDUCE_TAC THEN - DISCH_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_ARITH_TAC; - (* Subgoal3 *) - MAP_EVERY (fun i -> BYTE_LIST_AT_ADD_ASSUM_TAC - (mk_binop (mk_const("+", [`:num`, `:A`])) (mk_var("pos", `:num`)) - (mk_numeral (num i))) `0x30`) (32--47) THEN - REWRITE_TAC[WORD_ADD_ASSOC_CONSTS] THEN - REPEAT STRIP_TAC THEN - ASM_REWRITE_TAC[BYTES128_TO_BYTES8_THM; GSYM ADD_ASSOC] THEN - NUM_REDUCE_TAC THEN ASM_REWRITE_TAC[] THEN AP_TERM_TAC THEN - MP_TAC (ISPECL [`bl:byte list`; `(pos+0x20):num`] SUB_LIST_16) THEN - REWRITE_TAC[GSYM ADD_ASSOC] THEN NUM_REDUCE_TAC THEN - DISCH_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_ARITH_TAC - ] -);; - -let BYTE_LIST_AT_2BLOCKS = prove( - `! pos bl bl_ptr len s. - byte_list_at bl bl_ptr len s - ==> LENGTH bl = val len - ==> pos + 0x20 <= LENGTH bl - ==> (read (memory :> bytes128 (word_add bl_ptr (word pos))) s = - bytes_to_int128 (SUB_LIST (pos, 0x10) bl) /\ - read (memory :> bytes128 (word_add (word_add bl_ptr (word pos)) (word 0x10))) s = - bytes_to_int128 (SUB_LIST (pos + 0x10, 0x10) bl))`, - REWRITE_TAC[byte_list_at] THEN - REPEAT STRIP_TAC THENL - [ (* Subgoal1 *) - MAP_EVERY (fun i -> BYTE_LIST_AT_ADD_ASSUM_TAC - (mk_binop (mk_const("+", [`:num`, `:A`])) (mk_var("pos", `:num`)) - (mk_numeral (num i))) `0x20`) (0--15) THEN - REWRITE_TAC[WORD_ADD_ASSOC_CONSTS] THEN - REPEAT STRIP_TAC THEN - ASM_REWRITE_TAC[BYTES128_TO_BYTES8_THM; GSYM ADD_ASSOC] THEN - NUM_REDUCE_TAC THEN ASM_REWRITE_TAC[] THEN AP_TERM_TAC THEN - MP_TAC (ISPECL [`bl:byte list`; `pos:num`] SUB_LIST_16) THEN - REWRITE_TAC[GSYM ADD_ASSOC] THEN NUM_REDUCE_TAC THEN - DISCH_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_ARITH_TAC; - (* Subgoal2 *) - MAP_EVERY (fun i -> BYTE_LIST_AT_ADD_ASSUM_TAC - (mk_binop (mk_const("+", [`:num`, `:A`])) (mk_var("pos", `:num`)) - (mk_numeral (num i))) `0x20`) (16--31) THEN - REWRITE_TAC[WORD_ADD_ASSOC_CONSTS] THEN - REPEAT STRIP_TAC THEN - ASM_REWRITE_TAC[BYTES128_TO_BYTES8_THM; GSYM ADD_ASSOC] THEN - NUM_REDUCE_TAC THEN ASM_REWRITE_TAC[] THEN AP_TERM_TAC THEN - MP_TAC (ISPECL [`bl:byte list`; `(pos+0x10):num`] SUB_LIST_16) THEN - REWRITE_TAC[GSYM ADD_ASSOC] THEN NUM_REDUCE_TAC THEN - DISCH_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_ARITH_TAC - ] -);; - -let BYTE_LIST_AT_1BLOCKS = prove( - `! pos bl bl_ptr len s. - byte_list_at bl bl_ptr len s - ==> LENGTH bl = val len - ==> pos + 0x10 <= LENGTH bl - ==> read (memory :> bytes128 (word_add bl_ptr (word pos))) s = - bytes_to_int128 (SUB_LIST (pos, 0x10) bl)`, - REWRITE_TAC[byte_list_at] THEN - REPEAT STRIP_TAC THENL - [ (* Subgoal1 *) - MAP_EVERY (fun i -> BYTE_LIST_AT_ADD_ASSUM_TAC - (mk_binop (mk_const("+", [`:num`, `:A`])) (mk_var("pos", `:num`)) - (mk_numeral (num i))) `0x10`) (0--15) THEN - REWRITE_TAC[WORD_ADD_ASSOC_CONSTS] THEN - REPEAT STRIP_TAC THEN - ASM_REWRITE_TAC[BYTES128_TO_BYTES8_THM; GSYM ADD_ASSOC] THEN - NUM_REDUCE_TAC THEN ASM_REWRITE_TAC[] THEN AP_TERM_TAC THEN - MP_TAC (ISPECL [`bl:byte list`; `pos:num`] SUB_LIST_16) THEN - REWRITE_TAC[GSYM ADD_ASSOC] THEN NUM_REDUCE_TAC THEN - DISCH_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_ARITH_TAC - ] -);; - -let READ_CT_LEMMA = prove( - `!ct_ptr i (len:int64) (ct:byte list) s. - (forall j. j < val len ==> read (memory :> bytes8 (word_add ct_ptr (word j))) s = EL j ct) - /\ i * 0x50 + 0x50 <= val len - /\ LENGTH ct = val len - ==> - read (memory :> bytes128 (word_add ct_ptr (word_mul (word 0x50) (word i)))) s = - bytes_to_int128 (SUB_LIST (i * 80, 16) ct) /\ - read (memory :> bytes128 (word_add (word_add ct_ptr (word_mul (word 0x50) (word i))) (word 0x10))) s = - bytes_to_int128 (SUB_LIST (i * 80 + 16, 16) ct) /\ - read (memory :> bytes128 (word_add (word_add ct_ptr (word_mul (word 0x50) (word i))) (word 0x20))) s = - bytes_to_int128 (SUB_LIST (i * 80 + 32, 16) ct) /\ - read (memory :> bytes128 (word_add (word_add ct_ptr (word_mul (word 0x50) (word i))) (word 0x30))) s = - bytes_to_int128 (SUB_LIST (i * 80 + 48, 16) ct) /\ - read (memory :> bytes128 (word_add (word_add ct_ptr (word_mul (word 0x50) (word i))) (word 0x40))) s = - bytes_to_int128 (SUB_LIST (i * 80 + 64, 16) ct) - `, - REPEAT GEN_TAC THEN STRIP_TAC THEN - REWRITE_TAC [WORD_RULE `word_mul (word 0x50) (word i) = word (i * 80)`] THEN - MP_TAC - (SPECL [`(i * 80):num`; `ct:byte list`; `ct_ptr:int64`; `len:int64`; `s:armstate`] - BYTE_LIST_AT_5BLOCKS) THEN - REWRITE_TAC[byte_list_at] THEN ASM_SIMP_TAC[] -);; - -let READ_CT_TAIL4_LEMMA = prove( - `!ct_ptr (num_5blocks_adjusted:int64) (len:int64) (ct:byte list) s. - (forall j. j < val len ==> read (memory :> bytes8 (word_add ct_ptr (word j))) s = EL j ct) - /\ val num_5blocks_adjusted * 0x50 + 0x40 <= val len - /\ LENGTH ct = val len - ==> - read (memory :> bytes128 (word_add - (word_add ct_ptr (word_mul (word 0x50) num_5blocks_adjusted)) - (word 0x30))) s = - bytes_to_int128 (SUB_LIST (val num_5blocks_adjusted * 80 + 0x30, 16) ct) /\ - read (memory :> bytes128 (word_add - (word_add ct_ptr (word_mul (word 0x50) num_5blocks_adjusted)) - (word 0x20))) s = - bytes_to_int128 (SUB_LIST (val num_5blocks_adjusted * 80 + 0x20, 16) ct) /\ - read (memory :> bytes128 (word_add - (word_add ct_ptr (word_mul (word 0x50) num_5blocks_adjusted)) - (word 0x10))) s = - bytes_to_int128 (SUB_LIST (val num_5blocks_adjusted * 80 + 0x10, 16) ct) /\ - read (memory :> bytes128 - (word_add ct_ptr (word_mul (word 0x50) num_5blocks_adjusted))) s = - bytes_to_int128 (SUB_LIST (val num_5blocks_adjusted * 80, 16) ct) - `, - REPEAT GEN_TAC THEN STRIP_TAC THEN - REWRITE_TAC [WORD_RULE `(word_mul (word 0x50) (num_5blocks_adjusted:int64)) = word (val num_5blocks_adjusted * 80)`] THEN - MP_TAC - (SPECL [`(val (num_5blocks_adjusted:int64) * 80):num`; `ct:byte list`; `ct_ptr:int64`; `len:int64`; `s:armstate`] - BYTE_LIST_AT_4BLOCKS) THEN - REWRITE_TAC[byte_list_at] THEN ASM_SIMP_TAC[] + REWRITE_TAC[cipher_stealing] THEN + ASM_REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + REWRITE_TAC[LENGTH_OF_INT128_TO_BYTES] );; -let READ_CT_TAIL3_LEMMA = prove( - `!ct_ptr (num_5blocks_adjusted:int64) (len:int64) (ct:byte list) s. - (forall j. j < val len ==> read (memory :> bytes8 (word_add ct_ptr (word j))) s = EL j ct) - /\ val num_5blocks_adjusted * 0x50 + 0x30 <= val len - /\ LENGTH ct = val len - ==> - read (memory :> bytes128 (word_add - (word_add ct_ptr (word_mul (word 0x50) num_5blocks_adjusted)) - (word 0x20))) s = - bytes_to_int128 (SUB_LIST (val num_5blocks_adjusted * 80 + 0x20, 16) ct) /\ - read (memory :> bytes128 (word_add - (word_add ct_ptr (word_mul (word 0x50) num_5blocks_adjusted)) - (word 0x10))) s = - bytes_to_int128 (SUB_LIST (val num_5blocks_adjusted * 80 + 0x10, 16) ct) /\ - read (memory :> bytes128 - (word_add ct_ptr (word_mul (word 0x50) num_5blocks_adjusted))) s = - bytes_to_int128 (SUB_LIST (val num_5blocks_adjusted * 80, 16) ct) - `, - REPEAT GEN_TAC THEN STRIP_TAC THEN - REWRITE_TAC [WORD_RULE `(word_mul (word 0x50) (num_5blocks_adjusted:int64)) = word (val num_5blocks_adjusted * 80)`] THEN - MP_TAC - (SPECL [`(val (num_5blocks_adjusted:int64) * 80):num`; `ct:byte list`; `ct_ptr:int64`; `len:int64`; `s:armstate`] - BYTE_LIST_AT_3BLOCKS) THEN - REWRITE_TAC[byte_list_at] THEN ASM_SIMP_TAC[] +let LENGTH_OF_SND_OF_CIPHER_STEALING = prove( + `!(block:byte list) (tail:byte list) (tail_len:num) + (iv:int128) (i:num) (key1:int128 list) (key2:int128 list). + LENGTH (SND (cipher_stealing block tail tail_len iv i key1 key2)) = MIN tail_len 16`, + REPEAT STRIP_TAC THEN + REWRITE_TAC[cipher_stealing] THEN + ASM_REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + REWRITE_TAC[LENGTH_SUB_LIST] THEN + REWRITE_TAC[LENGTH_OF_INT128_TO_BYTES] THEN + REWRITE_TAC[MIN] THEN + CONV_TAC NUM_REDUCE_CONV );; -let READ_CT_TAIL2_LEMMA = prove( - `!ct_ptr (num_5blocks_adjusted:int64) (len:int64) (ct:byte list) s. - (forall j. j < val len ==> read (memory :> bytes8 (word_add ct_ptr (word j))) s = EL j ct) - /\ val num_5blocks_adjusted * 0x50 + 0x20 <= val len - /\ LENGTH ct = val len - ==> - read (memory :> bytes128 (word_add - (word_add ct_ptr (word_mul (word 0x50) num_5blocks_adjusted)) - (word 0x10))) s = - bytes_to_int128 (SUB_LIST (val num_5blocks_adjusted * 80 + 0x10, 16) ct) /\ - read (memory :> bytes128 - (word_add ct_ptr (word_mul (word 0x50) num_5blocks_adjusted))) s = - bytes_to_int128 (SUB_LIST (val num_5blocks_adjusted * 80, 16) ct) - `, - REPEAT GEN_TAC THEN STRIP_TAC THEN - REWRITE_TAC [WORD_RULE `(word_mul (word 0x50) (num_5blocks_adjusted:int64)) = word (val num_5blocks_adjusted * 80)`] THEN - MP_TAC - (SPECL [`(val (num_5blocks_adjusted:int64) * 80):num`; `ct:byte list`; `ct_ptr:int64`; `len:int64`; `s:armstate`] - BYTE_LIST_AT_2BLOCKS) THEN - REWRITE_TAC[byte_list_at] THEN ASM_SIMP_TAC[] -);; +let LENGTH_OF_AES256_XTS_DECRYPT_TAIL = prove( + `! (i:num) (tail_len:num) (C:byte list) (iv:int128) (key1:int128 list) (key2:int128 list). + LENGTH(aes256_xts_decrypt_tail i tail_len C iv key1 key2) = 0x10 + MIN tail_len 16`, + REPEAT STRIP_TAC THEN + REWRITE_TAC[aes256_xts_decrypt_tail] THEN + COND_CASES_TAC THENL [ + ASM_REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + REWRITE_TAC[LENGTH_OF_INT128_TO_BYTES] THEN + REWRITE_TAC[ADD_CLAUSES; MIN] THEN + CONV_TAC NUM_REDUCE_CONV; -let READ_CT_TAIL1_LEMMA = prove( - `!ct_ptr (num_5blocks_adjusted:int64) (len:int64) (ct:byte list) s. - (forall j. j < val len ==> read (memory :> bytes8 (word_add ct_ptr (word j))) s = EL j ct) - /\ val num_5blocks_adjusted * 0x50 + 0x10 <= val len - /\ LENGTH ct = val len - ==> - read (memory :> bytes128 - (word_add ct_ptr (word_mul (word 0x50) num_5blocks_adjusted))) s = - bytes_to_int128 (SUB_LIST (val num_5blocks_adjusted * 80, 16) ct) - `, - REPEAT GEN_TAC THEN STRIP_TAC THEN - REWRITE_TAC [WORD_RULE `(word_mul (word 0x50) (num_5blocks_adjusted:int64)) = word (val num_5blocks_adjusted * 80)`] THEN - MP_TAC - (SPECL [`(val (num_5blocks_adjusted:int64) * 80):num`; `ct:byte list`; `ct_ptr:int64`; `len:int64`; `s:armstate`] - BYTE_LIST_AT_1BLOCKS) THEN - REWRITE_TAC[byte_list_at] THEN ASM_SIMP_TAC[] + REWRITE_TAC[LET_DEF; LET_END_DEF; LENGTH_APPEND] THEN + REWRITE_TAC[LENGTH_OF_FST_OF_CIPHER_STEALING] THEN + REWRITE_TAC[LENGTH_OF_SND_OF_CIPHER_STEALING]] );; -let READ_CT_LAST_LEMMA = prove( - `!ct_ptr (curr_len:num) (len:int64) (ct:byte list) s. - (forall j. j < val len ==> read (memory :> bytes8 (word_add ct_ptr (word j))) s = EL j ct) - /\ curr_len + 0x10 <= val len - /\ LENGTH ct = val len - ==> - read (memory :> bytes128 (word_add ct_ptr (word curr_len))) s = - bytes_to_int128 (SUB_LIST (curr_len, 16) ct) - `, - REPEAT GEN_TAC THEN STRIP_TAC THEN - MP_TAC - (SPECL [`curr_len:num`; `ct:byte list`; `ct_ptr:int64`; `len:int64`; `s:armstate`] - BYTE_LIST_AT_1BLOCKS) THEN - REWRITE_TAC[byte_list_at] THEN ASM_SIMP_TAC[] +let LENGTH_OF_AES256_XTS_DECRYPT_REC_TRIVIAL = prove( + `!(ct:byte list) (iv:int128) (key1:int128 list) (key2:int128 list). + LENGTH (aes256_xts_decrypt_rec 0x0 0x0 ct iv key1 key2) = 16`, + REPEAT STRIP_TAC THEN + REWRITE_TAC[LENGTH_OF_AES256_XTS_DECRYPT_REC] THEN + CONV_TAC NUM_REDUCE_CONV );; - -let UDIV_OPT_THM = prove(`!n:num. n < 0x2 EXP 0x40 - ==> (word (val ((word ((n * 0xcccccccccccccccd) DIV 0x2 EXP 0x40)):int64) DIV 0x2 EXP 0x6)):int64 = word (n DIV 0x50)`, +let LENGTH_OF_AES256_XTS_DECRYPT_TAIL_TRIVIAL = prove( + `!(ct:byte list) (iv:int128) (key1:int128 list) (key2:int128 list). + LENGTH(aes256_xts_decrypt_tail 0 0 ct iv key1 key2) = 16`, REPEAT STRIP_TAC THEN - REWRITE_TAC[VAL_WORD; DIMINDEX_64] THEN - SUBGOAL_THEN `!p n:num. ~(p = 0) /\ n < p * p ==> n DIV p MOD p = n DIV p` - (MP_TAC o SPECL [`0x2 EXP 0x40`; `n * 0xcccccccccccccccd`]) THENL - [ REPEAT STRIP_TAC THEN - REWRITE_TAC[DIV_MOD] THEN - AP_THM_TAC THEN AP_TERM_TAC THEN - MATCH_MP_TAC MOD_LT THEN - ASM_ARITH_TAC; ALL_TAC] THEN - ANTS_TAC THENL [ASM_ARITH_TAC;ALL_TAC] THEN - DISCH_TAC THEN ASM_REWRITE_TAC[] THEN - AP_TERM_TAC THEN ASM_ARITH_TAC);; - -let NUM_BLOCKS_LO_BOUND_THM = prove( - `!(len:int64) num_blocks. word_and len (word 0xfffffffffffffff0) = num_blocks - ==> ~(val len < 0x60) - ==> ~(val num_blocks < 0x60)`, - BITBLAST_TAC);; - -let NUM_BLOCKS_LO_BOUND_1BLOCK_THM = prove( - `!(len:int64) num_blocks. word_and len (word 0xfffffffffffffff0) = num_blocks - ==> ~(val len < 16) - ==> ~(val num_blocks < 16)`, - BITBLAST_TAC);; - -let NUM_BLOCKS_HI_BOUND_THM = prove( - `!(len:int64) num_blocks. word_and len (word 0xfffffffffffffff0) = num_blocks - ==> val len <= 2 EXP 24 - ==> val num_blocks <= 2 EXP 24`, - BITBLAST_TAC);; - -let TAIL_LEN_BOUND_THM = prove( - `!(len:int64) tail_len. word_and len (word 0xf) = tail_len - ==> val tail_len < 0x10`, - BITBLAST_TAC);; - -let NUM_BLOCKS_ADJUSTED_LO_BOUND_THM = prove( - `!(num_blocks:int64) (tail_len:int64) num_blocks_adjusted. - (if val tail_len = 0x0 then num_blocks else word_sub num_blocks (word 0x10)) = num_blocks_adjusted - ==> ~(val num_blocks < 0x60) - ==> ~(val num_blocks_adjusted < 0x50)`, - BITBLAST_TAC + REWRITE_TAC[LENGTH_OF_AES256_XTS_DECRYPT_TAIL] THEN + CONV_TAC NUM_REDUCE_CONV );; -let NUM_BLOCKS_ADJUSTED_LO_BOUND_1BLOCK_THM = prove( - `!(num_blocks:int64) (tail_len:int64) num_blocks_adjusted. - (if val tail_len = 0x0 then num_blocks else word_sub num_blocks (word 0x10)) = num_blocks_adjusted - ==> ~(val num_blocks < 16) - ==> ~(val num_blocks_adjusted < 0)`, - BITBLAST_TAC -);; +let AES256_XTS_DECRYPT_REC_EQ_TAIL_TRIVIAL = prove( + `!(ct:byte list) (iv:int128) (key1:int128 list) (key2:int128 list). + aes256_xts_decrypt_rec 0x0 0x0 ct iv key1 key2 = + aes256_xts_decrypt_tail 0x0 0x0 ct iv key1 key2`, + REPEAT STRIP_TAC THEN + ONCE_REWRITE_TAC[aes256_xts_decrypt_rec] THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + ONCE_REWRITE_TAC[aes256_xts_decrypt_rec] THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[APPEND_NIL] THEN -let NUM_BLOCKS_ADJUSTED_HI_BOUND_THM = prove( - `!(num_blocks:int64) (tail_len:int64) num_blocks_adjusted. - (if val tail_len = 0x0 then num_blocks else word_sub num_blocks (word 0x10)) = num_blocks_adjusted - ==> val num_blocks <= 2 EXP 24 - ==> ~(val num_blocks < 16) - ==> val num_blocks_adjusted <= 2 EXP 24`, - BITBLAST_TAC + REWRITE_TAC[aes256_xts_decrypt_tail] THEN + REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + CONV_TAC NUM_REDUCE_CONV );; -let NUM_5BLOCKS_ADJUSTED_LO_BOUND_THM = prove( - `!(num_blocks_adjusted:int64) (num_5blocks_adjusted:int64). - val num_blocks_adjusted <= 0x2 EXP 0x18 - ==> ~(val num_blocks_adjusted < 0x50) - ==> word (val num_blocks_adjusted DIV 0x50) = num_5blocks_adjusted - ==> 0x0 < val num_5blocks_adjusted`, +let LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS = prove( + `! (i:num) (ct:byte list) (iv:int128) (key1:int128 list) (key2:int128 list). + LENGTH(aes256_xts_decrypt ct (0x10 * i) iv key1 key2) = 0x10 * i`, REPEAT STRIP_TAC THEN - EXPAND_TAC "num_5blocks_adjusted" THEN - REWRITE_TAC[VAL_WORD; DIMINDEX_64] THEN - UNDISCH_TAC `~(val (num_blocks_adjusted:int64) < 0x50)` THEN - ABBREV_TAC `n = val (num_blocks_adjusted:int64)` THEN - SUBGOAL_THEN `n DIV 80 < 2 EXP 64` ASSUME_TAC THENL - [ ASM_ARITH_TAC; ALL_TAC] THEN - ASM_SIMP_TAC[MOD_LT] THEN - ARITH_TAC -);; - -let NUM_BLOCKS_LT_LEN_THM = prove( - `!(len:int64). val (word_and len (word 0xfffffffffffffff0)) <= val len`, - BITBLAST_TAC -);; + SPEC_TAC (`i:num`, `i:num`) THEN + INDUCT_TAC THENL + [ + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[aes256_xts_decrypt] THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[LENGTH_EQ_NIL]; + ALL_TAC] THEN -let NUM_BLOCKS_ADJUSTED_LT_LEN_THM = prove( - `!(len:int64) num_blocks. - word_and len (word 0xfffffffffffffff0) = num_blocks - ==> ~(val num_blocks < 16) - ==> val (word_sub num_blocks (word 0x10)) <= val len`, - BITBLAST_TAC -);; + REWRITE_TAC[ADD1; LEFT_ADD_DISTRIB] THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[aes256_xts_decrypt] THEN -let NUM_OF_BYTELIST_APPEND = prove - (`!l1 l2. num_of_bytelist (APPEND l1 l2) = - num_of_bytelist l1 + 2 EXP (8 * LENGTH l1) * num_of_bytelist l2`, - LIST_INDUCT_TAC THENL - [ REWRITE_TAC[APPEND; LENGTH; num_of_bytelist; MULT_CLAUSES; EXP; ADD_CLAUSES]; - REWRITE_TAC[APPEND; LENGTH; num_of_bytelist] THEN - ASM_REWRITE_TAC[] THEN - REWRITE_TAC[MULT_SUC; EXP_ADD] THEN - REWRITE_TAC[MULT_ASSOC; LEFT_ADD_DISTRIB] THEN - ARITH_TAC]);; - -let NUM_OF_BYTELIST_OF_SUB_LIST = prove( - `!sz len (x:byte list). - sz <= LENGTH x ==> - num_of_bytelist (SUB_LIST (0, sz + len) x) = - num_of_bytelist (SUB_LIST (0, sz) x) + - 2 EXP (8 * sz) * num_of_bytelist (SUB_LIST (sz, len) x)`, - REPEAT STRIP_TAC THEN - SUBST1_TAC(ISPECL [`x:byte list`; `sz:num`; `len:num`; `0:num`] SUB_LIST_SPLIT) THEN - REWRITE_TAC[NUM_OF_BYTELIST_APPEND] THEN - ASM_SIMP_TAC[LENGTH_SUB_LIST; SUB_0; MIN; ARITH_RULE `0 + sz = sz`] -);; + ASM_CASES_TAC `i = 0` THENL + [ ASM_SIMP_TAC[] THEN + CONV_TAC NUM_REDUCE_CONV THEN + IMP_REWRITE_TAC[LET_DEF;LET_END_DEF;SUB_0] THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[LENGTH_OF_AES256_XTS_DECRYPT_TAIL_TRIVIAL] + ; ALL_TAC + ] THEN -let MEMORY_READ_SUBSET_LEMMA = prove - (`!len (bl:byte list) s. - (forall i. - i < SUC len - ==> read (memory :> bytes8 (word_add pt_ptr (word i))) s = EL i bl) ==> - (forall i. - i < len - ==> read (memory :> bytes8 (word_add pt_ptr (word i))) s = EL i bl) /\ - read (memory :> bytes (word_add pt_ptr (word len),1)) s = - val(read (memory :> bytes8 (word_add pt_ptr (word len))) s) - `, - REPEAT GEN_TAC THEN - DISCH_TAC THEN - CONJ_TAC THENL - [ GEN_TAC THEN DISCH_TAC THEN - FIRST_X_ASSUM MATCH_MP_TAC THEN - ASM_REWRITE_TAC[LT_SUC_LE] THEN - ASM_ARITH_TAC; - ALL_TAC] THEN - REWRITE_TAC[bytes8; READ_COMPONENT_COMPOSE; asword; through; read] THEN - REWRITE_TAC[VAL_WORD; DIMINDEX_8] THEN + SUBGOAL_THEN `~(0x10 * i + 0x10 < 0x10)` ASSUME_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC ] THEN ASM_SIMP_TAC[] THEN + REWRITE_TAC[ARITH_RULE `0x10 * i + 0x10 = 0x10 * (i + 1)`; MOD_MULT] THEN + IMP_REWRITE_TAC[LET_DEF; LET_END_DEF;SUB_0;DIV_MULT] THEN + CONJ_TAC THENL [ALL_TAC; ARITH_TAC] THEN + SUBGOAL_THEN `~(i + 0x1 < 0x2)` ASSUME_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC] THEN ASM_SIMP_TAC[] THEN + REWRITE_TAC[LENGTH_APPEND] THEN + REWRITE_TAC[LENGTH_OF_AES256_XTS_DECRYPT_REC] THEN + REWRITE_TAC[LENGTH_OF_AES256_XTS_DECRYPT_TAIL] THEN CONV_TAC NUM_REDUCE_CONV THEN - IMP_REWRITE_TAC[MOD_LT] THEN - MP_TAC (ISPECL [`(word_add (pt_ptr:int64) (word len)):int64`; `1:num`; `(read memory s):int64->byte`] READ_BYTES_BOUND) THEN - CONV_TAC NUM_REDUCE_CONV + ASM_ARITH_TAC );; -let BYTE_LIST_AT_SPLIT = prove( - `!len (bl:byte list) (pt_ptr:int64) s. - SUC len <= LENGTH bl ==> - ((forall i. - i < SUC len - ==> read (memory :> bytes8 (word_add pt_ptr (word i))) s = EL i bl) <=> - ((forall i. - i < len - ==> read (memory :> bytes8 (word_add pt_ptr (word i))) s = EL i bl) /\ - read (memory :> bytes8 (word_add pt_ptr (word len))) s = EL len bl))`, - REPEAT STRIP_TAC THEN - EQ_TAC THENL - [ STRIP_TAC THEN - CONJ_TAC THENL - [ ASM_SIMP_TAC[ARITH_RULE `i < len ==> i < SUC len`]; - ASM_SIMP_TAC[ARITH_RULE `len < SUC len`]]; - ALL_TAC ] THEN - REPEAT STRIP_TAC THEN - ASM_CASES_TAC `i < len` THENL - [ FIRST_X_ASSUM MATCH_MP_TAC THEN - ASM_SIMP_TAC[]; - SUBGOAL_THEN `i = len:num` SUBST1_TAC THENL - [ASM_ARITH_TAC; ASM_REWRITE_TAC[]] - ] -);; - -let HD_SUB_LIST_CONS = prove - (`!(h:A) (t:A list) n. 0 < n ==> HD (SUB_LIST (0,n) (CONS h t)) = h`, - REPEAT GEN_TAC THEN STRIP_TAC THEN - MP_TAC(SPEC `n:num` num_CASES) THEN - ASM_SIMP_TAC[ARITH_RULE `0 < n ==> ~(n = 0)`] THEN - DISCH_THEN(X_CHOOSE_THEN `m:num` SUBST_ALL_TAC) THEN - REWRITE_TAC[SUB_LIST_CLAUSES; HD]);; - -let HD_SUB_LIST_CONS_GENERAL = prove( - `!p n (l:A list). p < LENGTH l /\ 0 < n ==> HD (SUB_LIST (p,n) l) = EL p l`, - INDUCT_TAC THENL - [ - GEN_TAC THEN - LIST_INDUCT_TAC THENL - [ - REWRITE_TAC[LENGTH] THEN ARITH_TAC; - REPEAT STRIP_TAC THEN - REWRITE_TAC[EL; HD] THEN - MP_TAC (SPECL [`h:A`; `t:A list`; `n:num`] HD_SUB_LIST_CONS) THEN - ASM_SIMP_TAC[] - ]; ALL_TAC - ] THEN - GEN_TAC THEN - LIST_INDUCT_TAC THENL +let LENGTH_OF_AES256_XTS_DECRYPT = prove( + `! (i:num) (tail_len:num) (ct:byte list) (iv:int128) (key1:int128 list) (key2:int128 list). + ~(tail_len = 0) /\ tail_len < 16 ==> + LENGTH(aes256_xts_decrypt ct (16 * i + 16 + tail_len) iv key1 key2) = 16 * i + 16 + tail_len`, + REPEAT STRIP_TAC THEN + (* Case 1: i = 0 *) + ASM_CASES_TAC `i = 0` THENL [ - REWRITE_TAC[LENGTH] THEN ARITH_TAC; - REPEAT STRIP_TAC THEN - REWRITE_TAC[SUB_LIST_CLAUSES] THEN - REWRITE_TAC[EL; TL] THEN - FIRST_X_ASSUM (fun th -> MATCH_MP_TAC (SPECL [`n:num`; `t:A list`] th)) THEN + ASM_SIMP_TAC[ADD_ASSOC] THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[aes256_xts_decrypt] THEN + SUBGOAL_THEN `~(0x10 + tail_len < 0x10)` ASSUME_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `(0x10 + tail_len) MOD 0x10 = tail_len` ASSUME_TAC THENL + [ REWRITE_TAC[ARITH_RULE `0x10 + tail_len = 1 * 16 + tail_len`] THEN + IMP_REWRITE_TAC[MOD_MULT_ADD; MOD_LT]; ALL_TAC] THEN ASM_SIMP_TAC[] THEN - UNDISCH_TAC `SUC p < LENGTH (CONS h (t:A list))` THEN - REWRITE_TAC[LENGTH] THEN - ARITH_TAC - ] -);; + REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + SUBGOAL_THEN `((0x10 + tail_len) - tail_len) DIV 0x10 = 1` SUBST1_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC ] THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[LENGTH_OF_AES256_XTS_DECRYPT_TAIL] THEN + ASM_ARITH_TAC; + ALL_TAC + ] THEN -let TL_SUB_LIST_CONS = prove -(`!(h:A) (t:A list) n. 0 < n ==> TL (SUB_LIST (0,n) (CONS h t)) = SUB_LIST (0, n - 1) t`, - REPEAT GEN_TAC THEN STRIP_TAC THEN - MP_TAC(SPEC `n:num` num_CASES) THEN - ASM_SIMP_TAC[ARITH_RULE `0 < n ==> ~(n = 0)`] THEN - DISCH_THEN(X_CHOOSE_THEN `m:num` SUBST_ALL_TAC) THEN - REWRITE_TAC[SUB_LIST_CLAUSES; TL] THEN - REWRITE_TAC[ARITH_RULE `SUC m - 1 = m`]);; - -let TL_SUB_LIST_CONS_GENERAL = prove( - `!p n (l:A list). p < LENGTH l ==> 0 < n - ==> TL (SUB_LIST (p, n) l) = SUB_LIST (p + 1, n - 1) l`, - INDUCT_TAC THENL + (* Case 2: i >= 1 *) + ASM_CASES_TAC `i >= 1` THENL [ - GEN_TAC THEN - LIST_INDUCT_TAC THENL - [ - REWRITE_TAC[LENGTH] THEN ARITH_TAC; - CONV_TAC NUM_REDUCE_CONV THEN - REPEAT STRIP_TAC THEN - MP_TAC (SPECL [`h:A`; `t:A list`; `n:num`] TL_SUB_LIST_CONS) THEN - ASM_SIMP_TAC[num_CONV `1`; SUB_LIST_CLAUSES] - ]; ALL_TAC + REWRITE_TAC[aes256_xts_decrypt] THEN + SUBGOAL_THEN `(0x10 * i + 0x10 + tail_len) MOD 0x10 = tail_len` SUBST1_TAC THENL + [ REWRITE_TAC[ADD_ASSOC; ARITH_RULE `0x10 * i + 0x10 = 16 * (i + 1)`] THEN + IMP_REWRITE_TAC[MOD_MULT_ADD; MOD_LT]; ALL_TAC] THEN + SUBGOAL_THEN `~(0x10 * i + 0x10 + tail_len < 0x10)` ASSUME_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[] THEN + REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + SUBGOAL_THEN `((0x10 * i + 0x10 + tail_len) - tail_len) DIV 0x10 = i + 1` SUBST1_TAC THENL + [ REWRITE_TAC[ARITH_RULE `(0x10 * i + 0x10 + tail_len) - tail_len = 16 * (i + 1)`] THEN + IMP_REWRITE_TAC[DIV_MULT] THEN + ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `~(i + 1 < 2)` ASSUME_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[] THEN + IMP_REWRITE_TAC[ARITH_RULE `(i + 1) - 2 = i - 1`; ADD_SUB] THEN + REWRITE_TAC[LENGTH_APPEND] THEN + IMP_REWRITE_TAC[LENGTH_OF_AES256_XTS_DECRYPT_REC] THEN + IMP_REWRITE_TAC[LENGTH_OF_AES256_XTS_DECRYPT_TAIL] THEN + ASM_ARITH_TAC; + ALL_TAC ] THEN - GEN_TAC THEN - LIST_INDUCT_TAC THENL - [ - REWRITE_TAC[LENGTH] THEN ARITH_TAC; - REPEAT STRIP_TAC THEN - REWRITE_TAC[ARITH_RULE `SUC p + 1 = SUC (p + 1)`] THEN - REWRITE_TAC[SUB_LIST_CLAUSES] THEN - FIRST_X_ASSUM (fun th -> MP_TAC (SPECL [`n:num`; `t:A list`] th)) THEN - SUBGOAL_THEN `p < LENGTH (t:A list)` ASSUME_TAC THENL - [ UNDISCH_TAC `SUC p < LENGTH (CONS h (t:A list))` THEN - REWRITE_TAC[LENGTH] THEN ARITH_TAC - ; ALL_TAC] THEN - ASM_SIMP_TAC[] - ] -);; -let EL_SUB_LIST_TRIVIAL = prove( - `!i n (l:A list). i < LENGTH l /\ 0 < n ==> EL 0x0 (SUB_LIST (i, n) l) = EL i l`, - REWRITE_TAC[EL] THEN - SIMP_TAC[HD_SUB_LIST_CONS_GENERAL] + ASM_ARITH_TAC );; -let EL_SUB_LIST = prove( - `!(i:num) n (l:A list). i < n /\ n <= LENGTH l ==> - EL i (SUB_LIST (0, n) l) = EL i l`, - INDUCT_TAC THENL - [ (* i = 0 *) - ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN - LIST_INDUCT_TAC THENL - [ - REPEAT STRIP_TAC THEN - IMP_REWRITE_TAC[SUB_LIST_TRIVIAL] THEN - REWRITE_TAC[LENGTH] THEN - ARITH_TAC; ALL_TAC - ] THEN - REPEAT STRIP_TAC THEN - IMP_REWRITE_TAC[EL; HD; HD_SUB_LIST_CONS]; - ALL_TAC - ] THEN - (* i != 0 *) - ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN - LIST_INDUCT_TAC THENL - [ - REPEAT STRIP_TAC THEN - IMP_REWRITE_TAC[SUB_LIST_TRIVIAL] THEN - REWRITE_TAC[LENGTH] THEN - ARITH_TAC; ALL_TAC - ] THEN +let AES256_XTS_DECRYPT_TAIL_WHEN_1BLOCK = prove( + `!(n:num) (ct:byte list) (iv:int128) (key1:int128 list) (key2:int128 list). + bytes_to_int128 + (aes256_xts_decrypt_tail n 0x0 ct iv key1 key2) = + aes256_xts_decrypt_round + (bytes_to_int128 (SUB_LIST (n * 0x10,0x10) ct)) + (calculate_tweak n iv key2) key1`, REPEAT STRIP_TAC THEN - REWRITE_TAC[EL; TL] THEN - IMP_REWRITE_TAC[TL_SUB_LIST_CONS] THEN - REPEAT CONJ_TAC THENL - [ ASM_SIMP_TAC[ARITH_RULE `SUC i < n ==> i < n - 1`]; - SUBGOAL_THEN `LENGTH (CONS h (t:A list)) = SUC (LENGTH t)` ASSUME_TAC THENL - [ REWRITE_TAC[LENGTH]; ALL_TAC ] THEN - ASM_ARITH_TAC; - MP_TAC (ARITH_RULE `SUC i < n ==> 0 < n`) THEN - ASM_SIMP_TAC[] - ] + REWRITE_TAC[aes256_xts_decrypt_tail] THEN + REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + REWRITE_TAC[BYTES_TO_INT128_OF_INT128_TO_BYTES] );; -let EL_SUB_LIST_GENERAL = prove( - `!p (l:A list) i n. i >= p /\ i < p + n /\ p + n <= LENGTH l ==> - EL (i - p) (SUB_LIST (p, n) l) = EL i l`, - INDUCT_TAC THENL - [ IMP_REWRITE_TAC[ADD; SUB_0; EL_SUB_LIST]; - ALL_TAC - ] THEN - LIST_INDUCT_TAC THENL - [ REWRITE_TAC[SUB_LIST_CLAUSES; LENGTH] THEN - REPEAT STRIP_TAC THEN - ASM_ARITH_TAC; - ALL_TAC +let AES256_XTS_DECRYPT_REC_EQ_TAIL = prove( + `!(i:num) (k:num) (ct:byte list) (iv:int128) (key1:int128 list) (key2:int128 list). + k >= i ==> + aes256_xts_decrypt_rec i (k + 1) ct iv key1 key2 = + APPEND (aes256_xts_decrypt_rec i k ct iv key1 key2) + (aes256_xts_decrypt_tail (k + 1) 0x0 ct iv key1 key2)`, + REPEAT GEN_TAC THEN + WF_INDUCT_TAC `(k + 1) - i` THEN + STRIP_TAC THEN + GEN_REWRITE_TAC (RATOR_CONV o ONCE_DEPTH_CONV) [aes256_xts_decrypt_rec] THEN + SUBGOAL_THEN `~(k + 0x1 < i)` ASSUME_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[] THEN + REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + SUBGOAL_THEN `(k + 1) - (i + 1) < (k + 1) - i` ASSUME_TAC THENL [ ASM_ARITH_TAC; ALL_TAC] THEN + FIRST_X_ASSUM (MP_TAC o SPECL [`k:num`; `i + 1:num`]) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN + ASM_CASES_TAC `k >= i + 1` THENL + [ + ASM_SIMP_TAC[] THEN DISCH_TAC THEN + REWRITE_TAC[APPEND_ASSOC] THEN + AP_THM_TAC THEN + GEN_REWRITE_TAC (RAND_CONV o ONCE_DEPTH_CONV) [aes256_xts_decrypt_rec] THEN + SUBGOAL_THEN `~(k < i)` ASSUME_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[] THEN + REWRITE_TAC[LET_DEF; LET_END_DEF]; ALL_TAC ] THEN - REWRITE_TAC[LENGTH] THEN - REPEAT STRIP_TAC THEN - REWRITE_TAC[SUB_LIST_CLAUSES] THEN - SUBGOAL_THEN `EL i (CONS h (t:A list)) = EL (i - 1) t` SUBST1_TAC THENL - [ SUBGOAL_THEN `i = SUC (i - 1)` SUBST1_TAC THENL - [ ASM_ARITH_TAC; ALL_TAC] THEN - REWRITE_TAC[EL; TL] THEN - AP_THM_TAC THEN AP_TERM_TAC THEN - ARITH_TAC; ALL_TAC] THEN - REWRITE_TAC[ARITH_RULE `i - SUC p = i - 1 - p`] THEN - FIRST_X_ASSUM (fun th -> MP_TAC (SPECL [`t:A list`; `(i - 1):num`; `n:num`] th)) THEN - ANTS_TAC THENL [ ASM_ARITH_TAC; ALL_TAC ] THEN - SIMP_TAC[] + SUBGOAL_THEN `k:num = i` ASSUME_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + ONCE_REWRITE_TAC[aes256_xts_decrypt_rec] THEN + REWRITE_TAC[LT_REFL; LET_DEF; LET_END_DEF] THEN + ONCE_REWRITE_TAC[aes256_xts_decrypt_rec] THEN + REWRITE_TAC[ARITH_RULE `i < i + 1`; APPEND_NIL] THEN + AP_TERM_TAC THEN + REWRITE_TAC[aes256_xts_decrypt_tail; LET_DEF; LET_END_DEF] );; -let EL_SUB_LIST_SHIFT = prove( - `!(i:num) p (l:A list) n. 0 < i /\ i < n /\ n <= LENGTH l - p ==> - EL (i - 1) (SUB_LIST (p + 1, n - 1) l) = EL i (SUB_LIST (p, n) l)`, - REPEAT STRIP_TAC THEN - SUBGOAL_THEN `EL i (SUB_LIST (p, n) (l:A list)) = EL (SUC (i - 1)) (SUB_LIST (p, SUC (n - 1)) l)` SUBST1_TAC THENL - [ IMP_REWRITE_TAC[ARITH_RULE `0 < i ==> SUC (i - 1) = i`] THEN - ASM_ARITH_TAC; ALL_TAC ] THEN - DISJ_CASES_TAC (ISPEC `l:(A)list` list_CASES) THENL [ - FIRST_X_ASSUM SUBST_ALL_TAC THEN - UNDISCH_TAC `n <= LENGTH ([]:A list) - p` THEN - REWRITE_TAC[LENGTH] THEN - ASM_ARITH_TAC; ALL_TAC - ] THEN - - REPEAT_N 2 (FIRST_X_ASSUM CHOOSE_TAC) THEN - FIRST_X_ASSUM SUBST_ALL_TAC THEN - REWRITE_TAC[EL; TL] THEN - IMP_REWRITE_TAC[TL_SUB_LIST_CONS_GENERAL] THEN - IMP_REWRITE_TAC[ARITH_RULE `0 < n ==> SUC (n - 1) = n`] THEN - ASM_ARITH_TAC - );; -let BYTE_LIST_AT_SPLIT_BACKWARDS = prove( - `!(pt_ptr:int64) i len curr_len bl s. - 0 <= i ==> i < len ==> len < 16 ==> LENGTH bl >= 16 ==> - (forall j. - j < len - (i + 1) - ==> read (memory :> bytes8 - (word_add (word_add pt_ptr (word (curr_len + 16 + i + 1))) - (word j))) s = - EL j (SUB_LIST (i + 1, len - (i + 1)) bl)) ==> - read (memory :> bytes8 (word_add pt_ptr (word (curr_len + 16 + i)))) s = (EL i bl) ==> - forall j. - j < len - i - ==> read (memory :> bytes8 - (word_add (word_add pt_ptr (word (curr_len + 16 + i))) - (word j))) s = - EL j (SUB_LIST (i, len - i) bl) - `, - REPEAT GEN_TAC THEN +let SUB_LIST_OF_AES256_XTS_DECRYPT_FULL_BLOCKS = prove( + `!(i:num) (ct:byte list) (iv:int128) (key1:int128 list) (key2:int128 list). + (SUB_LIST (0,16 * i) + (aes256_xts_decrypt ct (16 * i + 16) iv key1 key2)) + = aes256_xts_decrypt ct (16 * i) iv key1 key2`, REPEAT STRIP_TAC THEN - ASM_CASES_TAC `j > 0` THENL + + (* when i = 0, trivial *) + ASM_CASES_TAC `i = 0` THENL [ - FIRST_X_ASSUM(MP_TAC o SPEC `j - 1`) THEN - ANTS_TAC THENL[ ASM_ARITH_TAC; ALL_TAC] THEN - SUBGOAL_THEN `(word_add (word_add (pt_ptr:int64) (word (curr_len + 0x10 + i + 0x1))) - (word (j - 0x1))) = (word_add (word_add pt_ptr (word (curr_len + 0x10 + i))) (word j))` SUBST1_TAC THENL - [ REWRITE_TAC[WORD_RULE `word_add (word_add a (word b)) (word c) = word_add a (word (b + c))`] THEN - AP_TERM_TAC THEN AP_TERM_TAC THEN - ASM_ARITH_TAC; ALL_TAC] THEN - SIMP_TAC[] THEN DISCH_TAC THEN - IMP_REWRITE_TAC[ARITH_RULE `len - (i + 1) = len - i - 1`; - EL_SUB_LIST_SHIFT] THEN - ASM_ARITH_TAC; + ASM_REWRITE_TAC[] THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[CONJUNCT1 SUB_LIST; aes256_xts_decrypt] THEN + CONV_TAC NUM_REDUCE_CONV; ALL_TAC ] THEN - SUBGOAL_THEN `j = 0` SUBST_ALL_TAC THENL[ASM_ARITH_TAC;ALL_TAC] THEN - REWRITE_TAC[WORD_ADD_0] THEN - ASM_REWRITE_TAC[] THEN - IMP_REWRITE_TAC[EL_SUB_LIST_TRIVIAL] THEN - ASM_ARITH_TAC -);; - -let MEMORY_READ_BYTES_SUBSET_LEMMA = prove( - `!len (bl:byte list) s. - SUC len <= LENGTH bl ==> - read (memory :> bytes (pt_ptr,SUC len)) s = - num_of_bytelist (SUB_LIST (0x0,SUC len) bl) ==> - read (memory :> bytes (pt_ptr,len)) s = - num_of_bytelist (SUB_LIST (0x0,len) bl) /\ - read (memory :> bytes8 (word_add pt_ptr (word len))) s = EL len bl`, - REPEAT GEN_TAC THEN STRIP_TAC THEN - SUBGOAL_THEN `SUC len = len + 1` SUBST_ALL_TAC THENL [ARITH_TAC; ALL_TAC] THEN - REWRITE_TAC[READ_COMPONENT_COMPOSE] THEN - SUBGOAL_THEN `len <= LENGTH (bl:byte list)` ASSUME_TAC THENL [ ASM_ARITH_TAC; ALL_TAC] THEN - (* Use READ_BYTES_COMBINE to decompose the memory read *) - MP_TAC(ISPECL [`pt_ptr:int64`; `len:num`; `1:num`; `(read memory s):int64->byte`] READ_BYTES_COMBINE) THEN - DISCH_TAC THEN - (* Use SUB_LIST_SPLIT to decompose the byte list *) - MP_TAC(ISPECL [`bl:byte list`; `len:num`; `1:num`; `0:num`] SUB_LIST_SPLIT) THEN - REWRITE_TAC[ADD_CLAUSES] THEN DISCH_TAC THEN - (* Decompose num_of_bytelist *) - SUBGOAL_THEN - `num_of_bytelist (SUB_LIST (0,len + 1) (bl:byte list)) = - num_of_bytelist (SUB_LIST (0,len) bl) + - 2 EXP (8 * len) * num_of_bytelist (SUB_LIST (len,1) bl)` - ASSUME_TAC THENL - [ ASM_REWRITE_TAC[] THEN - REWRITE_TAC[NUM_OF_BYTELIST_APPEND] THEN - AP_TERM_TAC THEN AP_THM_TAC THEN REPEAT_N 3 AP_TERM_TAC THEN - IMP_REWRITE_TAC[LENGTH_SUB_LIST; MIN; SUB_0] THEN - ASM_SIMP_TAC[] - ; ALL_TAC] THEN - (* Rewrite in goal *) - ASM_REWRITE_TAC[] THEN - DISCH_TAC THEN - CONJ_TAC THENL - [ (* First part: read (memory :> bytes (pt_ptr,len)) s = num_of_bytelist (SUB_LIST (0,len) bl) *) - FIRST_X_ASSUM(MP_TAC o AP_TERM `\x. x MOD 2 EXP (8 * len)`) THEN + (* when i = 1, using aes256_xts_decrypt_tail *) + ASM_CASES_TAC `i = 1` THENL + [ ASM_REWRITE_TAC[] THEN - REWRITE_TAC[MOD_MULT_ADD; MOD_LT] THEN - REWRITE_TAC[READ_BYTES_MOD; MIN] THEN - SIMP_TAC[ARITH_RULE `len <= len`] THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[aes256_xts_decrypt] THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + CONV_TAC NUM_REDUCE_CONV THEN + MP_TAC (SPECL [`ct:byte list`; `iv:int128`; `key1: int128 list`; `key2: int128 list`] + LENGTH_OF_AES256_XTS_DECRYPT_REC_TRIVIAL) THEN DISCH_TAC THEN - IMP_REWRITE_TAC[MOD_LT] THEN - MP_TAC (SPEC `(SUB_LIST (0,len) bl:byte list)` NUM_OF_BYTELIST_BOUND) THEN - IMP_REWRITE_TAC[LENGTH_SUB_LIST; SUB_0; MIN] THEN - SUBGOAL_THEN `256 EXP len = 2 EXP (8 * len)` SUBST1_TAC THENL - [ REWRITE_TAC[ARITH_RULE `256 = 2 EXP 8`; EXP_EXP]; ALL_TAC] THEN - SIMP_TAC[]; + IMP_REWRITE_TAC[SUB_LIST_APPEND_LEFT] THEN + CONV_TAC NUM_REDUCE_CONV THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN + REWRITE_TAC[AES256_XTS_DECRYPT_REC_EQ_TAIL_TRIVIAL]; ALL_TAC ] THEN - (* Second part: read (memory :> bytes8 (word_add pt_ptr (word len))) s = EL len bl *) - FIRST_X_ASSUM(MP_TAC o AP_TERM `\x. x DIV 2 EXP (8 * len)`) THEN - ASM_REWRITE_TAC[] THEN - SUBGOAL_THEN `~(0x2 EXP (0x8 * len) = 0x0)` ASSUME_TAC THENL - [ REWRITE_TAC[EXP_EQ_0; ARITH_EQ]; ALL_TAC] THEN - IMP_REWRITE_TAC[DIV_MULT_ADD] THEN - SUBGOAL_THEN `read (bytes (pt_ptr,len)) (read memory s) < 0x2 EXP (0x8 * len)` ASSUME_TAC THENL - [ REWRITE_TAC[READ_BYTES_BOUND]; ALL_TAC] THEN - SUBGOAL_THEN `num_of_bytelist (SUB_LIST (0x0,len) bl) < 0x2 EXP (0x8 * len)` ASSUME_TAC THENL - [ MP_TAC (SPEC `(SUB_LIST (0,len) bl:byte list)` NUM_OF_BYTELIST_BOUND) THEN - IMP_REWRITE_TAC[LENGTH_SUB_LIST; SUB_0; MIN] THEN - SUBGOAL_THEN `256 EXP len = 2 EXP (8 * len)` SUBST1_TAC THENL - [ REWRITE_TAC[ARITH_RULE `256 = 2 EXP 8`; EXP_EXP]; ALL_TAC] THEN SIMP_TAC[]; ALL_TAC] THEN - IMP_REWRITE_TAC[DIV_LT; ADD] THEN - (* Some rewrites to close the goal *) - REWRITE_TAC[bytes8; READ_COMPONENT_COMPOSE; asword; through; read] THEN - SUBGOAL_THEN `len < LENGTH (bl:byte list)` ASSUME_TAC THENL [ ASM_ARITH_TAC; ALL_TAC] THEN - ASM_SIMP_TAC[SUB_LIST_1] THEN - REWRITE_TAC[num_of_bytelist; MULT_CLAUSES; ADD_CLAUSES; WORD_VAL] -);; - -let BYTE_LIST_TO_NUM_THM = prove( - `!len (pt_ptr:int64) (bl:byte list) s. - len <= LENGTH bl ==> - ((forall i. i < len - ==> read (memory :> bytes8 (word_add pt_ptr (word i))) s = EL i bl) <=> - (read (memory :> bytes (pt_ptr, len)) s = num_of_bytelist (SUB_LIST (0, len) bl)))`, - REPEAT GEN_TAC THEN - SPEC_TAC (`len:num`, `len:num`) THEN - (* Base case: len = 0 *) - INDUCT_TAC THENL - [ STRIP_TAC THEN - REWRITE_TAC[READ_COMPONENT_COMPOSE; READ_BYTES_TRIVIAL; - CONJUNCT1 SUB_LIST; CONJUNCT1 num_of_bytelist] THEN - GEN_TAC THEN MESON_TAC[ARITH_RULE `~(i < 0)`]; - ALL_TAC] THEN - - (* Inductive step: left to right *) - STRIP_TAC THEN - EQ_TAC THENL - [ MP_TAC (ARITH_RULE `SUC len <= LENGTH (bl:byte list) ==> len <= LENGTH bl`) THEN - ASM_SIMP_TAC[] THEN REPEAT DISCH_TAC THEN - MP_TAC (SPECL [`len:num`; `bl:byte list`; `s:armstate`] MEMORY_READ_SUBSET_LEMMA) THEN - ASM_SIMP_TAC[] THEN - DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN - REWRITE_TAC[READ_COMPONENT_COMPOSE; ADD1] THEN - ONCE_REWRITE_TAC[READ_BYTES_COMBINE] THEN - REWRITE_TAC[SUB_LIST_SPLIT; NUM_OF_BYTELIST_APPEND; CONJUNCT1 ADD] THEN - IMP_REWRITE_TAC[ARITH_RULE `a = c ==> (a + b = c + d) = (b = d)`] THEN - CONJ_TAC THENL [ - REWRITE_TAC[LENGTH_SUB_LIST; MIN; SUB_0] THEN - ASM_SIMP_TAC[] THEN - AP_TERM_TAC THEN - REWRITE_TAC[GSYM READ_COMPONENT_COMPOSE] THEN - FIRST_X_ASSUM (fun th -> MP_TAC (SPEC `len:num` th)) THEN - REWRITE_TAC[ARITH_RULE `len < SUC len`] THEN - SUBGOAL_THEN `len < LENGTH (bl:byte list)` ASSUME_TAC THENL - [ ASM_ARITH_TAC; ALL_TAC] THEN - ASM_REWRITE_TAC[SUB_LIST_1; num_of_bytelist] THEN - CONV_TAC NUM_REDUCE_CONV THEN - REWRITE_TAC[ADD_0] THEN - STRIP_TAC THEN AP_TERM_TAC THEN ASM_SIMP_TAC[] - ; ALL_TAC] THEN - REWRITE_TAC[GSYM READ_COMPONENT_COMPOSE] THEN - ASM_SIMP_TAC[] - ; ALL_TAC] THEN - - (* Inductive step: right to left *) - MP_TAC (ARITH_RULE `SUC len <= LENGTH (bl:byte list) ==> len <= LENGTH bl`) THEN - ASM_SIMP_TAC[] THEN REPEAT DISCH_TAC THEN - MP_TAC (SPECL [`len:num`; `bl:byte list`; `s:armstate`] MEMORY_READ_BYTES_SUBSET_LEMMA) THEN - ASM_SIMP_TAC[] THEN - DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN - IMP_REWRITE_TAC[BYTE_LIST_AT_SPLIT] THEN - CONJ_TAC THENL [ASM_SIMP_TAC[]; ALL_TAC] THEN - ASM_SIMP_TAC[] -);; - -let MEMORY_BYTES_BOUND = prove - (`read (memory :> bytes (x,16)) s < 2 EXP dimindex (:128)`, - REWRITE_TAC[READ_COMPONENT_COMPOSE; DIMINDEX_128] THEN - SUBST1_TAC(ARITH_RULE `128 = 8 * 16`) THEN REWRITE_TAC[READ_BYTES_BOUND] - );; - -(* Copied from bignum_copy_row_from_table_8n.ml *) -let READ_MEMORY_BYTES_BYTES128 = prove(`!z s. - read (memory :> bytes (z,16)) s = val (read (memory :> bytes128 z) s)`, - REPEAT GEN_TAC THEN - REWRITE_TAC[el 1 (CONJUNCTS READ_MEMORY_BYTESIZED_SPLIT)] THEN - REWRITE_TAC[VAL_WORD_JOIN;DIMINDEX_64;DIMINDEX_128] THEN - IMP_REWRITE_TAC[MOD_LT] THEN - REWRITE_TAC[ARITH_RULE`2 EXP 128 = 2 EXP 64 * 2 EXP 64`] THEN - IMP_REWRITE_TAC[LT_MULT_ADD_MULT] THEN - REWRITE_TAC[VAL_BOUND_64;ARITH_RULE`0<2 EXP 64`;LE_REFL] THEN - REWRITE_TAC[ARITH_RULE`16 = 8*(1+1)`;GSYM BIGNUM_FROM_MEMORY_BYTES;BIGNUM_FROM_MEMORY_STEP;BIGNUM_FROM_MEMORY_SING] THEN - REWRITE_TAC[ARITH_RULE`8*1=8`;ARITH_RULE`64*1=64`] THEN ARITH_TAC);; - -let READ_MEMORY_BYTES128_BYTES = prove(`!z s. - read (memory :> bytes128 z) s = word (read (memory :> bytes (z,16)) s)`, - REPEAT STRIP_TAC THEN - ONCE_REWRITE_TAC[GSYM VAL_EQ] THEN - IMP_REWRITE_TAC [VAL_WORD_EQ] THEN - CONJ_TAC THENL [REWRITE_TAC [READ_MEMORY_BYTES_BYTES128]; ALL_TAC] THEN - REWRITE_TAC [MEMORY_BYTES_BOUND] - );; -let WORD_JOIN_BOUND_TAC x y = - REWRITE_TAC[VAL_WORD_JOIN; DIMINDEX_CLAUSES] THEN - CONV_TAC NUM_REDUCE_CONV THEN - IMP_REWRITE_TAC[MOD_LT] THEN - CONJ_TAC THENL[ REWRITE_TAC[ADD_SYM]; ALL_TAC ] THEN - MP_TAC (ISPECL [x] VAL_BOUND) THEN - MP_TAC (ISPECL [y] VAL_BOUND) THEN - REWRITE_TAC[DIMINDEX_CLAUSES] THEN + (* when i >= 2, using aes256_xts_decrypt_rec *) + REWRITE_TAC[aes256_xts_decrypt] THEN CONV_TAC NUM_REDUCE_CONV THEN - ARITH_TAC;; - -let WORD_JOIN_16_8_ASSOC = WORD_BLAST - `!(x0:byte) (x1:byte) (x2:byte) (x3:byte) - (x4:byte) (x5:byte) (x6:byte) (x7:byte) - (x8:byte) (x9:byte) (x10:byte) (x11:byte) - (x12:byte) (x13:byte) (x14:byte) (x15:byte). - (word_join - (word_join - (word_join (word_join x15 x14 : int16) (word_join x13 x12 : int16) : int32) - (word_join (word_join x11 x10 : int16) (word_join x9 x8 : int16) : int32) : int64) - (word_join - (word_join (word_join x7 x6 : int16) (word_join x5 x4 : int16) : int32) - (word_join (word_join x3 x2 : int16) (word_join x1 x0 : int16) : int32) : int64)) = - (word_join - (word_join - (word_join - (word_join - (word_join - (word_join - (word_join - (word_join - (word_join - (word_join - (word_join - (word_join - (word_join - (word_join - (word_join x15 x14:16 word) - x13:24 word) - x12:32 word) - x11:40 word) - x10:48 word) - x9:56 word) - x8:64 word) - x7:72 word) - x6:80 word) - x5:88 word) - x4:96 word) - x3:104 word) - x2:112 word) - x1:120 word) - x0:128 word)`;; - -let VAL_OF_BYTES_TO_INT128_EQ_NUM_OF_BYTELIST = prove( - `!x:byte list. LENGTH x = 16 ==> val (bytes_to_int128 x) = num_of_bytelist x`, - REPEAT STRIP_TAC THEN - (* conversion for breaking down a list *) - MP_TAC ((GEN_REWRITE_CONV I [LENGTH_EQ_LIST_OF_SEQ] THENC - RAND_CONV LIST_OF_SEQ_CONV) `LENGTH (x:byte list) = 16`) THEN + SUBGOAL_THEN `~(0x10 * i < 0x10)` ASSUME_TAC THENL + [ ASM_ARITH_TAC ; ALL_TAC] THEN + SUBGOAL_THEN `~(0x10 * i + 0x10 < 0x10)` ASSUME_TAC THENL + [ ASM_ARITH_TAC ; ALL_TAC] THEN ASM_SIMP_TAC[] THEN - DISCH_THEN (fun th -> ONCE_REWRITE_TAC[th]) THEN - REWRITE_TAC[bytes_to_int128] THEN - REWRITE_TAC EL_16_8_CLAUSES THEN - REPEAT_N 16 (ONCE_REWRITE_TAC[num_of_bytelist]) THEN - REWRITE_TAC[CONJUNCT1 num_of_bytelist] THEN - MAP_EVERY ABBREV_TAC - [`x0 = EL 0 x:byte`; `x1 = EL 1 x:byte`; `x2 = EL 2 x:byte`; `x3 = EL 3 x:byte`; - `x4 = EL 4 x:byte`; `x5 = EL 5 x:byte`; `x6 = EL 6 x:byte`; `x7 = EL 7 x:byte`; - `x8 = EL 8 x:byte`; `x9 = EL 9 x:byte`; `x10 = EL 10 x:byte`; `x11 = EL 11 x:byte`; - `x12 = EL 12 x:byte`; `x13 = EL 13 x:byte`; `x14 = EL 14 x:byte`; `x15 = EL 15 x:byte`] THEN + REWRITE_TAC[ARITH_RULE `16 * i + 16 = 16 * (i + 1)`; MOD_MULT] THEN + IMP_REWRITE_TAC[LET_DEF;LET_END_DEF;SUB_0;DIV_MULT] THEN CONV_TAC NUM_REDUCE_CONV THEN - REWRITE_TAC[ADD_0; WORD_JOIN_16_8_ASSOC] THEN - (* reduce RHS to LHS *) - SUBGOAL_THEN `val (x14:byte) + 0x100 * val (x15:byte) = val ((word_join x15 x14):int16)` SUBST1_TAC THENL - [ WORD_JOIN_BOUND_TAC `x15:byte` `x14:byte`; ALL_TAC] THEN ABBREV_TAC `y14:int16 = word_join (x15:byte) (x14:byte)` THEN - SUBGOAL_THEN `val (x13:byte) + 0x100 * val (y14:16 word) = val ((word_join y14 x13):24 word)` SUBST1_TAC THENL - [ WORD_JOIN_BOUND_TAC `y14:16 word` `x13:byte`; ALL_TAC] THEN ABBREV_TAC `y13:24 word = word_join (y14:16 word) (x13:byte)` THEN - SUBGOAL_THEN `val (x12:byte) + 0x100 * val (y13:24 word) = val ((word_join y13 x12):32 word)` SUBST1_TAC THENL - [ WORD_JOIN_BOUND_TAC `y13:24 word` `x12:byte`; ALL_TAC] THEN ABBREV_TAC `y12:32 word = word_join (y13:24 word) (x12:byte)` THEN - SUBGOAL_THEN `val (x11:byte) + 0x100 * val (y12:32 word) = val ((word_join y12 x11):40 word)` SUBST1_TAC THENL - [ WORD_JOIN_BOUND_TAC `y12:32 word` `x11:byte`; ALL_TAC] THEN ABBREV_TAC `y11:40 word = word_join (y12:32 word) (x11:byte)` THEN - SUBGOAL_THEN `val (x10:byte) + 0x100 * val (y11:40 word) = val ((word_join y11 x10):48 word)` SUBST1_TAC THENL - [ WORD_JOIN_BOUND_TAC `y11:40 word` `x10:byte`; ALL_TAC] THEN ABBREV_TAC `y10:48 word = word_join (y11:40 word) (x10:byte)` THEN - SUBGOAL_THEN `val (x9:byte) + 0x100 * val (y10:48 word) = val ((word_join y10 x9):56 word)` SUBST1_TAC THENL - [ WORD_JOIN_BOUND_TAC `y10:48 word` `x9:byte`; ALL_TAC] THEN ABBREV_TAC `y9:56 word = word_join (y10:48 word) (x9:byte)` THEN - SUBGOAL_THEN `val (x8:byte) + 0x100 * val (y9:56 word) = val ((word_join y9 x8):64 word)` SUBST1_TAC THENL - [ WORD_JOIN_BOUND_TAC `y9:56 word` `x8:byte`; ALL_TAC] THEN ABBREV_TAC `y8:64 word = word_join (y9:56 word) (x8:byte)` THEN - SUBGOAL_THEN `val (x7:byte) + 0x100 * val (y8:64 word) = val ((word_join y8 x7):72 word)` SUBST1_TAC THENL - [ WORD_JOIN_BOUND_TAC `y8:64 word` `x7:byte`; ALL_TAC] THEN ABBREV_TAC `y7:72 word = word_join (y8:64 word) (x7:byte)` THEN - SUBGOAL_THEN `val (x6:byte) + 0x100 * val (y7:72 word) = val ((word_join y7 x6):80 word)` SUBST1_TAC THENL - [ WORD_JOIN_BOUND_TAC `y7:72 word` `x6:byte`; ALL_TAC] THEN ABBREV_TAC `y6:80 word = word_join (y7:72 word) (x6:byte)` THEN - SUBGOAL_THEN `val (x5:byte) + 0x100 * val (y6:80 word) = val ((word_join y6 x5):88 word)` SUBST1_TAC THENL - [ WORD_JOIN_BOUND_TAC `y6:80 word` `x5:byte`; ALL_TAC] THEN ABBREV_TAC `y5:88 word = word_join (y6:80 word) (x5:byte)` THEN - SUBGOAL_THEN `val (x4:byte) + 0x100 * val (y5:88 word) = val ((word_join y5 x4):96 word)` SUBST1_TAC THENL - [ WORD_JOIN_BOUND_TAC `y5:88 word` `x4:byte`; ALL_TAC] THEN ABBREV_TAC `y4:96 word = word_join (y5:88 word) (x4:byte)` THEN - SUBGOAL_THEN `val (x3:byte) + 0x100 * val (y4:96 word) = val ((word_join y4 x3):104 word)` SUBST1_TAC THENL - [ WORD_JOIN_BOUND_TAC `y4:96 word` `x3:byte`; ALL_TAC] THEN ABBREV_TAC `y3:104 word = word_join (y4:96 word) (x3:byte)` THEN - SUBGOAL_THEN `val (x2:byte) + 0x100 * val (y3:104 word) = val ((word_join y3 x2):112 word)` SUBST1_TAC THENL - [ WORD_JOIN_BOUND_TAC `y3:104 word` `x2:byte`; ALL_TAC] THEN ABBREV_TAC `y2:112 word = word_join (y3:104 word) (x2:byte)` THEN - SUBGOAL_THEN `val (x1:byte) + 0x100 * val (y2:112 word) = val ((word_join y2 x1):120 word)` SUBST1_TAC THENL - [ WORD_JOIN_BOUND_TAC `y2:112 word` `x1:byte`; ALL_TAC] THEN ABBREV_TAC `y1:120 word = word_join (y2:112 word) (x1:byte)` THEN - SUBGOAL_THEN `val (x0:byte) + 0x100 * val (y1:120 word) = val ((word_join y1 x0):128 word)` SUBST1_TAC THENL - [ WORD_JOIN_BOUND_TAC `y1:120 word` `x0:byte`; ALL_TAC] THEN ABBREV_TAC `y0:128 word = word_join (y1:120 word) (x0:byte)` THEN - REFL_TAC + SUBGOAL_THEN `~(i < 0x2)` ASSUME_TAC THENL + [ ASM_ARITH_TAC ; ALL_TAC] THEN + SUBGOAL_THEN `~(i + 1 < 0x2)` ASSUME_TAC THENL + [ ASM_ARITH_TAC ; ALL_TAC] THEN + ASM_SIMP_TAC[ARITH_RULE `(i + 0x1) - 0x2 = i - 1`; ADD_SUB] THEN + SUBGOAL_THEN `LENGTH (aes256_xts_decrypt_rec 0x0 (i - 0x1) ct iv key1 key2) = 16 * i` ASSUME_TAC THENL + [ REWRITE_TAC[LENGTH_OF_AES256_XTS_DECRYPT_REC] THEN + ASM_ARITH_TAC; ALL_TAC] THEN + IMP_REWRITE_TAC[SUB_LIST_APPEND_LEFT; SUB_LIST_LENGTH_IMPLIES] THEN + CONJ_TAC THENL [ALL_TAC; ARITH_TAC] THEN + SUBGOAL_THEN `i - 1 = i - 2 + 1` ASSUME_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC ] THEN + ASM_REWRITE_TAC[] THEN + IMP_REWRITE_TAC[AES256_XTS_DECRYPT_REC_EQ_TAIL] THEN + ASM_ARITH_TAC );; -let READ_BYTES_AND_BYTE128_SPLIT = prove( - `!(pt_ptr:int64) (sz:num) (x:byte list) (s:armstate). - sz + 16 <= LENGTH x ==> - read (memory :> bytes128 (word_add pt_ptr (word sz))) s = bytes_to_int128 (SUB_LIST (sz, 0x10) x) - /\ read (memory :> bytes (pt_ptr, sz)) s = num_of_bytelist (SUB_LIST (0, sz) x) - ==> read (memory :> bytes (pt_ptr,sz + 0x10)) s = num_of_bytelist (SUB_LIST (0, sz + 0x10) x)`, - REWRITE_TAC[READ_MEMORY_BYTES128_BYTES] THEN +let SUB_LIST_OF_AES256_XTS_DECRYPT = prove( + `!(i:num) (tail_len:num) (ct:byte list) (iv:int128) (key1:int128 list) (key2:int128 list). + ~(tail_len = 0) /\ tail_len < 16 ==> + (SUB_LIST (0,16 * i) + (aes256_xts_decrypt ct (16 * i + 16 + tail_len) iv key1 key2)) + = aes256_xts_decrypt ct (16 * i) iv key1 key2`, REPEAT STRIP_TAC THEN - - SUBGOAL_THEN `sz <= LENGTH (x:byte list)` ASSUME_TAC THENL - [ UNDISCH_TAC `sz + 16 <= LENGTH (x:byte list)` THEN ARITH_TAC; ALL_TAC ] THEN - - SUBGOAL_THEN `16 <= LENGTH (x:byte list) - sz` ASSUME_TAC THENL - [ UNDISCH_TAC `sz + 16 <= LENGTH (x:byte list)` THEN ARITH_TAC; ALL_TAC ] THEN - - SUBGOAL_THEN `read (memory :> bytes (pt_ptr, sz + 16)) s = - read (memory :> bytes (pt_ptr, sz)) s + - 2 EXP (8 * sz) * (read (memory :> bytes (word_add pt_ptr (word sz), 16)) s)` SUBST1_TAC THENL - [ REWRITE_TAC[READ_COMPONENT_COMPOSE] THEN - REWRITE_TAC[READ_BYTES_COMBINE]; ALL_TAC] THEN - - ASM_REWRITE_TAC[] THEN - SUBGOAL_THEN `read (memory :> bytes (word_add pt_ptr (word sz),0x10)) s = - val (bytes_to_int128 (SUB_LIST (sz,0x10) x))` SUBST1_TAC THENL - [ UNDISCH_THEN - `word (read (memory :> bytes (word_add (pt_ptr:int64) (word sz),0x10)) s) = - bytes_to_int128 (SUB_LIST (sz,0x10) x)` - (fun th -> MP_TAC (AP_TERM `val:int128->num` th)) THEN - IMP_REWRITE_TAC[VAL_WORD] THEN - SUBGOAL_THEN `read (memory :> bytes (word_add pt_ptr (word sz),0x10)) s < 2 EXP dimindex (:128)` ASSUME_TAC THENL - [ SIMP_TAC[MEMORY_BYTES_BOUND] ; ALL_TAC] THEN - SUBST_ALL_TAC DIMINDEX_128 THEN - ASM_SIMP_TAC[MOD_LT]; ALL_TAC] THEN - - IMP_REWRITE_TAC[NUM_OF_BYTELIST_OF_SUB_LIST] THEN - IMP_REWRITE_TAC[VAL_OF_BYTES_TO_INT128_EQ_NUM_OF_BYTELIST] THEN - REWRITE_TAC[LENGTH_SUB_LIST; MIN] THEN ASM_SIMP_TAC[] - );; - - -let SUB_LIST_APPEND_RIGHT_LEMMA = prove( - `!(x:A list) y n m. LENGTH x = n ==> SUB_LIST (n,m) (APPEND x y) = SUB_LIST (0,m) y`, - LIST_INDUCT_TAC THENL - [ REPEAT GEN_TAC THEN - SIMP_TAC[CONJUNCT1 LENGTH; APPEND; SUB_LIST_CLAUSES]; - - ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN - INDUCT_TAC THENL[ - SIMP_TAC[LENGTH_EQ_NIL] THEN REWRITE_TAC[APPEND]; - ASM_SIMP_TAC[APPEND; LENGTH; SUB_LIST_CLAUSES; SUC_INJ]]]);; - -let SUB_LIST_APPEND_RIGHT_GENERAL = prove( - `!(x:A list) y n m p. LENGTH x = p ==> n >= p ==> - SUB_LIST (n,m) (APPEND x y) = SUB_LIST (n - p,m) y`, - LIST_INDUCT_TAC THENL + (* Case 1: i = 0 *) + ASM_CASES_TAC `i = 0` THENL [ - REPEAT GEN_TAC THEN - SIMP_TAC[CONJUNCT1 LENGTH; APPEND; SUB_LIST_CLAUSES] THEN - DISCH_THEN (fun th -> REWRITE_TAC[GSYM th]) THEN - REWRITE_TAC[SUB_0]; - - ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN - INDUCT_TAC THENL - [ - REPEAT STRIP_TAC THEN - SUBGOAL_THEN `p = 0` SUBST_ALL_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN - CONV_TAC NUM_REDUCE_CONV THEN - SUBGOAL_THEN `CONS h t = ([]:A list)` ASSUME_TAC THENL - [ UNDISCH_TAC `LENGTH (CONS h (t:A list)) = 0` THEN - SIMP_TAC[LENGTH_EQ_NIL]; ALL_TAC] THEN - ASM_REWRITE_TAC[] THEN - REWRITE_TAC[APPEND]; - - REPEAT STRIP_TAC THEN - SUBGOAL_THEN `p > 0` ASSUME_TAC THENL - [ UNDISCH_TAC `LENGTH (CONS h (t:A list)) = p` THEN - ASM_REWRITE_TAC[LENGTH] THEN - MP_TAC (SPEC `LENGTH (t:A list)` (ARITH_RULE `!x. SUC x > 0`)) THEN - ARITH_TAC; ALL_TAC] THEN - SUBGOAL_THEN `LENGTH (t:A list) = p - 1` ASSUME_TAC THENL - [ UNDISCH_TAC `LENGTH (CONS h (t:A list)) = p` THEN - ASM_REWRITE_TAC[LENGTH] THEN - MP_TAC (SPECL [`LENGTH (t:A list)`; `p:num`] (ARITH_RULE `!n m. SUC n = m ==> n = m - 1`)) THEN - SIMP_TAC[]; ALL_TAC] THEN - SUBGOAL_THEN `n >= p - 1` ASSUME_TAC THENL - [ MP_TAC (ARITH_RULE `SUC n >= p /\ p > 0 ==> n >= p - 1`) THEN - ASM_ARITH_TAC; ALL_TAC] THEN - SUBGOAL_THEN `SUC n - p = n - (p - 1)` ASSUME_TAC THENL - [ MP_TAC (ARITH_RULE `SUC n >= p /\ p > 0 ==> SUC n - p = n - (p - 1)`) THEN - ASM_ARITH_TAC; ALL_TAC] THEN - ASM_REWRITE_TAC[APPEND; LENGTH; SUB_LIST_CLAUSES; SUC_INJ] THEN - FIRST_X_ASSUM (fun th -> MP_TAC (SPECL [`y:A list`; `n:num`; `m:num`; `(p-1):num`] th)) THEN - ASM_SIMP_TAC[] - ] - ] -);; - -let SUB_LIST_LENGTH_IMPLIES = prove( - `!(l:A list) n. LENGTH l = n ==> SUB_LIST(0,n) l = l`, - REPEAT STRIP_TAC THEN - UNDISCH_THEN `LENGTH (l:A list) = n` (fun th -> REWRITE_TAC[GSYM th]) THEN - REWRITE_TAC[SUB_LIST_LENGTH] -);; - -let SUB_LIST_IDEMPOTENT_P = prove( - `!p n (l:(A)list). SUB_LIST (0,n) (SUB_LIST (p,n) l) = SUB_LIST (p,n) l`, - INDUCT_TAC THENL[ - REWRITE_TAC[SUB_LIST_IDEMPOTENT]; - - REPEAT STRIP_TAC THEN - DISJ_CASES_TAC (ISPEC `l:(A)list` list_CASES) THENL [ - ASM_REWRITE_TAC[] THEN REWRITE_TAC[SUB_LIST_CLAUSES]; - ALL_TAC - ] THEN - FIRST_X_ASSUM MP_TAC THEN STRIP_TAC THEN - ASM_REWRITE_TAC[] THEN REWRITE_TAC[SUB_LIST_CLAUSES] THEN - ASM_REWRITE_TAC[] - ]);; - -let SUB_LIST_MIN_RIGHT = prove( - `!p (l:(A)list) (n:num) m. SUB_LIST (0,n) (SUB_LIST (p,m) l) = SUB_LIST (p, MIN n m) l`, - REPEAT STRIP_TAC THEN - ASM_CASES_TAC `(m:num) <= n` THENL [ - FIRST_X_ASSUM MP_TAC THEN REWRITE_TAC[LE_EXISTS] THEN - STRIP_TAC THEN ASM_REWRITE_TAC[] THEN - REWRITE_TAC[SUB_LIST_SPLIT;ADD_CLAUSES;ARITH_RULE`MIN ((x:num)+y) x = x`] THEN - REWRITE_TAC[SUB_LIST_IDEMPOTENT_P] THEN - GEN_REWRITE_TAC RAND_CONV [GSYM APPEND_NIL] THEN - AP_TERM_TAC THEN MATCH_MP_TAC SUB_LIST_TRIVIAL THEN - REWRITE_TAC[LENGTH_SUB_LIST] THEN ARITH_TAC; ALL_TAC] THEN - - IMP_REWRITE_TAC[ARITH_RULE `~(m <= n) ==> MIN n m = n`] THEN - FIRST_X_ASSUM MP_TAC THEN REWRITE_TAC[NOT_LE;LT_EXISTS] THEN - STRIP_TAC THEN ASM_REWRITE_TAC[] THEN - REWRITE_TAC[SUB_LIST_SPLIT;ADD_CLAUSES;ARITH_RULE`MIN (x:num) (x+y) = x`] THEN - - MP_TAC (ISPECL [`l:A list`; `p:num`; `n:num`] LENGTH_SUB_LIST) THEN - ASM_CASES_TAC `n <= LENGTH (l:A list) - p` THENL [ - IMP_REWRITE_TAC[ARITH_RULE `!n m. n <= m ==> MIN n m = n`] THEN - DISCH_TAC THEN - IMP_REWRITE_TAC[SUB_LIST_APPEND_LEFT] THEN - IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN - ARITH_TAC; ALL_TAC - ] THEN - - IMP_REWRITE_TAC[ARITH_RULE `!n m. ~(n <= m) ==> MIN n m = m`] THEN - SUBGOAL_THEN `SUB_LIST (p + n,SUC d) (l:A list) = []` SUBST1_TAC THENL - [ MATCH_MP_TAC SUB_LIST_TRIVIAL THEN - ASM_ARITH_TAC; ALL_TAC] THEN - REWRITE_TAC[APPEND_NIL] THEN - REWRITE_TAC[SUB_LIST_IDEMPOTENT_P] -);; - -let SUB_LIST_MIN_LEFT = prove( - `!q (l:A list) n m. - SUB_LIST (q,n) (SUB_LIST (0,m) l) = SUB_LIST (q, MIN n (m - q)) l`, - REPEAT STRIP_TAC THEN - ASM_CASES_TAC `n <= m - q` THENL [ - IMP_REWRITE_TAC[ARITH_RULE `x <= y ==> MIN x y = x`] THEN - UNDISCH_TAC `n <= m - q` THEN - MAP_EVERY SPEC1_TAC [`n:num`; `l:A list`; `q:num`; `m:num`] THEN - (* Induct over m *) - INDUCT_TAC THENL - [ - REPEAT STRIP_TAC THEN - IMP_REWRITE_TAC[ARITH_RULE `n <= 0 - q ==> n = 0`] THEN - REWRITE_TAC[SUB_LIST_CLAUSES]; - - INDUCT_TAC THENL - [ - REWRITE_TAC[SUB_0] THEN - REPEAT STRIP_TAC THEN - MP_TAC (SPECL [`0:num`; `l:A list`; `n:num`; `SUC m:num`] SUB_LIST_MIN_RIGHT) THEN - IMP_REWRITE_TAC[ARITH_RULE `x <= y ==> MIN x y = x`]; - - LIST_INDUCT_TAC THENL[ - REWRITE_TAC[SUB_LIST_CLAUSES]; - REWRITE_TAC[SUB_LIST_CLAUSES] THEN - REPEAT STRIP_TAC THEN - FIRST_X_ASSUM - (fun th -> MP_TAC - (SPECL [`q:num`; `t:A list`; `n:num`] th)) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN - SIMP_TAC[] - ] - ] - ]; ALL_TAC + ASM_REWRITE_TAC[] THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[ADD; SUB_LIST_CLAUSES; aes256_xts_decrypt] THEN + CONV_TAC NUM_REDUCE_CONV; + ALL_TAC ] THEN - - (* Case n > m - q*) - IMP_REWRITE_TAC[ARITH_RULE `~(x <= y) ==> MIN x y = y`] THEN - UNDISCH_TAC `~(n <= m - q)` THEN - MAP_EVERY SPEC1_TAC [`n:num`; `l:A list`; `q:num`; `m:num`] THEN - INDUCT_TAC THENL + (* Case 2: i = 1 *) + ASM_CASES_TAC `i = 1` THENL [ - REPEAT STRIP_TAC THEN - REWRITE_TAC[ARITH_RULE `0 - q = 0`] THEN - REWRITE_TAC[SUB_LIST_CLAUSES]; - - INDUCT_TAC THENL - [ - REWRITE_TAC[SUB_0] THEN - REPEAT STRIP_TAC THEN - MP_TAC (SPECL [`0:num`; `l:A list`; `n:num`; `SUC m:num`] SUB_LIST_MIN_RIGHT) THEN - IMP_REWRITE_TAC[ARITH_RULE `~(x <= y) ==> MIN x y = y`]; - - LIST_INDUCT_TAC THENL[ - REWRITE_TAC[SUB_LIST_CLAUSES]; - REWRITE_TAC[SUB_LIST_CLAUSES] THEN - REPEAT STRIP_TAC THEN - REWRITE_TAC[ARITH_RULE `SUC m - SUC q = m - q`] THEN - FIRST_X_ASSUM - (fun th -> MP_TAC - (SPECL [`q:num`; `t:A list`; `n:num`] th)) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN - SIMP_TAC[] - ] - ] - ] -);; - -let SUB_LIST_MIN_GENERAL = prove( - `!p q (l:(A)list) (n:num) m. - SUB_LIST (q,n) (SUB_LIST (p,m) l) = SUB_LIST (p + q, MIN n (m - q)) l`, - REPEAT STRIP_TAC THEN - (* Case n <= m - q *) - ASM_CASES_TAC `n <= m - q` THENL [ - IMP_REWRITE_TAC[ARITH_RULE `x <= y ==> MIN x y = x`] THEN - (* Induct over p *) - UNDISCH_TAC `n <= m - q` THEN - MAP_EVERY SPEC1_TAC [`m:num`; `n:num`; `l:A list`; `q:num`; `p:num`] THEN - INDUCT_TAC THENL - [ - REWRITE_TAC[ADD] THEN - REPEAT STRIP_TAC THEN - MP_TAC (SPECL [`q:num`; `l:A list`; `n:num`; `m:num`] SUB_LIST_MIN_LEFT) THEN - IMP_REWRITE_TAC[ARITH_RULE `x <= y ==> MIN x y = x`]; - ALL_TAC - ] THEN - - ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN - LIST_INDUCT_TAC THENL[ - REWRITE_TAC[SUB_LIST_CLAUSES]; - REWRITE_TAC[ARITH_RULE `SUC p + q = SUC (p + q)`] THEN - REWRITE_TAC[SUB_LIST_CLAUSES] THEN - ASM_REWRITE_TAC[] - ]; ALL_TAC + ASM_REWRITE_TAC[] THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[aes256_xts_decrypt; ADD_ASSOC] THEN + CONV_TAC NUM_REDUCE_CONV THEN + SUBGOAL_THEN `~(0x20 + tail_len < 0x10)` ASSUME_TAC THENL [ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[] THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + CONV_TAC NUM_REDUCE_CONV THEN + SUBGOAL_THEN `(0x20 + tail_len) MOD 0x10 = tail_len` ASSUME_TAC THENL + [ ASM_SIMP_TAC[ARITH_RULE `32 = 2 * 16`; MOD_MULT_ADD] THEN + IMP_REWRITE_TAC[MOD_LT] + ; ALL_TAC] THEN + SUBGOAL_THEN `((0x20 + tail_len) - (0x20 + tail_len) MOD 0x10) DIV 0x10 = 0x2` ASSUME_TAC THENL + [ ASM_REWRITE_TAC[ADD_ASSOC; ADD_SUB] THEN + ARITH_TAC ; ALL_TAC] THEN + ASM_SIMP_TAC[] THEN + CONV_TAC NUM_REDUCE_CONV THEN + ASM_REWRITE_TAC[] THEN + MP_TAC (SPECL [`ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT_REC_TRIVIAL) THEN + DISCH_TAC THEN IMP_REWRITE_TAC[SUB_LIST_APPEND_LEFT] THEN + REWRITE_TAC[AES256_XTS_DECRYPT_REC_EQ_TAIL_TRIVIAL] THEN + MP_TAC (SPECL [`ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT_TAIL_TRIVIAL) THEN + DISCH_TAC THEN IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN + ARITH_TAC; + ALL_TAC ] THEN - (* Case n > m - q*) - IMP_REWRITE_TAC[ARITH_RULE `~(x <= y) ==> MIN x y = y`] THEN - UNDISCH_TAC `~(n <= m - q)` THEN - MAP_EVERY SPEC1_TAC [`m:num`; `n:num`; `l:A list`; `q:num`; `p:num`] THEN - INDUCT_TAC THENL + (* Case 3: i >= 2 *) + ASM_CASES_TAC `i >= 2` THENL [ - REWRITE_TAC[ADD] THEN - REPEAT STRIP_TAC THEN - MP_TAC (SPECL [`q:num`; `l:A list`; `n:num`; `m:num`] SUB_LIST_MIN_LEFT) THEN - IMP_REWRITE_TAC[ARITH_RULE `~(x <= y) ==> MIN x y = y`]; + ASM_REWRITE_TAC[ADD_ASSOC] THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[aes256_xts_decrypt] THEN + SUBGOAL_THEN `~(0x10 * i < 0x10)` ASSUME_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `~((0x10 * i + 0x10) + tail_len < 0x10)` ASSUME_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[LET_DEF; LET_END_DEF] THEN + SUBGOAL_THEN `((0x10 * i + 0x10) + tail_len) MOD 0x10 = tail_len` SUBST1_TAC THENL + [ REWRITE_TAC[ARITH_RULE `0x10 * i + 0x10 = 16 * (i + 1)`] THEN + IMP_REWRITE_TAC[MOD_MULT_ADD; MOD_LT] + ; ALL_TAC] THEN + REWRITE_TAC[ADD_SUB; MOD_MULT; SUB_0; + ARITH_RULE `0x10 * i + 0x10 = 16 * (i + 1)`] THEN + IMP_REWRITE_TAC[DIV_MULT] THEN + SUBGOAL_THEN `~(i + 1 < 2)` ASSUME_TAC THENL [ ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `~(i < 2)` ASSUME_TAC THENL [ ASM_ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[ADD_SUB; ARITH_RULE `(i + 1) - 2 = i - 1`] THEN + CONV_TAC NUM_REDUCE_CONV THEN + MP_TAC (SPECL [`0:num`; `(i - 1):num`; `ct:byte list`; `iv:int128`; + `key1:int128 list`; `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT_REC) THEN + SUBGOAL_THEN `~((i - 1) < 0)` ASSUME_TAC THENL [ ASM_ARITH_TAC; ALL_TAC] THEN + IMP_REWRITE_TAC[ARITH_RULE `i >= 2 ==> i - 0x1 - 0x0 + 0x1 = i`] THEN + IMP_REWRITE_TAC[SUB_LIST_APPEND_LEFT] THEN + SIMP_TAC[ARITH_RULE `16 * i <= i * 16`] THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN + SIMP_TAC[ARITH_RULE `i * 16 = 16 * i`] THEN + DISCH_TAC THEN + MP_TAC (SPECL [`0`; `(i-2):num`; `ct:byte list`; `iv:int128`; + `key1:int128 list`; `key2:int128 list`] AES256_XTS_DECRYPT_REC_EQ_TAIL) THEN + ANTS_TAC THENL [ ASM_ARITH_TAC; ALL_TAC ] THEN + IMP_REWRITE_TAC[ARITH_RULE `i >= 2 ==> i - 0x2 + 0x1 = i - 1`]; ALL_TAC ] THEN - ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN - LIST_INDUCT_TAC THENL[ - REWRITE_TAC[SUB_LIST_CLAUSES]; - REWRITE_TAC[ARITH_RULE `SUC p + q = SUC (p + q)`] THEN - REWRITE_TAC[SUB_LIST_CLAUSES] THEN - ASM_REWRITE_TAC[] - ] -);; - -let LENGTH_OF_INT128_TO_BYTES = prove( - `!x. LENGTH(int128_to_bytes x) = 16`, - STRIP_TAC THEN - REWRITE_TAC[int128_to_bytes] THEN - REWRITE_TAC[LENGTH] THEN - CONV_TAC NUM_REDUCE_CONV -);; - -let SUB_LIST_OF_INT128_TO_BYTES = prove( - `!x. SUB_LIST (0, 16) (int128_to_bytes x) = int128_to_bytes x`, - GEN_TAC THEN - MP_TAC (SPEC `x:int128` LENGTH_OF_INT128_TO_BYTES) THEN - DISCH_TAC THEN - IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] -);; - -let ELEM_TAC i = - CONV_TAC (RAND_CONV (REWRITE_CONV [num_CONV i])) THEN - REWRITE_TAC[bytelist_of_num] THEN - REWRITE_TAC[CONS_11] THEN - CONJ_TAC THENL [ - REWRITE_TAC[word_subword] THEN - AP_TERM_TAC THEN - (ARITH_TAC ORELSE - ( ASM_REWRITE_TAC[CONJUNCT1 EXP; DIV_1; DIV_DIV] THEN - CONV_TAC NUM_REDUCE_CONV)); ALL_TAC];; - -let INT128_TO_BYTES_EQ_BYTELIST_OF_NUM = prove( - `!x. int128_to_bytes x = bytelist_of_num 16 (val x)`, - GEN_TAC THEN - REWRITE_TAC[int128_to_bytes] THEN - - MAP_EVERY (fun i -> ELEM_TAC (mk_numeral (num i))) (List.rev (2 -- 16)) THEN - CONV_TAC (RAND_CONV (REWRITE_CONV [num_CONV `1`])) THEN - REWRITE_TAC[bytelist_of_num] THEN - REWRITE_TAC[CONS_11] THEN - REWRITE_TAC[word_subword] THEN - AP_TERM_TAC THEN - ASM_REWRITE_TAC[DIV_DIV] THEN - CONV_TAC NUM_REDUCE_CONV -);; - -let NUM_OF_BYTELIST_OF_INT128_TO_BYTES = prove( - `!x. num_of_bytelist (int128_to_bytes x) = val x`, - GEN_TAC THEN - REWRITE_TAC[INT128_TO_BYTES_EQ_BYTELIST_OF_NUM] THEN - REWRITE_TAC[NUM_OF_BYTELIST_OF_NUM] THEN - SUBGOAL_THEN `val (x:int128) < 2 EXP 128` ASSUME_TAC THENL - [ MP_TAC (ISPEC `x:int128` VAL_BOUND) THEN - REWRITE_TAC[DIMINDEX_128] THEN - ARITH_TAC; ALL_TAC - ] THEN - IMP_REWRITE_TAC[MOD_LT] THEN ASM_ARITH_TAC );; -let BYTES_TO_INT128_OF_INT128_TO_BYTES = prove( - `!x. bytes_to_int128 (int128_to_bytes x) = x`, - GEN_TAC THEN - REWRITE_TAC[int128_to_bytes; bytes_to_int128] THEN - REWRITE_TAC EL_16_8_CLAUSES THEN - BITBLAST_TAC -);; - -let INT128_TO_BYTES_OF_BYTES_TO_INT128 = prove( - `!x. LENGTH x = 16 ==> int128_to_bytes (bytes_to_int128 x) = x`, - REPEAT STRIP_TAC THEN - MP_TAC ((GEN_REWRITE_CONV I [LENGTH_EQ_LIST_OF_SEQ] THENC - RAND_CONV LIST_OF_SEQ_CONV) `LENGTH (x:byte list) = 16`) THEN - ASM_SIMP_TAC[] THEN - DISCH_THEN (fun th -> ONCE_REWRITE_TAC[th]) THEN - REWRITE_TAC[bytes_to_int128] THEN - REWRITE_TAC EL_16_8_CLAUSES THEN - REWRITE_TAC[int128_to_bytes] THEN - REWRITE_TAC[CONS_11] THEN - REPEAT (CONJ_TAC THEN BITBLAST_TAC) -);; - -let CALCULATE_TWEAK_EXPAND = prove( - `!x iv key. - GF_128_mult_by_primitive (calculate_tweak x iv key) = - calculate_tweak (x + 0x1) iv key`, - REPEAT GEN_TAC THEN - REWRITE_TAC[ARITH_RULE `x + 1 = SUC x`] THEN - CONV_TAC (RAND_CONV (REWRITE_CONV[CONJUNCT2 calculate_tweak])) THEN - REFL_TAC -);; - -let DIVISION_REMAINDER_CASES = prove - (`!a b. a DIV 80 = b ==> - let r = a MOD 80 in - a = b * 80 + r /\ r < 80`, +let READ_BYTES_EQ_READ_BYTE128_1BLOCK = prove( + `!(ptr:int64) (ct:byte list) (iv:int128) (key1:int128 list) (key2:int128 list) s. + (read (memory :> bytes128 pt_ptr) s = + aes256_xts_decrypt_round (bytes_to_int128 (SUB_LIST (0x0,0x10) ct)) + (calculate_tweak 0x0 iv key2) + key1) ==> + read (memory :> bytes (pt_ptr,0x10)) s = + num_of_bytelist (SUB_LIST (0x0,0x10) (aes256_xts_decrypt ct 0x10 iv key1 key2))`, REPEAT STRIP_TAC THEN + REWRITE_TAC[READ_MEMORY_BYTES_BYTES128] THEN + ASM_REWRITE_TAC[] THEN + REWRITE_TAC[aes256_xts_decrypt] THEN + CONV_TAC NUM_REDUCE_CONV THEN REWRITE_TAC[LET_DEF; LET_END_DEF] THEN - CONJ_TAC THENL - [ EXPAND_TAC "b" THEN REWRITE_TAC[GSYM DIVISION_SIMP]; - REWRITE_TAC[MOD_LT_EQ] THEN ARITH_TAC]);; - -let DIVISION_BY_80_LEMMA = prove( - `!(a:num) b. a DIV 0x50 = b /\ - 0x10 divides a /\ - ~(a - b * 0x50 = 0x10) /\ - ~(a - b * 0x50 = 0x20) /\ - ~(a - b * 0x50 = 0x30) /\ - ~(a - b * 0x50 = 0x40) ==> - b * 0x50 = a`, - REPEAT STRIP_TAC THEN - (* Use the division theorem: a = b * 0x50 + (a MOD 0x50) *) - MP_TAC (SPECL [`a:num`; `0x50`] DIVISION) THEN CONV_TAC NUM_REDUCE_CONV THEN - REPEAT STRIP_TAC THEN - - (* We have a = b * 0x50 + (a MOD 0x50) and a DIV 0x50 = b *) - SUBGOAL_THEN `a = b * 0x50 + (a MOD 0x50)` ASSUME_TAC THENL [ - ASM_ARITH_TAC; ALL_TAC] THEN - - (* Show that a MOD 0x50 = 0 by case analysis *) - SUBGOAL_THEN `a MOD 0x50 = 0` ASSUME_TAC THENL [ - (* Since 0x10 divides a, we know a = k * 0x10 for some k *) - UNDISCH_TAC `0x10 divides a` THEN - REWRITE_TAC[divides] THEN - STRIP_TAC THEN - - (* The remainder a MOD 0x50 must be a multiple of 0x10 and < 0x50 *) - (* So it's one of: 0, 0x10, 0x20, 0x30, 0x40 *) - SUBGOAL_THEN `(a MOD 0x50 = 0) \/ (a MOD 0x50 = 0x10) \/ - (a MOD 0x50 = 0x20) \/ (a MOD 0x50 = 0x30) \/ - (a MOD 0x50 = 0x40)` ASSUME_TAC THENL - [ ASM_REWRITE_TAC[] THEN - - SUBGOAL_THEN `(0x10 * x) MOD 0x50 = (x MOD 5) * 0x10` SUBST1_TAC THENL [ - SUBGOAL_THEN `0x50 = 5 * 0x10` SUBST1_TAC THENL [ - CONV_TAC NUM_REDUCE_CONV; ALL_TAC] THEN - MP_TAC (SPECL [`0x10 * x`; `0x10`; `5`] MOD_MULT_MOD) THEN - REWRITE_TAC[MOD_MULT; ADD_CLAUSES] THEN - IMP_REWRITE_TAC[DIV_MULT] THEN - CONV_TAC NUM_REDUCE_CONV THEN - SIMP_TAC[] THEN DISCH_TAC THEN - REWRITE_TAC[MULT_SYM] - ; ALL_TAC] THEN - - SUBGOAL_THEN `x MOD 5 < 5` ASSUME_TAC THENL [ - REWRITE_TAC[MOD_LT_EQ] THEN CONV_TAC NUM_REDUCE_CONV; ALL_TAC] THEN - SUBGOAL_THEN `x MOD 5 = 0 \/ x MOD 5 = 1 \/ x MOD 5 = 2 \/ x MOD 5 = 3 \/ x MOD 5 = 4` ASSUME_TAC THENL [ - UNDISCH_TAC `x MOD 0x5 < 0x5` THEN ARITH_TAC ; ALL_TAC] THEN - - REPEAT (FIRST_X_ASSUM DISJ_CASES_TAC) THENL - [ ASM_REWRITE_TAC[] THEN CONV_TAC NUM_REDUCE_CONV; - ASM_REWRITE_TAC[] THEN CONV_TAC NUM_REDUCE_CONV; - ASM_REWRITE_TAC[] THEN CONV_TAC NUM_REDUCE_CONV; - ASM_REWRITE_TAC[] THEN CONV_TAC NUM_REDUCE_CONV; - ASM_REWRITE_TAC[] THEN CONV_TAC NUM_REDUCE_CONV] - ; ALL_TAC] THEN - - (* Now eliminate the non-zero cases using the assumptions *) - SUBGOAL_THEN `~(a MOD 0x50 = 0x10)` ASSUME_TAC THENL - [ UNDISCH_TAC `~(a - b * 0x50 = 0x10)` THEN - UNDISCH_TAC `a = b * 0x50 + a MOD 0x50` THEN - ARITH_TAC; ALL_TAC] THEN - SUBGOAL_THEN `~(a MOD 0x50 = 0x20)` ASSUME_TAC THENL - [ UNDISCH_TAC `~(a - b * 0x50 = 0x20)` THEN - UNDISCH_TAC `a = b * 0x50 + a MOD 0x50` THEN - ARITH_TAC; ALL_TAC] THEN - SUBGOAL_THEN `~(a MOD 0x50 = 0x30)` ASSUME_TAC THENL - [ UNDISCH_TAC `~(a - b * 0x50 = 0x30)` THEN - UNDISCH_TAC `a = b * 0x50 + a MOD 0x50` THEN - ARITH_TAC; ALL_TAC] THEN - SUBGOAL_THEN `~(a MOD 0x50 = 0x40)` ASSUME_TAC THENL - [ UNDISCH_TAC `~(a - b * 0x50 = 0x40)` THEN - UNDISCH_TAC `a = b * 0x50 + a MOD 0x50` THEN - ARITH_TAC; ALL_TAC] THEN - - ASM_MESON_TAC[]; ALL_TAC - ] THEN - - (* Finally conclude b * 0x50 = a *) - ASM_ARITH_TAC -);; - -let WORD_AND_MASK16 = prove( - `word_and (len:int64) (word 0xfffffffffffffff0) = word_sub len (word_and len (word 0xf))`, - BITBLAST_TAC + REWRITE_TAC[aes256_xts_decrypt_tail] THEN + REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[SUB_LIST_OF_INT128_TO_BYTES] THEN + REWRITE_TAC[NUM_OF_BYTELIST_OF_INT128_TO_BYTES] );; -let WORD_AND_MASK16_EQ_0 = prove( - `!(x:int64). val x < 16 ==> ~(val x = 0x0) ==> ~(val (word_and x (word 0xf)) = 0x0)`, - BITBLAST_TAC);; - -(* Surprisingly hard to prove *) -let NUM_BLOCKS_TO_VAL = prove( - `!(len:int64). word_and len (word 0xfffffffffffffff0) = word (16 * (val len DIV 16))`, - GEN_TAC THEN - REWRITE_TAC[WORD_AND_MASK16] THEN - REWRITE_TAC[GSYM VAL_EQ] THEN - SUBGOAL_THEN `16 * val (len:int64) DIV 16 = val len - (val len MOD 16)` SUBST1_TAC THENL - [REWRITE_TAC[DIVISION_SIMP] THEN ARITH_TAC; ALL_TAC] THEN - REWRITE_TAC[ARITH_RULE `0xf = 2 EXP 4 - 1`] THEN - REWRITE_TAC[WORD_AND_MASK_WORD] THEN - CONV_TAC NUM_REDUCE_CONV THEN +let READ_BYTES_EQ_READ_BYTE128_2BLOCKS = prove( + `!(ptr:int64) (ct:byte list) (iv:int128) (key1:int128 list) (key2:int128 list) s. + (read (memory :> bytes128 pt_ptr) s = + aes256_xts_decrypt_round (bytes_to_int128 (SUB_LIST (0x0,0x10) ct)) + (calculate_tweak 0x0 iv key2) + key1) ==> + (read (memory :> bytes128 (word_add pt_ptr (word 0x10))) s = + aes256_xts_decrypt_round (bytes_to_int128 (SUB_LIST (0x10,0x10) ct)) + (calculate_tweak 0x1 iv key2) + key1) ==> + read (memory :> bytes (pt_ptr,0x20)) s = + num_of_bytelist (SUB_LIST (0x0,0x20) (aes256_xts_decrypt ct 0x20 iv key1 key2))`, + REPEAT STRIP_TAC THEN + IMP_REWRITE_TAC[ARITH_RULE `0x20 = 0x10 + 0x10`; READ_BYTES_AND_BYTE128_SPLIT] THEN + EXISTS_TAC `aes256_xts_decrypt ct 0x20 iv key1 key2` THEN + REPEAT CONJ_TAC THENL + [ + CONV_TAC NUM_REDUCE_CONV; - REWRITE_TAC[VAL_WORD_SUB] THEN - SUBGOAL_THEN `val (len:int64) >= val ((word (val len MOD 0x10)):int64)` ASSUME_TAC THENL [ - REWRITE_TAC[VAL_WORD; DIMINDEX_64; GE] THEN - MP_TAC (SPECL [`val (len:int64) MOD 0x10`; `0x2 EXP 0x40`] MOD_LE) THEN + MP_TAC (SPECL [`2:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN ARITH_TAC; - ALL_TAC - ] THEN - REWRITE_TAC[VAL_WORD; DIMINDEX_64] THEN - - SUBGOAL_THEN `val (len:int64) MOD 0x10 < 0x2 EXP 0x40` ASSUME_TAC THENL - [ TRANS_TAC LET_TRANS `val (len:int64)` THEN - REWRITE_TAC[VAL_BOUND_64; MOD_LE]; ALL_TAC] THEN - SUBGOAL_THEN `val (len:int64) MOD 0x10 MOD 0x2 EXP 0x40 = val len MOD 0x10` ASSUME_TAC THENL - [ MP_TAC (SPECL [`val (len:int64) MOD 0x10`; `0x2 EXP 0x40`] MOD_LT) THEN - ASM_SIMP_TAC[]; ALL_TAC] THEN - ASM_REWRITE_TAC[] THEN - - MP_TAC (SPECL [`val (len:int64)`; `0x2 EXP 0x40`; `val (len:int64) MOD 0x10`] - (ARITH_RULE `!a b c. c <= a ==> c <= b ==> a + b - c = (a - c) + b`)) THEN - ANTS_TAC THENL [ REWRITE_TAC[MOD_LE]; ALL_TAC] THEN - ANTS_TAC THENL [ ASM_ARITH_TAC; ALL_TAC] THEN - ASM_SIMP_TAC[] THEN DISCH_TAC THEN - - MP_TAC (SPECL [`1`; `0x2 EXP 0x40`; `val (len:int64) - val len MOD 0x10`] - (CONJUNCT1 (CONJUNCT2 (CONJUNCT2 MOD_MULT_ADD)))) THEN - CONV_TAC NUM_REDUCE_CONV - );; + REWRITE_TAC[aes256_xts_decrypt] THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + CONV_TAC NUM_REDUCE_CONV THEN + MP_TAC (SPECL [`ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + LENGTH_OF_AES256_XTS_DECRYPT_REC_TRIVIAL) THEN + IMP_REWRITE_TAC[SUB_LIST_APPEND_RIGHT_LEMMA] THEN DISCH_TAC THEN + REWRITE_TAC[aes256_xts_decrypt_tail] THEN + REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + REWRITE_TAC[SUB_LIST_OF_INT128_TO_BYTES] THEN + REWRITE_TAC[NUM_OF_BYTELIST_OF_INT128_TO_BYTES] THEN + REWRITE_TAC[BYTES_TO_INT128_OF_INT128_TO_BYTES] THEN + CONV_TAC NUM_REDUCE_CONV; -let NUM_BLOCKS_MINUS1_TO_VAL = prove( - `!(len:int64). val len >= 16 ==> - word_sub (word_and (len:int64) (word 0xfffffffffffffff0)) (word 0x10) = - word (16 * (val len DIV 16 - 1))`, - REWRITE_TAC[NUM_BLOCKS_TO_VAL] THEN - REPEAT STRIP_TAC THEN - REWRITE_TAC[LEFT_SUB_DISTRIB; WORD_SUB] THEN - CONV_TAC NUM_REDUCE_CONV THEN - SUBGOAL_THEN `0x10 <= 0x10 * val (len:int64) DIV 0x10` ASSUME_TAC THENL - [ MP_TAC (SPECL [`0x10`; `val (len:int64)`; `1`] LE_RDIV_EQ) THEN + MP_TAC (SPECL [`1:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + SUB_LIST_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN CONV_TAC NUM_REDUCE_CONV THEN - REWRITE_TAC[GSYM GE] THEN - ASM_SIMP_TAC[] THEN - ARITH_TAC; ALL_TAC] THEN - ASM_SIMP_TAC[] + SIMP_TAC[] THEN DISCH_TAC THEN + IMP_REWRITE_TAC[READ_BYTES_EQ_READ_BYTE128_1BLOCK] THEN + MP_TAC (SPECL [`1:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN + CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] + ] );; -let BREAK_ONE_BLOCK_INTO_BYTES = prove( - `!(addr:int64) (s:armstate) (p:int128). - read (memory :> bytes128 addr) s = p <=> - (read (memory :> bytes8 addr) s = EL 0 (int128_to_bytes p) /\ - read (memory :> bytes8 (word_add addr (word 1))) s = EL 1 (int128_to_bytes p) /\ - read (memory :> bytes8 (word_add addr (word 2))) s = EL 2 (int128_to_bytes p) /\ - read (memory :> bytes8 (word_add addr (word 3))) s = EL 3 (int128_to_bytes p) /\ - read (memory :> bytes8 (word_add addr (word 4))) s = EL 4 (int128_to_bytes p) /\ - read (memory :> bytes8 (word_add addr (word 5))) s = EL 5 (int128_to_bytes p) /\ - read (memory :> bytes8 (word_add addr (word 6))) s = EL 6 (int128_to_bytes p) /\ - read (memory :> bytes8 (word_add addr (word 7))) s = EL 7 (int128_to_bytes p) /\ - read (memory :> bytes8 (word_add addr (word 8))) s = EL 8 (int128_to_bytes p) /\ - read (memory :> bytes8 (word_add addr (word 9))) s = EL 9 (int128_to_bytes p) /\ - read (memory :> bytes8 (word_add addr (word 10))) s = EL 10 (int128_to_bytes p) /\ - read (memory :> bytes8 (word_add addr (word 11))) s = EL 11 (int128_to_bytes p) /\ - read (memory :> bytes8 (word_add addr (word 12))) s = EL 12 (int128_to_bytes p) /\ - read (memory :> bytes8 (word_add addr (word 13))) s = EL 13 (int128_to_bytes p) /\ - read (memory :> bytes8 (word_add addr (word 14))) s = EL 14 (int128_to_bytes p) /\ - read (memory :> bytes8 (word_add addr (word 15))) s = EL 15 (int128_to_bytes p)) - `, - REPEAT GEN_TAC THEN - EQ_TAC THENL[ - STRIP_TAC THEN - MP_TAC (SPECL [`0:num`; `addr:int64`; `s:armstate`] BYTES128_TO_BYTES8_THM) THEN - REWRITE_TAC[WORD_ADD_0] THEN CONV_TAC NUM_REDUCE_CONV THEN - ASM_REWRITE_TAC[] THEN - DISCH_TAC THEN - REWRITE_TAC[int128_to_bytes] THEN - REWRITE_TAC EL_16_8_CLAUSES THEN - ASM_REWRITE_TAC[] THEN - REWRITE_TAC[bytes_to_int128] THEN - REWRITE_TAC EL_16_8_CLAUSES THEN - REWRITE_TAC[WORD_ADD_0] THEN - ABBREV_TAC `x0 = read (memory :> bytes8 (addr:int64)) s` THEN - ABBREV_TAC `x1 = read (memory :> bytes8 (word_add (addr:int64) (word 0x1))) s` THEN - ABBREV_TAC `x2 = read (memory :> bytes8 (word_add (addr:int64) (word 0x2))) s` THEN - ABBREV_TAC `x3 = read (memory :> bytes8 (word_add (addr:int64) (word 0x3))) s` THEN - ABBREV_TAC `x4 = read (memory :> bytes8 (word_add (addr:int64) (word 0x4))) s` THEN - ABBREV_TAC `x5 = read (memory :> bytes8 (word_add (addr:int64) (word 0x5))) s` THEN - ABBREV_TAC `x6 = read (memory :> bytes8 (word_add (addr:int64) (word 0x6))) s` THEN - ABBREV_TAC `x7 = read (memory :> bytes8 (word_add (addr:int64) (word 0x7))) s` THEN - ABBREV_TAC `x8 = read (memory :> bytes8 (word_add (addr:int64) (word 0x8))) s` THEN - ABBREV_TAC `x9 = read (memory :> bytes8 (word_add (addr:int64) (word 0x9))) s` THEN - ABBREV_TAC `xa = read (memory :> bytes8 (word_add (addr:int64) (word 0xa))) s` THEN - ABBREV_TAC `xb = read (memory :> bytes8 (word_add (addr:int64) (word 0xb))) s` THEN - ABBREV_TAC `xc = read (memory :> bytes8 (word_add (addr:int64) (word 0xc))) s` THEN - ABBREV_TAC `xd = read (memory :> bytes8 (word_add (addr:int64) (word 0xd))) s` THEN - ABBREV_TAC `xe = read (memory :> bytes8 (word_add (addr:int64) (word 0xe))) s` THEN - ABBREV_TAC `xf = read (memory :> bytes8 (word_add (addr:int64) (word 0xf))) s` THEN - REPEAT STRIP_TAC THEN - REPEAT BITBLAST_TAC; ALL_TAC] THEN - - REPEAT STRIP_TAC THEN - MP_TAC (SPECL [`0:num`; `addr:int64`; `s:armstate`] BYTES128_TO_BYTES8_THM) THEN - CONV_TAC NUM_REDUCE_CONV THEN REWRITE_TAC[WORD_ADD_0] THEN - ASM_REWRITE_TAC[] THEN - DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN - REWRITE_TAC[int128_to_bytes] THEN - REWRITE_TAC EL_16_8_CLAUSES THEN - REWRITE_TAC[bytes_to_int128] THEN - REWRITE_TAC EL_16_8_CLAUSES THEN - BITBLAST_TAC -);; - -let SELECT_ONE_BYTE_FROM_BLOCK = prove( - `!(addr:int64) (off:int64) (s:armstate) (p:int128). - read (memory :> bytes128 addr) s = p ==> - val off < 16 ==> - read (memory :> bytes8 (word_add addr off)) s = EL (val off) (int128_to_bytes p)`, +let READ_BYTES_EQ_READ_BYTE128_3BLOCKS = prove( + `!(ptr:int64) (ct:byte list) (iv:int128) (key1:int128 list) (key2:int128 list) s. + (read (memory :> bytes128 pt_ptr) s = + aes256_xts_decrypt_round (bytes_to_int128 (SUB_LIST (0x0,0x10) ct)) + (calculate_tweak 0x0 iv key2) + key1) ==> + (read (memory :> bytes128 (word_add pt_ptr (word 0x10))) s = + aes256_xts_decrypt_round (bytes_to_int128 (SUB_LIST (0x10,0x10) ct)) + (calculate_tweak 0x1 iv key2) + key1) ==> + (read (memory :> bytes128 (word_add pt_ptr (word 0x20))) s = + aes256_xts_decrypt_round (bytes_to_int128 (SUB_LIST (0x20,0x10) ct)) + (calculate_tweak 0x2 iv key2) + key1) ==> + read (memory :> bytes (pt_ptr,0x30)) s = + num_of_bytelist (SUB_LIST (0x0,0x30) (aes256_xts_decrypt ct 0x30 iv key1 key2))`, REPEAT STRIP_TAC THEN - FIRST_ASSUM (STRIP_ASSUME_TAC o - MATCH_MP (fst (EQ_IMP_RULE - (SPECL [`addr:int64`; `s:armstate`; `p:int128`] BREAK_ONE_BLOCK_INTO_BYTES)))) THEN - SUBGOAL_THEN `word_add addr (off:int64) = word_add addr (word (val off))` SUBST1_TAC THENL - [REWRITE_TAC[WORD_VAL]; ALL_TAC] THEN - UNDISCH_TAC `val (off:int64) < 16` THEN - SPEC_TAC (`val (off:int64)`, `n:num`) THEN - CONV_TAC EXPAND_CASES_CONV THEN - ASM_REWRITE_TAC[WORD_ADD_0] -);; + IMP_REWRITE_TAC[ARITH_RULE `0x30 = 0x20 + 0x10`; READ_BYTES_AND_BYTE128_SPLIT] THEN + EXISTS_TAC `aes256_xts_decrypt ct 0x30 iv key1 key2` THEN + REPEAT CONJ_TAC THENL + [ + CONV_TAC NUM_REDUCE_CONV; -let SELECT_ONE_BYTE_FROM_FORALL = prove( - `!(ptr:int64) (len:int64) (addr:int64) (bl:byte list) (s:armstate). - (forall j. j < val len ==> read (memory :> bytes8 (word_add ptr (word j))) s = EL j bl) ==> - val addr < val len ==> - LENGTH bl = val len ==> - read (memory :> bytes8 (word_add ptr addr)) s = EL (val addr) bl`, - REPEAT STRIP_TAC THEN - FIRST_X_ASSUM (MP_TAC o SPEC `val (addr:int64)`) THEN - ASM_REWRITE_TAC[] THEN - REWRITE_TAC[WORD_VAL] -);; + MP_TAC (SPECL [`3:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN + ARITH_TAC; -let IVAL_WORD_LT = prove( - `!i. i < 2 EXP 63 ==> ival ((word i):int64) = &i`, - GEN_TAC THEN DISCH_TAC THEN - REWRITE_TAC[ival; DIMINDEX_64; ARITH_RULE `64 - 1 = 63`] THEN - REWRITE_TAC[VAL_WORD; DIMINDEX_64] THEN - SUBGOAL_THEN `i < 2 EXP 64` ASSUME_TAC THENL - [ TRANS_TAC LT_TRANS `2 EXP 63` THEN - ASM_REWRITE_TAC[] THEN + REWRITE_TAC[aes256_xts_decrypt] THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + CONV_TAC NUM_REDUCE_CONV THEN + MP_TAC (SPECL [`0:num`; `1:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + LENGTH_OF_AES256_XTS_DECRYPT_REC) THEN + CONV_TAC NUM_REDUCE_CONV THEN + IMP_REWRITE_TAC[SUB_LIST_APPEND_RIGHT_LEMMA] THEN DISCH_TAC THEN + REWRITE_TAC[aes256_xts_decrypt_tail] THEN + REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + REWRITE_TAC[SUB_LIST_OF_INT128_TO_BYTES] THEN + REWRITE_TAC[NUM_OF_BYTELIST_OF_INT128_TO_BYTES] THEN + REWRITE_TAC[BYTES_TO_INT128_OF_INT128_TO_BYTES] THEN CONV_TAC NUM_REDUCE_CONV; ALL_TAC] THEN - ASM_SIMP_TAC[MOD_LT] -);; -(* ********************************************************** *) -(* Properties that we prove about the specification functions *) - -let LENGTH_OF_AES256_XTS_DECRYPT_REC = prove( - `!(i:num) (m:num) (C:byte list) (iv:int128) (key1:int128 list) (key2:int128 list). - LENGTH(aes256_xts_decrypt_rec i m C iv key1 key2) = (if m < i then 0 else (m - i + 1) * 0x10)`, - REPEAT GEN_TAC THEN - (* Wellfounded induction with measure (m + 1) - i - Note that the parentheses are essential because of the precedence of + and - *) - WF_INDUCT_TAC `(m + 1) - i` THEN - ONCE_REWRITE_TAC[aes256_xts_decrypt_rec] THEN - COND_CASES_TAC THENL - [ SIMP_TAC[LENGTH_EQ_NIL]; - SIMP_TAC[] THEN - REWRITE_TAC[LET_DEF; LET_END_DEF] THEN - REWRITE_TAC[LENGTH_APPEND] THEN - SUBGOAL_THEN `~(m < i) ==> (m + 1) - (i + 1) < (m + 1) - i` ASSUME_TAC THENL - [ ASM_ARITH_TAC ; ALL_TAC ] THEN - ASM_SIMP_TAC[] THEN - REWRITE_TAC[LENGTH_OF_INT128_TO_BYTES] THEN - COND_CASES_TAC THENL - [ASM_ARITH_TAC; ASM_ARITH_TAC]] + MP_TAC (SPECL [`2:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + SUB_LIST_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN + CONV_TAC NUM_REDUCE_CONV THEN + SIMP_TAC[] THEN DISCH_TAC THEN + IMP_REWRITE_TAC[READ_BYTES_EQ_READ_BYTE128_2BLOCKS] THEN + MP_TAC (SPECL [`2:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN + CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] );; -let LENGTH_OF_FST_OF_CIPHER_STEALING = prove( - `!(block:byte list) (tail:byte list) (tail_len:num) - (iv:int128) (i:num) (key1:int128 list) (key2:int128 list). - LENGTH (FST (cipher_stealing block tail tail_len iv i key1 key2)) = 16`, +let READ_BYTES_EQ_READ_BYTE128_4BLOCKS = prove( + `!(ptr:int64) (ct:byte list) (iv:int128) (key1:int128 list) (key2:int128 list) s. + (read (memory :> bytes128 pt_ptr) s = + aes256_xts_decrypt_round (bytes_to_int128 (SUB_LIST (0x0,0x10) ct)) + (calculate_tweak 0x0 iv key2) + key1) ==> + (read (memory :> bytes128 (word_add pt_ptr (word 0x10))) s = + aes256_xts_decrypt_round (bytes_to_int128 (SUB_LIST (0x10,0x10) ct)) + (calculate_tweak 0x1 iv key2) + key1) ==> + (read (memory :> bytes128 (word_add pt_ptr (word 0x20))) s = + aes256_xts_decrypt_round (bytes_to_int128 (SUB_LIST (0x20,0x10) ct)) + (calculate_tweak 0x2 iv key2) + key1) ==> + (read (memory :> bytes128 (word_add pt_ptr (word 0x30))) s = + aes256_xts_decrypt_round (bytes_to_int128 (SUB_LIST (0x30,0x10) ct)) + (calculate_tweak 0x3 iv key2) + key1) ==> + read (memory :> bytes (pt_ptr,0x40)) s = + num_of_bytelist (SUB_LIST (0x0,0x40) (aes256_xts_decrypt ct 0x40 iv key1 key2))`, REPEAT STRIP_TAC THEN - REWRITE_TAC[cipher_stealing] THEN - ASM_REWRITE_TAC[LET_DEF; LET_END_DEF] THEN - REWRITE_TAC[LENGTH_OF_INT128_TO_BYTES] -);; + IMP_REWRITE_TAC[ARITH_RULE `0x40 = 0x30 + 0x10`; READ_BYTES_AND_BYTE128_SPLIT] THEN + EXISTS_TAC `aes256_xts_decrypt ct 0x40 iv key1 key2` THEN + REPEAT CONJ_TAC THENL + [ + CONV_TAC NUM_REDUCE_CONV; -let LENGTH_OF_SND_OF_CIPHER_STEALING = prove( - `!(block:byte list) (tail:byte list) (tail_len:num) - (iv:int128) (i:num) (key1:int128 list) (key2:int128 list). - LENGTH (SND (cipher_stealing block tail tail_len iv i key1 key2)) = MIN tail_len 16`, - REPEAT STRIP_TAC THEN - REWRITE_TAC[cipher_stealing] THEN - ASM_REWRITE_TAC[LET_DEF; LET_END_DEF] THEN - REWRITE_TAC[LENGTH_SUB_LIST] THEN - REWRITE_TAC[LENGTH_OF_INT128_TO_BYTES] THEN - REWRITE_TAC[MIN] THEN - CONV_TAC NUM_REDUCE_CONV -);; + MP_TAC (SPECL [`4:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN + ARITH_TAC; -let LENGTH_OF_AES256_XTS_DECRYPT_TAIL = prove( - `! (i:num) (tail_len:num) (C:byte list) (iv:int128) (key1:int128 list) (key2:int128 list). - LENGTH(aes256_xts_decrypt_tail i tail_len C iv key1 key2) = 0x10 + MIN tail_len 16`, - REPEAT STRIP_TAC THEN - REWRITE_TAC[aes256_xts_decrypt_tail] THEN - COND_CASES_TAC THENL [ - ASM_REWRITE_TAC[LET_DEF; LET_END_DEF] THEN - REWRITE_TAC[LENGTH_OF_INT128_TO_BYTES] THEN - REWRITE_TAC[ADD_CLAUSES; MIN] THEN + REWRITE_TAC[aes256_xts_decrypt] THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + CONV_TAC NUM_REDUCE_CONV THEN + MP_TAC (SPECL [`0:num`; `2:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + LENGTH_OF_AES256_XTS_DECRYPT_REC) THEN + CONV_TAC NUM_REDUCE_CONV THEN + IMP_REWRITE_TAC[SUB_LIST_APPEND_RIGHT_LEMMA] THEN DISCH_TAC THEN + REWRITE_TAC[aes256_xts_decrypt_tail] THEN + REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + REWRITE_TAC[SUB_LIST_OF_INT128_TO_BYTES] THEN + REWRITE_TAC[BYTES_TO_INT128_OF_INT128_TO_BYTES] THEN CONV_TAC NUM_REDUCE_CONV; + ALL_TAC] THEN - REWRITE_TAC[LET_DEF; LET_END_DEF; LENGTH_APPEND] THEN - REWRITE_TAC[LENGTH_OF_FST_OF_CIPHER_STEALING] THEN - REWRITE_TAC[LENGTH_OF_SND_OF_CIPHER_STEALING]] -);; - -let LENGTH_OF_AES256_XTS_DECRYPT_REC_TRIVIAL = prove( - `!(ct:byte list) (iv:int128) (key1:int128 list) (key2:int128 list). - LENGTH (aes256_xts_decrypt_rec 0x0 0x0 ct iv key1 key2) = 16`, - REPEAT STRIP_TAC THEN - REWRITE_TAC[LENGTH_OF_AES256_XTS_DECRYPT_REC] THEN - CONV_TAC NUM_REDUCE_CONV + MP_TAC (SPECL [`3:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + SUB_LIST_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN + CONV_TAC NUM_REDUCE_CONV THEN + SIMP_TAC[] THEN DISCH_TAC THEN + IMP_REWRITE_TAC[READ_BYTES_EQ_READ_BYTE128_3BLOCKS] THEN + MP_TAC (SPECL [`3:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN + CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] );; -let LENGTH_OF_AES256_XTS_DECRYPT_TAIL_TRIVIAL = prove( - `!(ct:byte list) (iv:int128) (key1:int128 list) (key2:int128 list). - LENGTH(aes256_xts_decrypt_tail 0 0 ct iv key1 key2) = 16`, - REPEAT STRIP_TAC THEN - REWRITE_TAC[LENGTH_OF_AES256_XTS_DECRYPT_TAIL] THEN - CONV_TAC NUM_REDUCE_CONV -);; -let AES256_XTS_DECRYPT_REC_EQ_TAIL_TRIVIAL = prove( - `!(ct:byte list) (iv:int128) (key1:int128 list) (key2:int128 list). - aes256_xts_decrypt_rec 0x0 0x0 ct iv key1 key2 = - aes256_xts_decrypt_tail 0x0 0x0 ct iv key1 key2`, +let READ_BYTES_EQ_READ_BYTE128_5BLOCKS = prove( + `!(ptr:int64) (ct:byte list) (iv:int128) (key1:int128 list) (key2:int128 list) s. + (read (memory :> bytes128 pt_ptr) s = + aes256_xts_decrypt_round (bytes_to_int128 (SUB_LIST (0x0,0x10) ct)) + (calculate_tweak 0x0 iv key2) + key1) ==> + (read (memory :> bytes128 (word_add pt_ptr (word 0x10))) s = + aes256_xts_decrypt_round (bytes_to_int128 (SUB_LIST (0x10,0x10) ct)) + (calculate_tweak 0x1 iv key2) + key1) ==> + (read (memory :> bytes128 (word_add pt_ptr (word 0x20))) s = + aes256_xts_decrypt_round (bytes_to_int128 (SUB_LIST (0x20,0x10) ct)) + (calculate_tweak 0x2 iv key2) + key1) ==> + (read (memory :> bytes128 (word_add pt_ptr (word 0x30))) s = + aes256_xts_decrypt_round (bytes_to_int128 (SUB_LIST (0x30,0x10) ct)) + (calculate_tweak 0x3 iv key2) + key1) ==> + (read (memory :> bytes128 (word_add pt_ptr (word 0x40))) s = + aes256_xts_decrypt_round (bytes_to_int128 (SUB_LIST (0x40,0x10) ct)) + (calculate_tweak 0x4 iv key2) + key1) ==> + read (memory :> bytes (pt_ptr,0x50)) s = + num_of_bytelist (SUB_LIST (0x0,0x50) (aes256_xts_decrypt ct 0x50 iv key1 key2))`, REPEAT STRIP_TAC THEN - ONCE_REWRITE_TAC[aes256_xts_decrypt_rec] THEN - CONV_TAC NUM_REDUCE_CONV THEN - REWRITE_TAC[LET_DEF; LET_END_DEF] THEN - ONCE_REWRITE_TAC[aes256_xts_decrypt_rec] THEN - CONV_TAC NUM_REDUCE_CONV THEN - REWRITE_TAC[APPEND_NIL] THEN + IMP_REWRITE_TAC[ARITH_RULE `0x50 = 0x40 + 0x10`; READ_BYTES_AND_BYTE128_SPLIT] THEN + EXISTS_TAC `aes256_xts_decrypt ct 0x50 iv key1 key2` THEN + REPEAT CONJ_TAC THENL + [ + CONV_TAC NUM_REDUCE_CONV; - REWRITE_TAC[aes256_xts_decrypt_tail] THEN - REWRITE_TAC[LET_DEF; LET_END_DEF] THEN - CONV_TAC NUM_REDUCE_CONV -);; + MP_TAC (SPECL [`5:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN + ARITH_TAC; -let LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS = prove( - `! (i:num) (ct:byte list) (iv:int128) (key1:int128 list) (key2:int128 list). - LENGTH(aes256_xts_decrypt ct (0x10 * i) iv key1 key2) = 0x10 * i`, - REPEAT STRIP_TAC THEN - SPEC_TAC (`i:num`, `i:num`) THEN - INDUCT_TAC THENL - [ - CONV_TAC NUM_REDUCE_CONV THEN REWRITE_TAC[aes256_xts_decrypt] THEN CONV_TAC NUM_REDUCE_CONV THEN - REWRITE_TAC[LENGTH_EQ_NIL]; + REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + CONV_TAC NUM_REDUCE_CONV THEN + MP_TAC (SPECL [`0:num`; `3:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + LENGTH_OF_AES256_XTS_DECRYPT_REC) THEN + CONV_TAC NUM_REDUCE_CONV THEN + IMP_REWRITE_TAC[SUB_LIST_APPEND_RIGHT_LEMMA] THEN DISCH_TAC THEN + REWRITE_TAC[aes256_xts_decrypt_tail] THEN + REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + REWRITE_TAC[SUB_LIST_OF_INT128_TO_BYTES] THEN + REWRITE_TAC[BYTES_TO_INT128_OF_INT128_TO_BYTES] THEN + CONV_TAC NUM_REDUCE_CONV; ALL_TAC] THEN - REWRITE_TAC[ADD1; LEFT_ADD_DISTRIB] THEN + MP_TAC (SPECL [`4:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + SUB_LIST_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN CONV_TAC NUM_REDUCE_CONV THEN - REWRITE_TAC[aes256_xts_decrypt] THEN + SIMP_TAC[] THEN DISCH_TAC THEN + IMP_REWRITE_TAC[READ_BYTES_EQ_READ_BYTE128_4BLOCKS] THEN + MP_TAC (SPECL [`4:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN + CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] +);; - ASM_CASES_TAC `i = 0` THENL - [ ASM_SIMP_TAC[] THEN - CONV_TAC NUM_REDUCE_CONV THEN - IMP_REWRITE_TAC[LET_DEF;LET_END_DEF;SUB_0] THEN - CONV_TAC NUM_REDUCE_CONV THEN - REWRITE_TAC[LENGTH_OF_AES256_XTS_DECRYPT_TAIL_TRIVIAL] - ; ALL_TAC - ] THEN - - SUBGOAL_THEN `~(0x10 * i + 0x10 < 0x10)` ASSUME_TAC THENL - [ ASM_ARITH_TAC; ALL_TAC ] THEN ASM_SIMP_TAC[] THEN - REWRITE_TAC[ARITH_RULE `0x10 * i + 0x10 = 0x10 * (i + 1)`; MOD_MULT] THEN - IMP_REWRITE_TAC[LET_DEF; LET_END_DEF;SUB_0;DIV_MULT] THEN - CONJ_TAC THENL [ALL_TAC; ARITH_TAC] THEN - SUBGOAL_THEN `~(i + 0x1 < 0x2)` ASSUME_TAC THENL - [ ASM_ARITH_TAC; ALL_TAC] THEN ASM_SIMP_TAC[] THEN - REWRITE_TAC[LENGTH_APPEND] THEN - REWRITE_TAC[LENGTH_OF_AES256_XTS_DECRYPT_REC] THEN - REWRITE_TAC[LENGTH_OF_AES256_XTS_DECRYPT_TAIL] THEN - CONV_TAC NUM_REDUCE_CONV THEN - ASM_ARITH_TAC -);; - -let LENGTH_OF_AES256_XTS_DECRYPT = prove( - `! (i:num) (tail_len:num) (ct:byte list) (iv:int128) (key1:int128 list) (key2:int128 list). - ~(tail_len = 0) /\ tail_len < 16 ==> - LENGTH(aes256_xts_decrypt ct (16 * i + 16 + tail_len) iv key1 key2) = 16 * i + 16 + tail_len`, - REPEAT STRIP_TAC THEN - (* Case 1: i = 0 *) - ASM_CASES_TAC `i = 0` THENL - [ - ASM_SIMP_TAC[ADD_ASSOC] THEN - CONV_TAC NUM_REDUCE_CONV THEN - REWRITE_TAC[aes256_xts_decrypt] THEN - SUBGOAL_THEN `~(0x10 + tail_len < 0x10)` ASSUME_TAC THENL - [ ASM_ARITH_TAC; ALL_TAC] THEN - SUBGOAL_THEN `(0x10 + tail_len) MOD 0x10 = tail_len` ASSUME_TAC THENL - [ REWRITE_TAC[ARITH_RULE `0x10 + tail_len = 1 * 16 + tail_len`] THEN - IMP_REWRITE_TAC[MOD_MULT_ADD; MOD_LT]; ALL_TAC] THEN - ASM_SIMP_TAC[] THEN - REWRITE_TAC[LET_DEF; LET_END_DEF] THEN - SUBGOAL_THEN `((0x10 + tail_len) - tail_len) DIV 0x10 = 1` SUBST1_TAC THENL - [ ASM_ARITH_TAC; ALL_TAC ] THEN - CONV_TAC NUM_REDUCE_CONV THEN - REWRITE_TAC[LENGTH_OF_AES256_XTS_DECRYPT_TAIL] THEN - ASM_ARITH_TAC; - ALL_TAC - ] THEN - - (* Case 2: i >= 1 *) - ASM_CASES_TAC `i >= 1` THENL - [ - REWRITE_TAC[aes256_xts_decrypt] THEN - SUBGOAL_THEN `(0x10 * i + 0x10 + tail_len) MOD 0x10 = tail_len` SUBST1_TAC THENL - [ REWRITE_TAC[ADD_ASSOC; ARITH_RULE `0x10 * i + 0x10 = 16 * (i + 1)`] THEN - IMP_REWRITE_TAC[MOD_MULT_ADD; MOD_LT]; ALL_TAC] THEN - SUBGOAL_THEN `~(0x10 * i + 0x10 + tail_len < 0x10)` ASSUME_TAC THENL - [ ASM_ARITH_TAC; ALL_TAC] THEN - ASM_SIMP_TAC[] THEN - REWRITE_TAC[LET_DEF; LET_END_DEF] THEN - SUBGOAL_THEN `((0x10 * i + 0x10 + tail_len) - tail_len) DIV 0x10 = i + 1` SUBST1_TAC THENL - [ REWRITE_TAC[ARITH_RULE `(0x10 * i + 0x10 + tail_len) - tail_len = 16 * (i + 1)`] THEN - IMP_REWRITE_TAC[DIV_MULT] THEN - ARITH_TAC; ALL_TAC] THEN - SUBGOAL_THEN `~(i + 1 < 2)` ASSUME_TAC THENL - [ ASM_ARITH_TAC; ALL_TAC] THEN - ASM_SIMP_TAC[] THEN - IMP_REWRITE_TAC[ARITH_RULE `(i + 1) - 2 = i - 1`; ADD_SUB] THEN - REWRITE_TAC[LENGTH_APPEND] THEN - IMP_REWRITE_TAC[LENGTH_OF_AES256_XTS_DECRYPT_REC] THEN - IMP_REWRITE_TAC[LENGTH_OF_AES256_XTS_DECRYPT_TAIL] THEN - ASM_ARITH_TAC; - ALL_TAC - ] THEN - - ASM_ARITH_TAC -);; - -let AES256_XTS_DECRYPT_TAIL_WHEN_1BLOCK = prove( - `!(n:num) (ct:byte list) (iv:int128) (key1:int128 list) (key2:int128 list). - bytes_to_int128 - (aes256_xts_decrypt_tail n 0x0 ct iv key1 key2) = - aes256_xts_decrypt_round - (bytes_to_int128 (SUB_LIST (n * 0x10,0x10) ct)) - (calculate_tweak n iv key2) key1`, - REPEAT STRIP_TAC THEN - REWRITE_TAC[aes256_xts_decrypt_tail] THEN - REWRITE_TAC[LET_DEF; LET_END_DEF] THEN - REWRITE_TAC[BYTES_TO_INT128_OF_INT128_TO_BYTES] -);; - -let AES256_XTS_DECRYPT_REC_EQ_TAIL = prove( - `!(i:num) (k:num) (ct:byte list) (iv:int128) (key1:int128 list) (key2:int128 list). - k >= i ==> - aes256_xts_decrypt_rec i (k + 1) ct iv key1 key2 = - APPEND (aes256_xts_decrypt_rec i k ct iv key1 key2) - (aes256_xts_decrypt_tail (k + 1) 0x0 ct iv key1 key2)`, - REPEAT GEN_TAC THEN - WF_INDUCT_TAC `(k + 1) - i` THEN - STRIP_TAC THEN - GEN_REWRITE_TAC (RATOR_CONV o ONCE_DEPTH_CONV) [aes256_xts_decrypt_rec] THEN - SUBGOAL_THEN `~(k + 0x1 < i)` ASSUME_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN - ASM_SIMP_TAC[] THEN - REWRITE_TAC[LET_DEF; LET_END_DEF] THEN - SUBGOAL_THEN `(k + 1) - (i + 1) < (k + 1) - i` ASSUME_TAC THENL [ ASM_ARITH_TAC; ALL_TAC] THEN - FIRST_X_ASSUM (MP_TAC o SPECL [`k:num`; `i + 1:num`]) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN - ASM_CASES_TAC `k >= i + 1` THENL - [ - ASM_SIMP_TAC[] THEN DISCH_TAC THEN - REWRITE_TAC[APPEND_ASSOC] THEN - AP_THM_TAC THEN - GEN_REWRITE_TAC (RAND_CONV o ONCE_DEPTH_CONV) [aes256_xts_decrypt_rec] THEN - SUBGOAL_THEN `~(k < i)` ASSUME_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN - ASM_SIMP_TAC[] THEN - REWRITE_TAC[LET_DEF; LET_END_DEF]; ALL_TAC - ] THEN - SUBGOAL_THEN `k:num = i` ASSUME_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN - STRIP_TAC THEN ASM_REWRITE_TAC[] THEN - ONCE_REWRITE_TAC[aes256_xts_decrypt_rec] THEN - REWRITE_TAC[LT_REFL; LET_DEF; LET_END_DEF] THEN - ONCE_REWRITE_TAC[aes256_xts_decrypt_rec] THEN - REWRITE_TAC[ARITH_RULE `i < i + 1`; APPEND_NIL] THEN - AP_TERM_TAC THEN - REWRITE_TAC[aes256_xts_decrypt_tail; LET_DEF; LET_END_DEF] -);; - - -let SUB_LIST_OF_AES256_XTS_DECRYPT_FULL_BLOCKS = prove( - `!(i:num) (ct:byte list) (iv:int128) (key1:int128 list) (key2:int128 list). - (SUB_LIST (0,16 * i) - (aes256_xts_decrypt ct (16 * i + 16) iv key1 key2)) - = aes256_xts_decrypt ct (16 * i) iv key1 key2`, - REPEAT STRIP_TAC THEN - - (* when i = 0, trivial *) - ASM_CASES_TAC `i = 0` THENL - [ - ASM_REWRITE_TAC[] THEN - CONV_TAC NUM_REDUCE_CONV THEN - REWRITE_TAC[CONJUNCT1 SUB_LIST; aes256_xts_decrypt] THEN - CONV_TAC NUM_REDUCE_CONV; - ALL_TAC - ] THEN - - (* when i = 1, using aes256_xts_decrypt_tail *) - ASM_CASES_TAC `i = 1` THENL - [ - ASM_REWRITE_TAC[] THEN - CONV_TAC NUM_REDUCE_CONV THEN - REWRITE_TAC[aes256_xts_decrypt] THEN - CONV_TAC NUM_REDUCE_CONV THEN - REWRITE_TAC[LET_DEF; LET_END_DEF] THEN - CONV_TAC NUM_REDUCE_CONV THEN - MP_TAC (SPECL [`ct:byte list`; `iv:int128`; `key1: int128 list`; `key2: int128 list`] - LENGTH_OF_AES256_XTS_DECRYPT_REC_TRIVIAL) THEN - DISCH_TAC THEN - IMP_REWRITE_TAC[SUB_LIST_APPEND_LEFT] THEN - CONV_TAC NUM_REDUCE_CONV THEN - IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN - REWRITE_TAC[AES256_XTS_DECRYPT_REC_EQ_TAIL_TRIVIAL]; - ALL_TAC - ] THEN - - (* when i >= 2, using aes256_xts_decrypt_rec *) - REWRITE_TAC[aes256_xts_decrypt] THEN - CONV_TAC NUM_REDUCE_CONV THEN - SUBGOAL_THEN `~(0x10 * i < 0x10)` ASSUME_TAC THENL - [ ASM_ARITH_TAC ; ALL_TAC] THEN - SUBGOAL_THEN `~(0x10 * i + 0x10 < 0x10)` ASSUME_TAC THENL - [ ASM_ARITH_TAC ; ALL_TAC] THEN - ASM_SIMP_TAC[] THEN - REWRITE_TAC[ARITH_RULE `16 * i + 16 = 16 * (i + 1)`; MOD_MULT] THEN - IMP_REWRITE_TAC[LET_DEF;LET_END_DEF;SUB_0;DIV_MULT] THEN - CONV_TAC NUM_REDUCE_CONV THEN - SUBGOAL_THEN `~(i < 0x2)` ASSUME_TAC THENL - [ ASM_ARITH_TAC ; ALL_TAC] THEN - SUBGOAL_THEN `~(i + 1 < 0x2)` ASSUME_TAC THENL - [ ASM_ARITH_TAC ; ALL_TAC] THEN - ASM_SIMP_TAC[ARITH_RULE `(i + 0x1) - 0x2 = i - 1`; ADD_SUB] THEN - SUBGOAL_THEN `LENGTH (aes256_xts_decrypt_rec 0x0 (i - 0x1) ct iv key1 key2) = 16 * i` ASSUME_TAC THENL - [ REWRITE_TAC[LENGTH_OF_AES256_XTS_DECRYPT_REC] THEN - ASM_ARITH_TAC; ALL_TAC] THEN - IMP_REWRITE_TAC[SUB_LIST_APPEND_LEFT; SUB_LIST_LENGTH_IMPLIES] THEN - CONJ_TAC THENL [ALL_TAC; ARITH_TAC] THEN - SUBGOAL_THEN `i - 1 = i - 2 + 1` ASSUME_TAC THENL - [ ASM_ARITH_TAC; ALL_TAC ] THEN - ASM_REWRITE_TAC[] THEN - IMP_REWRITE_TAC[AES256_XTS_DECRYPT_REC_EQ_TAIL] THEN - ASM_ARITH_TAC -);; - -let SUB_LIST_OF_AES256_XTS_DECRYPT = prove( - `!(i:num) (tail_len:num) (ct:byte list) (iv:int128) (key1:int128 list) (key2:int128 list). - ~(tail_len = 0) /\ tail_len < 16 ==> - (SUB_LIST (0,16 * i) - (aes256_xts_decrypt ct (16 * i + 16 + tail_len) iv key1 key2)) - = aes256_xts_decrypt ct (16 * i) iv key1 key2`, - REPEAT STRIP_TAC THEN - (* Case 1: i = 0 *) - ASM_CASES_TAC `i = 0` THENL - [ - ASM_REWRITE_TAC[] THEN - CONV_TAC NUM_REDUCE_CONV THEN - REWRITE_TAC[ADD; SUB_LIST_CLAUSES; aes256_xts_decrypt] THEN - CONV_TAC NUM_REDUCE_CONV; - ALL_TAC - ] THEN - (* Case 2: i = 1 *) - ASM_CASES_TAC `i = 1` THENL - [ - ASM_REWRITE_TAC[] THEN - CONV_TAC NUM_REDUCE_CONV THEN - REWRITE_TAC[aes256_xts_decrypt; ADD_ASSOC] THEN - CONV_TAC NUM_REDUCE_CONV THEN - SUBGOAL_THEN `~(0x20 + tail_len < 0x10)` ASSUME_TAC THENL [ARITH_TAC; ALL_TAC] THEN - ASM_SIMP_TAC[] THEN - CONV_TAC NUM_REDUCE_CONV THEN - REWRITE_TAC[LET_DEF; LET_END_DEF] THEN - CONV_TAC NUM_REDUCE_CONV THEN - SUBGOAL_THEN `(0x20 + tail_len) MOD 0x10 = tail_len` ASSUME_TAC THENL - [ ASM_SIMP_TAC[ARITH_RULE `32 = 2 * 16`; MOD_MULT_ADD] THEN - IMP_REWRITE_TAC[MOD_LT] - ; ALL_TAC] THEN - SUBGOAL_THEN `((0x20 + tail_len) - (0x20 + tail_len) MOD 0x10) DIV 0x10 = 0x2` ASSUME_TAC THENL - [ ASM_REWRITE_TAC[ADD_ASSOC; ADD_SUB] THEN - ARITH_TAC ; ALL_TAC] THEN - ASM_SIMP_TAC[] THEN - CONV_TAC NUM_REDUCE_CONV THEN - ASM_REWRITE_TAC[] THEN - MP_TAC (SPECL [`ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT_REC_TRIVIAL) THEN - DISCH_TAC THEN IMP_REWRITE_TAC[SUB_LIST_APPEND_LEFT] THEN - REWRITE_TAC[AES256_XTS_DECRYPT_REC_EQ_TAIL_TRIVIAL] THEN - MP_TAC (SPECL [`ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT_TAIL_TRIVIAL) THEN - DISCH_TAC THEN IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN - ARITH_TAC; - ALL_TAC - ] THEN - - (* Case 3: i >= 2 *) - ASM_CASES_TAC `i >= 2` THENL - [ - ASM_REWRITE_TAC[ADD_ASSOC] THEN - CONV_TAC NUM_REDUCE_CONV THEN - REWRITE_TAC[aes256_xts_decrypt] THEN - SUBGOAL_THEN `~(0x10 * i < 0x10)` ASSUME_TAC THENL - [ ASM_ARITH_TAC; ALL_TAC] THEN - SUBGOAL_THEN `~((0x10 * i + 0x10) + tail_len < 0x10)` ASSUME_TAC THENL - [ ASM_ARITH_TAC; ALL_TAC] THEN - ASM_SIMP_TAC[LET_DEF; LET_END_DEF] THEN - SUBGOAL_THEN `((0x10 * i + 0x10) + tail_len) MOD 0x10 = tail_len` SUBST1_TAC THENL - [ REWRITE_TAC[ARITH_RULE `0x10 * i + 0x10 = 16 * (i + 1)`] THEN - IMP_REWRITE_TAC[MOD_MULT_ADD; MOD_LT] - ; ALL_TAC] THEN - REWRITE_TAC[ADD_SUB; MOD_MULT; SUB_0; - ARITH_RULE `0x10 * i + 0x10 = 16 * (i + 1)`] THEN - IMP_REWRITE_TAC[DIV_MULT] THEN - SUBGOAL_THEN `~(i + 1 < 2)` ASSUME_TAC THENL [ ASM_ARITH_TAC; ALL_TAC] THEN - SUBGOAL_THEN `~(i < 2)` ASSUME_TAC THENL [ ASM_ARITH_TAC; ALL_TAC] THEN - ASM_SIMP_TAC[ADD_SUB; ARITH_RULE `(i + 1) - 2 = i - 1`] THEN - CONV_TAC NUM_REDUCE_CONV THEN - MP_TAC (SPECL [`0:num`; `(i - 1):num`; `ct:byte list`; `iv:int128`; - `key1:int128 list`; `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT_REC) THEN - SUBGOAL_THEN `~((i - 1) < 0)` ASSUME_TAC THENL [ ASM_ARITH_TAC; ALL_TAC] THEN - IMP_REWRITE_TAC[ARITH_RULE `i >= 2 ==> i - 0x1 - 0x0 + 0x1 = i`] THEN - IMP_REWRITE_TAC[SUB_LIST_APPEND_LEFT] THEN - SIMP_TAC[ARITH_RULE `16 * i <= i * 16`] THEN - IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN - SIMP_TAC[ARITH_RULE `i * 16 = 16 * i`] THEN - DISCH_TAC THEN - MP_TAC (SPECL [`0`; `(i-2):num`; `ct:byte list`; `iv:int128`; - `key1:int128 list`; `key2:int128 list`] AES256_XTS_DECRYPT_REC_EQ_TAIL) THEN - ANTS_TAC THENL [ ASM_ARITH_TAC; ALL_TAC ] THEN - IMP_REWRITE_TAC[ARITH_RULE `i >= 2 ==> i - 0x2 + 0x1 = i - 1`]; - ALL_TAC - ] THEN - - ASM_ARITH_TAC -);; - -let acc_len = new_definition -`acc_len (i:int64) (len:int64) : num = - if val i * 0x50 + 0x40 = val len then 0x50 * val i + 0x40 - else - if val i * 0x50 + 0x30 = val len then 0x50 * val i + 0x30 - else - if val i * 0x50 + 0x20 = val len then 0x50 * val i + 0x20 - else - if val i * 0x50 + 0x10 = val len then 0x50 * val i + 0x10 - else 0x50 * val i`;; - -let VALUE_OF_ACC_LEN = prove( - `!(i:int64) (len:int64). - val i * 0x50 <= val len ==> - val len DIV 0x50 = val i ==> - 0x10 divides val len ==> - acc_len i len = val len`, - REPEAT STRIP_TAC THEN - REWRITE_TAC[acc_len] THEN - REPEAT COND_CASES_TAC THENL - [ - ASM_ARITH_TAC; - ASM_ARITH_TAC; - ASM_ARITH_TAC; - ASM_ARITH_TAC; - REWRITE_TAC[ARITH_RULE `!a. 0x50 * a = a * 0x50`] THEN - SUBGOAL_THEN `val (i:int64) * 0x50 = val (len:int64)` ASSUME_TAC THENL - [ MATCH_MP_TAC (SPECL [`val (len:int64)`; `val (i:int64)`] DIVISION_BY_80_LEMMA) THEN - REPEAT CONJ_TAC THENL - [ - ASM_SIMP_TAC[]; - ASM_SIMP_TAC[]; - UNDISCH_TAC `~(val (i:int64) * 0x50 + 0x10 = val (len:int64))` THEN - UNDISCH_TAC `val (i:int64) * 0x50 <= val (len:int64)` THEN - ARITH_TAC; - UNDISCH_TAC `~(val (i:int64) * 0x50 + 0x20 = val (len:int64))` THEN - UNDISCH_TAC `val (i:int64) * 0x50 <= val (len:int64)` THEN - ARITH_TAC; - UNDISCH_TAC `~(val (i:int64) * 0x50 + 0x30 = val (len:int64))` THEN - UNDISCH_TAC `val (i:int64) * 0x50 <= val (len:int64)` THEN - ARITH_TAC; - UNDISCH_TAC `~(val (i:int64) * 0x50 + 0x40 = val (len:int64))` THEN - UNDISCH_TAC `val (i:int64) * 0x50 <= val (len:int64)` THEN - ARITH_TAC - ]; ALL_TAC] THEN - ASM_ARITH_TAC - ] -);; - -let BOUND_OF_ACC_LEN = prove( - `!(i:int64) (len:int64) x. - val i * 0x50 <= val len ==> - val len DIV 0x50 = val i ==> - 0x10 divides val len ==> - val len < x ==> acc_len i len < x`, - REPEAT STRIP_TAC THEN - SUBGOAL_THEN `acc_len i len = val (len:int64)` ASSUME_TAC THENL - [ MP_TAC (SPECL [`i:int64`; `len:int64`] VALUE_OF_ACC_LEN) THEN - ASM_SIMP_TAC[]; ALL_TAC] THEN - ASM_ARITH_TAC -);; - -let acc_blocks = new_definition -`acc_blocks (i:int64) (len:int64) (last:bool) : num = - if val i * 0x50 + 0x40 = val len then val i * 0x5 + 4 - else - if val i * 0x50 + 0x30 = val len then val i * 0x5 + 3 - else - if val i * 0x50 + 0x20 = val len then val i * 0x5 + 2 - else - if val i * 0x50 + 0x10 = val len then val i * 0x5 + 1 - else val i * 0x5`;; - -let cipher_stealing_inv = new_definition -`cipher_stealing_inv (i:num) (curr_len:num) (tail_len:num) (PP:int128) (ct:byte list): int128 = - bytes_to_int128( - APPEND (SUB_LIST (0, i) (int128_to_bytes PP)) - (APPEND (SUB_LIST (i, tail_len - i) (SUB_LIST (curr_len + 16, tail_len) ct)) - (SUB_LIST (tail_len, 16 - tail_len) (int128_to_bytes PP))))`;; - - -let CIPHER_STEALING_BYTE_EQUAL = prove( - `!(i:num) (curr_len:num) (tail_len:int64) (PP:int128) (ct:byte list). - i < val tail_len /\ val tail_len < 16 ==> - curr_len + 16 + val tail_len = LENGTH ct ==> - let InvPP = cipher_stealing_inv (i + 1) curr_len (val tail_len) PP ct - and InvPP' = cipher_stealing_inv i curr_len (val tail_len) PP ct in - (!j. 0 <= j /\ j < 16 /\ ~(j = i) ==> EL j (int128_to_bytes InvPP) = EL j (int128_to_bytes InvPP')) /\ - EL i (int128_to_bytes InvPP') = word_zx (EL (curr_len + 16 + i) ct)`, - REPEAT STRIP_TAC THEN - REWRITE_TAC[LET_DEF; LET_END_DEF] THEN - CONJ_TAC THENL - [ - REPEAT STRIP_TAC THEN - REWRITE_TAC[cipher_stealing_inv] THEN - IMP_REWRITE_TAC[INT128_TO_BYTES_OF_BYTES_TO_INT128] THEN - REPEAT CONJ_TAC THENL - [ - (* Three cases: 0 <= j < i, i < j < val tail_len, val tail_len <= j < 16 *) - ASM_CASES_TAC `j < i` THENL - [ - SUBGOAL_THEN `j < LENGTH (SUB_LIST (0x0,i + 0x1) (int128_to_bytes PP))` ASSUME_TAC THENL - [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN - ASM_ARITH_TAC; ALL_TAC] THEN - SUBGOAL_THEN `j < LENGTH (SUB_LIST (0x0,i) (int128_to_bytes PP))` ASSUME_TAC THENL - [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN - ASM_ARITH_TAC ; ALL_TAC] THEN - REWRITE_TAC[EL_APPEND] THEN - ASM_SIMP_TAC[] THEN - MP_TAC (ISPECL [`j:num`; `i:num`; `(int128_to_bytes PP):byte list`] EL_SUB_LIST) THEN - ANTS_TAC THENL - [ REWRITE_TAC[LENGTH_OF_INT128_TO_BYTES] THEN - ASM_ARITH_TAC; ALL_TAC ] THEN - MP_TAC (ISPECL [`j:num`; `(i + 1):num`; `(int128_to_bytes PP):byte list`] EL_SUB_LIST) THEN - ANTS_TAC THENL - [ REWRITE_TAC[LENGTH_OF_INT128_TO_BYTES] THEN - ASM_ARITH_TAC; ALL_TAC ] THEN - SIMP_TAC[]; ALL_TAC - ] THEN - ASM_CASES_TAC `j < val (tail_len:int64)` THENL - [ - SUBGOAL_THEN `j > i` ASSUME_TAC THENL[ASM_ARITH_TAC; ALL_TAC] THEN - REWRITE_TAC[EL_APPEND] THEN - SUBGOAL_THEN `LENGTH (SUB_LIST (0x0,i + 0x1) (int128_to_bytes PP)) = i + 1` SUBST1_TAC THENL - [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN - ASM_ARITH_TAC; ALL_TAC] THEN - SUBGOAL_THEN `LENGTH (SUB_LIST (0x0,i) (int128_to_bytes PP)) = i` SUBST1_TAC THENL - [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN - ASM_ARITH_TAC; ALL_TAC] THEN - SUBGOAL_THEN `LENGTH (SUB_LIST (i + 0x1,val (tail_len:int64) - (i + 0x1)) - (SUB_LIST (curr_len + 0x10,val tail_len) (ct:byte list))) - = val tail_len - (i + 1)` SUBST1_TAC THENL - [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN - ASM_ARITH_TAC; ALL_TAC] THEN - SUBGOAL_THEN `LENGTH (SUB_LIST (i,val (tail_len:int64) - i) - (SUB_LIST (curr_len + 0x10,val tail_len) (ct:byte list))) - = val tail_len - i` SUBST1_TAC THENL - [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN - ASM_ARITH_TAC; ALL_TAC] THEN - SUBGOAL_THEN `~(j < i)` ASSUME_TAC THENL - [ ASM_ARITH_TAC; ALL_TAC] THEN - SUBGOAL_THEN `~(j < i + 1)` ASSUME_TAC THENL - [ ASM_ARITH_TAC; ALL_TAC] THEN - SUBGOAL_THEN `j - i < val (tail_len:int64) - i` ASSUME_TAC THENL - [ ASM_ARITH_TAC; ALL_TAC] THEN - SUBGOAL_THEN `j - (i + 1) < val (tail_len:int64) - (i + 1)` ASSUME_TAC THENL - [ ASM_ARITH_TAC; ALL_TAC] THEN - ASM_SIMP_TAC[] THEN - MP_TAC (ISPECL [`(j - i):num`; `i:num`; - `(SUB_LIST (curr_len + 16,val (tail_len:int64)) (ct:byte list)):byte list`; - `(val (tail_len:int64) - i):num`] EL_SUB_LIST_SHIFT) THEN - ASM_SIMP_TAC[] THEN - ANTS_TAC THENL [ REWRITE_TAC[LENGTH_SUB_LIST] THEN ASM_ARITH_TAC; ALL_TAC] THEN - IMP_REWRITE_TAC[ARITH_RULE `!i j. j > i ==> j - i - 1 = j - (i + 1)`] THEN - ASM_ARITH_TAC; ALL_TAC - ] THEN - (* j >= val tail_len *) - REWRITE_TAC[EL_APPEND] THEN - SUBGOAL_THEN `LENGTH (SUB_LIST (0x0,i + 0x1) (int128_to_bytes PP)) = i + 1` SUBST1_TAC THENL - [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN - ASM_ARITH_TAC; ALL_TAC] THEN - SUBGOAL_THEN `LENGTH (SUB_LIST (0x0,i) (int128_to_bytes PP)) = i` SUBST1_TAC THENL - [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN - ASM_ARITH_TAC; ALL_TAC] THEN - SUBGOAL_THEN `LENGTH (SUB_LIST (i + 0x1,val (tail_len:int64) - (i + 0x1)) - (SUB_LIST (curr_len + 0x10,val tail_len) (ct:byte list))) - = val tail_len - (i + 1)` SUBST1_TAC THENL - [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN - ASM_ARITH_TAC; ALL_TAC] THEN - SUBGOAL_THEN `LENGTH (SUB_LIST (i,val (tail_len:int64) - i) - (SUB_LIST (curr_len + 0x10,val tail_len) (ct:byte list))) - = val tail_len - i` SUBST1_TAC THENL - [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN - ASM_ARITH_TAC; ALL_TAC] THEN - SUBGOAL_THEN `~(j < i)` ASSUME_TAC THENL - [ ASM_ARITH_TAC; ALL_TAC] THEN - SUBGOAL_THEN `~(j < i + 1)` ASSUME_TAC THENL - [ ASM_ARITH_TAC; ALL_TAC] THEN - SUBGOAL_THEN `~(j - i < val (tail_len:int64) - i)` ASSUME_TAC THENL - [ ASM_ARITH_TAC; ALL_TAC] THEN - SUBGOAL_THEN `~(j - (i + 1) < val (tail_len:int64) - (i + 1))` ASSUME_TAC THENL - [ ASM_ARITH_TAC; ALL_TAC] THEN - ASM_SIMP_TAC[] THEN - AP_THM_TAC THEN AP_TERM_TAC THEN - ASM_ARITH_TAC; +(**********************************************************************) +(** Tactics **) - REWRITE_TAC[LENGTH_APPEND] THEN - REWRITE_TAC[LENGTH_SUB_LIST] THEN - REWRITE_TAC[LENGTH_OF_INT128_TO_BYTES] THEN - CONV_TAC NUM_REDUCE_CONV THEN - IMP_REWRITE_TAC[ARITH_RULE `i < 16 ==> MIN i 16 = i`] THEN - SUBGOAL_THEN `LENGTH (ct:byte list) - (curr_len + 16) = val (tail_len:int64)` SUBST1_TAC THENL - [ ASM_ARITH_TAC; ALL_TAC ] THEN - REWRITE_TAC[ARITH_RULE `!x. MIN x x = x`] THEN - ASM_ARITH_TAC; - - REWRITE_TAC[LENGTH_APPEND] THEN - REWRITE_TAC[LENGTH_SUB_LIST] THEN - REWRITE_TAC[LENGTH_OF_INT128_TO_BYTES] THEN - CONV_TAC NUM_REDUCE_CONV THEN - IMP_REWRITE_TAC[ARITH_RULE `i < 16 ==> MIN (i + 1) 16 = i + 1`] THEN - SUBGOAL_THEN `LENGTH (ct:byte list) - (curr_len + 16) = val (tail_len:int64)` SUBST1_TAC THENL - [ ASM_ARITH_TAC; ALL_TAC ] THEN - REWRITE_TAC[ARITH_RULE `!x. MIN x x = x`] THEN - ASM_ARITH_TAC - ] ; ALL_TAC - ] THEN +let AESENC_TAC = + REWRITE_TAC [aes256_encrypt] THEN + REWRITE_TAC EL_15_128_CLAUSES THEN + REWRITE_TAC [aes256_encrypt_round] THEN + CONV_TAC(TOP_DEPTH_CONV let_CONV) THEN + REWRITE_TAC [aese;aesmc] THEN + GEN_REWRITE_TAC LAND_CONV [WORD_XOR_SYM] THEN + REFL_TAC;; - REWRITE_TAC[cipher_stealing_inv] THEN - IMP_REWRITE_TAC[INT128_TO_BYTES_OF_BYTES_TO_INT128] THEN - CONJ_TAC THENL [ - REWRITE_TAC[EL_APPEND] THEN - SUBGOAL_THEN `LENGTH (SUB_LIST (0x0,i) (int128_to_bytes PP)) = i` SUBST1_TAC THENL - [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN - ASM_ARITH_TAC; ALL_TAC] THEN - SUBGOAL_THEN `LENGTH (SUB_LIST (i,val (tail_len:int64) - i) - (SUB_LIST (curr_len + 0x10,val tail_len) (ct:byte list))) - = val tail_len - i` SUBST1_TAC THENL - [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN - ASM_ARITH_TAC; ALL_TAC] THEN - SIMP_TAC[ARITH_RULE `~(i < i)`; SUB_REFL] THEN - SUBGOAL_THEN `0 < val (tail_len:int64) - i` ASSUME_TAC THENL - [ ASM_ARITH_TAC; ALL_TAC] THEN - ASM_SIMP_TAC[] THEN - MP_TAC (ISPECL [`curr_len + 0x10:num`; `i:num`; `ct:byte list`; - `val (tail_len:int64) - i:num`; `val (tail_len:int64)`] SUB_LIST_MIN_GENERAL) THEN - REWRITE_TAC[ARITH_RULE `!a. MIN a a = a`; GSYM ADD_ASSOC] THEN - DISCH_THEN (fun th -> (REWRITE_TAC [th])) THEN - REWRITE_TAC[WORD_ZX_TRIVIAL; EL] THEN - MATCH_MP_TAC HD_SUB_LIST_CONS_GENERAL THEN - ASM_ARITH_TAC; ALL_TAC] THEN - REWRITE_TAC[LENGTH_APPEND] THEN - REWRITE_TAC[LENGTH_SUB_LIST] THEN - REWRITE_TAC[LENGTH_OF_INT128_TO_BYTES] THEN - CONV_TAC NUM_REDUCE_CONV THEN - ASM_ARITH_TAC -);; +let AESDEC_TAC = + REWRITE_TAC [aes256_decrypt] THEN + REWRITE_TAC EL_15_128_CLAUSES THEN + CONV_TAC(TOP_DEPTH_CONV let_CONV) THEN + REWRITE_TAC [aes256_decrypt_round] THEN + CONV_TAC(TOP_DEPTH_CONV let_CONV) THEN + REWRITE_TAC [aesd;aesimc] THEN + (* NOTE: BITBLAST_TAC couldn't handle this goal *) + GEN_REWRITE_TAC LAND_CONV [WORD_XOR_SYM] THEN + AP_THM_TAC THEN AP_TERM_TAC THEN + GEN_REWRITE_TAC LAND_CONV [WORD_XOR_SYM] THEN + AP_THM_TAC THEN AP_TERM_TAC THEN AP_TERM_TAC THEN AP_TERM_TAC THEN + REPLICATE_TAC 13 (AP_THM_TAC THEN (REPLICATE_TAC 4 AP_TERM_TAC)) THEN + AP_THM_TAC THEN AP_TERM_TAC THEN + GEN_REWRITE_TAC LAND_CONV [WORD_XOR_SYM] THEN REFL_TAC;; -let CIPHER_STEALING_INV_SELECT = prove( - `!(i:num) (curr_len:num) (tail_len:int64) (PP:int128) (ct:byte list). - i < val tail_len ==> val tail_len < 16 ==> - curr_len + 16 + (val tail_len) = LENGTH ct ==> - EL i (int128_to_bytes (cipher_stealing_inv (i + 1) curr_len (val tail_len) PP ct)) = - EL i (int128_to_bytes PP)`, - REPEAT STRIP_TAC THEN - REWRITE_TAC[cipher_stealing_inv] THEN - IMP_REWRITE_TAC[INT128_TO_BYTES_OF_BYTES_TO_INT128] THEN - CONJ_TAC THENL [ - SUBGOAL_THEN `LENGTH (SUB_LIST (0x0,i + 1) (int128_to_bytes PP)) <= i + 1` ASSUME_TAC THENL - [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN - ARITH_TAC; ALL_TAC] THEN - REWRITE_TAC[EL_APPEND] THEN - SUBGOAL_THEN `i < LENGTH (SUB_LIST (0x0,i + 0x1) (int128_to_bytes PP))` ASSUME_TAC THENL - [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN - ASM_ARITH_TAC; ALL_TAC] THEN - ASM_SIMP_TAC[] THEN - MATCH_MP_TAC EL_SUB_LIST THEN - REWRITE_TAC[LENGTH_OF_INT128_TO_BYTES] THEN - ASM_ARITH_TAC; ALL_TAC - ] THEN +let TWEAK_UPDATE_CONV = + let ADD_SUC_1 = ARITH_RULE `!n. n + 1 = SUC(n)` in + let ADD_SUC_2 = ARITH_RULE `!n. n + 2 = SUC(n + 1)` in + let ADD_SUC_3 = ARITH_RULE `!n. n + 3 = SUC(n + 2)` in + let ADD_SUC_4 = ARITH_RULE `!n. n + 4 = SUC(n + 3)` in + let ADD_SUC_5 = ARITH_RULE `!n. n + 5 = SUC(n + 4)` in + let ADD_SUC_6 = ARITH_RULE `!n. n + 6 = SUC(n + 5)` in + let ADD_SUC_7 = ARITH_RULE `!n. n + 7 = SUC(n + 6)` in + let ADD_SUC_8 = ARITH_RULE `!n. n + 8 = SUC(n + 7)` in + let ADD_SUC_9 = ARITH_RULE `!n. n + 9 = SUC(n + 8)` in + NUM_REDUCE_CONV THENC + RATOR_CONV (LAND_CONV (num_CONV ORELSEC + FIRST_CONV + [ CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_1]); + CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_2]); + CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_3]); + CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_4]); + CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_5]); + CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_6]); + CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_7]); + CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_8]); + CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_9]);])) THENC + REWRITE_CONV [CONJUNCT2 calculate_tweak] THENC + GF_128_MULT_BY_PRIMITIVE_CONV;; - REWRITE_TAC[LENGTH_APPEND] THEN - REWRITE_TAC[LENGTH_SUB_LIST] THEN - REWRITE_TAC[LENGTH_OF_INT128_TO_BYTES] THEN - CONV_TAC NUM_REDUCE_CONV THEN - IMP_REWRITE_TAC[ARITH_RULE `i < 16 ==> MIN (i + 1) 16 = i + 1`] THEN - SUBGOAL_THEN `LENGTH (ct:byte list) - (curr_len + 16) = val (tail_len:int64)` SUBST1_TAC THENL - [ ASM_ARITH_TAC; ALL_TAC ] THEN - REWRITE_TAC[ARITH_RULE `!x. MIN x x = x`] THEN - ASM_ARITH_TAC -);; +let TWEAK_TAC reg ind indm1 = + let lower_term = subst [ind,`ind:num`] `(word_zx:int128->int64) (calculate_tweak ind iv key2)` in + let upper_term = subst [ind,`ind:num`] `(word_subword:int128->num#num->int64) (calculate_tweak ind iv key2) (64,64)` in + let full_term = subst [ind,`ind:num`] `calculate_tweak ind iv key2` in + let full_lemma = subst [reg,`reg:(armstate,int128)component`] `read (reg:(armstate,int128)component) (s:armstate) = a ==> !a'. a = a' ==> read reg s = a'` in + let abbrev_term = subst [indm1,`indm1:num`] `tweak_pre:int128 = (calculate_tweak indm1 iv key2)` in + FIRST_X_ASSUM(MP_TAC o SPEC lower_term + o MATCH_MP (MESON[] `read X9 s = a ==> !a'. a = a' ==> read X9 s = a'`)) THEN + ANTS_TAC THENL [CONV_TAC (RAND_CONV (RAND_CONV TWEAK_UPDATE_CONV)) THEN + ABBREV_TAC abbrev_term THEN + BITBLAST_TAC; DISCH_TAC] THEN + FIRST_X_ASSUM(MP_TAC o SPEC upper_term + o MATCH_MP (MESON[] `read X10 s = a ==> !a'. a = a' ==> read X10 s = a'`)) THEN + ANTS_TAC THENL [CONV_TAC (RAND_CONV (RATOR_CONV (RAND_CONV TWEAK_UPDATE_CONV))) THEN + ABBREV_TAC abbrev_term THEN + BITBLAST_TAC; DISCH_TAC] THEN + FIRST_X_ASSUM(MP_TAC o SPEC full_term + o MATCH_MP (MESON[] full_lemma)) THEN + ANTS_TAC THENL [CONV_TAC (RAND_CONV TWEAK_UPDATE_CONV) THEN + ABBREV_TAC abbrev_term THEN + BITBLAST_TAC; DISCH_TAC];; -let CIPHER_STEALING_INV_SIMP_TAC i = - ( FIRST_ASSUM (fun th -> MATCH_MP_TAC(SPEC i th)) THEN CONV_TAC NUM_REDUCE_CONV) ORELSE - ( ASM_REWRITE_TAC[] THEN - REWRITE_TAC[WORD_RULE `!a b. word_add ((word a):int64) (word b) = word (a + b)`] THEN - REWRITE_TAC[GSYM ADD_ASSOC] THEN - CONV_TAC NUM_REDUCE_CONV THEN - IMP_REWRITE_TAC[WORD_ZX_ZX; WORD_ZX_TRIVIAL] THEN - REWRITE_TAC[DIMINDEX_8; DIMINDEX_32; DIMINDEX_64] THEN - IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN - ASM_ARITH_TAC);; +let XTSDEC_TAC reg ind ind_tweak = + let tm = subst [ind, `ind:num`; ind_tweak, `ind_tweak:num`] + `aes256_xts_decrypt_round (bytes_to_int128 (SUB_LIST (ind,0x10) (ct:byte list))) + (calculate_tweak ind_tweak iv key2) key1` in + let lemma = subst [reg, `reg:(armstate,int128)component`] + `read (reg:(armstate,int128)component) (s:armstate) = a ==> !a'. a = a' ==> read reg s = a'` in + FIRST_X_ASSUM(MP_TAC o SPEC tm o MATCH_MP (MESON[] lemma)) THEN + ANTS_TAC THENL + [ EXPAND_TAC "key1" THEN + CONV_TAC (RAND_CONV ( + REWRITE_CONV [aes256_xts_decrypt_round] THENC + DEPTH_CONV let_CONV)) THEN + AESDEC_TAC; DISCH_TAC ];; let TAIL_SWAP_CASE_TAC case = let c_tm = `case:num` in @@ -3408,80 +1602,16 @@ let TAIL_SWAP_ASM_CASES_TAC case = MP_TAC (SPECL [case; `i:num`] LE_LT) THEN ASM_SIMP_TAC[] THEN DISCH_TAC THEN - MP_TAC (SPECL [case; `i:num`] LE_SUC_LT) THEN - ASM_SIMP_TAC[] THEN - CONV_TAC NUM_REDUCE_CONV THEN - ASM_SIMP_TAC[] THEN - DISCH_TAC;; - - -let BREAK_DATA_INTO_PARTS = prove( - `!curr_len (tail_len:int64) (pt_ptr:int64) (s:armstate). - ((curr_len + 0x10 + val tail_len <= LENGTH bl) /\ - (forall i. i < curr_len - ==> read (memory :> bytes8 (word_add pt_ptr (word i))) s = EL i bl) /\ - (forall i. i < 16 - ==> read (memory :> bytes8 (word_add (word_add pt_ptr (word curr_len)) (word i))) s = - EL i (SUB_LIST (curr_len, 16 + val tail_len) bl)) /\ - (forall i. i < val tail_len - ==> read (memory :> bytes8 - (word_add (word_add pt_ptr (word (curr_len + 0x10))) (word i))) s = - EL i (SUB_LIST (curr_len + 16, val tail_len) bl))) ==> - forall i. - i < curr_len + 0x10 + val tail_len - ==> read (memory :> bytes8 (word_add pt_ptr (word i))) s = EL i bl`, - REPEAT GEN_TAC THEN - DISCH_THEN (CONJUNCTS_THEN2 (LABEL_TAC "H") - (CONJUNCTS_THEN2 (LABEL_TAC "H1") - (CONJUNCTS_THEN2 (LABEL_TAC "H2") (LABEL_TAC "H3")))) THEN - REPEAT STRIP_TAC THEN - - ASM_CASES_TAC `i < curr_len` THENL - [ - FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[]; - ALL_TAC - ] THEN - - ASM_CASES_TAC `i < curr_len + 16` THENL - [ - USE_THEN "H2" (fun th -> MP_TAC (SPEC `i - curr_len` th)) THEN - REMOVE_THEN "H2" (K ALL_TAC) THEN - SUBGOAL_THEN `(word_add (word_add (pt_ptr:int64) (word curr_len)) (word (i - curr_len))) - = (word_add pt_ptr (word i))` ASSUME_TAC THENL - [ REWRITE_TAC[WORD_RULE `word_add (word_add a (word b)) (word c) = word_add a (word (b + c))`] THEN - AP_TERM_TAC THEN AP_TERM_TAC THEN - ASM_ARITH_TAC; ALL_TAC] THEN - ASM_REWRITE_TAC[] THEN - ANTS_TAC THENL[ASM_ARITH_TAC; ALL_TAC] THEN - SIMP_TAC[] THEN DISCH_TAC THEN - IMP_REWRITE_TAC[EL_SUB_LIST_GENERAL] THEN - ASM_ARITH_TAC; - ALL_TAC - ] THEN + MP_TAC (SPECL [case; `i:num`] LE_SUC_LT) THEN + ASM_SIMP_TAC[] THEN + CONV_TAC NUM_REDUCE_CONV THEN + ASM_SIMP_TAC[] THEN + DISCH_TAC;; - ASM_CASES_TAC `i < curr_len + 16 + val (tail_len:int64)` THENL - [ - USE_THEN "H3" (fun th -> MP_TAC (SPEC `i - curr_len - 16` th)) THEN - REMOVE_THEN "H3" (K ALL_TAC) THEN - SUBGOAL_THEN `(word_add (word_add (pt_ptr:int64) (word (curr_len + 0x10))) - (word (i - curr_len - 0x10))) = (word_add pt_ptr (word i))` ASSUME_TAC THENL - [ REWRITE_TAC[WORD_RULE `word_add (word_add a (word b)) (word c) = word_add a (word (b + c))`] THEN - AP_TERM_TAC THEN AP_TERM_TAC THEN - ASM_ARITH_TAC; ALL_TAC] THEN - ASM_REWRITE_TAC[] THEN - ANTS_TAC THENL[ASM_ARITH_TAC; ALL_TAC] THEN - SIMP_TAC[] THEN DISCH_TAC THEN - REWRITE_TAC[ARITH_RULE `i - curr_len - 16 = i - (curr_len + 16)`] THEN - IMP_REWRITE_TAC[EL_SUB_LIST_GENERAL] THEN - ASM_ARITH_TAC; - ALL_TAC - ] THEN - ASM_ARITH_TAC -);; +(**********************************************************************) +(** Proofs **) -(* ************************************** *) -(* Assembly proofs *) (* Proof: Cipher stealing *) let CIPHER_STEALING_CORRECT = time prove( @@ -3757,7 +1887,7 @@ let CIPHER_STEALING_CORRECT = time prove( (* Decrypt last block *) ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (3--11) THEN TWEAK_TAC `Q8:(armstate,int128)component` `(curr_blocks + 1):num` `curr_blocks:num` THEN - MP_TAC (SPECL [`ct_ptr:int64`; `curr_len:num`; `len:int64`; `ct:byte list`; `s11:armstate`] READ_CT_LAST_LEMMA) THEN + MP_TAC (SPECL [`ct_ptr:int64`; `curr_len:num`; `len:int64`; `ct:byte list`; `s11:armstate`] READ_LAST_LEMMA) THEN ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (12--42) THEN XTSDEC_TAC `Q26:(armstate,int128)component` `curr_len:num` `(curr_blocks + 1):num` THEN @@ -4100,7 +2230,7 @@ let CIPHER_STEALING_CORRECT = time prove( COND_CASES_TAC THENL [SIMP_TAC[] THEN ARITH_TAC; ALL_TAC] THEN SIMP_TAC[] THEN ARITH_TAC; ALL_TAC] THEN - MATCH_MP_TAC BREAK_DATA_INTO_PARTS THEN + MATCH_MP_TAC BREAK_DATA_INTO_PARTS_DECRYPT THEN REPEAT CONJ_TAC THENL [ (* 0. Trivial *) @@ -4184,498 +2314,138 @@ let CIPHER_STEALING_CORRECT = time prove( EXPAND_TAC "combinedPP" THEN EXPAND_TAC "PP" THEN CONV_TAC NUM_REDUCE_CONV; - ALL_TAC - ] THEN - - SUBGOAL_THEN `curr_blocks >= 1` ASSUME_TAC THENL - [ UNDISCH_TAC `~(curr_blocks + 0x1 < 0x2)` THEN ARITH_TAC; ALL_TAC] THEN - - IMP_REWRITE_TAC[ADD_SUB; ARITH_RULE `((curr_blocks + 0x1) - 0x2) = curr_blocks - 1`] THEN - - MP_TAC (SPECL [`0:num`; `(curr_blocks - 1):num`; `ct:byte list`; `iv:int128`; - `key1:int128 list`; `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT_REC) THEN - ASM_SIMP_TAC[ARITH_RULE `curr_blocks >= 1 ==> ~(curr_blocks - 1 < 0)`] THEN - IMP_REWRITE_TAC[SUB_0; ARITH_RULE `curr_blocks >= 1 ==> curr_blocks - 1 + 1 = curr_blocks`] THEN - ONCE_REWRITE_TAC[ARITH_RULE `curr_blocks * 16 = 16 * curr_blocks`] THEN - DISCH_TAC THEN - IMP_REWRITE_TAC[SUB_LIST_APPEND_RIGHT_LEMMA] THEN - - REWRITE_TAC[aes256_xts_decrypt_tail] THEN - ASM_SIMP_TAC[LET_DEF; LET_END_DEF] THEN - - MP_TAC (SPECL [`(SUB_LIST (curr_blocks * 0x10,0x10) ct):byte list`; - `(SUB_LIST ((curr_blocks + 0x1) * 0x10,val (tail_len:int64)) ct):byte list`; - `val (tail_len:int64)`; `iv:int128`; `curr_blocks:num`; `key1:int128 list`; - `key2:int128 list`] LENGTH_OF_FST_OF_CIPHER_STEALING) THEN - DISCH_TAC THEN - IMP_REWRITE_TAC[SUB_LIST_APPEND_LEFT; ARITH_RULE `16 <= 16`] THEN - - REWRITE_TAC[cipher_stealing; LET_DEF; LET_END_DEF] THEN - REWRITE_TAC[SUB_LIST_OF_INT128_TO_BYTES; - NUM_OF_BYTELIST_OF_INT128_TO_BYTES; CALCULATE_TWEAK_EXPAND; - ARITH_RULE `curr_blocks * 16 = 16 * curr_blocks`; - ARITH_RULE `0x10 * (curr_blocks + 0x1) = 16 * curr_blocks + 16`] THEN - EXPAND_TAC "combinedPP" THEN - EXPAND_TAC "PP" THEN - REFL_TAC; - - (* 3. Proving tail is correct *) - UNDISCH_TAC - `forall i. i < val (tail_len:int64) - ==> read (memory :> bytes8 - (word_add (word_add pt_ptr (word (0x10 * curr_blocks + 0x10))) - (word i))) s33 = - EL i (SUB_LIST (0x0,val tail_len) (int128_to_bytes PP))` THEN - MP_TAC (SPECL [`val (tail_len:int64):num`; `(word_add pt_ptr (word (0x10 * curr_blocks + 0x10))):int64`; - `(SUB_LIST (0x0,val (tail_len:int64)) (int128_to_bytes PP)):byte list`; - `s33:armstate`] BYTE_LIST_TO_NUM_THM) THEN - ANTS_TAC THENL[ - REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN - CONV_TAC NUM_REDUCE_CONV THEN - UNDISCH_TAC `val (tail_len:int64) < 0x10` THEN - ARITH_TAC; ALL_TAC] THEN - DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN - MP_TAC (SPECL [`val (tail_len:int64):num`; `(word_add pt_ptr (word (0x10 * curr_blocks + 0x10))):int64`; - `(SUB_LIST (0x10 * curr_blocks + 0x10,val (tail_len:int64)) - (aes256_xts_decrypt ct (0x10 * curr_blocks + 0x10 + val tail_len) iv key1 key2)):byte list`; - `s33:armstate`] BYTE_LIST_TO_NUM_THM) THEN - ANTS_TAC THENL[ - REWRITE_TAC[LENGTH_SUB_LIST] THEN - IMP_REWRITE_TAC[LENGTH_OF_AES256_XTS_DECRYPT] THEN - ARITH_TAC; ALL_TAC] THEN - DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN - - DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN - AP_TERM_TAC THEN - REWRITE_TAC[SUB_LIST_IDEMPOTENT] THEN - REWRITE_TAC[SUB_LIST_MIN_RIGHT; MIN; LE_REFL] THEN - - REWRITE_TAC[aes256_xts_decrypt; - ARITH_RULE `~(0x10 * curr_blocks + 0x10 + val (tail_len:int64) < 0x10)`] THEN - REWRITE_TAC[ARITH_RULE `0x10 * curr_blocks + 0x10 + val tail_len = - 0x10 * (curr_blocks + 1) + val tail_len`] THEN - REWRITE_TAC[MOD_MULT_ADD] THEN - ASM_SIMP_TAC[MOD_LT] THEN - REWRITE_TAC[LET_DEF; LET_END_DEF] THEN - REWRITE_TAC[ARITH_RULE - `((0x10 * (curr_blocks + 0x1) + val tail_len) - val tail_len) DIV 0x10 = - (0x10 * (curr_blocks + 0x1)) DIV 0x10`] THEN - IMP_REWRITE_TAC[DIV_MULT; ARITH_RULE `~(16 = 0)`] THEN - COND_CASES_TAC THENL - [ - SUBGOAL_THEN `curr_blocks = 0` SUBST_ALL_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN - REWRITE_TAC[aes256_xts_decrypt_tail] THEN - ASM_SIMP_TAC[LET_DEF; LET_END_DEF] THEN - CONV_TAC NUM_REDUCE_CONV THEN - - MP_TAC (SPECL [`(SUB_LIST (0,0x10) ct):byte list`; - `(SUB_LIST (0x10,val (tail_len:int64)) ct):byte list`; - `val (tail_len:int64)`; `iv:int128`; `0:num`; `key1:int128 list`; - `key2:int128 list`] LENGTH_OF_FST_OF_CIPHER_STEALING) THEN - DISCH_TAC THEN - IMP_REWRITE_TAC[SUB_LIST_APPEND_RIGHT_LEMMA; ARITH_RULE `16 <= 16`] THEN - - REWRITE_TAC[cipher_stealing; LET_DEF; LET_END_DEF; SUB_LIST_IDEMPOTENT] THEN - EXPAND_TAC "PP" THEN - REWRITE_TAC[CALCULATE_TWEAK_EXPAND] THEN - CONV_TAC NUM_REDUCE_CONV; - ALL_TAC - ] THEN - - SUBGOAL_THEN `curr_blocks >= 1` ASSUME_TAC THENL - [ UNDISCH_TAC `~(curr_blocks + 0x1 < 0x2)` THEN ARITH_TAC; ALL_TAC] THEN - - IMP_REWRITE_TAC[ADD_SUB; ARITH_RULE `((curr_blocks + 0x1) - 0x2) = curr_blocks - 1`] THEN - - MP_TAC (ISPECL [`(aes256_xts_decrypt_rec 0x0 (curr_blocks - 0x1) ct iv key1 key2):byte list`; - `(aes256_xts_decrypt_tail curr_blocks (val (tail_len:int64)) ct iv key1 key2):byte list`; - `0x10 * curr_blocks + 0x10:num`; `val (tail_len:int64)`; `0x10 * curr_blocks:num` - ] SUB_LIST_APPEND_RIGHT_GENERAL) THEN - ANTS_TAC THENL - [ REWRITE_TAC[LENGTH_OF_AES256_XTS_DECRYPT_REC] THEN - UNDISCH_TAC `curr_blocks >= 1` THEN - ARITH_TAC; ALL_TAC] THEN - ANTS_TAC THENL [ ARITH_TAC; ALL_TAC] THEN - DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN - - REWRITE_TAC[ARITH_RULE `(0x10 * curr_blocks + 0x10) - 0x10 * curr_blocks = 0x10`] THEN - REWRITE_TAC[aes256_xts_decrypt_tail] THEN - ASM_SIMP_TAC[LET_DEF; LET_END_DEF] THEN - - MP_TAC (SPECL [`(SUB_LIST (curr_blocks * 0x10,0x10) ct):byte list`; - `(SUB_LIST ((curr_blocks + 0x1) * 0x10,val (tail_len:int64)) ct):byte list`; - `val (tail_len:int64)`; `iv:int128`; `curr_blocks:num`; `key1:int128 list`; - `key2:int128 list`] LENGTH_OF_FST_OF_CIPHER_STEALING) THEN - DISCH_TAC THEN - IMP_REWRITE_TAC[SUB_LIST_APPEND_RIGHT_LEMMA; ARITH_RULE `16 <= 16`] THEN - - REWRITE_TAC[cipher_stealing; LET_DEF; LET_END_DEF; SUB_LIST_IDEMPOTENT] THEN - EXPAND_TAC "PP" THEN - REWRITE_TAC[ARITH_RULE `curr_blocks * 0x10 = 0x10 * curr_blocks`; - CALCULATE_TWEAK_EXPAND] - ] - ] -);; - -let READ_LT_2BLOCK = prove( - `!(ptr:int64) (len:int64) (bl:byte list) (s:armstate). - LENGTH bl = val len ==> - val len >= 0x10 ==> - val len < 0x20 ==> - (forall i. i < val len - ==> read (memory :> bytes8 (word_add ptr (word i))) s = EL i bl) - ==> read (memory :> bytes128 ptr) s = bytes_to_int128 (SUB_LIST (0, 16) bl)`, - REPEAT STRIP_TAC THEN - MP_TAC (SPECL [`0:num`; `bl:byte list`; `ptr:int64`; - `len:int64`; `s:armstate`] BYTE_LIST_AT_1BLOCKS) THEN - REWRITE_TAC[byte_list_at] THEN - ANTS_TAC THENL[ ASM_SIMP_TAC[]; ALL_TAC] THEN - ANTS_TAC THENL[ ASM_SIMP_TAC[]; ALL_TAC] THEN - ANTS_TAC THENL[ ASM_ARITH_TAC; ALL_TAC] THEN - ASM_SIMP_TAC[WORD_ADD_0] -);; - -let READ_LT_3BLOCK = prove( - `!(ptr:int64) (len:int64) (bl:byte list) (s:armstate). - LENGTH bl = val len ==> - ~(val len < 0x20) ==> - val len < 0x30 ==> - (forall i. i < val len - ==> read (memory :> bytes8 (word_add ptr (word i))) s = EL i bl) - ==> read (memory :> bytes128 ptr) s = bytes_to_int128 (SUB_LIST (0, 16) bl) /\ - read (memory :> bytes128 (word_add ptr (word 16))) s = - bytes_to_int128 (SUB_LIST (16, 16) bl)`, - REPEAT GEN_TAC THEN REPEAT_N 4 STRIP_TAC THEN - MP_TAC (SPECL [`0:num`; `bl:byte list`; `ptr:int64`; - `len:int64`; `s:armstate`] BYTE_LIST_AT_2BLOCKS) THEN - REWRITE_TAC[byte_list_at] THEN - ANTS_TAC THENL[ ASM_SIMP_TAC[]; ALL_TAC] THEN - ANTS_TAC THENL[ ASM_SIMP_TAC[]; ALL_TAC] THEN - ANTS_TAC THENL[ ASM_ARITH_TAC; ALL_TAC] THEN - CONV_TAC NUM_REDUCE_CONV THEN - ASM_SIMP_TAC[WORD_ADD_0] -);; - -let READ_LT_4BLOCK = prove( - `!(ptr:int64) (len:int64) (bl:byte list) (s:armstate). - LENGTH bl = val len ==> - ~(val len < 0x30) ==> - val len < 0x40 ==> - (forall i. i < val len - ==> read (memory :> bytes8 (word_add ptr (word i))) s = EL i bl) - ==> read (memory :> bytes128 ptr) s = bytes_to_int128 (SUB_LIST (0, 16) bl) /\ - read (memory :> bytes128 (word_add ptr (word 16))) s = - bytes_to_int128 (SUB_LIST (16, 16) bl) /\ - read (memory :> bytes128 (word_add ptr (word 32))) s = - bytes_to_int128 (SUB_LIST (32, 16) bl)`, - REPEAT GEN_TAC THEN REPEAT_N 4 STRIP_TAC THEN - MP_TAC (SPECL [`0:num`; `bl:byte list`; `ptr:int64`; - `len:int64`; `s:armstate`] BYTE_LIST_AT_3BLOCKS) THEN - REWRITE_TAC[byte_list_at] THEN - ANTS_TAC THENL[ ASM_SIMP_TAC[]; ALL_TAC] THEN - ANTS_TAC THENL[ ASM_SIMP_TAC[]; ALL_TAC] THEN - ANTS_TAC THENL[ ASM_ARITH_TAC; ALL_TAC] THEN - CONV_TAC NUM_REDUCE_CONV THEN - ASM_SIMP_TAC[WORD_ADD_0] -);; - -let READ_LT_5BLOCK = prove( - `!(ptr:int64) (len:int64) (bl:byte list) (s:armstate). - LENGTH bl = val len ==> - ~(val len < 0x40) ==> - val len < 0x50 ==> - (forall i. i < val len - ==> read (memory :> bytes8 (word_add ptr (word i))) s = EL i bl) - ==> read (memory :> bytes128 ptr) s = bytes_to_int128 (SUB_LIST (0, 16) bl) /\ - read (memory :> bytes128 (word_add ptr (word 16))) s = - bytes_to_int128 (SUB_LIST (16, 16) bl) /\ - read (memory :> bytes128 (word_add ptr (word 32))) s = - bytes_to_int128 (SUB_LIST (32, 16) bl) /\ - read (memory :> bytes128 (word_add ptr (word 48))) s = - bytes_to_int128 (SUB_LIST (48, 16) bl)`, - REPEAT GEN_TAC THEN REPEAT_N 4 STRIP_TAC THEN - MP_TAC (SPECL [`0:num`; `bl:byte list`; `ptr:int64`; - `len:int64`; `s:armstate`] BYTE_LIST_AT_4BLOCKS) THEN - REWRITE_TAC[byte_list_at] THEN - ANTS_TAC THENL[ ASM_SIMP_TAC[]; ALL_TAC] THEN - ANTS_TAC THENL[ ASM_SIMP_TAC[]; ALL_TAC] THEN - ANTS_TAC THENL[ ASM_ARITH_TAC; ALL_TAC] THEN - CONV_TAC NUM_REDUCE_CONV THEN - ASM_SIMP_TAC[WORD_ADD_0] -);; - -let READ_LT_6BLOCK = prove( - `!(ptr:int64) (len:int64) (bl:byte list) (s:armstate). - LENGTH bl = val len ==> - ~(val len < 0x50) ==> - val len < 0x60 ==> - (forall i. i < val len - ==> read (memory :> bytes8 (word_add ptr (word i))) s = EL i bl) - ==> read (memory :> bytes128 ptr) s = bytes_to_int128 (SUB_LIST (0, 16) bl) /\ - read (memory :> bytes128 (word_add ptr (word 16))) s = - bytes_to_int128 (SUB_LIST (16, 16) bl) /\ - read (memory :> bytes128 (word_add ptr (word 32))) s = - bytes_to_int128 (SUB_LIST (32, 16) bl) /\ - read (memory :> bytes128 (word_add ptr (word 48))) s = - bytes_to_int128 (SUB_LIST (48, 16) bl) /\ - read (memory :> bytes128 (word_add ptr (word 64))) s = - bytes_to_int128 (SUB_LIST (64, 16) bl)`, - REPEAT GEN_TAC THEN REPEAT_N 4 STRIP_TAC THEN - MP_TAC (SPECL [`0:num`; `bl:byte list`; `ptr:int64`; - `len:int64`; `s:armstate`] BYTE_LIST_AT_5BLOCKS) THEN - REWRITE_TAC[byte_list_at] THEN - ANTS_TAC THENL[ ASM_SIMP_TAC[]; ALL_TAC] THEN - ANTS_TAC THENL[ ASM_SIMP_TAC[]; ALL_TAC] THEN - ANTS_TAC THENL[ ASM_ARITH_TAC; ALL_TAC] THEN - CONV_TAC NUM_REDUCE_CONV THEN - ASM_SIMP_TAC[WORD_ADD_0] -);; - -let READ_BYTES_EQ_READ_BYTE128_1BLOCK = prove( - `!(ptr:int64) (ct:byte list) (iv:int128) (key1:int128 list) (key2:int128 list) s. - (read (memory :> bytes128 pt_ptr) s = - aes256_xts_decrypt_round (bytes_to_int128 (SUB_LIST (0x0,0x10) ct)) - (calculate_tweak 0x0 iv key2) - key1) ==> - read (memory :> bytes (pt_ptr,0x10)) s = - num_of_bytelist (SUB_LIST (0x0,0x10) (aes256_xts_decrypt ct 0x10 iv key1 key2))`, - REPEAT STRIP_TAC THEN - REWRITE_TAC[READ_MEMORY_BYTES_BYTES128] THEN - ASM_REWRITE_TAC[] THEN - REWRITE_TAC[aes256_xts_decrypt] THEN - CONV_TAC NUM_REDUCE_CONV THEN - REWRITE_TAC[LET_DEF; LET_END_DEF] THEN - CONV_TAC NUM_REDUCE_CONV THEN - REWRITE_TAC[aes256_xts_decrypt_tail] THEN - REWRITE_TAC[LET_DEF; LET_END_DEF] THEN - CONV_TAC NUM_REDUCE_CONV THEN - REWRITE_TAC[SUB_LIST_OF_INT128_TO_BYTES] THEN - REWRITE_TAC[NUM_OF_BYTELIST_OF_INT128_TO_BYTES] -);; - -let READ_BYTES_EQ_READ_BYTE128_2BLOCKS = prove( - `!(ptr:int64) (ct:byte list) (iv:int128) (key1:int128 list) (key2:int128 list) s. - (read (memory :> bytes128 pt_ptr) s = - aes256_xts_decrypt_round (bytes_to_int128 (SUB_LIST (0x0,0x10) ct)) - (calculate_tweak 0x0 iv key2) - key1) ==> - (read (memory :> bytes128 (word_add pt_ptr (word 0x10))) s = - aes256_xts_decrypt_round (bytes_to_int128 (SUB_LIST (0x10,0x10) ct)) - (calculate_tweak 0x1 iv key2) - key1) ==> - read (memory :> bytes (pt_ptr,0x20)) s = - num_of_bytelist (SUB_LIST (0x0,0x20) (aes256_xts_decrypt ct 0x20 iv key1 key2))`, - REPEAT STRIP_TAC THEN - IMP_REWRITE_TAC[ARITH_RULE `0x20 = 0x10 + 0x10`; READ_BYTES_AND_BYTE128_SPLIT] THEN - EXISTS_TAC `aes256_xts_decrypt ct 0x20 iv key1 key2` THEN - REPEAT CONJ_TAC THENL - [ - CONV_TAC NUM_REDUCE_CONV; - - MP_TAC (SPECL [`2:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] - LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN - ARITH_TAC; - - REWRITE_TAC[aes256_xts_decrypt] THEN - CONV_TAC NUM_REDUCE_CONV THEN - REWRITE_TAC[LET_DEF; LET_END_DEF] THEN - CONV_TAC NUM_REDUCE_CONV THEN - MP_TAC (SPECL [`ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] - LENGTH_OF_AES256_XTS_DECRYPT_REC_TRIVIAL) THEN - IMP_REWRITE_TAC[SUB_LIST_APPEND_RIGHT_LEMMA] THEN DISCH_TAC THEN - REWRITE_TAC[aes256_xts_decrypt_tail] THEN - REWRITE_TAC[LET_DEF; LET_END_DEF] THEN - REWRITE_TAC[SUB_LIST_OF_INT128_TO_BYTES] THEN - REWRITE_TAC[NUM_OF_BYTELIST_OF_INT128_TO_BYTES] THEN - REWRITE_TAC[BYTES_TO_INT128_OF_INT128_TO_BYTES] THEN - CONV_TAC NUM_REDUCE_CONV; - - MP_TAC (SPECL [`1:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] - SUB_LIST_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN - CONV_TAC NUM_REDUCE_CONV THEN - SIMP_TAC[] THEN DISCH_TAC THEN - IMP_REWRITE_TAC[READ_BYTES_EQ_READ_BYTE128_1BLOCK] THEN - MP_TAC (SPECL [`1:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] - LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN - CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC THEN - IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] - ] -);; - -let READ_BYTES_EQ_READ_BYTE128_3BLOCKS = prove( - `!(ptr:int64) (ct:byte list) (iv:int128) (key1:int128 list) (key2:int128 list) s. - (read (memory :> bytes128 pt_ptr) s = - aes256_xts_decrypt_round (bytes_to_int128 (SUB_LIST (0x0,0x10) ct)) - (calculate_tweak 0x0 iv key2) - key1) ==> - (read (memory :> bytes128 (word_add pt_ptr (word 0x10))) s = - aes256_xts_decrypt_round (bytes_to_int128 (SUB_LIST (0x10,0x10) ct)) - (calculate_tweak 0x1 iv key2) - key1) ==> - (read (memory :> bytes128 (word_add pt_ptr (word 0x20))) s = - aes256_xts_decrypt_round (bytes_to_int128 (SUB_LIST (0x20,0x10) ct)) - (calculate_tweak 0x2 iv key2) - key1) ==> - read (memory :> bytes (pt_ptr,0x30)) s = - num_of_bytelist (SUB_LIST (0x0,0x30) (aes256_xts_decrypt ct 0x30 iv key1 key2))`, - REPEAT STRIP_TAC THEN - IMP_REWRITE_TAC[ARITH_RULE `0x30 = 0x20 + 0x10`; READ_BYTES_AND_BYTE128_SPLIT] THEN - EXISTS_TAC `aes256_xts_decrypt ct 0x30 iv key1 key2` THEN - REPEAT CONJ_TAC THENL - [ - CONV_TAC NUM_REDUCE_CONV; + ALL_TAC + ] THEN - MP_TAC (SPECL [`3:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] - LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN - ARITH_TAC; + SUBGOAL_THEN `curr_blocks >= 1` ASSUME_TAC THENL + [ UNDISCH_TAC `~(curr_blocks + 0x1 < 0x2)` THEN ARITH_TAC; ALL_TAC] THEN - REWRITE_TAC[aes256_xts_decrypt] THEN - CONV_TAC NUM_REDUCE_CONV THEN - REWRITE_TAC[LET_DEF; LET_END_DEF] THEN - CONV_TAC NUM_REDUCE_CONV THEN - MP_TAC (SPECL [`0:num`; `1:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] - LENGTH_OF_AES256_XTS_DECRYPT_REC) THEN - CONV_TAC NUM_REDUCE_CONV THEN - IMP_REWRITE_TAC[SUB_LIST_APPEND_RIGHT_LEMMA] THEN DISCH_TAC THEN - REWRITE_TAC[aes256_xts_decrypt_tail] THEN - REWRITE_TAC[LET_DEF; LET_END_DEF] THEN - REWRITE_TAC[SUB_LIST_OF_INT128_TO_BYTES] THEN - REWRITE_TAC[NUM_OF_BYTELIST_OF_INT128_TO_BYTES] THEN - REWRITE_TAC[BYTES_TO_INT128_OF_INT128_TO_BYTES] THEN - CONV_TAC NUM_REDUCE_CONV; - ALL_TAC] THEN + IMP_REWRITE_TAC[ADD_SUB; ARITH_RULE `((curr_blocks + 0x1) - 0x2) = curr_blocks - 1`] THEN - MP_TAC (SPECL [`2:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] - SUB_LIST_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN - CONV_TAC NUM_REDUCE_CONV THEN - SIMP_TAC[] THEN DISCH_TAC THEN - IMP_REWRITE_TAC[READ_BYTES_EQ_READ_BYTE128_2BLOCKS] THEN - MP_TAC (SPECL [`2:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] - LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN - CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC THEN - IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] -);; + MP_TAC (SPECL [`0:num`; `(curr_blocks - 1):num`; `ct:byte list`; `iv:int128`; + `key1:int128 list`; `key2:int128 list`] LENGTH_OF_AES256_XTS_DECRYPT_REC) THEN + ASM_SIMP_TAC[ARITH_RULE `curr_blocks >= 1 ==> ~(curr_blocks - 1 < 0)`] THEN + IMP_REWRITE_TAC[SUB_0; ARITH_RULE `curr_blocks >= 1 ==> curr_blocks - 1 + 1 = curr_blocks`] THEN + ONCE_REWRITE_TAC[ARITH_RULE `curr_blocks * 16 = 16 * curr_blocks`] THEN + DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_APPEND_RIGHT_LEMMA] THEN -let READ_BYTES_EQ_READ_BYTE128_4BLOCKS = prove( - `!(ptr:int64) (ct:byte list) (iv:int128) (key1:int128 list) (key2:int128 list) s. - (read (memory :> bytes128 pt_ptr) s = - aes256_xts_decrypt_round (bytes_to_int128 (SUB_LIST (0x0,0x10) ct)) - (calculate_tweak 0x0 iv key2) - key1) ==> - (read (memory :> bytes128 (word_add pt_ptr (word 0x10))) s = - aes256_xts_decrypt_round (bytes_to_int128 (SUB_LIST (0x10,0x10) ct)) - (calculate_tweak 0x1 iv key2) - key1) ==> - (read (memory :> bytes128 (word_add pt_ptr (word 0x20))) s = - aes256_xts_decrypt_round (bytes_to_int128 (SUB_LIST (0x20,0x10) ct)) - (calculate_tweak 0x2 iv key2) - key1) ==> - (read (memory :> bytes128 (word_add pt_ptr (word 0x30))) s = - aes256_xts_decrypt_round (bytes_to_int128 (SUB_LIST (0x30,0x10) ct)) - (calculate_tweak 0x3 iv key2) - key1) ==> - read (memory :> bytes (pt_ptr,0x40)) s = - num_of_bytelist (SUB_LIST (0x0,0x40) (aes256_xts_decrypt ct 0x40 iv key1 key2))`, - REPEAT STRIP_TAC THEN - IMP_REWRITE_TAC[ARITH_RULE `0x40 = 0x30 + 0x10`; READ_BYTES_AND_BYTE128_SPLIT] THEN - EXISTS_TAC `aes256_xts_decrypt ct 0x40 iv key1 key2` THEN - REPEAT CONJ_TAC THENL - [ - CONV_TAC NUM_REDUCE_CONV; + REWRITE_TAC[aes256_xts_decrypt_tail] THEN + ASM_SIMP_TAC[LET_DEF; LET_END_DEF] THEN - MP_TAC (SPECL [`4:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] - LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN - ARITH_TAC; + MP_TAC (SPECL [`(SUB_LIST (curr_blocks * 0x10,0x10) ct):byte list`; + `(SUB_LIST ((curr_blocks + 0x1) * 0x10,val (tail_len:int64)) ct):byte list`; + `val (tail_len:int64)`; `iv:int128`; `curr_blocks:num`; `key1:int128 list`; + `key2:int128 list`] LENGTH_OF_FST_OF_CIPHER_STEALING) THEN + DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_APPEND_LEFT; ARITH_RULE `16 <= 16`] THEN - REWRITE_TAC[aes256_xts_decrypt] THEN - CONV_TAC NUM_REDUCE_CONV THEN - REWRITE_TAC[LET_DEF; LET_END_DEF] THEN - CONV_TAC NUM_REDUCE_CONV THEN - MP_TAC (SPECL [`0:num`; `2:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] - LENGTH_OF_AES256_XTS_DECRYPT_REC) THEN - CONV_TAC NUM_REDUCE_CONV THEN - IMP_REWRITE_TAC[SUB_LIST_APPEND_RIGHT_LEMMA] THEN DISCH_TAC THEN - REWRITE_TAC[aes256_xts_decrypt_tail] THEN - REWRITE_TAC[LET_DEF; LET_END_DEF] THEN - REWRITE_TAC[SUB_LIST_OF_INT128_TO_BYTES] THEN - REWRITE_TAC[BYTES_TO_INT128_OF_INT128_TO_BYTES] THEN - CONV_TAC NUM_REDUCE_CONV; - ALL_TAC] THEN + REWRITE_TAC[cipher_stealing; LET_DEF; LET_END_DEF] THEN + REWRITE_TAC[SUB_LIST_OF_INT128_TO_BYTES; + NUM_OF_BYTELIST_OF_INT128_TO_BYTES; CALCULATE_TWEAK_EXPAND; + ARITH_RULE `curr_blocks * 16 = 16 * curr_blocks`; + ARITH_RULE `0x10 * (curr_blocks + 0x1) = 16 * curr_blocks + 16`] THEN + EXPAND_TAC "combinedPP" THEN + EXPAND_TAC "PP" THEN + REFL_TAC; - MP_TAC (SPECL [`3:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] - SUB_LIST_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN - CONV_TAC NUM_REDUCE_CONV THEN - SIMP_TAC[] THEN DISCH_TAC THEN - IMP_REWRITE_TAC[READ_BYTES_EQ_READ_BYTE128_3BLOCKS] THEN - MP_TAC (SPECL [`3:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] - LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN - CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC THEN - IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] -);; + (* 3. Proving tail is correct *) + UNDISCH_TAC + `forall i. i < val (tail_len:int64) + ==> read (memory :> bytes8 + (word_add (word_add pt_ptr (word (0x10 * curr_blocks + 0x10))) + (word i))) s33 = + EL i (SUB_LIST (0x0,val tail_len) (int128_to_bytes PP))` THEN + MP_TAC (SPECL [`val (tail_len:int64):num`; `(word_add pt_ptr (word (0x10 * curr_blocks + 0x10))):int64`; + `(SUB_LIST (0x0,val (tail_len:int64)) (int128_to_bytes PP)):byte list`; + `s33:armstate`] BYTE_LIST_TO_NUM_THM) THEN + ANTS_TAC THENL[ + REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN + CONV_TAC NUM_REDUCE_CONV THEN + UNDISCH_TAC `val (tail_len:int64) < 0x10` THEN + ARITH_TAC; ALL_TAC] THEN + DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN + MP_TAC (SPECL [`val (tail_len:int64):num`; `(word_add pt_ptr (word (0x10 * curr_blocks + 0x10))):int64`; + `(SUB_LIST (0x10 * curr_blocks + 0x10,val (tail_len:int64)) + (aes256_xts_decrypt ct (0x10 * curr_blocks + 0x10 + val tail_len) iv key1 key2)):byte list`; + `s33:armstate`] BYTE_LIST_TO_NUM_THM) THEN + ANTS_TAC THENL[ + REWRITE_TAC[LENGTH_SUB_LIST] THEN + IMP_REWRITE_TAC[LENGTH_OF_AES256_XTS_DECRYPT] THEN + ARITH_TAC; ALL_TAC] THEN + DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN + DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN + AP_TERM_TAC THEN + REWRITE_TAC[SUB_LIST_IDEMPOTENT] THEN + REWRITE_TAC[SUB_LIST_MIN_RIGHT; MIN; LE_REFL] THEN -let READ_BYTES_EQ_READ_BYTE128_5BLOCKS = prove( - `!(ptr:int64) (ct:byte list) (iv:int128) (key1:int128 list) (key2:int128 list) s. - (read (memory :> bytes128 pt_ptr) s = - aes256_xts_decrypt_round (bytes_to_int128 (SUB_LIST (0x0,0x10) ct)) - (calculate_tweak 0x0 iv key2) - key1) ==> - (read (memory :> bytes128 (word_add pt_ptr (word 0x10))) s = - aes256_xts_decrypt_round (bytes_to_int128 (SUB_LIST (0x10,0x10) ct)) - (calculate_tweak 0x1 iv key2) - key1) ==> - (read (memory :> bytes128 (word_add pt_ptr (word 0x20))) s = - aes256_xts_decrypt_round (bytes_to_int128 (SUB_LIST (0x20,0x10) ct)) - (calculate_tweak 0x2 iv key2) - key1) ==> - (read (memory :> bytes128 (word_add pt_ptr (word 0x30))) s = - aes256_xts_decrypt_round (bytes_to_int128 (SUB_LIST (0x30,0x10) ct)) - (calculate_tweak 0x3 iv key2) - key1) ==> - (read (memory :> bytes128 (word_add pt_ptr (word 0x40))) s = - aes256_xts_decrypt_round (bytes_to_int128 (SUB_LIST (0x40,0x10) ct)) - (calculate_tweak 0x4 iv key2) - key1) ==> - read (memory :> bytes (pt_ptr,0x50)) s = - num_of_bytelist (SUB_LIST (0x0,0x50) (aes256_xts_decrypt ct 0x50 iv key1 key2))`, - REPEAT STRIP_TAC THEN - IMP_REWRITE_TAC[ARITH_RULE `0x50 = 0x40 + 0x10`; READ_BYTES_AND_BYTE128_SPLIT] THEN - EXISTS_TAC `aes256_xts_decrypt ct 0x50 iv key1 key2` THEN - REPEAT CONJ_TAC THENL - [ - CONV_TAC NUM_REDUCE_CONV; + REWRITE_TAC[aes256_xts_decrypt; + ARITH_RULE `~(0x10 * curr_blocks + 0x10 + val (tail_len:int64) < 0x10)`] THEN + REWRITE_TAC[ARITH_RULE `0x10 * curr_blocks + 0x10 + val tail_len = + 0x10 * (curr_blocks + 1) + val tail_len`] THEN + REWRITE_TAC[MOD_MULT_ADD] THEN + ASM_SIMP_TAC[MOD_LT] THEN + REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + REWRITE_TAC[ARITH_RULE + `((0x10 * (curr_blocks + 0x1) + val tail_len) - val tail_len) DIV 0x10 = + (0x10 * (curr_blocks + 0x1)) DIV 0x10`] THEN + IMP_REWRITE_TAC[DIV_MULT; ARITH_RULE `~(16 = 0)`] THEN + COND_CASES_TAC THENL + [ + SUBGOAL_THEN `curr_blocks = 0` SUBST_ALL_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN + REWRITE_TAC[aes256_xts_decrypt_tail] THEN + ASM_SIMP_TAC[LET_DEF; LET_END_DEF] THEN + CONV_TAC NUM_REDUCE_CONV THEN - MP_TAC (SPECL [`5:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] - LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN - ARITH_TAC; + MP_TAC (SPECL [`(SUB_LIST (0,0x10) ct):byte list`; + `(SUB_LIST (0x10,val (tail_len:int64)) ct):byte list`; + `val (tail_len:int64)`; `iv:int128`; `0:num`; `key1:int128 list`; + `key2:int128 list`] LENGTH_OF_FST_OF_CIPHER_STEALING) THEN + DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_APPEND_RIGHT_LEMMA; ARITH_RULE `16 <= 16`] THEN - REWRITE_TAC[aes256_xts_decrypt] THEN - CONV_TAC NUM_REDUCE_CONV THEN - REWRITE_TAC[LET_DEF; LET_END_DEF] THEN - CONV_TAC NUM_REDUCE_CONV THEN - MP_TAC (SPECL [`0:num`; `3:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] - LENGTH_OF_AES256_XTS_DECRYPT_REC) THEN - CONV_TAC NUM_REDUCE_CONV THEN - IMP_REWRITE_TAC[SUB_LIST_APPEND_RIGHT_LEMMA] THEN DISCH_TAC THEN - REWRITE_TAC[aes256_xts_decrypt_tail] THEN - REWRITE_TAC[LET_DEF; LET_END_DEF] THEN - REWRITE_TAC[SUB_LIST_OF_INT128_TO_BYTES] THEN - REWRITE_TAC[BYTES_TO_INT128_OF_INT128_TO_BYTES] THEN - CONV_TAC NUM_REDUCE_CONV; - ALL_TAC] THEN + REWRITE_TAC[cipher_stealing; LET_DEF; LET_END_DEF; SUB_LIST_IDEMPOTENT] THEN + EXPAND_TAC "PP" THEN + REWRITE_TAC[CALCULATE_TWEAK_EXPAND] THEN + CONV_TAC NUM_REDUCE_CONV; + ALL_TAC + ] THEN - MP_TAC (SPECL [`4:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] - SUB_LIST_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN - CONV_TAC NUM_REDUCE_CONV THEN - SIMP_TAC[] THEN DISCH_TAC THEN - IMP_REWRITE_TAC[READ_BYTES_EQ_READ_BYTE128_4BLOCKS] THEN - MP_TAC (SPECL [`4:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] - LENGTH_OF_AES256_XTS_DECRYPT_FULL_BLOCKS) THEN - CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC THEN - IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] -);; + SUBGOAL_THEN `curr_blocks >= 1` ASSUME_TAC THENL + [ UNDISCH_TAC `~(curr_blocks + 0x1 < 0x2)` THEN ARITH_TAC; ALL_TAC] THEN + + IMP_REWRITE_TAC[ADD_SUB; ARITH_RULE `((curr_blocks + 0x1) - 0x2) = curr_blocks - 1`] THEN + + MP_TAC (ISPECL [`(aes256_xts_decrypt_rec 0x0 (curr_blocks - 0x1) ct iv key1 key2):byte list`; + `(aes256_xts_decrypt_tail curr_blocks (val (tail_len:int64)) ct iv key1 key2):byte list`; + `0x10 * curr_blocks + 0x10:num`; `val (tail_len:int64)`; `0x10 * curr_blocks:num` + ] SUB_LIST_APPEND_RIGHT_GENERAL) THEN + ANTS_TAC THENL + [ REWRITE_TAC[LENGTH_OF_AES256_XTS_DECRYPT_REC] THEN + UNDISCH_TAC `curr_blocks >= 1` THEN + ARITH_TAC; ALL_TAC] THEN + ANTS_TAC THENL [ ARITH_TAC; ALL_TAC] THEN + DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN + + REWRITE_TAC[ARITH_RULE `(0x10 * curr_blocks + 0x10) - 0x10 * curr_blocks = 0x10`] THEN + REWRITE_TAC[aes256_xts_decrypt_tail] THEN + ASM_SIMP_TAC[LET_DEF; LET_END_DEF] THEN + MP_TAC (SPECL [`(SUB_LIST (curr_blocks * 0x10,0x10) ct):byte list`; + `(SUB_LIST ((curr_blocks + 0x1) * 0x10,val (tail_len:int64)) ct):byte list`; + `val (tail_len:int64)`; `iv:int128`; `curr_blocks:num`; `key1:int128 list`; + `key2:int128 list`] LENGTH_OF_FST_OF_CIPHER_STEALING) THEN + DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_APPEND_RIGHT_LEMMA; ARITH_RULE `16 <= 16`] THEN + REWRITE_TAC[cipher_stealing; LET_DEF; LET_END_DEF; SUB_LIST_IDEMPOTENT] THEN + EXPAND_TAC "PP" THEN + REWRITE_TAC[ARITH_RULE `curr_blocks * 0x10 = 0x10 * curr_blocks`; + CALCULATE_TWEAK_EXPAND] + ] + ] +);; (* Proof: Less than 2 blocks *) let AES_XTS_DECRYPT_LT_2BLOCK_CORRECT = time prove( @@ -6684,7 +4454,7 @@ let AES_XTS_DECRYPT_CORRECT = time prove( ENSURES_INIT_TAC "s0" THEN (* List values for ct_ptr + [0 .. 0x40] *) - MP_TAC (SPECL [`ct_ptr:int64`; `i:num`; `len:int64`; `ct:byte list`; `s0:armstate`] READ_CT_LEMMA) THEN + MP_TAC (SPECL [`ct_ptr:int64`; `i:num`; `len:int64`; `ct:byte list`; `s0:armstate`] READ_BL_LEMMA) THEN ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (1--151) THEN (* Prove Q0, Q1, Q24, Q25, Q26 stores correct plaintext *) @@ -7177,7 +4947,7 @@ let AES_XTS_DECRYPT_CORRECT = time prove( [ UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 + 0x40 = val (num_blocks_adjusted:int64)` THEN UNDISCH_TAC `val (num_blocks_adjusted:int64) <= val (len:int64)` THEN ARITH_TAC; ALL_TAC] THEN - MP_TAC (SPECL [`ct_ptr:int64`; `num_5blocks_adjusted:int64`; `len:int64`; `ct:byte list`; `s3:armstate`] READ_CT_TAIL4_LEMMA) THEN + MP_TAC (SPECL [`ct_ptr:int64`; `num_5blocks_adjusted:int64`; `len:int64`; `ct:byte list`; `s3:armstate`] READ_TAIL4_LEMMA) THEN ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN (* Assumptions that help with reasoning about nonoverlapping @@ -7531,7 +5301,7 @@ let AES_XTS_DECRYPT_CORRECT = time prove( [ UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 + 0x30 = val (num_blocks_adjusted:int64)` THEN UNDISCH_TAC `val (num_blocks_adjusted:int64) <= val (len:int64)` THEN ARITH_TAC; ALL_TAC] THEN - MP_TAC (SPECL [`ct_ptr:int64`; `num_5blocks_adjusted:int64`; `len:int64`; `ct:byte list`; `s5:armstate`] READ_CT_TAIL3_LEMMA) THEN + MP_TAC (SPECL [`ct_ptr:int64`; `num_5blocks_adjusted:int64`; `len:int64`; `ct:byte list`; `s5:armstate`] READ_TAIL3_LEMMA) THEN ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN (* Assumptions that help with reasoning about nonoverlapping @@ -7832,7 +5602,7 @@ let AES_XTS_DECRYPT_CORRECT = time prove( [ UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 + 0x20 = val (num_blocks_adjusted:int64)` THEN UNDISCH_TAC `val (num_blocks_adjusted:int64) <= val (len:int64)` THEN ARITH_TAC; ALL_TAC] THEN - MP_TAC (SPECL [`ct_ptr:int64`; `num_5blocks_adjusted:int64`; `len:int64`; `ct:byte list`; `s7:armstate`] READ_CT_TAIL2_LEMMA) THEN + MP_TAC (SPECL [`ct_ptr:int64`; `num_5blocks_adjusted:int64`; `len:int64`; `ct:byte list`; `s7:armstate`] READ_TAIL2_LEMMA) THEN ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN (* Assumptions that help with reasoning about nonoverlapping @@ -8076,7 +5846,7 @@ let AES_XTS_DECRYPT_CORRECT = time prove( [ UNDISCH_TAC `val (num_5blocks_adjusted:int64) * 0x50 + 0x10 = val (num_blocks_adjusted:int64)` THEN UNDISCH_TAC `val (num_blocks_adjusted:int64) <= val (len:int64)` THEN ARITH_TAC; ALL_TAC] THEN - MP_TAC (SPECL [`ct_ptr:int64`; `num_5blocks_adjusted:int64`; `len:int64`; `ct:byte list`; `s9:armstate`] READ_CT_TAIL1_LEMMA) THEN + MP_TAC (SPECL [`ct_ptr:int64`; `num_5blocks_adjusted:int64`; `len:int64`; `ct:byte list`; `s9:armstate`] READ_TAIL1_LEMMA) THEN ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN (* Assumptions that help with reasoning about nonoverlapping diff --git a/arm/proofs/aes_xts_encrypt.ml b/arm/proofs/aes_xts_encrypt.ml index a1cdfcc0f..e2fa2c27c 100644 --- a/arm/proofs/aes_xts_encrypt.ml +++ b/arm/proofs/aes_xts_encrypt.ml @@ -2,15 +2,9 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT-0 *) - use_file_raise_failure := true;; -needs "arm/proofs/base.ml";; -needs "arm/proofs/aes_encrypt_spec.ml";; -needs "arm/proofs/aes_xts_encrypt_spec.ml";; - -arm_print_log := true;; -components_print_log := true;; +needs "arm/proofs/utils/aes_xts_common.ml";; (* print_literal_from_elf "arm/aes-xts/aes_xts_encrypt_armv8.o";; *) let aes256_xts_encrypt_mc = define_assert_from_elf "aes256_xts_encrypt_mc" "arm/aes-xts/aes_xts_encrypt_armv8.o" @@ -726,114 +720,7 @@ let aes256_xts_encrypt_mc = define_assert_from_elf "aes256_xts_encrypt_mc" "arm/ let AES256_XTS_ENCRYPT_EXEC = ARM_MK_EXEC_RULE aes256_xts_encrypt_mc;; -(** Definitions **) - -(* same as in aes_xts_decrypt.ml *) -let set_key_schedule = new_definition - `set_key_schedule (s:armstate) (key_ptr:int64) (k0:int128) - (k1:int128) (k2:int128) (k3:int128) (k4:int128) (k5:int128) - (k6:int128) (k7:int128) (k8:int128) (k9:int128) (ka:int128) - (kb:int128) (kc:int128) (kd:int128) (ke:int128) : bool = - (read(memory :> bytes128 key_ptr) s = k0 /\ - read(memory :> bytes128 (word_add key_ptr (word 16))) s = k1 /\ - read(memory :> bytes128 (word_add key_ptr (word 32))) s = k2 /\ - read(memory :> bytes128 (word_add key_ptr (word 48))) s = k3 /\ - read(memory :> bytes128 (word_add key_ptr (word 64))) s = k4 /\ - read(memory :> bytes128 (word_add key_ptr (word 80))) s = k5 /\ - read(memory :> bytes128 (word_add key_ptr (word 96))) s = k6 /\ - read(memory :> bytes128 (word_add key_ptr (word 112))) s = k7 /\ - read(memory :> bytes128 (word_add key_ptr (word 128))) s = k8 /\ - read(memory :> bytes128 (word_add key_ptr (word 144))) s = k9 /\ - read(memory :> bytes128 (word_add key_ptr (word 160))) s = ka /\ - read(memory :> bytes128 (word_add key_ptr (word 176))) s = kb /\ - read(memory :> bytes128 (word_add key_ptr (word 192))) s = kc /\ - read(memory :> bytes128 (word_add key_ptr (word 208))) s = kd /\ - read(memory :> bytes128 (word_add key_ptr (word 224))) s = ke /\ - read(memory :> bytes32 (word_add key_ptr (word 240))) s = word 14)`;; - -let AESENC_TAC = - REWRITE_TAC [aes256_encrypt] THEN - REWRITE_TAC EL_15_128_CLAUSES THEN - REWRITE_TAC [aes256_encrypt_round; aese; aesmc] THEN - CONV_TAC (TOP_DEPTH_CONV let_CONV) THEN - BITBLAST_TAC;; - -let AESXTS_ENC_ONE_BLOCK_TAC = - REWRITE_TAC [aes256_xts_encrypt_1block] THEN - REWRITE_TAC [xts_init_tweak; aes256_xts_encrypt_round] THEN - CONV_TAC (TOP_DEPTH_CONV let_CONV) THEN - GEN_REWRITE_TAC LAND_CONV [WORD_XOR_SYM] THEN - REPEAT (AP_THM_TAC THEN AP_TERM_TAC) THEN - BITBLAST_TAC;; - -let TWEAK_UPDATE_CONV = - let ADD_SUC_1 = ARITH_RULE `!n. n + 1 = SUC(n)` in - let ADD_SUC_2 = ARITH_RULE `!n. n + 2 = SUC(n + 1)` in - let ADD_SUC_3 = ARITH_RULE `!n. n + 3 = SUC(n + 2)` in - let ADD_SUC_4 = ARITH_RULE `!n. n + 4 = SUC(n + 3)` in - let ADD_SUC_5 = ARITH_RULE `!n. n + 5 = SUC(n + 4)` in - let ADD_SUC_6 = ARITH_RULE `!n. n + 6 = SUC(n + 5)` in - let ADD_SUC_7 = ARITH_RULE `!n. n + 7 = SUC(n + 6)` in - let ADD_SUC_8 = ARITH_RULE `!n. n + 8 = SUC(n + 7)` in - let ADD_SUC_9 = ARITH_RULE `!n. n + 9 = SUC(n + 8)` in - NUM_REDUCE_CONV THENC - RATOR_CONV (LAND_CONV (num_CONV ORELSEC - FIRST_CONV - [ CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_1]); - CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_2]); - CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_3]); - CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_4]); - CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_5]); - CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_6]); - CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_7]); - CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_8]); - CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_9]);])) THENC - REWRITE_CONV [CONJUNCT2 calculate_tweak] THENC - GF_128_MULT_BY_PRIMITIVE_CONV;; - -(* differs from the Decrypt definition in using key2_lst instead of key2 - TODO: it seems that value of indm1 doesn't matter to the tactic, can it be removed? *) -let TWEAK_TAC reg ind indm1 = - let lower_term = subst [ind,`ind:num`] `(word_zx:int128->int64) (calculate_tweak ind iv key2_lst)` in - let upper_term = subst [ind,`ind:num`] `(word_subword:int128->num#num->int64) (calculate_tweak ind iv key2_lst) (64,64)` in - let full_term = subst [ind,`ind:num`] `calculate_tweak ind iv key2_lst` in - let full_lemma = subst [reg,`reg:(armstate,int128)component`] `read (reg:(armstate,int128)component) (s:armstate) = a ==> !a'. a = a' ==> read reg s = a'` in - let abbrev_term = subst [indm1,`indm1:num`] `tweak_pre:int128 = (calculate_tweak indm1 iv key2_lst)` in - FIRST_X_ASSUM(MP_TAC o SPEC lower_term - o MATCH_MP (MESON[] `read X9 s = a ==> !a'. a = a' ==> read X9 s = a'`)) THEN - ANTS_TAC THENL [CONV_TAC (RAND_CONV (RAND_CONV TWEAK_UPDATE_CONV)) THEN - ABBREV_TAC abbrev_term THEN - BITBLAST_TAC; DISCH_TAC] THEN - FIRST_X_ASSUM(MP_TAC o SPEC upper_term - o MATCH_MP (MESON[] `read X10 s = a ==> !a'. a = a' ==> read X10 s = a'`)) THEN - ANTS_TAC THENL [CONV_TAC (RAND_CONV (RATOR_CONV (RAND_CONV TWEAK_UPDATE_CONV))) THEN - ABBREV_TAC abbrev_term THEN - BITBLAST_TAC; DISCH_TAC] THEN - FIRST_X_ASSUM(MP_TAC o SPEC full_term - o MATCH_MP (MESON[] full_lemma)) THEN - ANTS_TAC THENL [CONV_TAC (RAND_CONV TWEAK_UPDATE_CONV) THEN - ABBREV_TAC abbrev_term THEN - BITBLAST_TAC; DISCH_TAC];; - -let XTSENC_TAC reg ind ind_tweak = - let tm = subst [ind, `ind:num`; ind_tweak, `ind_tweak:num`] - `aes256_xts_encrypt_round (bytes_to_int128 (SUB_LIST (ind,0x10) (pt_in:byte list))) - (calculate_tweak (ind_tweak) iv key2_lst) key1_lst` in - let lemma = subst [reg, `reg:(armstate,int128)component`] - `read (reg:(armstate,int128)component) (s:armstate) = a ==> !a'. a = a' ==> read reg s = a'` in - let _ = print_term tm in - let _ = print_term lemma in - FIRST_X_ASSUM(MP_TAC o SPEC tm o MATCH_MP (MESON[] lemma)) THEN - ANTS_TAC THENL - [ EXPAND_TAC "key1_lst" THEN - CONV_TAC (RAND_CONV ( - REWRITE_CONV [aes256_xts_encrypt_round] THENC - DEPTH_CONV let_CONV)) THEN - GEN_REWRITE_TAC LAND_CONV [WORD_XOR_SYM] THEN - REPEAT (AP_THM_TAC THEN AP_TERM_TAC) THEN - GEN_REWRITE_TAC ONCE_DEPTH_CONV [WORD_XOR_SYM] THEN - AESENC_TAC; DISCH_TAC ];; - +(* (* void aes_hw_xts_encrypt(const uint8_t *in, uint8_t *out, size_t length, const AES_KEY *key1, const AES_KEY *key2, @@ -930,2444 +817,666 @@ let AES256_ENCRYPT_ONE_BLOCK_CORRECT = prove( ASM_REWRITE_TAC[] THEN ARITH_TAC );; +*) -(*******************************************) -(* Full proof *) - -(* The following definitions that precede the proof are the same as - the decrypt proof except where stated *) -let byte_list_at = define - `byte_list_at (m : byte list) (m_p : int64) (len:int64) s = - ! i. i < val len ==> read (memory :> bytes8(word_add m_p (word i))) s = EL i m`;; - -let word_split_lemma = prove( - `!len:int64. word_add (word_and len (word 0xf)) - (word_and len (word 0xfffffffffffffff0)) = len`, - BITBLAST_TAC);; - -let BYTE_LIST_AT_ADD_ASSUM_TAC new_pos bound = - let rule = subst [new_pos, `new_pos:num`; bound, `bound:num`] - `(pos:num) + bound <= LENGTH (bl:byte list) ==> new_pos < LENGTH bl` in - let p = subst [new_pos, `new_pos:num`] `new_pos:num` in - MP_TAC (ARITH_RULE rule) THEN - ASM_REWRITE_TAC[] THEN DISCH_THEN (LABEL_TAC "tmp") THEN - FIRST_ASSUM(fun th -> MP_TAC(SPEC p th)) THEN - USE_THEN "tmp" (fun th -> REWRITE_TAC[th]) THEN - POP_ASSUM (K ALL_TAC);; - -let BYTES128_TO_BYTES8_THM = prove( - `!pos bl_ptr s. - read (memory :> bytes128 (word_add bl_ptr (word pos))) s = - bytes_to_int128 - [read (memory :> bytes8 (word_add bl_ptr (word (pos + 0x0)))) s; - read (memory :> bytes8 (word_add bl_ptr (word (pos + 0x1)))) s; - read (memory :> bytes8 (word_add bl_ptr (word (pos + 0x2)))) s; - read (memory :> bytes8 (word_add bl_ptr (word (pos + 0x3)))) s; - read (memory :> bytes8 (word_add bl_ptr (word (pos + 0x4)))) s; - read (memory :> bytes8 (word_add bl_ptr (word (pos + 0x5)))) s; - read (memory :> bytes8 (word_add bl_ptr (word (pos + 0x6)))) s; - read (memory :> bytes8 (word_add bl_ptr (word (pos + 0x7)))) s; - read (memory :> bytes8 (word_add bl_ptr (word (pos + 0x8)))) s; - read (memory :> bytes8 (word_add bl_ptr (word (pos + 0x9)))) s; - read (memory :> bytes8 (word_add bl_ptr (word (pos + 0xa)))) s; - read (memory :> bytes8 (word_add bl_ptr (word (pos + 0xb)))) s; - read (memory :> bytes8 (word_add bl_ptr (word (pos + 0xc)))) s; - read (memory :> bytes8 (word_add bl_ptr (word (pos + 0xd)))) s; - read (memory :> bytes8 (word_add bl_ptr (word (pos + 0xe)))) s; - read (memory :> bytes8 (word_add bl_ptr (word (pos + 0xf)))) s]`, - REPEAT STRIP_TAC THEN - REWRITE_TAC[bytes_to_int128] THEN - REWRITE_TAC EL_16_8_CLAUSES THEN - GEN_REWRITE_TAC TOP_DEPTH_CONV [READ_MEMORY_BYTESIZED_SPLIT; WORD_ADD_ASSOC_CONSTS] THEN - CONV_TAC(DEPTH_CONV WORD_NUM_RED_CONV) THEN - ONCE_REWRITE_TAC [ARITH_RULE `pos + 0 = (pos:num)`] THEN - REFL_TAC -);; +(**********************************************************************) +(** Encrypt-specific lemmas **) -let SUB_LIST_SUCSPLIT = prove( - `!(l:A list) n p. SUB_LIST(p,SUC n) l = APPEND (SUB_LIST(p,1) l) (SUB_LIST(p+1,n) l)`, - REPEAT STRIP_TAC THEN - REWRITE_TAC [ARITH_RULE `SUC n = 1 + n`] THEN - REWRITE_TAC [SUB_LIST_SPLIT] +let LENGTH_OF_AES256_XTS_ENCRYPT_REC = prove( + `!(i:num) (m:num) (P:byte list) (iv:int128) (key1:int128 list) (key2:int128 list). + LENGTH(aes256_xts_encrypt_rec i m P iv key1 key2) = (if m < i then 0 else (m - i + 1) * 0x10)`, + REPEAT GEN_TAC THEN + (* Wellfounded induction with measure (m + 1) - i + Note that the parentheses are essential because of the precedence of + and - *) + WF_INDUCT_TAC `(m + 1) - i` THEN + ONCE_REWRITE_TAC[aes256_xts_encrypt_rec] THEN + COND_CASES_TAC THENL + [ SIMP_TAC[LENGTH_EQ_NIL]; + SIMP_TAC[] THEN + REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + REWRITE_TAC[LENGTH_APPEND] THEN + SUBGOAL_THEN `~(m < i) ==> (m + 1) - (i + 1) < (m + 1) - i` ASSUME_TAC THENL + [ ASM_ARITH_TAC ; ALL_TAC ] THEN + ASM_SIMP_TAC[] THEN + REWRITE_TAC[LENGTH_OF_INT128_TO_BYTES] THEN + COND_CASES_TAC THENL + [ASM_ARITH_TAC; ASM_ARITH_TAC]] );; -let SUB_LIST_16_TAC n exp = - let subgoal = subst [exp, `exp:num`] `exp < LENGTH (l:A list)` in - CONV_TAC(RAND_CONV (REWRITE_CONV[num_CONV n; SUB_LIST_SUCSPLIT])) THEN - SUBGOAL_THEN subgoal ASSUME_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN - REWRITE_TAC[SUB_LIST_1] THEN ASM_SIMP_TAC[GSYM ADD_ASSOC] THEN NUM_REDUCE_TAC;; - -let SUB_LIST_16 = prove( - `!(l:A list) n. n + 16 <= LENGTH l ==> - [ EL (n + 0) l; EL (n + 1) l; EL (n + 2) l; EL (n + 3) l; - EL (n + 4) l; EL (n + 5) l; EL (n + 6) l; EL (n + 7) l; - EL (n + 8) l; EL (n + 9) l; EL (n + 10) l; EL (n + 11) l; - EL (n + 12) l; EL (n + 13) l; EL (n + 14) l; EL (n + 15) l - ] = SUB_LIST (n,16) l`, +let LENGTH_OF_FST_OF_ENC_CIPHER_STEALING = prove( + `!(block:byte list) (tail:byte list) (tail_len:num) + (iv:int128) (i:num) (key1:int128 list) (key2:int128 list). + LENGTH (FST (cipher_stealing_encrypt block tail tail_len iv i key1 key2)) = 16`, REPEAT STRIP_TAC THEN - MAP_EVERY (fun i -> - if i == 0 - then SUB_LIST_16_TAC `0x10` `n:num` - else SUB_LIST_16_TAC (mk_numeral (num (16 - i))) - (mk_binop (mk_const("+", [`:num`, `:A`])) (mk_var("n", `:num`)) - (mk_numeral (num i)))) (0--14) THEN - SUBGOAL_THEN `n + 15 < LENGTH (l:A list)` ASSUME_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN - ASM_SIMP_TAC[APPEND; ARITH_RULE `n + 0 = n`] -);; - -let BYTE_LIST_AT_5BLOCKS = prove( - `! pos bl bl_ptr len s. - byte_list_at bl bl_ptr len s - ==> LENGTH bl = val len - ==> pos + 0x50 <= LENGTH bl - ==> (read (memory :> bytes128 (word_add bl_ptr (word pos))) s = - bytes_to_int128 (SUB_LIST (pos, 0x10) bl) /\ - read (memory :> bytes128 (word_add (word_add bl_ptr (word pos)) (word 0x10))) s = - bytes_to_int128 (SUB_LIST (pos + 0x10, 0x10) bl) /\ - read (memory :> bytes128 (word_add (word_add bl_ptr (word pos)) (word 0x20))) s = - bytes_to_int128 (SUB_LIST (pos + 0x20, 0x10) bl) /\ - read (memory :> bytes128 (word_add (word_add bl_ptr (word pos)) (word 0x30))) s = - bytes_to_int128 (SUB_LIST (pos + 0x30, 0x10) bl) /\ - read (memory :> bytes128 (word_add (word_add bl_ptr (word pos)) (word 0x40))) s = - bytes_to_int128 (SUB_LIST (pos + 0x40, 0x10) bl))`, - REWRITE_TAC[byte_list_at] THEN - REPEAT STRIP_TAC THENL - [ (* Subgoal1 *) - MAP_EVERY (fun i -> BYTE_LIST_AT_ADD_ASSUM_TAC - (mk_binop (mk_const("+", [`:num`, `:A`])) (mk_var("pos", `:num`)) - (mk_numeral (num i))) `0x50`) (0--15) THEN - REWRITE_TAC[WORD_ADD_ASSOC_CONSTS] THEN - REPEAT STRIP_TAC THEN - ASM_REWRITE_TAC[BYTES128_TO_BYTES8_THM; GSYM ADD_ASSOC] THEN - NUM_REDUCE_TAC THEN ASM_REWRITE_TAC[] THEN AP_TERM_TAC THEN - MP_TAC (ISPECL [`bl:byte list`; `pos:num`] SUB_LIST_16) THEN - REWRITE_TAC[GSYM ADD_ASSOC] THEN NUM_REDUCE_TAC THEN - DISCH_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_ARITH_TAC; - (* Subgoal2 *) - MAP_EVERY (fun i -> BYTE_LIST_AT_ADD_ASSUM_TAC - (mk_binop (mk_const("+", [`:num`, `:A`])) (mk_var("pos", `:num`)) - (mk_numeral (num i))) `0x50`) (16--31) THEN - REWRITE_TAC[WORD_ADD_ASSOC_CONSTS] THEN - REPEAT STRIP_TAC THEN - ASM_REWRITE_TAC[BYTES128_TO_BYTES8_THM; GSYM ADD_ASSOC] THEN - NUM_REDUCE_TAC THEN ASM_REWRITE_TAC[] THEN AP_TERM_TAC THEN - MP_TAC (ISPECL [`bl:byte list`; `(pos+0x10):num`] SUB_LIST_16) THEN - REWRITE_TAC[GSYM ADD_ASSOC] THEN NUM_REDUCE_TAC THEN - DISCH_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_ARITH_TAC; - (* Subgoal3 *) - MAP_EVERY (fun i -> BYTE_LIST_AT_ADD_ASSUM_TAC - (mk_binop (mk_const("+", [`:num`, `:A`])) (mk_var("pos", `:num`)) - (mk_numeral (num i))) `0x50`) (32--47) THEN - REWRITE_TAC[WORD_ADD_ASSOC_CONSTS] THEN - REPEAT STRIP_TAC THEN - ASM_REWRITE_TAC[BYTES128_TO_BYTES8_THM; GSYM ADD_ASSOC] THEN - NUM_REDUCE_TAC THEN ASM_REWRITE_TAC[] THEN AP_TERM_TAC THEN - MP_TAC (ISPECL [`bl:byte list`; `(pos+0x20):num`] SUB_LIST_16) THEN - REWRITE_TAC[GSYM ADD_ASSOC] THEN NUM_REDUCE_TAC THEN - DISCH_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_ARITH_TAC; - (* Subgoal4 *) - MAP_EVERY (fun i -> BYTE_LIST_AT_ADD_ASSUM_TAC - (mk_binop (mk_const("+", [`:num`, `:A`])) (mk_var("pos", `:num`)) - (mk_numeral (num i))) `0x50`) (48--63) THEN - REWRITE_TAC[WORD_ADD_ASSOC_CONSTS] THEN - REPEAT STRIP_TAC THEN - ASM_REWRITE_TAC[BYTES128_TO_BYTES8_THM; GSYM ADD_ASSOC] THEN - NUM_REDUCE_TAC THEN ASM_REWRITE_TAC[] THEN AP_TERM_TAC THEN - MP_TAC (ISPECL [`bl:byte list`; `(pos+0x30):num`] SUB_LIST_16) THEN - REWRITE_TAC[GSYM ADD_ASSOC] THEN NUM_REDUCE_TAC THEN - DISCH_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_ARITH_TAC; - (* Subgoal 5 *) - MAP_EVERY (fun i -> BYTE_LIST_AT_ADD_ASSUM_TAC - (mk_binop (mk_const("+", [`:num`, `:A`])) (mk_var("pos", `:num`)) - (mk_numeral (num i))) `0x50`) (64--79) THEN - REWRITE_TAC[WORD_ADD_ASSOC_CONSTS] THEN - REPEAT STRIP_TAC THEN - ASM_REWRITE_TAC[BYTES128_TO_BYTES8_THM; GSYM ADD_ASSOC] THEN - NUM_REDUCE_TAC THEN ASM_REWRITE_TAC[] THEN AP_TERM_TAC THEN - MP_TAC (ISPECL [`bl:byte list`; `(pos+0x40):num`] SUB_LIST_16) THEN - REWRITE_TAC[GSYM ADD_ASSOC] THEN NUM_REDUCE_TAC THEN - DISCH_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_ARITH_TAC - ] -);; - -let BYTE_LIST_AT_4BLOCKS = prove( - `! pos bl bl_ptr len s. - byte_list_at bl bl_ptr len s - ==> LENGTH bl = val len - ==> pos + 0x40 <= LENGTH bl - ==> (read (memory :> bytes128 (word_add bl_ptr (word pos))) s = - bytes_to_int128 (SUB_LIST (pos, 0x10) bl) /\ - read (memory :> bytes128 (word_add (word_add bl_ptr (word pos)) (word 0x10))) s = - bytes_to_int128 (SUB_LIST (pos + 0x10, 0x10) bl) /\ - read (memory :> bytes128 (word_add (word_add bl_ptr (word pos)) (word 0x20))) s = - bytes_to_int128 (SUB_LIST (pos + 0x20, 0x10) bl) /\ - read (memory :> bytes128 (word_add (word_add bl_ptr (word pos)) (word 0x30))) s = - bytes_to_int128 (SUB_LIST (pos + 0x30, 0x10) bl))`, - REWRITE_TAC[byte_list_at] THEN - REPEAT STRIP_TAC THENL - [ (* Subgoal1 *) - MAP_EVERY (fun i -> BYTE_LIST_AT_ADD_ASSUM_TAC - (mk_binop (mk_const("+", [`:num`, `:A`])) (mk_var("pos", `:num`)) - (mk_numeral (num i))) `0x40`) (0--15) THEN - REWRITE_TAC[WORD_ADD_ASSOC_CONSTS] THEN - REPEAT STRIP_TAC THEN - ASM_REWRITE_TAC[BYTES128_TO_BYTES8_THM; GSYM ADD_ASSOC] THEN - NUM_REDUCE_TAC THEN ASM_REWRITE_TAC[] THEN AP_TERM_TAC THEN - MP_TAC (ISPECL [`bl:byte list`; `pos:num`] SUB_LIST_16) THEN - REWRITE_TAC[GSYM ADD_ASSOC] THEN NUM_REDUCE_TAC THEN - DISCH_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_ARITH_TAC; - (* Subgoal2 *) - MAP_EVERY (fun i -> BYTE_LIST_AT_ADD_ASSUM_TAC - (mk_binop (mk_const("+", [`:num`, `:A`])) (mk_var("pos", `:num`)) - (mk_numeral (num i))) `0x40`) (16--31) THEN - REWRITE_TAC[WORD_ADD_ASSOC_CONSTS] THEN - REPEAT STRIP_TAC THEN - ASM_REWRITE_TAC[BYTES128_TO_BYTES8_THM; GSYM ADD_ASSOC] THEN - NUM_REDUCE_TAC THEN ASM_REWRITE_TAC[] THEN AP_TERM_TAC THEN - MP_TAC (ISPECL [`bl:byte list`; `(pos+0x10):num`] SUB_LIST_16) THEN - REWRITE_TAC[GSYM ADD_ASSOC] THEN NUM_REDUCE_TAC THEN - DISCH_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_ARITH_TAC; - (* Subgoal3 *) - MAP_EVERY (fun i -> BYTE_LIST_AT_ADD_ASSUM_TAC - (mk_binop (mk_const("+", [`:num`, `:A`])) (mk_var("pos", `:num`)) - (mk_numeral (num i))) `0x40`) (32--47) THEN - REWRITE_TAC[WORD_ADD_ASSOC_CONSTS] THEN - REPEAT STRIP_TAC THEN - ASM_REWRITE_TAC[BYTES128_TO_BYTES8_THM; GSYM ADD_ASSOC] THEN - NUM_REDUCE_TAC THEN ASM_REWRITE_TAC[] THEN AP_TERM_TAC THEN - MP_TAC (ISPECL [`bl:byte list`; `(pos+0x20):num`] SUB_LIST_16) THEN - REWRITE_TAC[GSYM ADD_ASSOC] THEN NUM_REDUCE_TAC THEN - DISCH_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_ARITH_TAC; - (* Subgoal4 *) - MAP_EVERY (fun i -> BYTE_LIST_AT_ADD_ASSUM_TAC - (mk_binop (mk_const("+", [`:num`, `:A`])) (mk_var("pos", `:num`)) - (mk_numeral (num i))) `0x40`) (48--63) THEN - REWRITE_TAC[WORD_ADD_ASSOC_CONSTS] THEN - REPEAT STRIP_TAC THEN - ASM_REWRITE_TAC[BYTES128_TO_BYTES8_THM; GSYM ADD_ASSOC] THEN - NUM_REDUCE_TAC THEN ASM_REWRITE_TAC[] THEN AP_TERM_TAC THEN - MP_TAC (ISPECL [`bl:byte list`; `(pos+0x30):num`] SUB_LIST_16) THEN - REWRITE_TAC[GSYM ADD_ASSOC] THEN NUM_REDUCE_TAC THEN - DISCH_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_ARITH_TAC - ] -);; - -let BYTE_LIST_AT_3BLOCKS = prove( - `! pos bl bl_ptr len s. - byte_list_at bl bl_ptr len s - ==> LENGTH bl = val len - ==> pos + 0x30 <= LENGTH bl - ==> (read (memory :> bytes128 (word_add bl_ptr (word pos))) s = - bytes_to_int128 (SUB_LIST (pos, 0x10) bl) /\ - read (memory :> bytes128 (word_add (word_add bl_ptr (word pos)) (word 0x10))) s = - bytes_to_int128 (SUB_LIST (pos + 0x10, 0x10) bl) /\ - read (memory :> bytes128 (word_add (word_add bl_ptr (word pos)) (word 0x20))) s = - bytes_to_int128 (SUB_LIST (pos + 0x20, 0x10) bl))`, - REWRITE_TAC[byte_list_at] THEN - REPEAT STRIP_TAC THENL - [ (* Subgoal1 *) - MAP_EVERY (fun i -> BYTE_LIST_AT_ADD_ASSUM_TAC - (mk_binop (mk_const("+", [`:num`, `:A`])) (mk_var("pos", `:num`)) - (mk_numeral (num i))) `0x30`) (0--15) THEN - REWRITE_TAC[WORD_ADD_ASSOC_CONSTS] THEN - REPEAT STRIP_TAC THEN - ASM_REWRITE_TAC[BYTES128_TO_BYTES8_THM; GSYM ADD_ASSOC] THEN - NUM_REDUCE_TAC THEN ASM_REWRITE_TAC[] THEN AP_TERM_TAC THEN - MP_TAC (ISPECL [`bl:byte list`; `pos:num`] SUB_LIST_16) THEN - REWRITE_TAC[GSYM ADD_ASSOC] THEN NUM_REDUCE_TAC THEN - DISCH_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_ARITH_TAC; - (* Subgoal2 *) - MAP_EVERY (fun i -> BYTE_LIST_AT_ADD_ASSUM_TAC - (mk_binop (mk_const("+", [`:num`, `:A`])) (mk_var("pos", `:num`)) - (mk_numeral (num i))) `0x30`) (16--31) THEN - REWRITE_TAC[WORD_ADD_ASSOC_CONSTS] THEN - REPEAT STRIP_TAC THEN - ASM_REWRITE_TAC[BYTES128_TO_BYTES8_THM; GSYM ADD_ASSOC] THEN - NUM_REDUCE_TAC THEN ASM_REWRITE_TAC[] THEN AP_TERM_TAC THEN - MP_TAC (ISPECL [`bl:byte list`; `(pos+0x10):num`] SUB_LIST_16) THEN - REWRITE_TAC[GSYM ADD_ASSOC] THEN NUM_REDUCE_TAC THEN - DISCH_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_ARITH_TAC; - (* Subgoal3 *) - MAP_EVERY (fun i -> BYTE_LIST_AT_ADD_ASSUM_TAC - (mk_binop (mk_const("+", [`:num`, `:A`])) (mk_var("pos", `:num`)) - (mk_numeral (num i))) `0x30`) (32--47) THEN - REWRITE_TAC[WORD_ADD_ASSOC_CONSTS] THEN - REPEAT STRIP_TAC THEN - ASM_REWRITE_TAC[BYTES128_TO_BYTES8_THM; GSYM ADD_ASSOC] THEN - NUM_REDUCE_TAC THEN ASM_REWRITE_TAC[] THEN AP_TERM_TAC THEN - MP_TAC (ISPECL [`bl:byte list`; `(pos+0x20):num`] SUB_LIST_16) THEN - REWRITE_TAC[GSYM ADD_ASSOC] THEN NUM_REDUCE_TAC THEN - DISCH_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_ARITH_TAC - ] -);; - -let BYTE_LIST_AT_2BLOCKS = prove( - `! pos bl bl_ptr len s. - byte_list_at bl bl_ptr len s - ==> LENGTH bl = val len - ==> pos + 0x20 <= LENGTH bl - ==> (read (memory :> bytes128 (word_add bl_ptr (word pos))) s = - bytes_to_int128 (SUB_LIST (pos, 0x10) bl) /\ - read (memory :> bytes128 (word_add (word_add bl_ptr (word pos)) (word 0x10))) s = - bytes_to_int128 (SUB_LIST (pos + 0x10, 0x10) bl))`, - REWRITE_TAC[byte_list_at] THEN - REPEAT STRIP_TAC THENL - [ (* Subgoal1 *) - MAP_EVERY (fun i -> BYTE_LIST_AT_ADD_ASSUM_TAC - (mk_binop (mk_const("+", [`:num`, `:A`])) (mk_var("pos", `:num`)) - (mk_numeral (num i))) `0x20`) (0--15) THEN - REWRITE_TAC[WORD_ADD_ASSOC_CONSTS] THEN - REPEAT STRIP_TAC THEN - ASM_REWRITE_TAC[BYTES128_TO_BYTES8_THM; GSYM ADD_ASSOC] THEN - NUM_REDUCE_TAC THEN ASM_REWRITE_TAC[] THEN AP_TERM_TAC THEN - MP_TAC (ISPECL [`bl:byte list`; `pos:num`] SUB_LIST_16) THEN - REWRITE_TAC[GSYM ADD_ASSOC] THEN NUM_REDUCE_TAC THEN - DISCH_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_ARITH_TAC; - (* Subgoal2 *) - MAP_EVERY (fun i -> BYTE_LIST_AT_ADD_ASSUM_TAC - (mk_binop (mk_const("+", [`:num`, `:A`])) (mk_var("pos", `:num`)) - (mk_numeral (num i))) `0x20`) (16--31) THEN - REWRITE_TAC[WORD_ADD_ASSOC_CONSTS] THEN - REPEAT STRIP_TAC THEN - ASM_REWRITE_TAC[BYTES128_TO_BYTES8_THM; GSYM ADD_ASSOC] THEN - NUM_REDUCE_TAC THEN ASM_REWRITE_TAC[] THEN AP_TERM_TAC THEN - MP_TAC (ISPECL [`bl:byte list`; `(pos+0x10):num`] SUB_LIST_16) THEN - REWRITE_TAC[GSYM ADD_ASSOC] THEN NUM_REDUCE_TAC THEN - DISCH_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_ARITH_TAC - ] -);; - -let BYTE_LIST_AT_1BLOCKS = prove( - `! pos bl bl_ptr len s. - byte_list_at bl bl_ptr len s - ==> LENGTH bl = val len - ==> pos + 0x10 <= LENGTH bl - ==> read (memory :> bytes128 (word_add bl_ptr (word pos))) s = - bytes_to_int128 (SUB_LIST (pos, 0x10) bl)`, - REWRITE_TAC[byte_list_at] THEN - REPEAT STRIP_TAC THENL - [ (* Subgoal1 *) - MAP_EVERY (fun i -> BYTE_LIST_AT_ADD_ASSUM_TAC - (mk_binop (mk_const("+", [`:num`, `:A`])) (mk_var("pos", `:num`)) - (mk_numeral (num i))) `0x10`) (0--15) THEN - REWRITE_TAC[WORD_ADD_ASSOC_CONSTS] THEN - REPEAT STRIP_TAC THEN - ASM_REWRITE_TAC[BYTES128_TO_BYTES8_THM; GSYM ADD_ASSOC] THEN - NUM_REDUCE_TAC THEN ASM_REWRITE_TAC[] THEN AP_TERM_TAC THEN - MP_TAC (ISPECL [`bl:byte list`; `pos:num`] SUB_LIST_16) THEN - REWRITE_TAC[GSYM ADD_ASSOC] THEN NUM_REDUCE_TAC THEN - DISCH_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_ARITH_TAC - ] -);; - -(* Copied from Decrypt proof without change because it can be instantiated for ptxt_p *) -let READ_CT_LEMMA = prove( - `!ct_ptr i (len:int64) (ct:byte list) s. - (forall j. j < val len ==> read (memory :> bytes8 (word_add ct_ptr (word j))) s = EL j ct) - /\ i * 0x50 + 0x50 <= val len - /\ LENGTH ct = val len - ==> - read (memory :> bytes128 (word_add ct_ptr (word_mul (word 0x50) (word i)))) s = - bytes_to_int128 (SUB_LIST (i * 80, 16) ct) /\ - read (memory :> bytes128 (word_add (word_add ct_ptr (word_mul (word 0x50) (word i))) (word 0x10))) s = - bytes_to_int128 (SUB_LIST (i * 80 + 16, 16) ct) /\ - read (memory :> bytes128 (word_add (word_add ct_ptr (word_mul (word 0x50) (word i))) (word 0x20))) s = - bytes_to_int128 (SUB_LIST (i * 80 + 32, 16) ct) /\ - read (memory :> bytes128 (word_add (word_add ct_ptr (word_mul (word 0x50) (word i))) (word 0x30))) s = - bytes_to_int128 (SUB_LIST (i * 80 + 48, 16) ct) /\ - read (memory :> bytes128 (word_add (word_add ct_ptr (word_mul (word 0x50) (word i))) (word 0x40))) s = - bytes_to_int128 (SUB_LIST (i * 80 + 64, 16) ct) - `, - REPEAT GEN_TAC THEN STRIP_TAC THEN - REWRITE_TAC [WORD_RULE `word_mul (word 0x50) (word i) = word (i * 80)`] THEN - MP_TAC - (SPECL [`(i * 80):num`; `ct:byte list`; `ct_ptr:int64`; `len:int64`; `s:armstate`] - BYTE_LIST_AT_5BLOCKS) THEN - REWRITE_TAC[byte_list_at] THEN ASM_SIMP_TAC[] -);; - -(* Same as Decrypt but with "num_5blocks" replaced by "num_5blocks", - which can still be used with Decrypt since it's universally quantified at the beginning of this lemma - and the following ones *) -let READ_CT_TAIL4_LEMMA = prove( - `!ct_ptr (num_5blocks:int64) (len:int64) (ct:byte list) s. - (forall j. j < val len ==> read (memory :> bytes8 (word_add ct_ptr (word j))) s = EL j ct) - /\ val num_5blocks * 0x50 + 0x40 <= val len - /\ LENGTH ct = val len - ==> - read (memory :> bytes128 (word_add - (word_add ct_ptr (word_mul (word 0x50) num_5blocks)) - (word 0x30))) s = - bytes_to_int128 (SUB_LIST (val num_5blocks * 80 + 0x30, 16) ct) /\ - read (memory :> bytes128 (word_add - (word_add ct_ptr (word_mul (word 0x50) num_5blocks)) - (word 0x20))) s = - bytes_to_int128 (SUB_LIST (val num_5blocks * 80 + 0x20, 16) ct) /\ - read (memory :> bytes128 (word_add - (word_add ct_ptr (word_mul (word 0x50) num_5blocks)) - (word 0x10))) s = - bytes_to_int128 (SUB_LIST (val num_5blocks * 80 + 0x10, 16) ct) /\ - read (memory :> bytes128 - (word_add ct_ptr (word_mul (word 0x50) num_5blocks))) s = - bytes_to_int128 (SUB_LIST (val num_5blocks * 80, 16) ct) - `, - REPEAT GEN_TAC THEN STRIP_TAC THEN - REWRITE_TAC [WORD_RULE `(word_mul (word 0x50) (num_5blocks:int64)) = word (val num_5blocks * 80)`] THEN - MP_TAC - (SPECL [`(val (num_5blocks:int64) * 80):num`; `ct:byte list`; `ct_ptr:int64`; `len:int64`; `s:armstate`] - BYTE_LIST_AT_4BLOCKS) THEN - REWRITE_TAC[byte_list_at] THEN ASM_SIMP_TAC[] -);; - -let READ_CT_TAIL3_LEMMA = prove( - `!ct_ptr (num_5blocks:int64) (len:int64) (ct:byte list) s. - (forall j. j < val len ==> read (memory :> bytes8 (word_add ct_ptr (word j))) s = EL j ct) - /\ val num_5blocks * 0x50 + 0x30 <= val len - /\ LENGTH ct = val len - ==> - read (memory :> bytes128 (word_add - (word_add ct_ptr (word_mul (word 0x50) num_5blocks)) - (word 0x20))) s = - bytes_to_int128 (SUB_LIST (val num_5blocks * 80 + 0x20, 16) ct) /\ - read (memory :> bytes128 (word_add - (word_add ct_ptr (word_mul (word 0x50) num_5blocks)) - (word 0x10))) s = - bytes_to_int128 (SUB_LIST (val num_5blocks * 80 + 0x10, 16) ct) /\ - read (memory :> bytes128 - (word_add ct_ptr (word_mul (word 0x50) num_5blocks))) s = - bytes_to_int128 (SUB_LIST (val num_5blocks * 80, 16) ct) - `, - REPEAT GEN_TAC THEN STRIP_TAC THEN - REWRITE_TAC [WORD_RULE `(word_mul (word 0x50) (num_5blocks:int64)) = word (val num_5blocks * 80)`] THEN - MP_TAC - (SPECL [`(val (num_5blocks:int64) * 80):num`; `ct:byte list`; `ct_ptr:int64`; `len:int64`; `s:armstate`] - BYTE_LIST_AT_3BLOCKS) THEN - REWRITE_TAC[byte_list_at] THEN ASM_SIMP_TAC[] -);; - -let READ_CT_TAIL2_LEMMA = prove( - `!ct_ptr (num_5blocks:int64) (len:int64) (ct:byte list) s. - (forall j. j < val len ==> read (memory :> bytes8 (word_add ct_ptr (word j))) s = EL j ct) - /\ val num_5blocks * 0x50 + 0x20 <= val len - /\ LENGTH ct = val len - ==> - read (memory :> bytes128 (word_add - (word_add ct_ptr (word_mul (word 0x50) num_5blocks)) - (word 0x10))) s = - bytes_to_int128 (SUB_LIST (val num_5blocks * 80 + 0x10, 16) ct) /\ - read (memory :> bytes128 - (word_add ct_ptr (word_mul (word 0x50) num_5blocks))) s = - bytes_to_int128 (SUB_LIST (val num_5blocks * 80, 16) ct) - `, - REPEAT GEN_TAC THEN STRIP_TAC THEN - REWRITE_TAC [WORD_RULE `(word_mul (word 0x50) (num_5blocks:int64)) = word (val num_5blocks * 80)`] THEN - MP_TAC - (SPECL [`(val (num_5blocks:int64) * 80):num`; `ct:byte list`; `ct_ptr:int64`; `len:int64`; `s:armstate`] - BYTE_LIST_AT_2BLOCKS) THEN - REWRITE_TAC[byte_list_at] THEN ASM_SIMP_TAC[] + REWRITE_TAC[cipher_stealing_encrypt] THEN + ASM_REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + REWRITE_TAC[LENGTH_OF_INT128_TO_BYTES] );; -let READ_CT_TAIL1_LEMMA = prove( - `!ct_ptr (num_5blocks:int64) (len:int64) (ct:byte list) s. - (forall j. j < val len ==> read (memory :> bytes8 (word_add ct_ptr (word j))) s = EL j ct) - /\ val num_5blocks * 0x50 + 0x10 <= val len - /\ LENGTH ct = val len - ==> - read (memory :> bytes128 - (word_add ct_ptr (word_mul (word 0x50) num_5blocks))) s = - bytes_to_int128 (SUB_LIST (val num_5blocks * 80, 16) ct) - `, - REPEAT GEN_TAC THEN STRIP_TAC THEN - REWRITE_TAC [WORD_RULE `(word_mul (word 0x50) (num_5blocks:int64)) = word (val num_5blocks * 80)`] THEN - MP_TAC - (SPECL [`(val (num_5blocks:int64) * 80):num`; `ct:byte list`; `ct_ptr:int64`; `len:int64`; `s:armstate`] - BYTE_LIST_AT_1BLOCKS) THEN - REWRITE_TAC[byte_list_at] THEN ASM_SIMP_TAC[] +let LENGTH_OF_SND_OF_ENC_CIPHER_STEALING = prove( + `!(block:byte list) (tail:byte list) (tail_len:num) + (iv:int128) (i:num) (key1:int128 list) (key2:int128 list). + LENGTH (SND (cipher_stealing_encrypt block tail tail_len iv i key1 key2)) = MIN tail_len 16`, + REPEAT STRIP_TAC THEN + REWRITE_TAC[cipher_stealing_encrypt] THEN + ASM_REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + REWRITE_TAC[LENGTH_SUB_LIST] THEN + REWRITE_TAC[LENGTH_OF_INT128_TO_BYTES] THEN + REWRITE_TAC[MIN] THEN + CONV_TAC NUM_REDUCE_CONV );; -let READ_CT_LAST_LEMMA = prove( - `!ct_ptr (curr_len:num) (len:int64) (ct:byte list) s. - (forall j. j < val len ==> read (memory :> bytes8 (word_add ct_ptr (word j))) s = EL j ct) - /\ curr_len + 0x10 <= val len - /\ LENGTH ct = val len - ==> - read (memory :> bytes128 (word_add ct_ptr (word curr_len))) s = - bytes_to_int128 (SUB_LIST (curr_len, 16) ct) - `, - REPEAT GEN_TAC THEN STRIP_TAC THEN - MP_TAC - (SPECL [`curr_len:num`; `ct:byte list`; `ct_ptr:int64`; `len:int64`; `s:armstate`] - BYTE_LIST_AT_1BLOCKS) THEN - REWRITE_TAC[byte_list_at] THEN ASM_SIMP_TAC[] -);; +let LENGTH_OF_AES256_XTS_ENCRYPT_TAIL = prove( + `! (i:num) (tail_len:num) (P:byte list) (iv:int128) (key1:int128 list) (key2:int128 list). + LENGTH(aes256_xts_encrypt_tail i tail_len P iv key1 key2) = 0x10 + MIN tail_len 16`, + REPEAT STRIP_TAC THEN + REWRITE_TAC[aes256_xts_encrypt_tail] THEN + COND_CASES_TAC THENL [ + ASM_REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + REWRITE_TAC[LENGTH_OF_INT128_TO_BYTES] THEN + REWRITE_TAC[ADD_CLAUSES; MIN] THEN + CONV_TAC NUM_REDUCE_CONV; -(* Different from decrypt in using len_full_blocks *) -let LEN_FULL_BLOCKS_LO_BOUND_THM = prove( - `!(len:int64) len_full_blocks. word_and len (word 0xfffffffffffffff0) = len_full_blocks - ==> ~(val len < 0x50) - ==> ~(val len_full_blocks < 0x50)`, - BITBLAST_TAC);; - -let LEN_FULL_BLOCKS_LO_BOUND_1BLOCK_THM = prove( - `!(len:int64) len_full_blocks. word_and len (word 0xfffffffffffffff0) = len_full_blocks - ==> ~(val len < 0x10) - ==> ~(val len_full_blocks < 0x10)`, - BITBLAST_TAC);; - -let LEN_FULL_BLOCKS_HI_BOUND_THM = prove( - `!(len:int64) len_full_blocks. word_and len (word 0xfffffffffffffff0) = len_full_blocks - ==> val len <= 2 EXP 24 - ==> val len_full_blocks <= 2 EXP 24`, - BITBLAST_TAC);; - -let LEN_FULL_BLOCKS_LT_LEN_THM = prove( - `!(len:int64). val (word_and len (word 0xfffffffffffffff0)) <= val len`, - BITBLAST_TAC + REWRITE_TAC[LET_DEF; LET_END_DEF; LENGTH_APPEND] THEN + REWRITE_TAC[LENGTH_OF_FST_OF_ENC_CIPHER_STEALING] THEN + REWRITE_TAC[LENGTH_OF_SND_OF_ENC_CIPHER_STEALING]] );; -let TAIL_LEN_BOUND_THM = prove( - `!(len:int64) tail_len. word_and len (word 0xf) = tail_len - ==> val tail_len < 0x10`, - BITBLAST_TAC);; - -(* Different from decrypt in using num_5blocks *) -let NUM_5BLOCKS_LO_BOUND_THM = prove( - `!(len_full_blocks:int64) (num_5blocks:int64). - val len_full_blocks <= 2 EXP 24 - ==> ~(val len_full_blocks < 0x50) - ==> word (val len_full_blocks DIV 0x50) = num_5blocks - ==> 0x0 < val num_5blocks`, - REPEAT STRIP_TAC THEN - EXPAND_TAC "num_5blocks" THEN - REWRITE_TAC[VAL_WORD; DIMINDEX_64] THEN - UNDISCH_TAC `~(val (len_full_blocks:int64) < 0x50)` THEN - ABBREV_TAC `n = val (len_full_blocks:int64)` THEN - SUBGOAL_THEN `n DIV 0x50 < 2 EXP 64` ASSUME_TAC THENL - [ ASM_ARITH_TAC; ALL_TAC] THEN - ASM_SIMP_TAC[MOD_LT] THEN - ARITH_TAC -);; -(* -let len_full_blocks_LT_LEN_THM = prove( - `!(len:int64) num_blocks. - word_and len (word 0xfffffffffffffff0) = num_blocks - ==> ~(val num_blocks < 0x60) - ==> val (word_sub num_blocks (word 0x10)) <= val len`, - BITBLAST_TAC -);; -*) -let NUM_OF_BYTELIST_APPEND = prove - (`!l1 l2. num_of_bytelist (APPEND l1 l2) = - num_of_bytelist l1 + 2 EXP (8 * LENGTH l1) * num_of_bytelist l2`, - LIST_INDUCT_TAC THENL - [ REWRITE_TAC[APPEND; LENGTH; num_of_bytelist; MULT_CLAUSES; EXP; ADD_CLAUSES]; - REWRITE_TAC[APPEND; LENGTH; num_of_bytelist] THEN - ASM_REWRITE_TAC[] THEN - REWRITE_TAC[MULT_SUC; EXP_ADD] THEN - REWRITE_TAC[MULT_ASSOC; LEFT_ADD_DISTRIB] THEN - ARITH_TAC]);; - -let NUM_OF_BYTELIST_OF_SUB_LIST = prove( - `!sz len (x:byte list). - sz <= LENGTH x ==> - num_of_bytelist (SUB_LIST (0, sz + len) x) = - num_of_bytelist (SUB_LIST (0, sz) x) + - 2 EXP (8 * sz) * num_of_bytelist (SUB_LIST (sz, len) x)`, +let LENGTH_OF_AES256_XTS_ENCRYPT_REC_TRIVIAL = prove( + `!(pt:byte list) (iv:int128) (key1:int128 list) (key2:int128 list). + LENGTH (aes256_xts_encrypt_rec 0x0 0x0 pt iv key1 key2) = 16`, REPEAT STRIP_TAC THEN - SUBST1_TAC(ISPECL [`x:byte list`; `sz:num`; `len:num`; `0:num`] SUB_LIST_SPLIT) THEN - REWRITE_TAC[NUM_OF_BYTELIST_APPEND] THEN - ASM_SIMP_TAC[LENGTH_SUB_LIST; SUB_0; MIN; ARITH_RULE `0 + sz = sz`] + REWRITE_TAC[LENGTH_OF_AES256_XTS_ENCRYPT_REC] THEN + CONV_TAC NUM_REDUCE_CONV );; -let INT128_TO_BYTES_OF_BYTES_TO_INT128 = prove( - `!x. LENGTH x = 16 ==> int128_to_bytes (bytes_to_int128 x) = x`, +let LENGTH_OF_AES256_XTS_ENCRYPT_TAIL_TRIVIAL = prove( + `!(pt:byte list) (iv:int128) (key1:int128 list) (key2:int128 list). + LENGTH(aes256_xts_encrypt_tail 0 0 pt iv key1 key2) = 16`, REPEAT STRIP_TAC THEN - MP_TAC ((GEN_REWRITE_CONV I [LENGTH_EQ_LIST_OF_SEQ] THENC - RAND_CONV LIST_OF_SEQ_CONV) `LENGTH (x:byte list) = 16`) THEN - ASM_SIMP_TAC[] THEN - DISCH_THEN (fun th -> ONCE_REWRITE_TAC[th]) THEN - REWRITE_TAC[bytes_to_int128] THEN - REWRITE_TAC EL_16_8_CLAUSES THEN - REWRITE_TAC[int128_to_bytes] THEN - REWRITE_TAC[CONS_11] THEN - REPEAT (CONJ_TAC THEN BITBLAST_TAC) + REWRITE_TAC[LENGTH_OF_AES256_XTS_ENCRYPT_TAIL] THEN + CONV_TAC NUM_REDUCE_CONV );; -let MEMORY_READ_SUBSET_LEMMA = prove - (`!len (ptr:int64) (bl:byte list) s. - (forall i. - i < SUC len - ==> read (memory :> bytes8 (word_add ptr (word i))) s = EL i bl) ==> - (forall i. - i < len - ==> read (memory :> bytes8 (word_add ptr (word i))) s = EL i bl) /\ - read (memory :> bytes (word_add ptr (word len),1)) s = - val(read (memory :> bytes8 (word_add ptr (word len))) s) - `, - REPEAT GEN_TAC THEN - DISCH_TAC THEN - CONJ_TAC THENL - [ GEN_TAC THEN DISCH_TAC THEN - FIRST_X_ASSUM MATCH_MP_TAC THEN - ASM_REWRITE_TAC[LT_SUC_LE] THEN - ASM_ARITH_TAC; - ALL_TAC] THEN - REWRITE_TAC[bytes8; READ_COMPONENT_COMPOSE; asword; through; read] THEN - REWRITE_TAC[VAL_WORD; DIMINDEX_8] THEN +let AES256_XTS_ENCRYPT_REC_EQ_TAIL_TRIVIAL = prove( + `!(pt:byte list) (iv:int128) (key1:int128 list) (key2:int128 list). + aes256_xts_encrypt_rec 0x0 0x0 ct iv key1 key2 = + aes256_xts_encrypt_tail 0x0 0x0 ct iv key1 key2`, + REPEAT STRIP_TAC THEN + ONCE_REWRITE_TAC[aes256_xts_encrypt_rec] THEN CONV_TAC NUM_REDUCE_CONV THEN - IMP_REWRITE_TAC[MOD_LT] THEN - MP_TAC (ISPECL [`(word_add (ptr:int64) (word len)):int64`; `1:num`; `(read memory s):int64->byte`] READ_BYTES_BOUND) THEN - CONV_TAC NUM_REDUCE_CONV -);; + REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + ONCE_REWRITE_TAC[aes256_xts_encrypt_rec] THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[APPEND_NIL] THEN -let BYTE_LIST_AT_SPLIT = prove( - `!len (ptr:int64) (bl:byte list) s. - SUC len <= LENGTH bl ==> - ((forall i. - i < SUC len - ==> read (memory :> bytes8 (word_add ptr (word i))) s = EL i bl) <=> - ((forall i. - i < len - ==> read (memory :> bytes8 (word_add ptr (word i))) s = EL i bl) /\ - read (memory :> bytes8 (word_add ptr (word len))) s = EL len bl))`, - REPEAT STRIP_TAC THEN - EQ_TAC THENL - [ STRIP_TAC THEN - CONJ_TAC THENL - [ ASM_SIMP_TAC[ARITH_RULE `i < len ==> i < SUC len`]; - ASM_SIMP_TAC[ARITH_RULE `len < SUC len`]]; - ALL_TAC ] THEN - REPEAT STRIP_TAC THEN - ASM_CASES_TAC `i < len` THENL - [ FIRST_X_ASSUM MATCH_MP_TAC THEN - ASM_SIMP_TAC[]; - SUBGOAL_THEN `i = len:num` SUBST1_TAC THENL - [ASM_ARITH_TAC; ASM_REWRITE_TAC[]] - ] + REWRITE_TAC[aes256_xts_encrypt_tail] THEN + REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + CONV_TAC NUM_REDUCE_CONV );; -let HD_SUB_LIST_CONS = prove - (`!(h:A) (t:A list) n. 0 < n ==> HD (SUB_LIST (0,n) (CONS h t)) = h`, - REPEAT GEN_TAC THEN STRIP_TAC THEN - MP_TAC(SPEC `n:num` num_CASES) THEN - ASM_SIMP_TAC[ARITH_RULE `0 < n ==> ~(n = 0)`] THEN - DISCH_THEN(X_CHOOSE_THEN `m:num` SUBST_ALL_TAC) THEN - REWRITE_TAC[SUB_LIST_CLAUSES; HD]);; - -let HD_SUB_LIST_CONS_GENERAL = prove( - `!p n (l:A list). p < LENGTH l /\ 0 < n ==> HD (SUB_LIST (p,n) l) = EL p l`, +let LENGTH_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS = prove( + `! (i:num) (pt:byte list) (iv:int128) (key1:int128 list) (key2:int128 list). + LENGTH(aes256_xts_encrypt pt (0x10 * i) iv key1 key2) = 0x10 * i`, + REPEAT STRIP_TAC THEN + SPEC_TAC (`i:num`, `i:num`) THEN INDUCT_TAC THENL [ - GEN_TAC THEN - LIST_INDUCT_TAC THENL - [ - REWRITE_TAC[LENGTH] THEN ARITH_TAC; - REPEAT STRIP_TAC THEN - REWRITE_TAC[EL; HD] THEN - MP_TAC (SPECL [`h:A`; `t:A list`; `n:num`] HD_SUB_LIST_CONS) THEN - ASM_SIMP_TAC[] - ]; ALL_TAC + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[aes256_xts_encrypt] THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[LENGTH_EQ_NIL]; + ALL_TAC] THEN + + REWRITE_TAC[ADD1; LEFT_ADD_DISTRIB] THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[aes256_xts_encrypt] THEN + + ASM_CASES_TAC `i = 0` THENL + [ ASM_SIMP_TAC[] THEN + CONV_TAC NUM_REDUCE_CONV THEN + IMP_REWRITE_TAC[LET_DEF;LET_END_DEF;SUB_0] THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[LENGTH_OF_AES256_XTS_ENCRYPT_TAIL_TRIVIAL] + ; ALL_TAC ] THEN - GEN_TAC THEN - LIST_INDUCT_TAC THENL - [ - REWRITE_TAC[LENGTH] THEN ARITH_TAC; - REPEAT STRIP_TAC THEN - REWRITE_TAC[SUB_LIST_CLAUSES] THEN - REWRITE_TAC[EL; TL] THEN - FIRST_X_ASSUM (fun th -> MATCH_MP_TAC (SPECL [`n:num`; `t:A list`] th)) THEN - ASM_SIMP_TAC[] THEN - UNDISCH_TAC `SUC p < LENGTH (CONS h (t:A list))` THEN - REWRITE_TAC[LENGTH] THEN - ARITH_TAC - ] -);; -let TL_SUB_LIST_CONS = prove -(`!(h:A) (t:A list) n. 0 < n ==> TL (SUB_LIST (0,n) (CONS h t)) = SUB_LIST (0, n - 1) t`, - REPEAT GEN_TAC THEN STRIP_TAC THEN - MP_TAC(SPEC `n:num` num_CASES) THEN - ASM_SIMP_TAC[ARITH_RULE `0 < n ==> ~(n = 0)`] THEN - DISCH_THEN(X_CHOOSE_THEN `m:num` SUBST_ALL_TAC) THEN - REWRITE_TAC[SUB_LIST_CLAUSES; TL] THEN - REWRITE_TAC[ARITH_RULE `SUC m - 1 = m`]);; - -let TL_SUB_LIST_CONS_GENERAL = prove( - `!p n (l:A list). p < LENGTH l ==> 0 < n - ==> TL (SUB_LIST (p, n) l) = SUB_LIST (p + 1, n - 1) l`, - INDUCT_TAC THENL - [ - GEN_TAC THEN - LIST_INDUCT_TAC THENL - [ - REWRITE_TAC[LENGTH] THEN ARITH_TAC; - CONV_TAC NUM_REDUCE_CONV THEN - REPEAT STRIP_TAC THEN - MP_TAC (SPECL [`h:A`; `t:A list`; `n:num`] TL_SUB_LIST_CONS) THEN - ASM_SIMP_TAC[num_CONV `1`; SUB_LIST_CLAUSES] - ]; ALL_TAC - ] THEN - GEN_TAC THEN - LIST_INDUCT_TAC THENL - [ - REWRITE_TAC[LENGTH] THEN ARITH_TAC; - REPEAT STRIP_TAC THEN - REWRITE_TAC[ARITH_RULE `SUC p + 1 = SUC (p + 1)`] THEN - REWRITE_TAC[SUB_LIST_CLAUSES] THEN - FIRST_X_ASSUM (fun th -> MP_TAC (SPECL [`n:num`; `t:A list`] th)) THEN - SUBGOAL_THEN `p < LENGTH (t:A list)` ASSUME_TAC THENL - [ UNDISCH_TAC `SUC p < LENGTH (CONS h (t:A list))` THEN - REWRITE_TAC[LENGTH] THEN ARITH_TAC - ; ALL_TAC] THEN - ASM_SIMP_TAC[] - ] -);; - -let EL_SUB_LIST_TRIVIAL = prove( - `!i n (l:A list). i < LENGTH l /\ 0 < n ==> EL 0x0 (SUB_LIST (i, n) l) = EL i l`, - REWRITE_TAC[EL] THEN - SIMP_TAC[HD_SUB_LIST_CONS_GENERAL] + SUBGOAL_THEN `~(0x10 * i + 0x10 < 0x10)` ASSUME_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC ] THEN ASM_SIMP_TAC[] THEN + REWRITE_TAC[ARITH_RULE `0x10 * i + 0x10 = 0x10 * (i + 1)`; MOD_MULT] THEN + IMP_REWRITE_TAC[LET_DEF; LET_END_DEF;SUB_0;DIV_MULT] THEN + CONJ_TAC THENL [ALL_TAC; ARITH_TAC] THEN + SUBGOAL_THEN `~(i + 0x1 < 0x2)` ASSUME_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC] THEN ASM_SIMP_TAC[] THEN + REWRITE_TAC[LENGTH_APPEND] THEN + REWRITE_TAC[LENGTH_OF_AES256_XTS_ENCRYPT_REC] THEN + REWRITE_TAC[LENGTH_OF_AES256_XTS_ENCRYPT_TAIL] THEN + CONV_TAC NUM_REDUCE_CONV THEN + ASM_ARITH_TAC );; -let EL_SUB_LIST = prove( - `!(i:num) n (l:A list). i < n /\ n <= LENGTH l ==> - EL i (SUB_LIST (0, n) l) = EL i l`, - INDUCT_TAC THENL - [ (* i = 0 *) - ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN - LIST_INDUCT_TAC THENL - [ - REPEAT STRIP_TAC THEN - IMP_REWRITE_TAC[SUB_LIST_TRIVIAL] THEN - REWRITE_TAC[LENGTH] THEN - ARITH_TAC; ALL_TAC - ] THEN - REPEAT STRIP_TAC THEN - IMP_REWRITE_TAC[EL; HD; HD_SUB_LIST_CONS]; - ALL_TAC - ] THEN - (* i != 0 *) - ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN - LIST_INDUCT_TAC THENL - [ - REPEAT STRIP_TAC THEN - IMP_REWRITE_TAC[SUB_LIST_TRIVIAL] THEN - REWRITE_TAC[LENGTH] THEN - ARITH_TAC; ALL_TAC - ] THEN +let LENGTH_OF_AES256_XTS_ENCRYPT = prove( + `! (i:num) (tail_len:num) (pt:byte list) (iv:int128) (key1:int128 list) (key2:int128 list). + ~(tail_len = 0) /\ tail_len < 16 ==> + LENGTH(aes256_xts_encrypt pt (16 * i + 16 + tail_len) iv key1 key2) = 16 * i + 16 + tail_len`, REPEAT STRIP_TAC THEN - REWRITE_TAC[EL; TL] THEN - IMP_REWRITE_TAC[TL_SUB_LIST_CONS] THEN - REPEAT CONJ_TAC THENL - [ ASM_SIMP_TAC[ARITH_RULE `SUC i < n ==> i < n - 1`]; - SUBGOAL_THEN `LENGTH (CONS h (t:A list)) = SUC (LENGTH t)` ASSUME_TAC THENL - [ REWRITE_TAC[LENGTH]; ALL_TAC ] THEN - ASM_ARITH_TAC; - MP_TAC (ARITH_RULE `SUC i < n ==> 0 < n`) THEN - ASM_SIMP_TAC[] - ] -);; - -let EL_SUB_LIST_GENERAL = prove( - `!p (l:A list) i n. i >= p /\ i < p + n /\ p + n <= LENGTH l ==> - EL (i - p) (SUB_LIST (p, n) l) = EL i l`, - INDUCT_TAC THENL - [ IMP_REWRITE_TAC[ADD; SUB_0; EL_SUB_LIST]; - ALL_TAC - ] THEN - LIST_INDUCT_TAC THENL - [ REWRITE_TAC[SUB_LIST_CLAUSES; LENGTH] THEN - REPEAT STRIP_TAC THEN + (* Case 1: i = 0 *) + ASM_CASES_TAC `i = 0` THENL + [ + ASM_SIMP_TAC[ADD_ASSOC] THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[aes256_xts_encrypt] THEN + SUBGOAL_THEN `~(0x10 + tail_len < 0x10)` ASSUME_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `(0x10 + tail_len) MOD 0x10 = tail_len` ASSUME_TAC THENL + [ REWRITE_TAC[ARITH_RULE `0x10 + tail_len = 1 * 16 + tail_len`] THEN + IMP_REWRITE_TAC[MOD_MULT_ADD; MOD_LT]; ALL_TAC] THEN + ASM_SIMP_TAC[] THEN + REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + SUBGOAL_THEN `((0x10 + tail_len) - tail_len) DIV 0x10 = 1` SUBST1_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC ] THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[LENGTH_OF_AES256_XTS_ENCRYPT_TAIL] THEN ASM_ARITH_TAC; ALL_TAC ] THEN - REWRITE_TAC[LENGTH] THEN - REPEAT STRIP_TAC THEN - REWRITE_TAC[SUB_LIST_CLAUSES] THEN - SUBGOAL_THEN `EL i (CONS h (t:A list)) = EL (i - 1) t` SUBST1_TAC THENL - [ SUBGOAL_THEN `i = SUC (i - 1)` SUBST1_TAC THENL - [ ASM_ARITH_TAC; ALL_TAC] THEN - REWRITE_TAC[EL; TL] THEN - AP_THM_TAC THEN AP_TERM_TAC THEN - ARITH_TAC; ALL_TAC] THEN - REWRITE_TAC[ARITH_RULE `i - SUC p = i - 1 - p`] THEN - FIRST_X_ASSUM (fun th -> MP_TAC (SPECL [`t:A list`; `(i - 1):num`; `n:num`] th)) THEN - ANTS_TAC THENL [ ASM_ARITH_TAC; ALL_TAC ] THEN - SIMP_TAC[] -);; - -let EL_SUB_LIST_SHIFT = prove( - `!(i:num) p (l:A list) n. 0 < i /\ i < n /\ n <= LENGTH l - p ==> - EL (i - 1) (SUB_LIST (p + 1, n - 1) l) = EL i (SUB_LIST (p, n) l)`, - REPEAT STRIP_TAC THEN - SUBGOAL_THEN `EL i (SUB_LIST (p, n) (l:A list)) = EL (SUC (i - 1)) (SUB_LIST (p, SUC (n - 1)) l)` SUBST1_TAC THENL - [ IMP_REWRITE_TAC[ARITH_RULE `0 < i ==> SUC (i - 1) = i`] THEN - ASM_ARITH_TAC; ALL_TAC ] THEN - DISJ_CASES_TAC (ISPEC `l:(A)list` list_CASES) THENL [ - FIRST_X_ASSUM SUBST_ALL_TAC THEN - UNDISCH_TAC `n <= LENGTH ([]:A list) - p` THEN - REWRITE_TAC[LENGTH] THEN - ASM_ARITH_TAC; ALL_TAC - ] THEN - - REPEAT_N 2 (FIRST_X_ASSUM CHOOSE_TAC) THEN - FIRST_X_ASSUM SUBST_ALL_TAC THEN - REWRITE_TAC[EL; TL] THEN - IMP_REWRITE_TAC[TL_SUB_LIST_CONS_GENERAL] THEN - IMP_REWRITE_TAC[ARITH_RULE `0 < n ==> SUC (n - 1) = n`] THEN - ASM_ARITH_TAC - );; -(* Differs from Encrypt in that the address is written in a canonical form *) - let BYTE_LIST_AT_SPLIT_BACKWARDS = prove( - `!(pt_ptr:int64) i len curr_len bl s. - 0 <= i ==> i < len ==> len < 16 ==> LENGTH bl >= 16 ==> - (forall j. - j < len - (i + 1) - ==> read (memory :> bytes8 - (word_add pt_ptr (word (curr_len + 16 + i + 1 + j)))) s = - EL j (SUB_LIST (i + 1, len - (i + 1)) bl)) ==> - read (memory :> bytes8 (word_add pt_ptr (word (curr_len + 16 + i)))) s = (EL i bl) ==> - forall j. - j < len - i - ==> read (memory :> bytes8 - (word_add pt_ptr (word (curr_len + 16 + i + j)))) s = - EL j (SUB_LIST (i, len - i) bl) - `, - REPEAT GEN_TAC THEN - REPEAT STRIP_TAC THEN - ASM_CASES_TAC `j > 0` THENL + (* Case 2: i >= 1 *) + ASM_CASES_TAC `i >= 1` THENL [ - FIRST_X_ASSUM(MP_TAC o SPEC `j - 1`) THEN - ANTS_TAC THENL[ ASM_ARITH_TAC; ALL_TAC] THEN - ASM_SIMP_TAC[ADD_ASSOC; ARITH_RULE `j > 0 ==> curr_len + 0x10 + i + 0x1 + j - 0x1 = curr_len + 0x10 + i + j`] THEN - SIMP_TAC[] THEN DISCH_TAC THEN - IMP_REWRITE_TAC[ARITH_RULE `len - (i + 1) = len - i - 1`; - EL_SUB_LIST_SHIFT] THEN + REWRITE_TAC[aes256_xts_encrypt] THEN + SUBGOAL_THEN `(0x10 * i + 0x10 + tail_len) MOD 0x10 = tail_len` SUBST1_TAC THENL + [ REWRITE_TAC[ADD_ASSOC; ARITH_RULE `0x10 * i + 0x10 = 16 * (i + 1)`] THEN + IMP_REWRITE_TAC[MOD_MULT_ADD; MOD_LT]; ALL_TAC] THEN + SUBGOAL_THEN `~(0x10 * i + 0x10 + tail_len < 0x10)` ASSUME_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[] THEN + REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + SUBGOAL_THEN `((0x10 * i + 0x10 + tail_len) - tail_len) DIV 0x10 = i + 1` SUBST1_TAC THENL + [ REWRITE_TAC[ARITH_RULE `(0x10 * i + 0x10 + tail_len) - tail_len = 16 * (i + 1)`] THEN + IMP_REWRITE_TAC[DIV_MULT] THEN + ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `~(i + 1 < 2)` ASSUME_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[] THEN + IMP_REWRITE_TAC[ARITH_RULE `(i + 1) - 2 = i - 1`; ADD_SUB] THEN + REWRITE_TAC[LENGTH_APPEND] THEN + IMP_REWRITE_TAC[LENGTH_OF_AES256_XTS_ENCRYPT_REC] THEN + IMP_REWRITE_TAC[LENGTH_OF_AES256_XTS_ENCRYPT_TAIL] THEN ASM_ARITH_TAC; ALL_TAC ] THEN - SUBGOAL_THEN `j = 0` SUBST_ALL_TAC THENL[ASM_ARITH_TAC;ALL_TAC] THEN - REWRITE_TAC[ADD_0] THEN - ASM_REWRITE_TAC[] THEN - IMP_REWRITE_TAC[EL_SUB_LIST_TRIVIAL] THEN ASM_ARITH_TAC );; -let MEMORY_READ_BYTES_SUBSET_LEMMA = prove( - `!len (ptr:int64) (bl:byte list) s. - SUC len <= LENGTH bl ==> - read (memory :> bytes (ptr,SUC len)) s = - num_of_bytelist (SUB_LIST (0x0,SUC len) bl) ==> - read (memory :> bytes (ptr,len)) s = - num_of_bytelist (SUB_LIST (0x0,len) bl) /\ - read (memory :> bytes8 (word_add ptr (word len))) s = EL len bl`, - REPEAT GEN_TAC THEN STRIP_TAC THEN - SUBGOAL_THEN `SUC len = len + 1` SUBST_ALL_TAC THENL [ARITH_TAC; ALL_TAC] THEN - REWRITE_TAC[READ_COMPONENT_COMPOSE] THEN - SUBGOAL_THEN `len <= LENGTH (bl:byte list)` ASSUME_TAC THENL [ ASM_ARITH_TAC; ALL_TAC] THEN - (* Use READ_BYTES_COMBINE to decompose the memory read *) - MP_TAC(ISPECL [`ptr:int64`; `len:num`; `1:num`; `(read memory s):int64->byte`] READ_BYTES_COMBINE) THEN - DISCH_TAC THEN - (* Use SUB_LIST_SPLIT to decompose the byte list *) - MP_TAC(ISPECL [`bl:byte list`; `len:num`; `1:num`; `0:num`] SUB_LIST_SPLIT) THEN - REWRITE_TAC[ADD_CLAUSES] THEN DISCH_TAC THEN - (* Decompose num_of_bytelist *) - SUBGOAL_THEN - `num_of_bytelist (SUB_LIST (0,len + 1) (bl:byte list)) = - num_of_bytelist (SUB_LIST (0,len) bl) + - 2 EXP (8 * len) * num_of_bytelist (SUB_LIST (len,1) bl)` - ASSUME_TAC THENL - [ ASM_REWRITE_TAC[] THEN - REWRITE_TAC[NUM_OF_BYTELIST_APPEND] THEN - AP_TERM_TAC THEN AP_THM_TAC THEN REPEAT_N 3 AP_TERM_TAC THEN - IMP_REWRITE_TAC[LENGTH_SUB_LIST; MIN; SUB_0] THEN - ASM_SIMP_TAC[] - ; ALL_TAC] THEN - (* Rewrite in goal *) - ASM_REWRITE_TAC[] THEN - DISCH_TAC THEN - CONJ_TAC THENL - [ (* First part: read (memory :> bytes (ptr,len)) s = num_of_bytelist (SUB_LIST (0,len) bl) *) - FIRST_X_ASSUM(MP_TAC o AP_TERM `\x. x MOD 2 EXP (8 * len)`) THEN - ASM_REWRITE_TAC[] THEN - REWRITE_TAC[MOD_MULT_ADD; MOD_LT] THEN - REWRITE_TAC[READ_BYTES_MOD; MIN] THEN - SIMP_TAC[ARITH_RULE `len <= len`] THEN - DISCH_TAC THEN - IMP_REWRITE_TAC[MOD_LT] THEN - MP_TAC (SPEC `(SUB_LIST (0,len) bl:byte list)` NUM_OF_BYTELIST_BOUND) THEN - IMP_REWRITE_TAC[LENGTH_SUB_LIST; SUB_0; MIN] THEN - SUBGOAL_THEN `256 EXP len = 2 EXP (8 * len)` SUBST1_TAC THENL - [ REWRITE_TAC[ARITH_RULE `256 = 2 EXP 8`; EXP_EXP]; ALL_TAC] THEN - SIMP_TAC[]; - ALL_TAC - ] THEN - (* Second part: read (memory :> bytes8 (word_add ptr (word len))) s = EL len bl *) - FIRST_X_ASSUM(MP_TAC o AP_TERM `\x. x DIV 2 EXP (8 * len)`) THEN - ASM_REWRITE_TAC[] THEN - SUBGOAL_THEN `~(0x2 EXP (0x8 * len) = 0x0)` ASSUME_TAC THENL - [ REWRITE_TAC[EXP_EQ_0; ARITH_EQ]; ALL_TAC] THEN - IMP_REWRITE_TAC[DIV_MULT_ADD] THEN - SUBGOAL_THEN `read (bytes (ptr,len)) (read memory s) < 0x2 EXP (0x8 * len)` ASSUME_TAC THENL - [ REWRITE_TAC[READ_BYTES_BOUND]; ALL_TAC] THEN - SUBGOAL_THEN `num_of_bytelist (SUB_LIST (0x0,len) bl) < 0x2 EXP (0x8 * len)` ASSUME_TAC THENL - [ MP_TAC (SPEC `(SUB_LIST (0,len) bl:byte list)` NUM_OF_BYTELIST_BOUND) THEN - IMP_REWRITE_TAC[LENGTH_SUB_LIST; SUB_0; MIN] THEN - SUBGOAL_THEN `256 EXP len = 2 EXP (8 * len)` SUBST1_TAC THENL - [ REWRITE_TAC[ARITH_RULE `256 = 2 EXP 8`; EXP_EXP]; ALL_TAC] THEN SIMP_TAC[]; ALL_TAC] THEN - IMP_REWRITE_TAC[DIV_LT; ADD] THEN - (* Some rewrites to close the goal *) - REWRITE_TAC[bytes8; READ_COMPONENT_COMPOSE; asword; through; read] THEN - SUBGOAL_THEN `len < LENGTH (bl:byte list)` ASSUME_TAC THENL [ ASM_ARITH_TAC; ALL_TAC] THEN - ASM_SIMP_TAC[SUB_LIST_1] THEN - REWRITE_TAC[num_of_bytelist; MULT_CLAUSES; ADD_CLAUSES; WORD_VAL] +let AES256_XTS_ENCRYPT_TAIL_WHEN_1BLOCK = prove( + `!(n:num) (pt:byte list) (iv:int128) (key1:int128 list) (key2:int128 list). + bytes_to_int128 + (aes256_xts_encrypt_tail n 0x0 pt iv key1 key2) = + aes256_xts_encrypt_round + (bytes_to_int128 (SUB_LIST (n * 0x10,0x10) pt)) + (calculate_tweak n iv key2) key1`, + REPEAT STRIP_TAC THEN + REWRITE_TAC[aes256_xts_encrypt_tail] THEN + REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + REWRITE_TAC[BYTES_TO_INT128_OF_INT128_TO_BYTES] );; -let BYTE_LIST_TO_NUM_THM = prove( - `!len (ptr:int64) (bl:byte list) s. - len <= LENGTH bl ==> - ((forall i. i < len - ==> read (memory :> bytes8 (word_add ptr (word i))) s = EL i bl) <=> - (read (memory :> bytes (ptr, len)) s = num_of_bytelist (SUB_LIST (0, len) bl)))`, +let AES256_XTS_ENCRYPT_REC_EQ_TAIL = prove( + `!(i:num) (k:num) (pt:byte list) (iv:int128) (key1:int128 list) (key2:int128 list). + k >= i ==> + aes256_xts_encrypt_rec i (k + 1) pt iv key1 key2 = + APPEND (aes256_xts_encrypt_rec i k pt iv key1 key2) + (aes256_xts_encrypt_tail (k + 1) 0x0 pt iv key1 key2)`, REPEAT GEN_TAC THEN - SPEC_TAC (`len:num`, `len:num`) THEN - (* Base case: len = 0 *) - INDUCT_TAC THENL - [ STRIP_TAC THEN - REWRITE_TAC[READ_COMPONENT_COMPOSE; READ_BYTES_TRIVIAL; - CONJUNCT1 SUB_LIST; CONJUNCT1 num_of_bytelist] THEN - GEN_TAC THEN MESON_TAC[ARITH_RULE `~(i < 0)`]; - ALL_TAC] THEN - - (* Inductive step: left to right *) + WF_INDUCT_TAC `(k + 1) - i` THEN STRIP_TAC THEN - EQ_TAC THENL - [ MP_TAC (ARITH_RULE `SUC len <= LENGTH (bl:byte list) ==> len <= LENGTH bl`) THEN - ASM_SIMP_TAC[] THEN REPEAT DISCH_TAC THEN - MP_TAC (SPECL [`len:num`; `ptr:int64`; `bl:byte list`; `s:armstate`] MEMORY_READ_SUBSET_LEMMA) THEN - ASM_SIMP_TAC[] THEN - DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN - REWRITE_TAC[READ_COMPONENT_COMPOSE; ADD1] THEN - ONCE_REWRITE_TAC[READ_BYTES_COMBINE] THEN - REWRITE_TAC[SUB_LIST_SPLIT; NUM_OF_BYTELIST_APPEND; CONJUNCT1 ADD] THEN - IMP_REWRITE_TAC[ARITH_RULE `a = c ==> (a + b = c + d) = (b = d)`] THEN - CONJ_TAC THENL [ - REWRITE_TAC[LENGTH_SUB_LIST; MIN; SUB_0] THEN - ASM_SIMP_TAC[] THEN - AP_TERM_TAC THEN - REWRITE_TAC[GSYM READ_COMPONENT_COMPOSE] THEN - FIRST_X_ASSUM (fun th -> MP_TAC (SPEC `len:num` th)) THEN - REWRITE_TAC[ARITH_RULE `len < SUC len`] THEN - SUBGOAL_THEN `len < LENGTH (bl:byte list)` ASSUME_TAC THENL - [ ASM_ARITH_TAC; ALL_TAC] THEN - ASM_REWRITE_TAC[SUB_LIST_1; num_of_bytelist] THEN - CONV_TAC NUM_REDUCE_CONV THEN - REWRITE_TAC[ADD_0] THEN - STRIP_TAC THEN AP_TERM_TAC THEN ASM_SIMP_TAC[] - ; ALL_TAC] THEN - REWRITE_TAC[GSYM READ_COMPONENT_COMPOSE] THEN - ASM_SIMP_TAC[] - ; ALL_TAC] THEN - - (* Inductive step: right to left *) - MP_TAC (ARITH_RULE `SUC len <= LENGTH (bl:byte list) ==> len <= LENGTH bl`) THEN - ASM_SIMP_TAC[] THEN REPEAT DISCH_TAC THEN - MP_TAC (SPECL [`len:num`; `ptr:int64`; `bl:byte list`; `s:armstate`] MEMORY_READ_BYTES_SUBSET_LEMMA) THEN + GEN_REWRITE_TAC (RATOR_CONV o ONCE_DEPTH_CONV) [aes256_xts_encrypt_rec] THEN + SUBGOAL_THEN `~(k + 0x1 < i)` ASSUME_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN ASM_SIMP_TAC[] THEN - DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN - IMP_REWRITE_TAC[BYTE_LIST_AT_SPLIT] THEN - CONJ_TAC THENL [ASM_SIMP_TAC[]; ALL_TAC] THEN - ASM_SIMP_TAC[] + REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + SUBGOAL_THEN `(k + 1) - (i + 1) < (k + 1) - i` ASSUME_TAC THENL [ ASM_ARITH_TAC; ALL_TAC] THEN + FIRST_X_ASSUM (MP_TAC o SPECL [`k:num`; `i + 1:num`]) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN + ASM_CASES_TAC `k >= i + 1` THENL + [ + ASM_SIMP_TAC[] THEN DISCH_TAC THEN + REWRITE_TAC[APPEND_ASSOC] THEN + AP_THM_TAC THEN + GEN_REWRITE_TAC (RAND_CONV o ONCE_DEPTH_CONV) [aes256_xts_encrypt_rec] THEN + SUBGOAL_THEN `~(k < i)` ASSUME_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[] THEN + REWRITE_TAC[LET_DEF; LET_END_DEF]; ALL_TAC + ] THEN + SUBGOAL_THEN `k:num = i` ASSUME_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + ONCE_REWRITE_TAC[aes256_xts_encrypt_rec] THEN + REWRITE_TAC[LT_REFL; LET_DEF; LET_END_DEF] THEN + ONCE_REWRITE_TAC[aes256_xts_encrypt_rec] THEN + REWRITE_TAC[ARITH_RULE `i < i + 1`; APPEND_NIL] THEN + AP_TERM_TAC THEN + REWRITE_TAC[aes256_xts_encrypt_tail; LET_DEF; LET_END_DEF] );; -let MEMORY_BYTES_BOUND = prove - (`read (memory :> bytes (x,16)) s < 2 EXP dimindex (:128)`, - REWRITE_TAC[READ_COMPONENT_COMPOSE; DIMINDEX_128] THEN - SUBST1_TAC(ARITH_RULE `128 = 8 * 16`) THEN REWRITE_TAC[READ_BYTES_BOUND] - );; - -(* Copied from bignum_copy_row_from_table_8n.ml *) -let READ_MEMORY_BYTES_BYTES128 = prove(`!z s. - read (memory :> bytes (z,16)) s = val (read (memory :> bytes128 z) s)`, - REPEAT GEN_TAC THEN - REWRITE_TAC[el 1 (CONJUNCTS READ_MEMORY_BYTESIZED_SPLIT)] THEN - REWRITE_TAC[VAL_WORD_JOIN;DIMINDEX_64;DIMINDEX_128] THEN - IMP_REWRITE_TAC[MOD_LT] THEN - REWRITE_TAC[ARITH_RULE`2 EXP 128 = 2 EXP 64 * 2 EXP 64`] THEN - IMP_REWRITE_TAC[LT_MULT_ADD_MULT] THEN - REWRITE_TAC[VAL_BOUND_64;ARITH_RULE`0<2 EXP 64`;LE_REFL] THEN - REWRITE_TAC[ARITH_RULE`16 = 8*(1+1)`;GSYM BIGNUM_FROM_MEMORY_BYTES;BIGNUM_FROM_MEMORY_STEP;BIGNUM_FROM_MEMORY_SING] THEN - REWRITE_TAC[ARITH_RULE`8*1=8`;ARITH_RULE`64*1=64`] THEN ARITH_TAC);; - -let READ_MEMORY_BYTES128_BYTES = prove(`!z s. - read (memory :> bytes128 z) s = word (read (memory :> bytes (z,16)) s)`, - REPEAT STRIP_TAC THEN - ONCE_REWRITE_TAC[GSYM VAL_EQ] THEN - IMP_REWRITE_TAC [VAL_WORD_EQ] THEN - CONJ_TAC THENL [REWRITE_TAC [READ_MEMORY_BYTES_BYTES128]; ALL_TAC] THEN - REWRITE_TAC [MEMORY_BYTES_BOUND] - );; - -let WORD_JOIN_BOUND_TAC x y = - REWRITE_TAC[VAL_WORD_JOIN; DIMINDEX_CLAUSES] THEN - CONV_TAC NUM_REDUCE_CONV THEN - IMP_REWRITE_TAC[MOD_LT] THEN - CONJ_TAC THENL[ REWRITE_TAC[ADD_SYM]; ALL_TAC ] THEN - MP_TAC (ISPECL [x] VAL_BOUND) THEN - MP_TAC (ISPECL [y] VAL_BOUND) THEN - REWRITE_TAC[DIMINDEX_CLAUSES] THEN - CONV_TAC NUM_REDUCE_CONV THEN - ARITH_TAC;; - -let WORD_JOIN_16_8_ASSOC = WORD_BLAST - `!(x0:byte) (x1:byte) (x2:byte) (x3:byte) - (x4:byte) (x5:byte) (x6:byte) (x7:byte) - (x8:byte) (x9:byte) (x10:byte) (x11:byte) - (x12:byte) (x13:byte) (x14:byte) (x15:byte). - (word_join - (word_join - (word_join (word_join x15 x14 : int16) (word_join x13 x12 : int16) : int32) - (word_join (word_join x11 x10 : int16) (word_join x9 x8 : int16) : int32) : int64) - (word_join - (word_join (word_join x7 x6 : int16) (word_join x5 x4 : int16) : int32) - (word_join (word_join x3 x2 : int16) (word_join x1 x0 : int16) : int32) : int64)) = - (word_join - (word_join - (word_join - (word_join - (word_join - (word_join - (word_join - (word_join - (word_join - (word_join - (word_join - (word_join - (word_join - (word_join - (word_join x15 x14:16 word) - x13:24 word) - x12:32 word) - x11:40 word) - x10:48 word) - x9:56 word) - x8:64 word) - x7:72 word) - x6:80 word) - x5:88 word) - x4:96 word) - x3:104 word) - x2:112 word) - x1:120 word) - x0:128 word)`;; - -let VAL_OF_BYTES_TO_INT128_EQ_NUM_OF_BYTELIST = prove( - `!x:byte list. LENGTH x = 16 ==> val (bytes_to_int128 x) = num_of_bytelist x`, +let SUB_LIST_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS = prove( + `!(i:num) (pt:byte list) (iv:int128) (key1:int128 list) (key2:int128 list). + (SUB_LIST (0,16 * i) + (aes256_xts_encrypt pt (16 * i + 16) iv key1 key2)) + = aes256_xts_encrypt pt (16 * i) iv key1 key2`, REPEAT STRIP_TAC THEN - (* conversion for breaking down a list *) - MP_TAC ((GEN_REWRITE_CONV I [LENGTH_EQ_LIST_OF_SEQ] THENC - RAND_CONV LIST_OF_SEQ_CONV) `LENGTH (x:byte list) = 16`) THEN - ASM_SIMP_TAC[] THEN - DISCH_THEN (fun th -> ONCE_REWRITE_TAC[th]) THEN - REWRITE_TAC[bytes_to_int128] THEN - REWRITE_TAC EL_16_8_CLAUSES THEN - REPEAT_N 16 (ONCE_REWRITE_TAC[num_of_bytelist]) THEN - REWRITE_TAC[CONJUNCT1 num_of_bytelist] THEN - MAP_EVERY ABBREV_TAC - [`x0 = EL 0 x:byte`; `x1 = EL 1 x:byte`; `x2 = EL 2 x:byte`; `x3 = EL 3 x:byte`; - `x4 = EL 4 x:byte`; `x5 = EL 5 x:byte`; `x6 = EL 6 x:byte`; `x7 = EL 7 x:byte`; - `x8 = EL 8 x:byte`; `x9 = EL 9 x:byte`; `x10 = EL 10 x:byte`; `x11 = EL 11 x:byte`; - `x12 = EL 12 x:byte`; `x13 = EL 13 x:byte`; `x14 = EL 14 x:byte`; `x15 = EL 15 x:byte`] THEN - CONV_TAC NUM_REDUCE_CONV THEN - REWRITE_TAC[ADD_0; WORD_JOIN_16_8_ASSOC] THEN - (* reduce RHS to LHS *) - SUBGOAL_THEN `val (x14:byte) + 0x100 * val (x15:byte) = val ((word_join x15 x14):int16)` SUBST1_TAC THENL - [ WORD_JOIN_BOUND_TAC `x15:byte` `x14:byte`; ALL_TAC] THEN ABBREV_TAC `y14:int16 = word_join (x15:byte) (x14:byte)` THEN - SUBGOAL_THEN `val (x13:byte) + 0x100 * val (y14:16 word) = val ((word_join y14 x13):24 word)` SUBST1_TAC THENL - [ WORD_JOIN_BOUND_TAC `y14:16 word` `x13:byte`; ALL_TAC] THEN ABBREV_TAC `y13:24 word = word_join (y14:16 word) (x13:byte)` THEN - SUBGOAL_THEN `val (x12:byte) + 0x100 * val (y13:24 word) = val ((word_join y13 x12):32 word)` SUBST1_TAC THENL - [ WORD_JOIN_BOUND_TAC `y13:24 word` `x12:byte`; ALL_TAC] THEN ABBREV_TAC `y12:32 word = word_join (y13:24 word) (x12:byte)` THEN - SUBGOAL_THEN `val (x11:byte) + 0x100 * val (y12:32 word) = val ((word_join y12 x11):40 word)` SUBST1_TAC THENL - [ WORD_JOIN_BOUND_TAC `y12:32 word` `x11:byte`; ALL_TAC] THEN ABBREV_TAC `y11:40 word = word_join (y12:32 word) (x11:byte)` THEN - SUBGOAL_THEN `val (x10:byte) + 0x100 * val (y11:40 word) = val ((word_join y11 x10):48 word)` SUBST1_TAC THENL - [ WORD_JOIN_BOUND_TAC `y11:40 word` `x10:byte`; ALL_TAC] THEN ABBREV_TAC `y10:48 word = word_join (y11:40 word) (x10:byte)` THEN - SUBGOAL_THEN `val (x9:byte) + 0x100 * val (y10:48 word) = val ((word_join y10 x9):56 word)` SUBST1_TAC THENL - [ WORD_JOIN_BOUND_TAC `y10:48 word` `x9:byte`; ALL_TAC] THEN ABBREV_TAC `y9:56 word = word_join (y10:48 word) (x9:byte)` THEN - SUBGOAL_THEN `val (x8:byte) + 0x100 * val (y9:56 word) = val ((word_join y9 x8):64 word)` SUBST1_TAC THENL - [ WORD_JOIN_BOUND_TAC `y9:56 word` `x8:byte`; ALL_TAC] THEN ABBREV_TAC `y8:64 word = word_join (y9:56 word) (x8:byte)` THEN - SUBGOAL_THEN `val (x7:byte) + 0x100 * val (y8:64 word) = val ((word_join y8 x7):72 word)` SUBST1_TAC THENL - [ WORD_JOIN_BOUND_TAC `y8:64 word` `x7:byte`; ALL_TAC] THEN ABBREV_TAC `y7:72 word = word_join (y8:64 word) (x7:byte)` THEN - SUBGOAL_THEN `val (x6:byte) + 0x100 * val (y7:72 word) = val ((word_join y7 x6):80 word)` SUBST1_TAC THENL - [ WORD_JOIN_BOUND_TAC `y7:72 word` `x6:byte`; ALL_TAC] THEN ABBREV_TAC `y6:80 word = word_join (y7:72 word) (x6:byte)` THEN - SUBGOAL_THEN `val (x5:byte) + 0x100 * val (y6:80 word) = val ((word_join y6 x5):88 word)` SUBST1_TAC THENL - [ WORD_JOIN_BOUND_TAC `y6:80 word` `x5:byte`; ALL_TAC] THEN ABBREV_TAC `y5:88 word = word_join (y6:80 word) (x5:byte)` THEN - SUBGOAL_THEN `val (x4:byte) + 0x100 * val (y5:88 word) = val ((word_join y5 x4):96 word)` SUBST1_TAC THENL - [ WORD_JOIN_BOUND_TAC `y5:88 word` `x4:byte`; ALL_TAC] THEN ABBREV_TAC `y4:96 word = word_join (y5:88 word) (x4:byte)` THEN - SUBGOAL_THEN `val (x3:byte) + 0x100 * val (y4:96 word) = val ((word_join y4 x3):104 word)` SUBST1_TAC THENL - [ WORD_JOIN_BOUND_TAC `y4:96 word` `x3:byte`; ALL_TAC] THEN ABBREV_TAC `y3:104 word = word_join (y4:96 word) (x3:byte)` THEN - SUBGOAL_THEN `val (x2:byte) + 0x100 * val (y3:104 word) = val ((word_join y3 x2):112 word)` SUBST1_TAC THENL - [ WORD_JOIN_BOUND_TAC `y3:104 word` `x2:byte`; ALL_TAC] THEN ABBREV_TAC `y2:112 word = word_join (y3:104 word) (x2:byte)` THEN - SUBGOAL_THEN `val (x1:byte) + 0x100 * val (y2:112 word) = val ((word_join y2 x1):120 word)` SUBST1_TAC THENL - [ WORD_JOIN_BOUND_TAC `y2:112 word` `x1:byte`; ALL_TAC] THEN ABBREV_TAC `y1:120 word = word_join (y2:112 word) (x1:byte)` THEN - SUBGOAL_THEN `val (x0:byte) + 0x100 * val (y1:120 word) = val ((word_join y1 x0):128 word)` SUBST1_TAC THENL - [ WORD_JOIN_BOUND_TAC `y1:120 word` `x0:byte`; ALL_TAC] THEN ABBREV_TAC `y0:128 word = word_join (y1:120 word) (x0:byte)` THEN - REFL_TAC -);; - -let READ_BYTES_AND_BYTE128_MERGE = prove( - `!(pt_ptr:int64) (sz:num) (x:byte list) (s:armstate). - sz + 16 <= LENGTH x ==> - read (memory :> bytes (pt_ptr,sz + 0x10)) s = num_of_bytelist (SUB_LIST (0, sz + 0x10) x) - ==> (read (memory :> bytes (pt_ptr, sz)) s = num_of_bytelist (SUB_LIST (0, sz) x) /\ - read (memory :> bytes128 (word_add pt_ptr (word sz))) s = bytes_to_int128 (SUB_LIST (sz, 0x10) x))`, - REPEAT GEN_TAC THEN - STRIP_TAC THEN - REWRITE_TAC[READ_MEMORY_BYTES128_BYTES] THEN - - SUBGOAL_THEN `sz <= LENGTH (x:byte list)` ASSUME_TAC THENL - [ UNDISCH_TAC `sz + 16 <= LENGTH (x:byte list)` THEN ARITH_TAC; ALL_TAC ] THEN - - SUBGOAL_THEN `16 <= LENGTH (x:byte list) - sz` ASSUME_TAC THENL - [ UNDISCH_TAC `sz + 16 <= LENGTH (x:byte list)` THEN ARITH_TAC; ALL_TAC ] THEN - - SUBGOAL_THEN `read (memory :> bytes (pt_ptr, sz + 16)) s = - read (memory :> bytes (pt_ptr, sz)) s + - 2 EXP (8 * sz) * (read (memory :> bytes (word_add pt_ptr (word sz), 16)) s)` SUBST1_TAC THENL - [ REWRITE_TAC[READ_COMPONENT_COMPOSE] THEN - REWRITE_TAC[READ_BYTES_COMBINE]; ALL_TAC] THEN - IMP_REWRITE_TAC[NUM_OF_BYTELIST_OF_SUB_LIST] THEN - REWRITE_TAC[READ_COMPONENT_COMPOSE] THEN - - DISCH_TAC THEN - CONJ_TAC THENL - [ (* First part: `read (bytes (pt_ptr,sz)) (read memory s) = - num_of_bytelist (SUB_LIST (0x0,sz) x)`*) - FIRST_X_ASSUM(MP_TAC o AP_TERM `\x. x MOD 2 EXP (8 * sz)`) THEN + (* when i = 0, trivial *) + ASM_CASES_TAC `i = 0` THENL + [ ASM_REWRITE_TAC[] THEN - REWRITE_TAC[MOD_MULT_ADD; MOD_LT] THEN - REWRITE_TAC[READ_BYTES_MOD; MIN] THEN - SIMP_TAC[ARITH_RULE `len <= len`] THEN - DISCH_TAC THEN - IMP_REWRITE_TAC[MOD_LT] THEN - MP_TAC (SPEC `(SUB_LIST (0,sz) x:byte list)` NUM_OF_BYTELIST_BOUND) THEN - IMP_REWRITE_TAC[LENGTH_SUB_LIST; SUB_0; MIN] THEN - SUBGOAL_THEN `256 EXP sz = 2 EXP (8 * sz)` SUBST1_TAC THENL - [ REWRITE_TAC[ARITH_RULE `256 = 2 EXP 8`; EXP_EXP]; ALL_TAC] THEN - SIMP_TAC[]; + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[CONJUNCT1 SUB_LIST; aes256_xts_encrypt] THEN + CONV_TAC NUM_REDUCE_CONV; ALL_TAC ] THEN - (* Second part: word (read (bytes (word_add pt_ptr (word sz),0x10)) (read memory s)) = - bytes_to_int128 (SUB_LIST (sz,0x10) x) *) - FIRST_X_ASSUM(MP_TAC o AP_TERM `\x. x DIV 2 EXP (8 * sz)`) THEN - ASM_REWRITE_TAC[] THEN - SUBGOAL_THEN `~(0x2 EXP (0x8 * sz) = 0x0)` ASSUME_TAC THENL - [ REWRITE_TAC[EXP_EQ_0; ARITH_EQ]; ALL_TAC] THEN - IMP_REWRITE_TAC[DIV_MULT_ADD] THEN - SUBGOAL_THEN `read (bytes (pt_ptr,sz)) (read memory s) < 0x2 EXP (0x8 * sz)` ASSUME_TAC THENL - [ REWRITE_TAC[READ_BYTES_BOUND]; ALL_TAC] THEN - SUBGOAL_THEN `num_of_bytelist (SUB_LIST (0x0,sz) x) < 0x2 EXP (0x8 * sz)` ASSUME_TAC THENL - [ MP_TAC (SPEC `(SUB_LIST (0,sz) x:byte list)` NUM_OF_BYTELIST_BOUND) THEN - IMP_REWRITE_TAC[LENGTH_SUB_LIST; SUB_0; MIN] THEN - SUBGOAL_THEN `256 EXP sz = 2 EXP (8 * sz)` SUBST1_TAC THENL - [ REWRITE_TAC[ARITH_RULE `256 = 2 EXP 8`; EXP_EXP]; ALL_TAC] THEN SIMP_TAC[]; ALL_TAC] THEN - IMP_REWRITE_TAC[DIV_LT; ADD] THEN - DISCH_TAC THEN - - ONCE_REWRITE_TAC[GSYM VAL_EQ] THEN - IMP_REWRITE_TAC[VAL_OF_BYTES_TO_INT128_EQ_NUM_OF_BYTELIST] THEN - REWRITE_TAC[LENGTH_SUB_LIST; MIN] THEN ASM_SIMP_TAC[] THEN - REWRITE_TAC[VAL_WORD; DIMINDEX_128] THEN - SUBGOAL_THEN `num_of_bytelist (SUB_LIST (sz,0x10) x) < 2 EXP 0x80` ASSUME_TAC THENL - [ MP_TAC (SPEC `(SUB_LIST (sz,0x10) x:byte list)` NUM_OF_BYTELIST_BOUND) THEN - IMP_REWRITE_TAC[LENGTH_SUB_LIST; SUB_0; MIN] THEN - ARITH_TAC; ALL_TAC] THEN - IMP_REWRITE_TAC[MOD_LT] - );; - -let READ_BYTES_AND_BYTE128_SPLIT = prove( - `!(pt_ptr:int64) (sz:num) (x:byte list) (s:armstate). - sz + 16 <= LENGTH x ==> - read (memory :> bytes128 (word_add pt_ptr (word sz))) s = bytes_to_int128 (SUB_LIST (sz, 0x10) x) - /\ read (memory :> bytes (pt_ptr, sz)) s = num_of_bytelist (SUB_LIST (0, sz) x) - ==> read (memory :> bytes (pt_ptr,sz + 0x10)) s = num_of_bytelist (SUB_LIST (0, sz + 0x10) x)`, - REWRITE_TAC[READ_MEMORY_BYTES128_BYTES] THEN - REPEAT STRIP_TAC THEN - - SUBGOAL_THEN `sz <= LENGTH (x:byte list)` ASSUME_TAC THENL - [ UNDISCH_TAC `sz + 16 <= LENGTH (x:byte list)` THEN ARITH_TAC; ALL_TAC ] THEN - - SUBGOAL_THEN `16 <= LENGTH (x:byte list) - sz` ASSUME_TAC THENL - [ UNDISCH_TAC `sz + 16 <= LENGTH (x:byte list)` THEN ARITH_TAC; ALL_TAC ] THEN - - SUBGOAL_THEN `read (memory :> bytes (pt_ptr, sz + 16)) s = - read (memory :> bytes (pt_ptr, sz)) s + - 2 EXP (8 * sz) * (read (memory :> bytes (word_add pt_ptr (word sz), 16)) s)` SUBST1_TAC THENL - [ REWRITE_TAC[READ_COMPONENT_COMPOSE] THEN - REWRITE_TAC[READ_BYTES_COMBINE]; ALL_TAC] THEN - ASM_REWRITE_TAC[] THEN - SUBGOAL_THEN `read (memory :> bytes (word_add pt_ptr (word sz),0x10)) s = - val (bytes_to_int128 (SUB_LIST (sz,0x10) x))` SUBST1_TAC THENL - [ UNDISCH_THEN - `word (read (memory :> bytes (word_add (pt_ptr:int64) (word sz),0x10)) s) = - bytes_to_int128 (SUB_LIST (sz,0x10) x)` - (fun th -> MP_TAC (AP_TERM `val:int128->num` th)) THEN - IMP_REWRITE_TAC[VAL_WORD] THEN - SUBGOAL_THEN `read (memory :> bytes (word_add pt_ptr (word sz),0x10)) s < 2 EXP dimindex (:128)` ASSUME_TAC THENL - [ SIMP_TAC[MEMORY_BYTES_BOUND] ; ALL_TAC] THEN - SUBST_ALL_TAC DIMINDEX_128 THEN - ASM_SIMP_TAC[MOD_LT]; ALL_TAC] THEN - - IMP_REWRITE_TAC[NUM_OF_BYTELIST_OF_SUB_LIST] THEN - IMP_REWRITE_TAC[VAL_OF_BYTES_TO_INT128_EQ_NUM_OF_BYTELIST] THEN - REWRITE_TAC[LENGTH_SUB_LIST; MIN] THEN ASM_SIMP_TAC[] - );; - -let SUB_LIST_APPEND_RIGHT_LEMMA = prove( - `!(x:A list) y n m. LENGTH x = n ==> SUB_LIST (n,m) (APPEND x y) = SUB_LIST (0,m) y`, - LIST_INDUCT_TAC THENL - [ REPEAT GEN_TAC THEN - SIMP_TAC[CONJUNCT1 LENGTH; APPEND; SUB_LIST_CLAUSES]; - - ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN - INDUCT_TAC THENL[ - SIMP_TAC[LENGTH_EQ_NIL] THEN REWRITE_TAC[APPEND]; - ASM_SIMP_TAC[APPEND; LENGTH; SUB_LIST_CLAUSES; SUC_INJ]]]);; - -let SUB_LIST_APPEND_RIGHT_GENERAL = prove( - `!(x:A list) y n m p. LENGTH x = p ==> n >= p ==> - SUB_LIST (n,m) (APPEND x y) = SUB_LIST (n - p,m) y`, - LIST_INDUCT_TAC THENL + (* when i = 1, using aes256_xts_encrypt_tail *) + ASM_CASES_TAC `i = 1` THENL [ - REPEAT GEN_TAC THEN - SIMP_TAC[CONJUNCT1 LENGTH; APPEND; SUB_LIST_CLAUSES] THEN - DISCH_THEN (fun th -> REWRITE_TAC[GSYM th]) THEN - REWRITE_TAC[SUB_0]; - - ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN - INDUCT_TAC THENL - [ - REPEAT STRIP_TAC THEN - SUBGOAL_THEN `p = 0` SUBST_ALL_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN - CONV_TAC NUM_REDUCE_CONV THEN - SUBGOAL_THEN `CONS h t = ([]:A list)` ASSUME_TAC THENL - [ UNDISCH_TAC `LENGTH (CONS h (t:A list)) = 0` THEN - SIMP_TAC[LENGTH_EQ_NIL]; ALL_TAC] THEN - ASM_REWRITE_TAC[] THEN - REWRITE_TAC[APPEND]; - - REPEAT STRIP_TAC THEN - SUBGOAL_THEN `p > 0` ASSUME_TAC THENL - [ UNDISCH_TAC `LENGTH (CONS h (t:A list)) = p` THEN - ASM_REWRITE_TAC[LENGTH] THEN - MP_TAC (SPEC `LENGTH (t:A list)` (ARITH_RULE `!x. SUC x > 0`)) THEN - ARITH_TAC; ALL_TAC] THEN - SUBGOAL_THEN `LENGTH (t:A list) = p - 1` ASSUME_TAC THENL - [ UNDISCH_TAC `LENGTH (CONS h (t:A list)) = p` THEN - ASM_REWRITE_TAC[LENGTH] THEN - MP_TAC (SPECL [`LENGTH (t:A list)`; `p:num`] (ARITH_RULE `!n m. SUC n = m ==> n = m - 1`)) THEN - SIMP_TAC[]; ALL_TAC] THEN - SUBGOAL_THEN `n >= p - 1` ASSUME_TAC THENL - [ MP_TAC (ARITH_RULE `SUC n >= p /\ p > 0 ==> n >= p - 1`) THEN - ASM_ARITH_TAC; ALL_TAC] THEN - SUBGOAL_THEN `SUC n - p = n - (p - 1)` ASSUME_TAC THENL - [ MP_TAC (ARITH_RULE `SUC n >= p /\ p > 0 ==> SUC n - p = n - (p - 1)`) THEN - ASM_ARITH_TAC; ALL_TAC] THEN - ASM_REWRITE_TAC[APPEND; LENGTH; SUB_LIST_CLAUSES; SUC_INJ] THEN - FIRST_X_ASSUM (fun th -> MP_TAC (SPECL [`y:A list`; `n:num`; `m:num`; `(p-1):num`] th)) THEN - ASM_SIMP_TAC[] - ] - ] -);; - -let SUB_LIST_LENGTH_IMPLIES = prove( - `!(l:A list) n. LENGTH l = n ==> SUB_LIST(0,n) l = l`, - REPEAT STRIP_TAC THEN - UNDISCH_THEN `LENGTH (l:A list) = n` (fun th -> REWRITE_TAC[GSYM th]) THEN - REWRITE_TAC[SUB_LIST_LENGTH] -);; - -let SUB_LIST_IDEMPOTENT_P = prove( - `!p n (l:(A)list). SUB_LIST (0,n) (SUB_LIST (p,n) l) = SUB_LIST (p,n) l`, - INDUCT_TAC THENL[ - REWRITE_TAC[SUB_LIST_IDEMPOTENT]; - - REPEAT STRIP_TAC THEN - DISJ_CASES_TAC (ISPEC `l:(A)list` list_CASES) THENL [ - ASM_REWRITE_TAC[] THEN REWRITE_TAC[SUB_LIST_CLAUSES]; - ALL_TAC - ] THEN - FIRST_X_ASSUM MP_TAC THEN STRIP_TAC THEN - ASM_REWRITE_TAC[] THEN REWRITE_TAC[SUB_LIST_CLAUSES] THEN - ASM_REWRITE_TAC[] - ] -);; - - -let SUB_LIST_MIN_RIGHT = prove( - `!p (l:(A)list) (n:num) m. SUB_LIST (0,n) (SUB_LIST (p,m) l) = SUB_LIST (p, MIN n m) l`, - REPEAT STRIP_TAC THEN - ASM_CASES_TAC `(m:num) <= n` THENL [ - FIRST_X_ASSUM MP_TAC THEN REWRITE_TAC[LE_EXISTS] THEN - STRIP_TAC THEN ASM_REWRITE_TAC[] THEN - REWRITE_TAC[SUB_LIST_SPLIT;ADD_CLAUSES;ARITH_RULE`MIN ((x:num)+y) x = x`] THEN - REWRITE_TAC[SUB_LIST_IDEMPOTENT_P] THEN - GEN_REWRITE_TAC RAND_CONV [GSYM APPEND_NIL] THEN - AP_TERM_TAC THEN MATCH_MP_TAC SUB_LIST_TRIVIAL THEN - REWRITE_TAC[LENGTH_SUB_LIST] THEN ARITH_TAC; ALL_TAC] THEN - - IMP_REWRITE_TAC[ARITH_RULE `~(m <= n) ==> MIN n m = n`] THEN - FIRST_X_ASSUM MP_TAC THEN REWRITE_TAC[NOT_LE;LT_EXISTS] THEN - STRIP_TAC THEN ASM_REWRITE_TAC[] THEN - REWRITE_TAC[SUB_LIST_SPLIT;ADD_CLAUSES;ARITH_RULE`MIN (x:num) (x+y) = x`] THEN - - MP_TAC (ISPECL [`l:A list`; `p:num`; `n:num`] LENGTH_SUB_LIST) THEN - ASM_CASES_TAC `n <= LENGTH (l:A list) - p` THENL [ - IMP_REWRITE_TAC[ARITH_RULE `!n m. n <= m ==> MIN n m = n`] THEN + ASM_REWRITE_TAC[] THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[aes256_xts_encrypt] THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + CONV_TAC NUM_REDUCE_CONV THEN + MP_TAC (SPECL [`pt:byte list`; `iv:int128`; `key1: int128 list`; `key2: int128 list`] + LENGTH_OF_AES256_XTS_ENCRYPT_REC_TRIVIAL) THEN DISCH_TAC THEN IMP_REWRITE_TAC[SUB_LIST_APPEND_LEFT] THEN + CONV_TAC NUM_REDUCE_CONV THEN IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN - ARITH_TAC; ALL_TAC + REWRITE_TAC[AES256_XTS_ENCRYPT_REC_EQ_TAIL_TRIVIAL]; + ALL_TAC ] THEN - IMP_REWRITE_TAC[ARITH_RULE `!n m. ~(n <= m) ==> MIN n m = m`] THEN - SUBGOAL_THEN `SUB_LIST (p + n,SUC d) (l:A list) = []` SUBST1_TAC THENL - [ MATCH_MP_TAC SUB_LIST_TRIVIAL THEN - ASM_ARITH_TAC; ALL_TAC] THEN - REWRITE_TAC[APPEND_NIL] THEN - REWRITE_TAC[SUB_LIST_IDEMPOTENT_P] -);; - -let SUB_LIST_MIN_LEFT = prove( - `!q (l:A list) n m. - SUB_LIST (q,n) (SUB_LIST (0,m) l) = SUB_LIST (q, MIN n (m - q)) l`, - REPEAT STRIP_TAC THEN - ASM_CASES_TAC `n <= m - q` THENL [ - IMP_REWRITE_TAC[ARITH_RULE `x <= y ==> MIN x y = x`] THEN - UNDISCH_TAC `n <= m - q` THEN - MAP_EVERY SPEC1_TAC [`n:num`; `l:A list`; `q:num`; `m:num`] THEN - (* Induct over m *) - INDUCT_TAC THENL - [ - REPEAT STRIP_TAC THEN - IMP_REWRITE_TAC[ARITH_RULE `n <= 0 - q ==> n = 0`] THEN - REWRITE_TAC[SUB_LIST_CLAUSES]; - - INDUCT_TAC THENL - [ - REWRITE_TAC[SUB_0] THEN - REPEAT STRIP_TAC THEN - MP_TAC (SPECL [`0:num`; `l:A list`; `n:num`; `SUC m:num`] SUB_LIST_MIN_RIGHT) THEN - IMP_REWRITE_TAC[ARITH_RULE `x <= y ==> MIN x y = x`]; - - LIST_INDUCT_TAC THENL[ - REWRITE_TAC[SUB_LIST_CLAUSES]; - REWRITE_TAC[SUB_LIST_CLAUSES] THEN - REPEAT STRIP_TAC THEN - FIRST_X_ASSUM - (fun th -> MP_TAC - (SPECL [`q:num`; `t:A list`; `n:num`] th)) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN - SIMP_TAC[] - ] - ] - ]; ALL_TAC - ] THEN - - (* Case n > m - q*) - IMP_REWRITE_TAC[ARITH_RULE `~(x <= y) ==> MIN x y = y`] THEN - UNDISCH_TAC `~(n <= m - q)` THEN - MAP_EVERY SPEC1_TAC [`n:num`; `l:A list`; `q:num`; `m:num`] THEN - INDUCT_TAC THENL - [ - REPEAT STRIP_TAC THEN - REWRITE_TAC[ARITH_RULE `0 - q = 0`] THEN - REWRITE_TAC[SUB_LIST_CLAUSES]; - - INDUCT_TAC THENL - [ - REWRITE_TAC[SUB_0] THEN - REPEAT STRIP_TAC THEN - MP_TAC (SPECL [`0:num`; `l:A list`; `n:num`; `SUC m:num`] SUB_LIST_MIN_RIGHT) THEN - IMP_REWRITE_TAC[ARITH_RULE `~(x <= y) ==> MIN x y = y`]; - - LIST_INDUCT_TAC THENL[ - REWRITE_TAC[SUB_LIST_CLAUSES]; - REWRITE_TAC[SUB_LIST_CLAUSES] THEN - REPEAT STRIP_TAC THEN - REWRITE_TAC[ARITH_RULE `SUC m - SUC q = m - q`] THEN - FIRST_X_ASSUM - (fun th -> MP_TAC - (SPECL [`q:num`; `t:A list`; `n:num`] th)) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN - SIMP_TAC[] - ] - ] - ] + (* when i >= 2, using aes256_xts_encrypt_rec *) + REWRITE_TAC[aes256_xts_encrypt] THEN + CONV_TAC NUM_REDUCE_CONV THEN + SUBGOAL_THEN `~(0x10 * i < 0x10)` ASSUME_TAC THENL + [ ASM_ARITH_TAC ; ALL_TAC] THEN + SUBGOAL_THEN `~(0x10 * i + 0x10 < 0x10)` ASSUME_TAC THENL + [ ASM_ARITH_TAC ; ALL_TAC] THEN + ASM_SIMP_TAC[] THEN + REWRITE_TAC[ARITH_RULE `16 * i + 16 = 16 * (i + 1)`; MOD_MULT] THEN + IMP_REWRITE_TAC[LET_DEF;LET_END_DEF;SUB_0;DIV_MULT] THEN + CONV_TAC NUM_REDUCE_CONV THEN + SUBGOAL_THEN `~(i < 0x2)` ASSUME_TAC THENL + [ ASM_ARITH_TAC ; ALL_TAC] THEN + SUBGOAL_THEN `~(i + 1 < 0x2)` ASSUME_TAC THENL + [ ASM_ARITH_TAC ; ALL_TAC] THEN + ASM_SIMP_TAC[ARITH_RULE `(i + 0x1) - 0x2 = i - 1`; ADD_SUB] THEN + SUBGOAL_THEN `LENGTH (aes256_xts_encrypt_rec 0x0 (i - 0x1) pt iv key1 key2) = 16 * i` ASSUME_TAC THENL + [ REWRITE_TAC[LENGTH_OF_AES256_XTS_ENCRYPT_REC] THEN + ASM_ARITH_TAC; ALL_TAC] THEN + IMP_REWRITE_TAC[SUB_LIST_APPEND_LEFT; SUB_LIST_LENGTH_IMPLIES] THEN + CONJ_TAC THENL [ALL_TAC; ARITH_TAC] THEN + SUBGOAL_THEN `i - 1 = i - 2 + 1` ASSUME_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC ] THEN + ASM_REWRITE_TAC[] THEN + IMP_REWRITE_TAC[AES256_XTS_ENCRYPT_REC_EQ_TAIL] THEN + ASM_ARITH_TAC );; -let SUB_LIST_MIN_GENERAL = prove( - `!p q (l:(A)list) (n:num) m. - SUB_LIST (q,n) (SUB_LIST (p,m) l) = SUB_LIST (p + q, MIN n (m - q)) l`, +let SUB_LIST_OF_AES256_XTS_ENCRYPT = prove( + `!(i:num) (tail_len:num) (pt:byte list) (iv:int128) (key1:int128 list) (key2:int128 list). + ~(tail_len = 0) /\ tail_len < 16 ==> + (SUB_LIST (0,16 * i) + (aes256_xts_encrypt pt (16 * i + 16 + tail_len) iv key1 key2)) + = aes256_xts_encrypt pt (16 * i) iv key1 key2`, REPEAT STRIP_TAC THEN - (* Case n <= m - q *) - ASM_CASES_TAC `n <= m - q` THENL [ - IMP_REWRITE_TAC[ARITH_RULE `x <= y ==> MIN x y = x`] THEN - (* Induct over p *) - UNDISCH_TAC `n <= m - q` THEN - MAP_EVERY SPEC1_TAC [`m:num`; `n:num`; `l:A list`; `q:num`; `p:num`] THEN - INDUCT_TAC THENL - [ - REWRITE_TAC[ADD] THEN - REPEAT STRIP_TAC THEN - MP_TAC (SPECL [`q:num`; `l:A list`; `n:num`; `m:num`] SUB_LIST_MIN_LEFT) THEN - IMP_REWRITE_TAC[ARITH_RULE `x <= y ==> MIN x y = x`]; - ALL_TAC - ] THEN - - ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN - LIST_INDUCT_TAC THENL[ - REWRITE_TAC[SUB_LIST_CLAUSES]; - REWRITE_TAC[ARITH_RULE `SUC p + q = SUC (p + q)`] THEN - REWRITE_TAC[SUB_LIST_CLAUSES] THEN - ASM_REWRITE_TAC[] - ]; ALL_TAC - ] THEN - - (* Case n > m - q*) - IMP_REWRITE_TAC[ARITH_RULE `~(x <= y) ==> MIN x y = y`] THEN - UNDISCH_TAC `~(n <= m - q)` THEN - MAP_EVERY SPEC1_TAC [`m:num`; `n:num`; `l:A list`; `q:num`; `p:num`] THEN - INDUCT_TAC THENL + (* Case 1: i = 0 *) + ASM_CASES_TAC `i = 0` THENL [ - REWRITE_TAC[ADD] THEN - REPEAT STRIP_TAC THEN - MP_TAC (SPECL [`q:num`; `l:A list`; `n:num`; `m:num`] SUB_LIST_MIN_LEFT) THEN - IMP_REWRITE_TAC[ARITH_RULE `~(x <= y) ==> MIN x y = y`]; + ASM_REWRITE_TAC[] THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[ADD; SUB_LIST_CLAUSES; aes256_xts_encrypt] THEN + CONV_TAC NUM_REDUCE_CONV; ALL_TAC ] THEN - - ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN - LIST_INDUCT_TAC THENL[ - REWRITE_TAC[SUB_LIST_CLAUSES]; - REWRITE_TAC[ARITH_RULE `SUC p + q = SUC (p + q)`] THEN - REWRITE_TAC[SUB_LIST_CLAUSES] THEN - ASM_REWRITE_TAC[] - ] -);; - -let UDIV_OPT_THM = prove(`!n:num. n < 0x2 EXP 0x40 - ==> (word (val ((word ((n * 0xcccccccccccccccd) DIV 0x2 EXP 0x40)):int64) DIV 0x2 EXP 0x6)):int64 = word (n DIV 0x50)`, - REPEAT STRIP_TAC THEN - REWRITE_TAC[VAL_WORD; DIMINDEX_64] THEN - SUBGOAL_THEN `!p n:num. ~(p = 0) /\ n < p * p ==> n DIV p MOD p = n DIV p` - (MP_TAC o SPECL [`0x2 EXP 0x40`; `n * 0xcccccccccccccccd`]) THENL - [ REPEAT STRIP_TAC THEN - REWRITE_TAC[DIV_MOD] THEN - AP_THM_TAC THEN AP_TERM_TAC THEN - MATCH_MP_TAC MOD_LT THEN - ASM_ARITH_TAC; ALL_TAC] THEN - ANTS_TAC THENL [ASM_ARITH_TAC;ALL_TAC] THEN - DISCH_TAC THEN ASM_REWRITE_TAC[] THEN - AP_TERM_TAC THEN ASM_ARITH_TAC);; - -let LENGTH_OF_INT128_TO_BYTES = prove( - `!x. LENGTH(int128_to_bytes x) = 16`, - STRIP_TAC THEN - REWRITE_TAC[int128_to_bytes] THEN - REWRITE_TAC[LENGTH] THEN - CONV_TAC NUM_REDUCE_CONV -);; - -let SUB_LIST_OF_INT128_TO_BYTES = prove( - `!x. SUB_LIST (0, 16) (int128_to_bytes x) = int128_to_bytes x`, - GEN_TAC THEN - MP_TAC (SPEC `x:int128` LENGTH_OF_INT128_TO_BYTES) THEN - DISCH_TAC THEN - IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] -);; - -let ELEM_TAC i = - CONV_TAC (RAND_CONV (REWRITE_CONV [num_CONV i])) THEN - REWRITE_TAC[bytelist_of_num] THEN - REWRITE_TAC[CONS_11] THEN - CONJ_TAC THENL [ - REWRITE_TAC[word_subword] THEN - AP_TERM_TAC THEN - (ARITH_TAC ORELSE - ( ASM_REWRITE_TAC[CONJUNCT1 EXP; DIV_1; DIV_DIV] THEN - CONV_TAC NUM_REDUCE_CONV)); ALL_TAC];; - -let INT128_TO_BYTES_EQ_BYTELIST_OF_NUM = prove( - `!x. int128_to_bytes x = bytelist_of_num 16 (val x)`, - GEN_TAC THEN - REWRITE_TAC[int128_to_bytes] THEN - - MAP_EVERY (fun i -> ELEM_TAC (mk_numeral (num i))) (List.rev (2 -- 16)) THEN - CONV_TAC (RAND_CONV (REWRITE_CONV [num_CONV `1`])) THEN - REWRITE_TAC[bytelist_of_num] THEN - REWRITE_TAC[CONS_11] THEN - REWRITE_TAC[word_subword] THEN - AP_TERM_TAC THEN - ASM_REWRITE_TAC[DIV_DIV] THEN - CONV_TAC NUM_REDUCE_CONV -);; - -let NUM_OF_BYTELIST_OF_INT128_TO_BYTES = prove( - `!x. num_of_bytelist (int128_to_bytes x) = val x`, - GEN_TAC THEN - REWRITE_TAC[INT128_TO_BYTES_EQ_BYTELIST_OF_NUM] THEN - REWRITE_TAC[NUM_OF_BYTELIST_OF_NUM] THEN - SUBGOAL_THEN `val (x:int128) < 2 EXP 128` ASSUME_TAC THENL - [ MP_TAC (ISPEC `x:int128` VAL_BOUND) THEN - REWRITE_TAC[DIMINDEX_128] THEN - ARITH_TAC; ALL_TAC + (* Case 2: i = 1 *) + ASM_CASES_TAC `i = 1` THENL + [ + ASM_REWRITE_TAC[] THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[aes256_xts_encrypt; ADD_ASSOC] THEN + CONV_TAC NUM_REDUCE_CONV THEN + SUBGOAL_THEN `~(0x20 + tail_len < 0x10)` ASSUME_TAC THENL [ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[] THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + CONV_TAC NUM_REDUCE_CONV THEN + SUBGOAL_THEN `(0x20 + tail_len) MOD 0x10 = tail_len` ASSUME_TAC THENL + [ ASM_SIMP_TAC[ARITH_RULE `32 = 2 * 16`; MOD_MULT_ADD] THEN + IMP_REWRITE_TAC[MOD_LT] + ; ALL_TAC] THEN + SUBGOAL_THEN `((0x20 + tail_len) - (0x20 + tail_len) MOD 0x10) DIV 0x10 = 0x2` ASSUME_TAC THENL + [ ASM_REWRITE_TAC[ADD_ASSOC; ADD_SUB] THEN + ARITH_TAC ; ALL_TAC] THEN + ASM_SIMP_TAC[] THEN + CONV_TAC NUM_REDUCE_CONV THEN + ASM_REWRITE_TAC[] THEN + MP_TAC (SPECL [`pt:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] LENGTH_OF_AES256_XTS_ENCRYPT_REC_TRIVIAL) THEN + DISCH_TAC THEN IMP_REWRITE_TAC[SUB_LIST_APPEND_LEFT] THEN + REWRITE_TAC[AES256_XTS_ENCRYPT_REC_EQ_TAIL_TRIVIAL] THEN + MP_TAC (SPECL [`pt:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] LENGTH_OF_AES256_XTS_ENCRYPT_TAIL_TRIVIAL) THEN + DISCH_TAC THEN IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN + ARITH_TAC; + ALL_TAC ] THEN - IMP_REWRITE_TAC[MOD_LT] THEN - ASM_ARITH_TAC -);; - -let CALCULATE_TWEAK_EXPAND = prove( - `!x iv key. - GF_128_mult_by_primitive (calculate_tweak x iv key) = - calculate_tweak (x + 0x1) iv key`, - REPEAT GEN_TAC THEN - REWRITE_TAC[ARITH_RULE `x + 1 = SUC x`] THEN - CONV_TAC (RAND_CONV (REWRITE_CONV[CONJUNCT2 calculate_tweak])) THEN - REFL_TAC -);; - -let DIVISION_BY_80_LEMMA = prove( - `!(a:num) b. a DIV 0x50 = b /\ - 0x10 divides a /\ - ~(a - b * 0x50 = 0x10) /\ - ~(a - b * 0x50 = 0x20) /\ - ~(a - b * 0x50 = 0x30) /\ - ~(a - b * 0x50 = 0x40) ==> - b * 0x50 = a`, - REPEAT STRIP_TAC THEN - (* Use the division theorem: a = b * 0x50 + (a MOD 0x50) *) - MP_TAC (SPECL [`a:num`; `0x50`] DIVISION) THEN - CONV_TAC NUM_REDUCE_CONV THEN - REPEAT STRIP_TAC THEN - (* We have a = b * 0x50 + (a MOD 0x50) and a DIV 0x50 = b *) - SUBGOAL_THEN `a = b * 0x50 + (a MOD 0x50)` ASSUME_TAC THENL [ - ASM_ARITH_TAC; ALL_TAC] THEN - - (* Show that a MOD 0x50 = 0 by case analysis *) - SUBGOAL_THEN `a MOD 0x50 = 0` ASSUME_TAC THENL [ - (* Since 0x10 divides a, we know a = k * 0x10 for some k *) - UNDISCH_TAC `0x10 divides a` THEN - REWRITE_TAC[divides] THEN - STRIP_TAC THEN - - (* The remainder a MOD 0x50 must be a multiple of 0x10 and < 0x50 *) - (* So it's one of: 0, 0x10, 0x20, 0x30, 0x40 *) - SUBGOAL_THEN `(a MOD 0x50 = 0) \/ (a MOD 0x50 = 0x10) \/ - (a MOD 0x50 = 0x20) \/ (a MOD 0x50 = 0x30) \/ - (a MOD 0x50 = 0x40)` ASSUME_TAC THENL - [ ASM_REWRITE_TAC[] THEN - - SUBGOAL_THEN `(0x10 * x) MOD 0x50 = (x MOD 5) * 0x10` SUBST1_TAC THENL [ - SUBGOAL_THEN `0x50 = 5 * 0x10` SUBST1_TAC THENL [ - CONV_TAC NUM_REDUCE_CONV; ALL_TAC] THEN - MP_TAC (SPECL [`0x10 * x`; `0x10`; `5`] MOD_MULT_MOD) THEN - REWRITE_TAC[MOD_MULT; ADD_CLAUSES] THEN - IMP_REWRITE_TAC[DIV_MULT] THEN - CONV_TAC NUM_REDUCE_CONV THEN - SIMP_TAC[] THEN DISCH_TAC THEN - REWRITE_TAC[MULT_SYM] - ; ALL_TAC] THEN - - SUBGOAL_THEN `x MOD 5 < 5` ASSUME_TAC THENL [ - REWRITE_TAC[MOD_LT_EQ] THEN CONV_TAC NUM_REDUCE_CONV; ALL_TAC] THEN - SUBGOAL_THEN `x MOD 5 = 0 \/ x MOD 5 = 1 \/ x MOD 5 = 2 \/ x MOD 5 = 3 \/ x MOD 5 = 4` ASSUME_TAC THENL [ - UNDISCH_TAC `x MOD 0x5 < 0x5` THEN ARITH_TAC ; ALL_TAC] THEN - - REPEAT (FIRST_X_ASSUM DISJ_CASES_TAC) THENL - [ ASM_REWRITE_TAC[] THEN CONV_TAC NUM_REDUCE_CONV; - ASM_REWRITE_TAC[] THEN CONV_TAC NUM_REDUCE_CONV; - ASM_REWRITE_TAC[] THEN CONV_TAC NUM_REDUCE_CONV; - ASM_REWRITE_TAC[] THEN CONV_TAC NUM_REDUCE_CONV; - ASM_REWRITE_TAC[] THEN CONV_TAC NUM_REDUCE_CONV] + (* Case 3: i >= 2 *) + ASM_CASES_TAC `i >= 2` THENL + [ + ASM_REWRITE_TAC[ADD_ASSOC] THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[aes256_xts_encrypt] THEN + SUBGOAL_THEN `~(0x10 * i < 0x10)` ASSUME_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `~((0x10 * i + 0x10) + tail_len < 0x10)` ASSUME_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[LET_DEF; LET_END_DEF] THEN + SUBGOAL_THEN `((0x10 * i + 0x10) + tail_len) MOD 0x10 = tail_len` SUBST1_TAC THENL + [ REWRITE_TAC[ARITH_RULE `0x10 * i + 0x10 = 16 * (i + 1)`] THEN + IMP_REWRITE_TAC[MOD_MULT_ADD; MOD_LT] ; ALL_TAC] THEN - - (* Now eliminate the non-zero cases using the assumptions *) - SUBGOAL_THEN `~(a MOD 0x50 = 0x10)` ASSUME_TAC THENL - [ UNDISCH_TAC `~(a - b * 0x50 = 0x10)` THEN - UNDISCH_TAC `a = b * 0x50 + a MOD 0x50` THEN - ARITH_TAC; ALL_TAC] THEN - SUBGOAL_THEN `~(a MOD 0x50 = 0x20)` ASSUME_TAC THENL - [ UNDISCH_TAC `~(a - b * 0x50 = 0x20)` THEN - UNDISCH_TAC `a = b * 0x50 + a MOD 0x50` THEN - ARITH_TAC; ALL_TAC] THEN - SUBGOAL_THEN `~(a MOD 0x50 = 0x30)` ASSUME_TAC THENL - [ UNDISCH_TAC `~(a - b * 0x50 = 0x30)` THEN - UNDISCH_TAC `a = b * 0x50 + a MOD 0x50` THEN - ARITH_TAC; ALL_TAC] THEN - SUBGOAL_THEN `~(a MOD 0x50 = 0x40)` ASSUME_TAC THENL - [ UNDISCH_TAC `~(a - b * 0x50 = 0x40)` THEN - UNDISCH_TAC `a = b * 0x50 + a MOD 0x50` THEN - ARITH_TAC; ALL_TAC] THEN - - ASM_MESON_TAC[]; ALL_TAC + REWRITE_TAC[ADD_SUB; MOD_MULT; SUB_0; + ARITH_RULE `0x10 * i + 0x10 = 16 * (i + 1)`] THEN + IMP_REWRITE_TAC[DIV_MULT] THEN + SUBGOAL_THEN `~(i + 1 < 2)` ASSUME_TAC THENL [ ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `~(i < 2)` ASSUME_TAC THENL [ ASM_ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[ADD_SUB; ARITH_RULE `(i + 1) - 2 = i - 1`] THEN + CONV_TAC NUM_REDUCE_CONV THEN + MP_TAC (SPECL [`0:num`; `(i - 1):num`; `pt:byte list`; `iv:int128`; + `key1:int128 list`; `key2:int128 list`] LENGTH_OF_AES256_XTS_ENCRYPT_REC) THEN + SUBGOAL_THEN `~((i - 1) < 0)` ASSUME_TAC THENL [ ASM_ARITH_TAC; ALL_TAC] THEN + IMP_REWRITE_TAC[ARITH_RULE `i >= 2 ==> i - 0x1 - 0x0 + 0x1 = i`] THEN + IMP_REWRITE_TAC[SUB_LIST_APPEND_LEFT] THEN + SIMP_TAC[ARITH_RULE `16 * i <= i * 16`] THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN + SIMP_TAC[ARITH_RULE `i * 16 = 16 * i`] THEN + DISCH_TAC THEN + MP_TAC (SPECL [`0`; `(i-2):num`; `pt:byte list`; `iv:int128`; + `key1:int128 list`; `key2:int128 list`] AES256_XTS_ENCRYPT_REC_EQ_TAIL) THEN + ANTS_TAC THENL [ ASM_ARITH_TAC; ALL_TAC ] THEN + IMP_REWRITE_TAC[ARITH_RULE `i >= 2 ==> i - 0x2 + 0x1 = i - 1`]; + ALL_TAC ] THEN - (* Finally conclude b * 0x50 = a *) ASM_ARITH_TAC );; -let WORD_AND_MASK16 = prove( - `word_and (len:int64) (word 0xfffffffffffffff0) = word_sub len (word_and len (word 0xf))`, - BITBLAST_TAC -);; - - -let WORD_AND_MASK16_EQ_0 = prove( - `!(x:int64). val x < 16 ==> ~(val x = 0x0) ==> ~(val (word_and x (word 0xf)) = 0x0)`, - BITBLAST_TAC);; - -(* Same as Decrypt proof with a different name *) -let LEN_FULL_BLOCKS_TO_VAL = prove( - `!(len:int64). word_and len (word 0xfffffffffffffff0) = word (16 * (val len DIV 16))`, - GEN_TAC THEN - REWRITE_TAC[WORD_AND_MASK16] THEN - REWRITE_TAC[GSYM VAL_EQ] THEN - SUBGOAL_THEN `16 * val (len:int64) DIV 16 = val len - (val len MOD 16)` SUBST1_TAC THENL - [REWRITE_TAC[DIVISION_SIMP] THEN ARITH_TAC; ALL_TAC] THEN - REWRITE_TAC[ARITH_RULE `0xf = 2 EXP 4 - 1`] THEN - REWRITE_TAC[WORD_AND_MASK_WORD] THEN - CONV_TAC NUM_REDUCE_CONV THEN - - REWRITE_TAC[VAL_WORD_SUB] THEN - SUBGOAL_THEN `val (len:int64) >= val ((word (val len MOD 0x10)):int64)` ASSUME_TAC THENL [ - REWRITE_TAC[VAL_WORD; DIMINDEX_64; GE] THEN - MP_TAC (SPECL [`val (len:int64) MOD 0x10`; `0x2 EXP 0x40`] MOD_LE) THEN - ARITH_TAC; - ALL_TAC - ] THEN - REWRITE_TAC[VAL_WORD; DIMINDEX_64] THEN - - SUBGOAL_THEN `val (len:int64) MOD 0x10 < 0x2 EXP 0x40` ASSUME_TAC THENL - [ TRANS_TAC LET_TRANS `val (len:int64)` THEN - REWRITE_TAC[VAL_BOUND_64; MOD_LE]; ALL_TAC] THEN - - SUBGOAL_THEN `val (len:int64) MOD 0x10 MOD 0x2 EXP 0x40 = val len MOD 0x10` ASSUME_TAC THENL - [ MP_TAC (SPECL [`val (len:int64) MOD 0x10`; `0x2 EXP 0x40`] MOD_LT) THEN - ASM_SIMP_TAC[]; ALL_TAC] THEN - ASM_REWRITE_TAC[] THEN - - MP_TAC (SPECL [`val (len:int64)`; `0x2 EXP 0x40`; `val (len:int64) MOD 0x10`] - (ARITH_RULE `!a b c. c <= a ==> c <= b ==> a + b - c = (a - c) + b`)) THEN - ANTS_TAC THENL [ REWRITE_TAC[MOD_LE]; ALL_TAC] THEN - ANTS_TAC THENL [ ASM_ARITH_TAC; ALL_TAC] THEN - ASM_SIMP_TAC[] THEN DISCH_TAC THEN - - MP_TAC (SPECL [`1`; `0x2 EXP 0x40`; `val (len:int64) - val len MOD 0x10`] - (CONJUNCT1 (CONJUNCT2 (CONJUNCT2 MOD_MULT_ADD)))) THEN - CONV_TAC NUM_REDUCE_CONV - );; - -let BREAK_ONE_BLOCK_INTO_BYTES = prove( - `!(addr:int64) (s:armstate) (p:int128). - read (memory :> bytes128 addr) s = p <=> - (read (memory :> bytes8 addr) s = EL 0 (int128_to_bytes p) /\ - read (memory :> bytes8 (word_add addr (word 1))) s = EL 1 (int128_to_bytes p) /\ - read (memory :> bytes8 (word_add addr (word 2))) s = EL 2 (int128_to_bytes p) /\ - read (memory :> bytes8 (word_add addr (word 3))) s = EL 3 (int128_to_bytes p) /\ - read (memory :> bytes8 (word_add addr (word 4))) s = EL 4 (int128_to_bytes p) /\ - read (memory :> bytes8 (word_add addr (word 5))) s = EL 5 (int128_to_bytes p) /\ - read (memory :> bytes8 (word_add addr (word 6))) s = EL 6 (int128_to_bytes p) /\ - read (memory :> bytes8 (word_add addr (word 7))) s = EL 7 (int128_to_bytes p) /\ - read (memory :> bytes8 (word_add addr (word 8))) s = EL 8 (int128_to_bytes p) /\ - read (memory :> bytes8 (word_add addr (word 9))) s = EL 9 (int128_to_bytes p) /\ - read (memory :> bytes8 (word_add addr (word 10))) s = EL 10 (int128_to_bytes p) /\ - read (memory :> bytes8 (word_add addr (word 11))) s = EL 11 (int128_to_bytes p) /\ - read (memory :> bytes8 (word_add addr (word 12))) s = EL 12 (int128_to_bytes p) /\ - read (memory :> bytes8 (word_add addr (word 13))) s = EL 13 (int128_to_bytes p) /\ - read (memory :> bytes8 (word_add addr (word 14))) s = EL 14 (int128_to_bytes p) /\ - read (memory :> bytes8 (word_add addr (word 15))) s = EL 15 (int128_to_bytes p)) - `, - REPEAT GEN_TAC THEN - EQ_TAC THENL[ - STRIP_TAC THEN - MP_TAC (SPECL [`0:num`; `addr:int64`; `s:armstate`] BYTES128_TO_BYTES8_THM) THEN - REWRITE_TAC[WORD_ADD_0] THEN CONV_TAC NUM_REDUCE_CONV THEN - ASM_REWRITE_TAC[] THEN - DISCH_TAC THEN - REWRITE_TAC[int128_to_bytes] THEN - REWRITE_TAC EL_16_8_CLAUSES THEN - ASM_REWRITE_TAC[] THEN - REWRITE_TAC[bytes_to_int128] THEN - REWRITE_TAC EL_16_8_CLAUSES THEN - REWRITE_TAC[WORD_ADD_0] THEN - ABBREV_TAC `x0 = read (memory :> bytes8 (addr:int64)) s` THEN - ABBREV_TAC `x1 = read (memory :> bytes8 (word_add (addr:int64) (word 0x1))) s` THEN - ABBREV_TAC `x2 = read (memory :> bytes8 (word_add (addr:int64) (word 0x2))) s` THEN - ABBREV_TAC `x3 = read (memory :> bytes8 (word_add (addr:int64) (word 0x3))) s` THEN - ABBREV_TAC `x4 = read (memory :> bytes8 (word_add (addr:int64) (word 0x4))) s` THEN - ABBREV_TAC `x5 = read (memory :> bytes8 (word_add (addr:int64) (word 0x5))) s` THEN - ABBREV_TAC `x6 = read (memory :> bytes8 (word_add (addr:int64) (word 0x6))) s` THEN - ABBREV_TAC `x7 = read (memory :> bytes8 (word_add (addr:int64) (word 0x7))) s` THEN - ABBREV_TAC `x8 = read (memory :> bytes8 (word_add (addr:int64) (word 0x8))) s` THEN - ABBREV_TAC `x9 = read (memory :> bytes8 (word_add (addr:int64) (word 0x9))) s` THEN - ABBREV_TAC `xa = read (memory :> bytes8 (word_add (addr:int64) (word 0xa))) s` THEN - ABBREV_TAC `xb = read (memory :> bytes8 (word_add (addr:int64) (word 0xb))) s` THEN - ABBREV_TAC `xc = read (memory :> bytes8 (word_add (addr:int64) (word 0xc))) s` THEN - ABBREV_TAC `xd = read (memory :> bytes8 (word_add (addr:int64) (word 0xd))) s` THEN - ABBREV_TAC `xe = read (memory :> bytes8 (word_add (addr:int64) (word 0xe))) s` THEN - ABBREV_TAC `xf = read (memory :> bytes8 (word_add (addr:int64) (word 0xf))) s` THEN - REPEAT STRIP_TAC THEN - REPEAT BITBLAST_TAC; ALL_TAC] THEN - +let READ_BYTES_EQ_READ_BYTE128_1BLOCK_ENC = prove( + `!(ptr:int64) (ct:byte list) (iv:int128) (key1:int128 list) (key2:int128 list) s. + (read (memory :> bytes128 pt_ptr) s = + aes256_xts_encrypt_round (bytes_to_int128 (SUB_LIST (0x0,0x10) ct)) + (calculate_tweak 0x0 iv key2) + key1) ==> + read (memory :> bytes (pt_ptr,0x10)) s = + num_of_bytelist (SUB_LIST (0x0,0x10) (aes256_xts_encrypt ct 0x10 iv key1 key2))`, REPEAT STRIP_TAC THEN - MP_TAC (SPECL [`0:num`; `addr:int64`; `s:armstate`] BYTES128_TO_BYTES8_THM) THEN - CONV_TAC NUM_REDUCE_CONV THEN REWRITE_TAC[WORD_ADD_0] THEN + REWRITE_TAC[READ_MEMORY_BYTES_BYTES128] THEN ASM_REWRITE_TAC[] THEN - DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN - REWRITE_TAC[int128_to_bytes] THEN - REWRITE_TAC EL_16_8_CLAUSES THEN - REWRITE_TAC[bytes_to_int128] THEN - REWRITE_TAC EL_16_8_CLAUSES THEN - BITBLAST_TAC + REWRITE_TAC[aes256_xts_encrypt] THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[aes256_xts_encrypt_tail] THEN + REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[SUB_LIST_OF_INT128_TO_BYTES] THEN + REWRITE_TAC[NUM_OF_BYTELIST_OF_INT128_TO_BYTES] );; -let SELECT_ONE_BYTE_FROM_BLOCK = prove( - `!(addr:int64) (off:int64) (s:armstate) (p:int128). - read (memory :> bytes128 addr) s = p ==> - val off < 16 ==> - read (memory :> bytes8 (word_add addr off)) s = EL (val off) (int128_to_bytes p)`, +let READ_BYTES_EQ_READ_BYTE128_2BLOCKS_ENC = prove( + `!(ptr:int64) (ct:byte list) (iv:int128) (key1:int128 list) (key2:int128 list) s. + (read (memory :> bytes128 pt_ptr) s = + aes256_xts_encrypt_round (bytes_to_int128 (SUB_LIST (0x0,0x10) ct)) + (calculate_tweak 0x0 iv key2) + key1) ==> + (read (memory :> bytes128 (word_add pt_ptr (word 0x10))) s = + aes256_xts_encrypt_round (bytes_to_int128 (SUB_LIST (0x10,0x10) ct)) + (calculate_tweak 0x1 iv key2) + key1) ==> + read (memory :> bytes (pt_ptr,0x20)) s = + num_of_bytelist (SUB_LIST (0x0,0x20) (aes256_xts_encrypt ct 0x20 iv key1 key2))`, REPEAT STRIP_TAC THEN - FIRST_ASSUM (STRIP_ASSUME_TAC o - MATCH_MP (fst (EQ_IMP_RULE - (SPECL [`addr:int64`; `s:armstate`; `p:int128`] BREAK_ONE_BLOCK_INTO_BYTES)))) THEN - SUBGOAL_THEN `word_add addr (off:int64) = word_add addr (word (val off))` SUBST1_TAC THENL - [REWRITE_TAC[WORD_VAL]; ALL_TAC] THEN - UNDISCH_TAC `val (off:int64) < 16` THEN - SPEC_TAC (`val (off:int64)`, `n:num`) THEN - CONV_TAC EXPAND_CASES_CONV THEN - ASM_REWRITE_TAC[WORD_ADD_0] -);; + IMP_REWRITE_TAC[ARITH_RULE `0x20 = 0x10 + 0x10`; READ_BYTES_AND_BYTE128_SPLIT] THEN + EXISTS_TAC `aes256_xts_encrypt ct 0x20 iv key1 key2` THEN + REPEAT CONJ_TAC THENL + [ + CONV_TAC NUM_REDUCE_CONV; -let SELECT_ONE_BYTE_FROM_FORALL = prove( - `!(ptr:int64) (len:int64) (addr:int64) (bl:byte list) (s:armstate). - (forall j. j < val len ==> read (memory :> bytes8 (word_add ptr (word j))) s = EL j bl) ==> - val addr < val len ==> - LENGTH bl = val len ==> - read (memory :> bytes8 (word_add ptr addr)) s = EL (val addr) bl`, - REPEAT STRIP_TAC THEN - FIRST_X_ASSUM (MP_TAC o SPEC `val (addr:int64)`) THEN - ASM_REWRITE_TAC[] THEN - REWRITE_TAC[WORD_VAL] -);; + MP_TAC (SPECL [`2:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + LENGTH_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS) THEN + ARITH_TAC; -let IVAL_WORD_LT = prove( - `!i. i < 2 EXP 63 ==> ival ((word i):int64) = &i`, - GEN_TAC THEN DISCH_TAC THEN - REWRITE_TAC[ival; DIMINDEX_64; ARITH_RULE `64 - 1 = 63`] THEN - REWRITE_TAC[VAL_WORD; DIMINDEX_64] THEN - SUBGOAL_THEN `i < 2 EXP 64` ASSUME_TAC THENL - [ TRANS_TAC LT_TRANS `2 EXP 63` THEN - ASM_REWRITE_TAC[] THEN + REWRITE_TAC[aes256_xts_encrypt] THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + CONV_TAC NUM_REDUCE_CONV THEN + MP_TAC (SPECL [`ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + LENGTH_OF_AES256_XTS_ENCRYPT_REC_TRIVIAL) THEN + IMP_REWRITE_TAC[SUB_LIST_APPEND_RIGHT_LEMMA] THEN DISCH_TAC THEN + REWRITE_TAC[aes256_xts_encrypt_tail] THEN + REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + REWRITE_TAC[SUB_LIST_OF_INT128_TO_BYTES] THEN + REWRITE_TAC[NUM_OF_BYTELIST_OF_INT128_TO_BYTES] THEN + REWRITE_TAC[BYTES_TO_INT128_OF_INT128_TO_BYTES] THEN CONV_TAC NUM_REDUCE_CONV; - ALL_TAC] THEN - ASM_SIMP_TAC[MOD_LT] -);; -(* ********************************************************** *) -(* Properties that we prove about the specification functions *) -(* Similar to the Decrypt ones but specified for Encrypt *) + MP_TAC (SPECL [`1:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + SUB_LIST_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS) THEN + CONV_TAC NUM_REDUCE_CONV THEN + SIMP_TAC[] THEN DISCH_TAC THEN + IMP_REWRITE_TAC[READ_BYTES_EQ_READ_BYTE128_1BLOCK_ENC] THEN + MP_TAC (SPECL [`1:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + LENGTH_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS) THEN + CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] + ] +);; -let LENGTH_OF_AES256_XTS_ENCRYPT_REC = prove( - `!(i:num) (m:num) (P:byte list) (iv:int128) (key1:int128 list) (key2:int128 list). - LENGTH(aes256_xts_encrypt_rec i m P iv key1 key2) = (if m < i then 0 else (m - i + 1) * 0x10)`, - REPEAT GEN_TAC THEN - (* Wellfounded induction with measure (m + 1) - i - Note that the parentheses are essential because of the precedence of + and - *) - WF_INDUCT_TAC `(m + 1) - i` THEN - ONCE_REWRITE_TAC[aes256_xts_encrypt_rec] THEN - COND_CASES_TAC THENL - [ SIMP_TAC[LENGTH_EQ_NIL]; - SIMP_TAC[] THEN - REWRITE_TAC[LET_DEF; LET_END_DEF] THEN - REWRITE_TAC[LENGTH_APPEND] THEN - SUBGOAL_THEN `~(m < i) ==> (m + 1) - (i + 1) < (m + 1) - i` ASSUME_TAC THENL - [ ASM_ARITH_TAC ; ALL_TAC ] THEN - ASM_SIMP_TAC[] THEN - REWRITE_TAC[LENGTH_OF_INT128_TO_BYTES] THEN - COND_CASES_TAC THENL - [ASM_ARITH_TAC; ASM_ARITH_TAC]] -);; - -let LENGTH_OF_FST_OF_ENC_CIPHER_STEALING = prove( - `!(block:byte list) (tail:byte list) (tail_len:num) - (iv:int128) (i:num) (key1:int128 list) (key2:int128 list). - LENGTH (FST (cipher_stealing_encrypt block tail tail_len iv i key1 key2)) = 16`, - REPEAT STRIP_TAC THEN - REWRITE_TAC[cipher_stealing_encrypt] THEN - ASM_REWRITE_TAC[LET_DEF; LET_END_DEF] THEN - REWRITE_TAC[LENGTH_OF_INT128_TO_BYTES] -);; - -let LENGTH_OF_SND_OF_ENC_CIPHER_STEALING = prove( - `!(block:byte list) (tail:byte list) (tail_len:num) - (iv:int128) (i:num) (key1:int128 list) (key2:int128 list). - LENGTH (SND (cipher_stealing_encrypt block tail tail_len iv i key1 key2)) = MIN tail_len 16`, - REPEAT STRIP_TAC THEN - REWRITE_TAC[cipher_stealing_encrypt] THEN - ASM_REWRITE_TAC[LET_DEF; LET_END_DEF] THEN - REWRITE_TAC[LENGTH_SUB_LIST] THEN - REWRITE_TAC[LENGTH_OF_INT128_TO_BYTES] THEN - REWRITE_TAC[MIN] THEN - CONV_TAC NUM_REDUCE_CONV -);; - -let LENGTH_OF_AES256_XTS_ENCRYPT_TAIL = prove( - `! (i:num) (tail_len:num) (P:byte list) (iv:int128) (key1:int128 list) (key2:int128 list). - LENGTH(aes256_xts_encrypt_tail i tail_len P iv key1 key2) = 0x10 + MIN tail_len 16`, +let READ_BYTES_EQ_READ_BYTE128_3BLOCKS_ENC = prove( + `!(ptr:int64) (ct:byte list) (iv:int128) (key1:int128 list) (key2:int128 list) s. + (read (memory :> bytes128 pt_ptr) s = + aes256_xts_encrypt_round (bytes_to_int128 (SUB_LIST (0x0,0x10) ct)) + (calculate_tweak 0x0 iv key2) + key1) ==> + (read (memory :> bytes128 (word_add pt_ptr (word 0x10))) s = + aes256_xts_encrypt_round (bytes_to_int128 (SUB_LIST (0x10,0x10) ct)) + (calculate_tweak 0x1 iv key2) + key1) ==> + (read (memory :> bytes128 (word_add pt_ptr (word 0x20))) s = + aes256_xts_encrypt_round (bytes_to_int128 (SUB_LIST (0x20,0x10) ct)) + (calculate_tweak 0x2 iv key2) + key1) ==> + read (memory :> bytes (pt_ptr,0x30)) s = + num_of_bytelist (SUB_LIST (0x0,0x30) (aes256_xts_encrypt ct 0x30 iv key1 key2))`, REPEAT STRIP_TAC THEN - REWRITE_TAC[aes256_xts_encrypt_tail] THEN - COND_CASES_TAC THENL [ - ASM_REWRITE_TAC[LET_DEF; LET_END_DEF] THEN - REWRITE_TAC[LENGTH_OF_INT128_TO_BYTES] THEN - REWRITE_TAC[ADD_CLAUSES; MIN] THEN + IMP_REWRITE_TAC[ARITH_RULE `0x30 = 0x20 + 0x10`; READ_BYTES_AND_BYTE128_SPLIT] THEN + EXISTS_TAC `aes256_xts_encrypt ct 0x30 iv key1 key2` THEN + REPEAT CONJ_TAC THENL + [ CONV_TAC NUM_REDUCE_CONV; - REWRITE_TAC[LET_DEF; LET_END_DEF; LENGTH_APPEND] THEN - REWRITE_TAC[LENGTH_OF_FST_OF_ENC_CIPHER_STEALING] THEN - REWRITE_TAC[LENGTH_OF_SND_OF_ENC_CIPHER_STEALING]] -);; - -let LENGTH_OF_AES256_XTS_ENCRYPT_REC_TRIVIAL = prove( - `!(pt:byte list) (iv:int128) (key1:int128 list) (key2:int128 list). - LENGTH (aes256_xts_encrypt_rec 0x0 0x0 pt iv key1 key2) = 16`, - REPEAT STRIP_TAC THEN - REWRITE_TAC[LENGTH_OF_AES256_XTS_ENCRYPT_REC] THEN - CONV_TAC NUM_REDUCE_CONV -);; - -let LENGTH_OF_AES256_XTS_ENCRYPT_TAIL_TRIVIAL = prove( - `!(pt:byte list) (iv:int128) (key1:int128 list) (key2:int128 list). - LENGTH(aes256_xts_encrypt_tail 0 0 pt iv key1 key2) = 16`, - REPEAT STRIP_TAC THEN - REWRITE_TAC[LENGTH_OF_AES256_XTS_ENCRYPT_TAIL] THEN - CONV_TAC NUM_REDUCE_CONV -);; - -let AES256_XTS_ENCRYPT_REC_EQ_TAIL_TRIVIAL = prove( - `!(pt:byte list) (iv:int128) (key1:int128 list) (key2:int128 list). - aes256_xts_encrypt_rec 0x0 0x0 ct iv key1 key2 = - aes256_xts_encrypt_tail 0x0 0x0 ct iv key1 key2`, - REPEAT STRIP_TAC THEN - ONCE_REWRITE_TAC[aes256_xts_encrypt_rec] THEN - CONV_TAC NUM_REDUCE_CONV THEN - REWRITE_TAC[LET_DEF; LET_END_DEF] THEN - ONCE_REWRITE_TAC[aes256_xts_encrypt_rec] THEN - CONV_TAC NUM_REDUCE_CONV THEN - REWRITE_TAC[APPEND_NIL] THEN - - REWRITE_TAC[aes256_xts_encrypt_tail] THEN - REWRITE_TAC[LET_DEF; LET_END_DEF] THEN - CONV_TAC NUM_REDUCE_CONV -);; + MP_TAC (SPECL [`3:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + LENGTH_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS) THEN + ARITH_TAC; -let LENGTH_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS = prove( - `! (i:num) (pt:byte list) (iv:int128) (key1:int128 list) (key2:int128 list). - LENGTH(aes256_xts_encrypt pt (0x10 * i) iv key1 key2) = 0x10 * i`, - REPEAT STRIP_TAC THEN - SPEC_TAC (`i:num`, `i:num`) THEN - INDUCT_TAC THENL - [ - CONV_TAC NUM_REDUCE_CONV THEN REWRITE_TAC[aes256_xts_encrypt] THEN CONV_TAC NUM_REDUCE_CONV THEN - REWRITE_TAC[LENGTH_EQ_NIL]; - ALL_TAC] THEN - - REWRITE_TAC[ADD1; LEFT_ADD_DISTRIB] THEN - CONV_TAC NUM_REDUCE_CONV THEN - REWRITE_TAC[aes256_xts_encrypt] THEN - - ASM_CASES_TAC `i = 0` THENL - [ ASM_SIMP_TAC[] THEN + REWRITE_TAC[LET_DEF; LET_END_DEF] THEN CONV_TAC NUM_REDUCE_CONV THEN - IMP_REWRITE_TAC[LET_DEF;LET_END_DEF;SUB_0] THEN + MP_TAC (SPECL [`0:num`; `1:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + LENGTH_OF_AES256_XTS_ENCRYPT_REC) THEN CONV_TAC NUM_REDUCE_CONV THEN - REWRITE_TAC[LENGTH_OF_AES256_XTS_ENCRYPT_TAIL_TRIVIAL] - ; ALL_TAC - ] THEN + IMP_REWRITE_TAC[SUB_LIST_APPEND_RIGHT_LEMMA] THEN DISCH_TAC THEN + REWRITE_TAC[aes256_xts_encrypt_tail] THEN + REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + REWRITE_TAC[SUB_LIST_OF_INT128_TO_BYTES] THEN + REWRITE_TAC[NUM_OF_BYTELIST_OF_INT128_TO_BYTES] THEN + REWRITE_TAC[BYTES_TO_INT128_OF_INT128_TO_BYTES] THEN + CONV_TAC NUM_REDUCE_CONV; + ALL_TAC] THEN - SUBGOAL_THEN `~(0x10 * i + 0x10 < 0x10)` ASSUME_TAC THENL - [ ASM_ARITH_TAC; ALL_TAC ] THEN ASM_SIMP_TAC[] THEN - REWRITE_TAC[ARITH_RULE `0x10 * i + 0x10 = 0x10 * (i + 1)`; MOD_MULT] THEN - IMP_REWRITE_TAC[LET_DEF; LET_END_DEF;SUB_0;DIV_MULT] THEN - CONJ_TAC THENL [ALL_TAC; ARITH_TAC] THEN - SUBGOAL_THEN `~(i + 0x1 < 0x2)` ASSUME_TAC THENL - [ ASM_ARITH_TAC; ALL_TAC] THEN ASM_SIMP_TAC[] THEN - REWRITE_TAC[LENGTH_APPEND] THEN - REWRITE_TAC[LENGTH_OF_AES256_XTS_ENCRYPT_REC] THEN - REWRITE_TAC[LENGTH_OF_AES256_XTS_ENCRYPT_TAIL] THEN + MP_TAC (SPECL [`2:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + SUB_LIST_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS) THEN CONV_TAC NUM_REDUCE_CONV THEN - ASM_ARITH_TAC + SIMP_TAC[] THEN DISCH_TAC THEN + IMP_REWRITE_TAC[READ_BYTES_EQ_READ_BYTE128_2BLOCKS_ENC] THEN + MP_TAC (SPECL [`2:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + LENGTH_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS) THEN + CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] );; -let LENGTH_OF_AES256_XTS_ENCRYPT = prove( - `! (i:num) (tail_len:num) (pt:byte list) (iv:int128) (key1:int128 list) (key2:int128 list). - ~(tail_len = 0) /\ tail_len < 16 ==> - LENGTH(aes256_xts_encrypt pt (16 * i + 16 + tail_len) iv key1 key2) = 16 * i + 16 + tail_len`, +let READ_BYTES_EQ_READ_BYTE128_4BLOCKS_ENC = prove( + `!(ptr:int64) (ct:byte list) (iv:int128) (key1:int128 list) (key2:int128 list) s. + (read (memory :> bytes128 pt_ptr) s = + aes256_xts_encrypt_round (bytes_to_int128 (SUB_LIST (0x0,0x10) ct)) + (calculate_tweak 0x0 iv key2) + key1) ==> + (read (memory :> bytes128 (word_add pt_ptr (word 0x10))) s = + aes256_xts_encrypt_round (bytes_to_int128 (SUB_LIST (0x10,0x10) ct)) + (calculate_tweak 0x1 iv key2) + key1) ==> + (read (memory :> bytes128 (word_add pt_ptr (word 0x20))) s = + aes256_xts_encrypt_round (bytes_to_int128 (SUB_LIST (0x20,0x10) ct)) + (calculate_tweak 0x2 iv key2) + key1) ==> + (read (memory :> bytes128 (word_add pt_ptr (word 0x30))) s = + aes256_xts_encrypt_round (bytes_to_int128 (SUB_LIST (0x30,0x10) ct)) + (calculate_tweak 0x3 iv key2) + key1) ==> + read (memory :> bytes (pt_ptr,0x40)) s = + num_of_bytelist (SUB_LIST (0x0,0x40) (aes256_xts_encrypt ct 0x40 iv key1 key2))`, REPEAT STRIP_TAC THEN - (* Case 1: i = 0 *) - ASM_CASES_TAC `i = 0` THENL + IMP_REWRITE_TAC[ARITH_RULE `0x40 = 0x30 + 0x10`; READ_BYTES_AND_BYTE128_SPLIT] THEN + EXISTS_TAC `aes256_xts_encrypt ct 0x40 iv key1 key2` THEN + REPEAT CONJ_TAC THENL [ - ASM_SIMP_TAC[ADD_ASSOC] THEN - CONV_TAC NUM_REDUCE_CONV THEN + CONV_TAC NUM_REDUCE_CONV; + + MP_TAC (SPECL [`4:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + LENGTH_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS) THEN + ARITH_TAC; + REWRITE_TAC[aes256_xts_encrypt] THEN - SUBGOAL_THEN `~(0x10 + tail_len < 0x10)` ASSUME_TAC THENL - [ ASM_ARITH_TAC; ALL_TAC] THEN - SUBGOAL_THEN `(0x10 + tail_len) MOD 0x10 = tail_len` ASSUME_TAC THENL - [ REWRITE_TAC[ARITH_RULE `0x10 + tail_len = 1 * 16 + tail_len`] THEN - IMP_REWRITE_TAC[MOD_MULT_ADD; MOD_LT]; ALL_TAC] THEN - ASM_SIMP_TAC[] THEN + CONV_TAC NUM_REDUCE_CONV THEN REWRITE_TAC[LET_DEF; LET_END_DEF] THEN - SUBGOAL_THEN `((0x10 + tail_len) - tail_len) DIV 0x10 = 1` SUBST1_TAC THENL - [ ASM_ARITH_TAC; ALL_TAC ] THEN CONV_TAC NUM_REDUCE_CONV THEN - REWRITE_TAC[LENGTH_OF_AES256_XTS_ENCRYPT_TAIL] THEN - ASM_ARITH_TAC; - ALL_TAC - ] THEN - - (* Case 2: i >= 1 *) - ASM_CASES_TAC `i >= 1` THENL - [ - REWRITE_TAC[aes256_xts_encrypt] THEN - SUBGOAL_THEN `(0x10 * i + 0x10 + tail_len) MOD 0x10 = tail_len` SUBST1_TAC THENL - [ REWRITE_TAC[ADD_ASSOC; ARITH_RULE `0x10 * i + 0x10 = 16 * (i + 1)`] THEN - IMP_REWRITE_TAC[MOD_MULT_ADD; MOD_LT]; ALL_TAC] THEN - SUBGOAL_THEN `~(0x10 * i + 0x10 + tail_len < 0x10)` ASSUME_TAC THENL - [ ASM_ARITH_TAC; ALL_TAC] THEN - ASM_SIMP_TAC[] THEN + MP_TAC (SPECL [`0:num`; `2:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + LENGTH_OF_AES256_XTS_ENCRYPT_REC) THEN + CONV_TAC NUM_REDUCE_CONV THEN + IMP_REWRITE_TAC[SUB_LIST_APPEND_RIGHT_LEMMA] THEN DISCH_TAC THEN + REWRITE_TAC[aes256_xts_encrypt_tail] THEN REWRITE_TAC[LET_DEF; LET_END_DEF] THEN - SUBGOAL_THEN `((0x10 * i + 0x10 + tail_len) - tail_len) DIV 0x10 = i + 1` SUBST1_TAC THENL - [ REWRITE_TAC[ARITH_RULE `(0x10 * i + 0x10 + tail_len) - tail_len = 16 * (i + 1)`] THEN - IMP_REWRITE_TAC[DIV_MULT] THEN - ARITH_TAC; ALL_TAC] THEN - SUBGOAL_THEN `~(i + 1 < 2)` ASSUME_TAC THENL - [ ASM_ARITH_TAC; ALL_TAC] THEN - ASM_SIMP_TAC[] THEN - IMP_REWRITE_TAC[ARITH_RULE `(i + 1) - 2 = i - 1`; ADD_SUB] THEN - REWRITE_TAC[LENGTH_APPEND] THEN - IMP_REWRITE_TAC[LENGTH_OF_AES256_XTS_ENCRYPT_REC] THEN - IMP_REWRITE_TAC[LENGTH_OF_AES256_XTS_ENCRYPT_TAIL] THEN - ASM_ARITH_TAC; - ALL_TAC - ] THEN + REWRITE_TAC[SUB_LIST_OF_INT128_TO_BYTES] THEN + REWRITE_TAC[BYTES_TO_INT128_OF_INT128_TO_BYTES] THEN + CONV_TAC NUM_REDUCE_CONV; + ALL_TAC] THEN - ASM_ARITH_TAC + MP_TAC (SPECL [`3:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + SUB_LIST_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS) THEN + CONV_TAC NUM_REDUCE_CONV THEN + SIMP_TAC[] THEN DISCH_TAC THEN + IMP_REWRITE_TAC[READ_BYTES_EQ_READ_BYTE128_3BLOCKS_ENC] THEN + MP_TAC (SPECL [`3:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] + LENGTH_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS) THEN + CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] );; -let BYTES_TO_INT128_OF_INT128_TO_BYTES = prove( - `!x. bytes_to_int128 (int128_to_bytes x) = x`, - GEN_TAC THEN - REWRITE_TAC[int128_to_bytes; bytes_to_int128] THEN - REWRITE_TAC EL_16_8_CLAUSES THEN - BITBLAST_TAC -);; -let AES256_XTS_ENCRYPT_TAIL_WHEN_1BLOCK = prove( - `!(n:num) (pt:byte list) (iv:int128) (key1:int128 list) (key2:int128 list). - bytes_to_int128 - (aes256_xts_encrypt_tail n 0x0 pt iv key1 key2) = - aes256_xts_encrypt_round - (bytes_to_int128 (SUB_LIST (n * 0x10,0x10) pt)) - (calculate_tweak n iv key2) key1`, - REPEAT STRIP_TAC THEN - REWRITE_TAC[aes256_xts_encrypt_tail] THEN - REWRITE_TAC[LET_DEF; LET_END_DEF] THEN - REWRITE_TAC[BYTES_TO_INT128_OF_INT128_TO_BYTES] -);; - -let AES256_XTS_ENCRYPT_REC_EQ_TAIL = prove( - `!(i:num) (k:num) (pt:byte list) (iv:int128) (key1:int128 list) (key2:int128 list). - k >= i ==> - aes256_xts_encrypt_rec i (k + 1) pt iv key1 key2 = - APPEND (aes256_xts_encrypt_rec i k pt iv key1 key2) - (aes256_xts_encrypt_tail (k + 1) 0x0 pt iv key1 key2)`, - REPEAT GEN_TAC THEN - WF_INDUCT_TAC `(k + 1) - i` THEN - STRIP_TAC THEN - GEN_REWRITE_TAC (RATOR_CONV o ONCE_DEPTH_CONV) [aes256_xts_encrypt_rec] THEN - SUBGOAL_THEN `~(k + 0x1 < i)` ASSUME_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN - ASM_SIMP_TAC[] THEN - REWRITE_TAC[LET_DEF; LET_END_DEF] THEN - SUBGOAL_THEN `(k + 1) - (i + 1) < (k + 1) - i` ASSUME_TAC THENL [ ASM_ARITH_TAC; ALL_TAC] THEN - FIRST_X_ASSUM (MP_TAC o SPECL [`k:num`; `i + 1:num`]) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN - ASM_CASES_TAC `k >= i + 1` THENL - [ - ASM_SIMP_TAC[] THEN DISCH_TAC THEN - REWRITE_TAC[APPEND_ASSOC] THEN - AP_THM_TAC THEN - GEN_REWRITE_TAC (RAND_CONV o ONCE_DEPTH_CONV) [aes256_xts_encrypt_rec] THEN - SUBGOAL_THEN `~(k < i)` ASSUME_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN - ASM_SIMP_TAC[] THEN - REWRITE_TAC[LET_DEF; LET_END_DEF]; ALL_TAC - ] THEN - SUBGOAL_THEN `k:num = i` ASSUME_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN - STRIP_TAC THEN ASM_REWRITE_TAC[] THEN - ONCE_REWRITE_TAC[aes256_xts_encrypt_rec] THEN - REWRITE_TAC[LT_REFL; LET_DEF; LET_END_DEF] THEN - ONCE_REWRITE_TAC[aes256_xts_encrypt_rec] THEN - REWRITE_TAC[ARITH_RULE `i < i + 1`; APPEND_NIL] THEN - AP_TERM_TAC THEN - REWRITE_TAC[aes256_xts_encrypt_tail; LET_DEF; LET_END_DEF] -);; - -let SUB_LIST_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS = prove( - `!(i:num) (pt:byte list) (iv:int128) (key1:int128 list) (key2:int128 list). - (SUB_LIST (0,16 * i) - (aes256_xts_encrypt pt (16 * i + 16) iv key1 key2)) - = aes256_xts_encrypt pt (16 * i) iv key1 key2`, - REPEAT STRIP_TAC THEN - - (* when i = 0, trivial *) - ASM_CASES_TAC `i = 0` THENL - [ - ASM_REWRITE_TAC[] THEN - CONV_TAC NUM_REDUCE_CONV THEN - REWRITE_TAC[CONJUNCT1 SUB_LIST; aes256_xts_encrypt] THEN - CONV_TAC NUM_REDUCE_CONV; - ALL_TAC - ] THEN - - (* when i = 1, using aes256_xts_encrypt_tail *) - ASM_CASES_TAC `i = 1` THENL - [ - ASM_REWRITE_TAC[] THEN - CONV_TAC NUM_REDUCE_CONV THEN - REWRITE_TAC[aes256_xts_encrypt] THEN - CONV_TAC NUM_REDUCE_CONV THEN - REWRITE_TAC[LET_DEF; LET_END_DEF] THEN - CONV_TAC NUM_REDUCE_CONV THEN - MP_TAC (SPECL [`pt:byte list`; `iv:int128`; `key1: int128 list`; `key2: int128 list`] - LENGTH_OF_AES256_XTS_ENCRYPT_REC_TRIVIAL) THEN - DISCH_TAC THEN - IMP_REWRITE_TAC[SUB_LIST_APPEND_LEFT] THEN - CONV_TAC NUM_REDUCE_CONV THEN - IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN - REWRITE_TAC[AES256_XTS_ENCRYPT_REC_EQ_TAIL_TRIVIAL]; - ALL_TAC - ] THEN - - (* when i >= 2, using aes256_xts_encrypt_rec *) - REWRITE_TAC[aes256_xts_encrypt] THEN - CONV_TAC NUM_REDUCE_CONV THEN - SUBGOAL_THEN `~(0x10 * i < 0x10)` ASSUME_TAC THENL - [ ASM_ARITH_TAC ; ALL_TAC] THEN - SUBGOAL_THEN `~(0x10 * i + 0x10 < 0x10)` ASSUME_TAC THENL - [ ASM_ARITH_TAC ; ALL_TAC] THEN - ASM_SIMP_TAC[] THEN - REWRITE_TAC[ARITH_RULE `16 * i + 16 = 16 * (i + 1)`; MOD_MULT] THEN - IMP_REWRITE_TAC[LET_DEF;LET_END_DEF;SUB_0;DIV_MULT] THEN - CONV_TAC NUM_REDUCE_CONV THEN - SUBGOAL_THEN `~(i < 0x2)` ASSUME_TAC THENL - [ ASM_ARITH_TAC ; ALL_TAC] THEN - SUBGOAL_THEN `~(i + 1 < 0x2)` ASSUME_TAC THENL - [ ASM_ARITH_TAC ; ALL_TAC] THEN - ASM_SIMP_TAC[ARITH_RULE `(i + 0x1) - 0x2 = i - 1`; ADD_SUB] THEN - SUBGOAL_THEN `LENGTH (aes256_xts_encrypt_rec 0x0 (i - 0x1) pt iv key1 key2) = 16 * i` ASSUME_TAC THENL - [ REWRITE_TAC[LENGTH_OF_AES256_XTS_ENCRYPT_REC] THEN - ASM_ARITH_TAC; ALL_TAC] THEN - IMP_REWRITE_TAC[SUB_LIST_APPEND_LEFT; SUB_LIST_LENGTH_IMPLIES] THEN - CONJ_TAC THENL [ALL_TAC; ARITH_TAC] THEN - SUBGOAL_THEN `i - 1 = i - 2 + 1` ASSUME_TAC THENL - [ ASM_ARITH_TAC; ALL_TAC ] THEN - ASM_REWRITE_TAC[] THEN - IMP_REWRITE_TAC[AES256_XTS_ENCRYPT_REC_EQ_TAIL] THEN - ASM_ARITH_TAC -);; - -let SUB_LIST_OF_AES256_XTS_ENCRYPT = prove( - `!(i:num) (tail_len:num) (pt:byte list) (iv:int128) (key1:int128 list) (key2:int128 list). - ~(tail_len = 0) /\ tail_len < 16 ==> - (SUB_LIST (0,16 * i) - (aes256_xts_encrypt pt (16 * i + 16 + tail_len) iv key1 key2)) - = aes256_xts_encrypt pt (16 * i) iv key1 key2`, - REPEAT STRIP_TAC THEN - (* Case 1: i = 0 *) - ASM_CASES_TAC `i = 0` THENL - [ - ASM_REWRITE_TAC[] THEN - CONV_TAC NUM_REDUCE_CONV THEN - REWRITE_TAC[ADD; SUB_LIST_CLAUSES; aes256_xts_encrypt] THEN - CONV_TAC NUM_REDUCE_CONV; - ALL_TAC - ] THEN - (* Case 2: i = 1 *) - ASM_CASES_TAC `i = 1` THENL - [ - ASM_REWRITE_TAC[] THEN - CONV_TAC NUM_REDUCE_CONV THEN - REWRITE_TAC[aes256_xts_encrypt; ADD_ASSOC] THEN - CONV_TAC NUM_REDUCE_CONV THEN - SUBGOAL_THEN `~(0x20 + tail_len < 0x10)` ASSUME_TAC THENL [ARITH_TAC; ALL_TAC] THEN - ASM_SIMP_TAC[] THEN - CONV_TAC NUM_REDUCE_CONV THEN - REWRITE_TAC[LET_DEF; LET_END_DEF] THEN - CONV_TAC NUM_REDUCE_CONV THEN - SUBGOAL_THEN `(0x20 + tail_len) MOD 0x10 = tail_len` ASSUME_TAC THENL - [ ASM_SIMP_TAC[ARITH_RULE `32 = 2 * 16`; MOD_MULT_ADD] THEN - IMP_REWRITE_TAC[MOD_LT] - ; ALL_TAC] THEN - SUBGOAL_THEN `((0x20 + tail_len) - (0x20 + tail_len) MOD 0x10) DIV 0x10 = 0x2` ASSUME_TAC THENL - [ ASM_REWRITE_TAC[ADD_ASSOC; ADD_SUB] THEN - ARITH_TAC ; ALL_TAC] THEN - ASM_SIMP_TAC[] THEN - CONV_TAC NUM_REDUCE_CONV THEN - ASM_REWRITE_TAC[] THEN - MP_TAC (SPECL [`pt:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] LENGTH_OF_AES256_XTS_ENCRYPT_REC_TRIVIAL) THEN - DISCH_TAC THEN IMP_REWRITE_TAC[SUB_LIST_APPEND_LEFT] THEN - REWRITE_TAC[AES256_XTS_ENCRYPT_REC_EQ_TAIL_TRIVIAL] THEN - MP_TAC (SPECL [`pt:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] LENGTH_OF_AES256_XTS_ENCRYPT_TAIL_TRIVIAL) THEN - DISCH_TAC THEN IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN - ARITH_TAC; - ALL_TAC - ] THEN - - (* Case 3: i >= 2 *) - ASM_CASES_TAC `i >= 2` THENL - [ - ASM_REWRITE_TAC[ADD_ASSOC] THEN - CONV_TAC NUM_REDUCE_CONV THEN - REWRITE_TAC[aes256_xts_encrypt] THEN - SUBGOAL_THEN `~(0x10 * i < 0x10)` ASSUME_TAC THENL - [ ASM_ARITH_TAC; ALL_TAC] THEN - SUBGOAL_THEN `~((0x10 * i + 0x10) + tail_len < 0x10)` ASSUME_TAC THENL - [ ASM_ARITH_TAC; ALL_TAC] THEN - ASM_SIMP_TAC[LET_DEF; LET_END_DEF] THEN - SUBGOAL_THEN `((0x10 * i + 0x10) + tail_len) MOD 0x10 = tail_len` SUBST1_TAC THENL - [ REWRITE_TAC[ARITH_RULE `0x10 * i + 0x10 = 16 * (i + 1)`] THEN - IMP_REWRITE_TAC[MOD_MULT_ADD; MOD_LT] - ; ALL_TAC] THEN - REWRITE_TAC[ADD_SUB; MOD_MULT; SUB_0; - ARITH_RULE `0x10 * i + 0x10 = 16 * (i + 1)`] THEN - IMP_REWRITE_TAC[DIV_MULT] THEN - SUBGOAL_THEN `~(i + 1 < 2)` ASSUME_TAC THENL [ ASM_ARITH_TAC; ALL_TAC] THEN - SUBGOAL_THEN `~(i < 2)` ASSUME_TAC THENL [ ASM_ARITH_TAC; ALL_TAC] THEN - ASM_SIMP_TAC[ADD_SUB; ARITH_RULE `(i + 1) - 2 = i - 1`] THEN - CONV_TAC NUM_REDUCE_CONV THEN - MP_TAC (SPECL [`0:num`; `(i - 1):num`; `pt:byte list`; `iv:int128`; - `key1:int128 list`; `key2:int128 list`] LENGTH_OF_AES256_XTS_ENCRYPT_REC) THEN - SUBGOAL_THEN `~((i - 1) < 0)` ASSUME_TAC THENL [ ASM_ARITH_TAC; ALL_TAC] THEN - IMP_REWRITE_TAC[ARITH_RULE `i >= 2 ==> i - 0x1 - 0x0 + 0x1 = i`] THEN - IMP_REWRITE_TAC[SUB_LIST_APPEND_LEFT] THEN - SIMP_TAC[ARITH_RULE `16 * i <= i * 16`] THEN - IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN - SIMP_TAC[ARITH_RULE `i * 16 = 16 * i`] THEN - DISCH_TAC THEN - MP_TAC (SPECL [`0`; `(i-2):num`; `pt:byte list`; `iv:int128`; - `key1:int128 list`; `key2:int128 list`] AES256_XTS_ENCRYPT_REC_EQ_TAIL) THEN - ANTS_TAC THENL [ ASM_ARITH_TAC; ALL_TAC ] THEN - IMP_REWRITE_TAC[ARITH_RULE `i >= 2 ==> i - 0x2 + 0x1 = i - 1`]; - ALL_TAC - ] THEN - - ASM_ARITH_TAC -);; - -let acc_len = new_definition -`acc_len (i:int64) (len:int64) : num = - if val i * 0x50 + 0x40 = val len then 0x50 * val i + 0x40 - else - if val i * 0x50 + 0x30 = val len then 0x50 * val i + 0x30 - else - if val i * 0x50 + 0x20 = val len then 0x50 * val i + 0x20 - else - if val i * 0x50 + 0x10 = val len then 0x50 * val i + 0x10 - else 0x50 * val i`;; - -let VALUE_OF_ACC_LEN = prove( - `!(i:int64) (len:int64). - val i * 0x50 <= val len ==> - val len DIV 0x50 = val i ==> - 0x10 divides val len ==> - acc_len i len = val len`, - REPEAT STRIP_TAC THEN - REWRITE_TAC[acc_len] THEN - REPEAT COND_CASES_TAC THENL - [ - ASM_ARITH_TAC; - ASM_ARITH_TAC; - ASM_ARITH_TAC; - ASM_ARITH_TAC; - REWRITE_TAC[ARITH_RULE `!a. 0x50 * a = a * 0x50`] THEN - SUBGOAL_THEN `val (i:int64) * 0x50 = val (len:int64)` ASSUME_TAC THENL - [ MATCH_MP_TAC (SPECL [`val (len:int64)`; `val (i:int64)`] DIVISION_BY_80_LEMMA) THEN - REPEAT CONJ_TAC THENL - [ - ASM_SIMP_TAC[]; - ASM_SIMP_TAC[]; - UNDISCH_TAC `~(val (i:int64) * 0x50 + 0x10 = val (len:int64))` THEN - UNDISCH_TAC `val (i:int64) * 0x50 <= val (len:int64)` THEN - ARITH_TAC; - UNDISCH_TAC `~(val (i:int64) * 0x50 + 0x20 = val (len:int64))` THEN - UNDISCH_TAC `val (i:int64) * 0x50 <= val (len:int64)` THEN - ARITH_TAC; - UNDISCH_TAC `~(val (i:int64) * 0x50 + 0x30 = val (len:int64))` THEN - UNDISCH_TAC `val (i:int64) * 0x50 <= val (len:int64)` THEN - ARITH_TAC; - UNDISCH_TAC `~(val (i:int64) * 0x50 + 0x40 = val (len:int64))` THEN - UNDISCH_TAC `val (i:int64) * 0x50 <= val (len:int64)` THEN - ARITH_TAC - ]; ALL_TAC] THEN - ASM_ARITH_TAC - ] -);; - -let BOUND_OF_ACC_LEN = prove( - `!(i:int64) (len:int64) x. - val i * 0x50 <= val len ==> - val len DIV 0x50 = val i ==> - 0x10 divides val len ==> - val len < x ==> acc_len i len < x`, - REPEAT STRIP_TAC THEN - SUBGOAL_THEN `acc_len i len = val (len:int64)` ASSUME_TAC THENL - [ MP_TAC (SPECL [`i:int64`; `len:int64`] VALUE_OF_ACC_LEN) THEN - ASM_SIMP_TAC[]; ALL_TAC] THEN - ASM_ARITH_TAC -);; - -(* For X9 and X10, they stand for i * 0x5 + 4 when number of blocks is divisible by 5. *) -let acc_blocks = new_definition -`acc_blocks (i:int64) (len:int64) (last:bool) : num = - if val i * 0x50 + 0x40 = val len then val i * 0x5 + 4 - else - if val i * 0x50 + 0x30 = val len then val i * 0x5 + 3 - else - if val i * 0x50 + 0x20 = val len then val i * 0x5 + 2 - else - if val i * 0x50 + 0x10 = val len then val i * 0x5 + 1 - else - if last then val i * 0x5 else val i * 0x5 + 4`;; - -(* The cipher-stealing invariant is the block read at ctxt_p + curr_len - 16 where Cm is being replaced by Pm - one byte at a time with a decreasing offset i from the beginning of the block. - Differs from decrypt in that, there, it's curr_len. - The following is copied from decrypt and will be instantiated with l1_curr_len (= curr_len-16) instead of curr_len *) -let cipher_stealing_inv = new_definition -`cipher_stealing_inv (i:num) (curr_len:num) (tail_len:num) (PP:int128) (ct:byte list): int128 = - bytes_to_int128( - APPEND (SUB_LIST (0, i) (int128_to_bytes PP)) - (APPEND (SUB_LIST (i, tail_len - i) (SUB_LIST (curr_len + 16, tail_len) ct)) - (SUB_LIST (tail_len, 16 - tail_len) (int128_to_bytes PP))))`;; - -(* In the cipher-stealing loop invariant, all bytes remain the same between iterations - except the current byte i, which is from the corresponding location i in the tail of pt *) -let CIPHER_STEALING_BYTE_EQUAL = prove( - `!(i:num) (curr_len:num) (tail_len:int64) (PP:int128) (ct:byte list). - i < val tail_len /\ val tail_len < 16 ==> - curr_len + 16 + val tail_len = LENGTH ct ==> - let InvPP = cipher_stealing_inv (i + 1) curr_len (val tail_len) PP ct - and InvPP' = cipher_stealing_inv i curr_len (val tail_len) PP ct in - (!j. 0 <= j /\ j < 16 /\ ~(j = i) ==> EL j (int128_to_bytes InvPP) = EL j (int128_to_bytes InvPP')) /\ - EL i (int128_to_bytes InvPP') = word_zx (EL (curr_len + 16 + i) ct)`, - REPEAT STRIP_TAC THEN - REWRITE_TAC[LET_DEF; LET_END_DEF] THEN - CONJ_TAC THENL - [ - REPEAT STRIP_TAC THEN - REWRITE_TAC[cipher_stealing_inv] THEN - IMP_REWRITE_TAC[INT128_TO_BYTES_OF_BYTES_TO_INT128] THEN - REPEAT CONJ_TAC THENL - [ - (* Three cases: 0 <= j < i, i < j < val tail_len, val tail_len <= j < 16 *) - ASM_CASES_TAC `j < i` THENL - [ - SUBGOAL_THEN `j < LENGTH (SUB_LIST (0x0,i + 0x1) (int128_to_bytes PP))` ASSUME_TAC THENL - [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN - ASM_ARITH_TAC; ALL_TAC] THEN - SUBGOAL_THEN `j < LENGTH (SUB_LIST (0x0,i) (int128_to_bytes PP))` ASSUME_TAC THENL - [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN - ASM_ARITH_TAC ; ALL_TAC] THEN - REWRITE_TAC[EL_APPEND] THEN - ASM_SIMP_TAC[] THEN - MP_TAC (ISPECL [`j:num`; `i:num`; `(int128_to_bytes PP):byte list`] EL_SUB_LIST) THEN - ANTS_TAC THENL - [ REWRITE_TAC[LENGTH_OF_INT128_TO_BYTES] THEN - ASM_ARITH_TAC; ALL_TAC ] THEN - MP_TAC (ISPECL [`j:num`; `(i + 1):num`; `(int128_to_bytes PP):byte list`] EL_SUB_LIST) THEN - ANTS_TAC THENL - [ REWRITE_TAC[LENGTH_OF_INT128_TO_BYTES] THEN - ASM_ARITH_TAC; ALL_TAC ] THEN - SIMP_TAC[]; ALL_TAC - ] THEN - ASM_CASES_TAC `j < val (tail_len:int64)` THENL - [ - SUBGOAL_THEN `j > i` ASSUME_TAC THENL[ASM_ARITH_TAC; ALL_TAC] THEN - REWRITE_TAC[EL_APPEND] THEN - SUBGOAL_THEN `LENGTH (SUB_LIST (0x0,i + 0x1) (int128_to_bytes PP)) = i + 1` SUBST1_TAC THENL - [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN - ASM_ARITH_TAC; ALL_TAC] THEN - SUBGOAL_THEN `LENGTH (SUB_LIST (0x0,i) (int128_to_bytes PP)) = i` SUBST1_TAC THENL - [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN - ASM_ARITH_TAC; ALL_TAC] THEN - SUBGOAL_THEN `LENGTH (SUB_LIST (i + 0x1,val (tail_len:int64) - (i + 0x1)) - (SUB_LIST (curr_len + 0x10,val tail_len) (ct:byte list))) - = val tail_len - (i + 1)` SUBST1_TAC THENL - [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN - ASM_ARITH_TAC; ALL_TAC] THEN - SUBGOAL_THEN `LENGTH (SUB_LIST (i,val (tail_len:int64) - i) - (SUB_LIST (curr_len + 0x10,val tail_len) (ct:byte list))) - = val tail_len - i` SUBST1_TAC THENL - [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN - ASM_ARITH_TAC; ALL_TAC] THEN - SUBGOAL_THEN `~(j < i)` ASSUME_TAC THENL - [ ASM_ARITH_TAC; ALL_TAC] THEN - SUBGOAL_THEN `~(j < i + 1)` ASSUME_TAC THENL - [ ASM_ARITH_TAC; ALL_TAC] THEN - SUBGOAL_THEN `j - i < val (tail_len:int64) - i` ASSUME_TAC THENL - [ ASM_ARITH_TAC; ALL_TAC] THEN - SUBGOAL_THEN `j - (i + 1) < val (tail_len:int64) - (i + 1)` ASSUME_TAC THENL - [ ASM_ARITH_TAC; ALL_TAC] THEN - ASM_SIMP_TAC[] THEN - MP_TAC (ISPECL [`(j - i):num`; `i:num`; - `(SUB_LIST (curr_len + 16,val (tail_len:int64)) (ct:byte list)):byte list`; - `(val (tail_len:int64) - i):num`] EL_SUB_LIST_SHIFT) THEN - ASM_SIMP_TAC[] THEN - ANTS_TAC THENL [ REWRITE_TAC[LENGTH_SUB_LIST] THEN ASM_ARITH_TAC; ALL_TAC] THEN - IMP_REWRITE_TAC[ARITH_RULE `!i j. j > i ==> j - i - 1 = j - (i + 1)`] THEN - ASM_ARITH_TAC; ALL_TAC - ] THEN - (* j >= val tail_len *) - REWRITE_TAC[EL_APPEND] THEN - SUBGOAL_THEN `LENGTH (SUB_LIST (0x0,i + 0x1) (int128_to_bytes PP)) = i + 1` SUBST1_TAC THENL - [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN - ASM_ARITH_TAC; ALL_TAC] THEN - SUBGOAL_THEN `LENGTH (SUB_LIST (0x0,i) (int128_to_bytes PP)) = i` SUBST1_TAC THENL - [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN - ASM_ARITH_TAC; ALL_TAC] THEN - SUBGOAL_THEN `LENGTH (SUB_LIST (i + 0x1,val (tail_len:int64) - (i + 0x1)) - (SUB_LIST (curr_len + 0x10,val tail_len) (ct:byte list))) - = val tail_len - (i + 1)` SUBST1_TAC THENL - [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN - ASM_ARITH_TAC; ALL_TAC] THEN - SUBGOAL_THEN `LENGTH (SUB_LIST (i,val (tail_len:int64) - i) - (SUB_LIST (curr_len + 0x10,val tail_len) (ct:byte list))) - = val tail_len - i` SUBST1_TAC THENL - [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN - ASM_ARITH_TAC; ALL_TAC] THEN - SUBGOAL_THEN `~(j < i)` ASSUME_TAC THENL - [ ASM_ARITH_TAC; ALL_TAC] THEN - SUBGOAL_THEN `~(j < i + 1)` ASSUME_TAC THENL - [ ASM_ARITH_TAC; ALL_TAC] THEN - SUBGOAL_THEN `~(j - i < val (tail_len:int64) - i)` ASSUME_TAC THENL - [ ASM_ARITH_TAC; ALL_TAC] THEN - SUBGOAL_THEN `~(j - (i + 1) < val (tail_len:int64) - (i + 1))` ASSUME_TAC THENL - [ ASM_ARITH_TAC; ALL_TAC] THEN - ASM_SIMP_TAC[] THEN - AP_THM_TAC THEN AP_TERM_TAC THEN - ASM_ARITH_TAC; - - REWRITE_TAC[LENGTH_APPEND] THEN - REWRITE_TAC[LENGTH_SUB_LIST] THEN - REWRITE_TAC[LENGTH_OF_INT128_TO_BYTES] THEN - CONV_TAC NUM_REDUCE_CONV THEN - IMP_REWRITE_TAC[ARITH_RULE `i < 16 ==> MIN i 16 = i`] THEN - SUBGOAL_THEN `LENGTH (ct:byte list) - (curr_len + 16) = val (tail_len:int64)` SUBST1_TAC THENL - [ ASM_ARITH_TAC; ALL_TAC ] THEN - REWRITE_TAC[ARITH_RULE `!x. MIN x x = x`] THEN - ASM_ARITH_TAC; +(**********************************************************************) +(** Tactics **) - REWRITE_TAC[LENGTH_APPEND] THEN - REWRITE_TAC[LENGTH_SUB_LIST] THEN - REWRITE_TAC[LENGTH_OF_INT128_TO_BYTES] THEN - CONV_TAC NUM_REDUCE_CONV THEN - IMP_REWRITE_TAC[ARITH_RULE `i < 16 ==> MIN (i + 1) 16 = i + 1`] THEN - SUBGOAL_THEN `LENGTH (ct:byte list) - (curr_len + 16) = val (tail_len:int64)` SUBST1_TAC THENL - [ ASM_ARITH_TAC; ALL_TAC ] THEN - REWRITE_TAC[ARITH_RULE `!x. MIN x x = x`] THEN - ASM_ARITH_TAC - ] ; ALL_TAC - ] THEN +let AESENC_TAC = + REWRITE_TAC [aes256_encrypt] THEN + REWRITE_TAC EL_15_128_CLAUSES THEN + REWRITE_TAC [aes256_encrypt_round; aese; aesmc] THEN + CONV_TAC (TOP_DEPTH_CONV let_CONV) THEN + BITBLAST_TAC;; - REWRITE_TAC[cipher_stealing_inv] THEN - IMP_REWRITE_TAC[INT128_TO_BYTES_OF_BYTES_TO_INT128] THEN - CONJ_TAC THENL [ - REWRITE_TAC[EL_APPEND] THEN - SUBGOAL_THEN `LENGTH (SUB_LIST (0x0,i) (int128_to_bytes PP)) = i` SUBST1_TAC THENL - [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN - ASM_ARITH_TAC; ALL_TAC] THEN - SUBGOAL_THEN `LENGTH (SUB_LIST (i,val (tail_len:int64) - i) - (SUB_LIST (curr_len + 0x10,val tail_len) (ct:byte list))) - = val tail_len - i` SUBST1_TAC THENL - [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN - ASM_ARITH_TAC; ALL_TAC] THEN - SIMP_TAC[ARITH_RULE `~(i < i)`; SUB_REFL] THEN - SUBGOAL_THEN `0 < val (tail_len:int64) - i` ASSUME_TAC THENL - [ ASM_ARITH_TAC; ALL_TAC] THEN - ASM_SIMP_TAC[] THEN - MP_TAC (ISPECL [`curr_len + 0x10:num`; `i:num`; `ct:byte list`; - `val (tail_len:int64) - i:num`; `val (tail_len:int64)`] SUB_LIST_MIN_GENERAL) THEN - REWRITE_TAC[ARITH_RULE `!a. MIN a a = a`; GSYM ADD_ASSOC] THEN - DISCH_THEN (fun th -> (REWRITE_TAC [th])) THEN - REWRITE_TAC[WORD_ZX_TRIVIAL; EL] THEN - MATCH_MP_TAC HD_SUB_LIST_CONS_GENERAL THEN - ASM_ARITH_TAC; ALL_TAC] THEN - REWRITE_TAC[LENGTH_APPEND] THEN - REWRITE_TAC[LENGTH_SUB_LIST] THEN - REWRITE_TAC[LENGTH_OF_INT128_TO_BYTES] THEN - CONV_TAC NUM_REDUCE_CONV THEN - ASM_ARITH_TAC -);; +let AESXTS_ENC_ONE_BLOCK_TAC = + REWRITE_TAC [aes256_xts_encrypt_1block] THEN + REWRITE_TAC [xts_init_tweak; aes256_xts_encrypt_round] THEN + CONV_TAC (TOP_DEPTH_CONV let_CONV) THEN + GEN_REWRITE_TAC LAND_CONV [WORD_XOR_SYM] THEN + REPEAT (AP_THM_TAC THEN AP_TERM_TAC) THEN + BITBLAST_TAC;; -let CIPHER_STEALING_INV_SELECT = prove( - `!(i:num) (curr_len:num) (tail_len:int64) (PP:int128) (ct:byte list). - i < val tail_len ==> val tail_len < 16 ==> - curr_len + 16 + (val tail_len) = LENGTH ct ==> - EL i (int128_to_bytes (cipher_stealing_inv (i + 1) curr_len (val tail_len) PP ct)) = - EL i (int128_to_bytes PP)`, - REPEAT STRIP_TAC THEN - REWRITE_TAC[cipher_stealing_inv] THEN - IMP_REWRITE_TAC[INT128_TO_BYTES_OF_BYTES_TO_INT128] THEN - CONJ_TAC THENL [ - SUBGOAL_THEN `LENGTH (SUB_LIST (0x0,i + 1) (int128_to_bytes PP)) <= i + 1` ASSUME_TAC THENL - [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN - ARITH_TAC; ALL_TAC] THEN - REWRITE_TAC[EL_APPEND] THEN - SUBGOAL_THEN `i < LENGTH (SUB_LIST (0x0,i + 0x1) (int128_to_bytes PP))` ASSUME_TAC THENL - [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN - ASM_ARITH_TAC; ALL_TAC] THEN - ASM_SIMP_TAC[] THEN - MATCH_MP_TAC EL_SUB_LIST THEN - REWRITE_TAC[LENGTH_OF_INT128_TO_BYTES] THEN - ASM_ARITH_TAC; ALL_TAC - ] THEN +let TWEAK_UPDATE_CONV = + let ADD_SUC_1 = ARITH_RULE `!n. n + 1 = SUC(n)` in + let ADD_SUC_2 = ARITH_RULE `!n. n + 2 = SUC(n + 1)` in + let ADD_SUC_3 = ARITH_RULE `!n. n + 3 = SUC(n + 2)` in + let ADD_SUC_4 = ARITH_RULE `!n. n + 4 = SUC(n + 3)` in + let ADD_SUC_5 = ARITH_RULE `!n. n + 5 = SUC(n + 4)` in + let ADD_SUC_6 = ARITH_RULE `!n. n + 6 = SUC(n + 5)` in + let ADD_SUC_7 = ARITH_RULE `!n. n + 7 = SUC(n + 6)` in + let ADD_SUC_8 = ARITH_RULE `!n. n + 8 = SUC(n + 7)` in + let ADD_SUC_9 = ARITH_RULE `!n. n + 9 = SUC(n + 8)` in + NUM_REDUCE_CONV THENC + RATOR_CONV (LAND_CONV (num_CONV ORELSEC + FIRST_CONV + [ CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_1]); + CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_2]); + CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_3]); + CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_4]); + CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_5]); + CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_6]); + CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_7]); + CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_8]); + CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_9]);])) THENC + REWRITE_CONV [CONJUNCT2 calculate_tweak] THENC + GF_128_MULT_BY_PRIMITIVE_CONV;; - REWRITE_TAC[LENGTH_APPEND] THEN - REWRITE_TAC[LENGTH_SUB_LIST] THEN - REWRITE_TAC[LENGTH_OF_INT128_TO_BYTES] THEN - CONV_TAC NUM_REDUCE_CONV THEN - IMP_REWRITE_TAC[ARITH_RULE `i < 16 ==> MIN (i + 1) 16 = i + 1`] THEN - SUBGOAL_THEN `LENGTH (ct:byte list) - (curr_len + 16) = val (tail_len:int64)` SUBST1_TAC THENL - [ ASM_ARITH_TAC; ALL_TAC ] THEN - REWRITE_TAC[ARITH_RULE `!x. MIN x x = x`] THEN - ASM_ARITH_TAC -);; +(* differs from the Decrypt definition in using key2_lst instead of key2 + TODO: it seems that value of indm1 doesn't matter to the tactic, can it be removed? *) +let TWEAK_TAC reg ind indm1 = + let lower_term = subst [ind,`ind:num`] `(word_zx:int128->int64) (calculate_tweak ind iv key2_lst)` in + let upper_term = subst [ind,`ind:num`] `(word_subword:int128->num#num->int64) (calculate_tweak ind iv key2_lst) (64,64)` in + let full_term = subst [ind,`ind:num`] `calculate_tweak ind iv key2_lst` in + let full_lemma = subst [reg,`reg:(armstate,int128)component`] `read (reg:(armstate,int128)component) (s:armstate) = a ==> !a'. a = a' ==> read reg s = a'` in + let abbrev_term = subst [indm1,`indm1:num`] `tweak_pre:int128 = (calculate_tweak indm1 iv key2_lst)` in + FIRST_X_ASSUM(MP_TAC o SPEC lower_term + o MATCH_MP (MESON[] `read X9 s = a ==> !a'. a = a' ==> read X9 s = a'`)) THEN + ANTS_TAC THENL [CONV_TAC (RAND_CONV (RAND_CONV TWEAK_UPDATE_CONV)) THEN + ABBREV_TAC abbrev_term THEN + BITBLAST_TAC; DISCH_TAC] THEN + FIRST_X_ASSUM(MP_TAC o SPEC upper_term + o MATCH_MP (MESON[] `read X10 s = a ==> !a'. a = a' ==> read X10 s = a'`)) THEN + ANTS_TAC THENL [CONV_TAC (RAND_CONV (RATOR_CONV (RAND_CONV TWEAK_UPDATE_CONV))) THEN + ABBREV_TAC abbrev_term THEN + BITBLAST_TAC; DISCH_TAC] THEN + FIRST_X_ASSUM(MP_TAC o SPEC full_term + o MATCH_MP (MESON[] full_lemma)) THEN + ANTS_TAC THENL [CONV_TAC (RAND_CONV TWEAK_UPDATE_CONV) THEN + ABBREV_TAC abbrev_term THEN + BITBLAST_TAC; DISCH_TAC];; -let CIPHER_STEALING_INV_SIMP_TAC i = - ( FIRST_ASSUM (fun th -> MATCH_MP_TAC(SPEC i th)) THEN CONV_TAC NUM_REDUCE_CONV) ORELSE - ( ASM_REWRITE_TAC[] THEN - REWRITE_TAC[WORD_RULE `!a b. word_add ((word a):int64) (word b) = word (a + b)`] THEN - REWRITE_TAC[GSYM ADD_ASSOC] THEN - CONV_TAC NUM_REDUCE_CONV THEN - IMP_REWRITE_TAC[WORD_ZX_ZX; WORD_ZX_TRIVIAL] THEN - REWRITE_TAC[DIMINDEX_8; DIMINDEX_32; DIMINDEX_64] THEN - IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN - ASM_ARITH_TAC);; +let XTSENC_TAC reg ind ind_tweak = + let tm = subst [ind, `ind:num`; ind_tweak, `ind_tweak:num`] + `aes256_xts_encrypt_round (bytes_to_int128 (SUB_LIST (ind,0x10) (pt_in:byte list))) + (calculate_tweak (ind_tweak) iv key2_lst) key1_lst` in + let lemma = subst [reg, `reg:(armstate,int128)component`] + `read (reg:(armstate,int128)component) (s:armstate) = a ==> !a'. a = a' ==> read reg s = a'` in + FIRST_X_ASSUM(MP_TAC o SPEC tm o MATCH_MP (MESON[] lemma)) THEN + ANTS_TAC THENL + [ EXPAND_TAC "key1_lst" THEN + CONV_TAC (RAND_CONV ( + REWRITE_CONV [aes256_xts_encrypt_round] THENC + DEPTH_CONV let_CONV)) THEN + GEN_REWRITE_TAC LAND_CONV [WORD_XOR_SYM] THEN + REPEAT (AP_THM_TAC THEN AP_TERM_TAC) THEN + GEN_REWRITE_TAC ONCE_DEPTH_CONV [WORD_XOR_SYM] THEN + AESENC_TAC; DISCH_TAC ];; let ENC_TAIL_SWAP_CASE_0_TAC = POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th]) THEN REWRITE_TAC[th]) THEN @@ -3411,7 +1520,7 @@ let ENC_TAIL_SWAP_CASE_0_TAC = MP_TAC (SPECL [`ctxt_p:int64`; `0x0`; `val (tail_len:int64)`; `l1_curr_len:num`; `(int128_to_bytes CC):byte list`; `s5:armstate`] - BYTE_LIST_AT_SPLIT_BACKWARDS) THEN + BYTE_LIST_AT_SPLIT_BACKWARDS_CARNONICAL) THEN REWRITE_TAC[LENGTH_OF_INT128_TO_BYTES] THEN CONV_TAC NUM_REDUCE_CONV THEN CONV_TAC(ONCE_DEPTH_CONV NORMALIZE_RELATIVE_ADDRESS_CONV) THEN @@ -3429,8 +1538,6 @@ let ENC_TAIL_SWAP_CASE_0_TAC = WORD_ARITH_TAC; ];; - - let ENC_TAIL_SWAP_CASE_TAC case = let c_tm = `case:num` in let v_tm = `v:num` in @@ -3473,7 +1580,7 @@ let ENC_TAIL_SWAP_CASE_TAC case = MP_TAC (SPECL [`ctxt_p:int64`; case; `val (tail_len:int64)`; `l1_curr_len:num`; `(int128_to_bytes CC):byte list`; `s5:armstate`] - BYTE_LIST_AT_SPLIT_BACKWARDS) THEN + BYTE_LIST_AT_SPLIT_BACKWARDS_CARNONICAL) THEN REWRITE_TAC[LENGTH_OF_INT128_TO_BYTES] THEN CONV_TAC NUM_REDUCE_CONV THEN CONV_TAC(ONCE_DEPTH_CONV NORMALIZE_RELATIVE_ADDRESS_CONV) THEN @@ -3505,87 +1612,9 @@ let ENC_TAIL_SWAP_ASM_CASES_TAC case = DISCH_TAC;; -let BREAK_DATA_INTO_PARTS = prove( - `!curr_len (tail_len:int64) (pt_ptr:int64) (s:armstate). - ((curr_len + 0x10 + val tail_len <= LENGTH bl) /\ - (forall i. i < curr_len - ==> read (memory :> bytes8 (word_add pt_ptr (word i))) s = EL i bl) /\ - (forall i. i < 16 - ==> read (memory :> bytes8 (word_add (word_add pt_ptr (word curr_len)) (word i))) s = - EL i (SUB_LIST (curr_len, 16) bl)) /\ - (forall i. i < val tail_len - ==> read (memory :> bytes8 - (word_add (word_add pt_ptr (word (curr_len + 0x10))) (word i))) s = - EL i (SUB_LIST (curr_len + 16, val tail_len) bl))) ==> - forall i. - i < curr_len + 0x10 + val tail_len - ==> read (memory :> bytes8 (word_add pt_ptr (word i))) s = EL i bl`, - REPEAT GEN_TAC THEN - DISCH_THEN (CONJUNCTS_THEN2 (LABEL_TAC "H") - (CONJUNCTS_THEN2 (LABEL_TAC "H1") - (CONJUNCTS_THEN2 (LABEL_TAC "H2") (LABEL_TAC "H3")))) THEN - REPEAT STRIP_TAC THEN - - ASM_CASES_TAC `i < curr_len` THENL - [ - FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[]; - ALL_TAC - ] THEN - - ASM_CASES_TAC `i < curr_len + 16` THENL - [ - USE_THEN "H2" (fun th -> MP_TAC (SPEC `i - curr_len` th)) THEN - REMOVE_THEN "H2" (K ALL_TAC) THEN - SUBGOAL_THEN `(word_add (word_add (pt_ptr:int64) (word curr_len)) (word (i - curr_len))) - = (word_add pt_ptr (word i))` ASSUME_TAC THENL - [ REWRITE_TAC[WORD_RULE `word_add (word_add a (word b)) (word c) = word_add a (word (b + c))`] THEN - AP_TERM_TAC THEN AP_TERM_TAC THEN - ASM_ARITH_TAC; ALL_TAC] THEN - ASM_REWRITE_TAC[] THEN - ANTS_TAC THENL[ASM_ARITH_TAC; ALL_TAC] THEN - SIMP_TAC[] THEN DISCH_TAC THEN - IMP_REWRITE_TAC[EL_SUB_LIST_GENERAL] THEN - ASM_ARITH_TAC; - ALL_TAC - ] THEN - - ASM_CASES_TAC `i < curr_len + 16 + val (tail_len:int64)` THENL - [ - USE_THEN "H3" (fun th -> MP_TAC (SPEC `i - curr_len - 16` th)) THEN - REMOVE_THEN "H3" (K ALL_TAC) THEN - SUBGOAL_THEN `(word_add (word_add (pt_ptr:int64) (word (curr_len + 0x10))) - (word (i - curr_len - 0x10))) = (word_add pt_ptr (word i))` ASSUME_TAC THENL - [ REWRITE_TAC[WORD_RULE `word_add (word_add a (word b)) (word c) = word_add a (word (b + c))`] THEN - AP_TERM_TAC THEN AP_TERM_TAC THEN - ASM_ARITH_TAC; ALL_TAC] THEN - ASM_REWRITE_TAC[] THEN - ANTS_TAC THENL[ASM_ARITH_TAC; ALL_TAC] THEN - SIMP_TAC[] THEN DISCH_TAC THEN - REWRITE_TAC[ARITH_RULE `i - curr_len - 16 = i - (curr_len + 16)`] THEN - IMP_REWRITE_TAC[EL_SUB_LIST_GENERAL] THEN - ASM_ARITH_TAC; - ALL_TAC - ] THEN - - ASM_ARITH_TAC -);; +(**********************************************************************) +(** Proofs **) -(* - `forall i. - i < curr_len - ==> read (memory :> bytes8 (word_add ctxt_p (word i))) s5 = - EL i (aes256_xts_encrypt pt_in curr_len iv key1_lst key2_lst) -==> - (forall i. - i < val (word (curr_len - 0x10)) - ==> read (memory :> bytes8 (word_add ctxt_p (word i))) s5 = - EL i - (aes256_xts_encrypt pt_in (curr_len - 0x10) iv key1_lst key2_lst)) /\ - read (memory :> bytes128 (word_add ctxt_p (word (curr_len - 0x10)))) s5 = - cipher_stealing_enc_inv (val tail_len) curr_len (val tail_len) CC pt_in`` -*) -(* ************************************** *) -(* Assembly proofs *) (* Proof: Cipher stealing *) let CIPHER_STEALING_ENC_CORRECT = time prove( @@ -3640,13 +1669,13 @@ let CIPHER_STEALING_ENC_CORRECT = time prove( [ SUBGOAL_THEN `~(val (len:int64) < 0x10)` MP_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN UNDISCH_TAC `word_and len (word 0xfffffffffffffff0) = (len_full_blocks:int64)` THEN - MP_TAC (SPECL [`len:int64`; `len_full_blocks:int64`] LEN_FULL_BLOCKS_LO_BOUND_1BLOCK_THM) THEN + MP_TAC (SPECL [`len:int64`; `len_full_blocks:int64`] NUM_BLOCKS_LO_BOUND_1BLOCK_THM) THEN SIMP_TAC[]; ALL_TAC] THEN SUBGOAL_THEN `val (len_full_blocks:int64) <= 0x2 EXP 24` ASSUME_TAC THENL [ UNDISCH_TAC `val (len:int64) <= 0x2 EXP 24` THEN UNDISCH_TAC `word_and len (word 0xfffffffffffffff0) = (len_full_blocks:int64)` THEN - MP_TAC (SPECL [`len:int64`; `len_full_blocks:int64`] LEN_FULL_BLOCKS_HI_BOUND_THM) THEN + MP_TAC (SPECL [`len:int64`; `len_full_blocks:int64`] NUM_BLOCKS_HI_BOUND_THM) THEN SIMP_TAC[]; ALL_TAC] THEN SUBGOAL_THEN `val (tail_len:int64) < 16` ASSUME_TAC THENL @@ -3660,7 +1689,7 @@ let CIPHER_STEALING_ENC_CORRECT = time prove( (* relationship between variables *) SUBGOAL_THEN `val (len_full_blocks:int64) <= val (len:int64)` ASSUME_TAC THENL - [ EXPAND_TAC "len_full_blocks" THEN SIMP_TAC[LEN_FULL_BLOCKS_LT_LEN_THM]; ALL_TAC] THEN + [ EXPAND_TAC "len_full_blocks" THEN SIMP_TAC[NUM_BLOCKS_LT_LEN_THM]; ALL_TAC] THEN SUBGOAL_THEN `val (num_5blocks:int64) * 0x50 <= val (len_full_blocks:int64)` ASSUME_TAC THENL [ EXPAND_TAC "num_5blocks" THEN @@ -3677,7 +1706,7 @@ let CIPHER_STEALING_ENC_CORRECT = time prove( SUBGOAL_THEN `0x10 divides val (len_full_blocks:int64)` ASSUME_TAC THENL [ EXPAND_TAC "len_full_blocks" THEN - REWRITE_TAC[LEN_FULL_BLOCKS_TO_VAL] THEN + REWRITE_TAC[NUM_BLOCKS_TO_VAL] THEN IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT; DIVIDES_RMUL; DIVIDES_REFL] THEN ASM_ARITH_TAC; ALL_TAC] THEN @@ -4020,9 +2049,9 @@ let CIPHER_STEALING_ENC_CORRECT = time prove( REWRITE_TAC[BYTES_TO_INT128_OF_INT128_TO_BYTES] THEN (* `read (memory :> bytes128 (word_sub (word_add ctxt_p (word curr_len)) (word 0x10))) s5 = CC` *) - (* Apply READ_CT_LAST_LEMMA with proper arguments *) + (* Apply READ_LAST_LEMMA with proper arguments *) MP_TAC (SPECL [`ctxt_p:int64`; `l1_curr_len:num`; `word (l1_curr_len+0x10):int64`; - `aes256_xts_encrypt pt_in (l1_curr_len+0x10) iv key1_lst key2_lst:byte list`; `s5:armstate`] READ_CT_LAST_LEMMA) THEN + `aes256_xts_encrypt pt_in (l1_curr_len+0x10) iv key1_lst key2_lst:byte list`; `s5:armstate`] READ_LAST_LEMMA) THEN UNDISCH_THEN `val ((word (l1_curr_len + 0x10)):int64) = l1_curr_len + 0x10` (fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th]) THEN REWRITE_TAC[th] THEN ASSUME_TAC th) THEN ASM_SIMP_TAC[] THEN @@ -4350,7 +2379,7 @@ let CIPHER_STEALING_ENC_CORRECT = time prove( ==> read (memory :> bytes8 (word_add ctxt_p (word i))) s33 = EL i (aes256_xts_encrypt pt_in (0x10 * l1_curr_blocks + 0x10 + val tail_len) iv key1_lst key2_lst)` *) MATCH_MP_TAC (SPECL [`0x10 * l1_curr_blocks:num`; `tail_len:int64`; `ctxt_p:int64`; `s33:armstate`] - BREAK_DATA_INTO_PARTS) THEN + BREAK_DATA_INTO_PARTS_ENCRYPT) THEN REPEAT CONJ_TAC THENL (* 4 subgoals *) [ (* 1. `0x10 * l1_curr_blocks + 0x10 + val tail_len <= @@ -4592,274 +2621,6 @@ let CIPHER_STEALING_ENC_CORRECT = time prove( ] (* end of loop invariant proof. *) );; -let READ_LT_2BLOCK = prove( - `!(ptr:int64) (len:int64) (bl:byte list) (s:armstate). - LENGTH bl = val len ==> - val len >= 0x10 ==> - val len < 0x20 ==> - (forall i. i < val len - ==> read (memory :> bytes8 (word_add ptr (word i))) s = EL i bl) - ==> read (memory :> bytes128 ptr) s = bytes_to_int128 (SUB_LIST (0, 16) bl)`, - REPEAT STRIP_TAC THEN - MP_TAC (SPECL [`0:num`; `bl:byte list`; `ptr:int64`; - `len:int64`; `s:armstate`] BYTE_LIST_AT_1BLOCKS) THEN - REWRITE_TAC[byte_list_at] THEN - ANTS_TAC THENL[ ASM_SIMP_TAC[]; ALL_TAC] THEN - ANTS_TAC THENL[ ASM_SIMP_TAC[]; ALL_TAC] THEN - ANTS_TAC THENL[ ASM_ARITH_TAC; ALL_TAC] THEN - ASM_SIMP_TAC[WORD_ADD_0] -);; - -let READ_LT_3BLOCK = prove( - `!(ptr:int64) (len:int64) (bl:byte list) (s:armstate). - LENGTH bl = val len ==> - ~(val len < 0x20) ==> - val len < 0x30 ==> - (forall i. i < val len - ==> read (memory :> bytes8 (word_add ptr (word i))) s = EL i bl) - ==> read (memory :> bytes128 ptr) s = bytes_to_int128 (SUB_LIST (0, 16) bl) /\ - read (memory :> bytes128 (word_add ptr (word 16))) s = - bytes_to_int128 (SUB_LIST (16, 16) bl)`, - REPEAT GEN_TAC THEN REPEAT_N 4 STRIP_TAC THEN - MP_TAC (SPECL [`0:num`; `bl:byte list`; `ptr:int64`; - `len:int64`; `s:armstate`] BYTE_LIST_AT_2BLOCKS) THEN - REWRITE_TAC[byte_list_at] THEN - ANTS_TAC THENL[ ASM_SIMP_TAC[]; ALL_TAC] THEN - ANTS_TAC THENL[ ASM_SIMP_TAC[]; ALL_TAC] THEN - ANTS_TAC THENL[ ASM_ARITH_TAC; ALL_TAC] THEN - CONV_TAC NUM_REDUCE_CONV THEN - ASM_SIMP_TAC[WORD_ADD_0] -);; - -let READ_LT_4BLOCK = prove( - `!(ptr:int64) (len:int64) (bl:byte list) (s:armstate). - LENGTH bl = val len ==> - ~(val len < 0x30) ==> - val len < 0x40 ==> - (forall i. i < val len - ==> read (memory :> bytes8 (word_add ptr (word i))) s = EL i bl) - ==> read (memory :> bytes128 ptr) s = bytes_to_int128 (SUB_LIST (0, 16) bl) /\ - read (memory :> bytes128 (word_add ptr (word 16))) s = - bytes_to_int128 (SUB_LIST (16, 16) bl) /\ - read (memory :> bytes128 (word_add ptr (word 32))) s = - bytes_to_int128 (SUB_LIST (32, 16) bl)`, - REPEAT GEN_TAC THEN REPEAT_N 4 STRIP_TAC THEN - MP_TAC (SPECL [`0:num`; `bl:byte list`; `ptr:int64`; - `len:int64`; `s:armstate`] BYTE_LIST_AT_3BLOCKS) THEN - REWRITE_TAC[byte_list_at] THEN - ANTS_TAC THENL[ ASM_SIMP_TAC[]; ALL_TAC] THEN - ANTS_TAC THENL[ ASM_SIMP_TAC[]; ALL_TAC] THEN - ANTS_TAC THENL[ ASM_ARITH_TAC; ALL_TAC] THEN - CONV_TAC NUM_REDUCE_CONV THEN - ASM_SIMP_TAC[WORD_ADD_0] -);; - -let READ_LT_5BLOCK = prove( - `!(ptr:int64) (len:int64) (bl:byte list) (s:armstate). - LENGTH bl = val len ==> - ~(val len < 0x40) ==> - val len < 0x50 ==> - (forall i. i < val len - ==> read (memory :> bytes8 (word_add ptr (word i))) s = EL i bl) - ==> read (memory :> bytes128 ptr) s = bytes_to_int128 (SUB_LIST (0, 16) bl) /\ - read (memory :> bytes128 (word_add ptr (word 16))) s = - bytes_to_int128 (SUB_LIST (16, 16) bl) /\ - read (memory :> bytes128 (word_add ptr (word 32))) s = - bytes_to_int128 (SUB_LIST (32, 16) bl) /\ - read (memory :> bytes128 (word_add ptr (word 48))) s = - bytes_to_int128 (SUB_LIST (48, 16) bl)`, - REPEAT GEN_TAC THEN REPEAT_N 4 STRIP_TAC THEN - MP_TAC (SPECL [`0:num`; `bl:byte list`; `ptr:int64`; - `len:int64`; `s:armstate`] BYTE_LIST_AT_4BLOCKS) THEN - REWRITE_TAC[byte_list_at] THEN - ANTS_TAC THENL[ ASM_SIMP_TAC[]; ALL_TAC] THEN - ANTS_TAC THENL[ ASM_SIMP_TAC[]; ALL_TAC] THEN - ANTS_TAC THENL[ ASM_ARITH_TAC; ALL_TAC] THEN - CONV_TAC NUM_REDUCE_CONV THEN - ASM_SIMP_TAC[WORD_ADD_0] -);; - -let READ_BYTES_EQ_READ_BYTE128_1BLOCK_ENC = prove( - `!(ptr:int64) (ct:byte list) (iv:int128) (key1:int128 list) (key2:int128 list) s. - (read (memory :> bytes128 pt_ptr) s = - aes256_xts_encrypt_round (bytes_to_int128 (SUB_LIST (0x0,0x10) ct)) - (calculate_tweak 0x0 iv key2) - key1) ==> - read (memory :> bytes (pt_ptr,0x10)) s = - num_of_bytelist (SUB_LIST (0x0,0x10) (aes256_xts_encrypt ct 0x10 iv key1 key2))`, - REPEAT STRIP_TAC THEN - REWRITE_TAC[READ_MEMORY_BYTES_BYTES128] THEN - ASM_REWRITE_TAC[] THEN - REWRITE_TAC[aes256_xts_encrypt] THEN - CONV_TAC NUM_REDUCE_CONV THEN - REWRITE_TAC[LET_DEF; LET_END_DEF] THEN - CONV_TAC NUM_REDUCE_CONV THEN - REWRITE_TAC[aes256_xts_encrypt_tail] THEN - REWRITE_TAC[LET_DEF; LET_END_DEF] THEN - CONV_TAC NUM_REDUCE_CONV THEN - REWRITE_TAC[SUB_LIST_OF_INT128_TO_BYTES] THEN - REWRITE_TAC[NUM_OF_BYTELIST_OF_INT128_TO_BYTES] -);; - -let READ_BYTES_EQ_READ_BYTE128_2BLOCKS_ENC = prove( - `!(ptr:int64) (ct:byte list) (iv:int128) (key1:int128 list) (key2:int128 list) s. - (read (memory :> bytes128 pt_ptr) s = - aes256_xts_encrypt_round (bytes_to_int128 (SUB_LIST (0x0,0x10) ct)) - (calculate_tweak 0x0 iv key2) - key1) ==> - (read (memory :> bytes128 (word_add pt_ptr (word 0x10))) s = - aes256_xts_encrypt_round (bytes_to_int128 (SUB_LIST (0x10,0x10) ct)) - (calculate_tweak 0x1 iv key2) - key1) ==> - read (memory :> bytes (pt_ptr,0x20)) s = - num_of_bytelist (SUB_LIST (0x0,0x20) (aes256_xts_encrypt ct 0x20 iv key1 key2))`, - REPEAT STRIP_TAC THEN - IMP_REWRITE_TAC[ARITH_RULE `0x20 = 0x10 + 0x10`; READ_BYTES_AND_BYTE128_SPLIT] THEN - EXISTS_TAC `aes256_xts_encrypt ct 0x20 iv key1 key2` THEN - REPEAT CONJ_TAC THENL - [ - CONV_TAC NUM_REDUCE_CONV; - - MP_TAC (SPECL [`2:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] - LENGTH_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS) THEN - ARITH_TAC; - - REWRITE_TAC[aes256_xts_encrypt] THEN - CONV_TAC NUM_REDUCE_CONV THEN - REWRITE_TAC[LET_DEF; LET_END_DEF] THEN - CONV_TAC NUM_REDUCE_CONV THEN - MP_TAC (SPECL [`ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] - LENGTH_OF_AES256_XTS_ENCRYPT_REC_TRIVIAL) THEN - IMP_REWRITE_TAC[SUB_LIST_APPEND_RIGHT_LEMMA] THEN DISCH_TAC THEN - REWRITE_TAC[aes256_xts_encrypt_tail] THEN - REWRITE_TAC[LET_DEF; LET_END_DEF] THEN - REWRITE_TAC[SUB_LIST_OF_INT128_TO_BYTES] THEN - REWRITE_TAC[NUM_OF_BYTELIST_OF_INT128_TO_BYTES] THEN - REWRITE_TAC[BYTES_TO_INT128_OF_INT128_TO_BYTES] THEN - CONV_TAC NUM_REDUCE_CONV; - - MP_TAC (SPECL [`1:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] - SUB_LIST_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS) THEN - CONV_TAC NUM_REDUCE_CONV THEN - SIMP_TAC[] THEN DISCH_TAC THEN - IMP_REWRITE_TAC[READ_BYTES_EQ_READ_BYTE128_1BLOCK_ENC] THEN - MP_TAC (SPECL [`1:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] - LENGTH_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS) THEN - CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC THEN - IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] - ] -);; - -let READ_BYTES_EQ_READ_BYTE128_3BLOCKS_ENC = prove( - `!(ptr:int64) (ct:byte list) (iv:int128) (key1:int128 list) (key2:int128 list) s. - (read (memory :> bytes128 pt_ptr) s = - aes256_xts_encrypt_round (bytes_to_int128 (SUB_LIST (0x0,0x10) ct)) - (calculate_tweak 0x0 iv key2) - key1) ==> - (read (memory :> bytes128 (word_add pt_ptr (word 0x10))) s = - aes256_xts_encrypt_round (bytes_to_int128 (SUB_LIST (0x10,0x10) ct)) - (calculate_tweak 0x1 iv key2) - key1) ==> - (read (memory :> bytes128 (word_add pt_ptr (word 0x20))) s = - aes256_xts_encrypt_round (bytes_to_int128 (SUB_LIST (0x20,0x10) ct)) - (calculate_tweak 0x2 iv key2) - key1) ==> - read (memory :> bytes (pt_ptr,0x30)) s = - num_of_bytelist (SUB_LIST (0x0,0x30) (aes256_xts_encrypt ct 0x30 iv key1 key2))`, - REPEAT STRIP_TAC THEN - IMP_REWRITE_TAC[ARITH_RULE `0x30 = 0x20 + 0x10`; READ_BYTES_AND_BYTE128_SPLIT] THEN - EXISTS_TAC `aes256_xts_encrypt ct 0x30 iv key1 key2` THEN - REPEAT CONJ_TAC THENL - [ - CONV_TAC NUM_REDUCE_CONV; - - MP_TAC (SPECL [`3:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] - LENGTH_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS) THEN - ARITH_TAC; - - REWRITE_TAC[aes256_xts_encrypt] THEN - CONV_TAC NUM_REDUCE_CONV THEN - REWRITE_TAC[LET_DEF; LET_END_DEF] THEN - CONV_TAC NUM_REDUCE_CONV THEN - MP_TAC (SPECL [`0:num`; `1:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] - LENGTH_OF_AES256_XTS_ENCRYPT_REC) THEN - CONV_TAC NUM_REDUCE_CONV THEN - IMP_REWRITE_TAC[SUB_LIST_APPEND_RIGHT_LEMMA] THEN DISCH_TAC THEN - REWRITE_TAC[aes256_xts_encrypt_tail] THEN - REWRITE_TAC[LET_DEF; LET_END_DEF] THEN - REWRITE_TAC[SUB_LIST_OF_INT128_TO_BYTES] THEN - REWRITE_TAC[NUM_OF_BYTELIST_OF_INT128_TO_BYTES] THEN - REWRITE_TAC[BYTES_TO_INT128_OF_INT128_TO_BYTES] THEN - CONV_TAC NUM_REDUCE_CONV; - ALL_TAC] THEN - - MP_TAC (SPECL [`2:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] - SUB_LIST_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS) THEN - CONV_TAC NUM_REDUCE_CONV THEN - SIMP_TAC[] THEN DISCH_TAC THEN - IMP_REWRITE_TAC[READ_BYTES_EQ_READ_BYTE128_2BLOCKS_ENC] THEN - MP_TAC (SPECL [`2:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] - LENGTH_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS) THEN - CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC THEN - IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] -);; - -let READ_BYTES_EQ_READ_BYTE128_4BLOCKS_ENC = prove( - `!(ptr:int64) (ct:byte list) (iv:int128) (key1:int128 list) (key2:int128 list) s. - (read (memory :> bytes128 pt_ptr) s = - aes256_xts_encrypt_round (bytes_to_int128 (SUB_LIST (0x0,0x10) ct)) - (calculate_tweak 0x0 iv key2) - key1) ==> - (read (memory :> bytes128 (word_add pt_ptr (word 0x10))) s = - aes256_xts_encrypt_round (bytes_to_int128 (SUB_LIST (0x10,0x10) ct)) - (calculate_tweak 0x1 iv key2) - key1) ==> - (read (memory :> bytes128 (word_add pt_ptr (word 0x20))) s = - aes256_xts_encrypt_round (bytes_to_int128 (SUB_LIST (0x20,0x10) ct)) - (calculate_tweak 0x2 iv key2) - key1) ==> - (read (memory :> bytes128 (word_add pt_ptr (word 0x30))) s = - aes256_xts_encrypt_round (bytes_to_int128 (SUB_LIST (0x30,0x10) ct)) - (calculate_tweak 0x3 iv key2) - key1) ==> - read (memory :> bytes (pt_ptr,0x40)) s = - num_of_bytelist (SUB_LIST (0x0,0x40) (aes256_xts_encrypt ct 0x40 iv key1 key2))`, - REPEAT STRIP_TAC THEN - IMP_REWRITE_TAC[ARITH_RULE `0x40 = 0x30 + 0x10`; READ_BYTES_AND_BYTE128_SPLIT] THEN - EXISTS_TAC `aes256_xts_encrypt ct 0x40 iv key1 key2` THEN - REPEAT CONJ_TAC THENL - [ - CONV_TAC NUM_REDUCE_CONV; - - MP_TAC (SPECL [`4:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] - LENGTH_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS) THEN - ARITH_TAC; - - REWRITE_TAC[aes256_xts_encrypt] THEN - CONV_TAC NUM_REDUCE_CONV THEN - REWRITE_TAC[LET_DEF; LET_END_DEF] THEN - CONV_TAC NUM_REDUCE_CONV THEN - MP_TAC (SPECL [`0:num`; `2:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] - LENGTH_OF_AES256_XTS_ENCRYPT_REC) THEN - CONV_TAC NUM_REDUCE_CONV THEN - IMP_REWRITE_TAC[SUB_LIST_APPEND_RIGHT_LEMMA] THEN DISCH_TAC THEN - REWRITE_TAC[aes256_xts_encrypt_tail] THEN - REWRITE_TAC[LET_DEF; LET_END_DEF] THEN - REWRITE_TAC[SUB_LIST_OF_INT128_TO_BYTES] THEN - REWRITE_TAC[BYTES_TO_INT128_OF_INT128_TO_BYTES] THEN - CONV_TAC NUM_REDUCE_CONV; - ALL_TAC] THEN - - MP_TAC (SPECL [`3:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] - SUB_LIST_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS) THEN - CONV_TAC NUM_REDUCE_CONV THEN - SIMP_TAC[] THEN DISCH_TAC THEN - IMP_REWRITE_TAC[READ_BYTES_EQ_READ_BYTE128_3BLOCKS_ENC] THEN - MP_TAC (SPECL [`3:num`; `ct:byte list`; `iv:int128`; `key1:int128 list`; `key2:int128 list`] - LENGTH_OF_AES256_XTS_ENCRYPT_FULL_BLOCKS) THEN - CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC THEN - IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] -);; (* Proof: Less than 2 blocks *) let AES_XTS_ENCRYPT_LT_2BLOCK_CORRECT = time prove( @@ -4909,7 +2670,7 @@ let AES_XTS_ENCRYPT_LT_2BLOCK_CORRECT = time prove( SUBGOAL_THEN `val (len_full_blocks:int64) = 16` ASSUME_TAC THENL [ EXPAND_TAC "len_full_blocks" THEN - REWRITE_TAC[LEN_FULL_BLOCKS_TO_VAL] THEN + REWRITE_TAC[NUM_BLOCKS_TO_VAL] THEN IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN CONV_TAC NUM_REDUCE_CONV THEN SUBGOAL_THEN `val (len:int64) DIV 16 = 1` SUBST1_TAC THENL @@ -5084,7 +2845,7 @@ let AES_XTS_ENCRYPT_LT_3BLOCK_CORRECT = time prove( SUBGOAL_THEN `val (len_full_blocks:int64) = 0x20` ASSUME_TAC THENL [ EXPAND_TAC "len_full_blocks" THEN - REWRITE_TAC[LEN_FULL_BLOCKS_TO_VAL] THEN + REWRITE_TAC[NUM_BLOCKS_TO_VAL] THEN IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN CONV_TAC NUM_REDUCE_CONV THEN SUBGOAL_THEN `val (len:int64) DIV 16 = 2` SUBST1_TAC THENL @@ -5253,7 +3014,7 @@ let AES_XTS_ENCRYPT_LT_4BLOCK_CORRECT = time prove( SUBGOAL_THEN `val (len_full_blocks:int64) = 0x30` ASSUME_TAC THENL [ EXPAND_TAC "len_full_blocks" THEN - REWRITE_TAC[LEN_FULL_BLOCKS_TO_VAL] THEN + REWRITE_TAC[NUM_BLOCKS_TO_VAL] THEN IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN CONV_TAC NUM_REDUCE_CONV THEN SUBGOAL_THEN `val (len:int64) DIV 16 = 3` SUBST1_TAC THENL @@ -5426,7 +3187,7 @@ let AES_XTS_ENCRYPT_LT_5BLOCK_CORRECT = time prove( SUBGOAL_THEN `val (len_full_blocks:int64) = 0x40` ASSUME_TAC THENL [ EXPAND_TAC "len_full_blocks" THEN - REWRITE_TAC[LEN_FULL_BLOCKS_TO_VAL] THEN + REWRITE_TAC[NUM_BLOCKS_TO_VAL] THEN IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN CONV_TAC NUM_REDUCE_CONV THEN SUBGOAL_THEN `val (len:int64) DIV 16 = 4` SUBST1_TAC THENL @@ -5674,7 +3435,7 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( SUBGOAL_THEN `val (len_full_blocks:int64) <= 0x2 EXP 24` ASSUME_TAC THENL [ UNDISCH_TAC `val (len:int64) <= 0x2 EXP 24` THEN UNDISCH_TAC `word_and len (word 0xfffffffffffffff0) = (len_full_blocks:int64)` THEN - MP_TAC (SPECL [`len:int64`; `len_full_blocks:int64`] LEN_FULL_BLOCKS_HI_BOUND_THM) THEN + MP_TAC (SPECL [`len:int64`; `len_full_blocks:int64`] NUM_BLOCKS_HI_BOUND_THM) THEN SIMP_TAC[]; ALL_TAC] THEN SUBGOAL_THEN `0 < val (num_5blocks:int64)` ASSUME_TAC THENL @@ -5686,7 +3447,7 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( ; ALL_TAC] THEN SUBGOAL_THEN `val (len_full_blocks:int64) <= val (len:int64)` ASSUME_TAC THENL - [ EXPAND_TAC "len_full_blocks" THEN SIMP_TAC[LEN_FULL_BLOCKS_LT_LEN_THM]; ALL_TAC] THEN + [ EXPAND_TAC "len_full_blocks" THEN SIMP_TAC[NUM_BLOCKS_LT_LEN_THM]; ALL_TAC] THEN SUBGOAL_THEN `val (num_5blocks:int64) * 0x50 <= val (len_full_blocks:int64)` ASSUME_TAC THENL [ EXPAND_TAC "num_5blocks" THEN @@ -5895,7 +3656,7 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( SUBGOAL_THEN `i + 1 <= val (num_5blocks:int64)` MP_TAC THENL [ ASM_ARITH_TAC; ALL_TAC ] THEN SUBGOAL_THEN `val (len_full_blocks:int64) <= val (len:int64)` ASSUME_TAC THENL - [ EXPAND_TAC "len_full_blocks" THEN SIMP_TAC[LEN_FULL_BLOCKS_LT_LEN_THM]; ALL_TAC ] THEN + [ EXPAND_TAC "len_full_blocks" THEN SIMP_TAC[NUM_BLOCKS_LT_LEN_THM]; ALL_TAC ] THEN SUBGOAL_THEN `val (num_5blocks:int64) * 0x50 <= val (len:int64)` ASSUME_TAC THENL [ EXPAND_TAC "num_5blocks" THEN REWRITE_TAC [VAL_WORD; DIMINDEX_64] THEN @@ -5929,7 +3690,7 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( ENSURES_INIT_TAC "s0" THEN (* List values for ptxt_p + [0 .. 0x40] *) - MP_TAC (SPECL [`ptxt_p:int64`; `i:num`; `len:int64`; `pt_in:byte list`; `s0:armstate`] READ_CT_LEMMA) THEN + MP_TAC (SPECL [`ptxt_p:int64`; `i:num`; `len:int64`; `pt_in:byte list`; `s0:armstate`] READ_BL_LEMMA) THEN ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN (* Prove Q0, Q1, Q24, Q25, Q26 stores correct plaintext *) (* and prove Q6, Q8, Q9, Q10, Q11 stores correct tweak: *) @@ -6522,7 +4283,7 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( UNDISCH_TAC `val (len_full_blocks:int64) <= val (len:int64)` THEN ARITH_TAC ; ALL_TAC] THEN - MP_TAC (SPECL [`ptxt_p:int64`; `num_5blocks:int64`; `len:int64`; `pt_in:byte list`; `s3:armstate`] READ_CT_TAIL4_LEMMA) THEN + MP_TAC (SPECL [`ptxt_p:int64`; `num_5blocks:int64`; `len:int64`; `pt_in:byte list`; `s3:armstate`] READ_TAIL4_LEMMA) THEN ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (4--127) THEN @@ -6994,7 +4755,7 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( UNDISCH_TAC `val (len_full_blocks:int64) <= val (len:int64)` THEN ARITH_TAC; ALL_TAC] THEN MP_TAC (SPECL [`ptxt_p:int64`; `num_5blocks:int64`; `len:int64`; `pt_in:byte list`; `s5:armstate`] - READ_CT_TAIL3_LEMMA) THEN + READ_TAIL3_LEMMA) THEN ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (6--97) THEN @@ -7291,7 +5052,7 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( UNDISCH_TAC `val (len_full_blocks:int64) <= val (len:int64)` THEN ARITH_TAC; ALL_TAC] THEN MP_TAC (SPECL [`ptxt_p:int64`; `num_5blocks:int64`; `len:int64`; `pt_in:byte list`; `s7:armstate`] - READ_CT_TAIL2_LEMMA) THEN + READ_TAIL2_LEMMA) THEN ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (8--68) THEN @@ -7525,7 +5286,7 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( UNDISCH_TAC `val (len_full_blocks:int64) <= val (len:int64)` THEN ARITH_TAC; ALL_TAC] THEN MP_TAC (SPECL [`ptxt_p:int64`; `num_5blocks:int64`; `len:int64`; `pt_in:byte list`; `s9:armstate`] - READ_CT_TAIL1_LEMMA) THEN + READ_TAIL1_LEMMA) THEN ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN ARM_ACCSTEPS_TAC AES256_XTS_ENCRYPT_EXEC [] (10--40) THEN @@ -7671,7 +5432,7 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( ARITH_TAC; EXPAND_TAC "len_full_blocks" THEN - REWRITE_TAC[LEN_FULL_BLOCKS_TO_VAL] THEN + REWRITE_TAC[NUM_BLOCKS_TO_VAL] THEN IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT; DIVIDES_RMUL; DIVIDES_REFL] THEN UNDISCH_TAC `val (len:int64) <= 0x2 EXP 0x18` THEN ARITH_TAC; diff --git a/arm/proofs/base.ml b/arm/proofs/base.ml index a9021f9f0..5c3c6046c 100644 --- a/arm/proofs/base.ml +++ b/arm/proofs/base.ml @@ -60,7 +60,7 @@ extra_word_CONV := (* Additional Cryptographic AES intrinsics *) (* ------------------------------------------------------------------------- *) -loadt "arm/proofs/aes.ml";; +loadt "arm/proofs/utils/aes.ml";; extra_word_CONV := [AESE_REDUCE_CONV; AESMC_REDUCE_CONV; AESD_REDUCE_CONV; AESIMC_REDUCE_CONV] diff --git a/arm/proofs/aes.ml b/arm/proofs/utils/aes.ml similarity index 100% rename from arm/proofs/aes.ml rename to arm/proofs/utils/aes.ml diff --git a/arm/proofs/aes_decrypt_spec.ml b/arm/proofs/utils/aes_decrypt_spec.ml similarity index 95% rename from arm/proofs/aes_decrypt_spec.ml rename to arm/proofs/utils/aes_decrypt_spec.ml index b3a4f6b87..539470a94 100644 --- a/arm/proofs/aes_decrypt_spec.ml +++ b/arm/proofs/utils/aes_decrypt_spec.ml @@ -1,10 +1,15 @@ -use_file_raise_failure := true;; +(* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT-0 + *) + needs "common/aes.ml";; -let pp_print_num fmt tm = +(* let pp_print_num fmt tm = let n = dest_numeral tm in pp_print_string fmt (string_of_num_hex n) in -install_user_printer("pp_print_num",pp_print_num);; +install_user_printer("pp_print_num",pp_print_num);; +*) (* NIST: https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.197-upd1.pdf diff --git a/arm/proofs/aes_encrypt_spec.ml b/arm/proofs/utils/aes_encrypt_spec.ml similarity index 96% rename from arm/proofs/aes_encrypt_spec.ml rename to arm/proofs/utils/aes_encrypt_spec.ml index 30bf82d6f..a6792e4ad 100644 --- a/arm/proofs/aes_encrypt_spec.ml +++ b/arm/proofs/utils/aes_encrypt_spec.ml @@ -1,10 +1,15 @@ -use_file_raise_failure := true;; +(* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT-0 + *) + needs "common/aes.ml";; -let pp_print_num fmt tm = +(* let pp_print_num fmt tm = let n = dest_numeral tm in pp_print_string fmt (string_of_num_hex n) in -install_user_printer("pp_print_num",pp_print_num);; +install_user_printer("pp_print_num",pp_print_num);; +*) (* // NIST FIPS 197 - Advanced Encryption Standard (AES) diff --git a/arm/proofs/utils/aes_xts_common.ml b/arm/proofs/utils/aes_xts_common.ml new file mode 100644 index 000000000..15f2b5041 --- /dev/null +++ b/arm/proofs/utils/aes_xts_common.ml @@ -0,0 +1,2443 @@ +(* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT-0 + *) + +(* BOZO: Do I need all of base?*) +needs "arm/proofs/base.ml";; +needs "arm/proofs/utils/aes_xts_encrypt_spec.ml";; +needs "arm/proofs/utils/aes_xts_decrypt_spec.ml";; + +(**********************************************************************) +(** Common definitions **) + +(* For defining the input and output buffers of arbitrary length len. + byte_list_at is adapted from Amanda's code at + https://github.com/amanda-zx/s2n-bignum/blob/ed25519/arm/sha512/utils.ml *) +let byte_list_at = define + `byte_list_at (m : byte list) (m_p : int64) (len: int64) s = + ! i. i < val len ==> read (memory :> bytes8(word_add m_p (word i))) s = EL i m`;; + +(** Function for initializing key schedule *) +let set_key_schedule = new_definition + `set_key_schedule (s:armstate) (key_ptr:int64) (k0:int128) + (k1:int128) (k2:int128) (k3:int128) (k4:int128) (k5:int128) + (k6:int128) (k7:int128) (k8:int128) (k9:int128) (ka:int128) + (kb:int128) (kc:int128) (kd:int128) (ke:int128) : bool = + (read(memory :> bytes128 key_ptr) s = k0 /\ + read(memory :> bytes128 (word_add key_ptr (word 16))) s = k1 /\ + read(memory :> bytes128 (word_add key_ptr (word 32))) s = k2 /\ + read(memory :> bytes128 (word_add key_ptr (word 48))) s = k3 /\ + read(memory :> bytes128 (word_add key_ptr (word 64))) s = k4 /\ + read(memory :> bytes128 (word_add key_ptr (word 80))) s = k5 /\ + read(memory :> bytes128 (word_add key_ptr (word 96))) s = k6 /\ + read(memory :> bytes128 (word_add key_ptr (word 112))) s = k7 /\ + read(memory :> bytes128 (word_add key_ptr (word 128))) s = k8 /\ + read(memory :> bytes128 (word_add key_ptr (word 144))) s = k9 /\ + read(memory :> bytes128 (word_add key_ptr (word 160))) s = ka /\ + read(memory :> bytes128 (word_add key_ptr (word 176))) s = kb /\ + read(memory :> bytes128 (word_add key_ptr (word 192))) s = kc /\ + read(memory :> bytes128 (word_add key_ptr (word 208))) s = kd /\ + read(memory :> bytes128 (word_add key_ptr (word 224))) s = ke /\ + read(memory :> bytes32 (word_add key_ptr (word 240))) s = word 14)`;; + +(** Define length of rest of input in bytes after the loop *) +let acc_len = new_definition +`acc_len (i:int64) (len:int64) : num = + if val i * 0x50 + 0x40 = val len then 0x50 * val i + 0x40 + else + if val i * 0x50 + 0x30 = val len then 0x50 * val i + 0x30 + else + if val i * 0x50 + 0x20 = val len then 0x50 * val i + 0x20 + else + if val i * 0x50 + 0x10 = val len then 0x50 * val i + 0x10 + else 0x50 * val i`;; + +(** Define length of rest of input in blocks after the loop *) +let acc_blocks = new_definition +`acc_blocks (i:int64) (len:int64) (last:bool) : num = + if val i * 0x50 + 0x40 = val len then val i * 0x5 + 4 + else + if val i * 0x50 + 0x30 = val len then val i * 0x5 + 3 + else + if val i * 0x50 + 0x20 = val len then val i * 0x5 + 2 + else + if val i * 0x50 + 0x10 = val len then val i * 0x5 + 1 + else val i * 0x5`;; + +(* The cipher-stealing invariant is the block read at ctxt_p + curr_len - 16 where Cm is being replaced by Pm + one byte at a time with a decreasing offset i from the beginning of the block. + Differs from decrypt in that, there, it's curr_len. + The following is copied from decrypt and will be instantiated with l1_curr_len (= curr_len-16) instead of curr_len *) +let cipher_stealing_inv = new_definition +`cipher_stealing_inv (i:num) (curr_len:num) (tail_len:num) (PP:int128) (ct:byte list): int128 = + bytes_to_int128( + APPEND (SUB_LIST (0, i) (int128_to_bytes PP)) + (APPEND (SUB_LIST (i, tail_len - i) (SUB_LIST (curr_len + 16, tail_len) ct)) + (SUB_LIST (tail_len, 16 - tail_len) (int128_to_bytes PP))))`;; + + +(**********************************************************************) +(** Common List Lemmas **) + +let SUB_LIST_SUCSPLIT = prove( + `!(l:A list) n p. SUB_LIST(p,SUC n) l = APPEND (SUB_LIST(p,1) l) (SUB_LIST(p+1,n) l)`, + REPEAT STRIP_TAC THEN + REWRITE_TAC [ARITH_RULE `SUC n = 1 + n`] THEN + REWRITE_TAC [SUB_LIST_SPLIT] +);; + +let HD_SUB_LIST_CONS = prove + (`!(h:A) (t:A list) n. 0 < n ==> HD (SUB_LIST (0,n) (CONS h t)) = h`, + REPEAT GEN_TAC THEN STRIP_TAC THEN + MP_TAC(SPEC `n:num` num_CASES) THEN + ASM_SIMP_TAC[ARITH_RULE `0 < n ==> ~(n = 0)`] THEN + DISCH_THEN(X_CHOOSE_THEN `m:num` SUBST_ALL_TAC) THEN + REWRITE_TAC[SUB_LIST_CLAUSES; HD]);; + +let HD_SUB_LIST_CONS_GENERAL = prove( + `!p n (l:A list). p < LENGTH l /\ 0 < n ==> HD (SUB_LIST (p,n) l) = EL p l`, + INDUCT_TAC THENL + [ + GEN_TAC THEN + LIST_INDUCT_TAC THENL + [ + REWRITE_TAC[LENGTH] THEN ARITH_TAC; + REPEAT STRIP_TAC THEN + REWRITE_TAC[EL; HD] THEN + MP_TAC (SPECL [`h:A`; `t:A list`; `n:num`] HD_SUB_LIST_CONS) THEN + ASM_SIMP_TAC[] + ]; ALL_TAC + ] THEN + GEN_TAC THEN + LIST_INDUCT_TAC THENL + [ + REWRITE_TAC[LENGTH] THEN ARITH_TAC; + REPEAT STRIP_TAC THEN + REWRITE_TAC[SUB_LIST_CLAUSES] THEN + REWRITE_TAC[EL; TL] THEN + FIRST_X_ASSUM (fun th -> MATCH_MP_TAC (SPECL [`n:num`; `t:A list`] th)) THEN + ASM_SIMP_TAC[] THEN + UNDISCH_TAC `SUC p < LENGTH (CONS h (t:A list))` THEN + REWRITE_TAC[LENGTH] THEN + ARITH_TAC + ] +);; + +let TL_SUB_LIST_CONS = prove +(`!(h:A) (t:A list) n. 0 < n ==> TL (SUB_LIST (0,n) (CONS h t)) = SUB_LIST (0, n - 1) t`, + REPEAT GEN_TAC THEN STRIP_TAC THEN + MP_TAC(SPEC `n:num` num_CASES) THEN + ASM_SIMP_TAC[ARITH_RULE `0 < n ==> ~(n = 0)`] THEN + DISCH_THEN(X_CHOOSE_THEN `m:num` SUBST_ALL_TAC) THEN + REWRITE_TAC[SUB_LIST_CLAUSES; TL] THEN + REWRITE_TAC[ARITH_RULE `SUC m - 1 = m`]);; + +let TL_SUB_LIST_CONS_GENERAL = prove( + `!p n (l:A list). p < LENGTH l ==> 0 < n + ==> TL (SUB_LIST (p, n) l) = SUB_LIST (p + 1, n - 1) l`, + INDUCT_TAC THENL + [ + GEN_TAC THEN + LIST_INDUCT_TAC THENL + [ + REWRITE_TAC[LENGTH] THEN ARITH_TAC; + CONV_TAC NUM_REDUCE_CONV THEN + REPEAT STRIP_TAC THEN + MP_TAC (SPECL [`h:A`; `t:A list`; `n:num`] TL_SUB_LIST_CONS) THEN + ASM_SIMP_TAC[num_CONV `1`; SUB_LIST_CLAUSES] + ]; ALL_TAC + ] THEN + GEN_TAC THEN + LIST_INDUCT_TAC THENL + [ + REWRITE_TAC[LENGTH] THEN ARITH_TAC; + REPEAT STRIP_TAC THEN + REWRITE_TAC[ARITH_RULE `SUC p + 1 = SUC (p + 1)`] THEN + REWRITE_TAC[SUB_LIST_CLAUSES] THEN + FIRST_X_ASSUM (fun th -> MP_TAC (SPECL [`n:num`; `t:A list`] th)) THEN + SUBGOAL_THEN `p < LENGTH (t:A list)` ASSUME_TAC THENL + [ UNDISCH_TAC `SUC p < LENGTH (CONS h (t:A list))` THEN + REWRITE_TAC[LENGTH] THEN ARITH_TAC + ; ALL_TAC] THEN + ASM_SIMP_TAC[] + ] +);; + +let EL_SUB_LIST_TRIVIAL = prove( + `!i n (l:A list). i < LENGTH l /\ 0 < n ==> EL 0x0 (SUB_LIST (i, n) l) = EL i l`, + REWRITE_TAC[EL] THEN + SIMP_TAC[HD_SUB_LIST_CONS_GENERAL] +);; + +let EL_SUB_LIST = prove( + `!(i:num) n (l:A list). i < n /\ n <= LENGTH l ==> + EL i (SUB_LIST (0, n) l) = EL i l`, + INDUCT_TAC THENL + [ (* i = 0 *) + ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN + LIST_INDUCT_TAC THENL + [ + REPEAT STRIP_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_TRIVIAL] THEN + REWRITE_TAC[LENGTH] THEN + ARITH_TAC; ALL_TAC + ] THEN + REPEAT STRIP_TAC THEN + IMP_REWRITE_TAC[EL; HD; HD_SUB_LIST_CONS]; + ALL_TAC + ] THEN + (* i != 0 *) + ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN + LIST_INDUCT_TAC THENL + [ + REPEAT STRIP_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_TRIVIAL] THEN + REWRITE_TAC[LENGTH] THEN + ARITH_TAC; ALL_TAC + ] THEN + REPEAT STRIP_TAC THEN + REWRITE_TAC[EL; TL] THEN + IMP_REWRITE_TAC[TL_SUB_LIST_CONS] THEN + REPEAT CONJ_TAC THENL + [ ASM_SIMP_TAC[ARITH_RULE `SUC i < n ==> i < n - 1`]; + SUBGOAL_THEN `LENGTH (CONS h (t:A list)) = SUC (LENGTH t)` ASSUME_TAC THENL + [ REWRITE_TAC[LENGTH]; ALL_TAC ] THEN + ASM_ARITH_TAC; + MP_TAC (ARITH_RULE `SUC i < n ==> 0 < n`) THEN + ASM_SIMP_TAC[] + ] +);; + +let EL_SUB_LIST_GENERAL = prove( + `!p (l:A list) i n. i >= p /\ i < p + n /\ p + n <= LENGTH l ==> + EL (i - p) (SUB_LIST (p, n) l) = EL i l`, + INDUCT_TAC THENL + [ IMP_REWRITE_TAC[ADD; SUB_0; EL_SUB_LIST]; + ALL_TAC + ] THEN + LIST_INDUCT_TAC THENL + [ REWRITE_TAC[SUB_LIST_CLAUSES; LENGTH] THEN + REPEAT STRIP_TAC THEN + ASM_ARITH_TAC; + ALL_TAC + ] THEN + REWRITE_TAC[LENGTH] THEN + REPEAT STRIP_TAC THEN + REWRITE_TAC[SUB_LIST_CLAUSES] THEN + SUBGOAL_THEN `EL i (CONS h (t:A list)) = EL (i - 1) t` SUBST1_TAC THENL + [ SUBGOAL_THEN `i = SUC (i - 1)` SUBST1_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC] THEN + REWRITE_TAC[EL; TL] THEN + AP_THM_TAC THEN AP_TERM_TAC THEN + ARITH_TAC; ALL_TAC] THEN + REWRITE_TAC[ARITH_RULE `i - SUC p = i - 1 - p`] THEN + FIRST_X_ASSUM (fun th -> MP_TAC (SPECL [`t:A list`; `(i - 1):num`; `n:num`] th)) THEN + ANTS_TAC THENL [ ASM_ARITH_TAC; ALL_TAC ] THEN + SIMP_TAC[] +);; + +let EL_SUB_LIST_SHIFT = prove( + `!(i:num) p (l:A list) n. 0 < i /\ i < n /\ n <= LENGTH l - p ==> + EL (i - 1) (SUB_LIST (p + 1, n - 1) l) = EL i (SUB_LIST (p, n) l)`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN `EL i (SUB_LIST (p, n) (l:A list)) = EL (SUC (i - 1)) (SUB_LIST (p, SUC (n - 1)) l)` SUBST1_TAC THENL + [ IMP_REWRITE_TAC[ARITH_RULE `0 < i ==> SUC (i - 1) = i`] THEN + ASM_ARITH_TAC; ALL_TAC ] THEN + DISJ_CASES_TAC (ISPEC `l:(A)list` list_CASES) THENL [ + FIRST_X_ASSUM SUBST_ALL_TAC THEN + UNDISCH_TAC `n <= LENGTH ([]:A list) - p` THEN + REWRITE_TAC[LENGTH] THEN + ASM_ARITH_TAC; ALL_TAC + ] THEN + + REPEAT_N 2 (FIRST_X_ASSUM CHOOSE_TAC) THEN + FIRST_X_ASSUM SUBST_ALL_TAC THEN + REWRITE_TAC[EL; TL] THEN + IMP_REWRITE_TAC[TL_SUB_LIST_CONS_GENERAL] THEN + IMP_REWRITE_TAC[ARITH_RULE `0 < n ==> SUC (n - 1) = n`] THEN + ASM_ARITH_TAC + );; + + +let SUB_LIST_APPEND_RIGHT_LEMMA = prove( + `!(x:A list) y n m. LENGTH x = n ==> SUB_LIST (n,m) (APPEND x y) = SUB_LIST (0,m) y`, + LIST_INDUCT_TAC THENL + [ REPEAT GEN_TAC THEN + SIMP_TAC[CONJUNCT1 LENGTH; APPEND; SUB_LIST_CLAUSES]; + + ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN + INDUCT_TAC THENL[ + SIMP_TAC[LENGTH_EQ_NIL] THEN REWRITE_TAC[APPEND]; + ASM_SIMP_TAC[APPEND; LENGTH; SUB_LIST_CLAUSES; SUC_INJ]]]);; + +let SUB_LIST_APPEND_RIGHT_GENERAL = prove( + `!(x:A list) y n m p. LENGTH x = p ==> n >= p ==> + SUB_LIST (n,m) (APPEND x y) = SUB_LIST (n - p,m) y`, + LIST_INDUCT_TAC THENL + [ + REPEAT GEN_TAC THEN + SIMP_TAC[CONJUNCT1 LENGTH; APPEND; SUB_LIST_CLAUSES] THEN + DISCH_THEN (fun th -> REWRITE_TAC[GSYM th]) THEN + REWRITE_TAC[SUB_0]; + + ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN + INDUCT_TAC THENL + [ + REPEAT STRIP_TAC THEN + SUBGOAL_THEN `p = 0` SUBST_ALL_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN + CONV_TAC NUM_REDUCE_CONV THEN + SUBGOAL_THEN `CONS h t = ([]:A list)` ASSUME_TAC THENL + [ UNDISCH_TAC `LENGTH (CONS h (t:A list)) = 0` THEN + SIMP_TAC[LENGTH_EQ_NIL]; ALL_TAC] THEN + ASM_REWRITE_TAC[] THEN + REWRITE_TAC[APPEND]; + + REPEAT STRIP_TAC THEN + SUBGOAL_THEN `p > 0` ASSUME_TAC THENL + [ UNDISCH_TAC `LENGTH (CONS h (t:A list)) = p` THEN + ASM_REWRITE_TAC[LENGTH] THEN + MP_TAC (SPEC `LENGTH (t:A list)` (ARITH_RULE `!x. SUC x > 0`)) THEN + ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `LENGTH (t:A list) = p - 1` ASSUME_TAC THENL + [ UNDISCH_TAC `LENGTH (CONS h (t:A list)) = p` THEN + ASM_REWRITE_TAC[LENGTH] THEN + MP_TAC (SPECL [`LENGTH (t:A list)`; `p:num`] (ARITH_RULE `!n m. SUC n = m ==> n = m - 1`)) THEN + SIMP_TAC[]; ALL_TAC] THEN + SUBGOAL_THEN `n >= p - 1` ASSUME_TAC THENL + [ MP_TAC (ARITH_RULE `SUC n >= p /\ p > 0 ==> n >= p - 1`) THEN + ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `SUC n - p = n - (p - 1)` ASSUME_TAC THENL + [ MP_TAC (ARITH_RULE `SUC n >= p /\ p > 0 ==> SUC n - p = n - (p - 1)`) THEN + ASM_ARITH_TAC; ALL_TAC] THEN + ASM_REWRITE_TAC[APPEND; LENGTH; SUB_LIST_CLAUSES; SUC_INJ] THEN + FIRST_X_ASSUM (fun th -> MP_TAC (SPECL [`y:A list`; `n:num`; `m:num`; `(p-1):num`] th)) THEN + ASM_SIMP_TAC[] + ] + ] +);; + +let SUB_LIST_LENGTH_IMPLIES = prove( + `!(l:A list) n. LENGTH l = n ==> SUB_LIST(0,n) l = l`, + REPEAT STRIP_TAC THEN + UNDISCH_THEN `LENGTH (l:A list) = n` (fun th -> REWRITE_TAC[GSYM th]) THEN + REWRITE_TAC[SUB_LIST_LENGTH] +);; + +let SUB_LIST_IDEMPOTENT_P = prove( + `!p n (l:(A)list). SUB_LIST (0,n) (SUB_LIST (p,n) l) = SUB_LIST (p,n) l`, + INDUCT_TAC THENL[ + REWRITE_TAC[SUB_LIST_IDEMPOTENT]; + + REPEAT STRIP_TAC THEN + DISJ_CASES_TAC (ISPEC `l:(A)list` list_CASES) THENL [ + ASM_REWRITE_TAC[] THEN REWRITE_TAC[SUB_LIST_CLAUSES]; + ALL_TAC + ] THEN + FIRST_X_ASSUM MP_TAC THEN STRIP_TAC THEN + ASM_REWRITE_TAC[] THEN REWRITE_TAC[SUB_LIST_CLAUSES] THEN + ASM_REWRITE_TAC[] + ]);; + +let SUB_LIST_MIN_RIGHT = prove( + `!p (l:(A)list) (n:num) m. SUB_LIST (0,n) (SUB_LIST (p,m) l) = SUB_LIST (p, MIN n m) l`, + REPEAT STRIP_TAC THEN + ASM_CASES_TAC `(m:num) <= n` THENL [ + FIRST_X_ASSUM MP_TAC THEN REWRITE_TAC[LE_EXISTS] THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[SUB_LIST_SPLIT;ADD_CLAUSES;ARITH_RULE`MIN ((x:num)+y) x = x`] THEN + REWRITE_TAC[SUB_LIST_IDEMPOTENT_P] THEN + GEN_REWRITE_TAC RAND_CONV [GSYM APPEND_NIL] THEN + AP_TERM_TAC THEN MATCH_MP_TAC SUB_LIST_TRIVIAL THEN + REWRITE_TAC[LENGTH_SUB_LIST] THEN ARITH_TAC; ALL_TAC] THEN + + IMP_REWRITE_TAC[ARITH_RULE `~(m <= n) ==> MIN n m = n`] THEN + FIRST_X_ASSUM MP_TAC THEN REWRITE_TAC[NOT_LE;LT_EXISTS] THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[SUB_LIST_SPLIT;ADD_CLAUSES;ARITH_RULE`MIN (x:num) (x+y) = x`] THEN + + MP_TAC (ISPECL [`l:A list`; `p:num`; `n:num`] LENGTH_SUB_LIST) THEN + ASM_CASES_TAC `n <= LENGTH (l:A list) - p` THENL [ + IMP_REWRITE_TAC[ARITH_RULE `!n m. n <= m ==> MIN n m = n`] THEN + DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_APPEND_LEFT] THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] THEN + ARITH_TAC; ALL_TAC + ] THEN + + IMP_REWRITE_TAC[ARITH_RULE `!n m. ~(n <= m) ==> MIN n m = m`] THEN + SUBGOAL_THEN `SUB_LIST (p + n,SUC d) (l:A list) = []` SUBST1_TAC THENL + [ MATCH_MP_TAC SUB_LIST_TRIVIAL THEN + ASM_ARITH_TAC; ALL_TAC] THEN + REWRITE_TAC[APPEND_NIL] THEN + REWRITE_TAC[SUB_LIST_IDEMPOTENT_P] +);; + +let SUB_LIST_MIN_LEFT = prove( + `!q (l:A list) n m. + SUB_LIST (q,n) (SUB_LIST (0,m) l) = SUB_LIST (q, MIN n (m - q)) l`, + REPEAT STRIP_TAC THEN + ASM_CASES_TAC `n <= m - q` THENL [ + IMP_REWRITE_TAC[ARITH_RULE `x <= y ==> MIN x y = x`] THEN + UNDISCH_TAC `n <= m - q` THEN + MAP_EVERY SPEC1_TAC [`n:num`; `l:A list`; `q:num`; `m:num`] THEN + (* Induct over m *) + INDUCT_TAC THENL + [ + REPEAT STRIP_TAC THEN + IMP_REWRITE_TAC[ARITH_RULE `n <= 0 - q ==> n = 0`] THEN + REWRITE_TAC[SUB_LIST_CLAUSES]; + + INDUCT_TAC THENL + [ + REWRITE_TAC[SUB_0] THEN + REPEAT STRIP_TAC THEN + MP_TAC (SPECL [`0:num`; `l:A list`; `n:num`; `SUC m:num`] SUB_LIST_MIN_RIGHT) THEN + IMP_REWRITE_TAC[ARITH_RULE `x <= y ==> MIN x y = x`]; + + LIST_INDUCT_TAC THENL[ + REWRITE_TAC[SUB_LIST_CLAUSES]; + REWRITE_TAC[SUB_LIST_CLAUSES] THEN + REPEAT STRIP_TAC THEN + FIRST_X_ASSUM + (fun th -> MP_TAC + (SPECL [`q:num`; `t:A list`; `n:num`] th)) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN + SIMP_TAC[] + ] + ] + ]; ALL_TAC + ] THEN + + (* Case n > m - q*) + IMP_REWRITE_TAC[ARITH_RULE `~(x <= y) ==> MIN x y = y`] THEN + UNDISCH_TAC `~(n <= m - q)` THEN + MAP_EVERY SPEC1_TAC [`n:num`; `l:A list`; `q:num`; `m:num`] THEN + INDUCT_TAC THENL + [ + REPEAT STRIP_TAC THEN + REWRITE_TAC[ARITH_RULE `0 - q = 0`] THEN + REWRITE_TAC[SUB_LIST_CLAUSES]; + + INDUCT_TAC THENL + [ + REWRITE_TAC[SUB_0] THEN + REPEAT STRIP_TAC THEN + MP_TAC (SPECL [`0:num`; `l:A list`; `n:num`; `SUC m:num`] SUB_LIST_MIN_RIGHT) THEN + IMP_REWRITE_TAC[ARITH_RULE `~(x <= y) ==> MIN x y = y`]; + + LIST_INDUCT_TAC THENL[ + REWRITE_TAC[SUB_LIST_CLAUSES]; + REWRITE_TAC[SUB_LIST_CLAUSES] THEN + REPEAT STRIP_TAC THEN + REWRITE_TAC[ARITH_RULE `SUC m - SUC q = m - q`] THEN + FIRST_X_ASSUM + (fun th -> MP_TAC + (SPECL [`q:num`; `t:A list`; `n:num`] th)) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN + SIMP_TAC[] + ] + ] + ] +);; + +let SUB_LIST_MIN_GENERAL = prove( + `!p q (l:(A)list) (n:num) m. + SUB_LIST (q,n) (SUB_LIST (p,m) l) = SUB_LIST (p + q, MIN n (m - q)) l`, + REPEAT STRIP_TAC THEN + (* Case n <= m - q *) + ASM_CASES_TAC `n <= m - q` THENL [ + IMP_REWRITE_TAC[ARITH_RULE `x <= y ==> MIN x y = x`] THEN + (* Induct over p *) + UNDISCH_TAC `n <= m - q` THEN + MAP_EVERY SPEC1_TAC [`m:num`; `n:num`; `l:A list`; `q:num`; `p:num`] THEN + INDUCT_TAC THENL + [ + REWRITE_TAC[ADD] THEN + REPEAT STRIP_TAC THEN + MP_TAC (SPECL [`q:num`; `l:A list`; `n:num`; `m:num`] SUB_LIST_MIN_LEFT) THEN + IMP_REWRITE_TAC[ARITH_RULE `x <= y ==> MIN x y = x`]; + ALL_TAC + ] THEN + + ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN + LIST_INDUCT_TAC THENL[ + REWRITE_TAC[SUB_LIST_CLAUSES]; + REWRITE_TAC[ARITH_RULE `SUC p + q = SUC (p + q)`] THEN + REWRITE_TAC[SUB_LIST_CLAUSES] THEN + ASM_REWRITE_TAC[] + ]; ALL_TAC + ] THEN + + (* Case n > m - q*) + IMP_REWRITE_TAC[ARITH_RULE `~(x <= y) ==> MIN x y = y`] THEN + UNDISCH_TAC `~(n <= m - q)` THEN + MAP_EVERY SPEC1_TAC [`m:num`; `n:num`; `l:A list`; `q:num`; `p:num`] THEN + INDUCT_TAC THENL + [ + REWRITE_TAC[ADD] THEN + REPEAT STRIP_TAC THEN + MP_TAC (SPECL [`q:num`; `l:A list`; `n:num`; `m:num`] SUB_LIST_MIN_LEFT) THEN + IMP_REWRITE_TAC[ARITH_RULE `~(x <= y) ==> MIN x y = y`]; + ALL_TAC + ] THEN + + ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN + LIST_INDUCT_TAC THENL[ + REWRITE_TAC[SUB_LIST_CLAUSES]; + REWRITE_TAC[ARITH_RULE `SUC p + q = SUC (p + q)`] THEN + REWRITE_TAC[SUB_LIST_CLAUSES] THEN + ASM_REWRITE_TAC[] + ] +);; + +let NUM_OF_BYTELIST_APPEND = prove + (`!l1 l2. num_of_bytelist (APPEND l1 l2) = + num_of_bytelist l1 + 2 EXP (8 * LENGTH l1) * num_of_bytelist l2`, + LIST_INDUCT_TAC THENL + [ REWRITE_TAC[APPEND; LENGTH; num_of_bytelist; MULT_CLAUSES; EXP; ADD_CLAUSES]; + REWRITE_TAC[APPEND; LENGTH; num_of_bytelist] THEN + ASM_REWRITE_TAC[] THEN + REWRITE_TAC[MULT_SUC; EXP_ADD] THEN + REWRITE_TAC[MULT_ASSOC; LEFT_ADD_DISTRIB] THEN + ARITH_TAC]);; + +let NUM_OF_BYTELIST_OF_SUB_LIST = prove( + `!sz len (x:byte list). + sz <= LENGTH x ==> + num_of_bytelist (SUB_LIST (0, sz + len) x) = + num_of_bytelist (SUB_LIST (0, sz) x) + + 2 EXP (8 * sz) * num_of_bytelist (SUB_LIST (sz, len) x)`, + REPEAT STRIP_TAC THEN + SUBST1_TAC(ISPECL [`x:byte list`; `sz:num`; `len:num`; `0:num`] SUB_LIST_SPLIT) THEN + REWRITE_TAC[NUM_OF_BYTELIST_APPEND] THEN + ASM_SIMP_TAC[LENGTH_SUB_LIST; SUB_0; MIN; ARITH_RULE `0 + sz = sz`] +);; + + +(**********************************************************************) +(** Common Lemmas **) + +let MEMORY_BYTES_BOUND = prove + (`read (memory :> bytes (x,16)) s < 2 EXP dimindex (:128)`, + REWRITE_TAC[READ_COMPONENT_COMPOSE; DIMINDEX_128] THEN + SUBST1_TAC(ARITH_RULE `128 = 8 * 16`) THEN REWRITE_TAC[READ_BYTES_BOUND] + );; + +(* Copied from bignum_copy_row_from_table_8n.ml *) +let READ_MEMORY_BYTES_BYTES128 = prove(`!z s. + read (memory :> bytes (z,16)) s = val (read (memory :> bytes128 z) s)`, + REPEAT GEN_TAC THEN + REWRITE_TAC[el 1 (CONJUNCTS READ_MEMORY_BYTESIZED_SPLIT)] THEN + REWRITE_TAC[VAL_WORD_JOIN;DIMINDEX_64;DIMINDEX_128] THEN + IMP_REWRITE_TAC[MOD_LT] THEN + REWRITE_TAC[ARITH_RULE`2 EXP 128 = 2 EXP 64 * 2 EXP 64`] THEN + IMP_REWRITE_TAC[LT_MULT_ADD_MULT] THEN + REWRITE_TAC[VAL_BOUND_64;ARITH_RULE`0<2 EXP 64`;LE_REFL] THEN + REWRITE_TAC[ARITH_RULE`16 = 8*(1+1)`;GSYM BIGNUM_FROM_MEMORY_BYTES;BIGNUM_FROM_MEMORY_STEP;BIGNUM_FROM_MEMORY_SING] THEN + REWRITE_TAC[ARITH_RULE`8*1=8`;ARITH_RULE`64*1=64`] THEN ARITH_TAC);; + + +let WORD_AND_MASK16 = prove( + `word_and (len:int64) (word 0xfffffffffffffff0) = word_sub len (word_and len (word 0xf))`, + BITBLAST_TAC +);; + +let WORD_AND_MASK16_EQ_0 = prove( + `!(x:int64). val x < 16 ==> ~(val x = 0x0) ==> ~(val (word_and x (word 0xf)) = 0x0)`, + BITBLAST_TAC);; + +let word_split_lemma = prove( + `!len:int64. word_add (word_and len (word 0xf)) + (word_and len (word 0xfffffffffffffff0)) = len`, + BITBLAST_TAC);; + +let BYTE_LIST_AT_ADD_ASSUM_TAC new_pos bound = + let rule = subst [new_pos, `new_pos:num`; bound, `bound:num`] + `(pos:num) + bound <= LENGTH (bl:byte list) ==> new_pos < LENGTH bl` in + let p = subst [new_pos, `new_pos:num`] `new_pos:num` in + MP_TAC (ARITH_RULE rule) THEN + ASM_REWRITE_TAC[] THEN DISCH_THEN (LABEL_TAC "tmp") THEN + FIRST_ASSUM(fun th -> MP_TAC(SPEC p th)) THEN + USE_THEN "tmp" (fun th -> REWRITE_TAC[th]) THEN + POP_ASSUM (K ALL_TAC);; + +let BYTES128_TO_BYTES8_THM = prove( + `!pos bl_ptr s. + read (memory :> bytes128 (word_add bl_ptr (word pos))) s = + bytes_to_int128 + [read (memory :> bytes8 (word_add bl_ptr (word (pos + 0x0)))) s; + read (memory :> bytes8 (word_add bl_ptr (word (pos + 0x1)))) s; + read (memory :> bytes8 (word_add bl_ptr (word (pos + 0x2)))) s; + read (memory :> bytes8 (word_add bl_ptr (word (pos + 0x3)))) s; + read (memory :> bytes8 (word_add bl_ptr (word (pos + 0x4)))) s; + read (memory :> bytes8 (word_add bl_ptr (word (pos + 0x5)))) s; + read (memory :> bytes8 (word_add bl_ptr (word (pos + 0x6)))) s; + read (memory :> bytes8 (word_add bl_ptr (word (pos + 0x7)))) s; + read (memory :> bytes8 (word_add bl_ptr (word (pos + 0x8)))) s; + read (memory :> bytes8 (word_add bl_ptr (word (pos + 0x9)))) s; + read (memory :> bytes8 (word_add bl_ptr (word (pos + 0xa)))) s; + read (memory :> bytes8 (word_add bl_ptr (word (pos + 0xb)))) s; + read (memory :> bytes8 (word_add bl_ptr (word (pos + 0xc)))) s; + read (memory :> bytes8 (word_add bl_ptr (word (pos + 0xd)))) s; + read (memory :> bytes8 (word_add bl_ptr (word (pos + 0xe)))) s; + read (memory :> bytes8 (word_add bl_ptr (word (pos + 0xf)))) s]`, + REPEAT STRIP_TAC THEN + REWRITE_TAC[bytes_to_int128] THEN + REWRITE_TAC EL_16_8_CLAUSES THEN + GEN_REWRITE_TAC TOP_DEPTH_CONV [READ_MEMORY_BYTESIZED_SPLIT; WORD_ADD_ASSOC_CONSTS] THEN + CONV_TAC(DEPTH_CONV WORD_NUM_RED_CONV) THEN + ONCE_REWRITE_TAC [ARITH_RULE `pos + 0 = (pos:num)`] THEN + REFL_TAC +);; + +let SUB_LIST_16_TAC n exp = + let subgoal = subst [exp, `exp:num`] `exp < LENGTH (l:A list)` in + CONV_TAC(RAND_CONV (REWRITE_CONV[num_CONV n; SUB_LIST_SUCSPLIT])) THEN + SUBGOAL_THEN subgoal ASSUME_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN + REWRITE_TAC[SUB_LIST_1] THEN ASM_SIMP_TAC[GSYM ADD_ASSOC] THEN NUM_REDUCE_TAC;; + +let SUB_LIST_16 = prove( + `!(l:A list) n. n + 16 <= LENGTH l ==> + [ EL (n + 0) l; EL (n + 1) l; EL (n + 2) l; EL (n + 3) l; + EL (n + 4) l; EL (n + 5) l; EL (n + 6) l; EL (n + 7) l; + EL (n + 8) l; EL (n + 9) l; EL (n + 10) l; EL (n + 11) l; + EL (n + 12) l; EL (n + 13) l; EL (n + 14) l; EL (n + 15) l + ] = SUB_LIST (n,16) l`, + REPEAT STRIP_TAC THEN + MAP_EVERY (fun i -> + if i == 0 + then SUB_LIST_16_TAC `0x10` `n:num` + else SUB_LIST_16_TAC (mk_numeral (num (16 - i))) + (mk_binop (mk_const("+", [`:num`, `:A`])) (mk_var("n", `:num`)) + (mk_numeral (num i)))) (0--14) THEN + SUBGOAL_THEN `n + 15 < LENGTH (l:A list)` ASSUME_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[APPEND; ARITH_RULE `n + 0 = n`] +);; + +let BYTE_LIST_AT_5BLOCKS = prove( + `! pos bl bl_ptr len s. + byte_list_at bl bl_ptr len s + ==> LENGTH bl = val len + ==> pos + 0x50 <= LENGTH bl + ==> (read (memory :> bytes128 (word_add bl_ptr (word pos))) s = + bytes_to_int128 (SUB_LIST (pos, 0x10) bl) /\ + read (memory :> bytes128 (word_add (word_add bl_ptr (word pos)) (word 0x10))) s = + bytes_to_int128 (SUB_LIST (pos + 0x10, 0x10) bl) /\ + read (memory :> bytes128 (word_add (word_add bl_ptr (word pos)) (word 0x20))) s = + bytes_to_int128 (SUB_LIST (pos + 0x20, 0x10) bl) /\ + read (memory :> bytes128 (word_add (word_add bl_ptr (word pos)) (word 0x30))) s = + bytes_to_int128 (SUB_LIST (pos + 0x30, 0x10) bl) /\ + read (memory :> bytes128 (word_add (word_add bl_ptr (word pos)) (word 0x40))) s = + bytes_to_int128 (SUB_LIST (pos + 0x40, 0x10) bl))`, + REWRITE_TAC[byte_list_at] THEN + REPEAT STRIP_TAC THENL + [ (* Subgoal1 *) + MAP_EVERY (fun i -> BYTE_LIST_AT_ADD_ASSUM_TAC + (mk_binop (mk_const("+", [`:num`, `:A`])) (mk_var("pos", `:num`)) + (mk_numeral (num i))) `0x50`) (0--15) THEN + REWRITE_TAC[WORD_ADD_ASSOC_CONSTS] THEN + REPEAT STRIP_TAC THEN + ASM_REWRITE_TAC[BYTES128_TO_BYTES8_THM; GSYM ADD_ASSOC] THEN + NUM_REDUCE_TAC THEN ASM_REWRITE_TAC[] THEN AP_TERM_TAC THEN + MP_TAC (ISPECL [`bl:byte list`; `pos:num`] SUB_LIST_16) THEN + REWRITE_TAC[GSYM ADD_ASSOC] THEN NUM_REDUCE_TAC THEN + DISCH_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_ARITH_TAC; + (* Subgoal2 *) + MAP_EVERY (fun i -> BYTE_LIST_AT_ADD_ASSUM_TAC + (mk_binop (mk_const("+", [`:num`, `:A`])) (mk_var("pos", `:num`)) + (mk_numeral (num i))) `0x50`) (16--31) THEN + REWRITE_TAC[WORD_ADD_ASSOC_CONSTS] THEN + REPEAT STRIP_TAC THEN + ASM_REWRITE_TAC[BYTES128_TO_BYTES8_THM; GSYM ADD_ASSOC] THEN + NUM_REDUCE_TAC THEN ASM_REWRITE_TAC[] THEN AP_TERM_TAC THEN + MP_TAC (ISPECL [`bl:byte list`; `(pos+0x10):num`] SUB_LIST_16) THEN + REWRITE_TAC[GSYM ADD_ASSOC] THEN NUM_REDUCE_TAC THEN + DISCH_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_ARITH_TAC; + (* Subgoal3 *) + MAP_EVERY (fun i -> BYTE_LIST_AT_ADD_ASSUM_TAC + (mk_binop (mk_const("+", [`:num`, `:A`])) (mk_var("pos", `:num`)) + (mk_numeral (num i))) `0x50`) (32--47) THEN + REWRITE_TAC[WORD_ADD_ASSOC_CONSTS] THEN + REPEAT STRIP_TAC THEN + ASM_REWRITE_TAC[BYTES128_TO_BYTES8_THM; GSYM ADD_ASSOC] THEN + NUM_REDUCE_TAC THEN ASM_REWRITE_TAC[] THEN AP_TERM_TAC THEN + MP_TAC (ISPECL [`bl:byte list`; `(pos+0x20):num`] SUB_LIST_16) THEN + REWRITE_TAC[GSYM ADD_ASSOC] THEN NUM_REDUCE_TAC THEN + DISCH_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_ARITH_TAC; + (* Subgoal4 *) + MAP_EVERY (fun i -> BYTE_LIST_AT_ADD_ASSUM_TAC + (mk_binop (mk_const("+", [`:num`, `:A`])) (mk_var("pos", `:num`)) + (mk_numeral (num i))) `0x50`) (48--63) THEN + REWRITE_TAC[WORD_ADD_ASSOC_CONSTS] THEN + REPEAT STRIP_TAC THEN + ASM_REWRITE_TAC[BYTES128_TO_BYTES8_THM; GSYM ADD_ASSOC] THEN + NUM_REDUCE_TAC THEN ASM_REWRITE_TAC[] THEN AP_TERM_TAC THEN + MP_TAC (ISPECL [`bl:byte list`; `(pos+0x30):num`] SUB_LIST_16) THEN + REWRITE_TAC[GSYM ADD_ASSOC] THEN NUM_REDUCE_TAC THEN + DISCH_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_ARITH_TAC; + (* Subgoal 5 *) + MAP_EVERY (fun i -> BYTE_LIST_AT_ADD_ASSUM_TAC + (mk_binop (mk_const("+", [`:num`, `:A`])) (mk_var("pos", `:num`)) + (mk_numeral (num i))) `0x50`) (64--79) THEN + REWRITE_TAC[WORD_ADD_ASSOC_CONSTS] THEN + REPEAT STRIP_TAC THEN + ASM_REWRITE_TAC[BYTES128_TO_BYTES8_THM; GSYM ADD_ASSOC] THEN + NUM_REDUCE_TAC THEN ASM_REWRITE_TAC[] THEN AP_TERM_TAC THEN + MP_TAC (ISPECL [`bl:byte list`; `(pos+0x40):num`] SUB_LIST_16) THEN + REWRITE_TAC[GSYM ADD_ASSOC] THEN NUM_REDUCE_TAC THEN + DISCH_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_ARITH_TAC + ] +);; + +let BYTE_LIST_AT_4BLOCKS = prove( + `! pos bl bl_ptr len s. + byte_list_at bl bl_ptr len s + ==> LENGTH bl = val len + ==> pos + 0x40 <= LENGTH bl + ==> (read (memory :> bytes128 (word_add bl_ptr (word pos))) s = + bytes_to_int128 (SUB_LIST (pos, 0x10) bl) /\ + read (memory :> bytes128 (word_add (word_add bl_ptr (word pos)) (word 0x10))) s = + bytes_to_int128 (SUB_LIST (pos + 0x10, 0x10) bl) /\ + read (memory :> bytes128 (word_add (word_add bl_ptr (word pos)) (word 0x20))) s = + bytes_to_int128 (SUB_LIST (pos + 0x20, 0x10) bl) /\ + read (memory :> bytes128 (word_add (word_add bl_ptr (word pos)) (word 0x30))) s = + bytes_to_int128 (SUB_LIST (pos + 0x30, 0x10) bl))`, + REWRITE_TAC[byte_list_at] THEN + REPEAT STRIP_TAC THENL + [ (* Subgoal1 *) + MAP_EVERY (fun i -> BYTE_LIST_AT_ADD_ASSUM_TAC + (mk_binop (mk_const("+", [`:num`, `:A`])) (mk_var("pos", `:num`)) + (mk_numeral (num i))) `0x40`) (0--15) THEN + REWRITE_TAC[WORD_ADD_ASSOC_CONSTS] THEN + REPEAT STRIP_TAC THEN + ASM_REWRITE_TAC[BYTES128_TO_BYTES8_THM; GSYM ADD_ASSOC] THEN + NUM_REDUCE_TAC THEN ASM_REWRITE_TAC[] THEN AP_TERM_TAC THEN + MP_TAC (ISPECL [`bl:byte list`; `pos:num`] SUB_LIST_16) THEN + REWRITE_TAC[GSYM ADD_ASSOC] THEN NUM_REDUCE_TAC THEN + DISCH_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_ARITH_TAC; + (* Subgoal2 *) + MAP_EVERY (fun i -> BYTE_LIST_AT_ADD_ASSUM_TAC + (mk_binop (mk_const("+", [`:num`, `:A`])) (mk_var("pos", `:num`)) + (mk_numeral (num i))) `0x40`) (16--31) THEN + REWRITE_TAC[WORD_ADD_ASSOC_CONSTS] THEN + REPEAT STRIP_TAC THEN + ASM_REWRITE_TAC[BYTES128_TO_BYTES8_THM; GSYM ADD_ASSOC] THEN + NUM_REDUCE_TAC THEN ASM_REWRITE_TAC[] THEN AP_TERM_TAC THEN + MP_TAC (ISPECL [`bl:byte list`; `(pos+0x10):num`] SUB_LIST_16) THEN + REWRITE_TAC[GSYM ADD_ASSOC] THEN NUM_REDUCE_TAC THEN + DISCH_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_ARITH_TAC; + (* Subgoal3 *) + MAP_EVERY (fun i -> BYTE_LIST_AT_ADD_ASSUM_TAC + (mk_binop (mk_const("+", [`:num`, `:A`])) (mk_var("pos", `:num`)) + (mk_numeral (num i))) `0x40`) (32--47) THEN + REWRITE_TAC[WORD_ADD_ASSOC_CONSTS] THEN + REPEAT STRIP_TAC THEN + ASM_REWRITE_TAC[BYTES128_TO_BYTES8_THM; GSYM ADD_ASSOC] THEN + NUM_REDUCE_TAC THEN ASM_REWRITE_TAC[] THEN AP_TERM_TAC THEN + MP_TAC (ISPECL [`bl:byte list`; `(pos+0x20):num`] SUB_LIST_16) THEN + REWRITE_TAC[GSYM ADD_ASSOC] THEN NUM_REDUCE_TAC THEN + DISCH_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_ARITH_TAC; + (* Subgoal4 *) + MAP_EVERY (fun i -> BYTE_LIST_AT_ADD_ASSUM_TAC + (mk_binop (mk_const("+", [`:num`, `:A`])) (mk_var("pos", `:num`)) + (mk_numeral (num i))) `0x40`) (48--63) THEN + REWRITE_TAC[WORD_ADD_ASSOC_CONSTS] THEN + REPEAT STRIP_TAC THEN + ASM_REWRITE_TAC[BYTES128_TO_BYTES8_THM; GSYM ADD_ASSOC] THEN + NUM_REDUCE_TAC THEN ASM_REWRITE_TAC[] THEN AP_TERM_TAC THEN + MP_TAC (ISPECL [`bl:byte list`; `(pos+0x30):num`] SUB_LIST_16) THEN + REWRITE_TAC[GSYM ADD_ASSOC] THEN NUM_REDUCE_TAC THEN + DISCH_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_ARITH_TAC + ] +);; + +let BYTE_LIST_AT_3BLOCKS = prove( + `! pos bl bl_ptr len s. + byte_list_at bl bl_ptr len s + ==> LENGTH bl = val len + ==> pos + 0x30 <= LENGTH bl + ==> (read (memory :> bytes128 (word_add bl_ptr (word pos))) s = + bytes_to_int128 (SUB_LIST (pos, 0x10) bl) /\ + read (memory :> bytes128 (word_add (word_add bl_ptr (word pos)) (word 0x10))) s = + bytes_to_int128 (SUB_LIST (pos + 0x10, 0x10) bl) /\ + read (memory :> bytes128 (word_add (word_add bl_ptr (word pos)) (word 0x20))) s = + bytes_to_int128 (SUB_LIST (pos + 0x20, 0x10) bl))`, + REWRITE_TAC[byte_list_at] THEN + REPEAT STRIP_TAC THENL + [ (* Subgoal1 *) + MAP_EVERY (fun i -> BYTE_LIST_AT_ADD_ASSUM_TAC + (mk_binop (mk_const("+", [`:num`, `:A`])) (mk_var("pos", `:num`)) + (mk_numeral (num i))) `0x30`) (0--15) THEN + REWRITE_TAC[WORD_ADD_ASSOC_CONSTS] THEN + REPEAT STRIP_TAC THEN + ASM_REWRITE_TAC[BYTES128_TO_BYTES8_THM; GSYM ADD_ASSOC] THEN + NUM_REDUCE_TAC THEN ASM_REWRITE_TAC[] THEN AP_TERM_TAC THEN + MP_TAC (ISPECL [`bl:byte list`; `pos:num`] SUB_LIST_16) THEN + REWRITE_TAC[GSYM ADD_ASSOC] THEN NUM_REDUCE_TAC THEN + DISCH_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_ARITH_TAC; + (* Subgoal2 *) + MAP_EVERY (fun i -> BYTE_LIST_AT_ADD_ASSUM_TAC + (mk_binop (mk_const("+", [`:num`, `:A`])) (mk_var("pos", `:num`)) + (mk_numeral (num i))) `0x30`) (16--31) THEN + REWRITE_TAC[WORD_ADD_ASSOC_CONSTS] THEN + REPEAT STRIP_TAC THEN + ASM_REWRITE_TAC[BYTES128_TO_BYTES8_THM; GSYM ADD_ASSOC] THEN + NUM_REDUCE_TAC THEN ASM_REWRITE_TAC[] THEN AP_TERM_TAC THEN + MP_TAC (ISPECL [`bl:byte list`; `(pos+0x10):num`] SUB_LIST_16) THEN + REWRITE_TAC[GSYM ADD_ASSOC] THEN NUM_REDUCE_TAC THEN + DISCH_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_ARITH_TAC; + (* Subgoal3 *) + MAP_EVERY (fun i -> BYTE_LIST_AT_ADD_ASSUM_TAC + (mk_binop (mk_const("+", [`:num`, `:A`])) (mk_var("pos", `:num`)) + (mk_numeral (num i))) `0x30`) (32--47) THEN + REWRITE_TAC[WORD_ADD_ASSOC_CONSTS] THEN + REPEAT STRIP_TAC THEN + ASM_REWRITE_TAC[BYTES128_TO_BYTES8_THM; GSYM ADD_ASSOC] THEN + NUM_REDUCE_TAC THEN ASM_REWRITE_TAC[] THEN AP_TERM_TAC THEN + MP_TAC (ISPECL [`bl:byte list`; `(pos+0x20):num`] SUB_LIST_16) THEN + REWRITE_TAC[GSYM ADD_ASSOC] THEN NUM_REDUCE_TAC THEN + DISCH_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_ARITH_TAC + ] +);; + +let BYTE_LIST_AT_2BLOCKS = prove( + `! pos bl bl_ptr len s. + byte_list_at bl bl_ptr len s + ==> LENGTH bl = val len + ==> pos + 0x20 <= LENGTH bl + ==> (read (memory :> bytes128 (word_add bl_ptr (word pos))) s = + bytes_to_int128 (SUB_LIST (pos, 0x10) bl) /\ + read (memory :> bytes128 (word_add (word_add bl_ptr (word pos)) (word 0x10))) s = + bytes_to_int128 (SUB_LIST (pos + 0x10, 0x10) bl))`, + REWRITE_TAC[byte_list_at] THEN + REPEAT STRIP_TAC THENL + [ (* Subgoal1 *) + MAP_EVERY (fun i -> BYTE_LIST_AT_ADD_ASSUM_TAC + (mk_binop (mk_const("+", [`:num`, `:A`])) (mk_var("pos", `:num`)) + (mk_numeral (num i))) `0x20`) (0--15) THEN + REWRITE_TAC[WORD_ADD_ASSOC_CONSTS] THEN + REPEAT STRIP_TAC THEN + ASM_REWRITE_TAC[BYTES128_TO_BYTES8_THM; GSYM ADD_ASSOC] THEN + NUM_REDUCE_TAC THEN ASM_REWRITE_TAC[] THEN AP_TERM_TAC THEN + MP_TAC (ISPECL [`bl:byte list`; `pos:num`] SUB_LIST_16) THEN + REWRITE_TAC[GSYM ADD_ASSOC] THEN NUM_REDUCE_TAC THEN + DISCH_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_ARITH_TAC; + (* Subgoal2 *) + MAP_EVERY (fun i -> BYTE_LIST_AT_ADD_ASSUM_TAC + (mk_binop (mk_const("+", [`:num`, `:A`])) (mk_var("pos", `:num`)) + (mk_numeral (num i))) `0x20`) (16--31) THEN + REWRITE_TAC[WORD_ADD_ASSOC_CONSTS] THEN + REPEAT STRIP_TAC THEN + ASM_REWRITE_TAC[BYTES128_TO_BYTES8_THM; GSYM ADD_ASSOC] THEN + NUM_REDUCE_TAC THEN ASM_REWRITE_TAC[] THEN AP_TERM_TAC THEN + MP_TAC (ISPECL [`bl:byte list`; `(pos+0x10):num`] SUB_LIST_16) THEN + REWRITE_TAC[GSYM ADD_ASSOC] THEN NUM_REDUCE_TAC THEN + DISCH_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_ARITH_TAC + ] +);; + +let BYTE_LIST_AT_1BLOCKS = prove( + `! pos bl bl_ptr len s. + byte_list_at bl bl_ptr len s + ==> LENGTH bl = val len + ==> pos + 0x10 <= LENGTH bl + ==> read (memory :> bytes128 (word_add bl_ptr (word pos))) s = + bytes_to_int128 (SUB_LIST (pos, 0x10) bl)`, + REWRITE_TAC[byte_list_at] THEN + REPEAT STRIP_TAC THENL + [ (* Subgoal1 *) + MAP_EVERY (fun i -> BYTE_LIST_AT_ADD_ASSUM_TAC + (mk_binop (mk_const("+", [`:num`, `:A`])) (mk_var("pos", `:num`)) + (mk_numeral (num i))) `0x10`) (0--15) THEN + REWRITE_TAC[WORD_ADD_ASSOC_CONSTS] THEN + REPEAT STRIP_TAC THEN + ASM_REWRITE_TAC[BYTES128_TO_BYTES8_THM; GSYM ADD_ASSOC] THEN + NUM_REDUCE_TAC THEN ASM_REWRITE_TAC[] THEN AP_TERM_TAC THEN + MP_TAC (ISPECL [`bl:byte list`; `pos:num`] SUB_LIST_16) THEN + REWRITE_TAC[GSYM ADD_ASSOC] THEN NUM_REDUCE_TAC THEN + DISCH_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_ARITH_TAC + ] +);; + +let READ_BL_LEMMA = prove( + `!ptr i (len:int64) (bl:byte list) s. + (forall j. j < val len ==> read (memory :> bytes8 (word_add ptr (word j))) s = EL j bl) + /\ i * 0x50 + 0x50 <= val len + /\ LENGTH bl = val len + ==> + read (memory :> bytes128 (word_add ptr (word_mul (word 0x50) (word i)))) s = + bytes_to_int128 (SUB_LIST (i * 80, 16) bl) /\ + read (memory :> bytes128 (word_add (word_add ptr (word_mul (word 0x50) (word i))) (word 0x10))) s = + bytes_to_int128 (SUB_LIST (i * 80 + 16, 16) bl) /\ + read (memory :> bytes128 (word_add (word_add ptr (word_mul (word 0x50) (word i))) (word 0x20))) s = + bytes_to_int128 (SUB_LIST (i * 80 + 32, 16) bl) /\ + read (memory :> bytes128 (word_add (word_add ptr (word_mul (word 0x50) (word i))) (word 0x30))) s = + bytes_to_int128 (SUB_LIST (i * 80 + 48, 16) bl) /\ + read (memory :> bytes128 (word_add (word_add ptr (word_mul (word 0x50) (word i))) (word 0x40))) s = + bytes_to_int128 (SUB_LIST (i * 80 + 64, 16) bl) + `, + REPEAT GEN_TAC THEN STRIP_TAC THEN + REWRITE_TAC [WORD_RULE `word_mul (word 0x50) (word i) = word (i * 80)`] THEN + MP_TAC + (SPECL [`(i * 80):num`; `bl:byte list`; `ptr:int64`; `len:int64`; `s:armstate`] + BYTE_LIST_AT_5BLOCKS) THEN + REWRITE_TAC[byte_list_at] THEN ASM_SIMP_TAC[] +);; + +let READ_TAIL4_LEMMA = prove( + `!ptr (n5blocks:int64) (len:int64) (bl:byte list) s. + (forall j. j < val len ==> read (memory :> bytes8 (word_add ptr (word j))) s = EL j bl) + /\ val n5blocks * 0x50 + 0x40 <= val len + /\ LENGTH bl = val len + ==> + read (memory :> bytes128 (word_add + (word_add ptr (word_mul (word 0x50) n5blocks)) + (word 0x30))) s = + bytes_to_int128 (SUB_LIST (val n5blocks * 80 + 0x30, 16) bl) /\ + read (memory :> bytes128 (word_add + (word_add ptr (word_mul (word 0x50) n5blocks)) + (word 0x20))) s = + bytes_to_int128 (SUB_LIST (val n5blocks * 80 + 0x20, 16) bl) /\ + read (memory :> bytes128 (word_add + (word_add ptr (word_mul (word 0x50) n5blocks)) + (word 0x10))) s = + bytes_to_int128 (SUB_LIST (val n5blocks * 80 + 0x10, 16) bl) /\ + read (memory :> bytes128 + (word_add ptr (word_mul (word 0x50) n5blocks))) s = + bytes_to_int128 (SUB_LIST (val n5blocks * 80, 16) bl) + `, + REPEAT GEN_TAC THEN STRIP_TAC THEN + REWRITE_TAC [WORD_RULE `(word_mul (word 0x50) (n5blocks:int64)) = word (val n5blocks * 80)`] THEN + MP_TAC + (SPECL [`(val (n5blocks:int64) * 80):num`; `bl:byte list`; `ptr:int64`; `len:int64`; `s:armstate`] + BYTE_LIST_AT_4BLOCKS) THEN + REWRITE_TAC[byte_list_at] THEN ASM_SIMP_TAC[] +);; + +let READ_TAIL3_LEMMA = prove( + `!ptr (n5blocks:int64) (len:int64) (bl:byte list) s. + (forall j. j < val len ==> read (memory :> bytes8 (word_add ptr (word j))) s = EL j bl) + /\ val n5blocks * 0x50 + 0x30 <= val len + /\ LENGTH bl = val len + ==> + read (memory :> bytes128 (word_add + (word_add ptr (word_mul (word 0x50) n5blocks)) + (word 0x20))) s = + bytes_to_int128 (SUB_LIST (val n5blocks * 80 + 0x20, 16) bl) /\ + read (memory :> bytes128 (word_add + (word_add ptr (word_mul (word 0x50) n5blocks)) + (word 0x10))) s = + bytes_to_int128 (SUB_LIST (val n5blocks * 80 + 0x10, 16) bl) /\ + read (memory :> bytes128 + (word_add ptr (word_mul (word 0x50) n5blocks))) s = + bytes_to_int128 (SUB_LIST (val n5blocks * 80, 16) bl) + `, + REPEAT GEN_TAC THEN STRIP_TAC THEN + REWRITE_TAC [WORD_RULE `(word_mul (word 0x50) (n5blocks:int64)) = word (val n5blocks * 80)`] THEN + MP_TAC + (SPECL [`(val (n5blocks:int64) * 80):num`; `bl:byte list`; `ptr:int64`; `len:int64`; `s:armstate`] + BYTE_LIST_AT_3BLOCKS) THEN + REWRITE_TAC[byte_list_at] THEN ASM_SIMP_TAC[] +);; + +let READ_TAIL2_LEMMA = prove( + `!ptr (n5blocks:int64) (len:int64) (bl:byte list) s. + (forall j. j < val len ==> read (memory :> bytes8 (word_add ptr (word j))) s = EL j bl) + /\ val n5blocks * 0x50 + 0x20 <= val len + /\ LENGTH bl = val len + ==> + read (memory :> bytes128 (word_add + (word_add ptr (word_mul (word 0x50) n5blocks)) + (word 0x10))) s = + bytes_to_int128 (SUB_LIST (val n5blocks * 80 + 0x10, 16) bl) /\ + read (memory :> bytes128 + (word_add ptr (word_mul (word 0x50) n5blocks))) s = + bytes_to_int128 (SUB_LIST (val n5blocks * 80, 16) bl) + `, + REPEAT GEN_TAC THEN STRIP_TAC THEN + REWRITE_TAC [WORD_RULE `(word_mul (word 0x50) (n5blocks:int64)) = word (val n5blocks * 80)`] THEN + MP_TAC + (SPECL [`(val (n5blocks:int64) * 80):num`; `bl:byte list`; `ptr:int64`; `len:int64`; `s:armstate`] + BYTE_LIST_AT_2BLOCKS) THEN + REWRITE_TAC[byte_list_at] THEN ASM_SIMP_TAC[] +);; + +let READ_TAIL1_LEMMA = prove( + `!ptr (n5blocks:int64) (len:int64) (bl:byte list) s. + (forall j. j < val len ==> read (memory :> bytes8 (word_add ptr (word j))) s = EL j bl) + /\ val n5blocks * 0x50 + 0x10 <= val len + /\ LENGTH bl = val len + ==> + read (memory :> bytes128 + (word_add ptr (word_mul (word 0x50) n5blocks))) s = + bytes_to_int128 (SUB_LIST (val n5blocks * 80, 16) bl) + `, + REPEAT GEN_TAC THEN STRIP_TAC THEN + REWRITE_TAC [WORD_RULE `(word_mul (word 0x50) (n5blocks:int64)) = word (val n5blocks * 80)`] THEN + MP_TAC + (SPECL [`(val (n5blocks:int64) * 80):num`; `bl:byte list`; `ptr:int64`; `len:int64`; `s:armstate`] + BYTE_LIST_AT_1BLOCKS) THEN + REWRITE_TAC[byte_list_at] THEN ASM_SIMP_TAC[] +);; + +let READ_LAST_LEMMA = prove( + `!ptr (curr_len:num) (len:int64) (bl:byte list) s. + (forall j. j < val len ==> read (memory :> bytes8 (word_add ptr (word j))) s = EL j bl) + /\ curr_len + 0x10 <= val len + /\ LENGTH bl = val len + ==> + read (memory :> bytes128 (word_add ptr (word curr_len))) s = + bytes_to_int128 (SUB_LIST (curr_len, 16) bl) + `, + REPEAT GEN_TAC THEN STRIP_TAC THEN + MP_TAC + (SPECL [`curr_len:num`; `bl:byte list`; `ptr:int64`; `len:int64`; `s:armstate`] + BYTE_LIST_AT_1BLOCKS) THEN + REWRITE_TAC[byte_list_at] THEN ASM_SIMP_TAC[] +);; + +let UDIV_OPT_THM = prove(`!n:num. n < 0x2 EXP 0x40 + ==> (word (val ((word ((n * 0xcccccccccccccccd) DIV 0x2 EXP 0x40)):int64) DIV 0x2 EXP 0x6)):int64 = word (n DIV 0x50)`, + REPEAT STRIP_TAC THEN + REWRITE_TAC[VAL_WORD; DIMINDEX_64] THEN + SUBGOAL_THEN `!p n:num. ~(p = 0) /\ n < p * p ==> n DIV p MOD p = n DIV p` + (MP_TAC o SPECL [`0x2 EXP 0x40`; `n * 0xcccccccccccccccd`]) THENL + [ REPEAT STRIP_TAC THEN + REWRITE_TAC[DIV_MOD] THEN + AP_THM_TAC THEN AP_TERM_TAC THEN + MATCH_MP_TAC MOD_LT THEN + ASM_ARITH_TAC; ALL_TAC] THEN + ANTS_TAC THENL [ASM_ARITH_TAC;ALL_TAC] THEN + DISCH_TAC THEN ASM_REWRITE_TAC[] THEN + AP_TERM_TAC THEN ASM_ARITH_TAC);; + +(* For encrypt *) +let LEN_FULL_BLOCKS_LO_BOUND_THM = prove( + `!(len:int64) len_full_blocks. word_and len (word 0xfffffffffffffff0) = len_full_blocks + ==> ~(val len < 0x50) + ==> ~(val len_full_blocks < 0x50)`, + BITBLAST_TAC);; + +(* For decrypt *) +let NUM_BLOCKS_LO_BOUND_THM = prove( + `!(len:int64) num_blocks. word_and len (word 0xfffffffffffffff0) = num_blocks + ==> ~(val len < 0x60) + ==> ~(val num_blocks < 0x60)`, + BITBLAST_TAC);; + +let NUM_BLOCKS_LO_BOUND_1BLOCK_THM = prove( + `!(len:int64) num_blocks. word_and len (word 0xfffffffffffffff0) = num_blocks + ==> ~(val len < 16) + ==> ~(val num_blocks < 16)`, + BITBLAST_TAC);; + +let NUM_BLOCKS_HI_BOUND_THM = prove( + `!(len:int64) num_blocks. word_and len (word 0xfffffffffffffff0) = num_blocks + ==> val len <= 2 EXP 24 + ==> val num_blocks <= 2 EXP 24`, + BITBLAST_TAC);; + +let TAIL_LEN_BOUND_THM = prove( + `!(len:int64) tail_len. word_and len (word 0xf) = tail_len + ==> val tail_len < 0x10`, + BITBLAST_TAC);; + +let NUM_BLOCKS_LT_LEN_THM = prove( + `!(len:int64). val (word_and len (word 0xfffffffffffffff0)) <= val len`, + BITBLAST_TAC +);; + +(* For encrypt *) +let NUM_5BLOCKS_LO_BOUND_THM = prove( + `!(len_full_blocks:int64) (num_5blocks:int64). + val len_full_blocks <= 2 EXP 24 + ==> ~(val len_full_blocks < 0x50) + ==> word (val len_full_blocks DIV 0x50) = num_5blocks + ==> 0x0 < val num_5blocks`, + REPEAT STRIP_TAC THEN + EXPAND_TAC "num_5blocks" THEN + REWRITE_TAC[VAL_WORD; DIMINDEX_64] THEN + UNDISCH_TAC `~(val (len_full_blocks:int64) < 0x50)` THEN + ABBREV_TAC `n = val (len_full_blocks:int64)` THEN + SUBGOAL_THEN `n DIV 0x50 < 2 EXP 64` ASSUME_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[MOD_LT] THEN + ARITH_TAC +);; + +(* For decrypt *) +let NUM_BLOCKS_ADJUSTED_LO_BOUND_THM = prove( + `!(num_blocks:int64) (tail_len:int64) num_blocks_adjusted. + (if val tail_len = 0x0 then num_blocks else word_sub num_blocks (word 0x10)) = num_blocks_adjusted + ==> ~(val num_blocks < 0x60) + ==> ~(val num_blocks_adjusted < 0x50)`, + BITBLAST_TAC +);; + +let NUM_BLOCKS_ADJUSTED_LO_BOUND_1BLOCK_THM = prove( + `!(num_blocks:int64) (tail_len:int64) num_blocks_adjusted. + (if val tail_len = 0x0 then num_blocks else word_sub num_blocks (word 0x10)) = num_blocks_adjusted + ==> ~(val num_blocks < 16) + ==> ~(val num_blocks_adjusted < 0)`, + BITBLAST_TAC +);; + +let NUM_BLOCKS_ADJUSTED_HI_BOUND_THM = prove( + `!(num_blocks:int64) (tail_len:int64) num_blocks_adjusted. + (if val tail_len = 0x0 then num_blocks else word_sub num_blocks (word 0x10)) = num_blocks_adjusted + ==> val num_blocks <= 2 EXP 24 + ==> ~(val num_blocks < 16) + ==> val num_blocks_adjusted <= 2 EXP 24`, + BITBLAST_TAC +);; + +let NUM_5BLOCKS_ADJUSTED_LO_BOUND_THM = prove( + `!(num_blocks_adjusted:int64) (num_5blocks_adjusted:int64). + val num_blocks_adjusted <= 0x2 EXP 0x18 + ==> ~(val num_blocks_adjusted < 0x50) + ==> word (val num_blocks_adjusted DIV 0x50) = num_5blocks_adjusted + ==> 0x0 < val num_5blocks_adjusted`, + REPEAT STRIP_TAC THEN + EXPAND_TAC "num_5blocks_adjusted" THEN + REWRITE_TAC[VAL_WORD; DIMINDEX_64] THEN + UNDISCH_TAC `~(val (num_blocks_adjusted:int64) < 0x50)` THEN + ABBREV_TAC `n = val (num_blocks_adjusted:int64)` THEN + SUBGOAL_THEN `n DIV 80 < 2 EXP 64` ASSUME_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[MOD_LT] THEN + ARITH_TAC +);; + +let NUM_BLOCKS_ADJUSTED_LT_LEN_THM = prove( + `!(len:int64) num_blocks. + word_and len (word 0xfffffffffffffff0) = num_blocks + ==> ~(val num_blocks < 16) + ==> val (word_sub num_blocks (word 0x10)) <= val len`, + BITBLAST_TAC +);; + + +let MEMORY_READ_SUBSET_LEMMA = prove + (`!len (ptr:int64) (bl:byte list) s. + (forall i. + i < SUC len + ==> read (memory :> bytes8 (word_add ptr (word i))) s = EL i bl) ==> + (forall i. + i < len + ==> read (memory :> bytes8 (word_add ptr (word i))) s = EL i bl) /\ + read (memory :> bytes (word_add ptr (word len),1)) s = + val(read (memory :> bytes8 (word_add ptr (word len))) s) + `, + REPEAT GEN_TAC THEN + DISCH_TAC THEN + CONJ_TAC THENL + [ GEN_TAC THEN DISCH_TAC THEN + FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_REWRITE_TAC[LT_SUC_LE] THEN + ASM_ARITH_TAC; + ALL_TAC] THEN + REWRITE_TAC[bytes8; READ_COMPONENT_COMPOSE; asword; through; read] THEN + REWRITE_TAC[VAL_WORD; DIMINDEX_8] THEN + CONV_TAC NUM_REDUCE_CONV THEN + IMP_REWRITE_TAC[MOD_LT] THEN + MP_TAC (ISPECL [`(word_add (ptr:int64) (word len)):int64`; `1:num`; `(read memory s):int64->byte`] READ_BYTES_BOUND) THEN + CONV_TAC NUM_REDUCE_CONV +);; + +let BYTE_LIST_AT_SPLIT = prove( + `!len (ptr:int64) (bl:byte list) s. + SUC len <= LENGTH bl ==> + ((forall i. + i < SUC len + ==> read (memory :> bytes8 (word_add ptr (word i))) s = EL i bl) <=> + ((forall i. + i < len + ==> read (memory :> bytes8 (word_add ptr (word i))) s = EL i bl) /\ + read (memory :> bytes8 (word_add ptr (word len))) s = EL len bl))`, + REPEAT STRIP_TAC THEN + EQ_TAC THENL + [ STRIP_TAC THEN + CONJ_TAC THENL + [ ASM_SIMP_TAC[ARITH_RULE `i < len ==> i < SUC len`]; + ASM_SIMP_TAC[ARITH_RULE `len < SUC len`]]; + ALL_TAC ] THEN + REPEAT STRIP_TAC THEN + ASM_CASES_TAC `i < len` THENL + [ FIRST_X_ASSUM MATCH_MP_TAC THEN + ASM_SIMP_TAC[]; + SUBGOAL_THEN `i = len:num` SUBST1_TAC THENL + [ASM_ARITH_TAC; ASM_REWRITE_TAC[]] + ] +);; + +let BYTE_LIST_AT_SPLIT_BACKWARDS = prove( + `!(pt_ptr:int64) i len curr_len bl s. + 0 <= i ==> i < len ==> len < 16 ==> LENGTH bl >= 16 ==> + (forall j. + j < len - (i + 1) + ==> read (memory :> bytes8 + (word_add (word_add pt_ptr (word (curr_len + 16 + i + 1))) + (word j))) s = + EL j (SUB_LIST (i + 1, len - (i + 1)) bl)) ==> + read (memory :> bytes8 (word_add pt_ptr (word (curr_len + 16 + i)))) s = (EL i bl) ==> + forall j. + j < len - i + ==> read (memory :> bytes8 + (word_add (word_add pt_ptr (word (curr_len + 16 + i))) + (word j))) s = + EL j (SUB_LIST (i, len - i) bl) + `, + REPEAT GEN_TAC THEN + REPEAT STRIP_TAC THEN + ASM_CASES_TAC `j > 0` THENL + [ + FIRST_X_ASSUM(MP_TAC o SPEC `j - 1`) THEN + ANTS_TAC THENL[ ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `(word_add (word_add (pt_ptr:int64) (word (curr_len + 0x10 + i + 0x1))) + (word (j - 0x1))) = (word_add (word_add pt_ptr (word (curr_len + 0x10 + i))) (word j))` SUBST1_TAC THENL + [ REWRITE_TAC[WORD_RULE `word_add (word_add a (word b)) (word c) = word_add a (word (b + c))`] THEN + AP_TERM_TAC THEN AP_TERM_TAC THEN + ASM_ARITH_TAC; ALL_TAC] THEN + SIMP_TAC[] THEN DISCH_TAC THEN + IMP_REWRITE_TAC[ARITH_RULE `len - (i + 1) = len - i - 1`; + EL_SUB_LIST_SHIFT] THEN + ASM_ARITH_TAC; + ALL_TAC + ] THEN + + SUBGOAL_THEN `j = 0` SUBST_ALL_TAC THENL[ASM_ARITH_TAC;ALL_TAC] THEN + REWRITE_TAC[WORD_ADD_0] THEN + ASM_REWRITE_TAC[] THEN + IMP_REWRITE_TAC[EL_SUB_LIST_TRIVIAL] THEN + ASM_ARITH_TAC +);; + +(* Differs from Encrypt in that the address is written in a canonical form *) +let BYTE_LIST_AT_SPLIT_BACKWARDS_CARNONICAL = prove( + `!(pt_ptr:int64) i len curr_len bl s. + 0 <= i ==> i < len ==> len < 16 ==> LENGTH bl >= 16 ==> + (forall j. + j < len - (i + 1) + ==> read (memory :> bytes8 + (word_add pt_ptr (word (curr_len + 16 + i + 1 + j)))) s = + EL j (SUB_LIST (i + 1, len - (i + 1)) bl)) ==> + read (memory :> bytes8 (word_add pt_ptr (word (curr_len + 16 + i)))) s = (EL i bl) ==> + forall j. + j < len - i + ==> read (memory :> bytes8 + (word_add pt_ptr (word (curr_len + 16 + i + j)))) s = + EL j (SUB_LIST (i, len - i) bl) + `, + REPEAT GEN_TAC THEN + REPEAT STRIP_TAC THEN + ASM_CASES_TAC `j > 0` THENL + [ + FIRST_X_ASSUM(MP_TAC o SPEC `j - 1`) THEN + ANTS_TAC THENL[ ASM_ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[ADD_ASSOC; ARITH_RULE `j > 0 ==> curr_len + 0x10 + i + 0x1 + j - 0x1 = curr_len + 0x10 + i + j`] THEN + SIMP_TAC[] THEN DISCH_TAC THEN + IMP_REWRITE_TAC[ARITH_RULE `len - (i + 1) = len - i - 1`; + EL_SUB_LIST_SHIFT] THEN + ASM_ARITH_TAC; + ALL_TAC + ] THEN + + SUBGOAL_THEN `j = 0` SUBST_ALL_TAC THENL[ASM_ARITH_TAC;ALL_TAC] THEN + REWRITE_TAC[ADD_0] THEN + ASM_REWRITE_TAC[] THEN + IMP_REWRITE_TAC[EL_SUB_LIST_TRIVIAL] THEN + ASM_ARITH_TAC +);; + +let MEMORY_READ_BYTES_SUBSET_LEMMA = prove( + `!len (ptr:int64) (bl:byte list) s. + SUC len <= LENGTH bl ==> + read (memory :> bytes (ptr,SUC len)) s = + num_of_bytelist (SUB_LIST (0x0,SUC len) bl) ==> + read (memory :> bytes (ptr,len)) s = + num_of_bytelist (SUB_LIST (0x0,len) bl) /\ + read (memory :> bytes8 (word_add ptr (word len))) s = EL len bl`, + REPEAT GEN_TAC THEN STRIP_TAC THEN + SUBGOAL_THEN `SUC len = len + 1` SUBST_ALL_TAC THENL [ARITH_TAC; ALL_TAC] THEN + REWRITE_TAC[READ_COMPONENT_COMPOSE] THEN + SUBGOAL_THEN `len <= LENGTH (bl:byte list)` ASSUME_TAC THENL [ ASM_ARITH_TAC; ALL_TAC] THEN + (* Use READ_BYTES_COMBINE to decompose the memory read *) + MP_TAC(ISPECL [`ptr:int64`; `len:num`; `1:num`; `(read memory s):int64->byte`] READ_BYTES_COMBINE) THEN + DISCH_TAC THEN + (* Use SUB_LIST_SPLIT to decompose the byte list *) + MP_TAC(ISPECL [`bl:byte list`; `len:num`; `1:num`; `0:num`] SUB_LIST_SPLIT) THEN + REWRITE_TAC[ADD_CLAUSES] THEN DISCH_TAC THEN + (* Decompose num_of_bytelist *) + SUBGOAL_THEN + `num_of_bytelist (SUB_LIST (0,len + 1) (bl:byte list)) = + num_of_bytelist (SUB_LIST (0,len) bl) + + 2 EXP (8 * len) * num_of_bytelist (SUB_LIST (len,1) bl)` + ASSUME_TAC THENL + [ ASM_REWRITE_TAC[] THEN + REWRITE_TAC[NUM_OF_BYTELIST_APPEND] THEN + AP_TERM_TAC THEN AP_THM_TAC THEN REPEAT_N 3 AP_TERM_TAC THEN + IMP_REWRITE_TAC[LENGTH_SUB_LIST; MIN; SUB_0] THEN + ASM_SIMP_TAC[] + ; ALL_TAC] THEN + (* Rewrite in goal *) + ASM_REWRITE_TAC[] THEN + DISCH_TAC THEN + CONJ_TAC THENL + [ (* First part: read (memory :> bytes (ptr,len)) s = num_of_bytelist (SUB_LIST (0,len) bl) *) + FIRST_X_ASSUM(MP_TAC o AP_TERM `\x. x MOD 2 EXP (8 * len)`) THEN + ASM_REWRITE_TAC[] THEN + REWRITE_TAC[MOD_MULT_ADD; MOD_LT] THEN + REWRITE_TAC[READ_BYTES_MOD; MIN] THEN + SIMP_TAC[ARITH_RULE `len <= len`] THEN + DISCH_TAC THEN + IMP_REWRITE_TAC[MOD_LT] THEN + MP_TAC (SPEC `(SUB_LIST (0,len) bl:byte list)` NUM_OF_BYTELIST_BOUND) THEN + IMP_REWRITE_TAC[LENGTH_SUB_LIST; SUB_0; MIN] THEN + SUBGOAL_THEN `256 EXP len = 2 EXP (8 * len)` SUBST1_TAC THENL + [ REWRITE_TAC[ARITH_RULE `256 = 2 EXP 8`; EXP_EXP]; ALL_TAC] THEN + SIMP_TAC[]; + ALL_TAC + ] THEN + (* Second part: read (memory :> bytes8 (word_add ptr (word len))) s = EL len bl *) + FIRST_X_ASSUM(MP_TAC o AP_TERM `\x. x DIV 2 EXP (8 * len)`) THEN + ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN `~(0x2 EXP (0x8 * len) = 0x0)` ASSUME_TAC THENL + [ REWRITE_TAC[EXP_EQ_0; ARITH_EQ]; ALL_TAC] THEN + IMP_REWRITE_TAC[DIV_MULT_ADD] THEN + SUBGOAL_THEN `read (bytes (ptr,len)) (read memory s) < 0x2 EXP (0x8 * len)` ASSUME_TAC THENL + [ REWRITE_TAC[READ_BYTES_BOUND]; ALL_TAC] THEN + SUBGOAL_THEN `num_of_bytelist (SUB_LIST (0x0,len) bl) < 0x2 EXP (0x8 * len)` ASSUME_TAC THENL + [ MP_TAC (SPEC `(SUB_LIST (0,len) bl:byte list)` NUM_OF_BYTELIST_BOUND) THEN + IMP_REWRITE_TAC[LENGTH_SUB_LIST; SUB_0; MIN] THEN + SUBGOAL_THEN `256 EXP len = 2 EXP (8 * len)` SUBST1_TAC THENL + [ REWRITE_TAC[ARITH_RULE `256 = 2 EXP 8`; EXP_EXP]; ALL_TAC] THEN SIMP_TAC[]; ALL_TAC] THEN + IMP_REWRITE_TAC[DIV_LT; ADD] THEN + (* Some rewrites to close the goal *) + REWRITE_TAC[bytes8; READ_COMPONENT_COMPOSE; asword; through; read] THEN + SUBGOAL_THEN `len < LENGTH (bl:byte list)` ASSUME_TAC THENL [ ASM_ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[SUB_LIST_1] THEN + REWRITE_TAC[num_of_bytelist; MULT_CLAUSES; ADD_CLAUSES; WORD_VAL] +);; + +let BYTE_LIST_TO_NUM_THM = prove( + `!len (ptr:int64) (bl:byte list) s. + len <= LENGTH bl ==> + ((forall i. i < len + ==> read (memory :> bytes8 (word_add ptr (word i))) s = EL i bl) <=> + (read (memory :> bytes (ptr, len)) s = num_of_bytelist (SUB_LIST (0, len) bl)))`, + REPEAT GEN_TAC THEN + SPEC_TAC (`len:num`, `len:num`) THEN + (* Base case: len = 0 *) + INDUCT_TAC THENL + [ STRIP_TAC THEN + REWRITE_TAC[READ_COMPONENT_COMPOSE; READ_BYTES_TRIVIAL; + CONJUNCT1 SUB_LIST; CONJUNCT1 num_of_bytelist] THEN + GEN_TAC THEN MESON_TAC[ARITH_RULE `~(i < 0)`]; + ALL_TAC] THEN + + (* Inductive step: left to right *) + STRIP_TAC THEN + EQ_TAC THENL + [ MP_TAC (ARITH_RULE `SUC len <= LENGTH (bl:byte list) ==> len <= LENGTH bl`) THEN + ASM_SIMP_TAC[] THEN REPEAT DISCH_TAC THEN + MP_TAC (SPECL [`len:num`; `ptr:int64`; `bl:byte list`; `s:armstate`] MEMORY_READ_SUBSET_LEMMA) THEN + ASM_SIMP_TAC[] THEN + DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN + REWRITE_TAC[READ_COMPONENT_COMPOSE; ADD1] THEN + ONCE_REWRITE_TAC[READ_BYTES_COMBINE] THEN + REWRITE_TAC[SUB_LIST_SPLIT; NUM_OF_BYTELIST_APPEND; CONJUNCT1 ADD] THEN + IMP_REWRITE_TAC[ARITH_RULE `a = c ==> (a + b = c + d) = (b = d)`] THEN + CONJ_TAC THENL [ + REWRITE_TAC[LENGTH_SUB_LIST; MIN; SUB_0] THEN + ASM_SIMP_TAC[] THEN + AP_TERM_TAC THEN + REWRITE_TAC[GSYM READ_COMPONENT_COMPOSE] THEN + FIRST_X_ASSUM (fun th -> MP_TAC (SPEC `len:num` th)) THEN + REWRITE_TAC[ARITH_RULE `len < SUC len`] THEN + SUBGOAL_THEN `len < LENGTH (bl:byte list)` ASSUME_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC] THEN + ASM_REWRITE_TAC[SUB_LIST_1; num_of_bytelist] THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[ADD_0] THEN + STRIP_TAC THEN AP_TERM_TAC THEN ASM_SIMP_TAC[] + ; ALL_TAC] THEN + REWRITE_TAC[GSYM READ_COMPONENT_COMPOSE] THEN + ASM_SIMP_TAC[] + ; ALL_TAC] THEN + + (* Inductive step: right to left *) + MP_TAC (ARITH_RULE `SUC len <= LENGTH (bl:byte list) ==> len <= LENGTH bl`) THEN + ASM_SIMP_TAC[] THEN REPEAT DISCH_TAC THEN + MP_TAC (SPECL [`len:num`; `ptr:int64`; `bl:byte list`; `s:armstate`] MEMORY_READ_BYTES_SUBSET_LEMMA) THEN + ASM_SIMP_TAC[] THEN + DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN + IMP_REWRITE_TAC[BYTE_LIST_AT_SPLIT] THEN + CONJ_TAC THENL [ASM_SIMP_TAC[]; ALL_TAC] THEN + ASM_SIMP_TAC[] +);; + + +let READ_MEMORY_BYTES128_BYTES = prove(`!z s. + read (memory :> bytes128 z) s = word (read (memory :> bytes (z,16)) s)`, + REPEAT STRIP_TAC THEN + ONCE_REWRITE_TAC[GSYM VAL_EQ] THEN + IMP_REWRITE_TAC [VAL_WORD_EQ] THEN + CONJ_TAC THENL [REWRITE_TAC [READ_MEMORY_BYTES_BYTES128]; ALL_TAC] THEN + REWRITE_TAC [MEMORY_BYTES_BOUND] + );; + +let WORD_JOIN_BOUND_TAC x y = + REWRITE_TAC[VAL_WORD_JOIN; DIMINDEX_CLAUSES] THEN + CONV_TAC NUM_REDUCE_CONV THEN + IMP_REWRITE_TAC[MOD_LT] THEN + CONJ_TAC THENL[ REWRITE_TAC[ADD_SYM]; ALL_TAC ] THEN + MP_TAC (ISPECL [x] VAL_BOUND) THEN + MP_TAC (ISPECL [y] VAL_BOUND) THEN + REWRITE_TAC[DIMINDEX_CLAUSES] THEN + CONV_TAC NUM_REDUCE_CONV THEN + ARITH_TAC;; + +let WORD_JOIN_16_8_ASSOC = WORD_BLAST + `!(x0:byte) (x1:byte) (x2:byte) (x3:byte) + (x4:byte) (x5:byte) (x6:byte) (x7:byte) + (x8:byte) (x9:byte) (x10:byte) (x11:byte) + (x12:byte) (x13:byte) (x14:byte) (x15:byte). + (word_join + (word_join + (word_join (word_join x15 x14 : int16) (word_join x13 x12 : int16) : int32) + (word_join (word_join x11 x10 : int16) (word_join x9 x8 : int16) : int32) : int64) + (word_join + (word_join (word_join x7 x6 : int16) (word_join x5 x4 : int16) : int32) + (word_join (word_join x3 x2 : int16) (word_join x1 x0 : int16) : int32) : int64)) = + (word_join + (word_join + (word_join + (word_join + (word_join + (word_join + (word_join + (word_join + (word_join + (word_join + (word_join + (word_join + (word_join + (word_join + (word_join x15 x14:16 word) + x13:24 word) + x12:32 word) + x11:40 word) + x10:48 word) + x9:56 word) + x8:64 word) + x7:72 word) + x6:80 word) + x5:88 word) + x4:96 word) + x3:104 word) + x2:112 word) + x1:120 word) + x0:128 word)`;; + +let VAL_OF_BYTES_TO_INT128_EQ_NUM_OF_BYTELIST = prove( + `!x:byte list. LENGTH x = 16 ==> val (bytes_to_int128 x) = num_of_bytelist x`, + REPEAT STRIP_TAC THEN + (* conversion for breaking down a list *) + MP_TAC ((GEN_REWRITE_CONV I [LENGTH_EQ_LIST_OF_SEQ] THENC + RAND_CONV LIST_OF_SEQ_CONV) `LENGTH (x:byte list) = 16`) THEN + ASM_SIMP_TAC[] THEN + DISCH_THEN (fun th -> ONCE_REWRITE_TAC[th]) THEN + REWRITE_TAC[bytes_to_int128] THEN + REWRITE_TAC EL_16_8_CLAUSES THEN + REPEAT_N 16 (ONCE_REWRITE_TAC[num_of_bytelist]) THEN + REWRITE_TAC[CONJUNCT1 num_of_bytelist] THEN + MAP_EVERY ABBREV_TAC + [`x0 = EL 0 x:byte`; `x1 = EL 1 x:byte`; `x2 = EL 2 x:byte`; `x3 = EL 3 x:byte`; + `x4 = EL 4 x:byte`; `x5 = EL 5 x:byte`; `x6 = EL 6 x:byte`; `x7 = EL 7 x:byte`; + `x8 = EL 8 x:byte`; `x9 = EL 9 x:byte`; `x10 = EL 10 x:byte`; `x11 = EL 11 x:byte`; + `x12 = EL 12 x:byte`; `x13 = EL 13 x:byte`; `x14 = EL 14 x:byte`; `x15 = EL 15 x:byte`] THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[ADD_0; WORD_JOIN_16_8_ASSOC] THEN + (* reduce RHS to LHS *) + SUBGOAL_THEN `val (x14:byte) + 0x100 * val (x15:byte) = val ((word_join x15 x14):int16)` SUBST1_TAC THENL + [ WORD_JOIN_BOUND_TAC `x15:byte` `x14:byte`; ALL_TAC] THEN ABBREV_TAC `y14:int16 = word_join (x15:byte) (x14:byte)` THEN + SUBGOAL_THEN `val (x13:byte) + 0x100 * val (y14:16 word) = val ((word_join y14 x13):24 word)` SUBST1_TAC THENL + [ WORD_JOIN_BOUND_TAC `y14:16 word` `x13:byte`; ALL_TAC] THEN ABBREV_TAC `y13:24 word = word_join (y14:16 word) (x13:byte)` THEN + SUBGOAL_THEN `val (x12:byte) + 0x100 * val (y13:24 word) = val ((word_join y13 x12):32 word)` SUBST1_TAC THENL + [ WORD_JOIN_BOUND_TAC `y13:24 word` `x12:byte`; ALL_TAC] THEN ABBREV_TAC `y12:32 word = word_join (y13:24 word) (x12:byte)` THEN + SUBGOAL_THEN `val (x11:byte) + 0x100 * val (y12:32 word) = val ((word_join y12 x11):40 word)` SUBST1_TAC THENL + [ WORD_JOIN_BOUND_TAC `y12:32 word` `x11:byte`; ALL_TAC] THEN ABBREV_TAC `y11:40 word = word_join (y12:32 word) (x11:byte)` THEN + SUBGOAL_THEN `val (x10:byte) + 0x100 * val (y11:40 word) = val ((word_join y11 x10):48 word)` SUBST1_TAC THENL + [ WORD_JOIN_BOUND_TAC `y11:40 word` `x10:byte`; ALL_TAC] THEN ABBREV_TAC `y10:48 word = word_join (y11:40 word) (x10:byte)` THEN + SUBGOAL_THEN `val (x9:byte) + 0x100 * val (y10:48 word) = val ((word_join y10 x9):56 word)` SUBST1_TAC THENL + [ WORD_JOIN_BOUND_TAC `y10:48 word` `x9:byte`; ALL_TAC] THEN ABBREV_TAC `y9:56 word = word_join (y10:48 word) (x9:byte)` THEN + SUBGOAL_THEN `val (x8:byte) + 0x100 * val (y9:56 word) = val ((word_join y9 x8):64 word)` SUBST1_TAC THENL + [ WORD_JOIN_BOUND_TAC `y9:56 word` `x8:byte`; ALL_TAC] THEN ABBREV_TAC `y8:64 word = word_join (y9:56 word) (x8:byte)` THEN + SUBGOAL_THEN `val (x7:byte) + 0x100 * val (y8:64 word) = val ((word_join y8 x7):72 word)` SUBST1_TAC THENL + [ WORD_JOIN_BOUND_TAC `y8:64 word` `x7:byte`; ALL_TAC] THEN ABBREV_TAC `y7:72 word = word_join (y8:64 word) (x7:byte)` THEN + SUBGOAL_THEN `val (x6:byte) + 0x100 * val (y7:72 word) = val ((word_join y7 x6):80 word)` SUBST1_TAC THENL + [ WORD_JOIN_BOUND_TAC `y7:72 word` `x6:byte`; ALL_TAC] THEN ABBREV_TAC `y6:80 word = word_join (y7:72 word) (x6:byte)` THEN + SUBGOAL_THEN `val (x5:byte) + 0x100 * val (y6:80 word) = val ((word_join y6 x5):88 word)` SUBST1_TAC THENL + [ WORD_JOIN_BOUND_TAC `y6:80 word` `x5:byte`; ALL_TAC] THEN ABBREV_TAC `y5:88 word = word_join (y6:80 word) (x5:byte)` THEN + SUBGOAL_THEN `val (x4:byte) + 0x100 * val (y5:88 word) = val ((word_join y5 x4):96 word)` SUBST1_TAC THENL + [ WORD_JOIN_BOUND_TAC `y5:88 word` `x4:byte`; ALL_TAC] THEN ABBREV_TAC `y4:96 word = word_join (y5:88 word) (x4:byte)` THEN + SUBGOAL_THEN `val (x3:byte) + 0x100 * val (y4:96 word) = val ((word_join y4 x3):104 word)` SUBST1_TAC THENL + [ WORD_JOIN_BOUND_TAC `y4:96 word` `x3:byte`; ALL_TAC] THEN ABBREV_TAC `y3:104 word = word_join (y4:96 word) (x3:byte)` THEN + SUBGOAL_THEN `val (x2:byte) + 0x100 * val (y3:104 word) = val ((word_join y3 x2):112 word)` SUBST1_TAC THENL + [ WORD_JOIN_BOUND_TAC `y3:104 word` `x2:byte`; ALL_TAC] THEN ABBREV_TAC `y2:112 word = word_join (y3:104 word) (x2:byte)` THEN + SUBGOAL_THEN `val (x1:byte) + 0x100 * val (y2:112 word) = val ((word_join y2 x1):120 word)` SUBST1_TAC THENL + [ WORD_JOIN_BOUND_TAC `y2:112 word` `x1:byte`; ALL_TAC] THEN ABBREV_TAC `y1:120 word = word_join (y2:112 word) (x1:byte)` THEN + SUBGOAL_THEN `val (x0:byte) + 0x100 * val (y1:120 word) = val ((word_join y1 x0):128 word)` SUBST1_TAC THENL + [ WORD_JOIN_BOUND_TAC `y1:120 word` `x0:byte`; ALL_TAC] THEN ABBREV_TAC `y0:128 word = word_join (y1:120 word) (x0:byte)` THEN + REFL_TAC +);; + + +let READ_BYTES_AND_BYTE128_SPLIT = prove( + `!(pt_ptr:int64) (sz:num) (x:byte list) (s:armstate). + sz + 16 <= LENGTH x ==> + read (memory :> bytes128 (word_add pt_ptr (word sz))) s = bytes_to_int128 (SUB_LIST (sz, 0x10) x) + /\ read (memory :> bytes (pt_ptr, sz)) s = num_of_bytelist (SUB_LIST (0, sz) x) + ==> read (memory :> bytes (pt_ptr,sz + 0x10)) s = num_of_bytelist (SUB_LIST (0, sz + 0x10) x)`, + REWRITE_TAC[READ_MEMORY_BYTES128_BYTES] THEN + REPEAT STRIP_TAC THEN + + SUBGOAL_THEN `sz <= LENGTH (x:byte list)` ASSUME_TAC THENL + [ UNDISCH_TAC `sz + 16 <= LENGTH (x:byte list)` THEN ARITH_TAC; ALL_TAC ] THEN + + SUBGOAL_THEN `16 <= LENGTH (x:byte list) - sz` ASSUME_TAC THENL + [ UNDISCH_TAC `sz + 16 <= LENGTH (x:byte list)` THEN ARITH_TAC; ALL_TAC ] THEN + + SUBGOAL_THEN `read (memory :> bytes (pt_ptr, sz + 16)) s = + read (memory :> bytes (pt_ptr, sz)) s + + 2 EXP (8 * sz) * (read (memory :> bytes (word_add pt_ptr (word sz), 16)) s)` SUBST1_TAC THENL + [ REWRITE_TAC[READ_COMPONENT_COMPOSE] THEN + REWRITE_TAC[READ_BYTES_COMBINE]; ALL_TAC] THEN + + ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN `read (memory :> bytes (word_add pt_ptr (word sz),0x10)) s = + val (bytes_to_int128 (SUB_LIST (sz,0x10) x))` SUBST1_TAC THENL + [ UNDISCH_THEN + `word (read (memory :> bytes (word_add (pt_ptr:int64) (word sz),0x10)) s) = + bytes_to_int128 (SUB_LIST (sz,0x10) x)` + (fun th -> MP_TAC (AP_TERM `val:int128->num` th)) THEN + IMP_REWRITE_TAC[VAL_WORD] THEN + SUBGOAL_THEN `read (memory :> bytes (word_add pt_ptr (word sz),0x10)) s < 2 EXP dimindex (:128)` ASSUME_TAC THENL + [ SIMP_TAC[MEMORY_BYTES_BOUND] ; ALL_TAC] THEN + SUBST_ALL_TAC DIMINDEX_128 THEN + ASM_SIMP_TAC[MOD_LT]; ALL_TAC] THEN + + IMP_REWRITE_TAC[NUM_OF_BYTELIST_OF_SUB_LIST] THEN + IMP_REWRITE_TAC[VAL_OF_BYTES_TO_INT128_EQ_NUM_OF_BYTELIST] THEN + REWRITE_TAC[LENGTH_SUB_LIST; MIN] THEN ASM_SIMP_TAC[] +);; + +let READ_BYTES_AND_BYTE128_MERGE = prove( + `!(pt_ptr:int64) (sz:num) (x:byte list) (s:armstate). + sz + 16 <= LENGTH x ==> + read (memory :> bytes (pt_ptr,sz + 0x10)) s = num_of_bytelist (SUB_LIST (0, sz + 0x10) x) + ==> (read (memory :> bytes (pt_ptr, sz)) s = num_of_bytelist (SUB_LIST (0, sz) x) /\ + read (memory :> bytes128 (word_add pt_ptr (word sz))) s = bytes_to_int128 (SUB_LIST (sz, 0x10) x))`, + REPEAT GEN_TAC THEN + STRIP_TAC THEN + REWRITE_TAC[READ_MEMORY_BYTES128_BYTES] THEN + + SUBGOAL_THEN `sz <= LENGTH (x:byte list)` ASSUME_TAC THENL + [ UNDISCH_TAC `sz + 16 <= LENGTH (x:byte list)` THEN ARITH_TAC; ALL_TAC ] THEN + + SUBGOAL_THEN `16 <= LENGTH (x:byte list) - sz` ASSUME_TAC THENL + [ UNDISCH_TAC `sz + 16 <= LENGTH (x:byte list)` THEN ARITH_TAC; ALL_TAC ] THEN + + SUBGOAL_THEN `read (memory :> bytes (pt_ptr, sz + 16)) s = + read (memory :> bytes (pt_ptr, sz)) s + + 2 EXP (8 * sz) * (read (memory :> bytes (word_add pt_ptr (word sz), 16)) s)` SUBST1_TAC THENL + [ REWRITE_TAC[READ_COMPONENT_COMPOSE] THEN + REWRITE_TAC[READ_BYTES_COMBINE]; ALL_TAC] THEN + + IMP_REWRITE_TAC[NUM_OF_BYTELIST_OF_SUB_LIST] THEN + REWRITE_TAC[READ_COMPONENT_COMPOSE] THEN + + DISCH_TAC THEN + CONJ_TAC THENL + [ (* First part: `read (bytes (pt_ptr,sz)) (read memory s) = + num_of_bytelist (SUB_LIST (0x0,sz) x)`*) + FIRST_X_ASSUM(MP_TAC o AP_TERM `\x. x MOD 2 EXP (8 * sz)`) THEN + ASM_REWRITE_TAC[] THEN + REWRITE_TAC[MOD_MULT_ADD; MOD_LT] THEN + REWRITE_TAC[READ_BYTES_MOD; MIN] THEN + SIMP_TAC[ARITH_RULE `len <= len`] THEN + DISCH_TAC THEN + IMP_REWRITE_TAC[MOD_LT] THEN + MP_TAC (SPEC `(SUB_LIST (0,sz) x:byte list)` NUM_OF_BYTELIST_BOUND) THEN + IMP_REWRITE_TAC[LENGTH_SUB_LIST; SUB_0; MIN] THEN + SUBGOAL_THEN `256 EXP sz = 2 EXP (8 * sz)` SUBST1_TAC THENL + [ REWRITE_TAC[ARITH_RULE `256 = 2 EXP 8`; EXP_EXP]; ALL_TAC] THEN + SIMP_TAC[]; + ALL_TAC + ] THEN + (* Second part: word (read (bytes (word_add pt_ptr (word sz),0x10)) (read memory s)) = + bytes_to_int128 (SUB_LIST (sz,0x10) x) *) + FIRST_X_ASSUM(MP_TAC o AP_TERM `\x. x DIV 2 EXP (8 * sz)`) THEN + ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN `~(0x2 EXP (0x8 * sz) = 0x0)` ASSUME_TAC THENL + [ REWRITE_TAC[EXP_EQ_0; ARITH_EQ]; ALL_TAC] THEN + IMP_REWRITE_TAC[DIV_MULT_ADD] THEN + SUBGOAL_THEN `read (bytes (pt_ptr,sz)) (read memory s) < 0x2 EXP (0x8 * sz)` ASSUME_TAC THENL + [ REWRITE_TAC[READ_BYTES_BOUND]; ALL_TAC] THEN + SUBGOAL_THEN `num_of_bytelist (SUB_LIST (0x0,sz) x) < 0x2 EXP (0x8 * sz)` ASSUME_TAC THENL + [ MP_TAC (SPEC `(SUB_LIST (0,sz) x:byte list)` NUM_OF_BYTELIST_BOUND) THEN + IMP_REWRITE_TAC[LENGTH_SUB_LIST; SUB_0; MIN] THEN + SUBGOAL_THEN `256 EXP sz = 2 EXP (8 * sz)` SUBST1_TAC THENL + [ REWRITE_TAC[ARITH_RULE `256 = 2 EXP 8`; EXP_EXP]; ALL_TAC] THEN SIMP_TAC[]; ALL_TAC] THEN + IMP_REWRITE_TAC[DIV_LT; ADD] THEN + DISCH_TAC THEN + + ONCE_REWRITE_TAC[GSYM VAL_EQ] THEN + IMP_REWRITE_TAC[VAL_OF_BYTES_TO_INT128_EQ_NUM_OF_BYTELIST] THEN + REWRITE_TAC[LENGTH_SUB_LIST; MIN] THEN ASM_SIMP_TAC[] THEN + REWRITE_TAC[VAL_WORD; DIMINDEX_128] THEN + SUBGOAL_THEN `num_of_bytelist (SUB_LIST (sz,0x10) x) < 2 EXP 0x80` ASSUME_TAC THENL + [ MP_TAC (SPEC `(SUB_LIST (sz,0x10) x:byte list)` NUM_OF_BYTELIST_BOUND) THEN + IMP_REWRITE_TAC[LENGTH_SUB_LIST; SUB_0; MIN] THEN + ARITH_TAC; ALL_TAC] THEN + IMP_REWRITE_TAC[MOD_LT] +);; + + +let DIVISION_BY_80_LEMMA = prove( + `!(a:num) b. a DIV 0x50 = b /\ + 0x10 divides a /\ + ~(a - b * 0x50 = 0x10) /\ + ~(a - b * 0x50 = 0x20) /\ + ~(a - b * 0x50 = 0x30) /\ + ~(a - b * 0x50 = 0x40) ==> + b * 0x50 = a`, + REPEAT STRIP_TAC THEN + (* Use the division theorem: a = b * 0x50 + (a MOD 0x50) *) + MP_TAC (SPECL [`a:num`; `0x50`] DIVISION) THEN + CONV_TAC NUM_REDUCE_CONV THEN + REPEAT STRIP_TAC THEN + + (* We have a = b * 0x50 + (a MOD 0x50) and a DIV 0x50 = b *) + SUBGOAL_THEN `a = b * 0x50 + (a MOD 0x50)` ASSUME_TAC THENL [ + ASM_ARITH_TAC; ALL_TAC] THEN + + (* Show that a MOD 0x50 = 0 by case analysis *) + SUBGOAL_THEN `a MOD 0x50 = 0` ASSUME_TAC THENL [ + (* Since 0x10 divides a, we know a = k * 0x10 for some k *) + UNDISCH_TAC `0x10 divides a` THEN + REWRITE_TAC[divides] THEN + STRIP_TAC THEN + + (* The remainder a MOD 0x50 must be a multiple of 0x10 and < 0x50 *) + (* So it's one of: 0, 0x10, 0x20, 0x30, 0x40 *) + SUBGOAL_THEN `(a MOD 0x50 = 0) \/ (a MOD 0x50 = 0x10) \/ + (a MOD 0x50 = 0x20) \/ (a MOD 0x50 = 0x30) \/ + (a MOD 0x50 = 0x40)` ASSUME_TAC THENL + [ ASM_REWRITE_TAC[] THEN + + SUBGOAL_THEN `(0x10 * x) MOD 0x50 = (x MOD 5) * 0x10` SUBST1_TAC THENL [ + SUBGOAL_THEN `0x50 = 5 * 0x10` SUBST1_TAC THENL [ + CONV_TAC NUM_REDUCE_CONV; ALL_TAC] THEN + MP_TAC (SPECL [`0x10 * x`; `0x10`; `5`] MOD_MULT_MOD) THEN + REWRITE_TAC[MOD_MULT; ADD_CLAUSES] THEN + IMP_REWRITE_TAC[DIV_MULT] THEN + CONV_TAC NUM_REDUCE_CONV THEN + SIMP_TAC[] THEN DISCH_TAC THEN + REWRITE_TAC[MULT_SYM] + ; ALL_TAC] THEN + + SUBGOAL_THEN `x MOD 5 < 5` ASSUME_TAC THENL [ + REWRITE_TAC[MOD_LT_EQ] THEN CONV_TAC NUM_REDUCE_CONV; ALL_TAC] THEN + SUBGOAL_THEN `x MOD 5 = 0 \/ x MOD 5 = 1 \/ x MOD 5 = 2 \/ x MOD 5 = 3 \/ x MOD 5 = 4` ASSUME_TAC THENL [ + UNDISCH_TAC `x MOD 0x5 < 0x5` THEN ARITH_TAC ; ALL_TAC] THEN + + REPEAT (FIRST_X_ASSUM DISJ_CASES_TAC) THENL + [ ASM_REWRITE_TAC[] THEN CONV_TAC NUM_REDUCE_CONV; + ASM_REWRITE_TAC[] THEN CONV_TAC NUM_REDUCE_CONV; + ASM_REWRITE_TAC[] THEN CONV_TAC NUM_REDUCE_CONV; + ASM_REWRITE_TAC[] THEN CONV_TAC NUM_REDUCE_CONV; + ASM_REWRITE_TAC[] THEN CONV_TAC NUM_REDUCE_CONV] + ; ALL_TAC] THEN + + (* Now eliminate the non-zero cases using the assumptions *) + SUBGOAL_THEN `~(a MOD 0x50 = 0x10)` ASSUME_TAC THENL + [ UNDISCH_TAC `~(a - b * 0x50 = 0x10)` THEN + UNDISCH_TAC `a = b * 0x50 + a MOD 0x50` THEN + ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `~(a MOD 0x50 = 0x20)` ASSUME_TAC THENL + [ UNDISCH_TAC `~(a - b * 0x50 = 0x20)` THEN + UNDISCH_TAC `a = b * 0x50 + a MOD 0x50` THEN + ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `~(a MOD 0x50 = 0x30)` ASSUME_TAC THENL + [ UNDISCH_TAC `~(a - b * 0x50 = 0x30)` THEN + UNDISCH_TAC `a = b * 0x50 + a MOD 0x50` THEN + ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `~(a MOD 0x50 = 0x40)` ASSUME_TAC THENL + [ UNDISCH_TAC `~(a - b * 0x50 = 0x40)` THEN + UNDISCH_TAC `a = b * 0x50 + a MOD 0x50` THEN + ARITH_TAC; ALL_TAC] THEN + + ASM_MESON_TAC[]; ALL_TAC + ] THEN + + (* Finally conclude b * 0x50 = a *) + ASM_ARITH_TAC +);; + + +let NUM_BLOCKS_TO_VAL = prove( + `!(len:int64). word_and len (word 0xfffffffffffffff0) = word (16 * (val len DIV 16))`, + GEN_TAC THEN + REWRITE_TAC[WORD_AND_MASK16] THEN + REWRITE_TAC[GSYM VAL_EQ] THEN + SUBGOAL_THEN `16 * val (len:int64) DIV 16 = val len - (val len MOD 16)` SUBST1_TAC THENL + [REWRITE_TAC[DIVISION_SIMP] THEN ARITH_TAC; ALL_TAC] THEN + REWRITE_TAC[ARITH_RULE `0xf = 2 EXP 4 - 1`] THEN + REWRITE_TAC[WORD_AND_MASK_WORD] THEN + CONV_TAC NUM_REDUCE_CONV THEN + + REWRITE_TAC[VAL_WORD_SUB] THEN + SUBGOAL_THEN `val (len:int64) >= val ((word (val len MOD 0x10)):int64)` ASSUME_TAC THENL [ + REWRITE_TAC[VAL_WORD; DIMINDEX_64; GE] THEN + MP_TAC (SPECL [`val (len:int64) MOD 0x10`; `0x2 EXP 0x40`] MOD_LE) THEN + ARITH_TAC; + ALL_TAC + ] THEN + REWRITE_TAC[VAL_WORD; DIMINDEX_64] THEN + + SUBGOAL_THEN `val (len:int64) MOD 0x10 < 0x2 EXP 0x40` ASSUME_TAC THENL + [ TRANS_TAC LET_TRANS `val (len:int64)` THEN + REWRITE_TAC[VAL_BOUND_64; MOD_LE]; ALL_TAC] THEN + + SUBGOAL_THEN `val (len:int64) MOD 0x10 MOD 0x2 EXP 0x40 = val len MOD 0x10` ASSUME_TAC THENL + [ MP_TAC (SPECL [`val (len:int64) MOD 0x10`; `0x2 EXP 0x40`] MOD_LT) THEN + ASM_SIMP_TAC[]; ALL_TAC] THEN + ASM_REWRITE_TAC[] THEN + + MP_TAC (SPECL [`val (len:int64)`; `0x2 EXP 0x40`; `val (len:int64) MOD 0x10`] + (ARITH_RULE `!a b c. c <= a ==> c <= b ==> a + b - c = (a - c) + b`)) THEN + ANTS_TAC THENL [ REWRITE_TAC[MOD_LE]; ALL_TAC] THEN + ANTS_TAC THENL [ ASM_ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[] THEN DISCH_TAC THEN + + MP_TAC (SPECL [`1`; `0x2 EXP 0x40`; `val (len:int64) - val len MOD 0x10`] + (CONJUNCT1 (CONJUNCT2 (CONJUNCT2 MOD_MULT_ADD)))) THEN + CONV_TAC NUM_REDUCE_CONV +);; + +let NUM_BLOCKS_MINUS1_TO_VAL = prove( + `!(len:int64). val len >= 16 ==> + word_sub (word_and (len:int64) (word 0xfffffffffffffff0)) (word 0x10) = + word (16 * (val len DIV 16 - 1))`, + REWRITE_TAC[NUM_BLOCKS_TO_VAL] THEN + REPEAT STRIP_TAC THEN + REWRITE_TAC[LEFT_SUB_DISTRIB; WORD_SUB] THEN + CONV_TAC NUM_REDUCE_CONV THEN + SUBGOAL_THEN `0x10 <= 0x10 * val (len:int64) DIV 0x10` ASSUME_TAC THENL + [ MP_TAC (SPECL [`0x10`; `val (len:int64)`; `1`] LE_RDIV_EQ) THEN + CONV_TAC NUM_REDUCE_CONV THEN + REWRITE_TAC[GSYM GE] THEN + ASM_SIMP_TAC[] THEN + ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[] +);; + +let BREAK_ONE_BLOCK_INTO_BYTES = prove( + `!(addr:int64) (s:armstate) (p:int128). + read (memory :> bytes128 addr) s = p <=> + (read (memory :> bytes8 addr) s = EL 0 (int128_to_bytes p) /\ + read (memory :> bytes8 (word_add addr (word 1))) s = EL 1 (int128_to_bytes p) /\ + read (memory :> bytes8 (word_add addr (word 2))) s = EL 2 (int128_to_bytes p) /\ + read (memory :> bytes8 (word_add addr (word 3))) s = EL 3 (int128_to_bytes p) /\ + read (memory :> bytes8 (word_add addr (word 4))) s = EL 4 (int128_to_bytes p) /\ + read (memory :> bytes8 (word_add addr (word 5))) s = EL 5 (int128_to_bytes p) /\ + read (memory :> bytes8 (word_add addr (word 6))) s = EL 6 (int128_to_bytes p) /\ + read (memory :> bytes8 (word_add addr (word 7))) s = EL 7 (int128_to_bytes p) /\ + read (memory :> bytes8 (word_add addr (word 8))) s = EL 8 (int128_to_bytes p) /\ + read (memory :> bytes8 (word_add addr (word 9))) s = EL 9 (int128_to_bytes p) /\ + read (memory :> bytes8 (word_add addr (word 10))) s = EL 10 (int128_to_bytes p) /\ + read (memory :> bytes8 (word_add addr (word 11))) s = EL 11 (int128_to_bytes p) /\ + read (memory :> bytes8 (word_add addr (word 12))) s = EL 12 (int128_to_bytes p) /\ + read (memory :> bytes8 (word_add addr (word 13))) s = EL 13 (int128_to_bytes p) /\ + read (memory :> bytes8 (word_add addr (word 14))) s = EL 14 (int128_to_bytes p) /\ + read (memory :> bytes8 (word_add addr (word 15))) s = EL 15 (int128_to_bytes p)) + `, + REPEAT GEN_TAC THEN + EQ_TAC THENL[ + STRIP_TAC THEN + MP_TAC (SPECL [`0:num`; `addr:int64`; `s:armstate`] BYTES128_TO_BYTES8_THM) THEN + REWRITE_TAC[WORD_ADD_0] THEN CONV_TAC NUM_REDUCE_CONV THEN + ASM_REWRITE_TAC[] THEN + DISCH_TAC THEN + REWRITE_TAC[int128_to_bytes] THEN + REWRITE_TAC EL_16_8_CLAUSES THEN + ASM_REWRITE_TAC[] THEN + REWRITE_TAC[bytes_to_int128] THEN + REWRITE_TAC EL_16_8_CLAUSES THEN + REWRITE_TAC[WORD_ADD_0] THEN + ABBREV_TAC `x0 = read (memory :> bytes8 (addr:int64)) s` THEN + ABBREV_TAC `x1 = read (memory :> bytes8 (word_add (addr:int64) (word 0x1))) s` THEN + ABBREV_TAC `x2 = read (memory :> bytes8 (word_add (addr:int64) (word 0x2))) s` THEN + ABBREV_TAC `x3 = read (memory :> bytes8 (word_add (addr:int64) (word 0x3))) s` THEN + ABBREV_TAC `x4 = read (memory :> bytes8 (word_add (addr:int64) (word 0x4))) s` THEN + ABBREV_TAC `x5 = read (memory :> bytes8 (word_add (addr:int64) (word 0x5))) s` THEN + ABBREV_TAC `x6 = read (memory :> bytes8 (word_add (addr:int64) (word 0x6))) s` THEN + ABBREV_TAC `x7 = read (memory :> bytes8 (word_add (addr:int64) (word 0x7))) s` THEN + ABBREV_TAC `x8 = read (memory :> bytes8 (word_add (addr:int64) (word 0x8))) s` THEN + ABBREV_TAC `x9 = read (memory :> bytes8 (word_add (addr:int64) (word 0x9))) s` THEN + ABBREV_TAC `xa = read (memory :> bytes8 (word_add (addr:int64) (word 0xa))) s` THEN + ABBREV_TAC `xb = read (memory :> bytes8 (word_add (addr:int64) (word 0xb))) s` THEN + ABBREV_TAC `xc = read (memory :> bytes8 (word_add (addr:int64) (word 0xc))) s` THEN + ABBREV_TAC `xd = read (memory :> bytes8 (word_add (addr:int64) (word 0xd))) s` THEN + ABBREV_TAC `xe = read (memory :> bytes8 (word_add (addr:int64) (word 0xe))) s` THEN + ABBREV_TAC `xf = read (memory :> bytes8 (word_add (addr:int64) (word 0xf))) s` THEN + REPEAT STRIP_TAC THEN + REPEAT BITBLAST_TAC; ALL_TAC] THEN + + REPEAT STRIP_TAC THEN + MP_TAC (SPECL [`0:num`; `addr:int64`; `s:armstate`] BYTES128_TO_BYTES8_THM) THEN + CONV_TAC NUM_REDUCE_CONV THEN REWRITE_TAC[WORD_ADD_0] THEN + ASM_REWRITE_TAC[] THEN + DISCH_THEN (fun th -> REWRITE_TAC[th]) THEN + REWRITE_TAC[int128_to_bytes] THEN + REWRITE_TAC EL_16_8_CLAUSES THEN + REWRITE_TAC[bytes_to_int128] THEN + REWRITE_TAC EL_16_8_CLAUSES THEN + BITBLAST_TAC +);; + +let SELECT_ONE_BYTE_FROM_BLOCK = prove( + `!(addr:int64) (off:int64) (s:armstate) (p:int128). + read (memory :> bytes128 addr) s = p ==> + val off < 16 ==> + read (memory :> bytes8 (word_add addr off)) s = EL (val off) (int128_to_bytes p)`, + REPEAT STRIP_TAC THEN + FIRST_ASSUM (STRIP_ASSUME_TAC o + MATCH_MP (fst (EQ_IMP_RULE + (SPECL [`addr:int64`; `s:armstate`; `p:int128`] BREAK_ONE_BLOCK_INTO_BYTES)))) THEN + SUBGOAL_THEN `word_add addr (off:int64) = word_add addr (word (val off))` SUBST1_TAC THENL + [REWRITE_TAC[WORD_VAL]; ALL_TAC] THEN + UNDISCH_TAC `val (off:int64) < 16` THEN + SPEC_TAC (`val (off:int64)`, `n:num`) THEN + CONV_TAC EXPAND_CASES_CONV THEN + ASM_REWRITE_TAC[WORD_ADD_0] +);; + +let SELECT_ONE_BYTE_FROM_FORALL = prove( + `!(ptr:int64) (len:int64) (addr:int64) (bl:byte list) (s:armstate). + (forall j. j < val len ==> read (memory :> bytes8 (word_add ptr (word j))) s = EL j bl) ==> + val addr < val len ==> + LENGTH bl = val len ==> + read (memory :> bytes8 (word_add ptr addr)) s = EL (val addr) bl`, + REPEAT STRIP_TAC THEN + FIRST_X_ASSUM (MP_TAC o SPEC `val (addr:int64)`) THEN + ASM_REWRITE_TAC[] THEN + REWRITE_TAC[WORD_VAL] +);; + +let IVAL_WORD_LT = prove( + `!i. i < 2 EXP 63 ==> ival ((word i):int64) = &i`, + GEN_TAC THEN DISCH_TAC THEN + REWRITE_TAC[ival; DIMINDEX_64; ARITH_RULE `64 - 1 = 63`] THEN + REWRITE_TAC[VAL_WORD; DIMINDEX_64] THEN + SUBGOAL_THEN `i < 2 EXP 64` ASSUME_TAC THENL + [ TRANS_TAC LT_TRANS `2 EXP 63` THEN + ASM_REWRITE_TAC[] THEN + CONV_TAC NUM_REDUCE_CONV; + ALL_TAC] THEN + ASM_SIMP_TAC[MOD_LT] +);; + +let READ_LT_2BLOCK = prove( + `!(ptr:int64) (len:int64) (bl:byte list) (s:armstate). + LENGTH bl = val len ==> + val len >= 0x10 ==> + val len < 0x20 ==> + (forall i. i < val len + ==> read (memory :> bytes8 (word_add ptr (word i))) s = EL i bl) + ==> read (memory :> bytes128 ptr) s = bytes_to_int128 (SUB_LIST (0, 16) bl)`, + REPEAT STRIP_TAC THEN + MP_TAC (SPECL [`0:num`; `bl:byte list`; `ptr:int64`; + `len:int64`; `s:armstate`] BYTE_LIST_AT_1BLOCKS) THEN + REWRITE_TAC[byte_list_at] THEN + ANTS_TAC THENL[ ASM_SIMP_TAC[]; ALL_TAC] THEN + ANTS_TAC THENL[ ASM_SIMP_TAC[]; ALL_TAC] THEN + ANTS_TAC THENL[ ASM_ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[WORD_ADD_0] +);; + +let READ_LT_3BLOCK = prove( + `!(ptr:int64) (len:int64) (bl:byte list) (s:armstate). + LENGTH bl = val len ==> + ~(val len < 0x20) ==> + val len < 0x30 ==> + (forall i. i < val len + ==> read (memory :> bytes8 (word_add ptr (word i))) s = EL i bl) + ==> read (memory :> bytes128 ptr) s = bytes_to_int128 (SUB_LIST (0, 16) bl) /\ + read (memory :> bytes128 (word_add ptr (word 16))) s = + bytes_to_int128 (SUB_LIST (16, 16) bl)`, + REPEAT GEN_TAC THEN REPEAT_N 4 STRIP_TAC THEN + MP_TAC (SPECL [`0:num`; `bl:byte list`; `ptr:int64`; + `len:int64`; `s:armstate`] BYTE_LIST_AT_2BLOCKS) THEN + REWRITE_TAC[byte_list_at] THEN + ANTS_TAC THENL[ ASM_SIMP_TAC[]; ALL_TAC] THEN + ANTS_TAC THENL[ ASM_SIMP_TAC[]; ALL_TAC] THEN + ANTS_TAC THENL[ ASM_ARITH_TAC; ALL_TAC] THEN + CONV_TAC NUM_REDUCE_CONV THEN + ASM_SIMP_TAC[WORD_ADD_0] +);; + +let READ_LT_4BLOCK = prove( + `!(ptr:int64) (len:int64) (bl:byte list) (s:armstate). + LENGTH bl = val len ==> + ~(val len < 0x30) ==> + val len < 0x40 ==> + (forall i. i < val len + ==> read (memory :> bytes8 (word_add ptr (word i))) s = EL i bl) + ==> read (memory :> bytes128 ptr) s = bytes_to_int128 (SUB_LIST (0, 16) bl) /\ + read (memory :> bytes128 (word_add ptr (word 16))) s = + bytes_to_int128 (SUB_LIST (16, 16) bl) /\ + read (memory :> bytes128 (word_add ptr (word 32))) s = + bytes_to_int128 (SUB_LIST (32, 16) bl)`, + REPEAT GEN_TAC THEN REPEAT_N 4 STRIP_TAC THEN + MP_TAC (SPECL [`0:num`; `bl:byte list`; `ptr:int64`; + `len:int64`; `s:armstate`] BYTE_LIST_AT_3BLOCKS) THEN + REWRITE_TAC[byte_list_at] THEN + ANTS_TAC THENL[ ASM_SIMP_TAC[]; ALL_TAC] THEN + ANTS_TAC THENL[ ASM_SIMP_TAC[]; ALL_TAC] THEN + ANTS_TAC THENL[ ASM_ARITH_TAC; ALL_TAC] THEN + CONV_TAC NUM_REDUCE_CONV THEN + ASM_SIMP_TAC[WORD_ADD_0] +);; + +let READ_LT_5BLOCK = prove( + `!(ptr:int64) (len:int64) (bl:byte list) (s:armstate). + LENGTH bl = val len ==> + ~(val len < 0x40) ==> + val len < 0x50 ==> + (forall i. i < val len + ==> read (memory :> bytes8 (word_add ptr (word i))) s = EL i bl) + ==> read (memory :> bytes128 ptr) s = bytes_to_int128 (SUB_LIST (0, 16) bl) /\ + read (memory :> bytes128 (word_add ptr (word 16))) s = + bytes_to_int128 (SUB_LIST (16, 16) bl) /\ + read (memory :> bytes128 (word_add ptr (word 32))) s = + bytes_to_int128 (SUB_LIST (32, 16) bl) /\ + read (memory :> bytes128 (word_add ptr (word 48))) s = + bytes_to_int128 (SUB_LIST (48, 16) bl)`, + REPEAT GEN_TAC THEN REPEAT_N 4 STRIP_TAC THEN + MP_TAC (SPECL [`0:num`; `bl:byte list`; `ptr:int64`; + `len:int64`; `s:armstate`] BYTE_LIST_AT_4BLOCKS) THEN + REWRITE_TAC[byte_list_at] THEN + ANTS_TAC THENL[ ASM_SIMP_TAC[]; ALL_TAC] THEN + ANTS_TAC THENL[ ASM_SIMP_TAC[]; ALL_TAC] THEN + ANTS_TAC THENL[ ASM_ARITH_TAC; ALL_TAC] THEN + CONV_TAC NUM_REDUCE_CONV THEN + ASM_SIMP_TAC[WORD_ADD_0] +);; + +let READ_LT_6BLOCK = prove( + `!(ptr:int64) (len:int64) (bl:byte list) (s:armstate). + LENGTH bl = val len ==> + ~(val len < 0x50) ==> + val len < 0x60 ==> + (forall i. i < val len + ==> read (memory :> bytes8 (word_add ptr (word i))) s = EL i bl) + ==> read (memory :> bytes128 ptr) s = bytes_to_int128 (SUB_LIST (0, 16) bl) /\ + read (memory :> bytes128 (word_add ptr (word 16))) s = + bytes_to_int128 (SUB_LIST (16, 16) bl) /\ + read (memory :> bytes128 (word_add ptr (word 32))) s = + bytes_to_int128 (SUB_LIST (32, 16) bl) /\ + read (memory :> bytes128 (word_add ptr (word 48))) s = + bytes_to_int128 (SUB_LIST (48, 16) bl) /\ + read (memory :> bytes128 (word_add ptr (word 64))) s = + bytes_to_int128 (SUB_LIST (64, 16) bl)`, + REPEAT GEN_TAC THEN REPEAT_N 4 STRIP_TAC THEN + MP_TAC (SPECL [`0:num`; `bl:byte list`; `ptr:int64`; + `len:int64`; `s:armstate`] BYTE_LIST_AT_5BLOCKS) THEN + REWRITE_TAC[byte_list_at] THEN + ANTS_TAC THENL[ ASM_SIMP_TAC[]; ALL_TAC] THEN + ANTS_TAC THENL[ ASM_SIMP_TAC[]; ALL_TAC] THEN + ANTS_TAC THENL[ ASM_ARITH_TAC; ALL_TAC] THEN + CONV_TAC NUM_REDUCE_CONV THEN + ASM_SIMP_TAC[WORD_ADD_0] +);; + + +(**********************************************************************) +(** Common Spec function lemmas **) + +let INT128_TO_BYTES_OF_BYTES_TO_INT128 = prove( + `!x. LENGTH x = 16 ==> int128_to_bytes (bytes_to_int128 x) = x`, + REPEAT STRIP_TAC THEN + MP_TAC ((GEN_REWRITE_CONV I [LENGTH_EQ_LIST_OF_SEQ] THENC + RAND_CONV LIST_OF_SEQ_CONV) `LENGTH (x:byte list) = 16`) THEN + ASM_SIMP_TAC[] THEN + DISCH_THEN (fun th -> ONCE_REWRITE_TAC[th]) THEN + REWRITE_TAC[bytes_to_int128] THEN + REWRITE_TAC EL_16_8_CLAUSES THEN + REWRITE_TAC[int128_to_bytes] THEN + REWRITE_TAC[CONS_11] THEN + REPEAT (CONJ_TAC THEN BITBLAST_TAC) +);; + +let LENGTH_OF_INT128_TO_BYTES = prove( + `!x. LENGTH(int128_to_bytes x) = 16`, + STRIP_TAC THEN + REWRITE_TAC[int128_to_bytes] THEN + REWRITE_TAC[LENGTH] THEN + CONV_TAC NUM_REDUCE_CONV +);; + +let SUB_LIST_OF_INT128_TO_BYTES = prove( + `!x. SUB_LIST (0, 16) (int128_to_bytes x) = int128_to_bytes x`, + GEN_TAC THEN + MP_TAC (SPEC `x:int128` LENGTH_OF_INT128_TO_BYTES) THEN + DISCH_TAC THEN + IMP_REWRITE_TAC[SUB_LIST_LENGTH_IMPLIES] +);; + +let ELEM_TAC i = + CONV_TAC (RAND_CONV (REWRITE_CONV [num_CONV i])) THEN + REWRITE_TAC[bytelist_of_num] THEN + REWRITE_TAC[CONS_11] THEN + CONJ_TAC THENL [ + REWRITE_TAC[word_subword] THEN + AP_TERM_TAC THEN + (ARITH_TAC ORELSE + ( ASM_REWRITE_TAC[CONJUNCT1 EXP; DIV_1; DIV_DIV] THEN + CONV_TAC NUM_REDUCE_CONV)); ALL_TAC];; + +let INT128_TO_BYTES_EQ_BYTELIST_OF_NUM = prove( + `!x. int128_to_bytes x = bytelist_of_num 16 (val x)`, + GEN_TAC THEN + REWRITE_TAC[int128_to_bytes] THEN + + MAP_EVERY (fun i -> ELEM_TAC (mk_numeral (num i))) (List.rev (2 -- 16)) THEN + CONV_TAC (RAND_CONV (REWRITE_CONV [num_CONV `1`])) THEN + REWRITE_TAC[bytelist_of_num] THEN + REWRITE_TAC[CONS_11] THEN + REWRITE_TAC[word_subword] THEN + AP_TERM_TAC THEN + ASM_REWRITE_TAC[DIV_DIV] THEN + CONV_TAC NUM_REDUCE_CONV +);; + +let NUM_OF_BYTELIST_OF_INT128_TO_BYTES = prove( + `!x. num_of_bytelist (int128_to_bytes x) = val x`, + GEN_TAC THEN + REWRITE_TAC[INT128_TO_BYTES_EQ_BYTELIST_OF_NUM] THEN + REWRITE_TAC[NUM_OF_BYTELIST_OF_NUM] THEN + SUBGOAL_THEN `val (x:int128) < 2 EXP 128` ASSUME_TAC THENL + [ MP_TAC (ISPEC `x:int128` VAL_BOUND) THEN + REWRITE_TAC[DIMINDEX_128] THEN + ARITH_TAC; ALL_TAC + ] THEN + IMP_REWRITE_TAC[MOD_LT] THEN + ASM_ARITH_TAC +);; + +let BYTES_TO_INT128_OF_INT128_TO_BYTES = prove( + `!x. bytes_to_int128 (int128_to_bytes x) = x`, + GEN_TAC THEN + REWRITE_TAC[int128_to_bytes; bytes_to_int128] THEN + REWRITE_TAC EL_16_8_CLAUSES THEN + BITBLAST_TAC +);; + +let CALCULATE_TWEAK_EXPAND = prove( + `!x iv key. + GF_128_mult_by_primitive (calculate_tweak x iv key) = + calculate_tweak (x + 0x1) iv key`, + REPEAT GEN_TAC THEN + REWRITE_TAC[ARITH_RULE `x + 1 = SUC x`] THEN + CONV_TAC (RAND_CONV (REWRITE_CONV[CONJUNCT2 calculate_tweak])) THEN + REFL_TAC +);; + +let VALUE_OF_ACC_LEN = prove( + `!(i:int64) (len:int64). + val i * 0x50 <= val len ==> + val len DIV 0x50 = val i ==> + 0x10 divides val len ==> + acc_len i len = val len`, + REPEAT STRIP_TAC THEN + REWRITE_TAC[acc_len] THEN + REPEAT COND_CASES_TAC THENL + [ + ASM_ARITH_TAC; + ASM_ARITH_TAC; + ASM_ARITH_TAC; + ASM_ARITH_TAC; + REWRITE_TAC[ARITH_RULE `!a. 0x50 * a = a * 0x50`] THEN + SUBGOAL_THEN `val (i:int64) * 0x50 = val (len:int64)` ASSUME_TAC THENL + [ MATCH_MP_TAC (SPECL [`val (len:int64)`; `val (i:int64)`] DIVISION_BY_80_LEMMA) THEN + REPEAT CONJ_TAC THENL + [ + ASM_SIMP_TAC[]; + ASM_SIMP_TAC[]; + UNDISCH_TAC `~(val (i:int64) * 0x50 + 0x10 = val (len:int64))` THEN + UNDISCH_TAC `val (i:int64) * 0x50 <= val (len:int64)` THEN + ARITH_TAC; + UNDISCH_TAC `~(val (i:int64) * 0x50 + 0x20 = val (len:int64))` THEN + UNDISCH_TAC `val (i:int64) * 0x50 <= val (len:int64)` THEN + ARITH_TAC; + UNDISCH_TAC `~(val (i:int64) * 0x50 + 0x30 = val (len:int64))` THEN + UNDISCH_TAC `val (i:int64) * 0x50 <= val (len:int64)` THEN + ARITH_TAC; + UNDISCH_TAC `~(val (i:int64) * 0x50 + 0x40 = val (len:int64))` THEN + UNDISCH_TAC `val (i:int64) * 0x50 <= val (len:int64)` THEN + ARITH_TAC + ]; ALL_TAC] THEN + ASM_ARITH_TAC + ] +);; + +let BOUND_OF_ACC_LEN = prove( + `!(i:int64) (len:int64) x. + val i * 0x50 <= val len ==> + val len DIV 0x50 = val i ==> + 0x10 divides val len ==> + val len < x ==> acc_len i len < x`, + REPEAT STRIP_TAC THEN + SUBGOAL_THEN `acc_len i len = val (len:int64)` ASSUME_TAC THENL + [ MP_TAC (SPECL [`i:int64`; `len:int64`] VALUE_OF_ACC_LEN) THEN + ASM_SIMP_TAC[]; ALL_TAC] THEN + ASM_ARITH_TAC +);; + + +(* In the cipher-stealing loop invariant, all bytes remain the same between iterations + except the current byte i, which is from the corresponding location i in the tail of pt *) +let CIPHER_STEALING_BYTE_EQUAL = prove( + `!(i:num) (curr_len:num) (tail_len:int64) (PP:int128) (ct:byte list). + i < val tail_len /\ val tail_len < 16 ==> + curr_len + 16 + val tail_len = LENGTH ct ==> + let InvPP = cipher_stealing_inv (i + 1) curr_len (val tail_len) PP ct + and InvPP' = cipher_stealing_inv i curr_len (val tail_len) PP ct in + (!j. 0 <= j /\ j < 16 /\ ~(j = i) ==> EL j (int128_to_bytes InvPP) = EL j (int128_to_bytes InvPP')) /\ + EL i (int128_to_bytes InvPP') = word_zx (EL (curr_len + 16 + i) ct)`, + REPEAT STRIP_TAC THEN + REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + CONJ_TAC THENL + [ + REPEAT STRIP_TAC THEN + REWRITE_TAC[cipher_stealing_inv] THEN + IMP_REWRITE_TAC[INT128_TO_BYTES_OF_BYTES_TO_INT128] THEN + REPEAT CONJ_TAC THENL + [ + (* Three cases: 0 <= j < i, i < j < val tail_len, val tail_len <= j < 16 *) + ASM_CASES_TAC `j < i` THENL + [ + SUBGOAL_THEN `j < LENGTH (SUB_LIST (0x0,i + 0x1) (int128_to_bytes PP))` ASSUME_TAC THENL + [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN + ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `j < LENGTH (SUB_LIST (0x0,i) (int128_to_bytes PP))` ASSUME_TAC THENL + [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN + ASM_ARITH_TAC ; ALL_TAC] THEN + REWRITE_TAC[EL_APPEND] THEN + ASM_SIMP_TAC[] THEN + MP_TAC (ISPECL [`j:num`; `i:num`; `(int128_to_bytes PP):byte list`] EL_SUB_LIST) THEN + ANTS_TAC THENL + [ REWRITE_TAC[LENGTH_OF_INT128_TO_BYTES] THEN + ASM_ARITH_TAC; ALL_TAC ] THEN + MP_TAC (ISPECL [`j:num`; `(i + 1):num`; `(int128_to_bytes PP):byte list`] EL_SUB_LIST) THEN + ANTS_TAC THENL + [ REWRITE_TAC[LENGTH_OF_INT128_TO_BYTES] THEN + ASM_ARITH_TAC; ALL_TAC ] THEN + SIMP_TAC[]; ALL_TAC + ] THEN + ASM_CASES_TAC `j < val (tail_len:int64)` THENL + [ + SUBGOAL_THEN `j > i` ASSUME_TAC THENL[ASM_ARITH_TAC; ALL_TAC] THEN + REWRITE_TAC[EL_APPEND] THEN + SUBGOAL_THEN `LENGTH (SUB_LIST (0x0,i + 0x1) (int128_to_bytes PP)) = i + 1` SUBST1_TAC THENL + [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN + ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `LENGTH (SUB_LIST (0x0,i) (int128_to_bytes PP)) = i` SUBST1_TAC THENL + [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN + ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `LENGTH (SUB_LIST (i + 0x1,val (tail_len:int64) - (i + 0x1)) + (SUB_LIST (curr_len + 0x10,val tail_len) (ct:byte list))) + = val tail_len - (i + 1)` SUBST1_TAC THENL + [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN + ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `LENGTH (SUB_LIST (i,val (tail_len:int64) - i) + (SUB_LIST (curr_len + 0x10,val tail_len) (ct:byte list))) + = val tail_len - i` SUBST1_TAC THENL + [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN + ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `~(j < i)` ASSUME_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `~(j < i + 1)` ASSUME_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `j - i < val (tail_len:int64) - i` ASSUME_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `j - (i + 1) < val (tail_len:int64) - (i + 1)` ASSUME_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[] THEN + MP_TAC (ISPECL [`(j - i):num`; `i:num`; + `(SUB_LIST (curr_len + 16,val (tail_len:int64)) (ct:byte list)):byte list`; + `(val (tail_len:int64) - i):num`] EL_SUB_LIST_SHIFT) THEN + ASM_SIMP_TAC[] THEN + ANTS_TAC THENL [ REWRITE_TAC[LENGTH_SUB_LIST] THEN ASM_ARITH_TAC; ALL_TAC] THEN + IMP_REWRITE_TAC[ARITH_RULE `!i j. j > i ==> j - i - 1 = j - (i + 1)`] THEN + ASM_ARITH_TAC; ALL_TAC + ] THEN + (* j >= val tail_len *) + REWRITE_TAC[EL_APPEND] THEN + SUBGOAL_THEN `LENGTH (SUB_LIST (0x0,i + 0x1) (int128_to_bytes PP)) = i + 1` SUBST1_TAC THENL + [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN + ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `LENGTH (SUB_LIST (0x0,i) (int128_to_bytes PP)) = i` SUBST1_TAC THENL + [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN + ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `LENGTH (SUB_LIST (i + 0x1,val (tail_len:int64) - (i + 0x1)) + (SUB_LIST (curr_len + 0x10,val tail_len) (ct:byte list))) + = val tail_len - (i + 1)` SUBST1_TAC THENL + [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN + ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `LENGTH (SUB_LIST (i,val (tail_len:int64) - i) + (SUB_LIST (curr_len + 0x10,val tail_len) (ct:byte list))) + = val tail_len - i` SUBST1_TAC THENL + [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN + ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `~(j < i)` ASSUME_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `~(j < i + 1)` ASSUME_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `~(j - i < val (tail_len:int64) - i)` ASSUME_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `~(j - (i + 1) < val (tail_len:int64) - (i + 1))` ASSUME_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[] THEN + AP_THM_TAC THEN AP_TERM_TAC THEN + ASM_ARITH_TAC; + + REWRITE_TAC[LENGTH_APPEND] THEN + REWRITE_TAC[LENGTH_SUB_LIST] THEN + REWRITE_TAC[LENGTH_OF_INT128_TO_BYTES] THEN + CONV_TAC NUM_REDUCE_CONV THEN + IMP_REWRITE_TAC[ARITH_RULE `i < 16 ==> MIN i 16 = i`] THEN + SUBGOAL_THEN `LENGTH (ct:byte list) - (curr_len + 16) = val (tail_len:int64)` SUBST1_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC ] THEN + REWRITE_TAC[ARITH_RULE `!x. MIN x x = x`] THEN + ASM_ARITH_TAC; + + REWRITE_TAC[LENGTH_APPEND] THEN + REWRITE_TAC[LENGTH_SUB_LIST] THEN + REWRITE_TAC[LENGTH_OF_INT128_TO_BYTES] THEN + CONV_TAC NUM_REDUCE_CONV THEN + IMP_REWRITE_TAC[ARITH_RULE `i < 16 ==> MIN (i + 1) 16 = i + 1`] THEN + SUBGOAL_THEN `LENGTH (ct:byte list) - (curr_len + 16) = val (tail_len:int64)` SUBST1_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC ] THEN + REWRITE_TAC[ARITH_RULE `!x. MIN x x = x`] THEN + ASM_ARITH_TAC + ] ; ALL_TAC + ] THEN + + REWRITE_TAC[cipher_stealing_inv] THEN + IMP_REWRITE_TAC[INT128_TO_BYTES_OF_BYTES_TO_INT128] THEN + CONJ_TAC THENL [ + REWRITE_TAC[EL_APPEND] THEN + SUBGOAL_THEN `LENGTH (SUB_LIST (0x0,i) (int128_to_bytes PP)) = i` SUBST1_TAC THENL + [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN + ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `LENGTH (SUB_LIST (i,val (tail_len:int64) - i) + (SUB_LIST (curr_len + 0x10,val tail_len) (ct:byte list))) + = val tail_len - i` SUBST1_TAC THENL + [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN + ASM_ARITH_TAC; ALL_TAC] THEN + SIMP_TAC[ARITH_RULE `~(i < i)`; SUB_REFL] THEN + SUBGOAL_THEN `0 < val (tail_len:int64) - i` ASSUME_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[] THEN + MP_TAC (ISPECL [`curr_len + 0x10:num`; `i:num`; `ct:byte list`; + `val (tail_len:int64) - i:num`; `val (tail_len:int64)`] SUB_LIST_MIN_GENERAL) THEN + REWRITE_TAC[ARITH_RULE `!a. MIN a a = a`; GSYM ADD_ASSOC] THEN + DISCH_THEN (fun th -> (REWRITE_TAC [th])) THEN + REWRITE_TAC[WORD_ZX_TRIVIAL; EL] THEN + MATCH_MP_TAC HD_SUB_LIST_CONS_GENERAL THEN + ASM_ARITH_TAC; ALL_TAC] THEN + REWRITE_TAC[LENGTH_APPEND] THEN + REWRITE_TAC[LENGTH_SUB_LIST] THEN + REWRITE_TAC[LENGTH_OF_INT128_TO_BYTES] THEN + CONV_TAC NUM_REDUCE_CONV THEN + ASM_ARITH_TAC +);; + +let CIPHER_STEALING_INV_SELECT = prove( + `!(i:num) (curr_len:num) (tail_len:int64) (PP:int128) (ct:byte list). + i < val tail_len ==> val tail_len < 16 ==> + curr_len + 16 + (val tail_len) = LENGTH ct ==> + EL i (int128_to_bytes (cipher_stealing_inv (i + 1) curr_len (val tail_len) PP ct)) = + EL i (int128_to_bytes PP)`, + REPEAT STRIP_TAC THEN + REWRITE_TAC[cipher_stealing_inv] THEN + IMP_REWRITE_TAC[INT128_TO_BYTES_OF_BYTES_TO_INT128] THEN + CONJ_TAC THENL [ + SUBGOAL_THEN `LENGTH (SUB_LIST (0x0,i + 1) (int128_to_bytes PP)) <= i + 1` ASSUME_TAC THENL + [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN + ARITH_TAC; ALL_TAC] THEN + REWRITE_TAC[EL_APPEND] THEN + SUBGOAL_THEN `i < LENGTH (SUB_LIST (0x0,i + 0x1) (int128_to_bytes PP))` ASSUME_TAC THENL + [ REWRITE_TAC[LENGTH_SUB_LIST; LENGTH_OF_INT128_TO_BYTES] THEN + ASM_ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[] THEN + MATCH_MP_TAC EL_SUB_LIST THEN + REWRITE_TAC[LENGTH_OF_INT128_TO_BYTES] THEN + ASM_ARITH_TAC; ALL_TAC + ] THEN + + REWRITE_TAC[LENGTH_APPEND] THEN + REWRITE_TAC[LENGTH_SUB_LIST] THEN + REWRITE_TAC[LENGTH_OF_INT128_TO_BYTES] THEN + CONV_TAC NUM_REDUCE_CONV THEN + IMP_REWRITE_TAC[ARITH_RULE `i < 16 ==> MIN (i + 1) 16 = i + 1`] THEN + SUBGOAL_THEN `LENGTH (ct:byte list) - (curr_len + 16) = val (tail_len:int64)` SUBST1_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC ] THEN + REWRITE_TAC[ARITH_RULE `!x. MIN x x = x`] THEN + ASM_ARITH_TAC +);; + +let CIPHER_STEALING_INV_SIMP_TAC i = + ( FIRST_ASSUM (fun th -> MATCH_MP_TAC(SPEC i th)) THEN CONV_TAC NUM_REDUCE_CONV) ORELSE + ( ASM_REWRITE_TAC[] THEN + REWRITE_TAC[WORD_RULE `!a b. word_add ((word a):int64) (word b) = word (a + b)`] THEN + REWRITE_TAC[GSYM ADD_ASSOC] THEN + CONV_TAC NUM_REDUCE_CONV THEN + IMP_REWRITE_TAC[WORD_ZX_ZX; WORD_ZX_TRIVIAL] THEN + REWRITE_TAC[DIMINDEX_8; DIMINDEX_32; DIMINDEX_64] THEN + IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN + ASM_ARITH_TAC);; + +let BREAK_DATA_INTO_PARTS_ENCRYPT = prove( + `!curr_len (tail_len:int64) (pt_ptr:int64) (s:armstate). + ((curr_len + 0x10 + val tail_len <= LENGTH bl) /\ + (forall i. i < curr_len + ==> read (memory :> bytes8 (word_add pt_ptr (word i))) s = EL i bl) /\ + (forall i. i < 16 + ==> read (memory :> bytes8 (word_add (word_add pt_ptr (word curr_len)) (word i))) s = + EL i (SUB_LIST (curr_len, 16) bl)) /\ + (forall i. i < val tail_len + ==> read (memory :> bytes8 + (word_add (word_add pt_ptr (word (curr_len + 0x10))) (word i))) s = + EL i (SUB_LIST (curr_len + 16, val tail_len) bl))) ==> + forall i. + i < curr_len + 0x10 + val tail_len + ==> read (memory :> bytes8 (word_add pt_ptr (word i))) s = EL i bl`, + REPEAT GEN_TAC THEN + DISCH_THEN (CONJUNCTS_THEN2 (LABEL_TAC "H") + (CONJUNCTS_THEN2 (LABEL_TAC "H1") + (CONJUNCTS_THEN2 (LABEL_TAC "H2") (LABEL_TAC "H3")))) THEN + REPEAT STRIP_TAC THEN + + ASM_CASES_TAC `i < curr_len` THENL + [ + FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[]; + ALL_TAC + ] THEN + + ASM_CASES_TAC `i < curr_len + 16` THENL + [ + USE_THEN "H2" (fun th -> MP_TAC (SPEC `i - curr_len` th)) THEN + REMOVE_THEN "H2" (K ALL_TAC) THEN + SUBGOAL_THEN `(word_add (word_add (pt_ptr:int64) (word curr_len)) (word (i - curr_len))) + = (word_add pt_ptr (word i))` ASSUME_TAC THENL + [ REWRITE_TAC[WORD_RULE `word_add (word_add a (word b)) (word c) = word_add a (word (b + c))`] THEN + AP_TERM_TAC THEN AP_TERM_TAC THEN + ASM_ARITH_TAC; ALL_TAC] THEN + ASM_REWRITE_TAC[] THEN + ANTS_TAC THENL[ASM_ARITH_TAC; ALL_TAC] THEN + SIMP_TAC[] THEN DISCH_TAC THEN + IMP_REWRITE_TAC[EL_SUB_LIST_GENERAL] THEN + ASM_ARITH_TAC; + ALL_TAC + ] THEN + + ASM_CASES_TAC `i < curr_len + 16 + val (tail_len:int64)` THENL + [ + USE_THEN "H3" (fun th -> MP_TAC (SPEC `i - curr_len - 16` th)) THEN + REMOVE_THEN "H3" (K ALL_TAC) THEN + SUBGOAL_THEN `(word_add (word_add (pt_ptr:int64) (word (curr_len + 0x10))) + (word (i - curr_len - 0x10))) = (word_add pt_ptr (word i))` ASSUME_TAC THENL + [ REWRITE_TAC[WORD_RULE `word_add (word_add a (word b)) (word c) = word_add a (word (b + c))`] THEN + AP_TERM_TAC THEN AP_TERM_TAC THEN + ASM_ARITH_TAC; ALL_TAC] THEN + ASM_REWRITE_TAC[] THEN + ANTS_TAC THENL[ASM_ARITH_TAC; ALL_TAC] THEN + SIMP_TAC[] THEN DISCH_TAC THEN + REWRITE_TAC[ARITH_RULE `i - curr_len - 16 = i - (curr_len + 16)`] THEN + IMP_REWRITE_TAC[EL_SUB_LIST_GENERAL] THEN + ASM_ARITH_TAC; + ALL_TAC + ] THEN + + ASM_ARITH_TAC +);; + +let BREAK_DATA_INTO_PARTS_DECRYPT = prove( + `!curr_len (tail_len:int64) (pt_ptr:int64) (s:armstate). + ((curr_len + 0x10 + val tail_len <= LENGTH bl) /\ + (forall i. i < curr_len + ==> read (memory :> bytes8 (word_add pt_ptr (word i))) s = EL i bl) /\ + (forall i. i < 16 + ==> read (memory :> bytes8 (word_add (word_add pt_ptr (word curr_len)) (word i))) s = + EL i (SUB_LIST (curr_len, 16 + val tail_len) bl)) /\ + (forall i. i < val tail_len + ==> read (memory :> bytes8 + (word_add (word_add pt_ptr (word (curr_len + 0x10))) (word i))) s = + EL i (SUB_LIST (curr_len + 16, val tail_len) bl))) ==> + forall i. + i < curr_len + 0x10 + val tail_len + ==> read (memory :> bytes8 (word_add pt_ptr (word i))) s = EL i bl`, + REPEAT GEN_TAC THEN + DISCH_THEN (CONJUNCTS_THEN2 (LABEL_TAC "H") + (CONJUNCTS_THEN2 (LABEL_TAC "H1") + (CONJUNCTS_THEN2 (LABEL_TAC "H2") (LABEL_TAC "H3")))) THEN + REPEAT STRIP_TAC THEN + + ASM_CASES_TAC `i < curr_len` THENL + [ + FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[]; + ALL_TAC + ] THEN + + ASM_CASES_TAC `i < curr_len + 16` THENL + [ + USE_THEN "H2" (fun th -> MP_TAC (SPEC `i - curr_len` th)) THEN + REMOVE_THEN "H2" (K ALL_TAC) THEN + SUBGOAL_THEN `(word_add (word_add (pt_ptr:int64) (word curr_len)) (word (i - curr_len))) + = (word_add pt_ptr (word i))` ASSUME_TAC THENL + [ REWRITE_TAC[WORD_RULE `word_add (word_add a (word b)) (word c) = word_add a (word (b + c))`] THEN + AP_TERM_TAC THEN AP_TERM_TAC THEN + ASM_ARITH_TAC; ALL_TAC] THEN + ASM_REWRITE_TAC[] THEN + ANTS_TAC THENL[ASM_ARITH_TAC; ALL_TAC] THEN + SIMP_TAC[] THEN DISCH_TAC THEN + IMP_REWRITE_TAC[EL_SUB_LIST_GENERAL] THEN + ASM_ARITH_TAC; + ALL_TAC + ] THEN + + ASM_CASES_TAC `i < curr_len + 16 + val (tail_len:int64)` THENL + [ + USE_THEN "H3" (fun th -> MP_TAC (SPEC `i - curr_len - 16` th)) THEN + REMOVE_THEN "H3" (K ALL_TAC) THEN + SUBGOAL_THEN `(word_add (word_add (pt_ptr:int64) (word (curr_len + 0x10))) + (word (i - curr_len - 0x10))) = (word_add pt_ptr (word i))` ASSUME_TAC THENL + [ REWRITE_TAC[WORD_RULE `word_add (word_add a (word b)) (word c) = word_add a (word (b + c))`] THEN + AP_TERM_TAC THEN AP_TERM_TAC THEN + ASM_ARITH_TAC; ALL_TAC] THEN + ASM_REWRITE_TAC[] THEN + ANTS_TAC THENL[ASM_ARITH_TAC; ALL_TAC] THEN + SIMP_TAC[] THEN DISCH_TAC THEN + REWRITE_TAC[ARITH_RULE `i - curr_len - 16 = i - (curr_len + 16)`] THEN + IMP_REWRITE_TAC[EL_SUB_LIST_GENERAL] THEN + ASM_ARITH_TAC; + ALL_TAC + ] THEN + + ASM_ARITH_TAC +);; diff --git a/arm/proofs/aes_xts_decrypt_spec.ml b/arm/proofs/utils/aes_xts_decrypt_spec.ml similarity index 98% rename from arm/proofs/aes_xts_decrypt_spec.ml rename to arm/proofs/utils/aes_xts_decrypt_spec.ml index d37d5e170..20cc4bd5d 100644 --- a/arm/proofs/aes_xts_decrypt_spec.ml +++ b/arm/proofs/utils/aes_xts_decrypt_spec.ml @@ -1,12 +1,18 @@ -use_file_raise_failure := true;; +(* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT-0 + *) + needs "common/aes.ml";; -loadt "arm/proofs/aes_encrypt_spec.ml";; -loadt "arm/proofs/aes_decrypt_spec.ml";; +needs "arm/proofs/utils/aes_encrypt_spec.ml";; +needs "arm/proofs/utils/aes_decrypt_spec.ml";; +(* let pp_print_num fmt tm = let n = dest_numeral tm in pp_print_string fmt (string_of_num_hex n) in install_user_printer("pp_print_num",pp_print_num);; +*) (*******************************************) (* Specification *) diff --git a/arm/proofs/aes_xts_encrypt_spec.ml b/arm/proofs/utils/aes_xts_encrypt_spec.ml similarity index 99% rename from arm/proofs/aes_xts_encrypt_spec.ml rename to arm/proofs/utils/aes_xts_encrypt_spec.ml index a592e835f..c092774d6 100644 --- a/arm/proofs/aes_xts_encrypt_spec.ml +++ b/arm/proofs/utils/aes_xts_encrypt_spec.ml @@ -1,5 +1,10 @@ -needs "arm/proofs/base.ml";; -needs "arm/proofs/aes_encrypt_spec.ml";; +(* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT-0 + *) + +needs "common/aes.ml";; +needs "arm/proofs/utils/aes_encrypt_spec.ml";; (* AES-256-XTS Encryption Algorithm for Any Input Length From 1efe5ed82dbdba2d1c494f5842ccf39a20aaf69e Mon Sep 17 00:00:00 2001 From: Yan Peng Date: Mon, 22 Dec 2025 23:25:51 -0800 Subject: [PATCH 113/132] Put AES encrypt and decrypt proofs in tutorial --- arm/Makefile | 5 +- arm/aes-xts/Makefile | 4 +- arm/proofs/aes_xts_decrypt.ml | 61 ------------ arm/proofs/aes_xts_encrypt.ml | 99 ------------------- arm/tutorial/README.md | 2 + .../aes_decrypt.S} | 0 arm/{proofs => tutorial}/aes_decrypt.ml | 4 + .../aes_encrypt.S} | 0 arm/{proofs => tutorial}/aes_encrypt.ml | 13 +-- 9 files changed, 13 insertions(+), 175 deletions(-) rename arm/{aes-xts/aes256_decrypt.S => tutorial/aes_decrypt.S} (100%) rename arm/{proofs => tutorial}/aes_decrypt.ml (95%) rename arm/{aes-xts/aes256_encrypt.S => tutorial/aes_encrypt.S} (100%) rename arm/{proofs => tutorial}/aes_encrypt.ml (92%) diff --git a/arm/Makefile b/arm/Makefile index 794bbe919..dbe0933ad 100644 --- a/arm/Makefile +++ b/arm/Makefile @@ -403,13 +403,10 @@ UNOPT_OBJ = p256/unopt/bignum_montmul_p256_base.o \ fastmul/unopt/bignum_mul_8_16_base.o \ fastmul/unopt/bignum_sqr_8_16_base.o -AES_XTS_OBJ = aes-xts/aes256_encrypt.o \ - aes-xts/aes256_decrypt.o \ - aes-xts/aes_xts_encrypt_armv8.o \ +AES_XTS_OBJ = aes-xts/aes_xts_encrypt_armv8.o \ aes-xts/aes_xts_decrypt_armv8.o OBJ = $(POINT_OBJ) $(BIGNUM_OBJ) $(AES_XTS_OBJ) -# OBJ = $(AES_XTS_OBJ) # Tutorial assembly files diff --git a/arm/aes-xts/Makefile b/arm/aes-xts/Makefile index 14d4f0b21..84bce8967 100644 --- a/arm/aes-xts/Makefile +++ b/arm/aes-xts/Makefile @@ -28,9 +28,7 @@ endif # List of object files -OBJ = aes256_encrypt.o \ - aes256_decrypt.o \ - aes_xts_encrypt_armv8.o \ +OBJ = aes_xts_encrypt_armv8.o \ aes_xts_decrypt_armv8.o %.o : %.S ; $(CC) -E -I../../include $< | $(GAS) -o $@ - diff --git a/arm/proofs/aes_xts_decrypt.ml b/arm/proofs/aes_xts_decrypt.ml index a091ea6a9..414278b53 100644 --- a/arm/proofs/aes_xts_decrypt.ml +++ b/arm/proofs/aes_xts_decrypt.ml @@ -747,67 +747,6 @@ let aes_xts_decrypt_mc = define_assert_from_elf "aes_xts_decrypt_mc" "arm/aes-xt let AES_XTS_DECRYPT_EXEC = ARM_MK_EXEC_RULE aes_xts_decrypt_mc;; -(** Proof **) -(* -let AES_XTS_DECRYPT_1BLOCK_CORRECT = prove( - `!ct_ptr pt_ptr key0_ptr key1_ptr iv_ptr ib iv - (k00:int128) k01 k02 k03 k04 k05 k06 k07 k08 k09 k0a k0b k0c k0d k0e - k10 k11 k12 k13 k14 k15 k16 k17 k18 k19 k1a k1b k1c k1d k1e - pc. - nonoverlapping (word pc, LENGTH aes_xts_decrypt_mc) (pt_ptr, 16) - ==> ensures arm - (\s. aligned_bytes_loaded s (word pc) aes_xts_decrypt_mc /\ - read PC s = word (pc + 0x1c) /\ - C_ARGUMENTS [ct_ptr; pt_ptr; word 16; key0_ptr; key1_ptr; iv_ptr] s /\ - read(memory :> bytes128 ct_ptr) s = ib /\ - read(memory :> bytes128 iv_ptr) s = iv /\ - set_key_schedule s key0_ptr k00 k01 k02 k03 k04 k05 k06 k07 k08 k09 k0a k0b k0c k0d k0e /\ - set_key_schedule s key1_ptr k10 k11 k12 k13 k14 k15 k16 k17 k18 k19 k1a k1b k1c k1d k1e) - (\s. read PC s = word (pc + 0xa10) /\ - read(memory :> bytes128 pt_ptr) s = - aes256_xts_decrypt_1block ib iv - [k00; k01; k02; k03; k04; k05; k06; k07; k08; k09; k0a; k0b; k0c; k0d; k0e] - [k10; k11; k12; k13; k14; k15; k16; k17; k18; k19; k1a; k1b; k1c; k1d; k1e] - ) - (MAYCHANGE [PC] ,, MAYCHANGE [events] ,, - MAYCHANGE [X21;X2;X6;X4;X9;X10;X19;X22;X11;X7;X0;X1;X8] ,, - MAYCHANGE [Q6;Q1;Q0;Q8;Q16;Q17;Q12;Q13;Q14;Q15;Q4;Q5;Q18;Q19;Q20;Q21;Q22;Q23;Q7;Q29;Q24] ,, - MAYCHANGE SOME_FLAGS,, MAYCHANGE [memory :> bytes128 pt_ptr]) - `, - REWRITE_TAC [(REWRITE_CONV [aes_xts_decrypt_mc] THENC LENGTH_CONV) `LENGTH aes_xts_decrypt_mc`] THEN - REWRITE_TAC[set_key_schedule; C_ARGUMENTS; SOME_FLAGS; NONOVERLAPPING_CLAUSES] THEN - REPEAT STRIP_TAC THEN - - (* Start symbolic simulation*) - ENSURES_INIT_TAC "s0" THEN - (* Simulate until the first tweak and verify the first tweak equiv the spec *) - ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (1--69) THEN - FIRST_X_ASSUM(MP_TAC o SPEC - `(aes256_encrypt iv [k10; k11; k12; k13; k14; k15; k16; k17; k18; k19; k1a; k1b; k1c; k1d; k1e]):int128` - o MATCH_MP (MESON[] `read Q6 s = a ==> !a'. a = a' ==> read Q6 s = a'`)) THEN - ANTS_TAC THENL [ASM_REWRITE_TAC[] THEN AESENC_TAC; DISCH_TAC] THEN - - (* Simulating until finish decrypting one block *) - ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (70--126) THEN - FIRST_X_ASSUM(MP_TAC o - SPEC `(aes256_xts_decrypt_1block ib iv - [k00; k01; k02; k03; k04; k05; k06; k07; k08; k09; k0a; k0b; k0c; k0d; k0e] - [k10; k11; k12; k13; k14; k15; k16; k17; k18; k19; k1a; k1b; k1c; k1d; k1e]):int128` - o MATCH_MP (MESON[] `read Q0 s = a ==> !a'. a = a' ==> read Q0 s = a'`)) THEN - ANTS_TAC THENL [ - REWRITE_TAC [aes256_xts_decrypt_1block] THEN - REWRITE_TAC [xts_init_tweak] THEN - CONV_TAC(TOP_DEPTH_CONV let_CONV) THEN - REWRITE_TAC [aes256_xts_decrypt_round] THEN - CONV_TAC(TOP_DEPTH_CONV let_CONV) THEN - AESDEC_TAC; DISCH_TAC] THEN - - (* Simulate to the end *) - ARM_ACCSTEPS_TAC AES_XTS_DECRYPT_EXEC [] (127--137) THEN - ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC [] -);; -*) - (**********************************************************************) (** Decrypt-specific lemmas **) diff --git a/arm/proofs/aes_xts_encrypt.ml b/arm/proofs/aes_xts_encrypt.ml index e2fa2c27c..348f187d0 100644 --- a/arm/proofs/aes_xts_encrypt.ml +++ b/arm/proofs/aes_xts_encrypt.ml @@ -720,105 +720,6 @@ let aes256_xts_encrypt_mc = define_assert_from_elf "aes256_xts_encrypt_mc" "arm/ let AES256_XTS_ENCRYPT_EXEC = ARM_MK_EXEC_RULE aes256_xts_encrypt_mc;; -(* -(* -void aes_hw_xts_encrypt(const uint8_t *in, uint8_t *out, size_t length, - const AES_KEY *key1, const AES_KEY *key2, - const uint8_t iv[16]) -*) -(* for stack pointer alignment and nonoverlapping examples, I looked at shigoel's sha512_block_data_order_hw.ml - and bignum_invsqrt_p25519_alt.ml *) -let AES256_ENCRYPT_ONE_BLOCK_CORRECT = prove( - `! ptxt_p ctxt_p key1_p key2_p iv_p - pt_in iv - (k1_0:int128) k1_1 k1_2 k1_3 k1_4 k1_5 k1_6 k1_7 k1_8 k1_9 k1_10 k1_11 k1_12 k1_13 k1_14 - k2_0 k2_1 k2_2 k2_3 k2_4 k2_5 k2_6 k2_7 k2_8 k2_9 k2_10 k2_11 k2_12 k2_13 k2_14 - pc stackpointer. - aligned 16 stackpointer /\ - PAIRWISE nonoverlapping - [(stackpointer, 6*16); - (word pc, LENGTH aes256_xts_encrypt_mc); - (ctxt_p, 16); - (key1_p, 244); - (key2_p, 244)] - ==> ensures arm - // precondition - (\s. aligned_bytes_loaded s (word pc) aes256_xts_encrypt_mc /\ - read PC s = word (pc + 28) /\ - read SP s = stackpointer /\ - C_ARGUMENTS [ptxt_p; ctxt_p; word 16; key1_p; key2_p; iv_p] s /\ - read(memory :> bytes128 ptxt_p) s = pt_in /\ - read(memory :> bytes128 iv_p) s = iv /\ - set_key_schedule s key1_p k1_0 k1_1 k1_2 k1_3 k1_4 k1_5 k1_6 k1_7 k1_8 k1_9 k1_10 k1_11 k1_12 k1_13 k1_14 /\ - set_key_schedule s key2_p k2_0 k2_1 k2_2 k2_3 k2_4 k2_5 k2_6 k2_7 k2_8 k2_9 k2_10 k2_11 k2_12 k2_13 k2_14 - ) - // postcondition - (\s. read PC s = word (pc + LENGTH aes256_xts_encrypt_mc - 8*4) /\ - read(memory :> bytes128 ctxt_p) s = - aes256_xts_encrypt_1block pt_in iv - [k1_0; k1_1; k1_2; k1_3; k1_4; k1_5; k1_6; k1_7; k1_8; k1_9; k1_10; k1_11; k1_12; k1_13; k1_14] - [k2_0; k2_1; k2_2; k2_3; k2_4; k2_5; k2_6; k2_7; k2_8; k2_9; k2_10; k2_11; k2_12; k2_13; k2_14] - ) - (MAYCHANGE [PC;X0;X1;X2;X4;X6;X7;X8;X9;X10;X11;X19;X20;X21;X22],, - MAYCHANGE [Q0;Q1;Q4;Q5;Q6;Q7;Q8;Q9;Q10;Q11;Q12;Q13;Q14;Q15;Q16;Q17;Q18;Q19;Q20;Q21;Q22;Q23;Q24;Q25;Q26],, - MAYCHANGE SOME_FLAGS,, MAYCHANGE [memory :> bytes128 ctxt_p],, - MAYCHANGE [events])`, - REWRITE_TAC [(REWRITE_CONV [aes256_xts_encrypt_mc] THENC LENGTH_CONV) `LENGTH aes256_xts_encrypt_mc`] THEN - REWRITE_TAC[set_key_schedule; NONOVERLAPPING_CLAUSES; C_ARGUMENTS; SOME_FLAGS; PAIRWISE; ALL] THEN - REPEAT STRIP_TAC THEN - (* Start symbolic simulation *) - ENSURES_INIT_TAC "s0" THEN - - (* Simulate until the iv encryption and verify it against AES encryption spec *) - ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (1--65) THEN - -(* FIRST_X_ASSUM(MP_TAC o MATCH_MP (MESON[] `read Q6 s = a ==> !a'. a = a' ==> read Q6 s = a'`)) THEN *) - FIRST_X_ASSUM(MP_TAC o SPEC - `(aes256_encrypt (iv:int128) [k2_0:int128; k2_1; k2_2; k2_3; k2_4; k2_5; k2_6; k2_7; k2_8; k2_9; k2_10; k2_11; k2_12; k2_13; k2_14]):int128` - o MATCH_MP (MESON[] `read Q6 s = a ==> !a'. a = a' ==> read Q6 s = a'`)) THEN - ANTS_TAC THENL [ASM_REWRITE_TAC[] THEN AESENC_TAC; DISCH_TAC] THEN - - (* Simulate until the one-block input encryption until before XORing the iv with the output. *) - ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (66--107) THEN - -(* FIRST_X_ASSUM(MP_TAC o MATCH_MP (MESON[] `read Q0 s = a ==> !a'. a = a' ==> read Q0 s = a'`)) THEN *) - FIRST_X_ASSUM(MP_TAC o SPEC - `(aes256_encrypt - (word_xor - (aes256_encrypt - iv - [k2_0; k2_1; k2_2; k2_3; k2_4; k2_5; k2_6; k2_7; k2_8; - k2_9; k2_10; k2_11; k2_12; k2_13; k2_14]) - pt_in:int128) - [k1_0:int128; k1_1; k1_2; k1_3; k1_4; k1_5; k1_6; k1_7; k1_8; k1_9; k1_10; k1_11; k1_12; k1_13; k1_14]):int128` - o MATCH_MP (MESON[] `read Q0 s = a ==> !a'. a = a' ==> read Q0 s = a'`)) THEN - ANTS_TAC THENL [ASM_REWRITE_TAC[] THEN AESENC_TAC; DISCH_TAC] THEN - - (* XOR the tweak with the output in Q0 *) - ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (108--108) THEN - - (* Write it to the ciphertext output *) - ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (109--109) THEN - FIRST_X_ASSUM(MP_TAC o SPEC - `(aes256_xts_encrypt_1block - (pt_in:int128) - (iv:int128) - [k1_0:int128; k1_1; k1_2; k1_3; k1_4; k1_5; k1_6; k1_7; k1_8; k1_9; k1_10; - k1_11; k1_12; k1_13; k1_14] - [k2_0:int128; k2_1; k2_2; k2_3; k2_4; k2_5; k2_6; k2_7; k2_8; k2_9; k2_10; - k2_11; k2_12; k2_13; k2_14]):int128` - o MATCH_MP (MESON[] `read (memory :> bytes128 ctxt_p) s = a ==> !a'. a = a' - ==> read (memory :> bytes128 ctxt_p) s = a'`)) THEN - ANTS_TAC THENL [ASM_REWRITE_TAC[] THEN AESXTS_ENC_ONE_BLOCK_TAC; DISCH_TAC] THEN - - ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (110--120) THEN - - ENSURES_FINAL_STATE_TAC THEN - ASM_REWRITE_TAC[] THEN - ARITH_TAC -);; -*) - (**********************************************************************) (** Encrypt-specific lemmas **) diff --git a/arm/tutorial/README.md b/arm/tutorial/README.md index 23697bc3b..3d6a66882 100644 --- a/arm/tutorial/README.md +++ b/arm/tutorial/README.md @@ -13,6 +13,8 @@ To verify programs in x86, see `x86/tutorial`. 5. `loop.ml`: Verifying a program that has a simple loop. 6. `bignum.ml`: Writing a specification of a program dealing with big numbers & proving it. 7. `rodata.ml`: Reading data from the read-only section. +8. `aes_encrypt.ml`: Verifying a simple AES encryption program. +9. `aes_decrypt.ml`: Verifying a simple AES decryption program. ### Relational reasoning diff --git a/arm/aes-xts/aes256_decrypt.S b/arm/tutorial/aes_decrypt.S similarity index 100% rename from arm/aes-xts/aes256_decrypt.S rename to arm/tutorial/aes_decrypt.S diff --git a/arm/proofs/aes_decrypt.ml b/arm/tutorial/aes_decrypt.ml similarity index 95% rename from arm/proofs/aes_decrypt.ml rename to arm/tutorial/aes_decrypt.ml index 213e306d7..6df367921 100644 --- a/arm/proofs/aes_decrypt.ml +++ b/arm/tutorial/aes_decrypt.ml @@ -3,6 +3,10 @@ * SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT-0 *) + (****************************************************************************** + An example AES decryption proof. +******************************************************************************) + needs "arm/proofs/base.ml";; needs "arm/proofs/utils/aes_decrypt_spec.ml";; diff --git a/arm/aes-xts/aes256_encrypt.S b/arm/tutorial/aes_encrypt.S similarity index 100% rename from arm/aes-xts/aes256_encrypt.S rename to arm/tutorial/aes_encrypt.S diff --git a/arm/proofs/aes_encrypt.ml b/arm/tutorial/aes_encrypt.ml similarity index 92% rename from arm/proofs/aes_encrypt.ml rename to arm/tutorial/aes_encrypt.ml index 0daaf069f..717680f7f 100644 --- a/arm/proofs/aes_encrypt.ml +++ b/arm/tutorial/aes_encrypt.ml @@ -3,6 +3,10 @@ * SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT-0 *) +(****************************************************************************** + An example AES encryption proof. +******************************************************************************) + needs "arm/proofs/base.ml";; needs "arm/proofs/utils/aes_encrypt_spec.ml";; @@ -70,14 +74,7 @@ let AES256_ENCRYPT_CORRECT = prove( REWRITE_TAC [(REWRITE_CONV [aes256_encrypt_mc] THENC LENGTH_CONV) `LENGTH aes256_encrypt_mc`] THEN REPEAT STRIP_TAC THEN ENSURES_INIT_TAC "s0" THEN - ARM_STEPS_TAC AES256_ENCRYPT_EXEC (1--5) THEN - (* 1 loop iteration is 8 steps *) - ARM_STEPS_TAC AES256_ENCRYPT_EXEC (6--13) THEN - (* 5 more iterations = 8*5 = 40 steps *) - ARM_STEPS_TAC AES256_ENCRYPT_EXEC (14--53) THEN - (* 6 final steps *) - ARM_STEPS_TAC AES256_ENCRYPT_EXEC (54--58) THEN - ARM_STEPS_TAC AES256_ENCRYPT_EXEC (59--59) THEN + ARM_STEPS_TAC AES256_ENCRYPT_EXEC (1--59) THEN ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN REWRITE_TAC [aes256_encrypt] THEN From 3d02501a78dd726ff41e02279b15c321f31e9172 Mon Sep 17 00:00:00 2001 From: Yan Peng Date: Tue, 23 Dec 2025 00:05:03 -0800 Subject: [PATCH 114/132] Integrate assembly --- arm/Makefile | 5 +- arm/aes-xts/Makefile | 5 +- ...s_decrypt_armv8.S => aes_hw_xts_decrypt.S} | 17 +- ...s_encrypt_armv8.S => aes_hw_xts_encrypt.S} | 11 + arm/proofs/specifications.txt | 2 + arm/tutorial/aes_decrypt.ml | 2 +- arm/tutorial/aes_encrypt.ml | 2 +- include/s2n-bignum.h | 16 + tests/arch.h | 42 ++ tests/known_value_tests_xts_decrypt.h | 362 ++++++++++++++++++ tests/known_value_tests_xts_encrypt.h | 362 ++++++++++++++++++ tests/test.c | 99 ++++- tools/collect-signatures.py | 2 + 13 files changed, 908 insertions(+), 19 deletions(-) rename arm/aes-xts/{aes_xts_decrypt_armv8.S => aes_hw_xts_decrypt.S} (97%) rename arm/aes-xts/{aes_xts_encrypt_armv8.S => aes_hw_xts_encrypt.S} (96%) create mode 100644 tests/known_value_tests_xts_decrypt.h create mode 100644 tests/known_value_tests_xts_encrypt.h diff --git a/arm/Makefile b/arm/Makefile index dbe0933ad..ddd29a1df 100644 --- a/arm/Makefile +++ b/arm/Makefile @@ -403,8 +403,9 @@ UNOPT_OBJ = p256/unopt/bignum_montmul_p256_base.o \ fastmul/unopt/bignum_mul_8_16_base.o \ fastmul/unopt/bignum_sqr_8_16_base.o -AES_XTS_OBJ = aes-xts/aes_xts_encrypt_armv8.o \ - aes-xts/aes_xts_decrypt_armv8.o +AES_XTS_OBJ = aes-xts/aes_hw_xts_decrypt.o \ + aes-xts/aes_hw_xts_encrypt.o + OBJ = $(POINT_OBJ) $(BIGNUM_OBJ) $(AES_XTS_OBJ) diff --git a/arm/aes-xts/Makefile b/arm/aes-xts/Makefile index 84bce8967..65ed9d9a1 100644 --- a/arm/aes-xts/Makefile +++ b/arm/aes-xts/Makefile @@ -28,8 +28,9 @@ endif # List of object files -OBJ = aes_xts_encrypt_armv8.o \ - aes_xts_decrypt_armv8.o +OBJ = aes_hw_xts_decrypt.o \ + aes_hw_xts_encrypt.o + %.o : %.S ; $(CC) -E -I../../include $< | $(GAS) -o $@ - diff --git a/arm/aes-xts/aes_xts_decrypt_armv8.S b/arm/aes-xts/aes_hw_xts_decrypt.S similarity index 97% rename from arm/aes-xts/aes_xts_decrypt_armv8.S rename to arm/aes-xts/aes_hw_xts_decrypt.S index 2889e65f5..2a8ef9d31 100644 --- a/arm/aes-xts/aes_xts_decrypt_armv8.S +++ b/arm/aes-xts/aes_hw_xts_decrypt.S @@ -1,17 +1,16 @@ -############################################################################# -# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. -# SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT-0 -# TODO: figure out copyright -############################################################################# +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT-0 // ---------------------------------------------------------------------------- // AES_XTS_DECRYPT (256-bit) +// Inputs *in, length, *key1, *key2, iv[16]; output *out // -// void aes_hw_xts_decrypt(const uint8_t *in, uint8_t *out, size_t length, -// const AES_KEY *key1, const AES_KEY *key2, -// const uint8_t iv[16]); +// extern void aes_hw_xts_decrypt(const uint8_t *in, uint8_t *out, +// size_t length, +// const AES_KEY *key1, const AES_KEY *key2, +// const uint8_t iv[16]); // -// Standard ARM ABI: X0 = in, X1 = out, X2 = length, X3 = key1, X4 = key2, X5 = iv, returns X1 +// Standard ARM ABI: X0 = in, X1 = out, X2 = length, X3 = key1, X4 = key2, X5 = iv // ---------------------------------------------------------------------------- #include "_internal_s2n_bignum.h" diff --git a/arm/aes-xts/aes_xts_encrypt_armv8.S b/arm/aes-xts/aes_hw_xts_encrypt.S similarity index 96% rename from arm/aes-xts/aes_xts_encrypt_armv8.S rename to arm/aes-xts/aes_hw_xts_encrypt.S index 9a87b2de3..d51b2206e 100644 --- a/arm/aes-xts/aes_xts_encrypt_armv8.S +++ b/arm/aes-xts/aes_hw_xts_encrypt.S @@ -1,6 +1,17 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT-0 +// ---------------------------------------------------------------------------- +// AES_XTS_ENCRYPT (256-bit) +// Inputs *in, length, *key1, *key2, iv[16]; output *out +// +// extern void aes_hw_xts_encrypt(const uint8_t *in, uint8_t *out, +// size_t length, +// const AES_KEY *key1, const AES_KEY *key2, +// const uint8_t iv[16]); +// +// Standard ARM ABI: X0 = in, X1 = out, X2 = length, X3 = key1, X4 = key2, X5 = iv +// ---------------------------------------------------------------------------- // Auto-added during import for AWS-LC symbol prefixing support #include "_internal_s2n_bignum.h" diff --git a/arm/proofs/specifications.txt b/arm/proofs/specifications.txt index e26e5f3a9..bc41113cb 100644 --- a/arm/proofs/specifications.txt +++ b/arm/proofs/specifications.txt @@ -1,3 +1,5 @@ +AES_XTS_DECRYPT_SUBROUTINE_CORRECT +AES_XTS_ENCRYPT_SUBROUTINE_CORRECT BIGNUM_ADD_P25519_SUBROUTINE_CORRECT BIGNUM_ADD_P256K1_SUBROUTINE_CORRECT BIGNUM_ADD_P256_SUBROUTINE_CORRECT diff --git a/arm/tutorial/aes_decrypt.ml b/arm/tutorial/aes_decrypt.ml index 6df367921..bfeea8aaf 100644 --- a/arm/tutorial/aes_decrypt.ml +++ b/arm/tutorial/aes_decrypt.ml @@ -11,7 +11,7 @@ needs "arm/proofs/base.ml";; needs "arm/proofs/utils/aes_decrypt_spec.ml";; (* print_literal_from_elf "arm/aes-xts/aes256_decrypt.o";; *) -let aes256_decrypt_mc = define_assert_from_elf "aes256_decrypt_mc" "arm/aes-xts/aes256_decrypt.o" +let aes256_decrypt_mc = define_assert_from_elf "aes256_decrypt_mc" "arm/tutorial/aes_decrypt.o" [ 0xb940f046; (* arm_LDR W6 X2 (Immediate_Offset (word 0xf0)) *) 0x4cdf7040; (* arm_LDR Q0 X2 (Postimmediate_Offset (word 0x10)) *) diff --git a/arm/tutorial/aes_encrypt.ml b/arm/tutorial/aes_encrypt.ml index 717680f7f..d4e00cfbe 100644 --- a/arm/tutorial/aes_encrypt.ml +++ b/arm/tutorial/aes_encrypt.ml @@ -11,7 +11,7 @@ needs "arm/proofs/base.ml";; needs "arm/proofs/utils/aes_encrypt_spec.ml";; (* print_literal_from_elf "arm/aes-xts/aes256_encrypt.o";; *) -let aes256_encrypt_mc = define_assert_from_elf "aes256_encrypt_mc" "arm/aes-xts/aes256_encrypt.o" +let aes256_encrypt_mc = define_assert_from_elf "aes256_encrypt_mc" "arm/tutorial/aes_encrypt.o" [ 0xb940f046; (* arm_LDR W6 X2 (Immediate_Offset (word 240)) *) 0x4cdf7040; (* arm_LDR Q0 X2 (Postimmediate_Offset (word 16)) *) diff --git a/include/s2n-bignum.h b/include/s2n-bignum.h index c30404d60..873ad8c71 100644 --- a/include/s2n-bignum.h +++ b/include/s2n-bignum.h @@ -30,6 +30,22 @@ #define S2N_BIGNUM_STATIC static #endif +struct aes_key_st { + uint64_t rd_key[30]; + int rounds; +}; +typedef struct aes_key_st AES_KEY; + +// AES_XTS_DECRYPT (256-bit) +// Inputs *in, length, *key1, *key2, iv[16]; output *out +extern void aes_hw_xts_decrypt(const uint8_t *in, uint8_t *out, size_t length, + const AES_KEY *key1, const AES_KEY *key2, const uint8_t iv[16]); + +// AES_XTS_ENCRYPT (256-bit) +// Inputs *in, length, *key1, *key2, iv[16]; output *out +extern void aes_hw_xts_encrypt(const uint8_t *in, uint8_t *out, size_t length, + const AES_KEY *key1, const AES_KEY *key2, const uint8_t iv[16]); + // Add, z := x + y // Inputs x[m], y[n]; outputs function return (carry-out) and z[p] extern uint64_t bignum_add (uint64_t p, uint64_t *z, uint64_t m, const uint64_t *x, uint64_t n, const uint64_t *y); diff --git a/tests/arch.h b/tests/arch.h index 18d772933..e97d13d70 100644 --- a/tests/arch.h +++ b/tests/arch.h @@ -27,6 +27,11 @@ int supports_arm_sha3(void) return 0; } +int supports_arm_aes(void) +{ // Not an ARM machine at all + return 0; +} + #else int supports_bmi2_and_adx(void) @@ -68,6 +73,43 @@ int supports_bmi2_and_adx(void) return 0; #endif } + +#endif + +#if __linux__ + #include + #include + int supports_arm_aes(void) + { + long hwcaps = getauxval(AT_HWCAP); + return (hwcaps & HWCAP_AES) != 0; + } + +#elif __FreeBSD__ || __OpenBSD__ + + #include + #include + int supports_arm_aes(void) + { + unsigned long hwcaps; + if (elf_aux_info(AT_HWCAP, &hwcaps, sizeof(hwcaps)) != 0) + { printf("Warning: Failed to read AT_HWCAP\n"); + return 0; + } + return (hwcaps & HWCAP_AES) != 0; + } + +#else + + int supports_arm_aes(void) + { + #if __ARM_FEATURE_AES + return 1; + #else + return 0; + #endif + } + #endif enum arch_name get_arch_name() diff --git a/tests/known_value_tests_xts_decrypt.h b/tests/known_value_tests_xts_decrypt.h new file mode 100644 index 000000000..ff16efa79 --- /dev/null +++ b/tests/known_value_tests_xts_decrypt.h @@ -0,0 +1,362 @@ +// key1 = fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0efeeedecebeae9e8e7e6e5e4e3e2e1e0 +// key2 = bfbebdbcbbbab9b8b7b6b5b4b3b2b1b0afaeadacabaaa9a8a7a6a5a4a3a2a1a0 +// iv = 9a785634120000000000000000000000 +// roundkey1 = +// 0xfcfdfeff 0xf8f9fafb 0xf4f5f6f7 0xf0f1f2f3 +// 0xecedeeef 0xe8e9eaeb 0xe4e5e6e7 0xe0e1e2e3 +// 0xed1c0666 0x15e5fc9d 0xe1100a6a 0x11e1f899 +// 0x6e15af01 0x86fc45ea 0x6219a30d 0x82f841ee +// 0xc50f47e7 0xd0eabb7a 0x31fab110 0x201b4989 +// 0xd9ba94a6 0x5f46d14c 0x3d5f7241 0xbfa733af +// 0xbc071b20 0x6ceda05a 0x5d17114a 0x7d0c58c3 +// 0x2644fe88 0x79022fc4 0x445d5d85 0xfbfa6e2a +// 0x590836b7 0x35e596ed 0x68f287a7 0x15fedf64 +// 0x7fff60cb 0x6fd4f0f 0x42a0128a 0xb95a7ca0 +// 0xb95e88b7 0x8cbb1e5a 0xe44999fd 0xf1b74699 +// 0xde563a25 0xd8ab752a 0x9a0b67a0 0x23511b00 +// 0xda785938 0x56c34762 0xb28ade9f 0x433d9806 +// 0xc4717c4a 0x1cda0960 0x86d16ec0 0xa58075c0 +// 0x607e94e5 0x36bdd387 0x84370d18 0xc70a951e +// roundkey2 = +// 0xbcbdbebf 0xb8b9babb 0xb4b5b6b7 0xb0b1b2b3 +// 0xacadaeaf 0xa8a9aaab 0xa4a5a6a7 0xa0a1a2a3 +// 0xb65d8c84 0xee4363f 0xba518088 0xae0323b +// 0xcb4c8d4d 0x63e527e6 0xc7408141 0x67e123e2 +// 0x2ed874a0 0x203c429f 0x9a6dc217 0x908df02c +// 0xab11013c 0xc8f426da 0xfb4a79b 0x68558479 +// 0x989d88fb 0xb8a1ca64 0x22cc0873 0xb241f85f +// 0x9c9240f3 0x54666629 0x5bd2c1b2 0x338745cb +// 0x875e9f9d 0x3fff55f9 0x1d335d8a 0xaf72a5d5 +// 0xe5d246f0 0xb1b420d9 0xea66e16b 0xd9e1a4a0 +// 0x676b67c4 0x5894323d 0x45a76fb7 0xead5ca62 +// 0x62d1325a 0xd3651283 0x3903f3e8 0xe0e25748 +// 0x358affbf 0x6d1ecd82 0x28b9a235 0xc26c6857 +// 0x47817701 0x94e46582 0xade7966a 0x4d05c122 +// 0xa6699487 0xcb775905 0xe3cefb30 0x21a29367 +key1->rd_key[0]=0x36bdd387607e94e5; key1->rd_key[1]=0xc70a951e84370d18; +key1->rd_key[2]=0x103340cce21b473d; key1->rd_key[3]=0x7ead95d6f74bf6b3; +key1->rd_key[4]=0x3d0757ddbebda060; key1->rd_key[5]=0x298c296cdf3241d5; +key1->rd_key[6]=0xf22807f1cdc91c8f; key1->rd_key[7]=0x89e66365e778b67f; +key1->rd_key[8]=0x83baf7bd2340b902; key1->rd_key[9]=0xf6be68b9e2351608; +key1->rd_key[10]=0x3fe11b7e185c513e; key1->rd_key[11]=0x6e9ed51a1550b18e; +key1->rd_key[12]=0xa0fa4ebf336ae76e; key1->rd_key[13]=0x148b7eb1618fe1b5; +key1->rd_key[14]=0x27bd4a40982968cd; key1->rd_key[15]=0x7bce64942ab1aaf0; +key1->rd_key[16]=0x9390a9d1d91a6526; key1->rd_key[17]=0x75049f04c175af0a; +key1->rd_key[18]=0xbf94228de7e3085d; key1->rd_key[19]=0x517fce640d0ce0b0; +key1->rd_key[20]=0x4a8accf7a81afe26; key1->rd_key[21]=0xb471300e52e506db; +key1->rd_key[22]=0x58772ad0be94ce31; key1->rd_key[23]=0x5c732ed4b298c23d; +key1->rd_key[24]=0xe29032d11463c620; key1->rd_key[25]=0xe69436d5186fca2c; +key1->rd_key[26]=0xe6e3e4e1e2e7e0e5; key1->rd_key[27]=0xeeebece9eaefe8ed; +key1->rd_key[28]=0xf8f9fafbfcfdfeff; key1->rd_key[29]=0xf0f1f2f3f4f5f6f7; + +key2->rd_key[0]=0xb8b9babbbcbdbebf; key2->rd_key[1]=0xb0b1b2b3b4b5b6b7; +key2->rd_key[2]=0xa8a9aaabacadaeaf; key2->rd_key[3]=0xa0a1a2a3a4a5a6a7; +key2->rd_key[4]=0x0ee4363fb65d8c84; key2->rd_key[5]=0x0ae0323bba518088; +key2->rd_key[6]=0x63e527e6cb4c8d4d; key2->rd_key[7]=0x67e123e2c7408141; +key2->rd_key[8]=0x203c429f2ed874a0; key2->rd_key[9]=0x908df02c9a6dc217; +key2->rd_key[10]=0xc8f426daab11013c; key2->rd_key[11]=0x685584790fb4a79b; +key2->rd_key[12]=0xb8a1ca64989d88fb; key2->rd_key[13]=0xb241f85f22cc0873; +key2->rd_key[14]=0x546666299c9240f3; key2->rd_key[15]=0x338745cb5bd2c1b2; +key2->rd_key[16]=0x3fff55f9875e9f9d; key2->rd_key[17]=0xaf72a5d51d335d8a; +key2->rd_key[18]=0xb1b420d9e5d246f0; key2->rd_key[19]=0xd9e1a4a0ea66e16b; +key2->rd_key[20]=0x5894323d676b67c4; key2->rd_key[21]=0xead5ca6245a76fb7; +key2->rd_key[22]=0xd365128362d1325a; key2->rd_key[23]=0xe0e257483903f3e8; +key2->rd_key[24]=0x6d1ecd82358affbf; key2->rd_key[25]=0xc26c685728b9a235; +key2->rd_key[26]=0x94e4658247817701; key2->rd_key[27]=0x4d05c122ade7966a; +key2->rd_key[28]=0xcb775905a6699487; key2->rd_key[29]=0x21a29367e3cefb30; + +key1->rounds=13; +key2->rounds=13; + +iv[0]=0x9a;iv[1]=0x78;iv[2]=0x56;iv[3]=0x34; +iv[4]=0x12;iv[5]=0x00;iv[6]=0x00;iv[7]=0x00; +iv[8]=0x00;iv[9]=0x00;iv[10]=0x00;iv[11]=0x00; +iv[12]=0x00;iv[13]=0x00;iv[14]=0x00;iv[15]=0x00; + +// 1block +len = 16; +ASSIGNHEX(res, "000102030405060708090a0b0c0d0e0f", len); +ASSIGNHEX(in, "c30ca8f2ed57307edc87e544867ac888", len); +ASSIGNZERO(out, len); +aes_hw_xts_decrypt(in,out,len,key1,key2,iv); +CHECKHEX(out,res,0,len); + +// 1block + 1byte = 17 bytes +len = 17; +ASSIGNHEX(res, "000102030405060708090a0b0c0d0e0f10", len); +ASSIGNHEX(in, "7f117752cc598a8b0d81d88af9f9bec8c3", len); +ASSIGNZERO(out, len); +aes_hw_xts_decrypt(in,out,len,key1,key2,iv); +CHECKHEX(out,res,0,len); + +// 1block + 6byte = 22 bytes +len = 22; +ASSIGNHEX(res, "000102030405060708090a0b0c0d0e0f101112131415", len); +ASSIGNHEX(in, "75e8188bcce59ada939f57de2cb9a489c30ca8f2ed57", len); +ASSIGNZERO(out, len); +aes_hw_xts_decrypt(in,out,len,key1,key2,iv); +CHECKHEX(out,res,0,len); + +// 1bock + 15bytes = 31 bytes +len = 31; +ASSIGNHEX(res, "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e", len); +ASSIGNHEX(in, "581ea1fee5516ad432ddebe75fd27c6fc30ca8f2ed57307edc87e544867ac8", len); +ASSIGNZERO(out, len); +aes_hw_xts_decrypt(in,out,len,key1,key2,iv); +CHECKHEX(out,res,0,len); + +// 3 blocks + 3 bytes +len = 51; +ASSIGNHEX(res, "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" + "202122232425262728292a2b2c2d2e2f303132", len); +ASSIGNHEX(in, "c30ca8f2ed57307edc87e544867ac888348c208928d7406269954551cb627b5b" + "bea47768aa25376e924cce6a102ca2e4e1c241", len); +ASSIGNZERO(out, len); +aes_hw_xts_decrypt(in,out,len,key1,key2,iv); +CHECKHEX(out,res,0,len); + +// 4 blocks +len = 64; +ASSIGNHEX(res, "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" + "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", len); +ASSIGNHEX(in, "c30ca8f2ed57307edc87e544867ac888348c208928d7406269954551cb627b5b" + "e1c241d0ff691de6b47ad81eac2b925b474e1fd14311edb95219ce64677f497b", len); +ASSIGNZERO(out, len); +aes_hw_xts_decrypt(in,out,len,key1,key2,iv); +CHECKHEX(out,res,0,len); + +// 4blocks + 10 bytes = 74 bytes +len = 74; +ASSIGNHEX(res, "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" + "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f" + "40414243444546474849", len); +ASSIGNHEX(in, "c30ca8f2ed57307edc87e544867ac888348c208928d7406269954551cb627b5b" + "e1c241d0ff691de6b47ad81eac2b925b0f451eb8847b98d48b1407f64a4f9ee3" + "474e1fd14311edb95219", len); +ASSIGNZERO(out, len); +aes_hw_xts_decrypt(in,out,len,key1,key2,iv); +CHECKHEX(out,res,0,len); + +// 5 blocks +len = 80; +ASSIGNHEX(res, "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" + "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f" + "404142434445464748494a4b4c4d4e4f", len); +ASSIGNHEX(in, "c30ca8f2ed57307edc87e544867ac888348c208928d7406269954551cb627b5b" + "e1c241d0ff691de6b47ad81eac2b925b474e1fd14311edb95219ce64677f497b" + "8917567652e9b4ef3838baf35e400fe1", len); +ASSIGNZERO(out, len); +aes_hw_xts_decrypt(in,out,len,key1,key2,iv); +CHECKHEX(out,res,0,len); + +// 5blocks + 7bytes = 87 bytes +len = 87; +ASSIGNHEX(res, "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" + "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f" + "404142434445464748494a4b4c4d4e4f50515253545556", len); +ASSIGNHEX(in, "c30ca8f2ed57307edc87e544867ac888348c208928d7406269954551cb627b5b" + "e1c241d0ff691de6b47ad81eac2b925b474e1fd14311edb95219ce64677f497b" + "a436b967e79bb8e8e4c29d1099fe1bbf8917567652e9b4", len); +ASSIGNZERO(out, len); +aes_hw_xts_decrypt(in,out,len,key1,key2,iv); +CHECKHEX(out,res,0,len); + +// 6 blocks +len = 96; +ASSIGNHEX(res, + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" + "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f" + "404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f", len); +ASSIGNHEX(in, + "c30ca8f2ed57307edc87e544867ac888348c208928d7406269954551cb627b5b" + "e1c241d0ff691de6b47ad81eac2b925b474e1fd14311edb95219ce64677f497b" + "8917567652e9b4ef3838baf35e400fe1ffe2f16cfa1900d7ae2b67f0e6f43b71", len); +ASSIGNZERO(out, len); +aes_hw_xts_decrypt(in,out,len,key1,key2,iv); +CHECKHEX(out,res,0,len); + +// 6blocks + 4bytes = 100 bytes +len = 100; +ASSIGNHEX(res, + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" + "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f" + "404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f" + "60616263", len); +ASSIGNHEX(in, + "c30ca8f2ed57307edc87e544867ac888348c208928d7406269954551cb627b5b" + "e1c241d0ff691de6b47ad81eac2b925b474e1fd14311edb95219ce64677f497b" + "8917567652e9b4ef3838baf35e400fe1aad32ff4d83b0af3f6a176025bd1321b" + "ffe2f16c", len); +ASSIGNZERO(out, len); +aes_hw_xts_decrypt(in,out,len,key1,key2,iv); +CHECKHEX(out,res,0,len); + +// 8 blocks +len = 128; +ASSIGNHEX(res, + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" + "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f" + "404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f" + "606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f", len); +ASSIGNHEX(in, + "c30ca8f2ed57307edc87e544867ac888348c208928d7406269954551cb627b5b" + "e1c241d0ff691de6b47ad81eac2b925b474e1fd14311edb95219ce64677f497b" + "8917567652e9b4ef3838baf35e400fe1ffe2f16cfa1900d7ae2b67f0e6f43b71" + "769d1b0e0c0b99ea11de58fcd3b72e1bce3d9a8750b87e945d77f4dc39d73b04", len); +ASSIGNZERO(out, len); +aes_hw_xts_decrypt(in,out,len,key1,key2,iv); +CHECKHEX(out,res,0,len); + +// 8blocks + 6 bytes = 134 bytes +len = 134; +ASSIGNHEX(res, + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" + "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f" + "404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f" + "606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f" + "808182838485", len); +ASSIGNHEX(in, + "c30ca8f2ed57307edc87e544867ac888348c208928d7406269954551cb627b5b" + "e1c241d0ff691de6b47ad81eac2b925b474e1fd14311edb95219ce64677f497b" + "8917567652e9b4ef3838baf35e400fe1ffe2f16cfa1900d7ae2b67f0e6f43b71" + "769d1b0e0c0b99ea11de58fcd3b72e1be0ad32884698e15420e52c96b698bba1" + "ce3d9a8750b8", len); +ASSIGNZERO(out, len); +aes_hw_xts_decrypt(in,out,len,key1,key2,iv); +CHECKHEX(out,res,0,len); + +// 9 blocks = 144 bytes +len = 144; +ASSIGNHEX(res, + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" + "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f" + "404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f" + "606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f" + "808182838485868788898a8b8c8d8e8f", len); +ASSIGNHEX(in, + "c30ca8f2ed57307edc87e544867ac888348c208928d7406269954551cb627b5b" + "e1c241d0ff691de6b47ad81eac2b925b474e1fd14311edb95219ce64677f497b" + "8917567652e9b4ef3838baf35e400fe1ffe2f16cfa1900d7ae2b67f0e6f43b71" + "769d1b0e0c0b99ea11de58fcd3b72e1bce3d9a8750b87e945d77f4dc39d73b04" + "e11b6adce343e1f38c6a879463c080d7", len); +ASSIGNZERO(out, len); +aes_hw_xts_decrypt(in,out,len,key1,key2,iv); +CHECKHEX(out,res,0,len); + +// 9blocks + 14bytes = 158bytes +len = 158; +ASSIGNHEX(res, + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" + "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f" + "404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f" + "606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f" + "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d", len); +ASSIGNHEX(in, + "c30ca8f2ed57307edc87e544867ac888348c208928d7406269954551cb627b5b" + "e1c241d0ff691de6b47ad81eac2b925b474e1fd14311edb95219ce64677f497b" + "8917567652e9b4ef3838baf35e400fe1ffe2f16cfa1900d7ae2b67f0e6f43b71" + "769d1b0e0c0b99ea11de58fcd3b72e1bce3d9a8750b87e945d77f4dc39d73b04" + "a5da920d96beb388ade417027054dbd0e11b6adce343e1f38c6a879463c0", len); +ASSIGNZERO(out, len); +aes_hw_xts_decrypt(in,out,len,key1,key2,iv); +CHECKHEX(out,res,0,len); + +// 10blocks = 160bytes +len = 160; +ASSIGNHEX(res, + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" + "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f" + "404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f" + "606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f" + "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f", len); +ASSIGNHEX(in, + "c30ca8f2ed57307edc87e544867ac888348c208928d7406269954551cb627b5b" + "e1c241d0ff691de6b47ad81eac2b925b474e1fd14311edb95219ce64677f497b" + "8917567652e9b4ef3838baf35e400fe1ffe2f16cfa1900d7ae2b67f0e6f43b71" + "769d1b0e0c0b99ea11de58fcd3b72e1bce3d9a8750b87e945d77f4dc39d73b04" + "e11b6adce343e1f38c6a879463c080d74a72a90b1e6fe46b7bc95a929f79947e", len); +ASSIGNZERO(out, len); +aes_hw_xts_decrypt(in,out,len,key1,key2,iv); +CHECKHEX(out,res,0,len); + +// 10blocks + 5bytes = 165bytes +len = 165; +ASSIGNHEX(res, + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" + "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f" + "404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f" + "606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f" + "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f" + "a0a1a2a3a4", len); +ASSIGNHEX(in, + "c30ca8f2ed57307edc87e544867ac888348c208928d7406269954551cb627b5b" + "e1c241d0ff691de6b47ad81eac2b925b474e1fd14311edb95219ce64677f497b" + "8917567652e9b4ef3838baf35e400fe1ffe2f16cfa1900d7ae2b67f0e6f43b71" + "769d1b0e0c0b99ea11de58fcd3b72e1bce3d9a8750b87e945d77f4dc39d73b04" + "e11b6adce343e1f38c6a879463c080d7254c4d65cf40e04934108bcde6bda824" + "4a72a90b1e", len); +ASSIGNZERO(out, len); +aes_hw_xts_decrypt(in,out,len,key1,key2,iv); +CHECKHEX(out,res,0,len); + +// 11 blocks = 176 bytes +len = 176; +ASSIGNHEX(res, + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" + "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f" + "404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f" + "606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f" + "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f" + "a0a1a2a3a4a5a6a7a8a9aaabacadaeaf", len); +ASSIGNHEX(in, + "c30ca8f2ed57307edc87e544867ac888348c208928d7406269954551cb627b5b" + "e1c241d0ff691de6b47ad81eac2b925b474e1fd14311edb95219ce64677f497b" + "8917567652e9b4ef3838baf35e400fe1ffe2f16cfa1900d7ae2b67f0e6f43b71" + "769d1b0e0c0b99ea11de58fcd3b72e1bce3d9a8750b87e945d77f4dc39d73b04" + "e11b6adce343e1f38c6a879463c080d74a72a90b1e6fe46b7bc95a929f79947e" + "ae8cc61cbb5f8cbd0c6f052e95ed6539", len); +ASSIGNZERO(out, len); +aes_hw_xts_decrypt(in,out,len,key1,key2,iv); +CHECKHEX(out,res,0,len); + +// 11 blocks + 9 bytes = 185bytes +len = 185; +ASSIGNHEX(res, + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" + "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f" + "404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f" + "606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f" + "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f" + "a0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8", len); +ASSIGNHEX(in, + "c30ca8f2ed57307edc87e544867ac888348c208928d7406269954551cb627b5b" + "e1c241d0ff691de6b47ad81eac2b925b474e1fd14311edb95219ce64677f497b" + "8917567652e9b4ef3838baf35e400fe1ffe2f16cfa1900d7ae2b67f0e6f43b71" + "769d1b0e0c0b99ea11de58fcd3b72e1bce3d9a8750b87e945d77f4dc39d73b04" + "e11b6adce343e1f38c6a879463c080d74a72a90b1e6fe46b7bc95a929f79947e" + "3ed782ad26e98e07f14d47f3c2a8e92aae8cc61cbb5f8cbd0c", len); +ASSIGNZERO(out, len); +aes_hw_xts_decrypt(in,out,len,key1,key2,iv); +CHECKHEX(out,res,0,len); + +// 14 blocks +len = 224; +ASSIGNHEX(res, + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" + "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f" + "404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f" + "606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f" + "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f" + "a0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebf" + "c0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedf", len); +ASSIGNHEX(in, + "c30ca8f2ed57307edc87e544867ac888348c208928d7406269954551cb627b5b" + "e1c241d0ff691de6b47ad81eac2b925b474e1fd14311edb95219ce64677f497b" + "8917567652e9b4ef3838baf35e400fe1ffe2f16cfa1900d7ae2b67f0e6f43b71" + "769d1b0e0c0b99ea11de58fcd3b72e1bce3d9a8750b87e945d77f4dc39d73b04" + "e11b6adce343e1f38c6a879463c080d74a72a90b1e6fe46b7bc95a929f79947e" + "ae8cc61cbb5f8cbd0c6f052e95ed65399009f56148fc07d88c8e0113d7eafb1f" + "ea39991882130ee45e95a3c6bc508f09c990add0cd3f1ca3403c096f9277e785", len); +ASSIGNZERO(out, len); +aes_hw_xts_decrypt(in,out,len,key1,key2,iv); +CHECKHEX(out,res,0,len); diff --git a/tests/known_value_tests_xts_encrypt.h b/tests/known_value_tests_xts_encrypt.h new file mode 100644 index 000000000..abb4377df --- /dev/null +++ b/tests/known_value_tests_xts_encrypt.h @@ -0,0 +1,362 @@ +// key1 = fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0efeeedecebeae9e8e7e6e5e4e3e2e1e0 +// key2 = bfbebdbcbbbab9b8b7b6b5b4b3b2b1b0afaeadacabaaa9a8a7a6a5a4a3a2a1a0 +// iv = 9a785634120000000000000000000000 +// roundkey1 = +// 0xfcfdfeff 0xf8f9fafb 0xf4f5f6f7 0xf0f1f2f3 +// 0xecedeeef 0xe8e9eaeb 0xe4e5e6e7 0xe0e1e2e3 +// 0xed1c0666 0x15e5fc9d 0xe1100a6a 0x11e1f899 +// 0x6e15af01 0x86fc45ea 0x6219a30d 0x82f841ee +// 0xc50f47e7 0xd0eabb7a 0x31fab110 0x201b4989 +// 0xd9ba94a6 0x5f46d14c 0x3d5f7241 0xbfa733af +// 0xbc071b20 0x6ceda05a 0x5d17114a 0x7d0c58c3 +// 0x2644fe88 0x79022fc4 0x445d5d85 0xfbfa6e2a +// 0x590836b7 0x35e596ed 0x68f287a7 0x15fedf64 +// 0x7fff60cb 0x6fd4f0f 0x42a0128a 0xb95a7ca0 +// 0xb95e88b7 0x8cbb1e5a 0xe44999fd 0xf1b74699 +// 0xde563a25 0xd8ab752a 0x9a0b67a0 0x23511b00 +// 0xda785938 0x56c34762 0xb28ade9f 0x433d9806 +// 0xc4717c4a 0x1cda0960 0x86d16ec0 0xa58075c0 +// 0x607e94e5 0x36bdd387 0x84370d18 0xc70a951e +// roundkey2 = +// 0xbcbdbebf 0xb8b9babb 0xb4b5b6b7 0xb0b1b2b3 +// 0xacadaeaf 0xa8a9aaab 0xa4a5a6a7 0xa0a1a2a3 +// 0xb65d8c84 0xee4363f 0xba518088 0xae0323b +// 0xcb4c8d4d 0x63e527e6 0xc7408141 0x67e123e2 +// 0x2ed874a0 0x203c429f 0x9a6dc217 0x908df02c +// 0xab11013c 0xc8f426da 0xfb4a79b 0x68558479 +// 0x989d88fb 0xb8a1ca64 0x22cc0873 0xb241f85f +// 0x9c9240f3 0x54666629 0x5bd2c1b2 0x338745cb +// 0x875e9f9d 0x3fff55f9 0x1d335d8a 0xaf72a5d5 +// 0xe5d246f0 0xb1b420d9 0xea66e16b 0xd9e1a4a0 +// 0x676b67c4 0x5894323d 0x45a76fb7 0xead5ca62 +// 0x62d1325a 0xd3651283 0x3903f3e8 0xe0e25748 +// 0x358affbf 0x6d1ecd82 0x28b9a235 0xc26c6857 +// 0x47817701 0x94e46582 0xade7966a 0x4d05c122 +// 0xa6699487 0xcb775905 0xe3cefb30 0x21a29367 +key1->rd_key[0]=0xf8f9fafbfcfdfeff; key1->rd_key[1]=0xf0f1f2f3f4f5f6f7; +key1->rd_key[2]=0xe8e9eaebecedeeef; key1->rd_key[3]=0xe0e1e2e3e4e5e6e7; +key1->rd_key[4]=0x15e5fc9ded1c0666; key1->rd_key[5]=0x11e1f899e1100a6a; +key1->rd_key[6]=0x86fc45ea6e15af01; key1->rd_key[7]=0x82f841ee6219a30d; +key1->rd_key[8]=0xd0eabb7ac50f47e7; key1->rd_key[9]=0x201b498931fab110; +key1->rd_key[10]=0x5f46d14cd9ba94a6; key1->rd_key[11]=0xbfa733af3d5f7241; +key1->rd_key[12]=0x6ceda05abc071b20; key1->rd_key[13]=0x7d0c58c35d17114a; +key1->rd_key[14]=0x79022fc42644fe88; key1->rd_key[15]=0xfbfa6e2a445d5d85; +key1->rd_key[16]=0x35e596ed590836b7; key1->rd_key[17]=0x15fedf6468f287a7; +key1->rd_key[18]=0x06fd4f0f7fff60cb; key1->rd_key[19]=0xb95a7ca042a0128a; +key1->rd_key[20]=0x8cbb1e5ab95e88b7; key1->rd_key[21]=0xf1b74699e44999fd; +key1->rd_key[22]=0xd8ab752ade563a25; key1->rd_key[23]=0x23511b009a0b67a0; +key1->rd_key[24]=0x56c34762da785938; key1->rd_key[25]=0x433d9806b28ade9f; +key1->rd_key[26]=0x1cda0960c4717c4a; key1->rd_key[27]=0xa58075c086d16ec0; +key1->rd_key[28]=0x36bdd387607e94e5; key1->rd_key[29]=0xc70a951e84370d18; + +key2->rd_key[0]=0xb8b9babbbcbdbebf; key2->rd_key[1]=0xb0b1b2b3b4b5b6b7; +key2->rd_key[2]=0xa8a9aaabacadaeaf; key2->rd_key[3]=0xa0a1a2a3a4a5a6a7; +key2->rd_key[4]=0x0ee4363fb65d8c84; key2->rd_key[5]=0x0ae0323bba518088; +key2->rd_key[6]=0x63e527e6cb4c8d4d; key2->rd_key[7]=0x67e123e2c7408141; +key2->rd_key[8]=0x203c429f2ed874a0; key2->rd_key[9]=0x908df02c9a6dc217; +key2->rd_key[10]=0xc8f426daab11013c; key2->rd_key[11]=0x685584790fb4a79b; +key2->rd_key[12]=0xb8a1ca64989d88fb; key2->rd_key[13]=0xb241f85f22cc0873; +key2->rd_key[14]=0x546666299c9240f3; key2->rd_key[15]=0x338745cb5bd2c1b2; +key2->rd_key[16]=0x3fff55f9875e9f9d; key2->rd_key[17]=0xaf72a5d51d335d8a; +key2->rd_key[18]=0xb1b420d9e5d246f0; key2->rd_key[19]=0xd9e1a4a0ea66e16b; +key2->rd_key[20]=0x5894323d676b67c4; key2->rd_key[21]=0xead5ca6245a76fb7; +key2->rd_key[22]=0xd365128362d1325a; key2->rd_key[23]=0xe0e257483903f3e8; +key2->rd_key[24]=0x6d1ecd82358affbf; key2->rd_key[25]=0xc26c685728b9a235; +key2->rd_key[26]=0x94e4658247817701; key2->rd_key[27]=0x4d05c122ade7966a; +key2->rd_key[28]=0xcb775905a6699487; key2->rd_key[29]=0x21a29367e3cefb30; + +key1->rounds=13; +key2->rounds=13; + +iv[0]=0x9a;iv[1]=0x78;iv[2]=0x56;iv[3]=0x34; +iv[4]=0x12;iv[5]=0x00;iv[6]=0x00;iv[7]=0x00; +iv[8]=0x00;iv[9]=0x00;iv[10]=0x00;iv[11]=0x00; +iv[12]=0x00;iv[13]=0x00;iv[14]=0x00;iv[15]=0x00; + +// 1block +len = 16; +ASSIGNHEX(in, "000102030405060708090a0b0c0d0e0f", len); +ASSIGNHEX(res, "c30ca8f2ed57307edc87e544867ac888", len); +ASSIGNZERO(out, len); +aes_hw_xts_encrypt(in,out,len,key1,key2,iv); +CHECKHEX(out,res,0,len); + +// 1block + 1byte = 17 bytes +len = 17; +ASSIGNHEX(in, "000102030405060708090a0b0c0d0e0f10", len); +ASSIGNHEX(res, "7f117752cc598a8b0d81d88af9f9bec8c3", len); +ASSIGNZERO(out, len); +aes_hw_xts_encrypt(in,out,len,key1,key2,iv); +CHECKHEX(out,res,0,len); + +// 1block + 6byte = 22 bytes +len = 22; +ASSIGNHEX(in, "000102030405060708090a0b0c0d0e0f101112131415", len); +ASSIGNHEX(res, "75e8188bcce59ada939f57de2cb9a489c30ca8f2ed57", len); +ASSIGNZERO(out, len); +aes_hw_xts_encrypt(in,out,len,key1,key2,iv); +CHECKHEX(out,res,0,len); + +// 1bock + 15bytes = 31 bytes +len = 31; +ASSIGNHEX(in, "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e", len); +ASSIGNHEX(res, "581ea1fee5516ad432ddebe75fd27c6fc30ca8f2ed57307edc87e544867ac8", len); +ASSIGNZERO(out, len); +aes_hw_xts_encrypt(in,out,len,key1,key2,iv); +CHECKHEX(out,res,0,len); + +// 3 blocks + 3 bytes +len = 51; +ASSIGNHEX(in, "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" + "202122232425262728292a2b2c2d2e2f303132", len); +ASSIGNHEX(res, "c30ca8f2ed57307edc87e544867ac888348c208928d7406269954551cb627b5b" + "bea47768aa25376e924cce6a102ca2e4e1c241", len); +ASSIGNZERO(out, len); +aes_hw_xts_encrypt(in,out,len,key1,key2,iv); +CHECKHEX(out,res,0,len); + +// 4 blocks +len = 64; +ASSIGNHEX(in, "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" + "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", len); +ASSIGNHEX(res, "c30ca8f2ed57307edc87e544867ac888348c208928d7406269954551cb627b5b" + "e1c241d0ff691de6b47ad81eac2b925b474e1fd14311edb95219ce64677f497b", len); +ASSIGNZERO(out, len); +aes_hw_xts_encrypt(in,out,len,key1,key2,iv); +CHECKHEX(out,res,0,len); + +// 4blocks + 10 bytes = 74 bytes +len = 74; +ASSIGNHEX(in, "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" + "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f" + "40414243444546474849", len); +ASSIGNHEX(res, "c30ca8f2ed57307edc87e544867ac888348c208928d7406269954551cb627b5b" + "e1c241d0ff691de6b47ad81eac2b925b0f451eb8847b98d48b1407f64a4f9ee3" + "474e1fd14311edb95219", len); +ASSIGNZERO(out, len); +aes_hw_xts_encrypt(in,out,len,key1,key2,iv); +CHECKHEX(out,res,0,len); + +// 5 blocks +len = 80; +ASSIGNHEX(in, "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" + "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f" + "404142434445464748494a4b4c4d4e4f", len); +ASSIGNHEX(res, "c30ca8f2ed57307edc87e544867ac888348c208928d7406269954551cb627b5b" + "e1c241d0ff691de6b47ad81eac2b925b474e1fd14311edb95219ce64677f497b" + "8917567652e9b4ef3838baf35e400fe1", len); +ASSIGNZERO(out, len); +aes_hw_xts_encrypt(in,out,len,key1,key2,iv); +CHECKHEX(out,res,0,len); + +// 5blocks + 7bytes = 87 bytes +len = 87; +ASSIGNHEX(in, "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" + "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f" + "404142434445464748494a4b4c4d4e4f50515253545556", len); +ASSIGNHEX(res, "c30ca8f2ed57307edc87e544867ac888348c208928d7406269954551cb627b5b" + "e1c241d0ff691de6b47ad81eac2b925b474e1fd14311edb95219ce64677f497b" + "a436b967e79bb8e8e4c29d1099fe1bbf8917567652e9b4", len); +ASSIGNZERO(out, len); +aes_hw_xts_encrypt(in,out,len,key1,key2,iv); +CHECKHEX(out,res,0,len); + +// 6 blocks +len = 96; +ASSIGNHEX(in, + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" + "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f" + "404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f", len); +ASSIGNHEX(res, + "c30ca8f2ed57307edc87e544867ac888348c208928d7406269954551cb627b5b" + "e1c241d0ff691de6b47ad81eac2b925b474e1fd14311edb95219ce64677f497b" + "8917567652e9b4ef3838baf35e400fe1ffe2f16cfa1900d7ae2b67f0e6f43b71", len); +ASSIGNZERO(out, len); +aes_hw_xts_encrypt(in,out,len,key1,key2,iv); +CHECKHEX(out,res,0,len); + +// 6blocks + 4bytes = 100 bytes +len = 100; +ASSIGNHEX(in, + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" + "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f" + "404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f" + "60616263", len); +ASSIGNHEX(res, + "c30ca8f2ed57307edc87e544867ac888348c208928d7406269954551cb627b5b" + "e1c241d0ff691de6b47ad81eac2b925b474e1fd14311edb95219ce64677f497b" + "8917567652e9b4ef3838baf35e400fe1aad32ff4d83b0af3f6a176025bd1321b" + "ffe2f16c", len); +ASSIGNZERO(out, len); +aes_hw_xts_encrypt(in,out,len,key1,key2,iv); +CHECKHEX(out,res,0,len); + +// 8 blocks +len = 128; +ASSIGNHEX(in, + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" + "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f" + "404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f" + "606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f", len); +ASSIGNHEX(res, + "c30ca8f2ed57307edc87e544867ac888348c208928d7406269954551cb627b5b" + "e1c241d0ff691de6b47ad81eac2b925b474e1fd14311edb95219ce64677f497b" + "8917567652e9b4ef3838baf35e400fe1ffe2f16cfa1900d7ae2b67f0e6f43b71" + "769d1b0e0c0b99ea11de58fcd3b72e1bce3d9a8750b87e945d77f4dc39d73b04", len); +ASSIGNZERO(out, len); +aes_hw_xts_encrypt(in,out,len,key1,key2,iv); +CHECKHEX(out,res,0,len); + +// 8blocks + 6 bytes = 134 bytes +len = 134; +ASSIGNHEX(in, + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" + "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f" + "404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f" + "606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f" + "808182838485", len); +ASSIGNHEX(res, + "c30ca8f2ed57307edc87e544867ac888348c208928d7406269954551cb627b5b" + "e1c241d0ff691de6b47ad81eac2b925b474e1fd14311edb95219ce64677f497b" + "8917567652e9b4ef3838baf35e400fe1ffe2f16cfa1900d7ae2b67f0e6f43b71" + "769d1b0e0c0b99ea11de58fcd3b72e1be0ad32884698e15420e52c96b698bba1" + "ce3d9a8750b8", len); +ASSIGNZERO(out, len); +aes_hw_xts_encrypt(in,out,len,key1,key2,iv); +CHECKHEX(out,res,0,len); + +// 9 blocks = 144 bytes +len = 144; +ASSIGNHEX(in, + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" + "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f" + "404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f" + "606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f" + "808182838485868788898a8b8c8d8e8f", len); +ASSIGNHEX(res, + "c30ca8f2ed57307edc87e544867ac888348c208928d7406269954551cb627b5b" + "e1c241d0ff691de6b47ad81eac2b925b474e1fd14311edb95219ce64677f497b" + "8917567652e9b4ef3838baf35e400fe1ffe2f16cfa1900d7ae2b67f0e6f43b71" + "769d1b0e0c0b99ea11de58fcd3b72e1bce3d9a8750b87e945d77f4dc39d73b04" + "e11b6adce343e1f38c6a879463c080d7", len); +ASSIGNZERO(out, len); +aes_hw_xts_encrypt(in,out,len,key1,key2,iv); +CHECKHEX(out,res,0,len); + +// 9blocks + 14bytes = 158bytes +len = 158; +ASSIGNHEX(in, + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" + "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f" + "404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f" + "606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f" + "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d", len); +ASSIGNHEX(res, + "c30ca8f2ed57307edc87e544867ac888348c208928d7406269954551cb627b5b" + "e1c241d0ff691de6b47ad81eac2b925b474e1fd14311edb95219ce64677f497b" + "8917567652e9b4ef3838baf35e400fe1ffe2f16cfa1900d7ae2b67f0e6f43b71" + "769d1b0e0c0b99ea11de58fcd3b72e1bce3d9a8750b87e945d77f4dc39d73b04" + "a5da920d96beb388ade417027054dbd0e11b6adce343e1f38c6a879463c0", len); +ASSIGNZERO(out, len); +aes_hw_xts_encrypt(in,out,len,key1,key2,iv); +CHECKHEX(out,res,0,len); + +// 10blocks = 160bytes +len = 160; +ASSIGNHEX(in, + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" + "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f" + "404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f" + "606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f" + "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f", len); +ASSIGNHEX(res, + "c30ca8f2ed57307edc87e544867ac888348c208928d7406269954551cb627b5b" + "e1c241d0ff691de6b47ad81eac2b925b474e1fd14311edb95219ce64677f497b" + "8917567652e9b4ef3838baf35e400fe1ffe2f16cfa1900d7ae2b67f0e6f43b71" + "769d1b0e0c0b99ea11de58fcd3b72e1bce3d9a8750b87e945d77f4dc39d73b04" + "e11b6adce343e1f38c6a879463c080d74a72a90b1e6fe46b7bc95a929f79947e", len); +ASSIGNZERO(out, len); +aes_hw_xts_encrypt(in,out,len,key1,key2,iv); +CHECKHEX(out,res,0,len); + +// 10blocks + 5bytes = 165bytes +len = 165; +ASSIGNHEX(in, + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" + "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f" + "404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f" + "606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f" + "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f" + "a0a1a2a3a4", len); +ASSIGNHEX(res, + "c30ca8f2ed57307edc87e544867ac888348c208928d7406269954551cb627b5b" + "e1c241d0ff691de6b47ad81eac2b925b474e1fd14311edb95219ce64677f497b" + "8917567652e9b4ef3838baf35e400fe1ffe2f16cfa1900d7ae2b67f0e6f43b71" + "769d1b0e0c0b99ea11de58fcd3b72e1bce3d9a8750b87e945d77f4dc39d73b04" + "e11b6adce343e1f38c6a879463c080d7254c4d65cf40e04934108bcde6bda824" + "4a72a90b1e", len); +ASSIGNZERO(out, len); +aes_hw_xts_encrypt(in,out,len,key1,key2,iv); +CHECKHEX(out,res,0,len); + +// 11 blocks = 176 bytes +len = 176; +ASSIGNHEX(in, + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" + "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f" + "404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f" + "606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f" + "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f" + "a0a1a2a3a4a5a6a7a8a9aaabacadaeaf", len); +ASSIGNHEX(res, + "c30ca8f2ed57307edc87e544867ac888348c208928d7406269954551cb627b5b" + "e1c241d0ff691de6b47ad81eac2b925b474e1fd14311edb95219ce64677f497b" + "8917567652e9b4ef3838baf35e400fe1ffe2f16cfa1900d7ae2b67f0e6f43b71" + "769d1b0e0c0b99ea11de58fcd3b72e1bce3d9a8750b87e945d77f4dc39d73b04" + "e11b6adce343e1f38c6a879463c080d74a72a90b1e6fe46b7bc95a929f79947e" + "ae8cc61cbb5f8cbd0c6f052e95ed6539", len); +ASSIGNZERO(out, len); +aes_hw_xts_encrypt(in,out,len,key1,key2,iv); +CHECKHEX(out,res,0,len); + +// 11 blocks + 9 bytes = 185bytes +len = 185; +ASSIGNHEX(in, + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" + "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f" + "404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f" + "606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f" + "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f" + "a0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8", len); +ASSIGNHEX(res, + "c30ca8f2ed57307edc87e544867ac888348c208928d7406269954551cb627b5b" + "e1c241d0ff691de6b47ad81eac2b925b474e1fd14311edb95219ce64677f497b" + "8917567652e9b4ef3838baf35e400fe1ffe2f16cfa1900d7ae2b67f0e6f43b71" + "769d1b0e0c0b99ea11de58fcd3b72e1bce3d9a8750b87e945d77f4dc39d73b04" + "e11b6adce343e1f38c6a879463c080d74a72a90b1e6fe46b7bc95a929f79947e" + "3ed782ad26e98e07f14d47f3c2a8e92aae8cc61cbb5f8cbd0c", len); +ASSIGNZERO(out, len); +aes_hw_xts_encrypt(in,out,len,key1,key2,iv); +CHECKHEX(out,res,0,len); + +// 14 blocks +len = 224; +ASSIGNHEX(in, + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" + "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f" + "404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f" + "606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f" + "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f" + "a0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebf" + "c0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedf", len); +ASSIGNHEX(res, + "c30ca8f2ed57307edc87e544867ac888348c208928d7406269954551cb627b5b" + "e1c241d0ff691de6b47ad81eac2b925b474e1fd14311edb95219ce64677f497b" + "8917567652e9b4ef3838baf35e400fe1ffe2f16cfa1900d7ae2b67f0e6f43b71" + "769d1b0e0c0b99ea11de58fcd3b72e1bce3d9a8750b87e945d77f4dc39d73b04" + "e11b6adce343e1f38c6a879463c080d74a72a90b1e6fe46b7bc95a929f79947e" + "ae8cc61cbb5f8cbd0c6f052e95ed65399009f56148fc07d88c8e0113d7eafb1f" + "ea39991882130ee45e95a3c6bc508f09c990add0cd3f1ca3403c096f9277e785", len); +ASSIGNZERO(out, len); +aes_hw_xts_encrypt(in,out,len,key1,key2,iv); +CHECKHEX(out,res,0,len); diff --git a/tests/test.c b/tests/test.c index dc9ac74c7..1be615759 100644 --- a/tests/test.c +++ b/tests/test.c @@ -14858,9 +14858,9 @@ int test_word_recip(void) if (x[0] != UINT64_C(n)) \ { printf("Failed known value test\n"); ++failures; } else { ++successes; } -int test_known_values(void) +int test_known_values_p384(void) { int failures = 0, successes = 0; - printf("Testing known value cases\n"); + printf("Testing known value cases for p384\n"); #include "known_value_tests_p384.h" @@ -14874,6 +14874,95 @@ int test_known_values(void) } } +// Helpers for writing XTS tests +void assign_bytearray_from_hexstring(uint8_t *bytearr, const char *hexstr, int len) +{ + for (int i = 0; i < len; i++) { + sscanf(&hexstr[i * 2], "%2hhx", &bytearr[i]); + } +} + +void assign_bytearray_zero(uint8_t *bytearr, int len) +{ + for(int i = 0; i < len; i++){ + bytearr[i] = 0x00; + } +} + +#define ASSIGNHEX(bytearr, hexstr, len) assign_bytearray_from_hexstring(bytearr, hexstr, len) +#define ASSIGNZERO(bytearr, len) assign_bytearray_zero(bytearr, len) + +int check_bytearr(const uint8_t *out, const uint8_t *res, int diff, int len) +{ + for(int i = 0; i < len; i++){ + if (out[i]!=res[i]){diff = 1;break;}; + } + return diff; +} + +#define CHECKHEX(out, res, diff, len) \ + if (check_bytearr(out, res, diff, len)) \ + { printf("Failed known value test\n"); ++failures; } else { ++successes; } + + +int test_known_values_xts_encrypt(void) +{ +#ifdef __x86_64__ + return 1; +#else + int failures = 0, successes = 0; + printf("Testing known value cases for aes-xts encrypt\n"); + + AES_KEY *key1 = (AES_KEY *)malloc(sizeof(AES_KEY)); + AES_KEY *key2 = (AES_KEY *)malloc(sizeof(AES_KEY)); + size_t len; + uint8_t iv[16]; + uint8_t in[224]; + uint8_t out[224]; + uint8_t res[224]; + +#include "known_value_tests_xts_encrypt.h" + + if (failures != 0) + { printf ("Failed %d known value tests, passed %d\n",failures,successes); + return failures; + } + else + { printf("Successfully passed %d known value tests\n",successes); + return 0; + } +#endif +} + +int test_known_values_xts_decrypt(void) +{ +#ifdef __x86_64__ + return 1; +#else + int failures = 0, successes = 0; + printf("Testing known value cases for aes-xts decrypt\n"); + + AES_KEY *key1 = (AES_KEY *)malloc(sizeof(AES_KEY)); + AES_KEY *key2 = (AES_KEY *)malloc(sizeof(AES_KEY)); + size_t len; + uint8_t iv[16]; + uint8_t in[224]; + uint8_t out[224]; + uint8_t res[224]; + +#include "known_value_tests_xts_decrypt.h" + + if (failures != 0) + { printf ("Failed %d known value tests, passed %d\n",failures,successes); + return failures; + } + else + { printf("Successfully passed %d known value tests\n",successes); + return 0; + } +#endif +} + // **************************************************************************** // Analogous testing of relevant functions against TweetNaCl as reference // @@ -15404,6 +15493,7 @@ void functionaltest(int enabled,char *name,int (*f)(void)) int main(int argc, char *argv[]) { int bmi = get_arch_name() == ARCH_AARCH64 || supports_bmi2_and_adx(); int sha3 = get_arch_name() == ARCH_AARCH64 && supports_arm_sha3(); + int aes = get_arch_name() == ARCH_AARCH64 && supports_arm_aes(); int arm = get_arch_name() == ARCH_AARCH64; int all = 1; int extrastrigger = 1; @@ -15788,12 +15878,13 @@ int main(int argc, char *argv[]) functionaltest(sha3,"sha3_keccak4_f1600",test_sha3_keccak4_f1600); functionaltest(arm,"sha3_keccak4_f1600_alt",test_sha3_keccak4_f1600_alt); functionaltest(sha3,"sha3_keccak4_f1600_alt2",test_sha3_keccak4_f1600_alt2); - + functionaltest(aes,"known value tests for aes-xts encrypt",test_known_values_xts_encrypt); + functionaltest(aes,"known value tests for aes-xts decrypt",test_known_values_xts_decrypt); } if (extrastrigger) function_to_test = "_"; - functionaltest(bmi,"known value tests",test_known_values); + functionaltest(bmi,"known value tests",test_known_values_p384); functionaltest(bmi,"curve25519_x25519 (TweetNaCl)",test_curve25519_x25519_tweetnacl); functionaltest(all,"curve25519_x25519_alt (TweetNaCl)",test_curve25519_x25519_alt_tweetnacl); diff --git a/tools/collect-signatures.py b/tools/collect-signatures.py index 384b4d4e7..2f98bd0af 100644 --- a/tools/collect-signatures.py +++ b/tools/collect-signatures.py @@ -291,6 +291,8 @@ def stripPrefixes(s, prefixes): # A list of functions that are either only in arm or x86 onlyInArm = [ + "aes_hw_xts_decrypt", + "aes_hw_xts_encrypt", "bignum_copy_row_from_table_8n", "bignum_copy_row_from_table_16", "bignum_copy_row_from_table_32", From c49f61e117aa85a78ea3e4e43b6820898b82cb4d Mon Sep 17 00:00:00 2001 From: Yan Peng Date: Tue, 23 Dec 2025 11:55:29 -0800 Subject: [PATCH 115/132] Fix issue in collect-signatures --- arm/aes-xts/aes_hw_xts_decrypt.S | 2 +- arm/aes-xts/aes_hw_xts_encrypt.S | 2 +- arm/proofs/subroutine_signatures.ml | 46 +++++++++++++++++++++++++++++ include/s2n-bignum.h | 4 +-- tools/collect-signatures.py | 7 +++++ 5 files changed, 57 insertions(+), 4 deletions(-) diff --git a/arm/aes-xts/aes_hw_xts_decrypt.S b/arm/aes-xts/aes_hw_xts_decrypt.S index 2a8ef9d31..7767c6780 100644 --- a/arm/aes-xts/aes_hw_xts_decrypt.S +++ b/arm/aes-xts/aes_hw_xts_decrypt.S @@ -3,7 +3,7 @@ // ---------------------------------------------------------------------------- // AES_XTS_DECRYPT (256-bit) -// Inputs *in, length, *key1, *key2, iv[16]; output *out +// Inputs in[length], length, key1[244], key2[244], iv[16]; output out[length] // // extern void aes_hw_xts_decrypt(const uint8_t *in, uint8_t *out, // size_t length, diff --git a/arm/aes-xts/aes_hw_xts_encrypt.S b/arm/aes-xts/aes_hw_xts_encrypt.S index d51b2206e..bb15817de 100644 --- a/arm/aes-xts/aes_hw_xts_encrypt.S +++ b/arm/aes-xts/aes_hw_xts_encrypt.S @@ -3,7 +3,7 @@ // ---------------------------------------------------------------------------- // AES_XTS_ENCRYPT (256-bit) -// Inputs *in, length, *key1, *key2, iv[16]; output *out +// Inputs in[length], length, key1[244], key2[244], iv[16]; output out[length] // // extern void aes_hw_xts_encrypt(const uint8_t *in, uint8_t *out, // size_t length, diff --git a/arm/proofs/subroutine_signatures.ml b/arm/proofs/subroutine_signatures.ml index 80301c0c7..aef67bde3 100644 --- a/arm/proofs/subroutine_signatures.ml +++ b/arm/proofs/subroutine_signatures.ml @@ -1,4 +1,50 @@ let subroutine_signatures = [ +("aes_hw_xts_decrypt", + ([(*args*) + ("in", "uint8_t*", (*is const?*)"true"); + ("out", "uint8_t*", (*is const?*)"false"); + ("length", "size_t", (*is const?*)"false"); + ("key1", "AES_KEY*", (*is const?*)"true"); + ("key2", "AES_KEY*", (*is const?*)"true"); + ("iv", "uint8_t[16]", (*is const?*)"true"); + ], + "void", + [(* input buffers *) + ("in", "length"(* num elems *), 1(* elem bytesize *)); + ("key1", "244"(* num elems *), 1(* elem bytesize *)); + ("key2", "244"(* num elems *), 1(* elem bytesize *)); + ("iv", "16"(* num elems *), 1(* elem bytesize *)); + ], + [(* output buffers *) + ("out", "length"(* num elems *), 1(* elem bytesize *)); + ], + [(* temporary buffers *) + ]) +); + +("aes_hw_xts_encrypt", + ([(*args*) + ("in", "uint8_t*", (*is const?*)"true"); + ("out", "uint8_t*", (*is const?*)"false"); + ("length", "size_t", (*is const?*)"false"); + ("key1", "AES_KEY*", (*is const?*)"true"); + ("key2", "AES_KEY*", (*is const?*)"true"); + ("iv", "uint8_t[16]", (*is const?*)"true"); + ], + "void", + [(* input buffers *) + ("in", "length"(* num elems *), 1(* elem bytesize *)); + ("key1", "244"(* num elems *), 1(* elem bytesize *)); + ("key2", "244"(* num elems *), 1(* elem bytesize *)); + ("iv", "16"(* num elems *), 1(* elem bytesize *)); + ], + [(* output buffers *) + ("out", "length"(* num elems *), 1(* elem bytesize *)); + ], + [(* temporary buffers *) + ]) +); + ("bignum_add", ([(*args*) ("p", "uint64_t", (*is const?*)"false"); diff --git a/include/s2n-bignum.h b/include/s2n-bignum.h index 873ad8c71..d93371916 100644 --- a/include/s2n-bignum.h +++ b/include/s2n-bignum.h @@ -37,12 +37,12 @@ struct aes_key_st { typedef struct aes_key_st AES_KEY; // AES_XTS_DECRYPT (256-bit) -// Inputs *in, length, *key1, *key2, iv[16]; output *out +// Inputs in[length], length, key1[244], key2[244], iv[16]; output out[length] extern void aes_hw_xts_decrypt(const uint8_t *in, uint8_t *out, size_t length, const AES_KEY *key1, const AES_KEY *key2, const uint8_t iv[16]); // AES_XTS_ENCRYPT (256-bit) -// Inputs *in, length, *key1, *key2, iv[16]; output *out +// Inputs in[length], length, key1[244], key2[244], iv[16]; output out[length] extern void aes_hw_xts_encrypt(const uint8_t *in, uint8_t *out, size_t length, const AES_KEY *key1, const AES_KEY *key2, const uint8_t iv[16]); diff --git a/tools/collect-signatures.py b/tools/collect-signatures.py index 2f98bd0af..7cd8b0819 100644 --- a/tools/collect-signatures.py +++ b/tools/collect-signatures.py @@ -48,6 +48,10 @@ def __eq__(self, io2): return self.meminputs == io2.meminputs and self.memoutputs == io2.memoutputs and \ self.temporaries == decl2.temporaries + def print(self): + print(f"- meminputs: {self.meminputs}") + print(f"- memoutputs: {self.memoutputs}") + print(f"- temporaries: {self.temporaries}") def parseFnDecl(s:str, filename:str) -> FnDecl: assert s.startswith("extern"), s @@ -396,6 +400,7 @@ def checkOnlyInArch(fnname, onlyIn): # Before printing input and output buffers, collect elem bytesize of buffers arg_elem_bytesizes = dict() + isPtr = lambda fullty, elemty: fullty.startswith(elemty + "*") isPtrOrArray = lambda fullty, elemty: fullty.startswith(elemty + "[") or fullty.startswith(elemty + "*") for argname, argtype, _ in fnsig.args: if isPtrOrArray(argtype, "int64_t") or isPtrOrArray(argtype, "uint64_t"): @@ -406,6 +411,8 @@ def checkOnlyInArch(fnname, onlyIn): arg_elem_bytesizes[argname] = 2 elif isPtrOrArray(argtype, "int8_t") or isPtrOrArray(argtype, "uint8_t"): arg_elem_bytesizes[argname] = 1 + elif isPtr(argtype, "AES_KEY"): + arg_elem_bytesizes[argname] = 1 elif "[" not in argtype and "*" not in argtype: continue else: From 71bbe67fd3ba3b14567fae533b3364b98ad93363 Mon Sep 17 00:00:00 2001 From: Yan Peng Date: Tue, 23 Dec 2025 12:22:51 -0800 Subject: [PATCH 116/132] Add benchmark for AES-XTS --- benchmarks/benchmark.c | 63 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/benchmarks/benchmark.c b/benchmarks/benchmark.c index d6b3644fb..0c7b8442c 100644 --- a/benchmarks/benchmark.c +++ b/benchmarks/benchmark.c @@ -49,6 +49,10 @@ static uint64_t bb[16][BUFFERSIZE]; static uint64_t bigbuff[100000]; +// AES keys for XTS mode testing +static AES_KEY aes_key1, aes_key2; +static uint8_t aes_iv[16]; + // Source of random 64-bit numbers with bit density // 0 = all zeros, 32 = "average", 64 = all ones // Then a generic one with the density itself randomized @@ -1147,10 +1151,57 @@ void call_mlkem_frombytes(void) {} void call_mlkem_unpack(void) {} #endif +// Helper function for AES XTS encrypt with parameterized length +static void aes_hw_xts_encrypt_helper(size_t len) +{ + int j; + for (j = 0; j < 30; ++j) { + aes_key1.rd_key[j] = b1[j % BUFFERSIZE]; + aes_key2.rd_key[j] = b2[j % BUFFERSIZE]; + } + aes_key1.rounds = 14; // AES-256 + aes_key2.rounds = 14; + for (j = 0; j < 16; ++j) aes_iv[j] = (uint8_t)(b3[j] & 0xFF); + + aes_hw_xts_encrypt((uint8_t*)b0, (uint8_t*)b1, len, &aes_key1, &aes_key2, aes_iv); +} + +// AES XTS encrypt wrapper functions for different block sizes +void call_aes_hw_xts_encrypt_16(void) { repeat(aes_hw_xts_encrypt_helper(16)); } +void call_aes_hw_xts_encrypt_32(void) { repeat(aes_hw_xts_encrypt_helper(32)); } +void call_aes_hw_xts_encrypt_64(void) { repeat(aes_hw_xts_encrypt_helper(64)); } +void call_aes_hw_xts_encrypt_128(void) { repeat(aes_hw_xts_encrypt_helper(128)); } +void call_aes_hw_xts_encrypt_256(void) { repeat(aes_hw_xts_encrypt_helper(256)); } +void call_aes_hw_xts_encrypt_512(void) { repeatfewer(10,aes_hw_xts_encrypt_helper(512)); } + +// Helper function for AES XTS decrypt with parameterized length +static void aes_hw_xts_decrypt_helper(size_t len) +{ + int j; + for (j = 0; j < 30; ++j) { + aes_key1.rd_key[j] = b1[j % BUFFERSIZE]; + aes_key2.rd_key[j] = b2[j % BUFFERSIZE]; + } + aes_key1.rounds = 14; // AES-256 + aes_key2.rounds = 14; + for (j = 0; j < 16; ++j) aes_iv[j] = (uint8_t)(b3[j] & 0xFF); + + aes_hw_xts_decrypt((uint8_t*)b0, (uint8_t*)b1, len, &aes_key1, &aes_key2, aes_iv); +} + +// AES XTS decrypt wrapper functions for different block sizes +void call_aes_hw_xts_decrypt_16(void) { repeat(aes_hw_xts_decrypt_helper(16)); } +void call_aes_hw_xts_decrypt_32(void) { repeat(aes_hw_xts_decrypt_helper(32)); } +void call_aes_hw_xts_decrypt_64(void) { repeat(aes_hw_xts_decrypt_helper(64)); } +void call_aes_hw_xts_decrypt_128(void) { repeat(aes_hw_xts_decrypt_helper(128)); } +void call_aes_hw_xts_decrypt_256(void) { repeat(aes_hw_xts_decrypt_helper(256)); } +void call_aes_hw_xts_decrypt_512(void) { repeatfewer(10,aes_hw_xts_decrypt_helper(512)); } + int main(int argc, char *argv[]) { int bmi = get_arch_name() == ARCH_AARCH64 || supports_bmi2_and_adx(); int sha3 = get_arch_name() == ARCH_AARCH64 && supports_arm_sha3(); + int aes = get_arch_name() == ARCH_AARCH64 && supports_arm_aes(); int all = 1; int arm = get_arch_name() == ARCH_AARCH64; char *argending; @@ -1603,6 +1654,18 @@ int main(int argc, char *argv[]) timingtest(all,"word_negmodinv",call_word_negmodinv); timingtest(all,"word_popcount",call_word_popcount); timingtest(all,"word_recip",call_word_recip); + timingtest(aes,"aes_hw_xts_encrypt (16 bytes)",call_aes_hw_xts_encrypt_16); + timingtest(aes,"aes_hw_xts_encrypt (32 bytes)",call_aes_hw_xts_encrypt_32); + timingtest(aes,"aes_hw_xts_encrypt (64 bytes)",call_aes_hw_xts_encrypt_64); + timingtest(aes,"aes_hw_xts_encrypt (128 bytes)",call_aes_hw_xts_encrypt_128); + timingtest(aes,"aes_hw_xts_encrypt (256 bytes)",call_aes_hw_xts_encrypt_256); + timingtest(aes,"aes_hw_xts_encrypt (512 bytes)",call_aes_hw_xts_encrypt_512); + timingtest(aes,"aes_hw_xts_decrypt (16 bytes)",call_aes_hw_xts_decrypt_16); + timingtest(aes,"aes_hw_xts_decrypt (32 bytes)",call_aes_hw_xts_decrypt_32); + timingtest(aes,"aes_hw_xts_decrypt (64 bytes)",call_aes_hw_xts_decrypt_64); + timingtest(aes,"aes_hw_xts_decrypt (128 bytes)",call_aes_hw_xts_decrypt_128); + timingtest(aes,"aes_hw_xts_decrypt (256 bytes)",call_aes_hw_xts_decrypt_256); + timingtest(aes,"aes_hw_xts_decrypt (512 bytes)",call_aes_hw_xts_decrypt_512); // Summarize performance in arithmetic and geometric means From 8940450e94efd385806cff85342bb97182716c08 Mon Sep 17 00:00:00 2001 From: Yan Peng Date: Tue, 23 Dec 2025 12:43:57 -0800 Subject: [PATCH 117/132] Fix missing sematest for ldrb shifted register variant --- arm/proofs/simulator_iclasses.ml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arm/proofs/simulator_iclasses.ml b/arm/proofs/simulator_iclasses.ml index 33ce5889b..1eec355f4 100644 --- a/arm/proofs/simulator_iclasses.ml +++ b/arm/proofs/simulator_iclasses.ml @@ -450,6 +450,9 @@ let check_insns () = "00111000010xxxxxxxxx11xxxxxxxxxx"; "0011100101xxxxxxxxxxxxxxxxxxxxxx"; + (*** ldrb (shifted register, no shift S = 0) ***) + "00111000011xxxxxxxx010xxxxxxxxxx"; + (*** ld1 (1 register, Post-immediate offset) ***) "0x001100110111110111xxxxxxxxxxxx"; From b5607f824828a094a8ef083ee2bb5c821c2c0873 Mon Sep 17 00:00:00 2001 From: Yan Peng Date: Tue, 23 Dec 2025 13:04:40 -0800 Subject: [PATCH 118/132] Rename AES_KEY as s2n_bignum_AES_KEY --- arm/aes-xts/aes_hw_xts_decrypt.S | 5 +++-- arm/aes-xts/aes_hw_xts_encrypt.S | 5 +++-- arm/proofs/aes_xts_encrypt.ml | 2 +- arm/proofs/subroutine_signatures.ml | 8 ++++---- benchmarks/benchmark.c | 2 +- include/s2n-bignum.h | 8 ++++---- tests/test.c | 8 ++++---- tools/collect-signatures.py | 2 +- 8 files changed, 21 insertions(+), 19 deletions(-) diff --git a/arm/aes-xts/aes_hw_xts_decrypt.S b/arm/aes-xts/aes_hw_xts_decrypt.S index 7767c6780..ad415b9b9 100644 --- a/arm/aes-xts/aes_hw_xts_decrypt.S +++ b/arm/aes-xts/aes_hw_xts_decrypt.S @@ -5,9 +5,10 @@ // AES_XTS_DECRYPT (256-bit) // Inputs in[length], length, key1[244], key2[244], iv[16]; output out[length] // -// extern void aes_hw_xts_decrypt(const uint8_t *in, uint8_t *out, +// extern void aes_hw_xts_decrypt(const uint8_t *in, uint8_t *out, // size_t length, -// const AES_KEY *key1, const AES_KEY *key2, +// const s2n_bignum_AES_KEY *key1, +// const s2n_bignum_AES_KEY *key2, // const uint8_t iv[16]); // // Standard ARM ABI: X0 = in, X1 = out, X2 = length, X3 = key1, X4 = key2, X5 = iv diff --git a/arm/aes-xts/aes_hw_xts_encrypt.S b/arm/aes-xts/aes_hw_xts_encrypt.S index bb15817de..50bf92f68 100644 --- a/arm/aes-xts/aes_hw_xts_encrypt.S +++ b/arm/aes-xts/aes_hw_xts_encrypt.S @@ -5,9 +5,10 @@ // AES_XTS_ENCRYPT (256-bit) // Inputs in[length], length, key1[244], key2[244], iv[16]; output out[length] // -// extern void aes_hw_xts_encrypt(const uint8_t *in, uint8_t *out, +// extern void aes_hw_xts_encrypt(const uint8_t *in, uint8_t *out, // size_t length, -// const AES_KEY *key1, const AES_KEY *key2, +// const s2n_bignum_AES_KEY *key1, +// const s2n_bignum_AES_KEY *key2, // const uint8_t iv[16]); // // Standard ARM ABI: X0 = in, X1 = out, X2 = length, X3 = key1, X4 = key2, X5 = iv diff --git a/arm/proofs/aes_xts_encrypt.ml b/arm/proofs/aes_xts_encrypt.ml index 348f187d0..d02e66589 100644 --- a/arm/proofs/aes_xts_encrypt.ml +++ b/arm/proofs/aes_xts_encrypt.ml @@ -3220,7 +3220,7 @@ let AES_XTS_ENCRYPT_LT_5BLOCK_CORRECT = time prove( (* void aes_hw_xts_encrypt(const uint8_t *in, uint8_t *out, size_t length, - const AES_KEY *key1, const AES_KEY *key2, + const s2n_bignum_AES_KEY *key1, const s2n_bignum_AES_KEY *key2, const uint8_t iv[16]) *) let AES256_XTS_ENCRYPT_CORRECT = prove( diff --git a/arm/proofs/subroutine_signatures.ml b/arm/proofs/subroutine_signatures.ml index aef67bde3..f3440a8f2 100644 --- a/arm/proofs/subroutine_signatures.ml +++ b/arm/proofs/subroutine_signatures.ml @@ -4,8 +4,8 @@ let subroutine_signatures = [ ("in", "uint8_t*", (*is const?*)"true"); ("out", "uint8_t*", (*is const?*)"false"); ("length", "size_t", (*is const?*)"false"); - ("key1", "AES_KEY*", (*is const?*)"true"); - ("key2", "AES_KEY*", (*is const?*)"true"); + ("key1", "s2n_bignum_AES_KEY*", (*is const?*)"true"); + ("key2", "s2n_bignum_AES_KEY*", (*is const?*)"true"); ("iv", "uint8_t[16]", (*is const?*)"true"); ], "void", @@ -27,8 +27,8 @@ let subroutine_signatures = [ ("in", "uint8_t*", (*is const?*)"true"); ("out", "uint8_t*", (*is const?*)"false"); ("length", "size_t", (*is const?*)"false"); - ("key1", "AES_KEY*", (*is const?*)"true"); - ("key2", "AES_KEY*", (*is const?*)"true"); + ("key1", "s2n_bignum_AES_KEY*", (*is const?*)"true"); + ("key2", "s2n_bignum_AES_KEY*", (*is const?*)"true"); ("iv", "uint8_t[16]", (*is const?*)"true"); ], "void", diff --git a/benchmarks/benchmark.c b/benchmarks/benchmark.c index 0c7b8442c..e9b3bc38c 100644 --- a/benchmarks/benchmark.c +++ b/benchmarks/benchmark.c @@ -50,7 +50,7 @@ static uint64_t bb[16][BUFFERSIZE]; static uint64_t bigbuff[100000]; // AES keys for XTS mode testing -static AES_KEY aes_key1, aes_key2; +static s2n_bignum_AES_KEY aes_key1, aes_key2; static uint8_t aes_iv[16]; // Source of random 64-bit numbers with bit density diff --git a/include/s2n-bignum.h b/include/s2n-bignum.h index d93371916..b553f06e9 100644 --- a/include/s2n-bignum.h +++ b/include/s2n-bignum.h @@ -30,21 +30,21 @@ #define S2N_BIGNUM_STATIC static #endif -struct aes_key_st { +struct s2n_bignum_aes_key_st { uint64_t rd_key[30]; int rounds; }; -typedef struct aes_key_st AES_KEY; +typedef struct s2n_bignum_aes_key_st s2n_bignum_AES_KEY; // AES_XTS_DECRYPT (256-bit) // Inputs in[length], length, key1[244], key2[244], iv[16]; output out[length] extern void aes_hw_xts_decrypt(const uint8_t *in, uint8_t *out, size_t length, - const AES_KEY *key1, const AES_KEY *key2, const uint8_t iv[16]); + const s2n_bignum_AES_KEY *key1, const s2n_bignum_AES_KEY *key2, const uint8_t iv[16]); // AES_XTS_ENCRYPT (256-bit) // Inputs in[length], length, key1[244], key2[244], iv[16]; output out[length] extern void aes_hw_xts_encrypt(const uint8_t *in, uint8_t *out, size_t length, - const AES_KEY *key1, const AES_KEY *key2, const uint8_t iv[16]); + const s2n_bignum_AES_KEY *key1, const s2n_bignum_AES_KEY *key2, const uint8_t iv[16]); // Add, z := x + y // Inputs x[m], y[n]; outputs function return (carry-out) and z[p] diff --git a/tests/test.c b/tests/test.c index 1be615759..eafafe19c 100644 --- a/tests/test.c +++ b/tests/test.c @@ -14913,8 +14913,8 @@ int test_known_values_xts_encrypt(void) int failures = 0, successes = 0; printf("Testing known value cases for aes-xts encrypt\n"); - AES_KEY *key1 = (AES_KEY *)malloc(sizeof(AES_KEY)); - AES_KEY *key2 = (AES_KEY *)malloc(sizeof(AES_KEY)); + s2n_bignum_AES_KEY *key1 = (s2n_bignum_AES_KEY *)malloc(sizeof(s2n_bignum_AES_KEY)); + s2n_bignum_AES_KEY *key2 = (s2n_bignum_AES_KEY *)malloc(sizeof(s2n_bignum_AES_KEY)); size_t len; uint8_t iv[16]; uint8_t in[224]; @@ -14942,8 +14942,8 @@ int test_known_values_xts_decrypt(void) int failures = 0, successes = 0; printf("Testing known value cases for aes-xts decrypt\n"); - AES_KEY *key1 = (AES_KEY *)malloc(sizeof(AES_KEY)); - AES_KEY *key2 = (AES_KEY *)malloc(sizeof(AES_KEY)); + s2n_bignum_AES_KEY *key1 = (s2n_bignum_AES_KEY *)malloc(sizeof(s2n_bignum_AES_KEY)); + s2n_bignum_AES_KEY *key2 = (s2n_bignum_AES_KEY *)malloc(sizeof(s2n_bignum_AES_KEY)); size_t len; uint8_t iv[16]; uint8_t in[224]; diff --git a/tools/collect-signatures.py b/tools/collect-signatures.py index 7cd8b0819..987ad1686 100644 --- a/tools/collect-signatures.py +++ b/tools/collect-signatures.py @@ -411,7 +411,7 @@ def checkOnlyInArch(fnname, onlyIn): arg_elem_bytesizes[argname] = 2 elif isPtrOrArray(argtype, "int8_t") or isPtrOrArray(argtype, "uint8_t"): arg_elem_bytesizes[argname] = 1 - elif isPtr(argtype, "AES_KEY"): + elif isPtr(argtype, "s2n_bignum_AES_KEY"): arg_elem_bytesizes[argname] = 1 elif "[" not in argtype and "*" not in argtype: continue From cc064b888fe396caa91c7c88f6f63e36a8ba2bdf Mon Sep 17 00:00:00 2001 From: Yan Peng Date: Tue, 23 Dec 2025 14:00:35 -0800 Subject: [PATCH 119/132] Fix benchmark platform check --- benchmarks/benchmark.c | 17 ++++++++++++++++- include/s2n-bignum-c89.h | 16 ++++++++++++++++ include/s2n-bignum.h | 4 ++-- 3 files changed, 34 insertions(+), 3 deletions(-) diff --git a/benchmarks/benchmark.c b/benchmarks/benchmark.c index e9b3bc38c..a156d902a 100644 --- a/benchmarks/benchmark.c +++ b/benchmarks/benchmark.c @@ -1120,6 +1120,20 @@ void call_sha3_keccak4_f1600(void) {} void call_sha3_keccak4_f1600_alt(void) {} void call_sha3_keccak4_f1600_alt2(void) {} +void call_aes_hw_xts_encrypt_16(void) {} +void call_aes_hw_xts_encrypt_32(void) {} +void call_aes_hw_xts_encrypt_64(void) {} +void call_aes_hw_xts_encrypt_128(void) {} +void call_aes_hw_xts_encrypt_256(void) {} +void call_aes_hw_xts_encrypt_512(void) {} + +void call_aes_hw_xts_decrypt_16(void) {} +void call_aes_hw_xts_decrypt_32(void) {} +void call_aes_hw_xts_decrypt_64(void) {} +void call_aes_hw_xts_decrypt_128(void) {} +void call_aes_hw_xts_decrypt_256(void) {} +void call_aes_hw_xts_decrypt_512(void) {} + #else void call_mldsa_ntt(void) {} @@ -1149,7 +1163,6 @@ void call_sha3_keccak4_f1600_alt2(void) repeat(sha3_keccak4_f1600_alt2(b0,b1)) void call_mlkem_frombytes(void) {} void call_mlkem_unpack(void) {} -#endif // Helper function for AES XTS encrypt with parameterized length static void aes_hw_xts_encrypt_helper(size_t len) @@ -1197,6 +1210,8 @@ void call_aes_hw_xts_decrypt_128(void) { repeat(aes_hw_xts_decrypt_helper(128)); void call_aes_hw_xts_decrypt_256(void) { repeat(aes_hw_xts_decrypt_helper(256)); } void call_aes_hw_xts_decrypt_512(void) { repeatfewer(10,aes_hw_xts_decrypt_helper(512)); } +#endif + int main(int argc, char *argv[]) { int bmi = get_arch_name() == ARCH_AARCH64 || supports_bmi2_and_adx(); diff --git a/include/s2n-bignum-c89.h b/include/s2n-bignum-c89.h index b04f068f1..8d758c8d1 100644 --- a/include/s2n-bignum-c89.h +++ b/include/s2n-bignum-c89.h @@ -25,6 +25,22 @@ * ---------------------------------------------------------------------------- */ +struct s2n_bignum_aes_key_st { + uint64_t rd_key[30]; + int rounds; +}; +typedef struct s2n_bignum_aes_key_st s2n_bignum_AES_KEY; + +/* AES_XTS_DECRYPT (256-bit) */ +/* Inputs in[length], length, key1[244], key2[244], iv[16]; output out[length] */ +extern void aes_hw_xts_decrypt(const uint8_t *in, uint8_t *out, size_t length, + const s2n_bignum_AES_KEY *key1, const s2n_bignum_AES_KEY *key2, const uint8_t iv[16]); + +/* AES_XTS_ENCRYPT (256-bit) */ +/* Inputs in[length], length, key1[244], key2[244], iv[16]; output out[length] */ +extern void aes_hw_xts_encrypt(const uint8_t *in, uint8_t *out, size_t length, + const s2n_bignum_AES_KEY *key1, const s2n_bignum_AES_KEY *key2, const uint8_t iv[16]); + /* Add, z := x + y */ /* Inputs x[m], y[n]; outputs function return (carry-out) and z[p] */ extern uint64_t bignum_add (uint64_t p, uint64_t *z, uint64_t m, const uint64_t *x, uint64_t n, const uint64_t *y); diff --git a/include/s2n-bignum.h b/include/s2n-bignum.h index b553f06e9..372388563 100644 --- a/include/s2n-bignum.h +++ b/include/s2n-bignum.h @@ -39,12 +39,12 @@ typedef struct s2n_bignum_aes_key_st s2n_bignum_AES_KEY; // AES_XTS_DECRYPT (256-bit) // Inputs in[length], length, key1[244], key2[244], iv[16]; output out[length] extern void aes_hw_xts_decrypt(const uint8_t *in, uint8_t *out, size_t length, - const s2n_bignum_AES_KEY *key1, const s2n_bignum_AES_KEY *key2, const uint8_t iv[16]); + const s2n_bignum_AES_KEY *key1, const s2n_bignum_AES_KEY *key2, const uint8_t iv[S2N_BIGNUM_STATIC 16]); // AES_XTS_ENCRYPT (256-bit) // Inputs in[length], length, key1[244], key2[244], iv[16]; output out[length] extern void aes_hw_xts_encrypt(const uint8_t *in, uint8_t *out, size_t length, - const s2n_bignum_AES_KEY *key1, const s2n_bignum_AES_KEY *key2, const uint8_t iv[16]); + const s2n_bignum_AES_KEY *key1, const s2n_bignum_AES_KEY *key2, const uint8_t iv[S2N_BIGNUM_STATIC 16]); // Add, z := x + y // Inputs x[m], y[n]; outputs function return (carry-out) and z[p] From f34f3b164402070dfb62df0cdd2774dea3e5fb7f Mon Sep 17 00:00:00 2001 From: Yan Peng Date: Tue, 23 Dec 2025 14:20:48 -0800 Subject: [PATCH 120/132] Add sematest for strb shifted register no shift --- arm/proofs/simulator_iclasses.ml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arm/proofs/simulator_iclasses.ml b/arm/proofs/simulator_iclasses.ml index 1eec355f4..629c9b7fb 100644 --- a/arm/proofs/simulator_iclasses.ml +++ b/arm/proofs/simulator_iclasses.ml @@ -450,8 +450,8 @@ let check_insns () = "00111000010xxxxxxxxx11xxxxxxxxxx"; "0011100101xxxxxxxxxxxxxxxxxxxxxx"; - (*** ldrb (shifted register, no shift S = 0) ***) - "00111000011xxxxxxxx010xxxxxxxxxx"; + (*** ldrb / strb (shifted register, no shift S = 0) ***) + "001110000x1xxxxxxxx010xxxxxxxxxx"; (*** ld1 (1 register, Post-immediate offset) ***) "0x001100110111110111xxxxxxxxxxxx"; From 3e4f5147e3970729a02e4fef37078baf0ebddc82 Mon Sep 17 00:00:00 2001 From: Yan Peng Date: Tue, 23 Dec 2025 14:24:25 -0800 Subject: [PATCH 121/132] Update signature --- arm/aes-xts/aes_hw_xts_decrypt.S | 2 +- arm/aes-xts/aes_hw_xts_encrypt.S | 2 +- arm/proofs/subroutine_signatures.ml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/arm/aes-xts/aes_hw_xts_decrypt.S b/arm/aes-xts/aes_hw_xts_decrypt.S index ad415b9b9..deea2e2d7 100644 --- a/arm/aes-xts/aes_hw_xts_decrypt.S +++ b/arm/aes-xts/aes_hw_xts_decrypt.S @@ -9,7 +9,7 @@ // size_t length, // const s2n_bignum_AES_KEY *key1, // const s2n_bignum_AES_KEY *key2, -// const uint8_t iv[16]); +// const uint8_t iv[static 16]); // // Standard ARM ABI: X0 = in, X1 = out, X2 = length, X3 = key1, X4 = key2, X5 = iv // ---------------------------------------------------------------------------- diff --git a/arm/aes-xts/aes_hw_xts_encrypt.S b/arm/aes-xts/aes_hw_xts_encrypt.S index 50bf92f68..01db56de4 100644 --- a/arm/aes-xts/aes_hw_xts_encrypt.S +++ b/arm/aes-xts/aes_hw_xts_encrypt.S @@ -9,7 +9,7 @@ // size_t length, // const s2n_bignum_AES_KEY *key1, // const s2n_bignum_AES_KEY *key2, -// const uint8_t iv[16]); +// const uint8_t iv[static 16]); // // Standard ARM ABI: X0 = in, X1 = out, X2 = length, X3 = key1, X4 = key2, X5 = iv // ---------------------------------------------------------------------------- diff --git a/arm/proofs/subroutine_signatures.ml b/arm/proofs/subroutine_signatures.ml index f3440a8f2..b26a4926e 100644 --- a/arm/proofs/subroutine_signatures.ml +++ b/arm/proofs/subroutine_signatures.ml @@ -6,7 +6,7 @@ let subroutine_signatures = [ ("length", "size_t", (*is const?*)"false"); ("key1", "s2n_bignum_AES_KEY*", (*is const?*)"true"); ("key2", "s2n_bignum_AES_KEY*", (*is const?*)"true"); - ("iv", "uint8_t[16]", (*is const?*)"true"); + ("iv", "uint8_t[static 16]", (*is const?*)"true"); ], "void", [(* input buffers *) @@ -29,7 +29,7 @@ let subroutine_signatures = [ ("length", "size_t", (*is const?*)"false"); ("key1", "s2n_bignum_AES_KEY*", (*is const?*)"true"); ("key2", "s2n_bignum_AES_KEY*", (*is const?*)"true"); - ("iv", "uint8_t[16]", (*is const?*)"true"); + ("iv", "uint8_t[static 16]", (*is const?*)"true"); ], "void", [(* input buffers *) From 5c072d5e51560346913aec5ede32aafb0826585c Mon Sep 17 00:00:00 2001 From: Yan Peng Date: Tue, 23 Dec 2025 14:45:38 -0800 Subject: [PATCH 122/132] Rename aes_hw_xts_encrypt to aes_xts_encrypt and similarly for decrypt --- arm/Makefile | 4 +- arm/aes-xts/Makefile | 4 +- ...aes_hw_xts_decrypt.S => aes_xts_decrypt.S} | 8 +- ...aes_hw_xts_encrypt.S => aes_xts_encrypt.S} | 8 +- arm/proofs/aes_xts_decrypt.ml | 4 +- arm/proofs/aes_xts_encrypt.ml | 6 +- arm/proofs/subroutine_signatures.ml | 4 +- benchmarks/benchmark.c | 82 +++++++++---------- include/s2n-bignum-c89.h | 4 +- include/s2n-bignum.h | 4 +- tests/known_value_tests_xts_decrypt.h | 40 ++++----- tests/known_value_tests_xts_encrypt.h | 40 ++++----- tools/collect-signatures.py | 4 +- 13 files changed, 106 insertions(+), 106 deletions(-) rename arm/aes-xts/{aes_hw_xts_decrypt.S => aes_xts_decrypt.S} (98%) rename arm/aes-xts/{aes_hw_xts_encrypt.S => aes_xts_encrypt.S} (98%) diff --git a/arm/Makefile b/arm/Makefile index ddd29a1df..28cd155e1 100644 --- a/arm/Makefile +++ b/arm/Makefile @@ -403,8 +403,8 @@ UNOPT_OBJ = p256/unopt/bignum_montmul_p256_base.o \ fastmul/unopt/bignum_mul_8_16_base.o \ fastmul/unopt/bignum_sqr_8_16_base.o -AES_XTS_OBJ = aes-xts/aes_hw_xts_decrypt.o \ - aes-xts/aes_hw_xts_encrypt.o +AES_XTS_OBJ = aes-xts/aes_xts_decrypt.o \ + aes-xts/aes_xts_encrypt.o OBJ = $(POINT_OBJ) $(BIGNUM_OBJ) $(AES_XTS_OBJ) diff --git a/arm/aes-xts/Makefile b/arm/aes-xts/Makefile index 65ed9d9a1..1c804cde2 100644 --- a/arm/aes-xts/Makefile +++ b/arm/aes-xts/Makefile @@ -28,8 +28,8 @@ endif # List of object files -OBJ = aes_hw_xts_decrypt.o \ - aes_hw_xts_encrypt.o +OBJ = aes_xts_decrypt.o \ + aes_xts_encrypt.o %.o : %.S ; $(CC) -E -I../../include $< | $(GAS) -o $@ - diff --git a/arm/aes-xts/aes_hw_xts_decrypt.S b/arm/aes-xts/aes_xts_decrypt.S similarity index 98% rename from arm/aes-xts/aes_hw_xts_decrypt.S rename to arm/aes-xts/aes_xts_decrypt.S index deea2e2d7..4f15c5202 100644 --- a/arm/aes-xts/aes_hw_xts_decrypt.S +++ b/arm/aes-xts/aes_xts_decrypt.S @@ -5,7 +5,7 @@ // AES_XTS_DECRYPT (256-bit) // Inputs in[length], length, key1[244], key2[244], iv[16]; output out[length] // -// extern void aes_hw_xts_decrypt(const uint8_t *in, uint8_t *out, +// extern void aes_xts_decrypt(const uint8_t *in, uint8_t *out, // size_t length, // const s2n_bignum_AES_KEY *key1, // const s2n_bignum_AES_KEY *key2, @@ -16,8 +16,8 @@ #include "_internal_s2n_bignum.h" .arch armv8-a+crypto - S2N_BN_SYM_VISIBILITY_DIRECTIVE(aes_hw_xts_decrypt) - S2N_BN_SYM_PRIVACY_DIRECTIVE(aes_hw_xts_decrypt) + S2N_BN_SYM_VISIBILITY_DIRECTIVE(aes_xts_decrypt) + S2N_BN_SYM_PRIVACY_DIRECTIVE(aes_xts_decrypt) .text .balign 4 @@ -75,7 +75,7 @@ umulh dst, src, dst __LF \ lsr dst, dst, #6 -S2N_BN_SYMBOL(aes_hw_xts_decrypt): +S2N_BN_SYMBOL(aes_xts_decrypt): // AARCH64_VALID_CALL_TARGET sub sp, sp, #STACK_SIZE save_vregs diff --git a/arm/aes-xts/aes_hw_xts_encrypt.S b/arm/aes-xts/aes_xts_encrypt.S similarity index 98% rename from arm/aes-xts/aes_hw_xts_encrypt.S rename to arm/aes-xts/aes_xts_encrypt.S index 01db56de4..e46ee52f3 100644 --- a/arm/aes-xts/aes_hw_xts_encrypt.S +++ b/arm/aes-xts/aes_xts_encrypt.S @@ -5,7 +5,7 @@ // AES_XTS_ENCRYPT (256-bit) // Inputs in[length], length, key1[244], key2[244], iv[16]; output out[length] // -// extern void aes_hw_xts_encrypt(const uint8_t *in, uint8_t *out, +// extern void aes_xts_encrypt(const uint8_t *in, uint8_t *out, // size_t length, // const s2n_bignum_AES_KEY *key1, // const s2n_bignum_AES_KEY *key2, @@ -17,8 +17,8 @@ #include "_internal_s2n_bignum.h" .arch armv8-a+crypto - S2N_BN_SYM_VISIBILITY_DIRECTIVE(aes_hw_xts_encrypt) - S2N_BN_SYM_PRIVACY_DIRECTIVE(aes_hw_xts_encrypt) + S2N_BN_SYM_VISIBILITY_DIRECTIVE(aes_xts_encrypt) + S2N_BN_SYM_PRIVACY_DIRECTIVE(aes_xts_encrypt) .text .balign 4 @@ -69,7 +69,7 @@ umulh dst, src, dst __LF \ lsr dst, dst, #6 -S2N_BN_SYMBOL(aes_hw_xts_encrypt): +S2N_BN_SYMBOL(aes_xts_encrypt): # AARCH64_VALID_CALL_TARGET sub sp, sp, #STACK_SIZE diff --git a/arm/proofs/aes_xts_decrypt.ml b/arm/proofs/aes_xts_decrypt.ml index 414278b53..4817ef9e0 100644 --- a/arm/proofs/aes_xts_decrypt.ml +++ b/arm/proofs/aes_xts_decrypt.ml @@ -6,8 +6,8 @@ use_file_raise_failure := true;; needs "arm/proofs/utils/aes_xts_common.ml";; -(* print_literal_from_elf "arm/aes-xts/aes_xts_decrypt_armv8.o";; *) -let aes_xts_decrypt_mc = define_assert_from_elf "aes_xts_decrypt_mc" "arm/aes-xts/aes_xts_decrypt_armv8.o" +(* print_literal_from_elf "arm/aes-xts/aes_xts_decrypt.o";; *) +let aes_xts_decrypt_mc = define_assert_from_elf "aes_xts_decrypt_mc" "arm/aes-xts/aes_xts_decrypt.o" [ 0xd10183ff; (* arm_SUB SP SP (rvalue (word 0x60)) *) 0x6d0227e8; (* arm_STP D8 D9 SP (Immediate_Offset (iword (&0x20))) *) diff --git a/arm/proofs/aes_xts_encrypt.ml b/arm/proofs/aes_xts_encrypt.ml index d02e66589..4397ef467 100644 --- a/arm/proofs/aes_xts_encrypt.ml +++ b/arm/proofs/aes_xts_encrypt.ml @@ -6,8 +6,8 @@ use_file_raise_failure := true;; needs "arm/proofs/utils/aes_xts_common.ml";; -(* print_literal_from_elf "arm/aes-xts/aes_xts_encrypt_armv8.o";; *) -let aes256_xts_encrypt_mc = define_assert_from_elf "aes256_xts_encrypt_mc" "arm/aes-xts/aes_xts_encrypt_armv8.o" +(* print_literal_from_elf "arm/aes-xts/aes_xts_encrypt.o";; *) +let aes256_xts_encrypt_mc = define_assert_from_elf "aes256_xts_encrypt_mc" "arm/aes-xts/aes_xts_encrypt.o" [ 0xd10183ff; (* arm_SUB SP SP (rvalue (word 0x60)) *) 0x6d0227e8; (* arm_STP D8 D9 SP (Immediate_Offset (iword (&0x20))) *) @@ -3219,7 +3219,7 @@ let AES_XTS_ENCRYPT_LT_5BLOCK_CORRECT = time prove( (* -void aes_hw_xts_encrypt(const uint8_t *in, uint8_t *out, size_t length, +void aes_xts_encrypt(const uint8_t *in, uint8_t *out, size_t length, const s2n_bignum_AES_KEY *key1, const s2n_bignum_AES_KEY *key2, const uint8_t iv[16]) *) diff --git a/arm/proofs/subroutine_signatures.ml b/arm/proofs/subroutine_signatures.ml index b26a4926e..59fc6dd70 100644 --- a/arm/proofs/subroutine_signatures.ml +++ b/arm/proofs/subroutine_signatures.ml @@ -1,5 +1,5 @@ let subroutine_signatures = [ -("aes_hw_xts_decrypt", +("aes_xts_decrypt", ([(*args*) ("in", "uint8_t*", (*is const?*)"true"); ("out", "uint8_t*", (*is const?*)"false"); @@ -22,7 +22,7 @@ let subroutine_signatures = [ ]) ); -("aes_hw_xts_encrypt", +("aes_xts_encrypt", ([(*args*) ("in", "uint8_t*", (*is const?*)"true"); ("out", "uint8_t*", (*is const?*)"false"); diff --git a/benchmarks/benchmark.c b/benchmarks/benchmark.c index a156d902a..378321673 100644 --- a/benchmarks/benchmark.c +++ b/benchmarks/benchmark.c @@ -1120,19 +1120,19 @@ void call_sha3_keccak4_f1600(void) {} void call_sha3_keccak4_f1600_alt(void) {} void call_sha3_keccak4_f1600_alt2(void) {} -void call_aes_hw_xts_encrypt_16(void) {} -void call_aes_hw_xts_encrypt_32(void) {} -void call_aes_hw_xts_encrypt_64(void) {} -void call_aes_hw_xts_encrypt_128(void) {} -void call_aes_hw_xts_encrypt_256(void) {} -void call_aes_hw_xts_encrypt_512(void) {} - -void call_aes_hw_xts_decrypt_16(void) {} -void call_aes_hw_xts_decrypt_32(void) {} -void call_aes_hw_xts_decrypt_64(void) {} -void call_aes_hw_xts_decrypt_128(void) {} -void call_aes_hw_xts_decrypt_256(void) {} -void call_aes_hw_xts_decrypt_512(void) {} +void call_aes_xts_encrypt_16(void) {} +void call_aes_xts_encrypt_32(void) {} +void call_aes_xts_encrypt_64(void) {} +void call_aes_xts_encrypt_128(void) {} +void call_aes_xts_encrypt_256(void) {} +void call_aes_xts_encrypt_512(void) {} + +void call_aes_xts_decrypt_16(void) {} +void call_aes_xts_decrypt_32(void) {} +void call_aes_xts_decrypt_64(void) {} +void call_aes_xts_decrypt_128(void) {} +void call_aes_xts_decrypt_256(void) {} +void call_aes_xts_decrypt_512(void) {} #else @@ -1165,7 +1165,7 @@ void call_mlkem_frombytes(void) {} void call_mlkem_unpack(void) {} // Helper function for AES XTS encrypt with parameterized length -static void aes_hw_xts_encrypt_helper(size_t len) +static void aes_xts_encrypt_helper(size_t len) { int j; for (j = 0; j < 30; ++j) { @@ -1176,19 +1176,19 @@ static void aes_hw_xts_encrypt_helper(size_t len) aes_key2.rounds = 14; for (j = 0; j < 16; ++j) aes_iv[j] = (uint8_t)(b3[j] & 0xFF); - aes_hw_xts_encrypt((uint8_t*)b0, (uint8_t*)b1, len, &aes_key1, &aes_key2, aes_iv); + aes_xts_encrypt((uint8_t*)b0, (uint8_t*)b1, len, &aes_key1, &aes_key2, aes_iv); } // AES XTS encrypt wrapper functions for different block sizes -void call_aes_hw_xts_encrypt_16(void) { repeat(aes_hw_xts_encrypt_helper(16)); } -void call_aes_hw_xts_encrypt_32(void) { repeat(aes_hw_xts_encrypt_helper(32)); } -void call_aes_hw_xts_encrypt_64(void) { repeat(aes_hw_xts_encrypt_helper(64)); } -void call_aes_hw_xts_encrypt_128(void) { repeat(aes_hw_xts_encrypt_helper(128)); } -void call_aes_hw_xts_encrypt_256(void) { repeat(aes_hw_xts_encrypt_helper(256)); } -void call_aes_hw_xts_encrypt_512(void) { repeatfewer(10,aes_hw_xts_encrypt_helper(512)); } +void call_aes_xts_encrypt_16(void) { repeat(aes_xts_encrypt_helper(16)); } +void call_aes_xts_encrypt_32(void) { repeat(aes_xts_encrypt_helper(32)); } +void call_aes_xts_encrypt_64(void) { repeat(aes_xts_encrypt_helper(64)); } +void call_aes_xts_encrypt_128(void) { repeat(aes_xts_encrypt_helper(128)); } +void call_aes_xts_encrypt_256(void) { repeat(aes_xts_encrypt_helper(256)); } +void call_aes_xts_encrypt_512(void) { repeatfewer(10,aes_xts_encrypt_helper(512)); } // Helper function for AES XTS decrypt with parameterized length -static void aes_hw_xts_decrypt_helper(size_t len) +static void aes_xts_decrypt_helper(size_t len) { int j; for (j = 0; j < 30; ++j) { @@ -1199,16 +1199,16 @@ static void aes_hw_xts_decrypt_helper(size_t len) aes_key2.rounds = 14; for (j = 0; j < 16; ++j) aes_iv[j] = (uint8_t)(b3[j] & 0xFF); - aes_hw_xts_decrypt((uint8_t*)b0, (uint8_t*)b1, len, &aes_key1, &aes_key2, aes_iv); + aes_xts_decrypt((uint8_t*)b0, (uint8_t*)b1, len, &aes_key1, &aes_key2, aes_iv); } // AES XTS decrypt wrapper functions for different block sizes -void call_aes_hw_xts_decrypt_16(void) { repeat(aes_hw_xts_decrypt_helper(16)); } -void call_aes_hw_xts_decrypt_32(void) { repeat(aes_hw_xts_decrypt_helper(32)); } -void call_aes_hw_xts_decrypt_64(void) { repeat(aes_hw_xts_decrypt_helper(64)); } -void call_aes_hw_xts_decrypt_128(void) { repeat(aes_hw_xts_decrypt_helper(128)); } -void call_aes_hw_xts_decrypt_256(void) { repeat(aes_hw_xts_decrypt_helper(256)); } -void call_aes_hw_xts_decrypt_512(void) { repeatfewer(10,aes_hw_xts_decrypt_helper(512)); } +void call_aes_xts_decrypt_16(void) { repeat(aes_xts_decrypt_helper(16)); } +void call_aes_xts_decrypt_32(void) { repeat(aes_xts_decrypt_helper(32)); } +void call_aes_xts_decrypt_64(void) { repeat(aes_xts_decrypt_helper(64)); } +void call_aes_xts_decrypt_128(void) { repeat(aes_xts_decrypt_helper(128)); } +void call_aes_xts_decrypt_256(void) { repeat(aes_xts_decrypt_helper(256)); } +void call_aes_xts_decrypt_512(void) { repeatfewer(10,aes_xts_decrypt_helper(512)); } #endif @@ -1669,18 +1669,18 @@ int main(int argc, char *argv[]) timingtest(all,"word_negmodinv",call_word_negmodinv); timingtest(all,"word_popcount",call_word_popcount); timingtest(all,"word_recip",call_word_recip); - timingtest(aes,"aes_hw_xts_encrypt (16 bytes)",call_aes_hw_xts_encrypt_16); - timingtest(aes,"aes_hw_xts_encrypt (32 bytes)",call_aes_hw_xts_encrypt_32); - timingtest(aes,"aes_hw_xts_encrypt (64 bytes)",call_aes_hw_xts_encrypt_64); - timingtest(aes,"aes_hw_xts_encrypt (128 bytes)",call_aes_hw_xts_encrypt_128); - timingtest(aes,"aes_hw_xts_encrypt (256 bytes)",call_aes_hw_xts_encrypt_256); - timingtest(aes,"aes_hw_xts_encrypt (512 bytes)",call_aes_hw_xts_encrypt_512); - timingtest(aes,"aes_hw_xts_decrypt (16 bytes)",call_aes_hw_xts_decrypt_16); - timingtest(aes,"aes_hw_xts_decrypt (32 bytes)",call_aes_hw_xts_decrypt_32); - timingtest(aes,"aes_hw_xts_decrypt (64 bytes)",call_aes_hw_xts_decrypt_64); - timingtest(aes,"aes_hw_xts_decrypt (128 bytes)",call_aes_hw_xts_decrypt_128); - timingtest(aes,"aes_hw_xts_decrypt (256 bytes)",call_aes_hw_xts_decrypt_256); - timingtest(aes,"aes_hw_xts_decrypt (512 bytes)",call_aes_hw_xts_decrypt_512); + timingtest(aes,"aes_xts_encrypt (16 bytes)",call_aes_xts_encrypt_16); + timingtest(aes,"aes_xts_encrypt (32 bytes)",call_aes_xts_encrypt_32); + timingtest(aes,"aes_xts_encrypt (64 bytes)",call_aes_xts_encrypt_64); + timingtest(aes,"aes_xts_encrypt (128 bytes)",call_aes_xts_encrypt_128); + timingtest(aes,"aes_xts_encrypt (256 bytes)",call_aes_xts_encrypt_256); + timingtest(aes,"aes_xts_encrypt (512 bytes)",call_aes_xts_encrypt_512); + timingtest(aes,"aes_xts_decrypt (16 bytes)",call_aes_xts_decrypt_16); + timingtest(aes,"aes_xts_decrypt (32 bytes)",call_aes_xts_decrypt_32); + timingtest(aes,"aes_xts_decrypt (64 bytes)",call_aes_xts_decrypt_64); + timingtest(aes,"aes_xts_decrypt (128 bytes)",call_aes_xts_decrypt_128); + timingtest(aes,"aes_xts_decrypt (256 bytes)",call_aes_xts_decrypt_256); + timingtest(aes,"aes_xts_decrypt (512 bytes)",call_aes_xts_decrypt_512); // Summarize performance in arithmetic and geometric means diff --git a/include/s2n-bignum-c89.h b/include/s2n-bignum-c89.h index 8d758c8d1..96cc2f413 100644 --- a/include/s2n-bignum-c89.h +++ b/include/s2n-bignum-c89.h @@ -33,12 +33,12 @@ typedef struct s2n_bignum_aes_key_st s2n_bignum_AES_KEY; /* AES_XTS_DECRYPT (256-bit) */ /* Inputs in[length], length, key1[244], key2[244], iv[16]; output out[length] */ -extern void aes_hw_xts_decrypt(const uint8_t *in, uint8_t *out, size_t length, +extern void aes_xts_decrypt(const uint8_t *in, uint8_t *out, size_t length, const s2n_bignum_AES_KEY *key1, const s2n_bignum_AES_KEY *key2, const uint8_t iv[16]); /* AES_XTS_ENCRYPT (256-bit) */ /* Inputs in[length], length, key1[244], key2[244], iv[16]; output out[length] */ -extern void aes_hw_xts_encrypt(const uint8_t *in, uint8_t *out, size_t length, +extern void aes_xts_encrypt(const uint8_t *in, uint8_t *out, size_t length, const s2n_bignum_AES_KEY *key1, const s2n_bignum_AES_KEY *key2, const uint8_t iv[16]); /* Add, z := x + y */ diff --git a/include/s2n-bignum.h b/include/s2n-bignum.h index 372388563..613e21ca2 100644 --- a/include/s2n-bignum.h +++ b/include/s2n-bignum.h @@ -38,12 +38,12 @@ typedef struct s2n_bignum_aes_key_st s2n_bignum_AES_KEY; // AES_XTS_DECRYPT (256-bit) // Inputs in[length], length, key1[244], key2[244], iv[16]; output out[length] -extern void aes_hw_xts_decrypt(const uint8_t *in, uint8_t *out, size_t length, +extern void aes_xts_decrypt(const uint8_t *in, uint8_t *out, size_t length, const s2n_bignum_AES_KEY *key1, const s2n_bignum_AES_KEY *key2, const uint8_t iv[S2N_BIGNUM_STATIC 16]); // AES_XTS_ENCRYPT (256-bit) // Inputs in[length], length, key1[244], key2[244], iv[16]; output out[length] -extern void aes_hw_xts_encrypt(const uint8_t *in, uint8_t *out, size_t length, +extern void aes_xts_encrypt(const uint8_t *in, uint8_t *out, size_t length, const s2n_bignum_AES_KEY *key1, const s2n_bignum_AES_KEY *key2, const uint8_t iv[S2N_BIGNUM_STATIC 16]); // Add, z := x + y diff --git a/tests/known_value_tests_xts_decrypt.h b/tests/known_value_tests_xts_decrypt.h index ff16efa79..0a5e01243 100644 --- a/tests/known_value_tests_xts_decrypt.h +++ b/tests/known_value_tests_xts_decrypt.h @@ -78,7 +78,7 @@ len = 16; ASSIGNHEX(res, "000102030405060708090a0b0c0d0e0f", len); ASSIGNHEX(in, "c30ca8f2ed57307edc87e544867ac888", len); ASSIGNZERO(out, len); -aes_hw_xts_decrypt(in,out,len,key1,key2,iv); +aes_xts_decrypt(in,out,len,key1,key2,iv); CHECKHEX(out,res,0,len); // 1block + 1byte = 17 bytes @@ -86,7 +86,7 @@ len = 17; ASSIGNHEX(res, "000102030405060708090a0b0c0d0e0f10", len); ASSIGNHEX(in, "7f117752cc598a8b0d81d88af9f9bec8c3", len); ASSIGNZERO(out, len); -aes_hw_xts_decrypt(in,out,len,key1,key2,iv); +aes_xts_decrypt(in,out,len,key1,key2,iv); CHECKHEX(out,res,0,len); // 1block + 6byte = 22 bytes @@ -94,7 +94,7 @@ len = 22; ASSIGNHEX(res, "000102030405060708090a0b0c0d0e0f101112131415", len); ASSIGNHEX(in, "75e8188bcce59ada939f57de2cb9a489c30ca8f2ed57", len); ASSIGNZERO(out, len); -aes_hw_xts_decrypt(in,out,len,key1,key2,iv); +aes_xts_decrypt(in,out,len,key1,key2,iv); CHECKHEX(out,res,0,len); // 1bock + 15bytes = 31 bytes @@ -102,7 +102,7 @@ len = 31; ASSIGNHEX(res, "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e", len); ASSIGNHEX(in, "581ea1fee5516ad432ddebe75fd27c6fc30ca8f2ed57307edc87e544867ac8", len); ASSIGNZERO(out, len); -aes_hw_xts_decrypt(in,out,len,key1,key2,iv); +aes_xts_decrypt(in,out,len,key1,key2,iv); CHECKHEX(out,res,0,len); // 3 blocks + 3 bytes @@ -112,7 +112,7 @@ ASSIGNHEX(res, "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f ASSIGNHEX(in, "c30ca8f2ed57307edc87e544867ac888348c208928d7406269954551cb627b5b" "bea47768aa25376e924cce6a102ca2e4e1c241", len); ASSIGNZERO(out, len); -aes_hw_xts_decrypt(in,out,len,key1,key2,iv); +aes_xts_decrypt(in,out,len,key1,key2,iv); CHECKHEX(out,res,0,len); // 4 blocks @@ -122,7 +122,7 @@ ASSIGNHEX(res, "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f ASSIGNHEX(in, "c30ca8f2ed57307edc87e544867ac888348c208928d7406269954551cb627b5b" "e1c241d0ff691de6b47ad81eac2b925b474e1fd14311edb95219ce64677f497b", len); ASSIGNZERO(out, len); -aes_hw_xts_decrypt(in,out,len,key1,key2,iv); +aes_xts_decrypt(in,out,len,key1,key2,iv); CHECKHEX(out,res,0,len); // 4blocks + 10 bytes = 74 bytes @@ -134,7 +134,7 @@ ASSIGNHEX(in, "c30ca8f2ed57307edc87e544867ac888348c208928d7406269954551cb627b5b" "e1c241d0ff691de6b47ad81eac2b925b0f451eb8847b98d48b1407f64a4f9ee3" "474e1fd14311edb95219", len); ASSIGNZERO(out, len); -aes_hw_xts_decrypt(in,out,len,key1,key2,iv); +aes_xts_decrypt(in,out,len,key1,key2,iv); CHECKHEX(out,res,0,len); // 5 blocks @@ -146,7 +146,7 @@ ASSIGNHEX(in, "c30ca8f2ed57307edc87e544867ac888348c208928d7406269954551cb627b5b" "e1c241d0ff691de6b47ad81eac2b925b474e1fd14311edb95219ce64677f497b" "8917567652e9b4ef3838baf35e400fe1", len); ASSIGNZERO(out, len); -aes_hw_xts_decrypt(in,out,len,key1,key2,iv); +aes_xts_decrypt(in,out,len,key1,key2,iv); CHECKHEX(out,res,0,len); // 5blocks + 7bytes = 87 bytes @@ -158,7 +158,7 @@ ASSIGNHEX(in, "c30ca8f2ed57307edc87e544867ac888348c208928d7406269954551cb627b5b" "e1c241d0ff691de6b47ad81eac2b925b474e1fd14311edb95219ce64677f497b" "a436b967e79bb8e8e4c29d1099fe1bbf8917567652e9b4", len); ASSIGNZERO(out, len); -aes_hw_xts_decrypt(in,out,len,key1,key2,iv); +aes_xts_decrypt(in,out,len,key1,key2,iv); CHECKHEX(out,res,0,len); // 6 blocks @@ -172,7 +172,7 @@ ASSIGNHEX(in, "e1c241d0ff691de6b47ad81eac2b925b474e1fd14311edb95219ce64677f497b" "8917567652e9b4ef3838baf35e400fe1ffe2f16cfa1900d7ae2b67f0e6f43b71", len); ASSIGNZERO(out, len); -aes_hw_xts_decrypt(in,out,len,key1,key2,iv); +aes_xts_decrypt(in,out,len,key1,key2,iv); CHECKHEX(out,res,0,len); // 6blocks + 4bytes = 100 bytes @@ -188,7 +188,7 @@ ASSIGNHEX(in, "8917567652e9b4ef3838baf35e400fe1aad32ff4d83b0af3f6a176025bd1321b" "ffe2f16c", len); ASSIGNZERO(out, len); -aes_hw_xts_decrypt(in,out,len,key1,key2,iv); +aes_xts_decrypt(in,out,len,key1,key2,iv); CHECKHEX(out,res,0,len); // 8 blocks @@ -204,7 +204,7 @@ ASSIGNHEX(in, "8917567652e9b4ef3838baf35e400fe1ffe2f16cfa1900d7ae2b67f0e6f43b71" "769d1b0e0c0b99ea11de58fcd3b72e1bce3d9a8750b87e945d77f4dc39d73b04", len); ASSIGNZERO(out, len); -aes_hw_xts_decrypt(in,out,len,key1,key2,iv); +aes_xts_decrypt(in,out,len,key1,key2,iv); CHECKHEX(out,res,0,len); // 8blocks + 6 bytes = 134 bytes @@ -222,7 +222,7 @@ ASSIGNHEX(in, "769d1b0e0c0b99ea11de58fcd3b72e1be0ad32884698e15420e52c96b698bba1" "ce3d9a8750b8", len); ASSIGNZERO(out, len); -aes_hw_xts_decrypt(in,out,len,key1,key2,iv); +aes_xts_decrypt(in,out,len,key1,key2,iv); CHECKHEX(out,res,0,len); // 9 blocks = 144 bytes @@ -240,7 +240,7 @@ ASSIGNHEX(in, "769d1b0e0c0b99ea11de58fcd3b72e1bce3d9a8750b87e945d77f4dc39d73b04" "e11b6adce343e1f38c6a879463c080d7", len); ASSIGNZERO(out, len); -aes_hw_xts_decrypt(in,out,len,key1,key2,iv); +aes_xts_decrypt(in,out,len,key1,key2,iv); CHECKHEX(out,res,0,len); // 9blocks + 14bytes = 158bytes @@ -258,7 +258,7 @@ ASSIGNHEX(in, "769d1b0e0c0b99ea11de58fcd3b72e1bce3d9a8750b87e945d77f4dc39d73b04" "a5da920d96beb388ade417027054dbd0e11b6adce343e1f38c6a879463c0", len); ASSIGNZERO(out, len); -aes_hw_xts_decrypt(in,out,len,key1,key2,iv); +aes_xts_decrypt(in,out,len,key1,key2,iv); CHECKHEX(out,res,0,len); // 10blocks = 160bytes @@ -276,7 +276,7 @@ ASSIGNHEX(in, "769d1b0e0c0b99ea11de58fcd3b72e1bce3d9a8750b87e945d77f4dc39d73b04" "e11b6adce343e1f38c6a879463c080d74a72a90b1e6fe46b7bc95a929f79947e", len); ASSIGNZERO(out, len); -aes_hw_xts_decrypt(in,out,len,key1,key2,iv); +aes_xts_decrypt(in,out,len,key1,key2,iv); CHECKHEX(out,res,0,len); // 10blocks + 5bytes = 165bytes @@ -296,7 +296,7 @@ ASSIGNHEX(in, "e11b6adce343e1f38c6a879463c080d7254c4d65cf40e04934108bcde6bda824" "4a72a90b1e", len); ASSIGNZERO(out, len); -aes_hw_xts_decrypt(in,out,len,key1,key2,iv); +aes_xts_decrypt(in,out,len,key1,key2,iv); CHECKHEX(out,res,0,len); // 11 blocks = 176 bytes @@ -316,7 +316,7 @@ ASSIGNHEX(in, "e11b6adce343e1f38c6a879463c080d74a72a90b1e6fe46b7bc95a929f79947e" "ae8cc61cbb5f8cbd0c6f052e95ed6539", len); ASSIGNZERO(out, len); -aes_hw_xts_decrypt(in,out,len,key1,key2,iv); +aes_xts_decrypt(in,out,len,key1,key2,iv); CHECKHEX(out,res,0,len); // 11 blocks + 9 bytes = 185bytes @@ -336,7 +336,7 @@ ASSIGNHEX(in, "e11b6adce343e1f38c6a879463c080d74a72a90b1e6fe46b7bc95a929f79947e" "3ed782ad26e98e07f14d47f3c2a8e92aae8cc61cbb5f8cbd0c", len); ASSIGNZERO(out, len); -aes_hw_xts_decrypt(in,out,len,key1,key2,iv); +aes_xts_decrypt(in,out,len,key1,key2,iv); CHECKHEX(out,res,0,len); // 14 blocks @@ -358,5 +358,5 @@ ASSIGNHEX(in, "ae8cc61cbb5f8cbd0c6f052e95ed65399009f56148fc07d88c8e0113d7eafb1f" "ea39991882130ee45e95a3c6bc508f09c990add0cd3f1ca3403c096f9277e785", len); ASSIGNZERO(out, len); -aes_hw_xts_decrypt(in,out,len,key1,key2,iv); +aes_xts_decrypt(in,out,len,key1,key2,iv); CHECKHEX(out,res,0,len); diff --git a/tests/known_value_tests_xts_encrypt.h b/tests/known_value_tests_xts_encrypt.h index abb4377df..d22f74ad7 100644 --- a/tests/known_value_tests_xts_encrypt.h +++ b/tests/known_value_tests_xts_encrypt.h @@ -78,7 +78,7 @@ len = 16; ASSIGNHEX(in, "000102030405060708090a0b0c0d0e0f", len); ASSIGNHEX(res, "c30ca8f2ed57307edc87e544867ac888", len); ASSIGNZERO(out, len); -aes_hw_xts_encrypt(in,out,len,key1,key2,iv); +aes_xts_encrypt(in,out,len,key1,key2,iv); CHECKHEX(out,res,0,len); // 1block + 1byte = 17 bytes @@ -86,7 +86,7 @@ len = 17; ASSIGNHEX(in, "000102030405060708090a0b0c0d0e0f10", len); ASSIGNHEX(res, "7f117752cc598a8b0d81d88af9f9bec8c3", len); ASSIGNZERO(out, len); -aes_hw_xts_encrypt(in,out,len,key1,key2,iv); +aes_xts_encrypt(in,out,len,key1,key2,iv); CHECKHEX(out,res,0,len); // 1block + 6byte = 22 bytes @@ -94,7 +94,7 @@ len = 22; ASSIGNHEX(in, "000102030405060708090a0b0c0d0e0f101112131415", len); ASSIGNHEX(res, "75e8188bcce59ada939f57de2cb9a489c30ca8f2ed57", len); ASSIGNZERO(out, len); -aes_hw_xts_encrypt(in,out,len,key1,key2,iv); +aes_xts_encrypt(in,out,len,key1,key2,iv); CHECKHEX(out,res,0,len); // 1bock + 15bytes = 31 bytes @@ -102,7 +102,7 @@ len = 31; ASSIGNHEX(in, "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e", len); ASSIGNHEX(res, "581ea1fee5516ad432ddebe75fd27c6fc30ca8f2ed57307edc87e544867ac8", len); ASSIGNZERO(out, len); -aes_hw_xts_encrypt(in,out,len,key1,key2,iv); +aes_xts_encrypt(in,out,len,key1,key2,iv); CHECKHEX(out,res,0,len); // 3 blocks + 3 bytes @@ -112,7 +112,7 @@ ASSIGNHEX(in, "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" ASSIGNHEX(res, "c30ca8f2ed57307edc87e544867ac888348c208928d7406269954551cb627b5b" "bea47768aa25376e924cce6a102ca2e4e1c241", len); ASSIGNZERO(out, len); -aes_hw_xts_encrypt(in,out,len,key1,key2,iv); +aes_xts_encrypt(in,out,len,key1,key2,iv); CHECKHEX(out,res,0,len); // 4 blocks @@ -122,7 +122,7 @@ ASSIGNHEX(in, "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" ASSIGNHEX(res, "c30ca8f2ed57307edc87e544867ac888348c208928d7406269954551cb627b5b" "e1c241d0ff691de6b47ad81eac2b925b474e1fd14311edb95219ce64677f497b", len); ASSIGNZERO(out, len); -aes_hw_xts_encrypt(in,out,len,key1,key2,iv); +aes_xts_encrypt(in,out,len,key1,key2,iv); CHECKHEX(out,res,0,len); // 4blocks + 10 bytes = 74 bytes @@ -134,7 +134,7 @@ ASSIGNHEX(res, "c30ca8f2ed57307edc87e544867ac888348c208928d7406269954551cb627b5b "e1c241d0ff691de6b47ad81eac2b925b0f451eb8847b98d48b1407f64a4f9ee3" "474e1fd14311edb95219", len); ASSIGNZERO(out, len); -aes_hw_xts_encrypt(in,out,len,key1,key2,iv); +aes_xts_encrypt(in,out,len,key1,key2,iv); CHECKHEX(out,res,0,len); // 5 blocks @@ -146,7 +146,7 @@ ASSIGNHEX(res, "c30ca8f2ed57307edc87e544867ac888348c208928d7406269954551cb627b5b "e1c241d0ff691de6b47ad81eac2b925b474e1fd14311edb95219ce64677f497b" "8917567652e9b4ef3838baf35e400fe1", len); ASSIGNZERO(out, len); -aes_hw_xts_encrypt(in,out,len,key1,key2,iv); +aes_xts_encrypt(in,out,len,key1,key2,iv); CHECKHEX(out,res,0,len); // 5blocks + 7bytes = 87 bytes @@ -158,7 +158,7 @@ ASSIGNHEX(res, "c30ca8f2ed57307edc87e544867ac888348c208928d7406269954551cb627b5b "e1c241d0ff691de6b47ad81eac2b925b474e1fd14311edb95219ce64677f497b" "a436b967e79bb8e8e4c29d1099fe1bbf8917567652e9b4", len); ASSIGNZERO(out, len); -aes_hw_xts_encrypt(in,out,len,key1,key2,iv); +aes_xts_encrypt(in,out,len,key1,key2,iv); CHECKHEX(out,res,0,len); // 6 blocks @@ -172,7 +172,7 @@ ASSIGNHEX(res, "e1c241d0ff691de6b47ad81eac2b925b474e1fd14311edb95219ce64677f497b" "8917567652e9b4ef3838baf35e400fe1ffe2f16cfa1900d7ae2b67f0e6f43b71", len); ASSIGNZERO(out, len); -aes_hw_xts_encrypt(in,out,len,key1,key2,iv); +aes_xts_encrypt(in,out,len,key1,key2,iv); CHECKHEX(out,res,0,len); // 6blocks + 4bytes = 100 bytes @@ -188,7 +188,7 @@ ASSIGNHEX(res, "8917567652e9b4ef3838baf35e400fe1aad32ff4d83b0af3f6a176025bd1321b" "ffe2f16c", len); ASSIGNZERO(out, len); -aes_hw_xts_encrypt(in,out,len,key1,key2,iv); +aes_xts_encrypt(in,out,len,key1,key2,iv); CHECKHEX(out,res,0,len); // 8 blocks @@ -204,7 +204,7 @@ ASSIGNHEX(res, "8917567652e9b4ef3838baf35e400fe1ffe2f16cfa1900d7ae2b67f0e6f43b71" "769d1b0e0c0b99ea11de58fcd3b72e1bce3d9a8750b87e945d77f4dc39d73b04", len); ASSIGNZERO(out, len); -aes_hw_xts_encrypt(in,out,len,key1,key2,iv); +aes_xts_encrypt(in,out,len,key1,key2,iv); CHECKHEX(out,res,0,len); // 8blocks + 6 bytes = 134 bytes @@ -222,7 +222,7 @@ ASSIGNHEX(res, "769d1b0e0c0b99ea11de58fcd3b72e1be0ad32884698e15420e52c96b698bba1" "ce3d9a8750b8", len); ASSIGNZERO(out, len); -aes_hw_xts_encrypt(in,out,len,key1,key2,iv); +aes_xts_encrypt(in,out,len,key1,key2,iv); CHECKHEX(out,res,0,len); // 9 blocks = 144 bytes @@ -240,7 +240,7 @@ ASSIGNHEX(res, "769d1b0e0c0b99ea11de58fcd3b72e1bce3d9a8750b87e945d77f4dc39d73b04" "e11b6adce343e1f38c6a879463c080d7", len); ASSIGNZERO(out, len); -aes_hw_xts_encrypt(in,out,len,key1,key2,iv); +aes_xts_encrypt(in,out,len,key1,key2,iv); CHECKHEX(out,res,0,len); // 9blocks + 14bytes = 158bytes @@ -258,7 +258,7 @@ ASSIGNHEX(res, "769d1b0e0c0b99ea11de58fcd3b72e1bce3d9a8750b87e945d77f4dc39d73b04" "a5da920d96beb388ade417027054dbd0e11b6adce343e1f38c6a879463c0", len); ASSIGNZERO(out, len); -aes_hw_xts_encrypt(in,out,len,key1,key2,iv); +aes_xts_encrypt(in,out,len,key1,key2,iv); CHECKHEX(out,res,0,len); // 10blocks = 160bytes @@ -276,7 +276,7 @@ ASSIGNHEX(res, "769d1b0e0c0b99ea11de58fcd3b72e1bce3d9a8750b87e945d77f4dc39d73b04" "e11b6adce343e1f38c6a879463c080d74a72a90b1e6fe46b7bc95a929f79947e", len); ASSIGNZERO(out, len); -aes_hw_xts_encrypt(in,out,len,key1,key2,iv); +aes_xts_encrypt(in,out,len,key1,key2,iv); CHECKHEX(out,res,0,len); // 10blocks + 5bytes = 165bytes @@ -296,7 +296,7 @@ ASSIGNHEX(res, "e11b6adce343e1f38c6a879463c080d7254c4d65cf40e04934108bcde6bda824" "4a72a90b1e", len); ASSIGNZERO(out, len); -aes_hw_xts_encrypt(in,out,len,key1,key2,iv); +aes_xts_encrypt(in,out,len,key1,key2,iv); CHECKHEX(out,res,0,len); // 11 blocks = 176 bytes @@ -316,7 +316,7 @@ ASSIGNHEX(res, "e11b6adce343e1f38c6a879463c080d74a72a90b1e6fe46b7bc95a929f79947e" "ae8cc61cbb5f8cbd0c6f052e95ed6539", len); ASSIGNZERO(out, len); -aes_hw_xts_encrypt(in,out,len,key1,key2,iv); +aes_xts_encrypt(in,out,len,key1,key2,iv); CHECKHEX(out,res,0,len); // 11 blocks + 9 bytes = 185bytes @@ -336,7 +336,7 @@ ASSIGNHEX(res, "e11b6adce343e1f38c6a879463c080d74a72a90b1e6fe46b7bc95a929f79947e" "3ed782ad26e98e07f14d47f3c2a8e92aae8cc61cbb5f8cbd0c", len); ASSIGNZERO(out, len); -aes_hw_xts_encrypt(in,out,len,key1,key2,iv); +aes_xts_encrypt(in,out,len,key1,key2,iv); CHECKHEX(out,res,0,len); // 14 blocks @@ -358,5 +358,5 @@ ASSIGNHEX(res, "ae8cc61cbb5f8cbd0c6f052e95ed65399009f56148fc07d88c8e0113d7eafb1f" "ea39991882130ee45e95a3c6bc508f09c990add0cd3f1ca3403c096f9277e785", len); ASSIGNZERO(out, len); -aes_hw_xts_encrypt(in,out,len,key1,key2,iv); +aes_xts_encrypt(in,out,len,key1,key2,iv); CHECKHEX(out,res,0,len); diff --git a/tools/collect-signatures.py b/tools/collect-signatures.py index 987ad1686..e7debcfdc 100644 --- a/tools/collect-signatures.py +++ b/tools/collect-signatures.py @@ -295,8 +295,8 @@ def stripPrefixes(s, prefixes): # A list of functions that are either only in arm or x86 onlyInArm = [ - "aes_hw_xts_decrypt", - "aes_hw_xts_encrypt", + "aes_xts_decrypt", + "aes_xts_encrypt", "bignum_copy_row_from_table_8n", "bignum_copy_row_from_table_16", "bignum_copy_row_from_table_32", From 32349ca35b3b1361b963f1c49f57397d7b787271 Mon Sep 17 00:00:00 2001 From: Nevine Ebeid Date: Fri, 16 Jan 2026 12:18:33 -0500 Subject: [PATCH 123/132] Added explanation to encrypt tutorial. --- arm/proofs/utils/aes_decrypt_spec.ml | 7 ++-- arm/proofs/utils/aes_encrypt_spec.ml | 6 ++- arm/tutorial/aes_encrypt.S | 6 +-- arm/tutorial/aes_encrypt.ml | 63 ++++++++++++++++++++++++---- 4 files changed, 65 insertions(+), 17 deletions(-) diff --git a/arm/proofs/utils/aes_decrypt_spec.ml b/arm/proofs/utils/aes_decrypt_spec.ml index 539470a94..620eb2631 100644 --- a/arm/proofs/utils/aes_decrypt_spec.ml +++ b/arm/proofs/utils/aes_decrypt_spec.ml @@ -2,18 +2,19 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT-0 *) +(* ====================================================================================== *) +(* AES-256 decryption spec https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.197-upd1.pdf. *) +(* ====================================================================================== *) needs "common/aes.ml";; (* let pp_print_num fmt tm = let n = dest_numeral tm in pp_print_string fmt (string_of_num_hex n) in -install_user_printer("pp_print_num",pp_print_num);; +install_user_printer("pp_print_num",pp_print_num);; *) (* -NIST: https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.197-upd1.pdf - procedure EQINVCIPHER(in, Nr, dw) 2: state ← in 3: state ← ADDROUNDKEY(state,dw[4 ∗Nr..4 ∗Nr +3]) diff --git a/arm/proofs/utils/aes_encrypt_spec.ml b/arm/proofs/utils/aes_encrypt_spec.ml index a6792e4ad..a480ebb88 100644 --- a/arm/proofs/utils/aes_encrypt_spec.ml +++ b/arm/proofs/utils/aes_encrypt_spec.ml @@ -2,13 +2,15 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT-0 *) - +(* ====================================================================================== *) +(* AES-256 encryption spec https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.197-upd1.pdf. *) +(* ====================================================================================== *) needs "common/aes.ml";; (* let pp_print_num fmt tm = let n = dest_numeral tm in pp_print_string fmt (string_of_num_hex n) in -install_user_printer("pp_print_num",pp_print_num);; +install_user_printer("pp_print_num",pp_print_num);; *) (* diff --git a/arm/tutorial/aes_encrypt.S b/arm/tutorial/aes_encrypt.S index 775da2f60..c2d977b77 100644 --- a/arm/tutorial/aes_encrypt.S +++ b/arm/tutorial/aes_encrypt.S @@ -12,11 +12,11 @@ aes_encrypt: ldr w6,[x2,#240] ld1 {v0.16b},[x2],#16 + ld1 {v1.16b},[x2],#16 ld1 {v6.16b},[x1] sub w6,w6,#2 - ld1 {v1.16b},[x2],#16 -Loop_enc_iv_enc: +Loop_enc: aese v6.16b,v0.16b aesmc v6.16b,v6.16b ld1 {v0.4s},[x2],#16 @@ -24,7 +24,7 @@ Loop_enc_iv_enc: aese v6.16b,v1.16b aesmc v6.16b,v6.16b ld1 {v1.4s},[x2],#16 - b.gt Loop_enc_iv_enc + b.gt Loop_enc aese v6.16b,v0.16b aesmc v6.16b,v6.16b diff --git a/arm/tutorial/aes_encrypt.ml b/arm/tutorial/aes_encrypt.ml index d4e00cfbe..4188842fb 100644 --- a/arm/tutorial/aes_encrypt.ml +++ b/arm/tutorial/aes_encrypt.ml @@ -4,20 +4,41 @@ *) (****************************************************************************** - An example AES encryption proof. + An AES-256 encryption proof. ******************************************************************************) needs "arm/proofs/base.ml";; needs "arm/proofs/utils/aes_encrypt_spec.ml";; -(* print_literal_from_elf "arm/aes-xts/aes256_encrypt.o";; *) -let aes256_encrypt_mc = define_assert_from_elf "aes256_encrypt_mc" "arm/tutorial/aes_encrypt.o" -[ +(* The following program performs an AES-256 encryption: + - input: 128-bit block stored in memory at address in x1 + - output: 128-bit block to be stored in memory at address in x0 + - round keys: 15 128-bit values stored starting at address in x2, k0 to k14. + After the round keys, the number of rounds is stored + at offset 240 of address in x2. This number is 14 for AES-256 (see below) + w6 is the round counter. + 2 round keys are loaded in v0 and v1 before the loop and then in the loop and + the counter is decremented by 2 in each iteration. + + The instructions AESE and AESMC form one AES round: + AESE: AESSubBytes(AESShiftRows(operand1 XOR operand2), // XOR = AddRoundKey + AESMC: AESMixColumns(operand) + The last round doesn't use AESMC, only AESE and XOR. + The output is stored at the end. + + In the specs, the first round key is used in AddRoundKey in the initialization + then 13 regular rounds, each ending with AddRoundKey, + then a last round that doesn't have MixColumns and ends with AddRoundKey + In the implementation, there are 14 rounds that start with AddRoundKey in AESE + and one last round (with no MixColumns) ending with AddRoundKey. +*) + +let aes256_encrypt_mc = define_assert_from_elf "aes256_encrypt_mc" "arm/tutorial/aes_encrypt.o" [ 0xb940f046; (* arm_LDR W6 X2 (Immediate_Offset (word 240)) *) 0x4cdf7040; (* arm_LDR Q0 X2 (Postimmediate_Offset (word 16)) *) + 0x4cdf7041; (* arm_LDR Q1 X2 (Postimmediate_Offset (word 16)) *) 0x4c407026; (* arm_LDR Q6 X1 No_Offset *) 0x510008c6; (* arm_SUB W6 W6 (rvalue (word 2)) *) - 0x4cdf7041; (* arm_LDR Q1 X2 (Postimmediate_Offset (word 16)) *) 0x4e284806; (* arm_AESE Q6 Q0 *) 0x4e2868c6; (* arm_AESMC Q6 Q6 *) 0x4cdf7840; (* arm_LDR Q0 X2 (Postimmediate_Offset (word 16)) *) @@ -34,17 +55,27 @@ let aes256_encrypt_mc = define_assert_from_elf "aes256_encrypt_mc" "arm/tutorial 0x4c007806 (* arm_STR Q6 X0 No_Offset *) ];; +(* +You can get the above OCaml list data structure from +First generating the by running at the command line under arm directory: + $ make tutorial/ +`print_literal_from_elf ""` or +`save_literal_from_elf "" ""`. +*) + let AES256_ENCRYPT_EXEC = ARM_MK_EXEC_RULE aes256_encrypt_mc;; let AES256_ENCRYPT_CORRECT = prove( - `!ciphertext plaintext key ib k0 k1 k2 k3 k4 k5 k6 k7 k8 k9 k10 k11 k12 k13 k14 pc. + `!ciphertext plaintext key pt_in k0 k1 k2 k3 k4 k5 k6 k7 k8 k9 k10 k11 k12 k13 k14 pc. nonoverlapping (word pc,LENGTH aes256_encrypt_mc) (ciphertext,16) ==> ensures arm // precondition (\s. aligned_bytes_loaded s (word pc) aes256_encrypt_mc /\ read PC s = word pc /\ + // uses the C ABI which puts the arguments in their order in registers x0 to x7. + // Here only 3 arguments are passed in. C_ARGUMENTS [ciphertext; plaintext; key] s /\ - read(memory :> bytes128 plaintext) s = ib /\ + read(memory :> bytes128 plaintext) s = pt_in /\ read(memory :> bytes32 (word_add key (word 240))) s = word 14 /\ read(memory :> bytes128 key) s = k0 /\ read(memory :> bytes128 (word_add key (word 16))) s = k1 /\ @@ -65,20 +96,34 @@ let AES256_ENCRYPT_CORRECT = prove( // postcondition (\s. read PC s = word (pc + LENGTH aes256_encrypt_mc) /\ read(memory :> bytes128 ciphertext) s = - aes256_encrypt ib + aes256_encrypt pt_in [k0; k1; k2; k3; k4; k5; k6; k7; k8; k9; k10; k11; k12; k13; k14] ) + // Registers (and memory locations) that may change after execution (MAYCHANGE [PC;X2;X6],, MAYCHANGE [Q0;Q1;Q6],, MAYCHANGE [events],, MAYCHANGE SOME_FLAGS,, MAYCHANGE [memory :> bytes128 ciphertext])`, - REWRITE_TAC[NONOVERLAPPING_CLAUSES; C_ARGUMENTS; SOME_FLAGS] THEN + + (* Convert C_ARGUMENTS to reading registers x0, x1, x2 and expand SOME_FLAGS *) + REWRITE_TAC[C_ARGUMENTS; SOME_FLAGS] THEN + + (* Find the length of the program using a Conversion *) REWRITE_TAC [(REWRITE_CONV [aes256_encrypt_mc] THENC LENGTH_CONV) `LENGTH aes256_encrypt_mc`] THEN + REPEAT STRIP_TAC THEN + (* Start symbolic execution with state 's0' *) ENSURES_INIT_TAC "s0" THEN + (* Symbolic execution of all instructions *) ARM_STEPS_TAC AES256_ENCRYPT_EXEC (1--59) THEN + (* Returned; Finalize symbolic execution. *) ENSURES_FINAL_STATE_TAC THEN + ASM_REWRITE_TAC[] THEN REWRITE_TAC [aes256_encrypt] THEN + + (* Replace the elements from the key round lists with their value *) REWRITE_TAC EL_15_128_CLAUSES THEN + + (* Expand definitions and evaluate `let` terms *) REWRITE_TAC [aes256_encrypt_round; aese; aesmc] THEN CONV_TAC (TOP_DEPTH_CONV let_CONV) THEN BITBLAST_TAC From d3035e88f01f4233624a248555a448cc99fa0ec5 Mon Sep 17 00:00:00 2001 From: Nevine Ebeid Date: Tue, 20 Jan 2026 14:31:46 -0500 Subject: [PATCH 124/132] Put AES encrypt and decrypt proofs in one file in the tutorial, with explanation. --- arm/tutorial/README.md | 3 +- arm/tutorial/aes_decrypt.S | 2 +- arm/tutorial/aes_decrypt.ml | 93 --------------- ...{aes_encrypt.ml => aes_encrypt_decrypt.ml} | 107 +++++++++++++++++- 4 files changed, 103 insertions(+), 102 deletions(-) delete mode 100644 arm/tutorial/aes_decrypt.ml rename arm/tutorial/{aes_encrypt.ml => aes_encrypt_decrypt.ml} (55%) diff --git a/arm/tutorial/README.md b/arm/tutorial/README.md index a96b4b776..55c83c962 100644 --- a/arm/tutorial/README.md +++ b/arm/tutorial/README.md @@ -14,8 +14,7 @@ To verify programs in x86, see `x86/tutorial`. 6. `bignum.ml`: Writing a specification of a program dealing with big numbers & proving it. 7. `rodata.ml`: Reading data from the read-only section. 8. `safety.ml`: Verify the safety property (constant-time and and memory-safe) -9. `aes_encrypt.ml`: Verifying a simple AES encryption program. -10. `aes_decrypt.ml`: Verifying a simple AES decryption program. +9. `aes_encrypt_decrypt.ml`: Verify AES block encryption and decryption. ### Relational reasoning diff --git a/arm/tutorial/aes_decrypt.S b/arm/tutorial/aes_decrypt.S index a2cac8c5c..8feef9fa2 100644 --- a/arm/tutorial/aes_decrypt.S +++ b/arm/tutorial/aes_decrypt.S @@ -12,9 +12,9 @@ aes_decrypt: ldr w6,[x2,#240] ld1 {v0.16b},[x2],#16 + ld1 {v1.16b},[x2],#16 ld1 {v6.16b},[x1] sub w6,w6,#2 - ld1 {v1.16b},[x2],#16 Loop_dec: aesd v6.16b,v0.16b diff --git a/arm/tutorial/aes_decrypt.ml b/arm/tutorial/aes_decrypt.ml deleted file mode 100644 index bfeea8aaf..000000000 --- a/arm/tutorial/aes_decrypt.ml +++ /dev/null @@ -1,93 +0,0 @@ -(* - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT-0 - *) - - (****************************************************************************** - An example AES decryption proof. -******************************************************************************) - -needs "arm/proofs/base.ml";; -needs "arm/proofs/utils/aes_decrypt_spec.ml";; - -(* print_literal_from_elf "arm/aes-xts/aes256_decrypt.o";; *) -let aes256_decrypt_mc = define_assert_from_elf "aes256_decrypt_mc" "arm/tutorial/aes_decrypt.o" -[ - 0xb940f046; (* arm_LDR W6 X2 (Immediate_Offset (word 0xf0)) *) - 0x4cdf7040; (* arm_LDR Q0 X2 (Postimmediate_Offset (word 0x10)) *) - 0x4c407026; (* arm_LDR Q6 X1 No_Offset *) - 0x510008c6; (* arm_SUB W6 W6 (rvalue (word 0x2)) *) - 0x4cdf7041; (* arm_LDR Q1 X2 (Postimmediate_Offset (word 0x10)) *) - 0x4e285806; (* arm_AESD Q6 Q0 *) - 0x4e2878c6; (* arm_AESIMC Q6 Q6 *) - 0x4cdf7840; (* arm_LDR Q0 X2 (Postimmediate_Offset (word 0x10)) *) - 0x710008c6; (* arm_SUBS W6 W6 (rvalue (word 0x2)) *) - 0x4e285826; (* arm_AESD Q6 Q1 *) - 0x4e2878c6; (* arm_AESIMC Q6 Q6 *) - 0x4cdf7841; (* arm_LDR Q1 X2 (Postimmediate_Offset (word 0x10)) *) - 0x54ffff2c; (* arm_BGT (word 0x1fffe4) *) - 0x4e285806; (* arm_AESD Q6 Q0 *) - 0x4e2878c6; (* arm_AESIMC Q6 Q6 *) - 0x4c407840; (* arm_LDR Q0 X2 No_Offset *) - 0x4e285826; (* arm_AESD Q6 Q1 *) - 0x6e201cc6; (* arm_EOR_VEC Q6 Q6 Q0 0x80 *) - 0x4c007806 (* arm_STR Q6 X0 No_Offset *) -];; - -let AES256_DECRYPT_EXEC = ARM_MK_EXEC_RULE aes256_decrypt_mc;; - -let AES256_DECRYPT_CORRECT = prove( - `!plaintext ciphertext key ib k0 k1 k2 k3 k4 k5 k6 k7 k8 k9 k10 k11 k12 k13 k14 pc. - nonoverlapping (word pc,LENGTH aes256_decrypt_mc) (plaintext,16) - ==> ensures arm - // precondition - (\s. aligned_bytes_loaded s (word pc) aes256_decrypt_mc /\ - read PC s = word pc /\ - C_ARGUMENTS [plaintext; ciphertext; key] s /\ - read(memory :> bytes128 ciphertext) s = ib /\ - read(memory :> bytes32 (word_add key (word 240))) s = word 14 /\ - read(memory :> bytes128 key) s = k0 /\ - read(memory :> bytes128 (word_add key (word 16))) s = k1 /\ - read(memory :> bytes128 (word_add key (word 32))) s = k2 /\ - read(memory :> bytes128 (word_add key (word 48))) s = k3 /\ - read(memory :> bytes128 (word_add key (word 64))) s = k4 /\ - read(memory :> bytes128 (word_add key (word 80))) s = k5 /\ - read(memory :> bytes128 (word_add key (word 96))) s = k6 /\ - read(memory :> bytes128 (word_add key (word 112))) s = k7 /\ - read(memory :> bytes128 (word_add key (word 128))) s = k8 /\ - read(memory :> bytes128 (word_add key (word 144))) s = k9 /\ - read(memory :> bytes128 (word_add key (word 160))) s = k10 /\ - read(memory :> bytes128 (word_add key (word 176))) s = k11 /\ - read(memory :> bytes128 (word_add key (word 192))) s = k12 /\ - read(memory :> bytes128 (word_add key (word 208))) s = k13 /\ - read(memory :> bytes128 (word_add key (word 224))) s = k14) - // postcondition - (\s. read PC s = word (pc + LENGTH aes256_decrypt_mc) /\ - read (memory :> bytes128 plaintext) s = - aes256_decrypt ib [k0; k1; k2; k3; k4; k5; k6; k7; k8; k9; k10; k11; k12; k13; k14] - ) - // MAYCHANGE - (MAYCHANGE [PC;X6;X2] ,, MAYCHANGE [Q0; Q1; Q6],, - MAYCHANGE [memory :> bytes128 plaintext],, - MAYCHANGE SOME_FLAGS,, MAYCHANGE [events])`, - MAP_EVERY X_GEN_TAC - [`plaintext:int64`; `ciphertext:int64`; `key:int64`; - `ib:int128`; `k0:int128`; `k1:int128`; `k2:int128`; - `k3:int128`; `k4:int128`; `k5:int128`; `k6:int128`; - `k7:int128`; `k8:int128`; `k9:int128`; `k10:int128`; - `k11:int128`; `k12:int128`; `k13:int128`; `k14:int128`; `pc:num`] THEN - REWRITE_TAC[C_ARGUMENTS; SOME_FLAGS;NONOVERLAPPING_CLAUSES] THEN - REWRITE_TAC [(REWRITE_CONV [aes256_decrypt_mc] THENC LENGTH_CONV) `LENGTH aes256_decrypt_mc`] THEN - DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN - ENSURES_INIT_TAC "s0" THEN - ARM_ACCSTEPS_TAC AES256_DECRYPT_EXEC [] (1--59) THEN - ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN - - REWRITE_TAC [aes256_decrypt] THEN - REWRITE_TAC EL_15_128_CLAUSES THEN - REWRITE_TAC [aes256_decrypt_round] THEN - CONV_TAC(TOP_DEPTH_CONV let_CONV) THEN - REWRITE_TAC [aesd;aesimc] THEN - GEN_REWRITE_TAC LAND_CONV [WORD_XOR_SYM] THEN - REFL_TAC -);; diff --git a/arm/tutorial/aes_encrypt.ml b/arm/tutorial/aes_encrypt_decrypt.ml similarity index 55% rename from arm/tutorial/aes_encrypt.ml rename to arm/tutorial/aes_encrypt_decrypt.ml index 4188842fb..d0898dcd2 100644 --- a/arm/tutorial/aes_encrypt.ml +++ b/arm/tutorial/aes_encrypt_decrypt.ml @@ -4,11 +4,12 @@ *) (****************************************************************************** - An AES-256 encryption proof. + AES-256 encryption and decryption proofs. ******************************************************************************) needs "arm/proofs/base.ml";; needs "arm/proofs/utils/aes_encrypt_spec.ml";; +needs "arm/proofs/utils/aes_decrypt_spec.ml";; (* The following program performs an AES-256 encryption: - input: 128-bit block stored in memory at address in x1 @@ -20,7 +21,7 @@ needs "arm/proofs/utils/aes_encrypt_spec.ml";; 2 round keys are loaded in v0 and v1 before the loop and then in the loop and the counter is decremented by 2 in each iteration. - The instructions AESE and AESMC form one AES round: + The instructions AESE and AESMC form one AES encryption round: AESE: AESSubBytes(AESShiftRows(operand1 XOR operand2), // XOR = AddRoundKey AESMC: AESMixColumns(operand) The last round doesn't use AESMC, only AESE and XOR. @@ -59,7 +60,7 @@ let aes256_encrypt_mc = define_assert_from_elf "aes256_encrypt_mc" "arm/tutorial You can get the above OCaml list data structure from First generating the by running at the command line under arm directory: $ make tutorial/ -`print_literal_from_elf ""` or +`print_literal_from_elf "arm/tutorial/"` or `save_literal_from_elf "" ""`. *) @@ -120,14 +121,108 @@ let AES256_ENCRYPT_CORRECT = prove( ASM_REWRITE_TAC[] THEN REWRITE_TAC [aes256_encrypt] THEN - (* Replace the elements from the key round lists with their value *) + (* Replace the elements from the key round list with their value *) REWRITE_TAC EL_15_128_CLAUSES THEN (* Expand definitions and evaluate `let` terms *) REWRITE_TAC [aes256_encrypt_round; aese; aesmc] THEN CONV_TAC (TOP_DEPTH_CONV let_CONV) THEN BITBLAST_TAC - (* Alternatively, use the XOR symmetry - GEN_REWRITE_TAC LAND_CONV [WORD_XOR_SYM] THEN + (* Alternatively, use the XOR symmetry *) + (* GEN_REWRITE_TAC LAND_CONV [WORD_XOR_SYM] THEN REFL_TAC *) );; + + +(* The following program performs an AES-256 decryption, + with the following differences from encryption: + + procedure EQINVCIPHER(in, Nr, dw) is the one used from the standard in order + to be able to use the same round keys in the same order. + + The instructions AESD and AESIMC form one AES decryption round: + AESD: AESInvSubBytes(AESInvShiftRows(operand1 XOR operand2), // XOR = AddRoundKey + AESIMC: AESInvMixColumns(operand) + The last round doesn't use AESIMC, only AESD and XOR. +*) + +let aes256_decrypt_mc = define_assert_from_elf "aes256_decrypt_mc" "arm/tutorial/aes_decrypt.o" +[ + 0xb940f046; (* arm_LDR W6 X2 (Immediate_Offset (word 240)) *) + 0x4cdf7040; (* arm_LDR Q0 X2 (Postimmediate_Offset (word 16)) *) + 0x4cdf7041; (* arm_LDR Q1 X2 (Postimmediate_Offset (word 16)) *) + 0x4c407026; (* arm_LDR Q6 X1 No_Offset *) + 0x510008c6; (* arm_SUB W6 W6 (rvalue (word 2)) *) + 0x4e285806; (* arm_AESD Q6 Q0 *) + 0x4e2878c6; (* arm_AESIMC Q6 Q6 *) + 0x4cdf7840; (* arm_LDR Q0 X2 (Postimmediate_Offset (word 16)) *) + 0x710008c6; (* arm_SUBS W6 W6 (rvalue (word 2)) *) + 0x4e285826; (* arm_AESD Q6 Q1 *) + 0x4e2878c6; (* arm_AESIMC Q6 Q6 *) + 0x4cdf7841; (* arm_LDR Q1 X2 (Postimmediate_Offset (word 16)) *) + 0x54ffff2c; (* arm_BGT (word 2097124) *) + 0x4e285806; (* arm_AESD Q6 Q0 *) + 0x4e2878c6; (* arm_AESIMC Q6 Q6 *) + 0x4c407840; (* arm_LDR Q0 X2 No_Offset *) + 0x4e285826; (* arm_AESD Q6 Q1 *) + 0x6e201cc6; (* arm_EOR_VEC Q6 Q6 Q0 128 *) + 0x4c007806 (* arm_STR Q6 X0 No_Offset *) +];; + +let AES256_DECRYPT_EXEC = ARM_MK_EXEC_RULE aes256_decrypt_mc;; + +let AES256_DECRYPT_CORRECT = prove( + `!plaintext ciphertext key ib k0 k1 k2 k3 k4 k5 k6 k7 k8 k9 k10 k11 k12 k13 k14 pc. + nonoverlapping (word pc,LENGTH aes256_decrypt_mc) (plaintext,16) + ==> ensures arm + // precondition + (\s. aligned_bytes_loaded s (word pc) aes256_decrypt_mc /\ + read PC s = word pc /\ + C_ARGUMENTS [plaintext; ciphertext; key] s /\ + read(memory :> bytes128 ciphertext) s = ib /\ + read(memory :> bytes32 (word_add key (word 240))) s = word 14 /\ + read(memory :> bytes128 key) s = k0 /\ + read(memory :> bytes128 (word_add key (word 16))) s = k1 /\ + read(memory :> bytes128 (word_add key (word 32))) s = k2 /\ + read(memory :> bytes128 (word_add key (word 48))) s = k3 /\ + read(memory :> bytes128 (word_add key (word 64))) s = k4 /\ + read(memory :> bytes128 (word_add key (word 80))) s = k5 /\ + read(memory :> bytes128 (word_add key (word 96))) s = k6 /\ + read(memory :> bytes128 (word_add key (word 112))) s = k7 /\ + read(memory :> bytes128 (word_add key (word 128))) s = k8 /\ + read(memory :> bytes128 (word_add key (word 144))) s = k9 /\ + read(memory :> bytes128 (word_add key (word 160))) s = k10 /\ + read(memory :> bytes128 (word_add key (word 176))) s = k11 /\ + read(memory :> bytes128 (word_add key (word 192))) s = k12 /\ + read(memory :> bytes128 (word_add key (word 208))) s = k13 /\ + read(memory :> bytes128 (word_add key (word 224))) s = k14) + // postcondition + (\s. read PC s = word (pc + LENGTH aes256_decrypt_mc) /\ + read (memory :> bytes128 plaintext) s = + aes256_decrypt ib [k0; k1; k2; k3; k4; k5; k6; k7; k8; k9; k10; k11; k12; k13; k14] + ) + // MAYCHANGE + (MAYCHANGE [PC;X6;X2] ,, MAYCHANGE [Q0; Q1; Q6],, + MAYCHANGE [memory :> bytes128 plaintext],, + MAYCHANGE SOME_FLAGS,, MAYCHANGE [events])`, + MAP_EVERY X_GEN_TAC + [`plaintext:int64`; `ciphertext:int64`; `key:int64`; + `ib:int128`; `k0:int128`; `k1:int128`; `k2:int128`; + `k3:int128`; `k4:int128`; `k5:int128`; `k6:int128`; + `k7:int128`; `k8:int128`; `k9:int128`; `k10:int128`; + `k11:int128`; `k12:int128`; `k13:int128`; `k14:int128`; `pc:num`] THEN + REWRITE_TAC[C_ARGUMENTS; SOME_FLAGS;NONOVERLAPPING_CLAUSES] THEN + REWRITE_TAC [(REWRITE_CONV [aes256_decrypt_mc] THENC LENGTH_CONV) `LENGTH aes256_decrypt_mc`] THEN + DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN + ENSURES_INIT_TAC "s0" THEN + ARM_ACCSTEPS_TAC AES256_DECRYPT_EXEC [] (1--59) THEN + ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN + + REWRITE_TAC [aes256_decrypt] THEN + REWRITE_TAC EL_15_128_CLAUSES THEN + REWRITE_TAC [aes256_decrypt_round] THEN + CONV_TAC(TOP_DEPTH_CONV let_CONV) THEN + REWRITE_TAC [aesd;aesimc] THEN + GEN_REWRITE_TAC LAND_CONV [WORD_XOR_SYM] THEN + REFL_TAC +);; From 45f4e61e4fb2627c1358bcbefea3a846fa4c057a Mon Sep 17 00:00:00 2001 From: Nevine Ebeid Date: Tue, 20 Jan 2026 15:34:35 -0500 Subject: [PATCH 125/132] Revert "Put AES encrypt and decrypt proofs in one file in the tutorial, with explanation." This reverts commit d3035e88f01f4233624a248555a448cc99fa0ec5. --- arm/tutorial/README.md | 3 +- arm/tutorial/aes_decrypt.S | 2 +- arm/tutorial/aes_decrypt.ml | 93 +++++++++++++++ ...{aes_encrypt_decrypt.ml => aes_encrypt.ml} | 107 +----------------- 4 files changed, 102 insertions(+), 103 deletions(-) create mode 100644 arm/tutorial/aes_decrypt.ml rename arm/tutorial/{aes_encrypt_decrypt.ml => aes_encrypt.ml} (55%) diff --git a/arm/tutorial/README.md b/arm/tutorial/README.md index 55c83c962..a96b4b776 100644 --- a/arm/tutorial/README.md +++ b/arm/tutorial/README.md @@ -14,7 +14,8 @@ To verify programs in x86, see `x86/tutorial`. 6. `bignum.ml`: Writing a specification of a program dealing with big numbers & proving it. 7. `rodata.ml`: Reading data from the read-only section. 8. `safety.ml`: Verify the safety property (constant-time and and memory-safe) -9. `aes_encrypt_decrypt.ml`: Verify AES block encryption and decryption. +9. `aes_encrypt.ml`: Verifying a simple AES encryption program. +10. `aes_decrypt.ml`: Verifying a simple AES decryption program. ### Relational reasoning diff --git a/arm/tutorial/aes_decrypt.S b/arm/tutorial/aes_decrypt.S index 8feef9fa2..a2cac8c5c 100644 --- a/arm/tutorial/aes_decrypt.S +++ b/arm/tutorial/aes_decrypt.S @@ -12,9 +12,9 @@ aes_decrypt: ldr w6,[x2,#240] ld1 {v0.16b},[x2],#16 - ld1 {v1.16b},[x2],#16 ld1 {v6.16b},[x1] sub w6,w6,#2 + ld1 {v1.16b},[x2],#16 Loop_dec: aesd v6.16b,v0.16b diff --git a/arm/tutorial/aes_decrypt.ml b/arm/tutorial/aes_decrypt.ml new file mode 100644 index 000000000..bfeea8aaf --- /dev/null +++ b/arm/tutorial/aes_decrypt.ml @@ -0,0 +1,93 @@ +(* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT-0 + *) + + (****************************************************************************** + An example AES decryption proof. +******************************************************************************) + +needs "arm/proofs/base.ml";; +needs "arm/proofs/utils/aes_decrypt_spec.ml";; + +(* print_literal_from_elf "arm/aes-xts/aes256_decrypt.o";; *) +let aes256_decrypt_mc = define_assert_from_elf "aes256_decrypt_mc" "arm/tutorial/aes_decrypt.o" +[ + 0xb940f046; (* arm_LDR W6 X2 (Immediate_Offset (word 0xf0)) *) + 0x4cdf7040; (* arm_LDR Q0 X2 (Postimmediate_Offset (word 0x10)) *) + 0x4c407026; (* arm_LDR Q6 X1 No_Offset *) + 0x510008c6; (* arm_SUB W6 W6 (rvalue (word 0x2)) *) + 0x4cdf7041; (* arm_LDR Q1 X2 (Postimmediate_Offset (word 0x10)) *) + 0x4e285806; (* arm_AESD Q6 Q0 *) + 0x4e2878c6; (* arm_AESIMC Q6 Q6 *) + 0x4cdf7840; (* arm_LDR Q0 X2 (Postimmediate_Offset (word 0x10)) *) + 0x710008c6; (* arm_SUBS W6 W6 (rvalue (word 0x2)) *) + 0x4e285826; (* arm_AESD Q6 Q1 *) + 0x4e2878c6; (* arm_AESIMC Q6 Q6 *) + 0x4cdf7841; (* arm_LDR Q1 X2 (Postimmediate_Offset (word 0x10)) *) + 0x54ffff2c; (* arm_BGT (word 0x1fffe4) *) + 0x4e285806; (* arm_AESD Q6 Q0 *) + 0x4e2878c6; (* arm_AESIMC Q6 Q6 *) + 0x4c407840; (* arm_LDR Q0 X2 No_Offset *) + 0x4e285826; (* arm_AESD Q6 Q1 *) + 0x6e201cc6; (* arm_EOR_VEC Q6 Q6 Q0 0x80 *) + 0x4c007806 (* arm_STR Q6 X0 No_Offset *) +];; + +let AES256_DECRYPT_EXEC = ARM_MK_EXEC_RULE aes256_decrypt_mc;; + +let AES256_DECRYPT_CORRECT = prove( + `!plaintext ciphertext key ib k0 k1 k2 k3 k4 k5 k6 k7 k8 k9 k10 k11 k12 k13 k14 pc. + nonoverlapping (word pc,LENGTH aes256_decrypt_mc) (plaintext,16) + ==> ensures arm + // precondition + (\s. aligned_bytes_loaded s (word pc) aes256_decrypt_mc /\ + read PC s = word pc /\ + C_ARGUMENTS [plaintext; ciphertext; key] s /\ + read(memory :> bytes128 ciphertext) s = ib /\ + read(memory :> bytes32 (word_add key (word 240))) s = word 14 /\ + read(memory :> bytes128 key) s = k0 /\ + read(memory :> bytes128 (word_add key (word 16))) s = k1 /\ + read(memory :> bytes128 (word_add key (word 32))) s = k2 /\ + read(memory :> bytes128 (word_add key (word 48))) s = k3 /\ + read(memory :> bytes128 (word_add key (word 64))) s = k4 /\ + read(memory :> bytes128 (word_add key (word 80))) s = k5 /\ + read(memory :> bytes128 (word_add key (word 96))) s = k6 /\ + read(memory :> bytes128 (word_add key (word 112))) s = k7 /\ + read(memory :> bytes128 (word_add key (word 128))) s = k8 /\ + read(memory :> bytes128 (word_add key (word 144))) s = k9 /\ + read(memory :> bytes128 (word_add key (word 160))) s = k10 /\ + read(memory :> bytes128 (word_add key (word 176))) s = k11 /\ + read(memory :> bytes128 (word_add key (word 192))) s = k12 /\ + read(memory :> bytes128 (word_add key (word 208))) s = k13 /\ + read(memory :> bytes128 (word_add key (word 224))) s = k14) + // postcondition + (\s. read PC s = word (pc + LENGTH aes256_decrypt_mc) /\ + read (memory :> bytes128 plaintext) s = + aes256_decrypt ib [k0; k1; k2; k3; k4; k5; k6; k7; k8; k9; k10; k11; k12; k13; k14] + ) + // MAYCHANGE + (MAYCHANGE [PC;X6;X2] ,, MAYCHANGE [Q0; Q1; Q6],, + MAYCHANGE [memory :> bytes128 plaintext],, + MAYCHANGE SOME_FLAGS,, MAYCHANGE [events])`, + MAP_EVERY X_GEN_TAC + [`plaintext:int64`; `ciphertext:int64`; `key:int64`; + `ib:int128`; `k0:int128`; `k1:int128`; `k2:int128`; + `k3:int128`; `k4:int128`; `k5:int128`; `k6:int128`; + `k7:int128`; `k8:int128`; `k9:int128`; `k10:int128`; + `k11:int128`; `k12:int128`; `k13:int128`; `k14:int128`; `pc:num`] THEN + REWRITE_TAC[C_ARGUMENTS; SOME_FLAGS;NONOVERLAPPING_CLAUSES] THEN + REWRITE_TAC [(REWRITE_CONV [aes256_decrypt_mc] THENC LENGTH_CONV) `LENGTH aes256_decrypt_mc`] THEN + DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN + ENSURES_INIT_TAC "s0" THEN + ARM_ACCSTEPS_TAC AES256_DECRYPT_EXEC [] (1--59) THEN + ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN + + REWRITE_TAC [aes256_decrypt] THEN + REWRITE_TAC EL_15_128_CLAUSES THEN + REWRITE_TAC [aes256_decrypt_round] THEN + CONV_TAC(TOP_DEPTH_CONV let_CONV) THEN + REWRITE_TAC [aesd;aesimc] THEN + GEN_REWRITE_TAC LAND_CONV [WORD_XOR_SYM] THEN + REFL_TAC +);; diff --git a/arm/tutorial/aes_encrypt_decrypt.ml b/arm/tutorial/aes_encrypt.ml similarity index 55% rename from arm/tutorial/aes_encrypt_decrypt.ml rename to arm/tutorial/aes_encrypt.ml index d0898dcd2..4188842fb 100644 --- a/arm/tutorial/aes_encrypt_decrypt.ml +++ b/arm/tutorial/aes_encrypt.ml @@ -4,12 +4,11 @@ *) (****************************************************************************** - AES-256 encryption and decryption proofs. + An AES-256 encryption proof. ******************************************************************************) needs "arm/proofs/base.ml";; needs "arm/proofs/utils/aes_encrypt_spec.ml";; -needs "arm/proofs/utils/aes_decrypt_spec.ml";; (* The following program performs an AES-256 encryption: - input: 128-bit block stored in memory at address in x1 @@ -21,7 +20,7 @@ needs "arm/proofs/utils/aes_decrypt_spec.ml";; 2 round keys are loaded in v0 and v1 before the loop and then in the loop and the counter is decremented by 2 in each iteration. - The instructions AESE and AESMC form one AES encryption round: + The instructions AESE and AESMC form one AES round: AESE: AESSubBytes(AESShiftRows(operand1 XOR operand2), // XOR = AddRoundKey AESMC: AESMixColumns(operand) The last round doesn't use AESMC, only AESE and XOR. @@ -60,7 +59,7 @@ let aes256_encrypt_mc = define_assert_from_elf "aes256_encrypt_mc" "arm/tutorial You can get the above OCaml list data structure from First generating the by running at the command line under arm directory: $ make tutorial/ -`print_literal_from_elf "arm/tutorial/"` or +`print_literal_from_elf ""` or `save_literal_from_elf "" ""`. *) @@ -121,108 +120,14 @@ let AES256_ENCRYPT_CORRECT = prove( ASM_REWRITE_TAC[] THEN REWRITE_TAC [aes256_encrypt] THEN - (* Replace the elements from the key round list with their value *) + (* Replace the elements from the key round lists with their value *) REWRITE_TAC EL_15_128_CLAUSES THEN (* Expand definitions and evaluate `let` terms *) REWRITE_TAC [aes256_encrypt_round; aese; aesmc] THEN CONV_TAC (TOP_DEPTH_CONV let_CONV) THEN BITBLAST_TAC - (* Alternatively, use the XOR symmetry *) - (* GEN_REWRITE_TAC LAND_CONV [WORD_XOR_SYM] THEN - REFL_TAC *) -);; - - -(* The following program performs an AES-256 decryption, - with the following differences from encryption: - - procedure EQINVCIPHER(in, Nr, dw) is the one used from the standard in order - to be able to use the same round keys in the same order. - - The instructions AESD and AESIMC form one AES decryption round: - AESD: AESInvSubBytes(AESInvShiftRows(operand1 XOR operand2), // XOR = AddRoundKey - AESIMC: AESInvMixColumns(operand) - The last round doesn't use AESIMC, only AESD and XOR. -*) - -let aes256_decrypt_mc = define_assert_from_elf "aes256_decrypt_mc" "arm/tutorial/aes_decrypt.o" -[ - 0xb940f046; (* arm_LDR W6 X2 (Immediate_Offset (word 240)) *) - 0x4cdf7040; (* arm_LDR Q0 X2 (Postimmediate_Offset (word 16)) *) - 0x4cdf7041; (* arm_LDR Q1 X2 (Postimmediate_Offset (word 16)) *) - 0x4c407026; (* arm_LDR Q6 X1 No_Offset *) - 0x510008c6; (* arm_SUB W6 W6 (rvalue (word 2)) *) - 0x4e285806; (* arm_AESD Q6 Q0 *) - 0x4e2878c6; (* arm_AESIMC Q6 Q6 *) - 0x4cdf7840; (* arm_LDR Q0 X2 (Postimmediate_Offset (word 16)) *) - 0x710008c6; (* arm_SUBS W6 W6 (rvalue (word 2)) *) - 0x4e285826; (* arm_AESD Q6 Q1 *) - 0x4e2878c6; (* arm_AESIMC Q6 Q6 *) - 0x4cdf7841; (* arm_LDR Q1 X2 (Postimmediate_Offset (word 16)) *) - 0x54ffff2c; (* arm_BGT (word 2097124) *) - 0x4e285806; (* arm_AESD Q6 Q0 *) - 0x4e2878c6; (* arm_AESIMC Q6 Q6 *) - 0x4c407840; (* arm_LDR Q0 X2 No_Offset *) - 0x4e285826; (* arm_AESD Q6 Q1 *) - 0x6e201cc6; (* arm_EOR_VEC Q6 Q6 Q0 128 *) - 0x4c007806 (* arm_STR Q6 X0 No_Offset *) -];; - -let AES256_DECRYPT_EXEC = ARM_MK_EXEC_RULE aes256_decrypt_mc;; - -let AES256_DECRYPT_CORRECT = prove( - `!plaintext ciphertext key ib k0 k1 k2 k3 k4 k5 k6 k7 k8 k9 k10 k11 k12 k13 k14 pc. - nonoverlapping (word pc,LENGTH aes256_decrypt_mc) (plaintext,16) - ==> ensures arm - // precondition - (\s. aligned_bytes_loaded s (word pc) aes256_decrypt_mc /\ - read PC s = word pc /\ - C_ARGUMENTS [plaintext; ciphertext; key] s /\ - read(memory :> bytes128 ciphertext) s = ib /\ - read(memory :> bytes32 (word_add key (word 240))) s = word 14 /\ - read(memory :> bytes128 key) s = k0 /\ - read(memory :> bytes128 (word_add key (word 16))) s = k1 /\ - read(memory :> bytes128 (word_add key (word 32))) s = k2 /\ - read(memory :> bytes128 (word_add key (word 48))) s = k3 /\ - read(memory :> bytes128 (word_add key (word 64))) s = k4 /\ - read(memory :> bytes128 (word_add key (word 80))) s = k5 /\ - read(memory :> bytes128 (word_add key (word 96))) s = k6 /\ - read(memory :> bytes128 (word_add key (word 112))) s = k7 /\ - read(memory :> bytes128 (word_add key (word 128))) s = k8 /\ - read(memory :> bytes128 (word_add key (word 144))) s = k9 /\ - read(memory :> bytes128 (word_add key (word 160))) s = k10 /\ - read(memory :> bytes128 (word_add key (word 176))) s = k11 /\ - read(memory :> bytes128 (word_add key (word 192))) s = k12 /\ - read(memory :> bytes128 (word_add key (word 208))) s = k13 /\ - read(memory :> bytes128 (word_add key (word 224))) s = k14) - // postcondition - (\s. read PC s = word (pc + LENGTH aes256_decrypt_mc) /\ - read (memory :> bytes128 plaintext) s = - aes256_decrypt ib [k0; k1; k2; k3; k4; k5; k6; k7; k8; k9; k10; k11; k12; k13; k14] - ) - // MAYCHANGE - (MAYCHANGE [PC;X6;X2] ,, MAYCHANGE [Q0; Q1; Q6],, - MAYCHANGE [memory :> bytes128 plaintext],, - MAYCHANGE SOME_FLAGS,, MAYCHANGE [events])`, - MAP_EVERY X_GEN_TAC - [`plaintext:int64`; `ciphertext:int64`; `key:int64`; - `ib:int128`; `k0:int128`; `k1:int128`; `k2:int128`; - `k3:int128`; `k4:int128`; `k5:int128`; `k6:int128`; - `k7:int128`; `k8:int128`; `k9:int128`; `k10:int128`; - `k11:int128`; `k12:int128`; `k13:int128`; `k14:int128`; `pc:num`] THEN - REWRITE_TAC[C_ARGUMENTS; SOME_FLAGS;NONOVERLAPPING_CLAUSES] THEN - REWRITE_TAC [(REWRITE_CONV [aes256_decrypt_mc] THENC LENGTH_CONV) `LENGTH aes256_decrypt_mc`] THEN - DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN - ENSURES_INIT_TAC "s0" THEN - ARM_ACCSTEPS_TAC AES256_DECRYPT_EXEC [] (1--59) THEN - ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN - - REWRITE_TAC [aes256_decrypt] THEN - REWRITE_TAC EL_15_128_CLAUSES THEN - REWRITE_TAC [aes256_decrypt_round] THEN - CONV_TAC(TOP_DEPTH_CONV let_CONV) THEN - REWRITE_TAC [aesd;aesimc] THEN + (* Alternatively, use the XOR symmetry GEN_REWRITE_TAC LAND_CONV [WORD_XOR_SYM] THEN - REFL_TAC + REFL_TAC *) );; From f958559282d1d42a0d0b071c954a8bc1dc8024d2 Mon Sep 17 00:00:00 2001 From: Nevine Ebeid Date: Wed, 21 Jan 2026 17:09:41 -0500 Subject: [PATCH 126/132] Added explanation to the decrypt tutorial. --- arm/proofs/utils/aes_encrypt_spec.ml | 2 +- arm/tutorial/aes_decrypt.S | 2 +- arm/tutorial/aes_decrypt.ml | 58 +++++++++++++++++++++------- arm/tutorial/aes_encrypt.ml | 28 +++++++++----- 4 files changed, 65 insertions(+), 25 deletions(-) diff --git a/arm/proofs/utils/aes_encrypt_spec.ml b/arm/proofs/utils/aes_encrypt_spec.ml index a480ebb88..ca1fbdc45 100644 --- a/arm/proofs/utils/aes_encrypt_spec.ml +++ b/arm/proofs/utils/aes_encrypt_spec.ml @@ -44,7 +44,7 @@ out = state end *) -(* TODO: Nevine will finish writing this spec *) + (* Note: In the spec, SubBytes precedes ShiftRows, but the instruction definition of aese in arm/proofs/aes.ml has them interchanged. This is possible but requires a modified lookup table, joined_GF2, diff --git a/arm/tutorial/aes_decrypt.S b/arm/tutorial/aes_decrypt.S index a2cac8c5c..8feef9fa2 100644 --- a/arm/tutorial/aes_decrypt.S +++ b/arm/tutorial/aes_decrypt.S @@ -12,9 +12,9 @@ aes_decrypt: ldr w6,[x2,#240] ld1 {v0.16b},[x2],#16 + ld1 {v1.16b},[x2],#16 ld1 {v6.16b},[x1] sub w6,w6,#2 - ld1 {v1.16b},[x2],#16 Loop_dec: aesd v6.16b,v0.16b diff --git a/arm/tutorial/aes_decrypt.ml b/arm/tutorial/aes_decrypt.ml index bfeea8aaf..45eec5cab 100644 --- a/arm/tutorial/aes_decrypt.ml +++ b/arm/tutorial/aes_decrypt.ml @@ -4,33 +4,44 @@ *) (****************************************************************************** - An example AES decryption proof. + AES-256 decryption proof. ******************************************************************************) needs "arm/proofs/base.ml";; needs "arm/proofs/utils/aes_decrypt_spec.ml";; -(* print_literal_from_elf "arm/aes-xts/aes256_decrypt.o";; *) +(* The following program performs an AES-256 decryption, + with the following differences from encryption (see tutorial/aes_encrypt.ml): + + procedure EQINVCIPHER(in, Nr, dw) is the one used from the standard in order + to be able to use the same round keys in the same order as with encrypt. + + The instructions AESD and AESIMC form one AES decryption round: + AESD: AESInvSubBytes(AESInvShiftRows(operand1 XOR operand2), // XOR = AddRoundKey + AESIMC: AESInvMixColumns(operand) + The last round doesn't use AESIMC, only AESD and XOR. +*) + let aes256_decrypt_mc = define_assert_from_elf "aes256_decrypt_mc" "arm/tutorial/aes_decrypt.o" [ - 0xb940f046; (* arm_LDR W6 X2 (Immediate_Offset (word 0xf0)) *) - 0x4cdf7040; (* arm_LDR Q0 X2 (Postimmediate_Offset (word 0x10)) *) + 0xb940f046; (* arm_LDR W6 X2 (Immediate_Offset (word 240)) *) + 0x4cdf7040; (* arm_LDR Q0 X2 (Postimmediate_Offset (word 16)) *) + 0x4cdf7041; (* arm_LDR Q1 X2 (Postimmediate_Offset (word 16)) *) 0x4c407026; (* arm_LDR Q6 X1 No_Offset *) - 0x510008c6; (* arm_SUB W6 W6 (rvalue (word 0x2)) *) - 0x4cdf7041; (* arm_LDR Q1 X2 (Postimmediate_Offset (word 0x10)) *) + 0x510008c6; (* arm_SUB W6 W6 (rvalue (word 2)) *) 0x4e285806; (* arm_AESD Q6 Q0 *) 0x4e2878c6; (* arm_AESIMC Q6 Q6 *) - 0x4cdf7840; (* arm_LDR Q0 X2 (Postimmediate_Offset (word 0x10)) *) - 0x710008c6; (* arm_SUBS W6 W6 (rvalue (word 0x2)) *) + 0x4cdf7840; (* arm_LDR Q0 X2 (Postimmediate_Offset (word 16)) *) + 0x710008c6; (* arm_SUBS W6 W6 (rvalue (word 2)) *) 0x4e285826; (* arm_AESD Q6 Q1 *) 0x4e2878c6; (* arm_AESIMC Q6 Q6 *) - 0x4cdf7841; (* arm_LDR Q1 X2 (Postimmediate_Offset (word 0x10)) *) - 0x54ffff2c; (* arm_BGT (word 0x1fffe4) *) + 0x4cdf7841; (* arm_LDR Q1 X2 (Postimmediate_Offset (word 16)) *) + 0x54ffff2c; (* arm_BGT (word 2097124) *) 0x4e285806; (* arm_AESD Q6 Q0 *) 0x4e2878c6; (* arm_AESIMC Q6 Q6 *) 0x4c407840; (* arm_LDR Q0 X2 No_Offset *) 0x4e285826; (* arm_AESD Q6 Q1 *) - 0x6e201cc6; (* arm_EOR_VEC Q6 Q6 Q0 0x80 *) + 0x6e201cc6; (* arm_EOR_VEC Q6 Q6 Q0 128 *) 0x4c007806 (* arm_STR Q6 X0 No_Offset *) ];; @@ -43,6 +54,8 @@ let AES256_DECRYPT_CORRECT = prove( // precondition (\s. aligned_bytes_loaded s (word pc) aes256_decrypt_mc /\ read PC s = word pc /\ + // uses the C ABI which puts the arguments in their order in registers x0 to x7. + // Here only 3 arguments are passed in. C_ARGUMENTS [plaintext; ciphertext; key] s /\ read(memory :> bytes128 ciphertext) s = ib /\ read(memory :> bytes32 (word_add key (word 240))) s = word 14 /\ @@ -66,25 +79,42 @@ let AES256_DECRYPT_CORRECT = prove( read (memory :> bytes128 plaintext) s = aes256_decrypt ib [k0; k1; k2; k3; k4; k5; k6; k7; k8; k9; k10; k11; k12; k13; k14] ) - // MAYCHANGE + // Registers (and memory locations) that may change after execution (MAYCHANGE [PC;X6;X2] ,, MAYCHANGE [Q0; Q1; Q6],, MAYCHANGE [memory :> bytes128 plaintext],, MAYCHANGE SOME_FLAGS,, MAYCHANGE [events])`, + MAP_EVERY X_GEN_TAC [`plaintext:int64`; `ciphertext:int64`; `key:int64`; `ib:int128`; `k0:int128`; `k1:int128`; `k2:int128`; `k3:int128`; `k4:int128`; `k5:int128`; `k6:int128`; `k7:int128`; `k8:int128`; `k9:int128`; `k10:int128`; `k11:int128`; `k12:int128`; `k13:int128`; `k14:int128`; `pc:num`] THEN - REWRITE_TAC[C_ARGUMENTS; SOME_FLAGS;NONOVERLAPPING_CLAUSES] THEN + + (* Convert C_ARGUMENTS to reading registers x0, x1, x2 and expand SOME_FLAGS *) + REWRITE_TAC[C_ARGUMENTS; SOME_FLAGS] THEN + + (* Find the length of the program using a Conversion *) REWRITE_TAC [(REWRITE_CONV [aes256_decrypt_mc] THENC LENGTH_CONV) `LENGTH aes256_decrypt_mc`] THEN DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN + + (* Start symbolic execution with state 's0' *) ENSURES_INIT_TAC "s0" THEN + (* Symbolic execution of all instructions *) ARM_ACCSTEPS_TAC AES256_DECRYPT_EXEC [] (1--59) THEN - ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN + (* Returned; Finalize symbolic execution. *) + ENSURES_FINAL_STATE_TAC THEN + (* Use ASM_REWRITE_TAC[] to rewrite the goal using equalities in assumptions. *) + ASM_REWRITE_TAC[] THEN + (* Use the specs to expand defintions *) REWRITE_TAC [aes256_decrypt] THEN + + (* Replace the elements selection, EL, with the selected element + from the key round list. *) REWRITE_TAC EL_15_128_CLAUSES THEN + + (* Expand definitions and evaluate `let` terms *) REWRITE_TAC [aes256_decrypt_round] THEN CONV_TAC(TOP_DEPTH_CONV let_CONV) THEN REWRITE_TAC [aesd;aesimc] THEN diff --git a/arm/tutorial/aes_encrypt.ml b/arm/tutorial/aes_encrypt.ml index 4188842fb..c36e3269e 100644 --- a/arm/tutorial/aes_encrypt.ml +++ b/arm/tutorial/aes_encrypt.ml @@ -4,7 +4,7 @@ *) (****************************************************************************** - An AES-256 encryption proof. + AES-256 encryption proof. ******************************************************************************) needs "arm/proofs/base.ml";; @@ -20,7 +20,7 @@ needs "arm/proofs/utils/aes_encrypt_spec.ml";; 2 round keys are loaded in v0 and v1 before the loop and then in the loop and the counter is decremented by 2 in each iteration. - The instructions AESE and AESMC form one AES round: + The instructions AESE and AESMC form one AES encryption round: AESE: AESSubBytes(AESShiftRows(operand1 XOR operand2), // XOR = AddRoundKey AESMC: AESMixColumns(operand) The last round doesn't use AESMC, only AESE and XOR. @@ -59,10 +59,13 @@ let aes256_encrypt_mc = define_assert_from_elf "aes256_encrypt_mc" "arm/tutorial You can get the above OCaml list data structure from First generating the by running at the command line under arm directory: $ make tutorial/ -`print_literal_from_elf ""` or +`print_literal_from_elf "arm/tutorial/"` or `save_literal_from_elf "" ""`. *) +(* ARM_MK_EXEC_RULE decodes the byte sequence into an OCaml array of + theorems describing the instruction decoded at each PC (only when + it is multiple of 4). *) let AES256_ENCRYPT_EXEC = ARM_MK_EXEC_RULE aes256_encrypt_mc;; let AES256_ENCRYPT_CORRECT = prove( @@ -109,25 +112,32 @@ let AES256_ENCRYPT_CORRECT = prove( (* Find the length of the program using a Conversion *) REWRITE_TAC [(REWRITE_CONV [aes256_encrypt_mc] THENC LENGTH_CONV) `LENGTH aes256_encrypt_mc`] THEN + (* Strips the outermost universal quantifier from the conclusion of a goal *) REPEAT STRIP_TAC THEN (* Start symbolic execution with state 's0' *) ENSURES_INIT_TAC "s0" THEN - (* Symbolic execution of all instructions *) - ARM_STEPS_TAC AES256_ENCRYPT_EXEC (1--59) THEN + (* Symbolic execution *) + ARM_STEPS_TAC AES256_ENCRYPT_EXEC (1--6) THEN + ARM_STEPS_TAC AES256_ENCRYPT_EXEC (7--59) THEN (* Returned; Finalize symbolic execution. *) ENSURES_FINAL_STATE_TAC THEN + (* Use ASM_REWRITE_TAC[] to rewrite the goal using equalities in assumptions. *) ASM_REWRITE_TAC[] THEN + (* Use the specs to expand defintions *) REWRITE_TAC [aes256_encrypt] THEN - (* Replace the elements from the key round lists with their value *) + (* Replace the elements selection, EL, with the selected element + from the key round list. *) REWRITE_TAC EL_15_128_CLAUSES THEN - (* Expand definitions and evaluate `let` terms *) + (* Expand definitions and evaluate `let` terms. *) REWRITE_TAC [aes256_encrypt_round; aese; aesmc] THEN CONV_TAC (TOP_DEPTH_CONV let_CONV) THEN + + (* Evaluate the logical expression on both sides as a gate circuit between bits. *) BITBLAST_TAC - (* Alternatively, use the XOR symmetry - GEN_REWRITE_TAC LAND_CONV [WORD_XOR_SYM] THEN + (* Alternatively, use the XOR symmetry *) + (* GEN_REWRITE_TAC LAND_CONV [WORD_XOR_SYM] THEN REFL_TAC *) );; From a124e9b47dd5f52e11b7276afa78a54bd78e8cd3 Mon Sep 17 00:00:00 2001 From: Nevine Ebeid Date: Thu, 22 Jan 2026 12:37:25 -0500 Subject: [PATCH 127/132] Add banners and remove print function in collect-signatures.py. --- arm/proofs/aes_xts_decrypt.ml | 4 +++- arm/proofs/aes_xts_encrypt.ml | 4 +++- tools/collect-signatures.py | 5 ----- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/arm/proofs/aes_xts_decrypt.ml b/arm/proofs/aes_xts_decrypt.ml index 4817ef9e0..79adf1bac 100644 --- a/arm/proofs/aes_xts_decrypt.ml +++ b/arm/proofs/aes_xts_decrypt.ml @@ -2,7 +2,9 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT-0 *) -use_file_raise_failure := true;; +(* ========================================================================= *) +(* AES-256-XTS decryption. *) +(* ========================================================================= *) needs "arm/proofs/utils/aes_xts_common.ml";; diff --git a/arm/proofs/aes_xts_encrypt.ml b/arm/proofs/aes_xts_encrypt.ml index 4397ef467..2a32e6931 100644 --- a/arm/proofs/aes_xts_encrypt.ml +++ b/arm/proofs/aes_xts_encrypt.ml @@ -2,7 +2,9 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT-0 *) -use_file_raise_failure := true;; +(* ========================================================================= *) +(* AES-256-XTS encryption. *) +(* ========================================================================= *) needs "arm/proofs/utils/aes_xts_common.ml";; diff --git a/tools/collect-signatures.py b/tools/collect-signatures.py index e7debcfdc..e8c3ca518 100644 --- a/tools/collect-signatures.py +++ b/tools/collect-signatures.py @@ -48,11 +48,6 @@ def __eq__(self, io2): return self.meminputs == io2.meminputs and self.memoutputs == io2.memoutputs and \ self.temporaries == decl2.temporaries - def print(self): - print(f"- meminputs: {self.meminputs}") - print(f"- memoutputs: {self.memoutputs}") - print(f"- temporaries: {self.temporaries}") - def parseFnDecl(s:str, filename:str) -> FnDecl: assert s.startswith("extern"), s original_lines = s From 58c21b569ff62cc42ed08a2c12b823a1ecd9c159 Mon Sep 17 00:00:00 2001 From: Nevine Ebeid Date: Thu, 22 Jan 2026 12:44:36 -0500 Subject: [PATCH 128/132] Put AES encrypt and decrypt proofs in one file in the tutorial (2nd attempt). --- arm/Makefile | 8 +- arm/tutorial/aes_decrypt.ml | 123 ------------------ ...{aes_encrypt.ml => aes_encrypt_decrypt.ml} | 118 +++++++++++++++++ 3 files changed, 125 insertions(+), 124 deletions(-) delete mode 100644 arm/tutorial/aes_decrypt.ml rename arm/tutorial/{aes_encrypt.ml => aes_encrypt_decrypt.ml} (54%) diff --git a/arm/Makefile b/arm/Makefile index d2e2ba928..cc8d4a0d2 100644 --- a/arm/Makefile +++ b/arm/Makefile @@ -414,7 +414,7 @@ OBJ = $(POINT_OBJ) $(BIGNUM_OBJ) $(AES_XTS_OBJ) TUTORIAL_PROOFS = $(wildcard tutorial/*.ml) -TUTORIAL_OBJ = $(filter-out tutorial/safety.o, $(TUTORIAL_PROOFS:.ml=.o)) \ +TUTORIAL_OBJ = $(filter-out tutorial/aes_encrypt_decrypt.o tutorial/safety.o, $(TUTORIAL_PROOFS:.ml=.o)) \ curve25519/bignum_mod_n25519.o p256/bignum_mux_4.o \ tutorial/rel_loop2.o \ tutorial/rel_simp2.o tutorial/rel_veceq2.o tutorial/rel_equivtac2.o \ @@ -529,6 +529,12 @@ sm2/sm2_montjscalarmul_alt.native: sm2/sm2_montjadd_alt.native sm2/sm2_montjdoub tutorial/safety.native: tutorial/safety.ml proofs/bignum_mux_4.ml \ curve25519/bignum_mod_n25519.o ; \ ../tools/build-proof.sh "$<" "$(HOLLIGHT)" "$@" + +# aes_encrypt_decrypt tutorial concatenates proofs for both aes_encrypt.S and aes_decrypt.S +tutorial/aes_encrypt_decrypt.native: tutorial/aes_encrypt_decrypt.ml \ + tutorial/aes_encrypt.o tutorial/aes_decrypt.o ; \ + ../tools/build-proof.sh "$<" "$(HOLLIGHT)" "$@" + # other tutorials have their .o files .SECONDEXPANSION: tutorial/%.native: tutorial/%.ml tutorial/%.o ; ../tools/build-proof.sh "$<" "$(HOLLIGHT)" "$@" diff --git a/arm/tutorial/aes_decrypt.ml b/arm/tutorial/aes_decrypt.ml deleted file mode 100644 index 45eec5cab..000000000 --- a/arm/tutorial/aes_decrypt.ml +++ /dev/null @@ -1,123 +0,0 @@ -(* - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT-0 - *) - - (****************************************************************************** - AES-256 decryption proof. -******************************************************************************) - -needs "arm/proofs/base.ml";; -needs "arm/proofs/utils/aes_decrypt_spec.ml";; - -(* The following program performs an AES-256 decryption, - with the following differences from encryption (see tutorial/aes_encrypt.ml): - - procedure EQINVCIPHER(in, Nr, dw) is the one used from the standard in order - to be able to use the same round keys in the same order as with encrypt. - - The instructions AESD and AESIMC form one AES decryption round: - AESD: AESInvSubBytes(AESInvShiftRows(operand1 XOR operand2), // XOR = AddRoundKey - AESIMC: AESInvMixColumns(operand) - The last round doesn't use AESIMC, only AESD and XOR. -*) - -let aes256_decrypt_mc = define_assert_from_elf "aes256_decrypt_mc" "arm/tutorial/aes_decrypt.o" -[ - 0xb940f046; (* arm_LDR W6 X2 (Immediate_Offset (word 240)) *) - 0x4cdf7040; (* arm_LDR Q0 X2 (Postimmediate_Offset (word 16)) *) - 0x4cdf7041; (* arm_LDR Q1 X2 (Postimmediate_Offset (word 16)) *) - 0x4c407026; (* arm_LDR Q6 X1 No_Offset *) - 0x510008c6; (* arm_SUB W6 W6 (rvalue (word 2)) *) - 0x4e285806; (* arm_AESD Q6 Q0 *) - 0x4e2878c6; (* arm_AESIMC Q6 Q6 *) - 0x4cdf7840; (* arm_LDR Q0 X2 (Postimmediate_Offset (word 16)) *) - 0x710008c6; (* arm_SUBS W6 W6 (rvalue (word 2)) *) - 0x4e285826; (* arm_AESD Q6 Q1 *) - 0x4e2878c6; (* arm_AESIMC Q6 Q6 *) - 0x4cdf7841; (* arm_LDR Q1 X2 (Postimmediate_Offset (word 16)) *) - 0x54ffff2c; (* arm_BGT (word 2097124) *) - 0x4e285806; (* arm_AESD Q6 Q0 *) - 0x4e2878c6; (* arm_AESIMC Q6 Q6 *) - 0x4c407840; (* arm_LDR Q0 X2 No_Offset *) - 0x4e285826; (* arm_AESD Q6 Q1 *) - 0x6e201cc6; (* arm_EOR_VEC Q6 Q6 Q0 128 *) - 0x4c007806 (* arm_STR Q6 X0 No_Offset *) -];; - -let AES256_DECRYPT_EXEC = ARM_MK_EXEC_RULE aes256_decrypt_mc;; - -let AES256_DECRYPT_CORRECT = prove( - `!plaintext ciphertext key ib k0 k1 k2 k3 k4 k5 k6 k7 k8 k9 k10 k11 k12 k13 k14 pc. - nonoverlapping (word pc,LENGTH aes256_decrypt_mc) (plaintext,16) - ==> ensures arm - // precondition - (\s. aligned_bytes_loaded s (word pc) aes256_decrypt_mc /\ - read PC s = word pc /\ - // uses the C ABI which puts the arguments in their order in registers x0 to x7. - // Here only 3 arguments are passed in. - C_ARGUMENTS [plaintext; ciphertext; key] s /\ - read(memory :> bytes128 ciphertext) s = ib /\ - read(memory :> bytes32 (word_add key (word 240))) s = word 14 /\ - read(memory :> bytes128 key) s = k0 /\ - read(memory :> bytes128 (word_add key (word 16))) s = k1 /\ - read(memory :> bytes128 (word_add key (word 32))) s = k2 /\ - read(memory :> bytes128 (word_add key (word 48))) s = k3 /\ - read(memory :> bytes128 (word_add key (word 64))) s = k4 /\ - read(memory :> bytes128 (word_add key (word 80))) s = k5 /\ - read(memory :> bytes128 (word_add key (word 96))) s = k6 /\ - read(memory :> bytes128 (word_add key (word 112))) s = k7 /\ - read(memory :> bytes128 (word_add key (word 128))) s = k8 /\ - read(memory :> bytes128 (word_add key (word 144))) s = k9 /\ - read(memory :> bytes128 (word_add key (word 160))) s = k10 /\ - read(memory :> bytes128 (word_add key (word 176))) s = k11 /\ - read(memory :> bytes128 (word_add key (word 192))) s = k12 /\ - read(memory :> bytes128 (word_add key (word 208))) s = k13 /\ - read(memory :> bytes128 (word_add key (word 224))) s = k14) - // postcondition - (\s. read PC s = word (pc + LENGTH aes256_decrypt_mc) /\ - read (memory :> bytes128 plaintext) s = - aes256_decrypt ib [k0; k1; k2; k3; k4; k5; k6; k7; k8; k9; k10; k11; k12; k13; k14] - ) - // Registers (and memory locations) that may change after execution - (MAYCHANGE [PC;X6;X2] ,, MAYCHANGE [Q0; Q1; Q6],, - MAYCHANGE [memory :> bytes128 plaintext],, - MAYCHANGE SOME_FLAGS,, MAYCHANGE [events])`, - - MAP_EVERY X_GEN_TAC - [`plaintext:int64`; `ciphertext:int64`; `key:int64`; - `ib:int128`; `k0:int128`; `k1:int128`; `k2:int128`; - `k3:int128`; `k4:int128`; `k5:int128`; `k6:int128`; - `k7:int128`; `k8:int128`; `k9:int128`; `k10:int128`; - `k11:int128`; `k12:int128`; `k13:int128`; `k14:int128`; `pc:num`] THEN - - (* Convert C_ARGUMENTS to reading registers x0, x1, x2 and expand SOME_FLAGS *) - REWRITE_TAC[C_ARGUMENTS; SOME_FLAGS] THEN - - (* Find the length of the program using a Conversion *) - REWRITE_TAC [(REWRITE_CONV [aes256_decrypt_mc] THENC LENGTH_CONV) `LENGTH aes256_decrypt_mc`] THEN - DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN - - (* Start symbolic execution with state 's0' *) - ENSURES_INIT_TAC "s0" THEN - (* Symbolic execution of all instructions *) - ARM_ACCSTEPS_TAC AES256_DECRYPT_EXEC [] (1--59) THEN - (* Returned; Finalize symbolic execution. *) - ENSURES_FINAL_STATE_TAC THEN - (* Use ASM_REWRITE_TAC[] to rewrite the goal using equalities in assumptions. *) - ASM_REWRITE_TAC[] THEN - - (* Use the specs to expand defintions *) - REWRITE_TAC [aes256_decrypt] THEN - - (* Replace the elements selection, EL, with the selected element - from the key round list. *) - REWRITE_TAC EL_15_128_CLAUSES THEN - - (* Expand definitions and evaluate `let` terms *) - REWRITE_TAC [aes256_decrypt_round] THEN - CONV_TAC(TOP_DEPTH_CONV let_CONV) THEN - REWRITE_TAC [aesd;aesimc] THEN - GEN_REWRITE_TAC LAND_CONV [WORD_XOR_SYM] THEN - REFL_TAC -);; diff --git a/arm/tutorial/aes_encrypt.ml b/arm/tutorial/aes_encrypt_decrypt.ml similarity index 54% rename from arm/tutorial/aes_encrypt.ml rename to arm/tutorial/aes_encrypt_decrypt.ml index c36e3269e..c9bbc5174 100644 --- a/arm/tutorial/aes_encrypt.ml +++ b/arm/tutorial/aes_encrypt_decrypt.ml @@ -141,3 +141,121 @@ let AES256_ENCRYPT_CORRECT = prove( (* GEN_REWRITE_TAC LAND_CONV [WORD_XOR_SYM] THEN REFL_TAC *) );; + +(****************************************************************************** + AES-256 decryption proof. +******************************************************************************) + +needs "arm/proofs/utils/aes_decrypt_spec.ml";; + +(* The following program performs an AES-256 decryption, + with the following differences from encryption (see tutorial/aes_encrypt.ml): + + procedure EQINVCIPHER(in, Nr, dw) is the one used from the standard in order + to be able to use the same round keys in the same order as with encrypt. + + The instructions AESD and AESIMC form one AES decryption round: + AESD: AESInvSubBytes(AESInvShiftRows(operand1 XOR operand2), // XOR = AddRoundKey + AESIMC: AESInvMixColumns(operand) + The last round doesn't use AESIMC, only AESD and XOR. +*) + +let aes256_decrypt_mc = define_assert_from_elf "aes256_decrypt_mc" "arm/tutorial/aes_decrypt.o" +[ + 0xb940f046; (* arm_LDR W6 X2 (Immediate_Offset (word 240)) *) + 0x4cdf7040; (* arm_LDR Q0 X2 (Postimmediate_Offset (word 16)) *) + 0x4cdf7041; (* arm_LDR Q1 X2 (Postimmediate_Offset (word 16)) *) + 0x4c407026; (* arm_LDR Q6 X1 No_Offset *) + 0x510008c6; (* arm_SUB W6 W6 (rvalue (word 2)) *) + 0x4e285806; (* arm_AESD Q6 Q0 *) + 0x4e2878c6; (* arm_AESIMC Q6 Q6 *) + 0x4cdf7840; (* arm_LDR Q0 X2 (Postimmediate_Offset (word 16)) *) + 0x710008c6; (* arm_SUBS W6 W6 (rvalue (word 2)) *) + 0x4e285826; (* arm_AESD Q6 Q1 *) + 0x4e2878c6; (* arm_AESIMC Q6 Q6 *) + 0x4cdf7841; (* arm_LDR Q1 X2 (Postimmediate_Offset (word 16)) *) + 0x54ffff2c; (* arm_BGT (word 2097124) *) + 0x4e285806; (* arm_AESD Q6 Q0 *) + 0x4e2878c6; (* arm_AESIMC Q6 Q6 *) + 0x4c407840; (* arm_LDR Q0 X2 No_Offset *) + 0x4e285826; (* arm_AESD Q6 Q1 *) + 0x6e201cc6; (* arm_EOR_VEC Q6 Q6 Q0 128 *) + 0x4c007806 (* arm_STR Q6 X0 No_Offset *) +];; + +let AES256_DECRYPT_EXEC = ARM_MK_EXEC_RULE aes256_decrypt_mc;; + +let AES256_DECRYPT_CORRECT = prove( + `!plaintext ciphertext key ib k0 k1 k2 k3 k4 k5 k6 k7 k8 k9 k10 k11 k12 k13 k14 pc. + nonoverlapping (word pc,LENGTH aes256_decrypt_mc) (plaintext,16) + ==> ensures arm + // precondition + (\s. aligned_bytes_loaded s (word pc) aes256_decrypt_mc /\ + read PC s = word pc /\ + // uses the C ABI which puts the arguments in their order in registers x0 to x7. + // Here only 3 arguments are passed in. + C_ARGUMENTS [plaintext; ciphertext; key] s /\ + read(memory :> bytes128 ciphertext) s = ib /\ + read(memory :> bytes32 (word_add key (word 240))) s = word 14 /\ + read(memory :> bytes128 key) s = k0 /\ + read(memory :> bytes128 (word_add key (word 16))) s = k1 /\ + read(memory :> bytes128 (word_add key (word 32))) s = k2 /\ + read(memory :> bytes128 (word_add key (word 48))) s = k3 /\ + read(memory :> bytes128 (word_add key (word 64))) s = k4 /\ + read(memory :> bytes128 (word_add key (word 80))) s = k5 /\ + read(memory :> bytes128 (word_add key (word 96))) s = k6 /\ + read(memory :> bytes128 (word_add key (word 112))) s = k7 /\ + read(memory :> bytes128 (word_add key (word 128))) s = k8 /\ + read(memory :> bytes128 (word_add key (word 144))) s = k9 /\ + read(memory :> bytes128 (word_add key (word 160))) s = k10 /\ + read(memory :> bytes128 (word_add key (word 176))) s = k11 /\ + read(memory :> bytes128 (word_add key (word 192))) s = k12 /\ + read(memory :> bytes128 (word_add key (word 208))) s = k13 /\ + read(memory :> bytes128 (word_add key (word 224))) s = k14) + // postcondition + (\s. read PC s = word (pc + LENGTH aes256_decrypt_mc) /\ + read (memory :> bytes128 plaintext) s = + aes256_decrypt ib [k0; k1; k2; k3; k4; k5; k6; k7; k8; k9; k10; k11; k12; k13; k14] + ) + // Registers (and memory locations) that may change after execution + (MAYCHANGE [PC;X6;X2] ,, MAYCHANGE [Q0; Q1; Q6],, + MAYCHANGE [memory :> bytes128 plaintext],, + MAYCHANGE SOME_FLAGS,, MAYCHANGE [events])`, + + MAP_EVERY X_GEN_TAC + [`plaintext:int64`; `ciphertext:int64`; `key:int64`; + `ib:int128`; `k0:int128`; `k1:int128`; `k2:int128`; + `k3:int128`; `k4:int128`; `k5:int128`; `k6:int128`; + `k7:int128`; `k8:int128`; `k9:int128`; `k10:int128`; + `k11:int128`; `k12:int128`; `k13:int128`; `k14:int128`; `pc:num`] THEN + + (* Convert C_ARGUMENTS to reading registers x0, x1, x2 and expand SOME_FLAGS *) + REWRITE_TAC[C_ARGUMENTS; SOME_FLAGS] THEN + + (* Find the length of the program using a Conversion *) + REWRITE_TAC [(REWRITE_CONV [aes256_decrypt_mc] THENC LENGTH_CONV) `LENGTH aes256_decrypt_mc`] THEN + DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN + + (* Start symbolic execution with state 's0' *) + ENSURES_INIT_TAC "s0" THEN + (* Symbolic execution of all instructions *) + ARM_ACCSTEPS_TAC AES256_DECRYPT_EXEC [] (1--59) THEN + (* Returned; Finalize symbolic execution. *) + ENSURES_FINAL_STATE_TAC THEN + (* Use ASM_REWRITE_TAC[] to rewrite the goal using equalities in assumptions. *) + ASM_REWRITE_TAC[] THEN + + (* Use the specs to expand defintions *) + REWRITE_TAC [aes256_decrypt] THEN + + (* Replace the elements selection, EL, with the selected element + from the key round list. *) + REWRITE_TAC EL_15_128_CLAUSES THEN + + (* Expand definitions and evaluate `let` terms *) + REWRITE_TAC [aes256_decrypt_round] THEN + CONV_TAC(TOP_DEPTH_CONV let_CONV) THEN + REWRITE_TAC [aesd;aesimc] THEN + GEN_REWRITE_TAC LAND_CONV [WORD_XOR_SYM] THEN + REFL_TAC +);; From d1962083eba626ae4a486d675436439ad4bc0ba5 Mon Sep 17 00:00:00 2001 From: Nevine Ebeid Date: Mon, 26 Jan 2026 11:28:56 -0500 Subject: [PATCH 129/132] Put specs for list and tweak calculation in a common spec file. Add ASCII drawing to explain the cipher-stealing loop invariant. Address comments on decrypt proof. --- arm/proofs/aes_xts_decrypt.ml | 26 +-- arm/proofs/aes_xts_encrypt.ml | 58 ++++--- arm/proofs/utils/aes_xts_common_spec.ml | 207 +++++++++++++++++++++++ arm/proofs/utils/aes_xts_decrypt_spec.ml | 56 +----- arm/proofs/utils/aes_xts_encrypt_spec.ml | 130 +------------- 5 files changed, 258 insertions(+), 219 deletions(-) create mode 100644 arm/proofs/utils/aes_xts_common_spec.ml diff --git a/arm/proofs/aes_xts_decrypt.ml b/arm/proofs/aes_xts_decrypt.ml index 79adf1bac..79738372d 100644 --- a/arm/proofs/aes_xts_decrypt.ml +++ b/arm/proofs/aes_xts_decrypt.ml @@ -762,8 +762,7 @@ let LENGTH_OF_AES256_XTS_DECRYPT_REC = prove( ONCE_REWRITE_TAC[aes256_xts_decrypt_rec] THEN COND_CASES_TAC THENL [ SIMP_TAC[LENGTH_EQ_NIL]; - SIMP_TAC[] THEN - REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + CONV_TAC (DEPTH_CONV let_CONV) THEN REWRITE_TAC[LENGTH_APPEND] THEN SUBGOAL_THEN `~(m < i) ==> (m + 1) - (i + 1) < (m + 1) - i` ASSUME_TAC THENL [ ASM_ARITH_TAC ; ALL_TAC ] THEN @@ -1415,27 +1414,14 @@ let AESDEC_TAC = GEN_REWRITE_TAC LAND_CONV [WORD_XOR_SYM] THEN REFL_TAC;; let TWEAK_UPDATE_CONV = - let ADD_SUC_1 = ARITH_RULE `!n. n + 1 = SUC(n)` in - let ADD_SUC_2 = ARITH_RULE `!n. n + 2 = SUC(n + 1)` in - let ADD_SUC_3 = ARITH_RULE `!n. n + 3 = SUC(n + 2)` in - let ADD_SUC_4 = ARITH_RULE `!n. n + 4 = SUC(n + 3)` in - let ADD_SUC_5 = ARITH_RULE `!n. n + 5 = SUC(n + 4)` in - let ADD_SUC_6 = ARITH_RULE `!n. n + 6 = SUC(n + 5)` in - let ADD_SUC_7 = ARITH_RULE `!n. n + 7 = SUC(n + 6)` in - let ADD_SUC_8 = ARITH_RULE `!n. n + 8 = SUC(n + 7)` in - let ADD_SUC_9 = ARITH_RULE `!n. n + 9 = SUC(n + 8)` in + let thms = CONJUNCTS + ((REWRITE_RULE[ARITH; ADD_0] o + CONV_RULE EXPAND_CASES_CONV o ARITH_RULE) + `forall i. i < 9 ==> forall n. n + SUC i = SUC (n + i)`) in NUM_REDUCE_CONV THENC RATOR_CONV (LAND_CONV (num_CONV ORELSEC FIRST_CONV - [ CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_1]); - CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_2]); - CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_3]); - CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_4]); - CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_5]); - CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_6]); - CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_7]); - CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_8]); - CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_9]);])) THENC + (map (fun th -> CHANGED_CONV (ONCE_REWRITE_CONV [th])) thms))) THENC REWRITE_CONV [CONJUNCT2 calculate_tweak] THENC GF_128_MULT_BY_PRIMITIVE_CONV;; diff --git a/arm/proofs/aes_xts_encrypt.ml b/arm/proofs/aes_xts_encrypt.ml index 2a32e6931..b8a4eb04b 100644 --- a/arm/proofs/aes_xts_encrypt.ml +++ b/arm/proofs/aes_xts_encrypt.ml @@ -735,8 +735,7 @@ let LENGTH_OF_AES256_XTS_ENCRYPT_REC = prove( ONCE_REWRITE_TAC[aes256_xts_encrypt_rec] THEN COND_CASES_TAC THENL [ SIMP_TAC[LENGTH_EQ_NIL]; - SIMP_TAC[] THEN - REWRITE_TAC[LET_DEF; LET_END_DEF] THEN + CONV_TAC (DEPTH_CONV let_CONV) THEN REWRITE_TAC[LENGTH_APPEND] THEN SUBGOAL_THEN `~(m < i) ==> (m + 1) - (i + 1) < (m + 1) - i` ASSUME_TAC THENL [ ASM_ARITH_TAC ; ALL_TAC ] THEN @@ -1316,27 +1315,14 @@ let AESXTS_ENC_ONE_BLOCK_TAC = BITBLAST_TAC;; let TWEAK_UPDATE_CONV = - let ADD_SUC_1 = ARITH_RULE `!n. n + 1 = SUC(n)` in - let ADD_SUC_2 = ARITH_RULE `!n. n + 2 = SUC(n + 1)` in - let ADD_SUC_3 = ARITH_RULE `!n. n + 3 = SUC(n + 2)` in - let ADD_SUC_4 = ARITH_RULE `!n. n + 4 = SUC(n + 3)` in - let ADD_SUC_5 = ARITH_RULE `!n. n + 5 = SUC(n + 4)` in - let ADD_SUC_6 = ARITH_RULE `!n. n + 6 = SUC(n + 5)` in - let ADD_SUC_7 = ARITH_RULE `!n. n + 7 = SUC(n + 6)` in - let ADD_SUC_8 = ARITH_RULE `!n. n + 8 = SUC(n + 7)` in - let ADD_SUC_9 = ARITH_RULE `!n. n + 9 = SUC(n + 8)` in + let thms = CONJUNCTS + ((REWRITE_RULE[ARITH; ADD_0] o + CONV_RULE EXPAND_CASES_CONV o ARITH_RULE) + `forall i. i < 9 ==> forall n. n + SUC i = SUC (n + i)`) in NUM_REDUCE_CONV THENC RATOR_CONV (LAND_CONV (num_CONV ORELSEC FIRST_CONV - [ CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_1]); - CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_2]); - CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_3]); - CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_4]); - CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_5]); - CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_6]); - CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_7]); - CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_8]); - CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_9]);])) THENC + (map (fun th -> CHANGED_CONV (ONCE_REWRITE_CONV [th])) thms))) THENC REWRITE_CONV [CONJUNCT2 calculate_tweak] THENC GF_128_MULT_BY_PRIMITIVE_CONV;; @@ -1791,6 +1777,38 @@ let CIPHER_STEALING_ENC_CORRECT = time prove( [tail_len,16] -- previous decryption result, CP Memory: For the tail, Cm, pointed to by X13, for each byte [i,tail_len) -- copied over from Pm block + + +----------------+ +----------------+ + | P_m-1 | | P_m | CP | + +----------------+ +----------------+ + | ^ | + | <-- | | + l1_curr_len | Enc curr_len x21 | Enc + | | | | | + v v v +---------+ v + +----------------+ | +----------------+ + | C_m | CP | | | C_m-1 | + +----------------+ | +--------+-------+ + ^ ^ | | + | <-- | | | + x1 x21 (decreasing offset) | | + || | | + +------------------------+ | + | (2) | + +------------------------------+ | + (1) | | + +----------------+ +---v--+ | + | C_m-1 | | C_m | | + +----------------+ +------+ | + ^ ^ ^ | + | | | | + x1 | (3) x13 | + +----------------------------------+ + + 1, 2 and 3 are order of moving bytes because they're written to the same place. + - 1 and 2 are in a loop iterating over the bytes at offset x21 + - 3 is after the loop and last block encryption (decryption) writing the block at the output at x1 + *) ENSURES_WHILE_PADOWN_TAC diff --git a/arm/proofs/utils/aes_xts_common_spec.ml b/arm/proofs/utils/aes_xts_common_spec.ml new file mode 100644 index 000000000..59cabd5ed --- /dev/null +++ b/arm/proofs/utils/aes_xts_common_spec.ml @@ -0,0 +1,207 @@ +(* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT-0 + *) + (* Common definitions between AES-XTS encrypt and decrypt specs. *) + +needs "common/aes.ml";; +needs "arm/proofs/utils/aes_encrypt_spec.ml";; +(* +let pp_print_num fmt tm = + let n = dest_numeral tm in + pp_print_string fmt (string_of_num_hex n) in +install_user_printer("pp_print_num",pp_print_num);; +*) + +(* Helper functions derived from Amanda's code: + https://github.com/amanda-zx/s2n-bignum/blob/sha512/arm/sha512/sha512_specs.ml#L360 *) + + let bytes_to_int128 = define + `bytes_to_int128 (bs : byte list) : int128 = + word_join + (word_join + (word_join (word_join (EL 15 bs) (EL 14 bs) : int16) (word_join (EL 13 bs) (EL 12 bs) : int16) : int32) + (word_join (word_join (EL 11 bs) (EL 10 bs) : int16) (word_join (EL 9 bs) (EL 8 bs) : int16) : int32) : int64) + (word_join + (word_join (word_join (EL 7 bs) (EL 6 bs) : int16) (word_join (EL 5 bs) (EL 4 bs) : int16) : int32) + (word_join (word_join (EL 3 bs) (EL 2 bs) : int16) (word_join (EL 1 bs) (EL 0 bs) : int16) : int32) : int64)`;; + +let int128_to_bytes = define + `int128_to_bytes (w : int128) : byte list = + [word_subword w (0, 8); word_subword w (8, 8); word_subword w (16, 8); word_subword w (24, 8); + word_subword w (32, 8); word_subword w (40, 8); word_subword w (48, 8); word_subword w (56, 8); + word_subword w (64, 8); word_subword w (72, 8); word_subword w (80, 8); word_subword w (88, 8); + word_subword w (96, 8); word_subword w (104, 8); word_subword w (112, 8); word_subword w (120, 8)]`;; + +(* XTS tweak initialization - encrypt the IV with key2 *) +let xts_init_tweak = new_definition + `xts_init_tweak (iv:int128) (key2:int128 list) = + aes256_encrypt iv key2`;; + +(* Note: the implementation sequences the calculation of the tweak for each block, + however, the specification will calculate the tweak from the very beginning for each block. + We write the specification in the sequenced version for proof simplicity. *) + +(* Multiplication by the primitive element \alpha in GF(2^128) *) +(* Same as the pseudo code of multiplying by \alpha in Annex C of the spec. *) +let GF_128_mult_by_primitive = new_definition + `GF_128_mult_by_primitive (tweak:(128)word) = + let shifted = word_shl tweak 1 in + let mask = word_ishr tweak 127 in + word_xor (word_and mask (word 0x87)) shifted`;; + +let calculate_tweak = new_recursive_definition num_RECURSION + `calculate_tweak 0 (iv:(128)word) (key2:int128 list) = xts_init_tweak iv key2 /\ + calculate_tweak (SUC n) (iv:(128)word) (key2:int128 list) = + GF_128_mult_by_primitive (calculate_tweak n iv key2)`;; + +(***********************************************) +(* Conversions and test vectors *) + +let EL_16_8_CLAUSES = + let pat = `EL n [x0;x1;x2;x3;x4;x5;x6;x7;x8;x9;x10;x11;x12;x13;x14;x15]:byte` in + map (fun n -> EL_CONV(subst [mk_small_numeral n,`n:num`] pat)) (0--15);; + +let BYTES_TO_INT128_CONV = + REWR_CONV bytes_to_int128 THENC + REWRITE_CONV EL_16_8_CLAUSES THENC + DEPTH_CONV WORD_RED_CONV;; +(* +let ptext = new_definition + `ptext = + int128_to_bytes (word 0x0F0E0D0C0B0A09080706050403020100 : int128)`;; + +time prove(`bytes_to_int128 ptext + = (word 0x0f0e0d0c0b0a09080706050403020100 :int128)`, + CONV_TAC(REWRITE_CONV [ptext;int128_to_bytes] THENC + LAND_CONV BYTES_TO_INT128_CONV) THEN + REFL_TAC + );; +*) + +let INT128_TO_BYTES_CONV = + REWRITE_CONV [int128_to_bytes] THENC + DEPTH_CONV WORD_RED_CONV;; +(* INT128_TO_BYTES_CONV `int128_to_bytes (word 0x0102030405060708090a0b0c0d0e0f)`;; *) + +let GF_128_MULT_BY_PRIMITIVE_CONV = + REWRITE_CONV [GF_128_mult_by_primitive] THENC + REPEATC let_CONV THENC + DEPTH_CONV WORD_RED_CONV;; +(* GF_128_MULT_BY_PRIMITIVE_CONV + `GF_128_mult_by_primitive (word 0x8b2b4a71228e98aed6aa0ca97775261a)`;; *) + +time prove(`GF_128_mult_by_primitive (word 0x8b2b4a71228e98aed6aa0ca97775261a) + = (word 0x165694e2451d315dad541952eeea4cb3 : int128)`, + CONV_TAC(LAND_CONV GF_128_MULT_BY_PRIMITIVE_CONV) THEN REFL_TAC + );; + +let XTS_INIT_TWEAK_CONV = + REWR_CONV xts_init_tweak THENC AESENC_HELPER_CONV;; + +let iv1 = new_definition + `iv1 = (word 0x000000000000000000000000000000FF) : int128`;; + +let tweak_key_schedule = new_definition `tweak_key_schedule:int128 list = + [ word 0x95278333646284239397585326594131 + ; word 0x92459474098205513799931697418802 + ; word 0xD6C4705143E3F36227817741B4162F12 + ; word 0xCD03DBE05F464F9456C44AC5615DD9D3 + ; word 0xE70DA0DB31C9D08A722A23E855AB54A9 + ; word 0x310BE7DBFC083C3BA34E73AFF58A396A + ; word 0x48822C80AF8F8C5B9E465CD1EC6C7F39 + ; word 0xC9D4E0E8F8DF073304D73B08A79948A7 + ; word 0x0EFACBDA4678E75AE9F76B0177B137D0 + ; word 0x39688B23F0BC6BCB08636CF80CB457F0 + ; word 0xF0D6357CFE2CFEA6B85419FC51A372FD + ; word 0x41F54DF0789DC6D38821AD188042C1E0 + ; word 0x6B8E46189B58736465748DC2DD20943E + ; word 0x4E12BD760FE7F086777A3655FF5B9B4D + ; word 0x70ADE5BA1B23A3A2807BD0C6E50F5D04 + ]`;; + +(* +let tmp_xts_tweak = (REWRITE_CONV [iv1; tweak_key_schedule] THENC XTS_INIT_TWEAK_CONV) + `xts_init_tweak iv1 + tweak_key_schedule`;; +(* Or the following: 36 sec on M3 *) +time prove(`xts_init_tweak iv1 + tweak_key_schedule + = word 0x8b2b4a71228e98aed6aa0ca97775261a`, + CONV_TAC(REWRITE_CONV [iv1; tweak_key_schedule] THENC + LAND_CONV XTS_INIT_TWEAK_CONV) + THEN REFL_TAC + );; +*) + +let rec CALCULATE_TWEAK_CONV tm = + let BASE_CONV = + ONCE_REWRITE_CONV [calculate_tweak] THENC + XTS_INIT_TWEAK_CONV in + let INDUCT_CONV = + RATOR_CONV(LAND_CONV num_CONV) THENC (* ((calculate_tweak 1) iv) key2 *) + (* PRINT_TERM_CONV THENC*) + ONCE_REWRITE_CONV [CONJUNCT2 calculate_tweak] THENC + RAND_CONV CALCULATE_TWEAK_CONV THENC + GF_128_MULT_BY_PRIMITIVE_CONV in + match tm with + | Comb + (Comb + (Comb + (Const ("calculate_tweak",_), n), + _), + _) -> + if dest_numeral n =/ num 0 + then BASE_CONV tm + else INDUCT_CONV tm + | _ -> failwith "CALCULATE_TWEAK_CONV: inapplicable";; +(* +(* result: word 0x8b2b4a71228e98aed6aa0ca97775261a, same as xts_init_tweak test above *) +(REWRITE_CONV [iv1;tweak_key_schedule] THENC CALCULATE_TWEAK_CONV) `calculate_tweak 0 iv1 tweak_key_schedule`;; + +(* result: word 0x165694e2451d315dad541952eeea4cb3, same as GF_128_mult_by_primitive test above *) +(REWRITE_CONV [iv1;tweak_key_schedule] THENC CALCULATE_TWEAK_CONV) `calculate_tweak 1 iv1 tweak_key_schedule`;; +*) + +(* +The following conversion (in its second form) is included directly where it's used in +aes_xts_encrypt.ml and +aes_xts_decrypt.ml + +let TWEAK_UPDATE_CONV = + let ADD_SUC_1 = ARITH_RULE `!n. n + 1 = SUC(n)` in + let ADD_SUC_2 = ARITH_RULE `!n. n + 2 = SUC(n + 1)` in + let ADD_SUC_3 = ARITH_RULE `!n. n + 3 = SUC(n + 2)` in + let ADD_SUC_4 = ARITH_RULE `!n. n + 4 = SUC(n + 3)` in + let ADD_SUC_5 = ARITH_RULE `!n. n + 5 = SUC(n + 4)` in + let ADD_SUC_6 = ARITH_RULE `!n. n + 6 = SUC(n + 5)` in + let ADD_SUC_7 = ARITH_RULE `!n. n + 7 = SUC(n + 6)` in + let ADD_SUC_8 = ARITH_RULE `!n. n + 8 = SUC(n + 7)` in + let ADD_SUC_9 = ARITH_RULE `!n. n + 9 = SUC(n + 8)` in + NUM_REDUCE_CONV THENC + RATOR_CONV (LAND_CONV (num_CONV ORELSEC + FIRST_CONV + [ CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_1]); + CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_2]); + CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_3]); + CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_4]); + CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_5]); + CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_6]); + CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_7]); + CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_8]); + CHANGED_CONV (ONCE_REWRITE_CONV [ADD_SUC_9]);])) THENC + REWRITE_CONV [CONJUNCT2 calculate_tweak] THENC + GF_128_MULT_BY_PRIMITIVE_CONV;; + +let TWEAK_UPDATE_CONV = + let thms = CONJUNCTS + ((REWRITE_RULE[ARITH; ADD_0] o + CONV_RULE EXPAND_CASES_CONV o ARITH_RULE) + `forall i. i < 9 ==> forall n. n + SUC i = SUC (n + i)`) in + NUM_REDUCE_CONV THENC + RATOR_CONV (LAND_CONV (num_CONV ORELSEC + FIRST_CONV + (map (fun th -> CHANGED_CONV (ONCE_REWRITE_CONV [th])) thms))) THENC + REWRITE_CONV [CONJUNCT2 calculate_tweak] THENC + GF_128_MULT_BY_PRIMITIVE_CONV;; +*) \ No newline at end of file diff --git a/arm/proofs/utils/aes_xts_decrypt_spec.ml b/arm/proofs/utils/aes_xts_decrypt_spec.ml index 20cc4bd5d..2defc36e4 100644 --- a/arm/proofs/utils/aes_xts_decrypt_spec.ml +++ b/arm/proofs/utils/aes_xts_decrypt_spec.ml @@ -3,8 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT-0 *) -needs "common/aes.ml";; -needs "arm/proofs/utils/aes_encrypt_spec.ml";; +needs "arm/proofs/utils/aes_xts_common_spec.ml";; needs "arm/proofs/utils/aes_decrypt_spec.ml";; (* @@ -24,10 +23,10 @@ https://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=8637988 Section 5.4.1 -a) T ← AES-enc(Key2, i) ⊗ αj -b) CC ← C ⊕ T -c) PP ← AES-dec(Key1, CC) -d) P ← PP ⊕ T +a) T := AES-enc(Key2, i) MUL alpha^j +b) CC := C XOR T +c) PP := AES-dec(Key1, CC) +d) P := PP XOR T *) @@ -50,51 +49,6 @@ let aes256_xts_decrypt_1block = new_definition (*******************************************) (* AES-XTS decryption *) -(* Helper functions derived from Amanda's code: - https://github.com/amanda-zx/s2n-bignum/blob/sha512/arm/sha512/sha512_specs.ml#L360 -*) -let bytes_to_int128 = define - `bytes_to_int128 (bs : byte list) : int128 = - word_join - (word_join - (word_join (word_join (EL 15 bs) (EL 14 bs) : int16) (word_join (EL 13 bs) (EL 12 bs) : int16) : int32) - (word_join (word_join (EL 11 bs) (EL 10 bs) : int16) (word_join (EL 9 bs) (EL 8 bs) : int16) : int32) : int64) - (word_join - (word_join (word_join (EL 7 bs) (EL 6 bs) : int16) (word_join (EL 5 bs) (EL 4 bs) : int16) : int32) - (word_join (word_join (EL 3 bs) (EL 2 bs) : int16) (word_join (EL 1 bs) (EL 0 bs) : int16) : int32) : int64)`;; - -let int128_to_bytes = define - `int128_to_bytes (w : int128) : byte list = - [word_subword w (0, 8); - word_subword w (8, 8); - word_subword w (16, 8); - word_subword w (24, 8); - word_subword w (32, 8); - word_subword w (40, 8); - word_subword w (48, 8); - word_subword w (56, 8); - word_subword w (64, 8); - word_subword w (72, 8); - word_subword w (80, 8); - word_subword w (88, 8); - word_subword w (96, 8); - word_subword w (104, 8); - word_subword w (112, 8); - word_subword w (120, 8)]`;; - -(* Multiplication by the primitive element \alpha in GF(2^128) *) -let GF_128_mult_by_primitive = new_definition - `GF_128_mult_by_primitive - (tweak:(128)word) = - let shifted = word_shl tweak 1 in - let mask = word_ishr tweak 127 in - word_xor (word_and mask (word 0x87)) shifted`;; - -let calculate_tweak = new_recursive_definition num_RECURSION - `calculate_tweak 0 (iv:(128)word) (key2:int128 list) = xts_init_tweak iv key2 /\ - calculate_tweak (SUC n) (iv:(128)word) (key2:int128 list) = - GF_128_mult_by_primitive (calculate_tweak n iv key2)`;; - let eth = prove_general_recursive_function_exists `?aes256_xts_decrypt_rec. ! (i:num) (m:num) (C:byte list) (iv:int128) (key1:int128 list) (key2:int128 list). diff --git a/arm/proofs/utils/aes_xts_encrypt_spec.ml b/arm/proofs/utils/aes_xts_encrypt_spec.ml index c092774d6..1c0379aae 100644 --- a/arm/proofs/utils/aes_xts_encrypt_spec.ml +++ b/arm/proofs/utils/aes_xts_encrypt_spec.ml @@ -3,8 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT-0 *) -needs "common/aes.ml";; -needs "arm/proofs/utils/aes_encrypt_spec.ml";; +needs "arm/proofs/utils/aes_xts_common_spec.ml";; (* AES-256-XTS Encryption Algorithm for Any Input Length @@ -37,51 +36,6 @@ For partial final blocks, ciphertext stealing is used as per Section 5.3.2. (*****************************************) (* AES-XTS encryption full *) -(* Note: the implementation sequences the calculation of the tweak for each block, - however, the specification will calculate the tweak from the very beginning for each block. - We write the specification in the sequenced version for proof simplicity. *) - -(* Helper functions derived from Amanda's code: - https://github.com/amanda-zx/s2n-bignum/blob/sha512/arm/sha512/sha512_specs.ml#L360 *) - -(* TODO: put it in a common place to be used with decrypt - Start *) -let bytes_to_int128 = define - `bytes_to_int128 (bs : byte list) : int128 = - word_join - (word_join - (word_join (word_join (EL 15 bs) (EL 14 bs) : int16) (word_join (EL 13 bs) (EL 12 bs) : int16) : int32) - (word_join (word_join (EL 11 bs) (EL 10 bs) : int16) (word_join (EL 9 bs) (EL 8 bs) : int16) : int32) : int64) - (word_join - (word_join (word_join (EL 7 bs) (EL 6 bs) : int16) (word_join (EL 5 bs) (EL 4 bs) : int16) : int32) - (word_join (word_join (EL 3 bs) (EL 2 bs) : int16) (word_join (EL 1 bs) (EL 0 bs) : int16) : int32) : int64)`;; - -let int128_to_bytes = define - `int128_to_bytes (w : int128) : byte list = - [word_subword w (0, 8); word_subword w (8, 8); word_subword w (16, 8); word_subword w (24, 8); - word_subword w (32, 8); word_subword w (40, 8); word_subword w (48, 8); word_subword w (56, 8); - word_subword w (64, 8); word_subword w (72, 8); word_subword w (80, 8); word_subword w (88, 8); - word_subword w (96, 8); word_subword w (104, 8); word_subword w (112, 8); word_subword w (120, 8)]`;; - -(* XTS tweak initialization - encrypt the IV with key2 *) -let xts_init_tweak = new_definition - `xts_init_tweak (iv:int128) (key2:int128 list) = - aes256_encrypt iv key2`;; - -(* Multiplication by the primitive element \alpha in GF(2^128) *) -let GF_128_mult_by_primitive = new_definition - `GF_128_mult_by_primitive (tweak:(128)word) = - let shifted = word_shl tweak 1 in - let mask = word_ishr tweak 127 in - word_xor (word_and mask (word 0x87)) shifted`;; - -let calculate_tweak = new_recursive_definition num_RECURSION - `calculate_tweak 0 (iv:(128)word) (key2:int128 list) = xts_init_tweak iv key2 /\ - calculate_tweak (SUC n) (iv:(128)word) (key2:int128 list) = - GF_128_mult_by_primitive (calculate_tweak n iv key2)`;; - -(* TODO: put it in a common place to be used with decrypt - End *) (* AES-XTS encryption round function *) let aes256_xts_encrypt_round = new_definition `aes256_xts_encrypt_round (P:int128) (tk:int128) (key1:int128 list) = @@ -160,8 +114,7 @@ let aes256_xts_encrypt_tail = new_definition return: Output ciphertext as a byte list When input len < 16, the function returns []. *) -(* TODO: Double check if NIST spec talks about the error case len < 16 *) -(* TODO: Double check the pseudo code in the spec for tweak calculation in ANEX c *) + let aes256_xts_encrypt = new_definition `aes256_xts_encrypt (P:byte list) (len:num) (iv:int128) (key1:int128 list) (key2:int128 list) : byte list = @@ -402,22 +355,6 @@ let key_2 = new_definition `key_2:int128 list = ]`;; -(* Common with decrypt *) -let XTS_INIT_TWEAK_CONV = - REWR_CONV xts_init_tweak THENC AESENC_HELPER_CONV;; -(* -let tmp_xts_tweak = (REWRITE_CONV [iv1; tweak_key_schedule] THENC XTS_INIT_TWEAK_CONV) - `xts_init_tweak iv1 - tweak_key_schedule`;; -(* Or the following: 33 sec *) -time prove(`xts_init_tweak iv1 - tweak_key_schedule - = word 0x8b2b4a71228e98aed6aa0ca97775261a`, - CONV_TAC(REWRITE_CONV [iv1; tweak_key_schedule] THENC LAND_CONV XTS_INIT_TWEAK_CONV) - THEN REFL_TAC - );; -*) - (* let AES_XTS_ENC_1BLK_HELPER_CONV = (* PRINT_TERM_CONV THENC *) @@ -506,70 +443,7 @@ time prove(`aes256_xts_encrypt_1block );; *) -(* Common with decrypt *) -let EL_16_8_CLAUSES = - let pat = `EL n [x0;x1;x2;x3;x4;x5;x6;x7;x8;x9;x10;x11;x12;x13;x14;x15]:byte` in - map (fun n -> EL_CONV(subst [mk_small_numeral n,`n:num`] pat)) (0--15);; - -let BYTES_TO_INT128_CONV = - REWR_CONV bytes_to_int128 THENC - REWRITE_CONV EL_16_8_CLAUSES THENC - DEPTH_CONV WORD_RED_CONV;; -(* -time prove(`bytes_to_int128 ptext - = (word 0x0f0e0d0c0b0a09080706050403020100 :int128)`, - CONV_TAC(REWRITE_CONV [ptext;int128_to_bytes] THENC - LAND_CONV BYTES_TO_INT128_CONV) THEN - REFL_TAC - );; -*) - -(* Common with decrypt *) -let INT128_TO_BYTES_CONV = - REWRITE_CONV [int128_to_bytes] THENC - DEPTH_CONV WORD_RED_CONV;; -(* INT128_TO_BYTES_CONV `int128_to_bytes (word 0x0102030405060708090a0b0c0d0e0f)`;; *) - -(* Common with decrypt *) -let GF_128_MULT_BY_PRIMITIVE_CONV = - REWRITE_CONV [GF_128_mult_by_primitive] THENC - REPEATC let_CONV THENC - DEPTH_CONV WORD_RED_CONV;; -(* GF_128_MULT_BY_PRIMITIVE_CONV - `GF_128_mult_by_primitive (word 0x8b2b4a71228e98aed6aa0ca97775261a)`;; *) -time prove(`GF_128_mult_by_primitive (word 0x8b2b4a71228e98aed6aa0ca97775261a) - = (word 0x165694e2451d315dad541952eeea4cb3 : int128)`, - CONV_TAC(LAND_CONV GF_128_MULT_BY_PRIMITIVE_CONV) THEN REFL_TAC - );; -let rec CALCULATE_TWEAK_CONV tm = - let BASE_CONV = - ONCE_REWRITE_CONV [calculate_tweak] THENC - XTS_INIT_TWEAK_CONV in - let INDUCT_CONV = - RATOR_CONV(LAND_CONV num_CONV) THENC (* ((calculate_tweak 1) iv_tweak) key_2 *) - (* PRINT_TERM_CONV THENC*) - ONCE_REWRITE_CONV [CONJUNCT2 calculate_tweak] THENC - RAND_CONV CALCULATE_TWEAK_CONV THENC - GF_128_MULT_BY_PRIMITIVE_CONV in - match tm with - | Comb - (Comb - (Comb - (Const ("calculate_tweak",_), n), - _), - _) -> - if dest_numeral n =/ num 0 - then BASE_CONV tm - else INDUCT_CONV tm - | _ -> failwith "CALCULATE_TWEAK_CONV: inapplicable";; -(* -(* result: word 0x8b2b4a71228e98aed6aa0ca97775261a, confirmed by input to first encrypt_round above *) -(REWRITE_CONV [iv1;tweak_key_schedule] THENC CALCULATE_TWEAK_CONV) `calculate_tweak 0 iv1 tweak_key_schedule`;; -*)(* -(* result: word 0x165694e2451d315dad541952eeea4cb3, confirmed by input to second encrypt_round above *) -(REWRITE_CONV [iv1;tweak_key_schedule] THENC CALCULATE_TWEAK_CONV) `calculate_tweak 1 iv1 tweak_key_schedule`;; -*) let rec AES256_XTS_ENCRYPT_REC_CONV tm = let BASE_CONV = From 2d46477e2022611c3acca8dff3709c235bf6aaff Mon Sep 17 00:00:00 2001 From: Nevine Ebeid Date: Mon, 26 Jan 2026 16:37:24 -0500 Subject: [PATCH 130/132] Update the name of the encrypt subroutine theorem to match the decrypt one. --- arm/proofs/aes_xts_encrypt.ml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arm/proofs/aes_xts_encrypt.ml b/arm/proofs/aes_xts_encrypt.ml index b8a4eb04b..6ae4716f6 100644 --- a/arm/proofs/aes_xts_encrypt.ml +++ b/arm/proofs/aes_xts_encrypt.ml @@ -5560,7 +5560,7 @@ let AES256_XTS_ENCRYPT_CORRECT = prove( ASM_SIMP_TAC[] );; -let AES256_XTS_ENCRYPT_SUBROUTINE_CORRECT = prove( +let AES_XTS_ENCRYPT_SUBROUTINE_CORRECT = prove( `!ptxt_p ctxt_p len key1_p key2_p iv_p pt_in iv k1_0 k1_1 k1_2 k1_3 k1_4 k1_5 k1_6 k1_7 k1_8 k1_9 k1_10 k1_11 k1_12 k1_13 k1_14 From 1a615ae99de035c8e4f1545e434e0e433ad538c1 Mon Sep 17 00:00:00 2001 From: Juneyoung Lee Date: Wed, 14 Jan 2026 23:30:15 +0000 Subject: [PATCH 131/132] Prove CIPHER_STEALING_SAFE of aes-xts decrypt Special thanks to Opus. Also, add abbrevs_unfold_before_f_events_tac to DISCHARGE_SAFETY_PROPERTY_TAC --- arm/proofs/aes_xts_decrypt.ml | 478 ++++++++++++++++++++++++++++++++++ common/consttime.ml | 16 +- 2 files changed, 490 insertions(+), 4 deletions(-) diff --git a/arm/proofs/aes_xts_decrypt.ml b/arm/proofs/aes_xts_decrypt.ml index 79738372d..833eb50e9 100644 --- a/arm/proofs/aes_xts_decrypt.ml +++ b/arm/proofs/aes_xts_decrypt.ml @@ -7,6 +7,7 @@ (* ========================================================================= *) needs "arm/proofs/utils/aes_xts_common.ml";; +needs "arm/proofs/consttime.ml";; (* print_literal_from_elf "arm/aes-xts/aes_xts_decrypt.o";; *) let aes_xts_decrypt_mc = define_assert_from_elf "aes_xts_decrypt_mc" "arm/aes-xts/aes_xts_decrypt.o" @@ -2374,6 +2375,483 @@ let CIPHER_STEALING_CORRECT = time prove( ] );; +let CIPHER_STEALING_SAFE = time prove( + `exists f_events. + forall ct_ptr pt_ptr key1_ptr len pc + tail_len num_blocks num_blocks_adjusted num_5blocks_adjusted. + nonoverlapping (word pc, LENGTH aes_xts_decrypt_mc) (pt_ptr, val len) + /\ nonoverlapping (ct_ptr, val len) (pt_ptr, val len) + /\ nonoverlapping (key1_ptr, 260) (pt_ptr, val len) + /\ val len >= 16 /\ val len <= 2 EXP 24 + /\ word_add tail_len num_blocks = len + /\ word_and len (word 0xfffffffffffffff0) = num_blocks + /\ word_and len (word 0xf) = tail_len + /\ (if val tail_len = 0x0 then num_blocks else word_sub num_blocks (word 0x10)) = num_blocks_adjusted + /\ word (val num_blocks_adjusted DIV 0x50) = num_5blocks_adjusted + ==> ensures arm + (\s. aligned_bytes_loaded s (word pc) aes_xts_decrypt_mc /\ + read PC s = word (pc + 0xa0c) /\ + read X0 s = word_add ct_ptr (word (acc_len num_5blocks_adjusted num_blocks_adjusted)) /\ + read X1 s = word_add pt_ptr (word (acc_len num_5blocks_adjusted num_blocks_adjusted)) /\ + read X3 s = key1_ptr /\ + read X21 s = tail_len /\ + read X19 s = word 0x87 /\ + read events s = e) + (\s. read PC s = word (pc + 0xb58) /\ + exists e2. + read events s = APPEND e2 e /\ + e2 = f_events ct_ptr pt_ptr key1_ptr tail_len num_blocks_adjusted + num_5blocks_adjusted pc /\ + memaccess_inbounds e2 + [(ct_ptr, val len); (pt_ptr, val len); (key1_ptr, 260)] + [(pt_ptr, val len)]) + (MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI,, + MAYCHANGE [X19; X20; X21; X22],, + MAYCHANGE [Q8; Q9; Q10; Q11; Q12; Q13; Q14; Q15],, + MAYCHANGE [memory :> bytes(pt_ptr, val len)])`, + + CONCRETIZE_F_EVENTS_TAC + `\(ct_ptr:int64) (pt_ptr:int64) (key1_ptr:int64) (tail_len:int64) + (num_blocks_adjusted:int64) (num_5blocks_adjusted:int64) (pc:num). + if val (tail_len) = 0 then + f_ev_short ct_ptr pt_ptr key1_ptr tail_len num_blocks_adjusted + num_5blocks_adjusted pc + else + APPEND + (APPEND + (f_ev_epil ct_ptr pt_ptr key1_ptr tail_len num_blocks_adjusted + num_5blocks_adjusted pc) + (APPEND + (ENUMERATEL (val tail_len) + (f_ev_loop ct_ptr pt_ptr key1_ptr tail_len num_blocks_adjusted + num_5blocks_adjusted pc)) + (f_ev_prol ct_ptr pt_ptr key1_ptr tail_len num_blocks_adjusted + num_5blocks_adjusted pc)) + ) + (f_ev_pre ct_ptr pt_ptr key1_ptr tail_len num_blocks_adjusted + num_5blocks_adjusted pc) + :(uarch_event)list` THEN + REPEAT META_EXISTS_TAC THEN + + REWRITE_TAC [(REWRITE_CONV [aes_xts_decrypt_mc] THENC LENGTH_CONV) `LENGTH aes_xts_decrypt_mc`] THEN + REWRITE_TAC[set_key_schedule; C_ARGUMENTS; SOME_FLAGS; + NONOVERLAPPING_CLAUSES; byte_list_at; + MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI] THEN + REPEAT STRIP_TAC THEN + + (* Prove once and for all the bounds for num_blocks, num_blocks_adjusted + and num_5blocks_adjusted *) + SUBGOAL_THEN `~(val (num_blocks:int64) < 16)` ASSUME_TAC THENL + [ SUBGOAL_THEN `~(val (len:int64) < 16)` MP_TAC THENL + [ASM_ARITH_TAC; ALL_TAC] THEN + UNDISCH_TAC `word_and len (word 0xfffffffffffffff0) = (num_blocks:int64)` THEN + MP_TAC (SPECL [`len:int64`; `num_blocks:int64`] NUM_BLOCKS_LO_BOUND_1BLOCK_THM) THEN + SIMP_TAC[]; ALL_TAC] THEN + SUBGOAL_THEN `val (num_blocks:int64) <= 2 EXP 24` ASSUME_TAC THENL + [ UNDISCH_TAC `val (len:int64) <= 2 EXP 24` THEN + UNDISCH_TAC `word_and len (word 0xfffffffffffffff0) = (num_blocks:int64)` THEN + MP_TAC (SPECL [`len:int64`; `num_blocks:int64`] NUM_BLOCKS_HI_BOUND_THM) THEN + SIMP_TAC[]; ALL_TAC] THEN + SUBGOAL_THEN `~(val (num_blocks_adjusted:int64) < 0)` ASSUME_TAC THENL + [ UNDISCH_TAC `~(val (num_blocks:int64) < 16)` THEN + UNDISCH_TAC `(if val (tail_len:int64) = 0x0 + then (num_blocks:int64) + else word_sub num_blocks (word 0x10)) = + num_blocks_adjusted` THEN + MP_TAC (SPECL [`num_blocks:int64`;`tail_len:int64`;`num_blocks_adjusted:int64`] + NUM_BLOCKS_ADJUSTED_LO_BOUND_1BLOCK_THM) THEN SIMP_TAC[] + ; ALL_TAC] THEN + SUBGOAL_THEN `val (num_blocks_adjusted:int64) <= 2 EXP 24` ASSUME_TAC THENL + [ UNDISCH_TAC `val (num_blocks:int64) <= 2 EXP 24` THEN + UNDISCH_TAC `~(val (num_blocks:int64) < 16)` THEN + UNDISCH_TAC `(if val (tail_len:int64) = 0x0 + then (num_blocks:int64) + else word_sub num_blocks (word 0x10)) = + num_blocks_adjusted` THEN + MP_TAC (SPECL [`num_blocks:int64`;`tail_len:int64`;`num_blocks_adjusted:int64`] + NUM_BLOCKS_ADJUSTED_HI_BOUND_THM) THEN SIMP_TAC[] + ; ALL_TAC] THEN + SUBGOAL_THEN `val (tail_len:int64) < 16` ASSUME_TAC THENL + [ EXPAND_TAC "tail_len" THEN + REWRITE_TAC[ARITH_RULE `0xf = 2 EXP 4 - 1`] THEN + REWRITE_TAC[VAL_WORD_AND_MASK_WORD] THEN + CONV_TAC NUM_REDUCE_CONV THEN + SIMP_TAC[MOD_LT_EQ] THEN + CONV_TAC NUM_REDUCE_CONV + ; ALL_TAC] THEN + (* relationship between variables *) + SUBGOAL_THEN `val (num_blocks:int64) <= val (len:int64)` ASSUME_TAC THENL + [ EXPAND_TAC "num_blocks" THEN SIMP_TAC[NUM_BLOCKS_LT_LEN_THM]; ALL_TAC] THEN + SUBGOAL_THEN `val (num_blocks_adjusted:int64) <= val (len:int64)` ASSUME_TAC THENL + [ EXPAND_TAC "num_blocks_adjusted" THEN + COND_CASES_TAC THENL + [ ASM_SIMP_TAC[]; + UNDISCH_TAC `~(val (num_blocks:int64) < 16)` THEN + UNDISCH_TAC `word_and (len:int64) (word 0xfffffffffffffff0) = (num_blocks:int64)` THEN + MP_TAC (SPECL [`len:int64`; `num_blocks:int64`] NUM_BLOCKS_ADJUSTED_LT_LEN_THM) THEN + SIMP_TAC[]]; ALL_TAC] THEN + SUBGOAL_THEN `val (num_5blocks_adjusted:int64) * 0x50 <= val (num_blocks_adjusted:int64)` ASSUME_TAC THENL + [ EXPAND_TAC "num_5blocks_adjusted" THEN + REWRITE_TAC [VAL_WORD; DIMINDEX_64] THEN + UNDISCH_TAC `val (num_blocks_adjusted:int64) <= 0x2 EXP 0x18` THEN + ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `val (num_5blocks_adjusted:int64) * 0x50 <= val (len:int64)` ASSUME_TAC THENL + [ EXPAND_TAC "num_5blocks_adjusted" THEN + REWRITE_TAC [VAL_WORD; DIMINDEX_64] THEN + UNDISCH_TAC `val (num_blocks_adjusted:int64) <= 0x2 EXP 0x18` THEN + UNDISCH_TAC `val (num_blocks_adjusted:int64) <= val (len:int64)` THEN + ARITH_TAC; ALL_TAC] THEN + + (* Prove more properties about num_blocks_adjusted and num_5blocks_adjusted *) + SUBGOAL_THEN `val (num_blocks_adjusted:int64) DIV 0x50 = val (num_5blocks_adjusted:int64)` ASSUME_TAC THENL + [ EXPAND_TAC "num_5blocks_adjusted" THEN + IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN + UNDISCH_TAC `val (num_blocks_adjusted:int64) <= 0x2 EXP 0x18` THEN + ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `0x10 divides val (num_blocks_adjusted:int64)` ASSUME_TAC THENL + [ EXPAND_TAC "num_blocks_adjusted" THEN + EXPAND_TAC "num_blocks" THEN + COND_CASES_TAC THENL + [ REWRITE_TAC[NUM_BLOCKS_TO_VAL] THEN + IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT; DIVIDES_RMUL; DIVIDES_REFL] THEN + MP_TAC (SPEC `len:int64` VAL_BOUND_64) THEN + ARITH_TAC; + + IMP_REWRITE_TAC[NUM_BLOCKS_MINUS1_TO_VAL] THEN + IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT; DIVIDES_RMUL; DIVIDES_REFL] THEN + MP_TAC (SPEC `len:int64` VAL_BOUND_64) THEN + ARITH_TAC]; ALL_TAC] THEN + + (* If no tail, execute to the end *) + ASM_CASES_TAC `val (tail_len:int64) = 0` THENL + [ + ENSURES_INIT_TAC "s0" THEN + ARM_STEPS_TAC AES_XTS_DECRYPT_EXEC (1--2) THEN + (* Discharge if condition *) + SUBGOAL_THEN `val (word_and (tail_len:int64) (word 0xf)) = 0x0` MP_TAC THENL + [ UNDISCH_TAC `val (tail_len:int64) = 0x0` THEN BITBLAST_TAC; ALL_TAC] THEN + ASM_REWRITE_TAC[] THEN DISCH_TAC THEN + POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th])) THEN + + ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN + DISCHARGE_SAFETY_PROPERTY_TAC; + + ALL_TAC] THEN + + (* The cipher stealing branch *) + ASM_REWRITE_TAC[] THEN + (* Break the rest of the program into two parts: before byte-swap and after. + This is because byte-swap needs another invariant proof. *) + ABBREV_TAC `curr_len = (acc_len (num_5blocks_adjusted:int64) (num_blocks_adjusted:int64)):num` THEN + ABBREV_TAC `curr_blocks = (acc_blocks (num_5blocks_adjusted:int64) (num_blocks_adjusted:int64) T):num` THEN + + SUBGOAL_THEN `curr_len + 0x10 <= val (len:int64)` ASSUME_TAC THENL + [ EXPAND_TAC "curr_len" THEN + MP_TAC (SPECL [`num_5blocks_adjusted:int64`; `num_blocks_adjusted:int64`] VALUE_OF_ACC_LEN) THEN + REPEAT_N 3 (ANTS_TAC THENL [ASM_ARITH_TAC ORELSE ASM_SIMP_TAC[]; ALL_TAC]) THEN + SIMP_TAC[] THEN DISCH_TAC THEN + EXPAND_TAC "num_blocks_adjusted" THEN + SIMP_TAC[ASSUME `~(val (tail_len:int64) = 0)`] THEN + UNDISCH_TAC `val (num_blocks:int64) <= val (len:int64)` THEN + SUBGOAL_THEN `val (num_blocks:int64) >= 16` MP_TAC THENL + [ASM_ARITH_TAC; ALL_TAC] THEN + WORD_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `val ((word curr_len):int64) = curr_len` ASSUME_TAC THENL + [ IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN + EXPAND_TAC "curr_len" THEN + MP_TAC (SPECL [`num_5blocks_adjusted:int64`; `num_blocks_adjusted:int64`; `2 EXP 64`] + BOUND_OF_ACC_LEN) THEN + ANTS_TAC THENL [ ASM_ARITH_TAC; ALL_TAC] THEN + ANTS_TAC THENL [ ASM_SIMP_TAC[]; ALL_TAC] THEN + ANTS_TAC THENL [ ASM_SIMP_TAC[]; ALL_TAC] THEN + ANTS_TAC THENL [ ASM_ARITH_TAC; ALL_TAC] THEN + SIMP_TAC[]; ALL_TAC] THEN + + ENSURES_EVENTS_SEQUENCE_TAC `pc + 0xab8` + `\s. + read X0 s = word_add (word_add ct_ptr (word curr_len)) (word 0x10) /\ + read X1 s = word_add pt_ptr (word curr_len) /\ + read X21 s = tail_len` THEN + CONJ_TAC THENL + [ + MATCH_MP_TAC ENSURES_FRAME_SUBSUMED THEN + EXISTS_TAC `MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI ,, + MAYCHANGE [X19; X20; X21; X22],, + MAYCHANGE [Q8; Q9; Q10; Q11; Q12; Q13; Q14; Q15],, + MAYCHANGE [memory :> bytes128 (word_add pt_ptr (word curr_len))]` THEN + REWRITE_TAC[MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI] THEN + CONJ_TAC THENL [ + REPEAT (GEN_REWRITE_TAC ONCE_DEPTH_CONV [GSYM SEQ_ASSOC] THEN + MATCH_MP_TAC SUBSUMED_SEQ THEN REWRITE_TAC[SUBSUMED_REFL]) THEN + ABBREV_TAC `vallen = val (len:int64)` THEN + SUBSUMED_MAYCHANGE_TAC; ALL_TAC] THEN + + REWRITE_TAC[byte_list_at] THEN + UNDISCH_THEN `val ((word curr_len):int64) = curr_len` + (fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th]) THEN REWRITE_TAC[th]) THEN + + ENSURES_INIT_TAC "s0" THEN + ARM_STEPS_TAC AES_XTS_DECRYPT_EXEC (1--2) THEN + + (* Discharge if condition *) + SUBGOAL_THEN `~(val (word_and (tail_len:int64) (word 0xf)) = 0x0)` MP_TAC THENL + [ UNDISCH_TAC `~(val (tail_len:int64) = 0x0)` THEN + UNDISCH_TAC `val (tail_len:int64) < 16` THEN + MP_TAC (SPEC `tail_len:int64` WORD_AND_MASK16_EQ_0) THEN + SIMP_TAC[]; ALL_TAC] THEN + ASM_REWRITE_TAC[] THEN DISCH_TAC THEN + POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th])) THEN + + (* Decrypt last block *) + ARM_STEPS_TAC AES_XTS_DECRYPT_EXEC (3--11) THEN + ARM_STEPS_TAC AES_XTS_DECRYPT_EXEC (12--42) THEN + ARM_STEPS_TAC AES_XTS_DECRYPT_EXEC (43--43) THEN + + ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN + EXPAND_TAC "curr_len" THEN + ABBREV_TAC `vlen = val (len:int64)` THEN + DISCHARGE_SAFETY_PROPERTY_TAC; + + ALL_TAC + ] THEN + + SUBGOAL_THEN `curr_len + 16 + val (tail_len:int64) = val (len:int64)` ASSUME_TAC THENL + [ REWRITE_TAC[GSYM (ASSUME `acc_len num_5blocks_adjusted num_blocks_adjusted = curr_len`)] THEN + MP_TAC (SPECL [`num_5blocks_adjusted:int64`; `num_blocks_adjusted:int64`] VALUE_OF_ACC_LEN) THEN + ANTS_TAC THENL[ASM_ARITH_TAC; ALL_TAC] THEN + ANTS_TAC THENL[ASM_ARITH_TAC; ALL_TAC] THEN + ANTS_TAC THENL[ASM_SIMP_TAC[]; ALL_TAC] THEN + SIMP_TAC[] THEN DISCH_TAC THEN + EXPAND_TAC "num_blocks_adjusted" THEN + UNDISCH_TAC `~(val (tail_len:int64) = 0)` THEN + SIMP_TAC[] THEN DISCH_TAC THEN + ASM_SIMP_TAC[VAL_WORD_SUB; DIMINDEX_64; VAL_WORD; + ARITH_RULE `16 MOD 2 EXP 64 = 16`] THEN + MP_TAC (SPECL [`val (num_blocks:int64)`; `0x2 EXP 0x40`; `16`] + (ARITH_RULE `!a b c. c <= a ==> c <= b ==> a + b - c = (a - c) + b`)) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN + ANTS_TAC THENL [ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[] THEN DISCH_TAC THEN + MP_TAC (SPECL [`1`; `0x2 EXP 0x40`; `val (num_blocks:int64) - 16`] + (CONJUNCT1 (CONJUNCT2 (CONJUNCT2 MOD_MULT_ADD)))) THEN + SIMP_TAC[ARITH_RULE `!x. 1 * x = x`] THEN DISCH_TAC THEN + IMP_REWRITE_TAC[MOD_LT] THEN + CONJ_TAC THENL [ + SUBGOAL_THEN `val (num_blocks:int64) - 0x10 + 0x10 + val (tail_len:int64) + = val num_blocks + val tail_len` SUBST1_TAC THENL + [ IMP_REWRITE_TAC[ADD_ASSOC; SUB_ADD] THEN ASM_ARITH_TAC; ALL_TAC] THEN + EXPAND_TAC "len" THEN + REWRITE_TAC[VAL_WORD_ADD] THEN + IMP_REWRITE_TAC[MOD_LT; DIMINDEX_64] THEN + CONJ_TAC THENL [ARITH_TAC; ASM_ARITH_TAC]; + ALL_TAC + ] THEN + ASM_ARITH_TAC; ALL_TAC] THEN + + (* Invariant proof for .composite_dec_loop *) + ENSURES_EVENTS_WHILE_UP2_TAC + `val (tail_len:int64)` + `pc + 0xac0` + `pc + 0xad8` + `\i s. + ( read X0 s = word_add (word_add ct_ptr (word curr_len)) (word 0x10) /\ + read X1 s = word_add pt_ptr (word curr_len) /\ + read X13 s = word_add (word_add pt_ptr (word curr_len)) (word 0x10) /\ + read X20 s = word_add (word_add ct_ptr (word curr_len)) (word 0x10) /\ + read X21 s = (word (val (tail_len:int64) - i)):int64)` THEN + ASM_REWRITE_TAC[] THEN REPEAT CONJ_TAC THENL + [ + (* Subgoal 1: invariant holds before entering loop *) + REWRITE_TAC[byte_list_at] THEN + UNDISCH_THEN `val ((word curr_len):int64) = curr_len` + (fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th]) THEN REWRITE_TAC[th]) THEN + + ENSURES_INIT_TAC "s0" THEN STRIP_EXISTS_ASSUM_TAC THEN + ARM_STEPS_TAC AES_XTS_DECRYPT_EXEC (1--2) THEN + ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN + REPEAT CONJ_TAC THENL + [ + REWRITE_TAC[WORD_VAL; SUB_0] THEN NO_TAC; + + DISCHARGE_SAFETY_PROPERTY_TAC + ]; + + (* Subgoal 2: inductive step *) + REWRITE_TAC[] THEN + REPEAT STRIP_TAC THEN + ABBREV_TAC `n = val (tail_len:int64)` THEN + + (* For non-overlapping and MAYCHANGE address reasoning *) + SUBGOAL_THEN `curr_len + 16 + (n - i - 1) < val (len:int64)` ASSUME_TAC THENL + [ REWRITE_TAC[GSYM (ASSUME `acc_len num_5blocks_adjusted num_blocks_adjusted = curr_len`)] THEN + MP_TAC (SPECL [`num_5blocks_adjusted:int64`; `num_blocks_adjusted:int64`] VALUE_OF_ACC_LEN) THEN + REPEAT_N 3 (ANTS_TAC THENL [ASM_ARITH_TAC ORELSE ASM_SIMP_TAC[]; ALL_TAC]) THEN + SIMP_TAC[] THEN DISCH_TAC THEN + ASM_ARITH_TAC; + + ALL_TAC] THEN + + MATCH_MP_TAC ENSURES_FRAME_SUBSUMED THEN + EXISTS_TAC `MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI ,, + MAYCHANGE [X19; X20; X21; X22],, + MAYCHANGE [Q8; Q9; Q10; Q11; Q12; Q13; Q14; Q15],, + MAYCHANGE [memory :> bytes8 (word_add pt_ptr (word (curr_len + 0x10 + + (n - i - 1))))],, + MAYCHANGE [memory :> bytes8 (word_add pt_ptr (word (curr_len + + (n - i - 1))))]` THEN + REWRITE_TAC[MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI] THEN + CONJ_TAC THENL [ + REPEAT (GEN_REWRITE_TAC ONCE_DEPTH_CONV [GSYM SEQ_ASSOC] THEN + MATCH_MP_TAC SUBSUMED_SEQ THEN REWRITE_TAC[SUBSUMED_REFL]) THEN + ABBREV_TAC `vallen = val (len:int64)` THEN + SUBSUMED_MAYCHANGE_TAC; ALL_TAC] THEN + + REWRITE_TAC[byte_list_at] THEN + UNDISCH_THEN `val ((word curr_len):int64) = curr_len` + (fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th]) THEN REWRITE_TAC[th]) THEN + ENSURES_INIT_TAC "s0" THEN + STRIP_EXISTS_ASSUM_TAC THEN + + SUBGOAL_THEN `val ((word (n - i)):int64) = n - i` SUBST_ALL_TAC THENL + [ IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN + UNDISCH_TAC `i < n` THEN + UNDISCH_TAC `n < 0x10` THEN + ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `val ((word (n - (i + 0x1))):int64) = n - (i + 1)` SUBST_ALL_TAC THENL + [ IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN + UNDISCH_TAC `i < n` THEN + UNDISCH_TAC `n < 0x10` THEN + ARITH_TAC; ALL_TAC] THEN + + SUBGOAL_THEN `word_sub ((word (i + 0x1)):int64) (word 0x1) = word i` ASSUME_TAC THENL + [ REWRITE_TAC[GSYM VAL_EQ; VAL_WORD_SUB; DIMINDEX_64] THEN + MP_TAC (SPECL [`val ((word (i + 0x1)):int64)`; `0x2 EXP 0x40`; `val ((word 0x1):int64)`] + (ARITH_RULE `!a b c. c <= a ==> c <= b ==> a + b - c = (a - c) + b`)) THEN + ANTS_TAC THENL [ + IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN ASM_ARITH_TAC + ; ALL_TAC] THEN + ANTS_TAC THENL [ WORD_ARITH_TAC; ALL_TAC] THEN + SIMP_TAC[] THEN DISCH_TAC THEN + MP_TAC (SPECL [`1`; `0x2 EXP 0x40`; `val ((word (i + 0x1)):int64) - val ((word 0x1):int64)`] + (CONJUNCT1 (CONJUNCT2 (CONJUNCT2 MOD_MULT_ADD)))) THEN + SIMP_TAC[ARITH_RULE `!x. 1 * x = x`] THEN DISCH_TAC THEN + IMP_REWRITE_TAC[MOD_LT] THEN + CONJ_TAC THENL + [ SUBGOAL_THEN `i + 1 < 2 EXP 64` MP_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN + IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN + ARITH_TAC; + UNDISCH_TAC `i < n` THEN + UNDISCH_TAC `n < 0x10` THEN + WORD_ARITH_TAC] + ; ALL_TAC] THEN + + SUBGOAL_THEN `val ((word i):int64) < 0x10` ASSUME_TAC THENL + [ UNDISCH_TAC `i < n` THEN + UNDISCH_TAC `n < 0x10` THEN + WORD_ARITH_TAC; ALL_TAC ] THEN + ASM_SIMP_TAC[] THEN + REPEAT STRIP_TAC THEN + + MP_TAC (SPECL [`ct_ptr:int64`; `len:int64`; + `(word_add (word (curr_len + 0x10)) (word i)):int64`; + `ct:byte list`; `s0:armstate`] SELECT_ONE_BYTE_FROM_FORALL) THEN + SUBGOAL_THEN `val (word_add ((word (curr_len + 0x10)):int64) (word i)) < val (len:int64)` ASSUME_TAC THENL + [ REWRITE_TAC[WORD_RULE `!a b. word_add ((word a):int64) (word b) = word (a + b)`] THEN + IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN + ASM_ARITH_TAC; ALL_TAC] THEN + ASM_SIMP_TAC[] THEN + STRIP_TAC THEN + + (* For address matching when symbolic simulation *) + SUBGOAL_THEN `word_add (ct_ptr:int64) (word_add (word (curr_len + 0x10)) (word i)) = + word_add ct_ptr (word (curr_len + 16 + i))` SUBST_ALL_TAC THENL + [ REWRITE_TAC[WORD_RULE `!a b. word_add ((word a):int64) (word b) = word (a + b)`; ADD_ASSOC] + ; ALL_TAC] THEN + SUBGOAL_THEN `!x. word_add (word_add (pt_ptr:int64) (word curr_len)) (word x) = + word_add pt_ptr (word (curr_len + x))` ASSUME_TAC THENL + [ GEN_TAC THEN REWRITE_TAC[ + WORD_RULE `!(a:int64) b c. word_add (word_add a b) c = word_add a (word_add b c)`; + WORD_RULE `!a b. word_add ((word a):int64) (word b) = word (a + b)`] + ; ALL_TAC] THEN + POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th])) THEN + + ARM_STEPS_TAC AES_XTS_DECRYPT_EXEC (1--6) THEN + (* Help MAYCHANGE predicate be syntactically similar to the MAYCHANGE conclusion *) + SUBGOAL_THEN `word_sub (word (n - i)) (word 1) = word (n - i - 1):int64` SUBST_ALL_TAC THENL [ + IMP_REWRITE_TAC[WORD_SUB2] THEN SIMPLE_ARITH_TAC; + ALL_TAC; + ] THEN + + ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN + CONJ_TAC THENL [ + (* Initial version of proof generated by Opus 4.6. :) *) + SUBGOAL_THEN `1 <= n - i /\ n - i <= 15` STRIP_ASSUME_TAC THENL + [SIMPLE_ARITH_TAC; ALL_TAC] THEN + VAL_INT64_TAC `n - i` THEN + VAL_INT64_TAC `n - i - 1` THEN + SUBGOAL_THEN `ival (word (n - i):int64) = &(n - i)` ASSUME_TAC THENL + [REWRITE_TAC[ival] THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[DIMINDEX_64] THEN CONV_TAC NUM_REDUCE_CONV THEN + SIMPLE_ARITH_TAC; + ALL_TAC] THEN + SUBGOAL_THEN `ival (word (n - i - 1):int64) = &(n - i - 1)` + ASSUME_TAC THENL + [REWRITE_TAC[ival] THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[DIMINDEX_64] THEN CONV_TAC NUM_REDUCE_CONV THEN + SIMPLE_ARITH_TAC; + ALL_TAC] THEN + ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN `~(&(n - i - 1):int < &0)` (fun th -> REWRITE_TAC[th]) THENL + [REWRITE_TAC[INT_NOT_LT; INT_POS]; ALL_TAC] THEN + SUBGOAL_THEN `&(n - i) - &1:int = &(n - i - 1)` SUBST1_TAC THENL + [MP_TAC(SPECL [`1`; `n - i:num`] INT_OF_NUM_SUB) THEN + UNDISCH_TAC `1 <= n - i` THEN SIMP_TAC[] THEN INT_ARITH_TAC; + ALL_TAC] THEN + REWRITE_TAC[] THEN + ASM_CASES_TAC `n - i - 1 = 0` THENL + [ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN `~(i + 1 < n)` (fun th -> REWRITE_TAC[th]) THEN SIMPLE_ARITH_TAC; + ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN `i + 1 < n` (fun th -> REWRITE_TAC[th]) THEN SIMPLE_ARITH_TAC]; + + ALL_TAC + ] THEN + CONJ_TAC THENL [ + CONV_TAC WORD_RULE; ALL_TAC + ] THEN + CONJ_TAC THENL [ + AP_TERM_TAC THEN SIMPLE_ARITH_TAC; + ALL_TAC + ] THEN + (* Abbbreviate val(len) because it appears memaccess_inbounds and + existence of 'val' blocks reasoning of contained/nonoverlapping + predicates *) + ABBREV_TAC `m = val (len:int64)` THEN + DISCHARGE_SAFETY_PROPERTY_TAC + ~abbrevs_unfold_before_f_events_tac:[ + `acc_len num_5blocks_adjusted num_blocks_adjusted = curr_len`; + `val (tail_len:int64) = n`; + ]; + + (* Subgoal 3: *) + REWRITE_TAC[] THEN + ENSURES_INIT_TAC "s0" THEN STRIP_EXISTS_ASSUM_TAC THEN + ARM_STEPS_TAC AES_XTS_DECRYPT_EXEC (1--32) THEN + ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN + CONJ_TAC THENL [ + REWRITE_TAC[GSYM (ASSUME `acc_len num_5blocks_adjusted num_blocks_adjusted = curr_len`)] THEN + ABBREV_TAC `vlen = val (len:int64)` THEN + DISCHARGE_SAFETY_PROPERTY_TAC; + + (* Maychange *) + ABBREV_TAC `vallen = val (len:int64)` THEN + ABBREV_TAC `valcurlen = val (curr_len:int64)` THEN + MONOTONE_MAYCHANGE_TAC + ] + ] +);; + + (* Proof: Less than 2 blocks *) let AES_XTS_DECRYPT_LT_2BLOCK_CORRECT = time prove( `!ct_ptr pt_ptr ct key1_ptr key2_ptr iv_ptr iv len diff --git a/common/consttime.ml b/common/consttime.ml index e5a315658..fb856f19f 100644 --- a/common/consttime.ml +++ b/common/consttime.ml @@ -365,7 +365,7 @@ let DISCHARGE_MEMACCESS_INBOUNDS_TAC = FAIL_TAC ("DISCHARGE_MEMACCESS_INBOUNDS_TAC could not identify the pattern. " ^ "Please check whether the event list in assumption matches the event " ^ - "list in the conclusion")));; + "list in the conclusion. setting safety_print_log := true might give more clue.")));; let mk_freshvar = let n = ref 0 in @@ -979,10 +979,18 @@ let FULL_UNIFY_F_EVENTS_TAC:tactic = end end) (asl,w)) ORELSE CANONICALIZE_UNIFY_F_EVENTS_TAC;; -(* The input goal: 'exists e2. ....' *) -let DISCHARGE_SAFETY_PROPERTY_TAC = +(* The input goal: 'exists e2. ....' + If FULL_UNIFY_F_EVENTS_TAC raises a failure because unseen variable x is + inside the goal of `... x ... = f_events ...`, provide the assumption + `x = ...` that can be used to expand x. +*) +let DISCHARGE_SAFETY_PROPERTY_TAC + ?(abbrevs_unfold_before_f_events_tac=[]) = SAFE_META_EXISTS_TAC allowed_vars_e THEN CONJ_TAC THENL [ EXISTS_E2_TAC allowed_vars_e; ALL_TAC ] THEN - CONJ_TAC THENL [ FULL_UNIFY_F_EVENTS_TAC; ALL_TAC ] THEN + CONJ_TAC THENL [ + MAP_EVERY (fun t -> UNDISCH_THEN t (SUBST_ALL_TAC o GSYM)) + abbrevs_unfold_before_f_events_tac THEN + FULL_UNIFY_F_EVENTS_TAC; ALL_TAC ] THEN (* Prove memaccess_inbounds predicates *) DISCHARGE_MEMACCESS_INBOUNDS_TAC;; From 2e362c735febfc3d38fb74b5fd294fadfffbd417 Mon Sep 17 00:00:00 2001 From: Nevine Ebeid Date: Tue, 10 Mar 2026 12:03:50 -0400 Subject: [PATCH 132/132] Prove CIPHER_STEALING_SAFE of aes-xts encrypt --- arm/proofs/aes_xts_encrypt.ml | 376 ++++++++++++++++++++++++++++++++++ 1 file changed, 376 insertions(+) diff --git a/arm/proofs/aes_xts_encrypt.ml b/arm/proofs/aes_xts_encrypt.ml index 6ae4716f6..289b8e612 100644 --- a/arm/proofs/aes_xts_encrypt.ml +++ b/arm/proofs/aes_xts_encrypt.ml @@ -7,6 +7,7 @@ (* ========================================================================= *) needs "arm/proofs/utils/aes_xts_common.ml";; +needs "arm/proofs/consttime.ml";; (* print_literal_from_elf "arm/aes-xts/aes_xts_encrypt.o";; *) let aes256_xts_encrypt_mc = define_assert_from_elf "aes256_xts_encrypt_mc" "arm/aes-xts/aes_xts_encrypt.o" @@ -2543,6 +2544,381 @@ let CIPHER_STEALING_ENC_CORRECT = time prove( );; +let CIPHER_STEALING_ENC_SAFE = time prove( + `exists f_events. + forall ptxt_p ctxt_p key1_p len pc + tail_len len_full_blocks num_5blocks. + PAIRWISE nonoverlapping + [(word pc, LENGTH aes256_xts_encrypt_mc); + (ptxt_p, val len); + (ctxt_p, val len); + (key1_p, 244)] + /\ val len >= 16 /\ val len <= 2 EXP 24 + /\ word_add tail_len len_full_blocks = len + /\ word_and len (word 0xfffffffffffffff0) = len_full_blocks + /\ word_and len (word 0xf) = tail_len + /\ word (val len_full_blocks DIV 0x50) = num_5blocks + ==> ensures arm + (\s. aligned_bytes_loaded s (word pc) aes256_xts_encrypt_mc /\ + read PC s = word (pc + 0x9e0) /\ + read X0 s = word_add ptxt_p (word (acc_len num_5blocks len_full_blocks)) /\ + read X1 s = word_add ctxt_p (word (acc_len num_5blocks len_full_blocks)) /\ + read X3 s = key1_p /\ + read X21 s = tail_len /\ + read X19 s = word 0x87 /\ + read events s = e) + (\s. read PC s = word (pc + 0xa8c) /\ + exists e2. + read events s = APPEND e2 e /\ + e2 = f_events ptxt_p ctxt_p key1_p tail_len len_full_blocks + num_5blocks pc /\ + memaccess_inbounds e2 + [(ptxt_p, val len); (ctxt_p, val len); (key1_p, 244)] + [(ctxt_p, val len)]) + (MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI,, + MAYCHANGE [X19; X20; X21; X22],, + MAYCHANGE [Q8; Q9; Q10; Q11; Q12; Q13; Q14; Q15],, + MAYCHANGE [memory :> bytes(ctxt_p, val len)])`, + + CONCRETIZE_F_EVENTS_TAC + `\(ptxt_p:int64) (ctxt_p:int64) (key1_p:int64) (tail_len:int64) + (len_full_blocks:int64) (num_5blocks:int64) (pc:num). + if val (tail_len) = 0 then + f_ev_short ptxt_p ctxt_p key1_p tail_len len_full_blocks + num_5blocks pc + else + APPEND + (APPEND + (f_ev_epil ptxt_p ctxt_p key1_p tail_len len_full_blocks + num_5blocks pc) + (APPEND + (ENUMERATEL (val tail_len) + (f_ev_loop ptxt_p ctxt_p key1_p tail_len len_full_blocks + num_5blocks pc)) + (f_ev_prol ptxt_p ctxt_p key1_p tail_len len_full_blocks + num_5blocks pc)) + ) + (f_ev_pre ptxt_p ctxt_p key1_p tail_len len_full_blocks + num_5blocks pc) + :(uarch_event)list` THEN + REPEAT META_EXISTS_TAC THEN + + REWRITE_TAC [(REWRITE_CONV [aes256_xts_encrypt_mc] THENC LENGTH_CONV) `LENGTH aes256_xts_encrypt_mc`] THEN + REWRITE_TAC[byte_list_at; PAIRWISE; ALL; + MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI] THEN + REPEAT STRIP_TAC THEN + + (* Prove the bounds on len_full_blocks, num_5blocks and len *) + SUBGOAL_THEN `~(val (len_full_blocks:int64) < 16)` ASSUME_TAC THENL + [ SUBGOAL_THEN `~(val (len:int64) < 16)` MP_TAC THENL + [ASM_ARITH_TAC; ALL_TAC] THEN + UNDISCH_TAC `word_and len (word 0xfffffffffffffff0) = (len_full_blocks:int64)` THEN + MP_TAC (SPECL [`len:int64`; `len_full_blocks:int64`] NUM_BLOCKS_LO_BOUND_1BLOCK_THM) THEN + SIMP_TAC[]; ALL_TAC] THEN + SUBGOAL_THEN `val (len_full_blocks:int64) <= 2 EXP 24` ASSUME_TAC THENL + [ UNDISCH_TAC `val (len:int64) <= 2 EXP 24` THEN + UNDISCH_TAC `word_and len (word 0xfffffffffffffff0) = (len_full_blocks:int64)` THEN + MP_TAC (SPECL [`len:int64`; `len_full_blocks:int64`] NUM_BLOCKS_HI_BOUND_THM) THEN + SIMP_TAC[]; ALL_TAC] THEN + SUBGOAL_THEN `val (tail_len:int64) < 16` ASSUME_TAC THENL + [ EXPAND_TAC "tail_len" THEN + REWRITE_TAC[ARITH_RULE `0xf = 2 EXP 4 - 1`] THEN + REWRITE_TAC[VAL_WORD_AND_MASK_WORD] THEN + CONV_TAC NUM_REDUCE_CONV THEN + SIMP_TAC[MOD_LT_EQ] THEN + CONV_TAC NUM_REDUCE_CONV + ; ALL_TAC] THEN + (* relationship between variables *) + SUBGOAL_THEN `val (len_full_blocks:int64) <= val (len:int64)` ASSUME_TAC THENL + [ EXPAND_TAC "len_full_blocks" THEN SIMP_TAC[NUM_BLOCKS_LT_LEN_THM]; ALL_TAC] THEN + SUBGOAL_THEN `val (num_5blocks:int64) * 0x50 <= val (len_full_blocks:int64)` ASSUME_TAC THENL + [ EXPAND_TAC "num_5blocks" THEN + REWRITE_TAC [VAL_WORD; DIMINDEX_64] THEN + UNDISCH_TAC `val (len_full_blocks:int64) <= 0x2 EXP 0x18` THEN + ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `val (num_5blocks:int64) * 0x50 <= val (len:int64)` ASSUME_TAC THENL + [ EXPAND_TAC "num_5blocks" THEN + REWRITE_TAC [VAL_WORD; DIMINDEX_64] THEN + UNDISCH_TAC `val (len_full_blocks:int64) <= 0x2 EXP 0x18` THEN + UNDISCH_TAC `val (len_full_blocks:int64) <= val (len:int64)` THEN + ARITH_TAC; ALL_TAC] THEN + + (* Prove more properties about len_full_blocks and num_5blocks *) + SUBGOAL_THEN `val (len_full_blocks:int64) DIV 0x50 = val (num_5blocks:int64)` ASSUME_TAC THENL + [ EXPAND_TAC "num_5blocks" THEN + IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN + UNDISCH_TAC `val (len_full_blocks:int64) <= 0x2 EXP 0x18` THEN + ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `0x10 divides val (len_full_blocks:int64)` ASSUME_TAC THENL + [ EXPAND_TAC "len_full_blocks" THEN + REWRITE_TAC[NUM_BLOCKS_TO_VAL] THEN + IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT; DIVIDES_RMUL; DIVIDES_REFL] THEN + MP_TAC (SPEC `len:int64` VAL_BOUND_64) THEN + ARITH_TAC; ALL_TAC] THEN + + (* If no tail, execute to the end *) + ASM_CASES_TAC `val (tail_len:int64) = 0` THENL + [ + ENSURES_INIT_TAC "s0" THEN + ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (1--2) THEN + (* Discharge if condition *) + SUBGOAL_THEN `val (word_and (tail_len:int64) (word 0xf)) = 0x0` MP_TAC THENL + [ UNDISCH_TAC `val (tail_len:int64) = 0x0` THEN BITBLAST_TAC; ALL_TAC] THEN + ASM_REWRITE_TAC[] THEN DISCH_TAC THEN + POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th])) THEN + + ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN + DISCHARGE_SAFETY_PROPERTY_TAC; + + ALL_TAC] THEN + + (* The cipher stealing branch *) + ASM_REWRITE_TAC[] THEN + ABBREV_TAC `curr_len = (acc_len (num_5blocks:int64) (len_full_blocks:int64)):num` THEN + + SUBGOAL_THEN `curr_len <= val (len:int64)` ASSUME_TAC THENL + [ EXPAND_TAC "curr_len" THEN + MP_TAC (SPECL [`num_5blocks:int64`; `len_full_blocks:int64`] VALUE_OF_ACC_LEN) THEN + REPEAT_N 3 (ANTS_TAC THENL [ASM_ARITH_TAC ORELSE ASM_SIMP_TAC[]; ALL_TAC]) THEN + SIMP_TAC[] THEN DISCH_TAC THEN + ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `val ((word curr_len):int64) = curr_len` ASSUME_TAC THENL + [ IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN + EXPAND_TAC "curr_len" THEN + MP_TAC (SPECL [`num_5blocks:int64`; `len_full_blocks:int64`; `2 EXP 64`] + BOUND_OF_ACC_LEN) THEN + ANTS_TAC THENL [ ASM_ARITH_TAC; ALL_TAC] THEN + ANTS_TAC THENL [ ASM_SIMP_TAC[]; ALL_TAC] THEN + ANTS_TAC THENL [ ASM_SIMP_TAC[]; ALL_TAC] THEN + ANTS_TAC THENL [ ASM_ARITH_TAC; ALL_TAC] THEN + SIMP_TAC[]; ALL_TAC] THEN + SUBGOAL_THEN `16 <= curr_len` ASSUME_TAC THENL + [ EXPAND_TAC "curr_len" THEN + MP_TAC (SPECL [`num_5blocks:int64`; `len_full_blocks:int64`] VALUE_OF_ACC_LEN) THEN + REPEAT_N 3 (ANTS_TAC THENL [ASM_ARITH_TAC ORELSE ASM_SIMP_TAC[]; ALL_TAC]) THEN + ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `curr_len + val (tail_len:int64) = val (len:int64)` ASSUME_TAC THENL + [ EXPAND_TAC "curr_len" THEN + MP_TAC (SPECL [`num_5blocks:int64`; `len_full_blocks:int64`] VALUE_OF_ACC_LEN) THEN + REPEAT_N 3 (ANTS_TAC THENL [ASM_ARITH_TAC ORELSE ASM_SIMP_TAC[]; ALL_TAC]) THEN + SIMP_TAC[] THEN DISCH_TAC THEN + REWRITE_TAC[GSYM (ASSUME `word_add (tail_len:int64) len_full_blocks = len`)] THEN + ASM_SIMP_TAC[VAL_WORD_ADD_CASES; DIMINDEX_64; + ARITH_RULE `val len_full_blocks <= 0x1000000 /\ val tail_len < 0x10 ==> + val tail_len + val len_full_blocks < 0x2 EXP 0x40`] THEN + ASM_ARITH_TAC; ALL_TAC] THEN + + (* Pre-loop: branch check + register setup, 5 steps to reach loop start *) + ENSURES_EVENTS_SEQUENCE_TAC `pc + 0x9f4` + `\s. + read X0 s = word_add ptxt_p (word curr_len) /\ + read X1 s = word_add ctxt_p (word (curr_len - 0x10)) /\ + read X13 s = word_add ctxt_p (word curr_len) /\ + read X20 s = word_add ptxt_p (word curr_len) /\ + read X21 s = tail_len` THEN + CONJ_TAC THENL + [ + REWRITE_TAC[byte_list_at] THEN + UNDISCH_THEN `val ((word curr_len):int64) = curr_len` + (fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th]) THEN REWRITE_TAC[th]) THEN + + ENSURES_INIT_TAC "s0" THEN + ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (1--2) THEN + + (* Discharge if condition *) + SUBGOAL_THEN `~(val (word_and (tail_len:int64) (word 0xf)) = 0x0)` MP_TAC THENL + [ UNDISCH_TAC `~(val (tail_len:int64) = 0x0)` THEN + UNDISCH_TAC `val (tail_len:int64) < 16` THEN + MP_TAC (SPEC `tail_len:int64` WORD_AND_MASK16_EQ_0) THEN + SIMP_TAC[]; ALL_TAC] THEN + ASM_REWRITE_TAC[] THEN DISCH_TAC THEN + POP_ASSUM(fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th])) THEN + + ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (3--5) THEN + + ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN + CONJ_TAC THENL [ + ASM_SIMP_TAC[WORD_SUB] THEN + CONV_TAC WORD_RULE; ALL_TAC] THEN + ABBREV_TAC `vlen = val (len:int64)` THEN + DISCHARGE_SAFETY_PROPERTY_TAC; + + ALL_TAC + ] THEN + + (* Abbreviate for the loop: l1_curr_len = curr_len - 16 *) + ABBREV_TAC `l1_curr_len = (curr_len - 0x10):num` THEN + SUBGOAL_THEN `curr_len = l1_curr_len + 0x10` ASSUME_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `l1_curr_len + 0x10 + val (tail_len:int64) = val (len:int64)` ASSUME_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC] THEN + + (* Invariant proof for .composite_enc_loop *) + ENSURES_EVENTS_WHILE_UP2_TAC + `val (tail_len:int64)` + `pc + 0x9f4` + `pc + 0xa0c` + `\i s. + ( read X0 s = word_add ptxt_p (word curr_len) /\ + read X1 s = word_add ctxt_p (word l1_curr_len) /\ + read X13 s = word_add ctxt_p (word curr_len) /\ + read X20 s = word_add ptxt_p (word curr_len) /\ + read X21 s = (word (val (tail_len:int64) - i)):int64)` THEN + ASM_REWRITE_TAC[] THEN REPEAT CONJ_TAC THENL + [ + (* Subgoal 1: invariant holds before entering loop *) + REWRITE_TAC[byte_list_at] THEN + + ENSURES_INIT_TAC "s0" THEN STRIP_EXISTS_ASSUM_TAC THEN + ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN + REPEAT CONJ_TAC THENL + [ + REWRITE_TAC[WORD_VAL; SUB_0] THEN NO_TAC; + + DISCHARGE_SAFETY_PROPERTY_TAC + ]; + + (* Subgoal 2: inductive step *) + REWRITE_TAC[] THEN + REPEAT STRIP_TAC THEN + ABBREV_TAC `n = val (tail_len:int64)` THEN + + (* For non-overlapping and MAYCHANGE address reasoning *) + SUBGOAL_THEN `l1_curr_len + 16 + (n - i - 1) < val (len:int64)` ASSUME_TAC THENL + [ ASM_ARITH_TAC; ALL_TAC] THEN + + MATCH_MP_TAC ENSURES_FRAME_SUBSUMED THEN + EXISTS_TAC `MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI ,, + MAYCHANGE [X19; X20; X21; X22],, + MAYCHANGE [Q8; Q9; Q10; Q11; Q12; Q13; Q14; Q15],, + MAYCHANGE [memory :> bytes8 (word_add ctxt_p (word (l1_curr_len + 0x10 + + (n - i - 1))))],, + MAYCHANGE [memory :> bytes8 (word_add ctxt_p (word (l1_curr_len + + (n - i - 1))))]` THEN + REWRITE_TAC[MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI] THEN + CONJ_TAC THENL [ + REPEAT (GEN_REWRITE_TAC ONCE_DEPTH_CONV [GSYM SEQ_ASSOC] THEN + MATCH_MP_TAC SUBSUMED_SEQ THEN REWRITE_TAC[SUBSUMED_REFL]) THEN + ABBREV_TAC `vallen = val (len:int64)` THEN + SUBSUMED_MAYCHANGE_TAC; ALL_TAC] THEN + + REWRITE_TAC[byte_list_at] THEN + ENSURES_INIT_TAC "s0" THEN + STRIP_EXISTS_ASSUM_TAC THEN + + SUBGOAL_THEN `val ((word (n - i)):int64) = n - i` SUBST_ALL_TAC THENL + [ IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN + UNDISCH_TAC `i < n` THEN + UNDISCH_TAC `n < 0x10` THEN + ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `val ((word (n - (i + 0x1))):int64) = n - (i + 1)` SUBST_ALL_TAC THENL + [ IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN + UNDISCH_TAC `i < n` THEN + UNDISCH_TAC `n < 0x10` THEN + ARITH_TAC; ALL_TAC] THEN + + SUBGOAL_THEN `word_sub ((word (i + 0x1)):int64) (word 0x1) = word i` ASSUME_TAC THENL + [ REWRITE_TAC[GSYM VAL_EQ; VAL_WORD_SUB; DIMINDEX_64] THEN + MP_TAC (SPECL [`val ((word (i + 0x1)):int64)`; `0x2 EXP 0x40`; `val ((word 0x1):int64)`] + (ARITH_RULE `!a b c. c <= a ==> c <= b ==> a + b - c = (a - c) + b`)) THEN + ANTS_TAC THENL [ + IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN ASM_ARITH_TAC + ; ALL_TAC] THEN + ANTS_TAC THENL [ WORD_ARITH_TAC; ALL_TAC] THEN + SIMP_TAC[] THEN DISCH_TAC THEN + MP_TAC (SPECL [`1`; `0x2 EXP 0x40`; `val ((word (i + 0x1)):int64) - val ((word 0x1):int64)`] + (CONJUNCT1 (CONJUNCT2 (CONJUNCT2 MOD_MULT_ADD)))) THEN + SIMP_TAC[ARITH_RULE `!x. 1 * x = x`] THEN DISCH_TAC THEN + IMP_REWRITE_TAC[MOD_LT] THEN + CONJ_TAC THENL + [ SUBGOAL_THEN `i + 1 < 2 EXP 64` MP_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN + IMP_REWRITE_TAC[VAL_WORD; DIMINDEX_64; MOD_LT] THEN + ARITH_TAC; + UNDISCH_TAC `i < n` THEN + UNDISCH_TAC `n < 0x10` THEN + WORD_ARITH_TAC] + ; ALL_TAC] THEN + + SUBGOAL_THEN `val ((word i):int64) < 0x10` ASSUME_TAC THENL + [ UNDISCH_TAC `i < n` THEN + UNDISCH_TAC `n < 0x10` THEN + WORD_ARITH_TAC; ALL_TAC ] THEN + + ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (1--6) THEN + (* Help MAYCHANGE predicate be syntactically similar to the MAYCHANGE conclusion *) + SUBGOAL_THEN `word_sub (word (n - i)) (word 1) = word (n - i - 1):int64` SUBST_ALL_TAC THENL [ + IMP_REWRITE_TAC[WORD_SUB2] THEN SIMPLE_ARITH_TAC; + ALL_TAC; + ] THEN + + ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN + + CONJ_TAC THENL [ + SUBGOAL_THEN `1 <= n - i /\ n - i <= 15` STRIP_ASSUME_TAC THENL + [SIMPLE_ARITH_TAC; ALL_TAC] THEN + VAL_INT64_TAC `n - i` THEN + VAL_INT64_TAC `n - i - 1` THEN + SUBGOAL_THEN `ival (word (n - i):int64) = &(n - i)` ASSUME_TAC THENL + [REWRITE_TAC[ival] THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[DIMINDEX_64] THEN CONV_TAC NUM_REDUCE_CONV THEN + SIMPLE_ARITH_TAC; + ALL_TAC] THEN + SUBGOAL_THEN `ival (word (n - i - 1):int64) = &(n - i - 1)` + ASSUME_TAC THENL + [REWRITE_TAC[ival] THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[DIMINDEX_64] THEN CONV_TAC NUM_REDUCE_CONV THEN + SIMPLE_ARITH_TAC; + ALL_TAC] THEN + ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN `~(&(n - i - 1):int < &0)` (fun th -> REWRITE_TAC[th]) THENL + [REWRITE_TAC[INT_NOT_LT; INT_POS]; ALL_TAC] THEN + + SUBGOAL_THEN `&(n - i) - &1:int = &(n - i - 1)` SUBST1_TAC THENL + [ ASM_SIMP_TAC[GSYM INT_OF_NUM_SUB]; ALL_TAC] THEN + SIMPLE_ARITH_TAC; + + ALL_TAC + ] THEN + CONJ_TAC THENL [ + AP_TERM_TAC THEN SIMPLE_ARITH_TAC; + ALL_TAC + ] THEN + + UNDISCH_THEN `curr_len - 0x10 = l1_curr_len` (SUBST_ALL_TAC o GSYM) THEN + + SUBGOAL_THEN `curr_len - 0x10 + 0x10 = curr_len` SUBST_ALL_TAC THENL + [ UNDISCH_TAC `0x10 <= curr_len` THEN ARITH_TAC; ALL_TAC] THEN + + ABBREV_TAC `m = val (len:int64)` THEN + DISCHARGE_SAFETY_PROPERTY_TAC + ~abbrevs_unfold_before_f_events_tac:[ + `acc_len num_5blocks len_full_blocks = curr_len`; + `val (tail_len:int64) = n`; + ]; + + (* Subgoal 3: post-loop epilogue *) + REWRITE_TAC[] THEN + ENSURES_INIT_TAC "s0" THEN STRIP_EXISTS_ASSUM_TAC THEN + ARM_STEPS_TAC AES256_XTS_ENCRYPT_EXEC (1--32) THEN + ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN + CONJ_TAC THENL [ + UNDISCH_THEN `curr_len - 0x10 = l1_curr_len` (SUBST_ALL_TAC o GSYM) THEN + + SUBGOAL_THEN `curr_len - 0x10 + 0x10 = curr_len` SUBST_ALL_TAC THENL + [ UNDISCH_TAC `0x10 <= curr_len` THEN ARITH_TAC; ALL_TAC] THEN + + REWRITE_TAC[GSYM (ASSUME `acc_len num_5blocks len_full_blocks = curr_len`)] THEN + ABBREV_TAC `vlen = val (len:int64)` THEN + DISCHARGE_SAFETY_PROPERTY_TAC; + + (* Maychange *) + ABBREV_TAC `vallen = val (len:int64)` THEN + MONOTONE_MAYCHANGE_TAC + ] + ] +);; + + (* Proof: Less than 2 blocks *) let AES_XTS_ENCRYPT_LT_2BLOCK_CORRECT = time prove( `!ptxt_p ctxt_p len key1_p key2_p iv_p