]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
Fix EVP_KDF_scrypt so that is uses a propq for its fetch.
authorShane Lontis <shane.lontis@oracle.com>
Tue, 22 Sep 2020 05:45:17 +0000 (15:45 +1000)
committerShane Lontis <shane.lontis@oracle.com>
Wed, 23 Sep 2020 07:31:40 +0000 (17:31 +1000)
The parameter can be set via settable parameter OSSL_KDF_PARAM_PROPERTIES

Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/12944)

doc/man7/EVP_KDF-SCRYPT.pod
providers/implementations/kdfs/scrypt.c

index 8650a8b39a835b0244cf0c9db3a1d9ad87bb60a8..ec4eab8f1c8f5ab80efa094e03ac306c56819f7e 100644 (file)
@@ -55,10 +55,17 @@ These parameters work as described in L<EVP_KDF(3)/PARAMETERS>.
 
 =item "p" (B<OSSL_KDF_PARAM_SCRYPT_P>) <unsigned integer>
 
-These parameters configure the scrypt work factors N, r and p.
-N is a parameter of type B<uint64_t>.
+=item "maxmem_bytes" (B<OSSL_KDF_PARAM_SCRYPT_MAXMEM>) <unsigned integer>
+
+These parameters configure the scrypt work factors N, r, maxmem and p.
+Both N and maxmem_bytes are parameters of type B<uint64_t>.
 Both r and p are parameters of type B<uint32_t>.
 
+=item "properties" (B<OSSL_KDF_PARAM_PROPERTIES>) <UTF8 string>
+
+This can be used to set the property query string when fetching the
+fixed digest internally. NULL is used if this value is not set.
+
 =back
 
 =head1 NOTES
index f412f1f8db467c92573c757516e75af65b5c66ab..7a389e65d83d4da3a092cf52b002d95cbc22c856 100644 (file)
@@ -40,7 +40,8 @@ static int scrypt_alg(const char *pass, size_t passlen,
                       OPENSSL_CTX *libctx, const char *propq);
 
 typedef struct {
-    void *provctx;
+    OPENSSL_CTX *libctx;
+    char *propq;
     unsigned char *pass;
     size_t pass_len;
     unsigned char *salt;
@@ -65,14 +66,7 @@ static void *kdf_scrypt_new(void *provctx)
         ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
         return NULL;
     }
-    ctx->provctx = provctx;
-    ctx->sha256 = EVP_MD_fetch(PROV_LIBRARY_CONTEXT_OF(provctx),
-                               "sha256", NULL);
-    if (ctx->sha256 == NULL) {
-        OPENSSL_free(ctx);
-        ERR_raise(ERR_LIB_PROV, PROV_R_UNABLE_TO_LOAD_SHA256);
-        return NULL;
-    }
+    ctx->libctx = PROV_LIBRARY_CONTEXT_OF(provctx);
     kdf_scrypt_init(ctx);
     return ctx;
 }
@@ -82,6 +76,7 @@ static void kdf_scrypt_free(void *vctx)
     KDF_SCRYPT *ctx = (KDF_SCRYPT *)vctx;
 
     if (ctx != NULL) {
+        OPENSSL_free(ctx->propq);
         EVP_MD_free(ctx->sha256);
         kdf_scrypt_reset(ctx);
         OPENSSL_free(ctx);
@@ -126,6 +121,32 @@ static int scrypt_set_membuf(unsigned char **buffer, size_t *buflen,
     return 1;
 }
 
+static int set_digest(KDF_SCRYPT *ctx)
+{
+    EVP_MD_free(ctx->sha256);
+    ctx->sha256 = EVP_MD_fetch(ctx->libctx, "sha256", ctx->propq);
+    if (ctx->sha256 == NULL) {
+        OPENSSL_free(ctx);
+        ERR_raise(ERR_LIB_PROV, PROV_R_UNABLE_TO_LOAD_SHA256);
+        return 0;
+    }
+    return 1;
+}
+
+static int set_property_query(KDF_SCRYPT *ctx, const char *propq)
+{
+    OPENSSL_free(ctx->propq);
+    ctx->propq = NULL;
+    if (propq != NULL) {
+        ctx->propq = OPENSSL_strdup(propq);
+        if (ctx->propq == NULL) {
+            ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
+            return 0;
+        }
+    }
+    return 1;
+}
+
 static int kdf_scrypt_derive(void *vctx, unsigned char *key,
                              size_t keylen)
 {
@@ -144,10 +165,13 @@ static int kdf_scrypt_derive(void *vctx, unsigned char *key,
         return 0;
     }
 
+    if (ctx->sha256 == NULL && !set_digest(ctx))
+        return 0;
+
     return scrypt_alg((char *)ctx->pass, ctx->pass_len, ctx->salt,
                       ctx->salt_len, ctx->N, ctx->r, ctx->p,
                       ctx->maxmem_bytes, key, keylen, ctx->sha256,
-                      PROV_LIBRARY_CONTEXT_OF(ctx->provctx), NULL);
+                      ctx->libctx, ctx->propq);
 }
 
 static int is_power_of_two(uint64_t value)
@@ -198,6 +222,14 @@ static int kdf_scrypt_set_ctx_params(void *vctx, const OSSL_PARAM params[])
             return 0;
         ctx->maxmem_bytes = u64_value;
     }
+
+    p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_PROPERTIES);
+    if (p != NULL) {
+        if (p->data_type != OSSL_PARAM_UTF8_STRING
+            || !set_property_query(ctx, p->data)
+            || !set_digest(ctx))
+            return 0;
+    }
     return 1;
 }
 
@@ -210,6 +242,7 @@ static const OSSL_PARAM *kdf_scrypt_settable_ctx_params(ossl_unused void *p_ctx)
         OSSL_PARAM_uint32(OSSL_KDF_PARAM_SCRYPT_R, NULL),
         OSSL_PARAM_uint32(OSSL_KDF_PARAM_SCRYPT_P, NULL),
         OSSL_PARAM_uint64(OSSL_KDF_PARAM_SCRYPT_MAXMEM, NULL),
+        OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_PROPERTIES, NULL, 0),
         OSSL_PARAM_END
     };
     return known_settable_ctx_params;