Skip to content

Commit e20448c

Browse files
document HPKE's mode_psk as unsupported
1 parent 4bfe929 commit e20448c

7 files changed

Lines changed: 17 additions & 5 deletions

File tree

‎README.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
- [RFC 7516 (JWE)](https://datatracker.ietf.org/doc/html/rfc7516) and [RFC 7518 (JWA)](https://datatracker.ietf.org/doc/html/rfc7518): compact and JSON serialization (incl. multiple recipients with per-recipient headers), `A256KW`, `PBES2-HS512+A256KW`, `ECDH-ES+A256KW` (P-256/P-384/P-521), `A128GCM`/`A256GCM`
1111
- [RFC 7515 (JWS)](https://datatracker.ietf.org/doc/html/rfc7515): compact serialization, `HS256`/`HS384`/`HS512`
1212
- [draft-ietf-jose-hpke-encrypt](https://datatracker.ietf.org/doc/draft-ietf-jose-hpke-encrypt/): use of HPKE ([RFC 9180](https://www.rfc-editor.org/rfc/rfc9180) / [draft-ietf-hpke-hpke](https://datatracker.ietf.org/doc/draft-ietf-hpke-hpke/)) with JWE, in both Key Management Modes —
13-
Integrated Encryption (`HPKE-0`, `HPKE-1`, `HPKE-2`) and Key Encryption (`HPKE-0-KE`, `HPKE-1-KE`, `HPKE-2-KE`)
13+
Integrated Encryption (`HPKE-0`, `HPKE-1`, `HPKE-2`) and Key Encryption (`HPKE-0-KE`, `HPKE-1-KE`, `HPKE-2-KE`); HPKE `mode_base` only, `mode_psk` (`psk_id`) is not supported yet
1414
- [draft-ietf-jose-hpke-pq-pqt](https://datatracker.ietf.org/doc/draft-ietf-jose-hpke-pq-pqt/): PQ/T hybrid HPKE — `HPKE-9` and `HPKE-9-KE`, based on the MLKEM768-X25519 KEM and SHAKE256 KDF from [draft-ietf-hpke-pq](https://datatracker.ietf.org/doc/draft-ietf-hpke-pq/); the KEM is identical to X-Wing ([draft-connolly-cfrg-xwing-kem](https://datatracker.ietf.org/doc/draft-connolly-cfrg-xwing-kem/))
1515
- [RFC 9964 (AKP JWKs)](https://www.rfc-editor.org/rfc/rfc9964): parsing Algorithm Key Pair JWKs for the PQ/T hybrid algorithms
1616

‎src/main/java/org/cryptomator/jose/Alg.java‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
/// A JWE algorithm, identified by its `alg` header value. It is split by direction into [EncryptionAlg] and [DecryptionAlg], and by JWE Key Management Mode
2222
/// into key management (protecting a content encryption key, [RFC 7518 Section 4](https://www.rfc-editor.org/rfc/rfc7518#section-4)) and Integrated Encryption
2323
/// ([draft-ietf-jose-hpke-encrypt Section 5](https://datatracker.ietf.org/doc/html/draft-ietf-jose-hpke-encrypt/#section-5), where HPKE encrypts the payload directly and there is no CEK).
24+
///
25+
/// All HPKE algorithms (`hpke0`…`hpke9`, `hpke0Ke`…`hpke9Ke`) run in HPKE `mode_base` only; `mode_psk` and the `psk_id` header parameter are not supported.
2426
public sealed interface Alg permits DecryptionAlg, EncryptionAlg {
2527

2628
/// The `alg` (algorithm) header parameter value identifying this algorithm.

‎src/main/java/org/cryptomator/jose/IntegratedDecryptionAlg.java‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import org.cryptomator.jose.alg.HPKEIntegratedAlg;
44

55
/// Decryption for the Integrated Encryption Key Management Mode: HPKE decrypts the payload directly, without a separate content encryption key.
6+
/// Only HPKE `mode_base` is supported; a token with a `psk_id` header parameter (`mode_psk`) cannot be decrypted.
67
public sealed interface IntegratedDecryptionAlg extends DecryptionAlg permits HPKEIntegratedAlg {
78

89
}

‎src/main/java/org/cryptomator/jose/IntegratedEncryptionAlg.java‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
/// HPKE Integrated Encryption as defined in [draft-ietf-jose-hpke-encrypt, Section 5](https://datatracker.ietf.org/doc/html/draft-ietf-jose-hpke-encrypt/#section-5):
66
/// HPKE encrypts the payload directly — there is no CEK, no `enc` or `ek` header parameter, the JWE IV and Authentication Tag are empty, and there is exactly one recipient.
7+
/// Only HPKE `mode_base` is supported; `mode_psk` (`psk_id` header parameter) is not.
78
public sealed interface IntegratedEncryptionAlg extends EncryptionAlg permits HPKEIntegratedAlg {
89

910
/// Encrypts the payload in a single HPKE operation.

‎src/main/java/org/cryptomator/jose/alg/HPKEIntegratedAlg.java‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@
1414
/// HPKE Integrated Encryption as defined in [draft-ietf-jose-hpke-encrypt, Section 5](https://datatracker.ietf.org/doc/html/draft-ietf-jose-hpke-encrypt/#section-5):
1515
/// HPKE encrypts the payload directly, the encapsulated secret travels in the JWE Encrypted Key field, and the JWE Protected Header
1616
/// (as well as an optional JWE AAD) is bound to the ciphertext via the HPKE `aad` parameter.
17+
///
18+
/// Only HPKE `mode_base` is supported. The draft also allows `mode_psk`, signalled by the `psk_id` header parameter; a token carrying `psk_id` is not understood
19+
/// (it is rejected when listed in `crit`, and otherwise fails to decrypt because the PSK never enters the key schedule).
1720
public final class HPKEIntegratedAlg implements IntegratedEncryptionAlg, IntegratedDecryptionAlg {
1821

1922
private static final byte[] EMPTY = new byte[0];

‎src/main/java/org/cryptomator/jose/alg/HPKEKeyEncryptionAlg.java‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@
1616

1717
/// HPKE Key Encryption as defined in [draft-ietf-jose-hpke-encrypt, Section 6](https://datatracker.ietf.org/doc/html/draft-ietf-jose-hpke-encrypt/#section-6):
1818
/// HPKE seals the CEK, the encapsulated secret travels in the `ek` header parameter, and the content is encrypted with a regular [org.cryptomator.jose.Enc].
19+
///
20+
/// Only HPKE `mode_base` is supported. The draft also allows `mode_psk`, signalled by the `psk_id` header parameter; a token carrying `psk_id` is not understood
21+
/// (it is rejected when listed in `crit`, and otherwise fails to decrypt because the PSK never enters the key schedule).
1922
public final class HPKEKeyEncryptionAlg extends AbstractKeyAlg {
2023

2124
private static final byte[] SEPARATOR = {(byte) 0xFF};

‎src/main/java/org/cryptomator/jose/hpke/HPKE.java‎

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@
1515
import java.security.PublicKey;
1616

1717
/// An HPKE ciphersuite (KEM, KDF, AEAD) as defined in [draft-ietf-hpke-hpke](https://datatracker.ietf.org/doc/html/draft-ietf-hpke-hpke-03), offering the base mode
18-
/// sender and recipient setup. The static factory methods provide the suites registered for JOSE in
18+
/// sender and recipient setup. Only `mode_base` is implemented: `mode_psk` (a pre-shared key authenticating the sender, draft-ietf-hpke-hpke Section 5.1.2) as
19+
/// well as `mode_auth` and `mode_auth_psk` are not supported, although the key schedule already accepts the PSK inputs. The static factory methods provide the suites registered for JOSE in
1920
/// [draft-ietf-jose-hpke-encrypt](https://datatracker.ietf.org/doc/html/draft-ietf-jose-hpke-encrypt/) and
2021
/// [draft-ietf-jose-hpke-pq-pqt](https://datatracker.ietf.org/doc/html/draft-ietf-jose-hpke-pq-pqt/); `baseName` is the JOSE `alg` name of the suite's
2122
/// Integrated Encryption variant (the Key Encryption variant appends `-KE`).
@@ -132,8 +133,9 @@ public record Sender(byte[] enc, Context context) {
132133
/// @param mode A one-byte value indicating the HPKE mode, defined in Table 1.
133134
/// @param sharedSecret A KEM shared secret generated for this transaction.
134135
/// @param info Application-supplied information (optional).
135-
/// @param psk A pre-shared key (PSK) held by both the sender and the recipient (optional).
136-
/// @param pskId An identifier for the PSK (optional).
136+
/// @param psk A pre-shared key (PSK) held by both the sender and the recipient; must be empty, as only `mode_base` is supported
137+
/// @param pskId An identifier for the PSK; must be empty, as only `mode_base` is supported
138+
/// @throws UnsupportedOperationException for any mode other than `mode_base`
137139
// visible for testing
138140
Context keySchedule(byte mode, SecretKey sharedSecret, byte[] info, byte[] psk, byte[] pskId) {
139141
if ((psk.length == 0) != (pskId.length == 0)) {
@@ -143,7 +145,7 @@ Context keySchedule(byte mode, SecretKey sharedSecret, byte[] info, byte[] psk,
143145
throw new IllegalArgumentException("PSK input provided when not needed");
144146
}
145147
if (mode != 0x00) {
146-
throw new UnsupportedOperationException("Only mode_base is currently supported");
148+
throw new UnsupportedOperationException("Only mode_base is supported (no mode_psk, mode_auth or mode_auth_psk)");
147149
}
148150

149151
var derived = kdf.combineSecrets(mode, sharedSecret, info, psk, pskId, suiteId, "AES", aead.nk, aead.nn);

0 commit comments

Comments
 (0)