Expand description
The CPace exchange that hands the credentials of an enrolled device to a new one, reverse engineered from 1Passwordβs WASM module: the local crypto, and the requests that carry it.
The new device proves it knows the verification code the user reads off the enrolled device, and both sides end up with the same key to move the credential bundle through the server.
StructsΒ§
- Ad π
- The associated data of a CPace message.
- MsgA π
- The first CPace message, from the enrolled device.
ConstantsΒ§
- CREDENTIAL_
BUNDLE_ πAAD - EXCHANGE_
KEY_ πINFO - PADDING_
LENGTH π - Pads the second hash input through the passcode hash to one 128 byte SHA-512 block.
- PASSCODE_
ITERATIONS π - TRANSPORT_
KEY_ πID - The key id of the exchange key, which also keys the first step of deriving it.
FunctionsΒ§
- calculate_
auth_ πa_ hash - The point both sides agree on:
yatimes the client scalar. - calculate_
auth_ πb_ hash - The session secret, hashed over the whole transcript.
- calculate_
auth_ πb_ tag_ b - Calculates the shared secret
authBand thetagbthat proves knowing it. - calculate_
first_ πhash - Binds the exchange to the user, the sign-in address and the enrollment.
- calculate_
msg_ πb - Calculates
msgb, the new deviceβs answer tomsga. - calculate_
passcode_ πhash - Stretches the verification code, salted by the enrolled device.
- calculate_
second_ πhash - The input of the CPace generator, which binds the passcode to the first hash and the session.
- calculate_
tag_ πb - The MAC of
msgbunder a key derived fromauthB. - cpace_
endpoint π - The CPace endpoints, under the enrollmentβs
cpaceprefix. - decompress_
point π - Fails for anything but the canonical encoding of a point.
- decrypt_
credentials π - Decrypts the credential bundle the enrolled device shared.
- derive_
exchange_ πkey - Derives the key that encrypts the credential bundle in transit from
authB. - enrollment_
endpoint π v3/device/enrollments/{enrollmentUuid}/{method}- expect_
success π - The server confirms each CPace message with
success: 1. - get_
tag_ πa - Waits for the enrolled deviceβs
taga, which onlyverify_tag_alooks at. - hmac_
sha384 π - hmac_
sha512 π - leb128_
prefixed π - Prefixes every field with its length as LEB128, and concatenates them.
- multiply_
by_ πclient_ scalar - Multiplies by the scalar the client secret reduces to, and compresses the result.
- parse_
msg_ πa - Parses the JSON of
msga, after its base64 layer is removed. - perform_
cpace π - Runs the whole exchange over
restwith a fresh random client secret and returns the credentials the enrolled device shared. - perform_
cpace_ πwith_ client_ secret - The CPace exchange with the client secret injected so the test vectors can pin it.
- post_
json_ πuntil_ result - POSTs until the endpoint answers a body instead of the empty 200 it sends while the enrolled device has not replied yet. The web frontend retries the same way.
- request_
encrypted_ πcredentials - Waits for the credential bundle, still encrypted for the exchange key and so invisible to the server that relays it.
- request_
msg_ πa - Fetches and parses the enrolled deviceβs first message.
- send_
msg_ πb - Replies with
msgband expects the server to accept it. - send_
tag_ πb - Replies with
tagband expects the server to accept it. - sha512 π
- sign_
in_ πbody - The body every CPace request carries besides the messages themselves.
- verify_
tag_ πa - Would check
taga, which proves the enrolled device knows the verification code too. - write_
leb128_ πprefixed - Writes
dataafter its length, as the little endian base 128 varint the WASM module uses.