1 /* srp.h 2 * 3 * Copyright (C) 2006-2021 wolfSSL Inc. 4 * 5 * This file is part of wolfSSL. 6 * 7 * wolfSSL is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 2 of the License, or 10 * (at your option) any later version. 11 * 12 * wolfSSL is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA 20 */ 21 22 /*! 23 \file wolfssl/wolfcrypt/srp.h 24 */ 25 26 #ifdef WOLFCRYPT_HAVE_SRP 27 28 #ifndef WOLFCRYPT_SRP_H 29 #define WOLFCRYPT_SRP_H 30 31 #include <wolfssl/wolfcrypt/types.h> 32 #include <wolfssl/wolfcrypt/sha.h> 33 #include <wolfssl/wolfcrypt/sha256.h> 34 #include <wolfssl/wolfcrypt/sha512.h> 35 #include <wolfssl/wolfcrypt/integer.h> 36 37 #ifdef __cplusplus 38 extern "C" { 39 #endif 40 41 /* Select the largest available hash for the buffer size. */ 42 #if defined(WOLFSSL_SHA512) 43 #define SRP_MAX_DIGEST_SIZE WC_SHA512_DIGEST_SIZE 44 #elif defined(WOLFSSL_SHA384) 45 #define SRP_MAX_DIGEST_SIZE WC_SHA384_DIGEST_SIZE 46 #elif !defined(NO_SHA256) 47 #define SRP_MAX_DIGEST_SIZE WC_SHA256_DIGEST_SIZE 48 #elif !defined(NO_SHA) 49 #define SRP_MAX_DIGEST_SIZE WC_SHA_DIGEST_SIZE 50 #else 51 #error "You have to have some kind of SHA hash if you want to use SRP." 52 #endif 53 54 /* Set the minimum number of bits acceptable in an SRP modulus */ 55 #define SRP_MODULUS_MIN_BITS 512 56 57 /* Set the minimum number of bits acceptable for private keys (RFC 5054) */ 58 #define SRP_PRIVATE_KEY_MIN_BITS 256 59 60 /* salt size for SRP password */ 61 #define SRP_SALT_SIZE 16 62 63 /** 64 * SRP side, client or server. 65 */ 66 typedef enum { 67 SRP_CLIENT_SIDE = 0, 68 SRP_SERVER_SIDE = 1, 69 } SrpSide; 70 71 /** 72 * SRP hash type, SHA[1|256|384|512]. 73 */ 74 typedef enum { 75 SRP_TYPE_SHA = 1, 76 SRP_TYPE_SHA256 = 2, 77 SRP_TYPE_SHA384 = 3, 78 SRP_TYPE_SHA512 = 4, 79 } SrpType; 80 81 82 /** 83 * SRP hash struct. 84 */ 85 typedef struct { 86 byte type; 87 union { 88 #ifndef NO_SHA 89 wc_Sha sha; 90 #endif 91 #ifndef NO_SHA256 92 wc_Sha256 sha256; 93 #endif 94 #ifdef WOLFSSL_SHA384 95 wc_Sha384 sha384; 96 #endif 97 #ifdef WOLFSSL_SHA512 98 wc_Sha512 sha512; 99 #endif 100 } data; 101 } SrpHash; 102 103 typedef struct Srp { 104 SrpSide side; /**< Client or Server, @see SrpSide. */ 105 SrpType type; /**< Hash type, @see SrpType. */ 106 byte* user; /**< Username, login. */ 107 word32 userSz; /**< Username length. */ 108 byte* salt; /**< Small salt. */ 109 word32 saltSz; /**< Salt length. */ 110 mp_int N; /**< Modulus. N = 2q+1, [q, N] are primes.*/ 111 mp_int g; /**< Generator. A generator modulo N. */ 112 byte k[SRP_MAX_DIGEST_SIZE]; /**< Multiplier parameter. k = H(N, g) */ 113 mp_int auth; /**< Client: x = H(salt + H(user:pswd)) */ 114 /**< Server: v = g ^ x % N */ 115 mp_int priv; /**< Private ephemeral value. */ 116 SrpHash client_proof; /**< Client proof. Sent to the Server. */ 117 SrpHash server_proof; /**< Server proof. Sent to the Client. */ 118 byte* key; /**< Session key. */ 119 word32 keySz; /**< Session key length. */ 120 int (*keyGenFunc_cb) (struct Srp* srp, byte* secret, word32 size); 121 /**< Function responsible for generating the session key. */ 122 /**< It MUST use XMALLOC with type DYNAMIC_TYPE_SRP to allocate the */ 123 /**< key buffer for this structure and set keySz to the buffer size. */ 124 /**< The default function used by this implementation is a modified */ 125 /**< version of t_mgf1 that uses the proper hash function according */ 126 /**< to srp->type. */ 127 void* heap; /**< heap hint pointer */ 128 } Srp; 129 130 /** 131 * Initializes the Srp struct for usage. 132 * 133 * @param[out] srp the Srp structure to be initialized. 134 * @param[in] type the hash type to be used. 135 * @param[in] side the side of the communication. 136 * 137 * @return 0 on success, {@literal <} 0 on error. @see error-crypt.h 138 */ 139 WOLFSSL_API int wc_SrpInit(Srp* srp, SrpType type, SrpSide side); 140 WOLFSSL_API int wc_SrpInit_ex(Srp* srp, SrpType type, SrpSide side, 141 void* heap, int devId); 142 143 /** 144 * Releases the Srp struct resources after usage. 145 * 146 * @param[in,out] srp the Srp structure to be terminated. 147 */ 148 WOLFSSL_API void wc_SrpTerm(Srp* srp); 149 150 /** 151 * Sets the username. 152 * 153 * This function MUST be called after wc_SrpInit. 154 * 155 * @param[in,out] srp the Srp structure. 156 * @param[in] username the buffer containing the username. 157 * @param[in] size the username size in bytes 158 * 159 * @return 0 on success, {@literal <} 0 on error. @see error-crypt.h 160 */ 161 WOLFSSL_API int wc_SrpSetUsername(Srp* srp, const byte* username, word32 size); 162 163 164 /** 165 * Sets the srp parameters based on the username. 166 * 167 * This function MUST be called after wc_SrpSetUsername. 168 * 169 * @param[in,out] srp the Srp structure. 170 * @param[in] N the Modulus. N = 2q+1, [q, N] are primes. 171 * @param[in] nSz the N size in bytes. 172 * @param[in] g the Generator modulo N. 173 * @param[in] gSz the g size in bytes 174 * @param[in] salt a small random salt. Specific for each username. 175 * @param[in] saltSz the salt size in bytes 176 * 177 * @return 0 on success, {@literal <} 0 on error. @see error-crypt.h 178 */ 179 WOLFSSL_API int wc_SrpSetParams(Srp* srp, const byte* N, word32 nSz, 180 const byte* g, word32 gSz, 181 const byte* salt, word32 saltSz); 182 183 /** 184 * Sets the password. 185 * 186 * Setting the password does not persists the clear password data in the 187 * srp structure. The client calculates x = H(salt + H(user:pswd)) and stores 188 * it in the auth field. 189 * 190 * This function MUST be called after wc_SrpSetParams and is CLIENT SIDE ONLY. 191 * 192 * @param[in,out] srp the Srp structure. 193 * @param[in] password the buffer containing the password. 194 * @param[in] size the password size in bytes. 195 * 196 * @return 0 on success, {@literal <} 0 on error. @see error-crypt.h 197 */ 198 WOLFSSL_API int wc_SrpSetPassword(Srp* srp, const byte* password, word32 size); 199 200 /** 201 * Sets the verifier. 202 * 203 * This function MUST be called after wc_SrpSetParams and is SERVER SIDE ONLY. 204 * 205 * @param[in,out] srp the Srp structure. 206 * @param[in] verifier the buffer containing the verifier. 207 * @param[in] size the verifier size in bytes. 208 * 209 * @return 0 on success, {@literal <} 0 on error. @see error-crypt.h 210 */ 211 WOLFSSL_API int wc_SrpSetVerifier(Srp* srp, const byte* verifier, word32 size); 212 213 /** 214 * Gets the verifier. 215 * 216 * The client calculates the verifier with v = g ^ x % N. 217 * This function MAY be called after wc_SrpSetPassword and is CLIENT SIDE ONLY. 218 * 219 * @param[in,out] srp the Srp structure. 220 * @param[out] verifier the buffer to write the verifier. 221 * @param[in,out] size the buffer size in bytes. Will be updated with the 222 * verifier size. 223 * 224 * @return 0 on success, {@literal <} 0 on error. @see error-crypt.h 225 */ 226 WOLFSSL_API int wc_SrpGetVerifier(Srp* srp, byte* verifier, word32* size); 227 228 /** 229 * Sets the private ephemeral value. 230 * 231 * The private ephemeral value is known as: 232 * a at the client side. a = random() 233 * b at the server side. b = random() 234 * This function is handy for unit test cases or if the developer wants to use 235 * an external random source to set the ephemeral value. 236 * This function MAY be called before wc_SrpGetPublic. 237 * 238 * @param[in,out] srp the Srp structure. 239 * @param[in] priv the ephemeral value. 240 * @param[in] size the private size in bytes. 241 * 242 * @return 0 on success, {@literal <} 0 on error. @see error-crypt.h 243 */ 244 WOLFSSL_API int wc_SrpSetPrivate(Srp* srp, const byte* priv, word32 size); 245 246 /** 247 * Gets the public ephemeral value. 248 * 249 * The public ephemeral value is known as: 250 * A at the client side. A = g ^ a % N 251 * B at the server side. B = (k * v + (g ^ b % N)) % N 252 * This function MUST be called after wc_SrpSetPassword or wc_SrpSetVerifier. 253 * 254 * @param[in,out] srp the Srp structure. 255 * @param[out] pub the buffer to write the public ephemeral value. 256 * @param[in,out] size the the buffer size in bytes. Will be updated with 257 * the ephemeral value size. 258 * 259 * @return 0 on success, {@literal <} 0 on error. @see error-crypt.h 260 */ 261 WOLFSSL_API int wc_SrpGetPublic(Srp* srp, byte* pub, word32* size); 262 263 264 /** 265 * Computes the session key. 266 * 267 * The key can be accessed at srp->key after success. 268 * 269 * @param[in,out] srp the Srp structure. 270 * @param[in] clientPubKey the client's public ephemeral value. 271 * @param[in] clientPubKeySz the client's public ephemeral value size. 272 * @param[in] serverPubKey the server's public ephemeral value. 273 * @param[in] serverPubKeySz the server's public ephemeral value size. 274 * 275 * @return 0 on success, {@literal <} 0 on error. @see error-crypt.h 276 */ 277 WOLFSSL_API int wc_SrpComputeKey(Srp* srp, 278 byte* clientPubKey, word32 clientPubKeySz, 279 byte* serverPubKey, word32 serverPubKeySz); 280 281 /** 282 * Gets the proof. 283 * 284 * This function MUST be called after wc_SrpComputeKey. 285 * 286 * @param[in,out] srp the Srp structure. 287 * @param[out] proof the buffer to write the proof. 288 * @param[in,out] size the buffer size in bytes. Will be updated with the 289 * proof size. 290 * 291 * @return 0 on success, {@literal <} 0 on error. @see error-crypt.h 292 */ 293 WOLFSSL_API int wc_SrpGetProof(Srp* srp, byte* proof, word32* size); 294 295 /** 296 * Verifies the peers proof. 297 * 298 * This function MUST be called before wc_SrpGetSessionKey. 299 * 300 * @param[in,out] srp the Srp structure. 301 * @param[in] proof the peers proof. 302 * @param[in] size the proof size in bytes. 303 * 304 * @return 0 on success, {@literal <} 0 on error. @see error-crypt.h 305 */ 306 WOLFSSL_API int wc_SrpVerifyPeersProof(Srp* srp, byte* proof, word32 size); 307 308 #ifdef __cplusplus 309 } /* extern "C" */ 310 #endif 311 312 #endif /* WOLFCRYPT_SRP_H */ 313 #endif /* WOLFCRYPT_HAVE_SRP */ 314