1 /*!
2     \ingroup SRP
3 
4     \brief Initializes the Srp struct for usage.
5 
6     \return 0 on success.
7     \return BAD_FUNC_ARG Returns when there's an issue with the arguments such
8     as srp being null or SrpSide not being SRP_CLIENT_SIDE or SRP_SERVER_SIDE.
9     \return NOT_COMPILED_IN Returns when a type is passed as an argument but
10     hasn't been configured in the wolfCrypt build.
11     \return <0 on error.
12 
13     \param srp the Srp structure to be initialized.
14     \param type the hash type to be used.
15     \param side the side of the communication.
16 
17     _Example_
18     \code
19     Srp srp;
20     if (wc_SrpInit(&srp, SRP_TYPE_SHA, SRP_CLIENT_SIDE) != 0)
21     {
22         // Initialization error
23     }
24     else
25     {
26         wc_SrpTerm(&srp);
27     }
28     \endcode
29 
30     \sa wc_SrpTerm
31     \sa wc_SrpSetUsername
32 */
33 WOLFSSL_API int wc_SrpInit(Srp* srp, SrpType type, SrpSide side);
34 
35 /*!
36     \ingroup SRP
37 
38     \brief Releases the Srp struct resources after usage.
39 
40     \return none No returns.
41 
42     \param srp Pointer to the Srp structure to be terminated.
43 
44     _Example_
45     \code
46     Srp srp;
47     wc_SrpInit(&srp, SRP_TYPE_SHA, SRP_CLIENT_SIDE);
48     // Use srp
49     wc_SrpTerm(&srp)
50     \endcode
51 
52     \sa wc_SrpInit
53 */
54 WOLFSSL_API void wc_SrpTerm(Srp* srp);
55 
56 /*!
57     \ingroup SRP
58 
59     \brief Sets the username. This function MUST be called after wc_SrpInit.
60 
61     \return 0 Username set successfully.
62     \return BAD_FUNC_ARG: Return if srp or username is null.
63     \return MEMORY_E: Returns if there is an issue allocating memory
64     for srp->user
65     \return < 0: Error.
66 
67     \param srp the Srp structure.
68     \param username the buffer containing the username.
69     \param size the username size in bytes
70 
71     _Example_
72     \code
73     Srp srp;
74     byte username[] = "user";
75     word32 usernameSize = 4;
76 
77     wc_SrpInit(&srp, SRP_TYPE_SHA, SRP_CLIENT_SIDE);
78     if(wc_SrpSetUsername(&srp, username, usernameSize) != 0)
79     {
80         // Error occurred setting username.
81     }
82     wc_SrpTerm(&srp);
83     \endcode
84 
85     \sa wc_SrpInit
86     \sa wc_SrpSetParams
87     \sa wc_SrpTerm
88 */
89 WOLFSSL_API int wc_SrpSetUsername(Srp* srp, const byte* username, word32 size);
90 
91 /*!
92     \ingroup SRP
93 
94     \brief Sets the srp parameters based on the username..  Must be called
95     after wc_SrpSetUsername.
96 
97     \return 0 Success
98     \return BAD_FUNC_ARG Returns if srp, N, g, or salt is null or if nSz < gSz.
99     \return SRP_CALL_ORDER_E Returns if wc_SrpSetParams is called before
100     wc_SrpSetUsername.
101     \return <0 Error
102 
103     \param srp the Srp structure.
104     \param N the Modulus. N = 2q+1, [q, N] are primes.
105     \param nSz the N size in bytes.
106     \param g the Generator modulo N.
107     \param gSz the g size in bytes
108     \param salt a small random salt. Specific for each username.
109     \param saltSz the salt size in bytes
110 
111     _Example_
112     \code
113     Srp srp;
114     byte username[] = "user";
115     word32 usernameSize = 4;
116 
117     byte N[] = { }; // Contents of byte array N
118     byte g[] = { }; // Contents of byte array g
119     byte salt[] = { }; // Contents of byte array salt
120 
121     wc_SrpInit(&srp, SRP_TYPE_SHA, SRP_CLIENT_SIDE);
122     wc_SrpSetUsername(&srp, username, usernameSize);
123 
124     if(wc_SrpSetParams(&srp, N, sizeof(N), g, sizeof(g), salt,
125     sizeof(salt)) != 0)
126     {
127         // Error setting params
128     }
129     wc_SrpTerm(&srp);
130     \endcode
131 
132     \sa wc_SrpInit
133     \sa wc_SrpSetUsername
134     \sa wc_SrpTerm
135 */
136 WOLFSSL_API int wc_SrpSetParams(Srp* srp, const byte* N,    word32 nSz,
137                                           const byte* g,    word32 gSz,
138                                           const byte* salt, word32 saltSz);
139 
140 /*!
141     \ingroup SRP
142 
143     \brief Sets the password. Setting the password does not persists the
144     clear password data in the srp structure. The client calculates
145     x = H(salt + H(user:pswd)) and stores it in the auth field. This function
146     MUST be called after wc_SrpSetParams and is CLIENT SIDE ONLY.
147 
148     \return 0 Success
149     \return BAD_FUNC_ARG Returns if srp or password is null or if srp->side
150     is not set to SRP_CLIENT_SIDE.
151     \return SRP_CALL_ORDER_E Returns when wc_SrpSetPassword is called out
152     of order.
153     \return <0 Error
154 
155     \param srp The Srp structure.
156     \param password The buffer containing the password.
157     \param size The size of the password in bytes.
158 
159     _Example_
160     \code
161     Srp srp;
162     byte username[] = "user";
163     word32 usernameSize = 4;
164     byte password[] = "password";
165     word32 passwordSize = 8;
166 
167     byte N[] = { }; // Contents of byte array N
168     byte g[] = { }; // Contents of byte array g
169     byte salt[] = { }; // Contents of byte array salt
170 
171     wc_SrpInit(&srp, SRP_TYPE_SHA, SRP_CLIENT_SIDE);
172     wc_SrpSetUsername(&srp, username, usernameSize);
173     wc_SrpSetParams(&srp, N, sizeof(N), g, sizeof(g), salt, sizeof(salt));
174 
175     if(wc_SrpSetPassword(&srp, password, passwordSize) != 0)
176     {
177         // Error setting password
178     }
179 
180     wc_SrpTerm(&srp);
181     \endcode
182 
183     \sa wc_SrpInit
184     \sa wc_SrpSetUsername
185     \sa wc_SrpSetParams
186 */
187 WOLFSSL_API int wc_SrpSetPassword(Srp* srp, const byte* password, word32 size);
188 
189 /*!
190     \ingroup SRP
191 
192     \brief Sets the verifier. This function MUST be called after
193     wc_SrpSetParams and is SERVER SIDE ONLY.
194 
195     \return 0 Success
196     \return BAD_FUNC_ARG Returned if srp or verifier is null or
197     srp->side is not SRP_SERVER_SIDE.
198     \return <0 Error
199 
200     \param srp The Srp structure.
201     \param verifier The structure containing the verifier.
202     \param size The verifier size in bytes.
203 
204     _Example_
205     \code
206     Srp srp;
207     byte username[] = "user";
208     word32 usernameSize = 4;
209 
210     byte N[] = { }; // Contents of byte array N
211     byte g[] = { }; // Contents of byte array g
212     byte salt[] = { }; // Contents of byte array salt
213     wc_SrpInit(&srp, SRP_TYPE_SHA, SRP_SERVER_SIDE);
214     wc_SrpSetUsername(&srp, username, usernameSize);
215     wc_SrpSetParams(&srp, N, sizeof(N), g, sizeof(g), salt, sizeof(salt))
216     byte verifier[] = { }; // Contents of some verifier
217 
218     if(wc_SrpSetVerifier(&srp, verifier, sizeof(verifier)) != 0)
219     {
220         // Error setting verifier
221     }
222 
223     wc_SrpTerm(&srp);
224     \endcode
225 
226     \sa wc_SrpInit
227     \sa wc_SrpSetParams
228     \sa wc_SrpGetVerifier
229 */
230 WOLFSSL_API int wc_SrpSetVerifier(Srp* srp, const byte* verifier, word32 size);
231 
232 /*!
233     \ingroup SRP
234 
235     \brief Gets the verifier. The client calculates the verifier
236     with v = g ^ x % N.
237     This function MAY be called after wc_SrpSetPassword and
238     is CLIENT SIDE ONLY.
239 
240     \return 0 Success
241     \return BAD_FUNC_ARG Returned if srp, verifier or size is null
242     or if srp->side is not SRP_CLIENT_SIDE.
243     \return SRP_CALL_ORDER_E Returned if wc_SrpGetVerifier is called
244     out of order.
245     \return <0 Error
246 
247     \param srp The Srp structure.
248     \param verifier The buffer to write the verifier.
249     \param size Buffer size in bytes.  Updated with the verifier size.
250 
251     _Example_
252     \code
253     Srp srp;
254     byte username[] = "user";
255     word32 usernameSize = 4;
256     byte password[] = "password";
257     word32 passwordSize = 8;
258 
259     byte N[] = { }; // Contents of byte array N
260     byte g[] = { }; // Contents of byte array g
261     byte salt[] = { }; // Contents of byte array salt
262     byte v[64];
263     word32 vSz = 0;
264     vSz = sizeof(v);
265 
266     wc_SrpInit(&srp, SRP_TYPE_SHA, SRP_CLIENT_SIDE);
267     wc_SrpSetUsername(&srp, username, usernameSize);
268     wc_SrpSetParams(&srp, N, sizeof(N), g, sizeof(g), salt, sizeof(salt))
269     wc_SrpSetPassword(&srp, password, passwordSize)
270 
271     if( wc_SrpGetVerifier(&srp, v, &vSz ) != 0)
272     {
273         // Error getting verifier
274     }
275     wc_SrpTerm(&srp);
276     \endcode
277 
278     \sa wc_SrpSetVerifier
279     \sa wc_SrpSetPassword
280 */
281 WOLFSSL_API int wc_SrpGetVerifier(Srp* srp, byte* verifier, word32* size);
282 
283 /*!
284     \ingroup SRP
285 
286     \brief Sets the private ephemeral value. The private ephemeral value
287     is known as:
288     a at the client side. a = random()
289     b at the server side. b = random()
290     This function is handy for unit test cases or if the developer wants
291     to use an external
292     random source to set the ephemeral value. This function MAY be called
293     before wc_SrpGetPublic.
294 
295     \return 0 Success
296     \return BAD_FUNC_ARG Returned if srp, private, or size is null.
297     \return SRP_CALL_ORDER_E Returned if wc_SrpSetPrivate is called out
298     of order.
299     \return <0 Error
300 
301     \param srp the Srp structure.
302     \param priv the ephemeral value.
303     \param size the private size in bytes.
304 
305     _Example_
306     \code
307     Srp srp;
308     byte username[] = "user";
309     word32 usernameSize = 4;
310 
311     byte N[] = { }; // Contents of byte array N
312     byte g[] = { }; // Contents of byte array g
313     byte salt[] = { }; // Contents of byte array salt
314     byte verifier = { }; // Contents of some verifier
315     wc_SrpInit(&srp, SRP_TYPE_SHA, SRP_SERVER_SIDE);
316     wc_SrpSetUsername(&srp, username, usernameSize);
317     wc_SrpSetParams(&srp, N, sizeof(N), g, sizeof(g), salt, sizeof(salt))
318     wc_SrpSetVerifier(&srp, verifier, sizeof(verifier))
319 
320     byte b[] = { }; // Some ephemeral value
321     if( wc_SrpSetPrivate(&srp, b, sizeof(b)) != 0)
322     {
323         // Error setting private ephemeral
324     }
325 
326     wc_SrpTerm(&srp);
327     \endcode
328 
329     \sa wc_SrpGetPublic
330 */
331 WOLFSSL_API int wc_SrpSetPrivate(Srp* srp, const byte* priv, word32 size);
332 
333 /*!
334     \ingroup SRP
335 
336     \brief Gets the public ephemeral value.  The public ephemeral value
337     is known as:
338     A at the client side. A = g ^ a % N
339     B at the server side. B = (k * v + (g ˆ b % N)) % N
340     This function MUST be called after wc_SrpSetPassword or wc_SrpSetVerifier.
341     The function wc_SrpSetPrivate may be called before wc_SrpGetPublic.
342 
343     \return 0 Success
344     \return BAD_FUNC_ARG Returned if srp, pub, or size is null.
345     \return SRP_CALL_ORDER_E Returned if wc_SrpGetPublic is called out
346     of order.
347     \return BUFFER_E Returned if size < srp.N.
348     \return <0 Error
349 
350     \param srp the Srp structure.
351     \param pub the buffer to write the public ephemeral value.
352     \param size the the buffer size in bytes. Will be updated with
353     the ephemeral value size.
354 
355     _Example_
356     \code
357     Srp srp;
358     byte username[] = "user";
359     word32 usernameSize = 4;
360     byte password[] = "password";
361     word32 passwordSize = 8;
362 
363     byte N[] = { }; // Contents of byte array N
364     byte g[] = { }; // Contents of byte array g
365     byte salt[] = { }; // Contents of byte array salt
366     wc_SrpInit(&srp, SRP_TYPE_SHA, SRP_CLIENT_SIDE);
367     wc_SrpSetUsername(&srp, username, usernameSize);
368     wc_SrpSetParams(&srp, N, sizeof(N), g, sizeof(g), salt, sizeof(salt));
369     wc_SrpSetPassword(&srp, password, passwordSize)
370 
371     byte public[64];
372     word32 publicSz = 0;
373 
374     if( wc_SrpGetPublic(&srp, public, &publicSz) != 0)
375     {
376         // Error getting public ephemeral
377     }
378 
379     wc_SrpTerm(&srp);
380     \endcode
381 
382     \sa wc_SrpSetPrivate
383     \sa wc_SrpSetPassword
384     \sa wc_SrpSetVerifier
385 */
386 WOLFSSL_API int wc_SrpGetPublic(Srp* srp, byte* pub, word32* size);
387 
388 /*!
389     \ingroup SRP
390 
391     \brief Computes the session key.  The key can be accessed at
392     srp->key after success.
393 
394     \return 0 Success
395     \return BAD_FUNC_ARG Returned if srp, clientPubKey, or serverPubKey
396     or if clientPubKeySz or serverPubKeySz is 0.
397     \return SRP_CALL_ORDER_E Returned if wc_SrpComputeKey is called out
398     of order.
399     \return <0 Error
400 
401     \param srp the Srp structure.
402     \param clientPubKey the client's public ephemeral value.
403     \param clientPubKeySz the client's public ephemeral value size.
404     \param serverPubKey the server's public ephemeral value.
405     \param serverPubKeySz the server's public ephemeral value size.
406 
407     _Example_
408     \code
409     Srp server;
410 
411     byte username[] = "user";
412         word32 usernameSize = 4;
413     byte password[] = "password";
414     word32 passwordSize = 8;
415     byte N[] = { }; // Contents of byte array N
416     byte g[] = { }; // Contents of byte array g
417     byte salt[] = { }; // Contents of byte array salt
418     byte verifier[] = { }; // Contents of some verifier
419     byte serverPubKey[] = { }; // Contents of server pub key
420     word32 serverPubKeySize = sizeof(serverPubKey);
421     byte clientPubKey[64];
422     word32 clientPubKeySize = 64;
423 
424     wc_SrpInit(&server, SRP_TYPE_SHA, SRP_SERVER_SIDE);
425     wc_SrpSetUsername(&server, username, usernameSize);
426     wc_SrpSetParams(&server, N, sizeof(N), g, sizeof(g), salt, sizeof(salt));
427     wc_SrpSetVerifier(&server, verifier, sizeof(verifier));
428     wc_SrpGetPublic(&server, serverPubKey, &serverPubKeySize);
429 
430     wc_SrpComputeKey(&server, clientPubKey, clientPubKeySz,
431                                           serverPubKey, serverPubKeySize)
432     wc_SrpTerm(&server);
433     \endcode
434 
435     \sa wc_SrpGetPublic
436 */
437 WOLFSSL_API int wc_SrpComputeKey(Srp* srp,
438                                  byte* clientPubKey, word32 clientPubKeySz,
439                                  byte* serverPubKey, word32 serverPubKeySz);
440 
441 /*!
442     \ingroup SRP
443 
444     \brief Gets the proof. This function MUST be called after wc_SrpComputeKey.
445 
446     \return 0 Success
447     \return BAD_FUNC_ARG Returns if srp, proof, or size is null.
448     \return BUFFER_E Returns if size is less than the hash size of srp->type.
449     \return <0 Error
450 
451     \param srp the Srp structure.
452     \param proof the peers proof.
453     \param size the proof size in bytes.
454 
455     _Example_
456     \code
457     Srp cli;
458     byte clientProof[SRP_MAX_DIGEST_SIZE];
459     word32 clientProofSz = SRP_MAX_DIGEST_SIZE;
460 
461     // Initialize Srp following steps from previous examples
462 
463     if (wc_SrpGetProof(&cli, clientProof, &clientProofSz) != 0)
464     {
465         // Error getting proof
466     }
467     \endcode
468 
469     \sa wc_SrpComputeKey
470 */
471 WOLFSSL_API int wc_SrpGetProof(Srp* srp, byte* proof, word32* size);
472 
473 /*!
474     \ingroup SRP
475 
476     \brief Verifies the peers proof. This function MUST be called before
477     wc_SrpGetSessionKey.
478 
479     \return 0 Success
480     \return <0 Error
481 
482     \param srp the Srp structure.
483     \param proof the peers proof.
484     \param size the proof size in bytes.
485 
486     _Example_
487     \code
488     Srp cli;
489     Srp srv;
490     byte clientProof[SRP_MAX_DIGEST_SIZE];
491     word32 clientProofSz = SRP_MAX_DIGEST_SIZE;
492 
493     // Initialize Srp following steps from previous examples
494     // First get the proof
495     wc_SrpGetProof(&cli, clientProof, &clientProofSz)
496 
497     if (wc_SrpVerifyPeersProof(&srv, clientProof, clientProofSz) != 0)
498     {
499         // Error verifying proof
500     }
501     \endcode
502 
503     \sa wc_SrpGetSessionKey
504     \sa wc_SrpGetProof
505     \sa wc_SrpTerm
506 */
507 WOLFSSL_API int wc_SrpVerifyPeersProof(Srp* srp, byte* proof, word32 size);
508