scrypt: implement ctx dup operation
[openssl.git] / providers / implementations / kdfs / scrypt.c
index a7072f785f0877ae8002bc41d0a0dfd0b24360e6..744f87847b8a156bdd944967942e6e80a4e06208 100644 (file)
 #include "prov/provider_ctx.h"
 #include "prov/providercommon.h"
 #include "prov/implementations.h"
+#include "prov/provider_util.h"
 
 #ifndef OPENSSL_NO_SCRYPT
 
 static OSSL_FUNC_kdf_newctx_fn kdf_scrypt_new;
+static OSSL_FUNC_kdf_dupctx_fn kdf_scrypt_dup;
 static OSSL_FUNC_kdf_freectx_fn kdf_scrypt_free;
 static OSSL_FUNC_kdf_reset_fn kdf_scrypt_reset;
 static OSSL_FUNC_kdf_derive_fn kdf_scrypt_derive;
@@ -92,6 +94,38 @@ static void kdf_scrypt_reset(void *vctx)
     kdf_scrypt_init(ctx);
 }
 
+static void *kdf_scrypt_dup(void *vctx)
+{
+    const KDF_SCRYPT *src = (const KDF_SCRYPT *)vctx;
+    KDF_SCRYPT *dest;
+
+    dest = kdf_scrypt_new(src->libctx);
+    if (dest != NULL) {
+        if (src->sha256 != NULL && !EVP_MD_up_ref(src->sha256))
+            goto err;
+        if (src->propq != NULL) {
+            dest->propq = OPENSSL_strdup(src->propq);
+            if (dest->propq == NULL)
+                goto err;
+        }
+        if (!ossl_prov_memdup(src->salt, src->salt_len,
+                              &dest->salt, &dest->salt_len)
+                || !ossl_prov_memdup(src->pass, src->pass_len,
+                                     &dest->pass , &dest->pass_len))
+            goto err;
+        dest->N = src->N;
+        dest->r = src->r;
+        dest->p = src->p;
+        dest->maxmem_bytes = src->maxmem_bytes;
+        dest->sha256 = src->sha256;
+    }
+    return dest;
+
+ err:
+    kdf_scrypt_free(dest);
+    return NULL;
+}
+
 static void kdf_scrypt_init(KDF_SCRYPT *ctx)
 {
     /* Default values are the most conservative recommendation given in the
@@ -275,6 +309,7 @@ static const OSSL_PARAM *kdf_scrypt_gettable_ctx_params(ossl_unused void *ctx,
 
 const OSSL_DISPATCH ossl_kdf_scrypt_functions[] = {
     { OSSL_FUNC_KDF_NEWCTX, (void(*)(void))kdf_scrypt_new },
+    { OSSL_FUNC_KDF_DUPCTX, (void(*)(void))kdf_scrypt_dup },
     { OSSL_FUNC_KDF_FREECTX, (void(*)(void))kdf_scrypt_free },
     { OSSL_FUNC_KDF_RESET, (void(*)(void))kdf_scrypt_reset },
     { OSSL_FUNC_KDF_DERIVE, (void(*)(void))kdf_scrypt_derive },