@@ -23,9 +23,9 @@ module MessageBody {
2323 var n, sequenceNumber := 0, 1;
2424 while n + frameLength <= |plaintext|
2525 invariant 0 <= n <= |plaintext|
26- invariant sequenceNumber <= 0xFFFF_FFFF
26+ invariant sequenceNumber <= ENDFRAME_SEQUENCE_NUMBER
2727 {
28- if sequenceNumber == 0xFFFF_FFFF {
28+ if sequenceNumber == ENDFRAME_SEQUENCE_NUMBER {
2929 return Failure ("too many frames");
3030 }
3131 var plaintextFrame := plaintext[n.. n + frameLength];
@@ -39,16 +39,16 @@ module MessageBody {
3939 }
4040
4141 method EncryptFrame (algorithmSuiteID: AlgorithmSuite .ID, key: seq <uint8 >, frameLength: int , messageID: Msg .MessageID,
42- plaintext: seq <uint8 >, sequenceNumber: int , final: bool )
42+ plaintext: seq <uint8 >, sequenceNumber: uint32 , final: bool )
4343 returns (res: Result< seq < uint8>> )
4444 requires |key| == algorithmSuiteID. KeyLength ()
45- requires 0 < frameLength && 0 < sequenceNumber <= 0xFFFF_FFFF
45+ requires 0 < frameLength && 0 < sequenceNumber <= ENDFRAME_SEQUENCE_NUMBER
4646 requires |plaintext| < UINT32_LIMIT
47- requires ! final ==> |plaintext| == frameLength && sequenceNumber != 0xFFFF_FFFF
47+ requires ! final ==> |plaintext| == frameLength && sequenceNumber != ENDFRAME_SEQUENCE_NUMBER
4848 requires final ==> |plaintext| < frameLength
4949 requires 4 <= algorithmSuiteID. IVLength ()
5050 {
51- var unauthenticatedFrame := if final then UInt32ToSeq (0xFFFF_FFFF ) else [];
51+ var unauthenticatedFrame := if final then UInt32ToSeq (ENDFRAME_SEQUENCE_NUMBER ) else [];
5252 var seqNumSeq := UInt32ToSeq (sequenceNumber as uint32);
5353 unauthenticatedFrame := unauthenticatedFrame + seqNumSeq;
5454
@@ -63,21 +63,33 @@ module MessageBody {
6363 var contentAAD := if final then BODY_AAD_CONTENT_FINAL_FRAME else BODY_AAD_CONTENT_REGULAR_FRAME;
6464 var aad := messageID + contentAAD + seqNumSeq + UInt64ToSeq (|plaintext| as uint64);
6565
66- var encryptedContents :- Encrypt (algorithmSuiteID, iv, key, plaintext, aad);
67- unauthenticatedFrame := unauthenticatedFrame + encryptedContents;
66+ var pair :- Encrypt (algorithmSuiteID, iv, key, plaintext, aad);
67+ var (encryptedContents, authTag) := pair;
68+ unauthenticatedFrame := unauthenticatedFrame + encryptedContents + authTag;
6869
69- var authTag :- Encrypt (algorithmSuiteID, iv, key, unauthenticatedFrame, aad);
70- return Success (unauthenticatedFrame + authTag);
70+ return Success (unauthenticatedFrame);
7171 }
7272
7373 const BODY_AAD_CONTENT_REGULAR_FRAME := StringToByteSeq ("AWSKMSEncryptionClient Frame");
7474 const BODY_AAD_CONTENT_FINAL_FRAME := StringToByteSeq ("AWSKMSEncryptionClient Final Frame");
7575
76- method Encrypt (algorithmSuiteID: AlgorithmSuite .ID, iv: seq <uint8 >, key: seq <uint8 >, plaintext: seq <uint8 >, aad: seq <uint8 >) returns (res: Result< seq < uint8>> )
76+ const ENDFRAME_SEQUENCE_NUMBER: uint32 := 0xFFFF_FFFF
77+
78+ method Encrypt (algorithmSuiteID: AlgorithmSuite .ID, iv: seq <uint8 >, key: seq <uint8 >, plaintext: seq <uint8 >, aad: seq <uint8 >) returns (res: Result< (seq < uint8> ,seq < uint8> )> )
7779 requires |iv| == algorithmSuiteID. IVLength ()
7880 requires |key| == algorithmSuiteID. KeyLength ()
81+ ensures match res
82+ case Success ((ciphertext, authTag)) =>
83+ |ciphertext| == |plaintext| &&
84+ |authTag| == algorithmSuiteID. TagLength ()
85+ case Failure (_) => true
7986 {
8087 var cipher := AlgorithmSuite. Suite[algorithmSuiteID]. params;
81- res := AESEncryption. AES. aes_encrypt (cipher, iv, key, plaintext, aad);
88+ var bytes :- AESEncryption. AES. aes_encrypt (cipher, iv, key, plaintext, aad);
89+ var n := |plaintext|;
90+ if |bytes| != n + algorithmSuiteID. TagLength () {
91+ return Failure ("unexpected AES encryption result");
92+ }
93+ return Success ((bytes[..n], bytes[n..]));
8294 }
8395}
0 commit comments