зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1698017 - Update ODoH to draft 06, r=necko-reviewers,dragana
Differential Revision: https://phabricator.services.mozilla.com/D110915
This commit is contained in:
Родитель
ef16e154ae
Коммит
6d57ed5e05
|
@ -156,10 +156,10 @@ union NetAddr {
|
|||
bool ToStringBuffer(char* buf, uint32_t bufSize) const;
|
||||
};
|
||||
|
||||
#define ODOH_VERSION 0xff04
|
||||
#define ODOH_VERSION 0xff06
|
||||
static const char kODoHQuery[] = "odoh query";
|
||||
static const char hODoHConfigID[] = "odoh key id";
|
||||
static const char kODoHSecret[] = "odoh secret";
|
||||
static const char kODoHResponse[] = "odoh response";
|
||||
static const char kODoHKey[] = "odoh key";
|
||||
static const char kODoHNonce[] = "odoh nonce";
|
||||
|
||||
|
|
|
@ -1417,11 +1417,12 @@ static SECStatus HKDFExpand(PK11SymKey* aPrk, const SECItem* aInfo, int aLen,
|
|||
return SECSuccess;
|
||||
}
|
||||
|
||||
/* def decrypt_response_body(context, Q_plain, R_encrypted):
|
||||
* key, nonce = derive_secrets(context, Q_plain)
|
||||
* aad = 0x02 || 0x0000 // 0x0000 represents a 0-length KeyId
|
||||
* R_plain, error = Open(key, nonce, aad, R_encrypted)
|
||||
* return R_plain, error
|
||||
/*
|
||||
* def decrypt_response_body(context, Q_plain, R_encrypted, response_nonce):
|
||||
* aead_key, aead_nonce = derive_secrets(context, Q_plain, response_nonce)
|
||||
* aad = 0x02 || len(response_nonce) || response_nonce
|
||||
* R_plain, error = Open(key, nonce, aad, R_encrypted)
|
||||
* return R_plain, error
|
||||
*/
|
||||
bool ODoHDNSPacket::DecryptDNSResponse() {
|
||||
ObliviousDoHMessage message;
|
||||
|
@ -1434,33 +1435,39 @@ bool ODoHDNSPacket::DecryptDNSResponse() {
|
|||
return false;
|
||||
}
|
||||
|
||||
// KeyID for response should be empty.
|
||||
if (!message.mKeyId.IsEmpty()) {
|
||||
const unsigned int kResponseNonceLen = 16;
|
||||
// KeyId is actually response_nonce
|
||||
if (message.mKeyId.Length() != kResponseNonceLen) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// def derive_secrets(context, Q_plain):
|
||||
// odoh_secret = context.Export("odoh secret", 32)
|
||||
// odoh_prk = Extract(Q_plain, odoh_secret)
|
||||
// def derive_secrets(context, Q_plain, response_nonce):
|
||||
// secret = context.Export("odoh response", Nk)
|
||||
// salt = Q_plain || len(response_nonce) || response_nonce
|
||||
// prk = Extract(salt, secret)
|
||||
// key = Expand(odoh_prk, "odoh key", Nk)
|
||||
// nonce = Expand(odoh_prk, "odoh nonce", Nn)
|
||||
// return key, nonce
|
||||
const SECItem kODoHSecretInfoItem = {
|
||||
siBuffer, (unsigned char*)kODoHSecret,
|
||||
static_cast<unsigned int>(strlen(kODoHSecret))};
|
||||
const int kAes128GcmKeyLen = 16;
|
||||
const int kAes128GcmNonceLen = 12;
|
||||
const SECItem kODoHResponsetInfoItem = {
|
||||
siBuffer, (unsigned char*)kODoHResponse,
|
||||
static_cast<unsigned int>(strlen(kODoHResponse))};
|
||||
const unsigned int kAes128GcmKeyLen = 16;
|
||||
const unsigned int kAes128GcmNonceLen = 12;
|
||||
PK11SymKey* tmp = nullptr;
|
||||
SECStatus rv =
|
||||
PK11_HPKE_ExportSecret(mContext, &kODoHSecretInfoItem, 32, &tmp);
|
||||
SECStatus rv = PK11_HPKE_ExportSecret(mContext, &kODoHResponsetInfoItem,
|
||||
kAes128GcmKeyLen, &tmp);
|
||||
if (rv != SECSuccess) {
|
||||
LOG(("ODoHDNSPacket::DecryptDNSResponse export secret failed"));
|
||||
return false;
|
||||
}
|
||||
UniquePK11SymKey odohSecret(tmp);
|
||||
|
||||
SECItem* salt(::SECITEM_AllocItem(nullptr, nullptr, mPlainQuery->len));
|
||||
SECItem* salt(::SECITEM_AllocItem(nullptr, nullptr,
|
||||
mPlainQuery->len + 2 + kResponseNonceLen));
|
||||
memcpy(salt->data, mPlainQuery->data, mPlainQuery->len);
|
||||
NetworkEndian::writeUint16(&salt->data[mPlainQuery->len], kResponseNonceLen);
|
||||
memcpy(salt->data + mPlainQuery->len + 2, message.mKeyId.Elements(),
|
||||
kResponseNonceLen);
|
||||
UniqueSECItem st(salt);
|
||||
UniquePK11SymKey odohPrk;
|
||||
rv = HKDFExtract(salt, odohSecret.get(), odohPrk);
|
||||
|
@ -1498,8 +1505,13 @@ bool ODoHDNSPacket::DecryptDNSResponse() {
|
|||
return false;
|
||||
}
|
||||
|
||||
// aad = 0x02 || 0x0000
|
||||
uint8_t aad[] = {0x2, 0, 0};
|
||||
// aad = 0x02 || len(response_nonce) || response_nonce
|
||||
SECItem* aadItem(
|
||||
::SECITEM_AllocItem(nullptr, nullptr, 1 + 2 + kResponseNonceLen));
|
||||
aadItem->data[0] = ODOH_RESPONSE;
|
||||
NetworkEndian::writeUint16(&aadItem->data[1], kResponseNonceLen);
|
||||
memcpy(&aadItem->data[3], message.mKeyId.Elements(), kResponseNonceLen);
|
||||
UniqueSECItem aad(aadItem);
|
||||
|
||||
SECItem paramItem;
|
||||
CK_GCM_PARAMS param;
|
||||
|
@ -1507,8 +1519,8 @@ bool ODoHDNSPacket::DecryptDNSResponse() {
|
|||
param.ulIvLen = derivedItem->len;
|
||||
param.ulIvBits = param.ulIvLen * 8;
|
||||
param.ulTagBits = 16 * 8;
|
||||
param.pAAD = (CK_BYTE_PTR)aad;
|
||||
param.ulAADLen = 3;
|
||||
param.pAAD = (CK_BYTE_PTR)aad->data;
|
||||
param.ulAADLen = aad->len;
|
||||
|
||||
paramItem.type = siBuffer;
|
||||
paramItem.data = (unsigned char*)(¶m);
|
||||
|
@ -1519,7 +1531,8 @@ bool ODoHDNSPacket::DecryptDNSResponse() {
|
|||
MAX_SIZE, message.mEncryptedMessage.Elements(),
|
||||
message.mEncryptedMessage.Length());
|
||||
if (rv != SECSuccess) {
|
||||
LOG(("ODoHDNSPacket::DecryptDNSResponse decrypt failed"));
|
||||
LOG(("ODoHDNSPacket::DecryptDNSResponse decrypt failed %d",
|
||||
PORT_GetError()));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -506,7 +506,6 @@ skip-if = os == "android" || !debug
|
|||
[test_SuperfluousAuth.js]
|
||||
[test_odoh.js]
|
||||
run-sequentially = node server exceptions dont replay well
|
||||
skip-if = true # Bug 1709551
|
||||
[test_trr_confirmation.js]
|
||||
skip-if = os =='android' || socketprocess_networking # confirmation state isn't passed cross-process
|
||||
run-sequentially = node server exceptions dont replay well
|
||||
|
|
|
@ -14,11 +14,12 @@ default = ["console_error_panic_hook"]
|
|||
|
||||
[dependencies]
|
||||
wasm-bindgen = "0.2.63"
|
||||
odoh-rs = "=0.1.8"
|
||||
hpke = "0.4.3"
|
||||
odoh-rs = "=0.1.10"
|
||||
hpke = "=0.5.0"
|
||||
js-sys = "0.3"
|
||||
hex = "0.4"
|
||||
futures = "0.3.1"
|
||||
rand = "=0.7"
|
||||
|
||||
# The `console_error_panic_hook` crate provides better debugging of panics by
|
||||
# logging them with `console.error`. This is great for development, but requires
|
||||
|
|
|
@ -93,22 +93,22 @@ module.exports.__wbg_log_b3f203d9e6882397 = function(arg0, arg1) {
|
|||
console.log(getStringFromWasm0(arg0, arg1));
|
||||
};
|
||||
|
||||
module.exports.__wbg_buffer_bc64154385c04ac4 = function(arg0) {
|
||||
module.exports.__wbg_buffer_ebc6c8e75510eae3 = function(arg0) {
|
||||
var ret = getObject(arg0).buffer;
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
|
||||
module.exports.__wbg_newwithbyteoffsetandlength_3c8748473807c7cf = function(arg0, arg1, arg2) {
|
||||
module.exports.__wbg_newwithbyteoffsetandlength_ca3d3d8811ecb569 = function(arg0, arg1, arg2) {
|
||||
var ret = new Uint8Array(getObject(arg0), arg1 >>> 0, arg2 >>> 0);
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
|
||||
module.exports.__wbg_new_22a33711cf65b661 = function(arg0) {
|
||||
module.exports.__wbg_new_135e963dedf67b22 = function(arg0) {
|
||||
var ret = new Uint8Array(getObject(arg0));
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
|
||||
module.exports.__wbg_newwithlength_48451d71403bfede = function(arg0) {
|
||||
module.exports.__wbg_newwithlength_78dc302d31527318 = function(arg0) {
|
||||
var ret = new Uint8Array(arg0 >>> 0);
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
|
|
Двоичные данные
testing/xpcshell/odoh-wasm/pkg/odoh_wasm_bg.wasm
Двоичные данные
testing/xpcshell/odoh-wasm/pkg/odoh_wasm_bg.wasm
Двоичный файл не отображается.
|
@ -21,6 +21,11 @@ pub type Kem = X25519HkdfSha256;
|
|||
#[global_allocator]
|
||||
static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;
|
||||
|
||||
pub const ODOH_VERSION: u16 = 0xff06;
|
||||
const KEM_ID: u16 = 0x0020;
|
||||
const KDF_ID: u16 = 0x0001;
|
||||
const AEAD_ID: u16 = 0x0001;
|
||||
|
||||
// random bytes, should be 32 bytes for X25519 keys
|
||||
pub const IKM: &str = "871389a8727130974e3eb3ee528d440a871389a8727130974e3eb3ee528d440a";
|
||||
|
||||
|
@ -53,9 +58,9 @@ fn generate_key_pair() -> ObliviousDoHKeyPair {
|
|||
let (secret_key, public_key) = Kem::derive_keypair(&ikm_bytes);
|
||||
let public_key_bytes = public_key.to_bytes().to_vec();
|
||||
let odoh_public_key = ObliviousDoHConfigContents {
|
||||
kem_id: 0x0020,
|
||||
kdf_id: 0x0001,
|
||||
aead_id: 0x0001,
|
||||
kem_id: KEM_ID,
|
||||
kdf_id: KDF_ID,
|
||||
aead_id: AEAD_ID,
|
||||
public_key: public_key_bytes,
|
||||
};
|
||||
ObliviousDoHKeyPair {
|
||||
|
@ -70,11 +75,11 @@ pub fn get_odoh_config() -> js_sys::Uint8Array {
|
|||
let public_key_bytes = key_pair.public_key.public_key;
|
||||
let length_bytes = (public_key_bytes.len() as u16).to_be_bytes();
|
||||
let odoh_config_length = 12 + public_key_bytes.len();
|
||||
let version = 0xff04;
|
||||
let version = ODOH_VERSION;
|
||||
let odoh_contents_length = 8 + public_key_bytes.len();
|
||||
let kem_id = 0x0020; // DHKEM(X25519, HKDF-SHA256)
|
||||
let kdf_id = 0x0001; // KDF(SHA-256)
|
||||
let aead_id = 0x0001; // AEAD(AES-GCM-128)
|
||||
let kem_id = KEM_ID; // DHKEM(X25519, HKDF-SHA256)
|
||||
let kdf_id = KDF_ID; // KDF(SHA-256)
|
||||
let aead_id = AEAD_ID; // AEAD(AES-GCM-128)
|
||||
let mut result = vec![];
|
||||
result.extend(&((odoh_config_length as u16).to_be_bytes()));
|
||||
result.extend(&((version as u16).to_be_bytes()));
|
||||
|
@ -123,15 +128,22 @@ pub fn create_response(
|
|||
unsafe {
|
||||
if let Some(body) = &QUERY_BODY {
|
||||
if let Some(secret) = &SERVER_SECRET {
|
||||
// random bytes
|
||||
let nonce = vec![0x1b, 0xff, 0xfd, 0xff, 0x1a, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xe];
|
||||
let result = executor::block_on(create_response_msg(
|
||||
&secret,
|
||||
&response,
|
||||
None,
|
||||
Some(nonce),
|
||||
&body,
|
||||
));
|
||||
let generated_response = match result {
|
||||
Ok(r) => r,
|
||||
Err(_) => return js_sys::Uint8Array::new_with_length(0),
|
||||
Err(_) => {
|
||||
console_log!("create_response_msg failed!");
|
||||
return js_sys::Uint8Array::new_with_length(0);
|
||||
}
|
||||
};
|
||||
|
||||
QUERY_BODY = None;
|
||||
|
|
Загрузка…
Ссылка в новой задаче