Skip to content

Commit 4e1178c

Browse files
committed
Adding support for expanded context
1 parent ffedd54 commit 4e1178c

4 files changed

Lines changed: 47 additions & 9 deletions

File tree

nodejs/ece.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,12 @@ function extractSecretAndContext(params, mode) {
110110
if (!secret) {
111111
throw new Error('Unable to determine key');
112112
}
113+
if (params.expandedContext) {
114+
context = Buffer.concat([
115+
context,
116+
base64.decode(params.expandedContext)
117+
]);
118+
}
113119
return { secret: secret, context: context };
114120
}
115121

nodejs/test.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,19 @@ function useExplicitKey() {
4848
encryptDecrypt(length.readUInt16BE(2), params);
4949
}
5050

51+
function expandedContext() {
52+
var length = crypto.randomBytes(4);
53+
var params = {
54+
key: base64.encode(crypto.randomBytes(16)),
55+
salt: base64.encode(crypto.randomBytes(16)),
56+
rs: length.readUInt16BE(0) + 1,
57+
expandedContext: base64.encode(crypto.randomBytes(16))
58+
};
59+
log('Key: ' + base64.encode(params.key));
60+
log('Context: ' + base64.encode(params.expandedContext));
61+
encryptDecrypt(length.readUInt16BE(2), params);
62+
}
63+
5164
function exactlyOneRecord() {
5265
var length = Math.min(crypto.randomBytes(2).readUInt16BE(0), maxLen);
5366
var params = {
@@ -136,6 +149,7 @@ function useDH() {
136149
var i;
137150
for (i = 0; i < count; ++i) {
138151
useExplicitKey();
152+
expandedContext();
139153
exactlyOneRecord();
140154
detectTruncation();
141155
useKeyId();

python/http_ece/__init__.py

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@
1010
keys = {}
1111
labels = {}
1212

13-
def deriveKey(mode, salt, key=None, dh=None, keyid=None):
13+
def deriveKey(mode, salt, key=None, dh=None, keyid=None, expandedContext=b""):
1414
def buildInfo(base, context):
15-
return b"Content-Encoding: " + base + b"\0" + context
15+
return b"Content-Encoding: " + base + b"\0" + context + expandedContext
1616

1717
def deriveDH(mode, keyid, dh):
1818
def lengthPrefix(key):
@@ -43,7 +43,7 @@ def lengthPrefix(key):
4343
if salt is None or len(salt) != 16:
4444
raise Exception(u"'salt' must be a 16 octet value")
4545

46-
context = b''
46+
context = b""
4747
if key is not None:
4848
secret = key
4949
elif dh is not None:
@@ -75,7 +75,7 @@ def iv(base, counter):
7575
(mask,) = struct.unpack("!Q", base[4:])
7676
return base[:4] + struct.pack("!Q", counter ^ mask)
7777

78-
def decrypt(buffer, salt, key=None, keyid=None, dh=None, rs=4096):
78+
def decrypt(buffer, salt, key=None, keyid=None, dh=None, rs=4096, expandedContext=b""):
7979
def decryptRecord(key, nonce, counter, buffer):
8080
decryptor = Cipher(
8181
algorithms.AES(key),
@@ -90,7 +90,8 @@ def decryptRecord(key, nonce, counter, buffer):
9090
return data
9191

9292
(key_, nonce_) = deriveKey(mode="decrypt", salt=salt,
93-
key=key, keyid=keyid, dh=dh)
93+
key=key, keyid=keyid, dh=dh,
94+
expandedContext=expandedContext)
9495
if rs < 2:
9596
raise Exception(u"Record size too small")
9697
rs += 16 # account for tags
@@ -104,7 +105,7 @@ def decryptRecord(key, nonce, counter, buffer):
104105
counter += 1
105106
return result
106107

107-
def encrypt(buffer, salt, key=None, keyid=None, dh=None, rs=4096):
108+
def encrypt(buffer, salt, key=None, keyid=None, dh=None, rs=4096, expandedContext=b""):
108109
def encryptRecord(key, nonce, counter, buffer):
109110
encryptor = Cipher(
110111
algorithms.AES(key),
@@ -116,7 +117,8 @@ def encryptRecord(key, nonce, counter, buffer):
116117
return data
117118

118119
(key_, nonce_) = deriveKey(mode="encrypt", salt=salt,
119-
key=key, keyid=keyid, dh=dh)
120+
key=key, keyid=keyid, dh=dh,
121+
expandedContext=expandedContext)
120122
if rs < 2:
121123
raise Exception(u"Record size too small")
122124
rs -= 1 # account for padding

python/test.py

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,15 @@ def encryptDecrypt(length, encryptParams, decryptParams=None):
3333
key=encryptParams.get("key"),
3434
keyid=encryptParams.get("keyid"),
3535
dh=encryptParams.get("dh"),
36-
rs=encryptParams.get("rs"))
36+
rs=encryptParams.get("rs"),
37+
expandedContext=encryptParams.get("expandedContext", b""))
3738
log("Encrypted: " + b64e(encrypted))
3839
decrypted = ece.decrypt(encrypted, salt=decryptParams.get("salt"),
3940
key=decryptParams.get("key"),
4041
keyid=decryptParams.get("keyid"),
4142
dh=decryptParams.get("dh"),
42-
rs=decryptParams.get("rs"))
43+
rs=decryptParams.get("rs"),
44+
expandedContext=decryptParams.get("expandedContext", b""))
4345
log("Decrypted: " + b64e(decrypted))
4446
assert input == decrypted
4547
log("----- OK");
@@ -54,6 +56,19 @@ def useExplicitKey():
5456
encryptDecrypt(rlen() + 1, params)
5557

5658

59+
def expandedContext():
60+
params = {
61+
"key": os.urandom(16),
62+
"salt": os.urandom(16),
63+
"rs": rlen() + 1,
64+
"expandedContext": os.urandom(10)
65+
}
66+
log("Key: " + b64e(params["key"]))
67+
log("Context: " + b64e(params["expandedContext"]))
68+
encryptDecrypt(rlen() + 1, params)
69+
70+
71+
5772
def exactlyOneRecord():
5873
length = min(rlen(), maxLen)
5974
params = {
@@ -135,6 +150,7 @@ def isUncompressed(k):
135150
if __name__ == "__main__":
136151
for i in list(range(0,count)):
137152
useExplicitKey()
153+
expandedContext()
138154
exactlyOneRecord()
139155
detectTruncation()
140156
useKeyId()

0 commit comments

Comments
 (0)