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 psk} and {@code psk_id} are supplied then Pre-Shared Key Authentication 42 * will be used. 43 * <p> 44 * If {@code senderKey} is supplied then Asymmetric Key Authentication will be used. 45 * <p> 46 * If neither is supplied then "base" mode (no sender authentication) will be used. 47 * <p> 48 * Note that only base mode is currently supported on Android. 49 * <p> 50 * Public and private keys must be supplied in a format that can be used by the 51 * implementation. An instance of the {@code "XDH"} {@link java.security.KeyFactory} can 52 * be used to translate {@code KeySpecs} or keys from another {@link java.security.Provider} 53 * 54 * @param recipientKey public key of the recipient 55 * @param info application-supplied information, may be null or empty 56 * @param senderKey private key of the sender, for symmetric auth modes only, else null 57 * @param psk pre-shared key, for PSK auth modes only, else null 58 * @param psk_id pre-shared key ID, for PSK auth modes only, else null 59 * @throws InvalidKeyException if recipientKey is null or an unsupported key format 60 * @throws UnsupportedOperationException if mode is not a supported HPKE mode 61 * @throws IllegalStateException if this SPI has already been initialised 62 */ engineInitSender( @onNull PublicKey recipientKey, @Nullable byte[] info, @Nullable PrivateKey senderKey, @Nullable byte[] psk, @Nullable byte[] psk_id)63 void engineInitSender( 64 @NonNull PublicKey recipientKey, 65 @Nullable byte[] info, 66 @Nullable PrivateKey senderKey, 67 @Nullable byte[] psk, 68 @Nullable byte[] psk_id) 69 throws InvalidKeyException; 70 71 /** 72 * Initialises an HPKE SPI in one of the sender modes described in RFC 9180 with 73 * a predefined random seed to allow testing against known test vectors. 74 * <p> 75 * This mode provides absolutely no security and should only be used for testing 76 * purposes. 77 * <p> 78 * If {@code psk} and {@code psk_id} are supplied then Pre-Shared Key Authentication 79 * will be used. 80 * <p> 81 * If {@code senderKey} is supplied then Asymmetric Key Authentication will be used. 82 * <p> 83 * If neither is supplied then "base" mode (no sender authentication) will be used. 84 * <p> 85 * Note that only base mode is currently supported on Android. 86 * <p> 87 * Public and private keys must be supplied in a format that can be used by the 88 * implementation. An instance of the {@code "XDH"} {@link java.security.KeyFactory} can 89 * be used to translate {@code KeySpecs} or keys from another {@link java.security.Provider} 90 * 91 * 92 * @param recipientKey public key of the recipient 93 * @param info application-supplied information, may be null or empty 94 * @param senderKey private key of the sender, for symmetric auth modes only, else null 95 * @param psk pre-shared key, for PSK auth modes only, else null 96 * @param psk_id pre-shared key ID, for PSK auth modes only, else null 97 * @param sKe Predetermined random seed, should only be usesd for validation against 98 * known test vectors 99 * @throws InvalidKeyException if recipientKey is null or an unsupported key format or senderKey 100 * is an unsupported key format 101 * @throws UnsupportedOperationException if mode is not a supported HPKE mode 102 * @throws IllegalStateException if this SPI has already been initialised 103 */ engineInitSenderWithSeed( @onNull PublicKey recipientKey, @Nullable byte[] info, @Nullable PrivateKey senderKey, @Nullable byte[] psk, @Nullable byte[] psk_id, @NonNull byte[] sKe)104 void engineInitSenderWithSeed( 105 @NonNull PublicKey recipientKey, 106 @Nullable byte[] info, 107 @Nullable PrivateKey senderKey, 108 @Nullable byte[] psk, 109 @Nullable byte[] psk_id, 110 @NonNull byte[] sKe) 111 throws InvalidKeyException; 112 113 /** 114 * Initialises an HPKE SPI in one of the sender modes described in RFC 9180. 115 * <p> 116 * If {@code psk} and {@code psk_id} are supplied then Pre-Shared Key Authentication 117 * will be used. 118 * <p> 119 * If {@code senderKey} is supplied then Asymmetric Key Authentication will be used. 120 * <p> 121 * If neither is supplied then "base" mode (no sender authentication) will be used. 122 * <p> 123 * Note that only base mode is currently supported on Android. 124 * <p> 125 * Public and private keys must be supplied in a format that can be used by the 126 * implementation. An instance of the {@code "XDH"} {@link java.security.KeyFactory} can 127 * be used to translate {@code KeySpecs} or keys from another {@link java.security.Provider} 128 * 129 * @param encapsulated encapsulated ephemeral key from a sender 130 * @param recipientKey private key of the recipient 131 * @param info application-supplied information, may be null or empty 132 * @param senderKey public key of sender, for asymmetric auth modes only, else null 133 * @param psk pre-shared key, for PSK auth modes only, else null 134 * @param psk_id pre-shared key ID, for PSK auth modes only, else null 135 * @throws InvalidKeyException if recipientKey is null or an unsupported key format or senderKey 136 * is an unsupported key format 137 * @throws UnsupportedOperationException if mode is not a supported HPKE mode 138 * @throws IllegalStateException if this SPI has already been initialised 139 */ engineInitRecipient( @onNull byte[] encapsulated, @NonNull PrivateKey recipientKey, @Nullable byte[] info, @Nullable PublicKey senderKey, @Nullable byte[] psk, @Nullable byte[] psk_id)140 void engineInitRecipient( 141 @NonNull byte[] encapsulated, 142 @NonNull PrivateKey recipientKey, 143 @Nullable byte[] info, 144 @Nullable PublicKey senderKey, 145 @Nullable byte[] psk, 146 @Nullable byte[] psk_id) 147 throws InvalidKeyException; 148 149 /** 150 * Seals a message, using the internal key schedule maintained by an HPKE sender SPI. 151 * 152 * @param plaintext the plaintext 153 * @param aad optional associated data, may be null or empty 154 * @return the ciphertext 155 * @throws NullPointerException if the plaintext is null 156 * @throws IllegalStateException if this SPI has not been initialised or if it was initialised 157 * as a recipient 158 */ engineSeal(@onNull byte[] plaintext, @Nullable byte[] aad)159 @NonNull byte[] engineSeal(@NonNull byte[] plaintext, @Nullable byte[] aad); 160 161 /** 162 * Opens a message, using the internal key schedule maintained by an HPKE recipient SPI. 163 * 164 * @param ciphertext the ciphertext 165 * @param aad optional associated data, may be null or empty 166 * @return the plaintext 167 * @throws IllegalStateException if this SPI has not been initialised or if it was initialised 168 * as a sender 169 * @throws GeneralSecurityException on decryption failures 170 */ engineOpen(@onNull byte[] ciphertext, @Nullable byte[] aad)171 @NonNull byte[] engineOpen(@NonNull byte[] ciphertext, @Nullable byte[] aad) 172 throws GeneralSecurityException; 173 174 /** 175 * Exports secret key material from this SPI as described in RFC 9180. 176 * 177 * @param length expected output length 178 * @param context optional context string, may be null or empty 179 * @return exported value 180 * @throws IllegalArgumentException if the length is not valid for the KDF in use 181 * @throws IllegalStateException if this SPI has not been initialised 182 * 183 */ engineExport(int length, @Nullable byte[] context)184 @NonNull byte[] engineExport(int length, @Nullable byte[] context); 185 186 /** 187 * Returns the encapsulated key material for an HPKE sender. 188 * 189 * @return the key material 190 * @throws IllegalStateException if this SPI has not been initialised or if it was initialised 191 * as a recipient 192 */ getEncapsulated()193 @NonNull byte[] getEncapsulated(); 194 } 195