• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2024 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.crypto.hpke;
18 
19 import java.security.GeneralSecurityException;
20 import java.security.InvalidKeyException;
21 import java.security.PrivateKey;
22 import java.security.PublicKey;
23 import libcore.util.NonNull;
24 import libcore.util.Nullable;
25 
26 
27 /**
28  * Service Provider Interface for HPKE client API classes to communicate with implementations
29  * of HPKE as described in RFC 9180.
30  * <p>
31  * There are no standard Java Cryptography Architecture names or interface classes for HPKE,
32  * but instances of this class can be obtained by calling
33  * {@code Provider.getService("ConscryptHpke", String SuiteName)} where {@code suiteName}
34  * is the name of the HPKE suite, e.g.
35  * {@code "DHKEM_X25519_HKDF_SHA256/HKDF_SHA256/AES_128_GCM"}.
36  */
37 public interface HpkeSpi {
38     /**
39      * Initialises an HPKE SPI in one of the sender modes described in RFC 9180.
40      * <p>
41      * If {@code senderKey} is supplied then Asymmetric Key Authentication will be used,
42      * (MODE_AUTH)
43      * <p>
44      * If {@code psk} and {@code psk_id} are supplied then Pre-Shared Key Authentication
45      * will be used (MODE_PSK).
46      * <p>
47      * If all of {@code senderKey}, {@code psk} and {@code psk_id} are supplied then both
48      * Key and PSK authentication will be used (MODE_PSK_AUTH).
49      * <p>
50      * If neither is supplied then no sender authentication will be used (MODE_BASE).
51      * <p>
52      * Note that only base mode is currently supported on Android.
53      * <p>
54      * Public and private keys must be supplied in a format that can be used by the
55      * implementation.  An instance of the {@code "XDH"} {@link java.security.KeyFactory} can
56      * be used to translate {@code KeySpecs} or keys from another {@link java.security.Provider}
57      *
58      * @param recipientKey public key of the recipient
59      * @param info application-supplied information, may be null or empty
60      * @param senderKey private key of the sender, for symmetric auth modes only, else null
61      * @param psk pre-shared key, for PSK auth modes only, else null
62      * @param psk_id pre-shared key ID, for PSK auth modes only, else null
63      * @throws InvalidKeyException if recipientKey is null or an unsupported key format
64      * @throws UnsupportedOperationException if the mode is not supported by this implementation
65      * @throws IllegalStateException if this SPI has already been initialised
66      */
engineInitSender( @onNull PublicKey recipientKey, @Nullable byte[] info, @Nullable PrivateKey senderKey, @Nullable byte[] psk, @Nullable byte[] psk_id)67     void engineInitSender(
68             @NonNull PublicKey recipientKey,
69             @Nullable byte[] info,
70             @Nullable PrivateKey senderKey,
71             @Nullable byte[] psk,
72             @Nullable byte[] psk_id)
73             throws InvalidKeyException;
74 
75     /**
76      * Initialises an HPKE SPI in one of the sender modes described in RFC 9180 with
77      * a predefined random seed to allow testing against known test vectors.
78      * <p>
79      * This mode provides absolutely no security and should only be used for testing
80      * purposes.
81      * <p>
82      * If {@code senderKey} is supplied then Asymmetric Key Authentication will be used,
83      * (MODE_AUTH)
84      * <p>
85      * If {@code psk} and {@code psk_id} are supplied then Pre-Shared Key Authentication
86      * will be used (MODE_PSK).
87      * <p>
88      * If all of {@code senderKey}, {@code psk} and {@code psk_id} are supplied then both
89      * Key and PSK authentication will be used (MODE_AUTH_PSK).
90      * <p>
91      * If neither is supplied then no sender authentication will be used (MODE_BASE).
92      * <p>
93      * Note that only base mode is currently supported on Android.
94      * <p>
95      * Public and private keys must be supplied in a format that can be used by the
96      * implementation.  An instance of the {@code "XDH"} {@link java.security.KeyFactory} can
97      * be used to translate {@code KeySpecs} or keys from another {@link java.security.Provider}
98      *
99      *
100      * @param recipientKey public key of the recipient
101      * @param info application-supplied information, may be null or empty
102      * @param senderKey private key of the sender, for symmetric auth modes only, else null
103      * @param psk pre-shared key, for PSK auth modes only, else null
104      * @param psk_id pre-shared key ID, for PSK auth modes only, else null
105      * @param sKe Predetermined random seed, should only be used for validation against
106      *            known test vectors
107      * @throws InvalidKeyException if recipientKey is null or an unsupported key format or senderKey
108      *            is an unsupported key format
109      * @throws UnsupportedOperationException if the mode is not supported by this implementation
110      * @throws IllegalStateException if this SPI has already been initialised
111      */
engineInitSenderWithSeed( @onNull PublicKey recipientKey, @Nullable byte[] info, @Nullable PrivateKey senderKey, @Nullable byte[] psk, @Nullable byte[] psk_id, @NonNull byte[] sKe)112     void engineInitSenderWithSeed(
113             @NonNull PublicKey recipientKey,
114             @Nullable byte[] info,
115             @Nullable PrivateKey senderKey,
116             @Nullable byte[] psk,
117             @Nullable byte[] psk_id,
118             @NonNull byte[] sKe)
119             throws InvalidKeyException;
120 
121     /**
122      * Initialises an HPKE SPI in one of the recipient modes described in RFC 9180.
123      * <p>
124      * If {@code senderKey} is supplied then Asymmetric Key Authentication will be used,
125      * (MODE_AUTH)
126      * <p>
127      * If {@code psk} and {@code psk_id} are supplied then Pre-Shared Key Authentication
128      * will be used (MODE_PSK).
129      * <p>
130      * If all of {@code senderKey}, {@code psk} and {@code psk_id} are supplied then both
131      * Key and PSK authentication will be used (MODE_AUTH_PSK).
132      * <p>
133      * If neither is supplied then no sender authentication will be used (MODE_BASE).
134      * <p>
135      * Note that only base mode is currently supported on Android.
136      * <p>
137      * Public and private keys must be supplied in a format that can be used by the
138      * implementation.  An instance of the {@code "XDH"} {@link java.security.KeyFactory} can
139      * be used to translate {@code KeySpecs} or keys from another {@link java.security.Provider}
140      *
141      * @param encapsulated encapsulated ephemeral key from a sender
142      * @param recipientKey private key of the recipient
143      * @param info application-supplied information, may be null or empty
144      * @param senderKey public key of sender, for asymmetric auth modes only, else null
145      * @param psk pre-shared key, for PSK auth modes only, else null
146      * @param psk_id pre-shared key ID, for PSK auth modes only, else null
147      * @throws InvalidKeyException if recipientKey is null or an unsupported key format or senderKey
148      *         is an unsupported key format
149      * @throws UnsupportedOperationException if the mode is not supported by this implementation
150      * @throws IllegalStateException if this SPI has already been initialised
151      */
engineInitRecipient( @onNull byte[] encapsulated, @NonNull PrivateKey recipientKey, @Nullable byte[] info, @Nullable PublicKey senderKey, @Nullable byte[] psk, @Nullable byte[] psk_id)152     void engineInitRecipient(
153             @NonNull byte[] encapsulated,
154             @NonNull PrivateKey recipientKey,
155             @Nullable byte[] info,
156             @Nullable PublicKey senderKey,
157             @Nullable byte[] psk,
158             @Nullable byte[] psk_id)
159             throws InvalidKeyException;
160 
161     /**
162      * Seals a message, using the internal key schedule maintained by an HPKE sender SPI.
163      *
164      * @param plaintext the plaintext
165      * @param aad optional associated data, may be null or empty
166      * @return the ciphertext
167      * @throws NullPointerException if the plaintext is null
168      * @throws IllegalStateException if this SPI has not been initialised or if it was initialised
169      *         as a recipient
170      */
engineSeal(@onNull byte[] plaintext, @Nullable byte[] aad)171     @NonNull byte[] engineSeal(@NonNull byte[] plaintext, @Nullable byte[] aad);
172 
173     /**
174      * Opens a message, using the internal key schedule maintained by an HPKE recipient SPI.
175      *
176      * @param ciphertext the ciphertext
177      * @param aad optional associated data, may be null or empty
178      * @return the plaintext
179      * @throws IllegalStateException if this SPI has not been initialised or if it was initialised
180      *         as a sender
181      * @throws GeneralSecurityException on decryption failures
182      */
engineOpen(@onNull byte[] ciphertext, @Nullable byte[] aad)183     @NonNull byte[] engineOpen(@NonNull byte[] ciphertext, @Nullable byte[] aad)
184             throws GeneralSecurityException;
185 
186     /**
187      * Exports secret key material from this SPI as described in RFC 9180.
188      *
189      * @param length  expected output length
190      * @param context optional context string, may be null or empty
191      * @return exported value
192      * @throws IllegalArgumentException if the length is not valid for the KDF in use
193      * @throws IllegalStateException if this SPI has not been initialised
194      *
195      */
engineExport(int length, @Nullable byte[] context)196     @NonNull byte[] engineExport(int length, @Nullable byte[] context);
197 
198     /**
199      * Returns the encapsulated key material for an HPKE sender.
200      *
201      * @return the key material
202      * @throws IllegalStateException if this SPI has not been initialised or if it was initialised
203      *         as a recipient
204      */
getEncapsulated()205     @NonNull byte[] getEncapsulated();
206 }
207