Skip to content

Commit 1ae3e06

Browse files
committed
Moving to a more formal authentication secret
1 parent 4e1178c commit 1ae3e06

4 files changed

Lines changed: 34 additions & 21 deletions

File tree

nodejs/ece.js

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ var AES_GCM = 'id-aes128-GCM';
99
var TAG_LENGTH = 16;
1010
var KEY_LENGTH = 16;
1111
var NONCE_LENGTH = 12;
12+
var SHA_256_LENGTH = 32;
1213
var MODE_ENCRYPT = 'encrypt';
1314
var MODE_DECRYPT = 'decrypt';
1415

@@ -38,6 +39,10 @@ function HKDF_expand(prk, info, l) {
3839
return output.slice(0, l);
3940
}
4041

42+
function HKDF(salt, ikm, info, l) {
43+
return HKDF_expand(HKDF_extract(salt, ikm), info, l);
44+
}
45+
4146
function info(base, context) {
4247
return Buffer.concat([
4348
new Buffer('Content-Encoding: ' + base + '\0', 'ascii'),
@@ -110,11 +115,9 @@ function extractSecretAndContext(params, mode) {
110115
if (!secret) {
111116
throw new Error('Unable to determine key');
112117
}
113-
if (params.expandedContext) {
114-
context = Buffer.concat([
115-
context,
116-
base64.decode(params.expandedContext)
117-
]);
118+
if (params.authSecret) {
119+
secret = HKDF(base64.decode(params.authSecret), secret,
120+
info('auth', new Buffer(0)), SHA_256_LENGTH);
118121
}
119122
return { secret: secret, context: context };
120123
}

nodejs/test.js

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

51-
function expandedContext() {
51+
function authenticationSecret() {
5252
var length = crypto.randomBytes(4);
5353
var params = {
5454
key: base64.encode(crypto.randomBytes(16)),
5555
salt: base64.encode(crypto.randomBytes(16)),
5656
rs: length.readUInt16BE(0) + 1,
57-
expandedContext: base64.encode(crypto.randomBytes(16))
57+
authSecret: base64.encode(crypto.randomBytes(16))
5858
};
5959
log('Key: ' + base64.encode(params.key));
60-
log('Context: ' + base64.encode(params.expandedContext));
60+
log('Context: ' + base64.encode(params.authSecret));
6161
encryptDecrypt(length.readUInt16BE(2), params);
6262
}
6363

@@ -149,7 +149,7 @@ function useDH() {
149149
var i;
150150
for (i = 0; i < count; ++i) {
151151
useExplicitKey();
152-
expandedContext();
152+
authenticationSecret();
153153
exactlyOneRecord();
154154
detectTruncation();
155155
useKeyId();

python/http_ece/__init__.py

Lines changed: 16 additions & 6 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, expandedContext=b""):
13+
def deriveKey(mode, salt, key=None, dh=None, keyid=None, authSecret=b""):
1414
def buildInfo(base, context):
15-
return b"Content-Encoding: " + base + b"\0" + context + expandedContext
15+
return b"Content-Encoding: " + base + b"\0" + context
1616

1717
def deriveDH(mode, keyid, dh):
1818
def lengthPrefix(key):
@@ -53,6 +53,16 @@ def lengthPrefix(key):
5353
if secret is None:
5454
raise Exception(u"unable to determine the secret")
5555

56+
if authSecret is not None:
57+
hkdf_auth = HKDF(
58+
algorithm=hashes.SHA256(),
59+
length=32,
60+
salt=authSecret,
61+
info=buildInfo(b"auth", b""),
62+
backend=default_backend()
63+
)
64+
secret = hkdf_auth.derive(secret)
65+
5666
hkdf_key = HKDF(
5767
algorithm=hashes.SHA256(),
5868
length=16,
@@ -75,7 +85,7 @@ def iv(base, counter):
7585
(mask,) = struct.unpack("!Q", base[4:])
7686
return base[:4] + struct.pack("!Q", counter ^ mask)
7787

78-
def decrypt(buffer, salt, key=None, keyid=None, dh=None, rs=4096, expandedContext=b""):
88+
def decrypt(buffer, salt, key=None, keyid=None, dh=None, rs=4096, authSecret=b""):
7989
def decryptRecord(key, nonce, counter, buffer):
8090
decryptor = Cipher(
8191
algorithms.AES(key),
@@ -91,7 +101,7 @@ def decryptRecord(key, nonce, counter, buffer):
91101

92102
(key_, nonce_) = deriveKey(mode="decrypt", salt=salt,
93103
key=key, keyid=keyid, dh=dh,
94-
expandedContext=expandedContext)
104+
authSecret=authSecret)
95105
if rs < 2:
96106
raise Exception(u"Record size too small")
97107
rs += 16 # account for tags
@@ -105,7 +115,7 @@ def decryptRecord(key, nonce, counter, buffer):
105115
counter += 1
106116
return result
107117

108-
def encrypt(buffer, salt, key=None, keyid=None, dh=None, rs=4096, expandedContext=b""):
118+
def encrypt(buffer, salt, key=None, keyid=None, dh=None, rs=4096, authSecret=b""):
109119
def encryptRecord(key, nonce, counter, buffer):
110120
encryptor = Cipher(
111121
algorithms.AES(key),
@@ -118,7 +128,7 @@ def encryptRecord(key, nonce, counter, buffer):
118128

119129
(key_, nonce_) = deriveKey(mode="encrypt", salt=salt,
120130
key=key, keyid=keyid, dh=dh,
121-
expandedContext=expandedContext)
131+
authSecret=authSecret)
122132
if rs < 2:
123133
raise Exception(u"Record size too small")
124134
rs -= 1 # account for padding

python/test.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,14 +34,14 @@ def encryptDecrypt(length, encryptParams, decryptParams=None):
3434
keyid=encryptParams.get("keyid"),
3535
dh=encryptParams.get("dh"),
3636
rs=encryptParams.get("rs"),
37-
expandedContext=encryptParams.get("expandedContext", b""))
37+
authSecret=encryptParams.get("authSecret", b""))
3838
log("Encrypted: " + b64e(encrypted))
3939
decrypted = ece.decrypt(encrypted, salt=decryptParams.get("salt"),
4040
key=decryptParams.get("key"),
4141
keyid=decryptParams.get("keyid"),
4242
dh=decryptParams.get("dh"),
4343
rs=decryptParams.get("rs"),
44-
expandedContext=decryptParams.get("expandedContext", b""))
44+
authSecret=decryptParams.get("authSecret", b""))
4545
log("Decrypted: " + b64e(decrypted))
4646
assert input == decrypted
4747
log("----- OK");
@@ -56,15 +56,15 @@ def useExplicitKey():
5656
encryptDecrypt(rlen() + 1, params)
5757

5858

59-
def expandedContext():
59+
def authSecret():
6060
params = {
6161
"key": os.urandom(16),
6262
"salt": os.urandom(16),
6363
"rs": rlen() + 1,
64-
"expandedContext": os.urandom(10)
64+
"authSecret": os.urandom(10)
6565
}
6666
log("Key: " + b64e(params["key"]))
67-
log("Context: " + b64e(params["expandedContext"]))
67+
log("Context: " + b64e(params["authSecret"]))
6868
encryptDecrypt(rlen() + 1, params)
6969

7070

@@ -150,7 +150,7 @@ def isUncompressed(k):
150150
if __name__ == "__main__":
151151
for i in list(range(0,count)):
152152
useExplicitKey()
153-
expandedContext()
153+
authSecret()
154154
exactlyOneRecord()
155155
detectTruncation()
156156
useKeyId()

0 commit comments

Comments
 (0)