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