@@ -193,6 +193,66 @@ static void wp_kdf_hkdf_reset(wp_HkdfCtx* ctx)
193193 }
194194}
195195
196+ /**
197+ * Duplicate the HKDF context object.
198+ *
199+ * Deep copies the configured key material so the copy derives identically.
200+ *
201+ * @param [in] src HKDF context object.
202+ * @return New HKDF context object on success.
203+ * @return NULL on failure.
204+ */
205+ static wp_HkdfCtx * wp_kdf_hkdf_dup (wp_HkdfCtx * src )
206+ {
207+ wp_HkdfCtx * dst = NULL ;
208+
209+ if (wolfssl_prov_is_running ()) {
210+ dst = wp_kdf_hkdf_new (src -> provCtx );
211+ }
212+ if (dst != NULL ) {
213+ int ok = 1 ;
214+
215+ dst -> mode = src -> mode ;
216+ dst -> mdType = src -> mdType ;
217+ dst -> mdLen = src -> mdLen ;
218+ dst -> keySz = src -> keySz ;
219+ dst -> saltSz = src -> saltSz ;
220+ dst -> infoSz = src -> infoSz ;
221+ dst -> prefixLen = src -> prefixLen ;
222+ dst -> labelLen = src -> labelLen ;
223+ dst -> dataLen = src -> dataLen ;
224+ XMEMCPY (dst -> info , src -> info , src -> infoSz );
225+
226+ if (ok && (src -> key != NULL )) {
227+ dst -> key = wp_octet_dup (src -> key , src -> keySz );
228+ ok = dst -> key != NULL ;
229+ }
230+ if (ok && (src -> salt != NULL )) {
231+ dst -> salt = wp_octet_dup (src -> salt , src -> saltSz );
232+ ok = dst -> salt != NULL ;
233+ }
234+ if (ok && (src -> prefix != NULL )) {
235+ dst -> prefix = wp_octet_dup (src -> prefix , src -> prefixLen );
236+ ok = dst -> prefix != NULL ;
237+ }
238+ if (ok && (src -> label != NULL )) {
239+ dst -> label = wp_octet_dup (src -> label , src -> labelLen );
240+ ok = dst -> label != NULL ;
241+ }
242+ if (ok && (src -> data != NULL )) {
243+ dst -> data = wp_octet_dup (src -> data , src -> dataLen );
244+ ok = dst -> data != NULL ;
245+ }
246+
247+ if (!ok ) {
248+ wp_kdf_hkdf_free (dst );
249+ dst = NULL ;
250+ }
251+ }
252+
253+ return dst ;
254+ }
255+
196256/**
197257 * Derive a key using HKDF.
198258 *
@@ -528,6 +588,7 @@ static const OSSL_PARAM* wp_kdf_hkdf_gettable_ctx_params(wp_HkdfCtx* ctx,
528588/** Dispatch table for HKDF functions implemented using wolfSSL. */
529589const OSSL_DISPATCH wp_kdf_hkdf_functions [] = {
530590 { OSSL_FUNC_KDF_NEWCTX , (DFUNC )wp_kdf_hkdf_new },
591+ { OSSL_FUNC_KDF_DUPCTX , (DFUNC )wp_kdf_hkdf_dup },
531592 { OSSL_FUNC_KDF_FREECTX , (DFUNC )wp_kdf_hkdf_free },
532593 { OSSL_FUNC_KDF_RESET , (DFUNC )wp_kdf_hkdf_reset },
533594 { OSSL_FUNC_KDF_DERIVE , (DFUNC )wp_kdf_hkdf_derive },
@@ -795,6 +856,7 @@ static const OSSL_PARAM* wp_kdf_tls1_3_settable_ctx_params(wp_HkdfCtx* ctx,
795856/** Dispatch table for TLS 1.3 HKDF functions implemented using wolfSSL. */
796857const OSSL_DISPATCH wp_kdf_tls1_3_kdf_functions [] = {
797858 { OSSL_FUNC_KDF_NEWCTX , (DFUNC )wp_kdf_hkdf_new },
859+ { OSSL_FUNC_KDF_DUPCTX , (DFUNC )wp_kdf_hkdf_dup },
798860 { OSSL_FUNC_KDF_FREECTX , (DFUNC )wp_kdf_hkdf_free },
799861 { OSSL_FUNC_KDF_RESET , (DFUNC )wp_kdf_hkdf_reset },
800862 { OSSL_FUNC_KDF_DERIVE , (DFUNC )wp_kdf_tls1_3_derive },
0 commit comments