This commit is contained in:
Dirk-Willem van Gulik 2023-02-16 04:44:53 -07:00 committed by GitHub
commit 2ad63f63db
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 13909 additions and 0 deletions

View File

@ -0,0 +1,126 @@
# DP3-T Implementation profile
Against version 2020/4/20 of the whitepaper
## Design 1
The PRF used is HMAC-SHA256 as per RFC 6234 and RFC 2104 - and and where Skt_ is used as the 'key and the string “Broadcast key"” (without trailing \0, i.e. exactly those 13 US-ASCII characters is the plaintext (i.e ASCII, not UTF8 with a 2 byte UTF8 bom prefix as in the apple/google proposals"):
const unsigned char plaintext[ 13 ] = {
0x42, 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61,
0x73, 0x74, 0x20, 0x6b, 0x65, 0x79
};
**Attention**: in some places in the documents/reference pager the string 'broadcast key' is used (first char lowercase).
#### Example PRF
For a seed of 32 0 bytes:
00000000000000000000000000000000
the PRF is the HMAC of that seed taken as a key and the string as the plaintext (with as per RFC 2014 definition of seed/plaintext). This results into:
d59d48e21935f3389e3bd3eb02cf66989190b7b09ed6c0a4b9616f49455c4f9a
The PRG is used as the key in AES256 in counter mode; with the IV set to a 128 bit unsigned number in network order (i.e the first IV is a byte array if [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 ]) we start at 0, not 1 and the plaintext 128 bits of 0s for each day:
0 8fd521e6c47060efcbfdb9b801c30743
1 d86e56bb702117b8cf20dc4aadd42310
2 964ae662b3f174814660846d4f9c11e2
3 374d270a0c559ad1e4672fb1688ae5ad
4 b5d017a67940300cd28b59a94f739c0e
5 3208756abf0314be9ffc27a0c391ee91
6 75b14e4879cd0d5b06cf2b460ab5559a
7 6ebfd0d03f8ba78086054f313af52c81
8 c3db7c504dd6172d1e48804bedbaebba
## Design 2
### General
Byte sequences are 8 bit octed strings.
In both designs - the CDN's webserver its Date: header set (RFC 2616, section 14.18) can be used, during the daily fetch, as the authoritative time specifier.
### Generating Empheral IDs
The H is an SHA256 as per per RFC 6234
TRUNKCATE128() takes the first 32 bytes (of the 64 byte SHA256)
Test vector:
Seed: 0000000000000000000000000000000000000000000000000000000000000000
(i.e. 0x00, 0x00 .. 0x00 32 bytes)
H (seed): 66687aadf862bd776c8fc18b8e9f8e20089714856ee233b3902a591d0d5f2925
TRUNKCATE128(H(seed)):
66687aadf862bd776c8fc18b8e9f8e20
### Local storare / handling of t
t is a network order (big endian) unsigned 32 bit number. I.e. the number 1 is encoded transmitted as 0x00, 0x00, 0x00, 0x01 on the wire.
t contains the unix UTC/Z timestamp as defined by RFC 3339.
So the H(EphID||t) stored is a SHA256 taken over 16 + 4 = 20 sequentiel bytes in that order (EphID, then time).
Test vector:
Time: 2020-4-10 00:00:00 UTC
T = 1586476800
5E8FB700 (4 bytes)
EphID || t =
66687aadf862bd776c8fc18b8e9f8e201586476800) (16+4 butes)
H(EphID || t)
109708e29597623f56fd365ba92f1c717ca23994aabd7939822909c465cb10a5 (32 bytes)
### Cuckoo filter and serialisation version 1.00
(Aligned with https://github.com/dirkx/DP-3T-Documents/tree/editable-version/impl/design-2-openssl-C)
The key shall be the hash as resulting from 2020/4/12 version of the Whitepaper: H(TRUNCATE128(H(seed))||i). No further hasing is required.
Note - hash propably not needed - less than 20% exposed.
The key shall be 32 bytes which are used as follows:
byte 0..3 up to <bits-hash bits for the LSB of the Cuckoo hash
byte 4..7 up to <bits-hash bits for the MSB of the Cuckoo hash
byte 8.. up to `<bits-verify>' bytes.
Where <bits-hash> and <bits-verify> are set as low as is feasible given the acceptable false positive rates.
The Cuckoo filter shall be serialised as:
Magic string 4 bytes D3, D3, 3D, 3D
Version 1 byte, major/minor, currently set to 0x10 for version 1.0
<Depth> 1 byte, fixed to 4
<bits-hash> 1 byte, without the occupy bit.
<bits-verify> 1 byte
<N buckets> 4 bytes, unsigned 32 bit integer, network order
<N slots> 4 bytes, unsigned 32 bit integer, network order
Followed by
<N buckets> with each
<Depth> slots with each
sequence of ( bit-hash + 1 )/ 8 rounded up bytes:
is occupied 1 bit
partial hash bits-hash bits
padding * any padding bits set to 0 if bits-hash +1 not a multiple of 8
verify hash bits-verify bits
padding * any padding bits set to 0 if bits-verify +1 not a multiple of 8
With the partial hash being limited to the number of bits needed for N buckets.
So this, 1.0, version of the serialisation does not pack the bits; both hashes are padded to the a full byte. Version numbers are semantically meaningful.
### Cuckoo filter publication
The filter should be published prefixed by a RFC3161 timestamp.

Binary file not shown.

13649
meta-arch/arch-seeder.vdx Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,43 @@
# Backoffice process for disclosure of contacts
# Assumptions
* Done by a medical professional in the context of a normal consult.
* Thus allowing for a professional assessment
* Thus allowing for accurate and appropriate advice, followups and so on -- meeting general accepted standards of medical care.
* Thus ensuring that the right (medical) information is captures in the right (separate) systems.
* Thus ensuring that the patient is able to provide an informed consent. With information professionally presented by a licensed medical professional at the appropriate levels and in the context of a treatment, patient/doctor relation.
# Process
* At some point, after explaining the ramifications the patient provides his or her informed consent to share the opaque infection information
* The medical professional may, or may not, log this as is required by their professional standards.
* The patient accesses a special section in the App and shows or conveys (e.g. over the phone) a sequence of (cryptographically random) 6 + 4 numbers or a sequence of words (aka as trustwords or ``car battery horse staple') in an appropriate language.
* The app posts a 32 byte hash of the opaque data that it intends to submit to a backend service with the first 6 digits as a reference.
* The health professional enters the the 6 + 4 digits into a backoffice systems; the system locates the hash an the professional then his or her UZI chipcard to digitally sign the hash+6+4 digits and posts the resulting S/MIME package back to the backend.
* The phone of the user picks this the signed package up; validates the signature of the professional using a build in root certifcate, paying attention to the 'flags' in the professional certficate (e.g. Zorgverlener waarvan het beroep valt onder artikel 3 van de Wet BIG) and if correct - posts the relevant opaque seeds to the backend along with the S/MIME package that contains the signed hash/10 digits. It then destroys any seeds and rekeys (as per the protocol).
* The backend receives this data, verifies the S/MIME signature, verifies that the hash contained in it matches that of the submitted seed and queues the seeds up to the next aggregation cycle.
## Special case for a patient that excercises his right to not know the results of the test.
In (most?) countries a patient has a right to not be informed of a test result in certain contexts.
* In this case - the patient generates the hash / 6 + 4 digits -prior- to consultation and test; and shares the 10 digits with the medical professional.
* Once the patient has left the room - the professinal may or may not use these to initiate the process once the rest results are in.
In this case - the user inteface of the app MUST be careful to not disclose this sharing.
In this case - the data needs to be kept for a while. It is not sensitive (it requires to the signature of the medical professonal - and professional standars dictate that this only can be given after reviewing the result in the contect of the indivudual patient).

BIN
meta-arch/backoffice.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 115 KiB

49
meta-arch/meta-arch.md Normal file
View File

@ -0,0 +1,49 @@
# Meta Architecture
Logical/abstract architecture - to help discuss the non-functional, information security and compliance aspects of any implementation. And help guide what needs to be arranged in terms of gouvernance.
## Overview
![Overview](overview.png)
A Mobile app(a) installed on million of devices does regular (e.g. 1-4 times per day) fetches through a common Content Delivery Network (CDN), with no particular integrity or reliability guarantees (best effort)[^1].
Fetched is a digitally signed file (c) with the contamination details of the day. This file is generated by a very reliable central backend (d) and contains just the relevant information.
At some point (e.g. on a national scale, several 10's to 100's of time an hour) a medical professional will ask if his patient is willing to divulge his contact.
If so - some process is initiated in the backoffce (g) by a medical professional (h).
The patients mobile (a) generates a nonce(f) which is then signed by the personal chipcard of the medical professional and returned to the phone (i).
Using the build in certificate; the mobile phone validates that the medical professional is licensed to practice (i.e. in the national registered of licensed medical professionals, with the right status and identified (these national registries also contain non-medical staff and `generic nameless card's).
The patent has then some sort of interaction and the phone sents (j) the opaque data to the central backend. Where (d) aggregates it regularly with the data of the past N days; and pushed it to the CDN (c) for publication.
Where a phone (a) fetches it (b), runs through the list & informs the user of any new contact.
## Back office
![backoffice](backoffice.png)
The device(a) posts, using plain http(s)/REST, its opaque contact data. This is filtered, at pure IP level, by (c); where no data is kept but a short log and a few flows.
It (d) arrives at a webserver (f) which publishes just the opaque contact data and nothing else onto a message bus(i). This webserver keeps nothing but a normal HTTP log file with IP address and user agent; for < 48 hours. But keeps no payload data.
Conceptually this frontend is separated from the rest by (h).
The message queue then has a certain level of persistence (short lived), (j) to deal with short outages & peak demand.
At a slower rate, readers (l) take the messages of the queue (k) and store this into a store.
During outages; cold/warm/hot stores (m) may get synchronised between sites (the contact lists in all current designs allow for easy merging by simply putting one on top of the other).
At regular interval (n) aggregators prepare a list for distribution and get this digitally signed. The resulting file, (o) is then pushed to a content delivery network (with no integrity & just best effort guarantees).
[^1]: It will likely be a requirement that the CDN webservers have the Date: header set (RFC 2616, section 14.18) correctly -- as this stabilises the calcuation of 't'.

42
meta-arch/meta-ux.md Normal file
View File

@ -0,0 +1,42 @@
# Meta UI/UX
## User journey's
_not yet written_
Questions to resolve
## Manual pull or auto pull.
Backend load is a concern - the more random te requests come in, the better. They should be updated at least once every 24 hours (H1) and it is makes no sense to do it more often that (H2).
So IMHO best practice would be auto pull with a nice bit random delay; and ONLY allow a reload by the user if the following two conditions are true a) the last successful load is more than H2 ago and b) the last successfull or unsuccessful reload is more than H3 ago.
## Can a user disable tracing.
Given the Waag and EU 'toolbox' requirements - entirely up to the user.
## Does the user need backups, etc.
The current protocol does not require backups on the phone side by design. Post contamination divulge/update of the backend the key is forcefully re-seeded. And therefore the `phone is as new'.
## Process for the infected / divulge process
Given the Waag and EU 'toolbox' requirements - it should be assumed that this can only be done by a medical professional who is licensed to practice. And who will also give the appropriate advice.
The actual process is TBD - but given that a low common denominator is desired - it may be something akin to providing a 6+4 digit number on the phone which is valid for 30 minutes - that the health professional enters into a web interface on his or her device/desktop.
The actual protocol from thereon is not defined - but probably entails the phone posting a nonce along the 6 digits to some queue; it polling/WS-getting that nonce, with the 4 digits back signed by a medical professional. After which the phone posts its seeds, destroys its old data, and restarts the seed process.
The user is shownsome sort of progress, OK thing.
--------
H1: daily guaranteed update rate - e.g 24 Hrs
H2: target update rate / best effort - e.g. 6 hours.
H3: max repeat of retries we can handle: 120 seconds

BIN
meta-arch/overview.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB