Skip to content

Commit 4c9d5d6

Browse files
committed
Added fixes in Client.Encrypt
* aes_encrypt returns the authTag, so don't try to compute it outside the routine * Store verification key, not signature key, under "aws-crypto-public-key" in encryption context. * Add function to compute StringToByteSeq(Base64.Encode(_)). In the future, the Base64 module may offer routines that operate directly on seq<uint8> instead of just seq<char>. * Use ENDFRAME_SEQUENCE_NUMBER constant instead of numeric literal * Fix spelling mistake in comment
1 parent ad6e97e commit 4c9d5d6

File tree

5 files changed

+39
-16
lines changed

5 files changed

+39
-16
lines changed

src/SDK/CMM/DefaultCMM.dfy

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ module DefaultCMMDef {
6161
case None => return Failure("Keygen error");
6262
case Some(ab) =>
6363
enc_sk := Some(ab.1);
64-
enc_ec := [(Materials.EC_PUBLIC_KEY_FIELD, StringToByteSeq(Base64.Encode(ab.1)))] + enc_ec;
64+
enc_ec := [(Materials.EC_PUBLIC_KEY_FIELD, Base64.EncodeToByteSeq(ab.0))] + enc_ec;
6565
}
6666

6767
var in_enc_mat := new Materials.EncryptionMaterials(id, [], enc_ec, None, enc_sk);

src/SDK/Client.dfy

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,10 @@ module ESDKClient {
6969
var unauthenticatedHeader := wr.data;
7070

7171
var iv: seq<uint8> := seq(encMat.algorithmSuiteID.IVLength(), _ => 0);
72-
var authTag :- MessageBody.Encrypt(encMat.algorithmSuiteID, iv, derivedDataKey, [], unauthenticatedHeader);
72+
var pair :- MessageBody.Encrypt(encMat.algorithmSuiteID, iv, derivedDataKey, [], unauthenticatedHeader);
73+
assert |pair.0| == 0;
74+
var headerAuthentication := Msg.HeaderAuthentication(iv, pair.1);
75+
var _ :- Serialize.SerializeHeaderAuthentication(wr, headerAuthentication, encMat.algorithmSuiteID);
7376

7477
/*
7578
* Encrypt the given plaintext into the message body.
@@ -81,7 +84,7 @@ module ESDKClient {
8184
* Add footer with signature, if required.
8285
*/
8386

84-
var msg := unauthenticatedHeader + authTag + body;
87+
var msg := wr.data + body;
8588

8689
match encMat.algorithmSuiteID.SignatureType() {
8790
case None =>

src/SDK/MessageBody.dfy

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -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
}

src/StandardLibrary/Base64.dfy

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,14 @@ module Base64 {
231231
res
232232
}
233233

234+
function method DecodeFromByteSeq(s: seq<uint8>): Result<seq<uint8>> {
235+
Decode(ByteSeqToString(s))
236+
}
237+
238+
function method EncodeToByteSeq(b: seq<uint8>): seq<uint8> {
239+
StringToByteSeq(Encode(b))
240+
}
241+
234242
method TestBase64(msg: string, expected: string)
235243
requires forall k :: 0 <= k < |msg| ==> 0 <= msg[k] as int < 0x100
236244
{

src/extern/dotnet/EncryptionExtern.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,7 @@ public static STL.Option<byteseq> Sign(ECDSAParams x, byteseq sk, byteseq msg) {
222222
byte[] bytes = SignatureToByteArray(sig[0], sig[1]);
223223
if (bytes.Length != x.SignatureLength()) {
224224
// Most of the time, a signature of the wrong length can be fixed
225-
// be negating s in the signature relative to the group order.
225+
// by negating s in the signature relative to the group order.
226226
bytes = SignatureToByteArray(sig[0], p.N.Subtract(sig[1]));
227227
if (bytes.Length != x.SignatureLength()) {
228228
// We give up. :(

0 commit comments

Comments
 (0)