1 /* 2 * Copyright (C) 2020 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 #pragma once 18 19 #include <stddef.h> 20 #include <stdint.h> 21 #include <sys/cdefs.h> 22 23 #if !defined(__INTRODUCED_IN) 24 #define __INTRODUCED_IN(__api_level) /* nothing */ 25 #endif 26 27 __BEGIN_DECLS 28 29 /** 30 * PairingAuthCtx is a wrapper around the SPAKE2 protocol + cipher initialization 31 * for encryption. On construction, the |password| will be used to generate a 32 * SPAKE2 message. Each peer will exchange the messages in |pairing_auth_get_msg| 33 * to initialize their ciphers in |pairing_auth_init_cipher|. If both peers used the 34 * same |password|, then both sides will be able to decrypt each other's messages. 35 * 36 * On creation of a PairingAuthCtx, |pairing_auth_init_cipher| prior to using 37 * the encrypt and decrypt APIs. Furthermore, you can only initialize the cipher 38 * once. 39 * 40 * See pairing_auth_test.cpp for example usage. 41 * 42 */ 43 struct PairingAuthCtx; 44 typedef struct PairingAuthCtx PairingAuthCtx; 45 46 /** 47 * Creates a new PairingAuthCtx instance as the server. 48 * 49 * @param pswd the shared secret the server and client use to authenticate each 50 * other. Will abort if null. 51 * @param len the length of the pswd in bytes. Will abort if 0. 52 * @return a new PairingAuthCtx server instance. Caller is responsible for 53 * destroying the context via #pairing_auth_destroy. 54 */ 55 PairingAuthCtx* pairing_auth_server_new(const uint8_t* pswd, size_t len) __INTRODUCED_IN(30); 56 57 /** 58 * Creates a new PairingAuthCtx instance as the client. 59 * 60 * @param pswd the shared secret the server and client use to authenticate each 61 * other. Will abort if null. 62 * @param len the length of the pswd in bytes. Will abort if 0. 63 * @return a new PairingAuthCtx client instance. Caller is responsible for 64 * destroying the context via #pairing_auth_destroy. 65 */ 66 PairingAuthCtx* pairing_auth_client_new(const uint8_t* pswd, size_t len) __INTRODUCED_IN(30); 67 68 /** 69 * Destroys the PairingAuthCtx. 70 * 71 * @param ctx the PairingAuthCtx instance to destroy. Will abort if null. 72 */ 73 void pairing_auth_destroy(PairingAuthCtx* ctx) __INTRODUCED_IN(30); 74 75 /** 76 * Returns the exact size of the SPAKE2 msg. 77 * 78 * Use this size as the buffer size when retrieving the message via 79 * #pairing_auth_get_msg. 80 * 81 * @param ctx the PairingAuthCtx instance. Will abort if null. 82 * @return the size of the SPAKE2 message in bytes. This is guaranteed to be > 0. 83 */ 84 size_t pairing_auth_msg_size(PairingAuthCtx* ctx) __INTRODUCED_IN(30); 85 86 /** 87 * Writes the SPAKE2 message to exchange with the other party to |out_buf|. 88 * 89 * This is guaranteed to write a valid message to |out_buf|. Use #pairing_auth_msg_size 90 * to get the size the |out_buf| should be. The SPAKE2 messages will be used to 91 * initialize the cipher for encryption/decryption (see #pairing_auth_init_cipher). 92 * 93 * @param ctx the PairingAuthCtx instance. Will abort if null. 94 * @param out_buf the buffer the message is written to. The buffer is assumed to 95 * be have at least #pairing_auth_msg_size size. Will abort if 96 * out_buf is null. 97 */ 98 void pairing_auth_get_spake2_msg(PairingAuthCtx* ctx, uint8_t* out_buf) __INTRODUCED_IN(30); 99 100 /** 101 * Processes the peer's |their_msg| and attempts to initialize the cipher for 102 * encryption. 103 * 104 * You can only call this method ONCE with a non-empty |msg|, regardless of success 105 * or failure. On success, you can use the #pairing_auth_decrypt and #pairing_auth_encrypt 106 * methods to exchange any further information securely. On failure, this 107 * PairingAuthCtx instance has no more purpose and should be destroyed. 108 * 109 * @param ctx the PairingAuthCtx instance. Will abort if null. 110 * @param their_msg the peer's SPAKE2 msg. See #pairing_auth_get_msg. Will abort 111 * if null. 112 * @param msg_len the length of their_msg in bytes. Will abort if 0. 113 * @return true iff the client and server used the same password when creating 114 * the PairingAuthCtx. See 115 * https: *commondatastorage.googleapis.com/chromium-boringssl-docs/curve25519.h.html#SPAKE2 116 * for more details on the SPAKE2 protocol. 117 */ 118 bool pairing_auth_init_cipher(PairingAuthCtx* ctx, const uint8_t* their_msg, size_t msg_len) 119 __INTRODUCED_IN(30); 120 121 /** 122 * Returns a safe buffer size for encrypting data of a certain size. 123 * 124 * IMPORTANT: This will abort if either #pairing_auth_init_cipher was not called 125 * or #pairing_auth_init_cipher failed. 126 * 127 * @param ctx the PairingAuthCtx instance. Will abort if null. 128 * @param len the size of the message wanting to encrypt in bytes. 129 * @return the minimum buffer size, in bytes, to hold an encrypted message of size len. See 130 * #pairing_auth_encrypt for usage. 131 */ 132 size_t pairing_auth_safe_encrypted_size(PairingAuthCtx* ctx, size_t len) __INTRODUCED_IN(30); 133 134 /** 135 * Encrypts input data and writes the encrypted data into a user-provided buffer. 136 * 137 * IMPORTANT: This will abort if either #pairing_auth_init_cipher was not called 138 * or #pairing_auth_init_cipher failed. 139 * 140 * @param ctx the PairingAuthCtx instance. Will abort if null. 141 * @param inbuf the buffer containing the data to encrypt. Will abort if null. 142 * @param inlen the size of inbuf in bytes. Will abort if 0. 143 * @param outbuf the buffer to write the encrypted data to. Will abort if null 144 * @param outlen the size of outbuf in bytes. See #pairing_auth_safe_encrypted_size. 145 * @return true if all the data was encrypted and written to outbuf, false 146 * otherwise. 147 */ 148 bool pairing_auth_encrypt(PairingAuthCtx* ctx, const uint8_t* inbuf, size_t inlen, uint8_t* outbuf, 149 size_t* outlen) __INTRODUCED_IN(30); 150 151 /** 152 * Returns a safe buffer size for decrypting data of a certain size. 153 * 154 * IMPORTANT: This will abort if either #pairing_auth_init_cipher was not called 155 * or #pairing_auth_init_cipher failed. 156 * 157 * @param ctx the PairingAuthCtx instance. Will abort if null. 158 * @param buf the buffer containing the encrypted data. Will abort if null. 159 * @param len the size of the buf in bytes. Will abort if 0. 160 * @return the minimum buffer size, in bytes, to hold a decrypted message of size len. See 161 * #pairing_auth_decrypt for usage. 162 */ 163 size_t pairing_auth_safe_decrypted_size(PairingAuthCtx* ctx, const uint8_t* buf, size_t len) 164 __INTRODUCED_IN(30); 165 166 /** 167 * Decrypts input data and writes the decrypted data into a user-provided buffer. 168 * 169 * IMPORTANT: This will abort if either #pairing_auth_init_cipher was not called 170 * or #pairing_auth_init_cipher failed. 171 * 172 * @param ctx the PairingAuthCtx instance. Will abort if null. 173 * @param inbuf the buffer containing the data to decrypt. Will abort if null. 174 * @param inlen the size of inbuf in bytes. WIll abort if 0. 175 * @param outbuf the buffer to write the decrypted data to. Will abort if null. 176 * @param outlen the size of outbuf in bytes. See #pairing_auth_safe_decrypted_size. 177 * Will abort if 0. 178 * @return true if all the data was decrypted and written to outbuf, false 179 * otherwise. 180 */ 181 bool pairing_auth_decrypt(PairingAuthCtx* ctx, const uint8_t* inbuf, size_t inlen, uint8_t* outbuf, 182 size_t* outlen) __INTRODUCED_IN(30); 183 184 __END_DECLS 185