[openssl] master update

Richard Levitte levitte at openssl.org
Tue Mar 12 18:17:36 UTC 2019


The branch master has been updated
       via  e2146e120f5bab21dcedfb34741141897f80e1ee (commit)
       via  eabf91cd11e733142b238c24f7ce39974bcfcb70 (commit)
       via  7ffbd7ca9696ade5274068c29a8e03217f596e57 (commit)
       via  8c4412ed8fe80a8b92549d7e2db1359012074d65 (commit)
      from  a61b7f2fa6de3bf8d5b1436e66c52d6bf7150ae4 (commit)


- Log -----------------------------------------------------------------
commit e2146e120f5bab21dcedfb34741141897f80e1ee
Author: Richard Levitte <levitte at openssl.org>
Date:   Mon Mar 11 21:49:54 2019 +0100

    Change OSSL_PARAM_UTF8_STRING_PTR to OSSL_PARAM_UTF8_PTR
    
    In unrelated code
    
    Reviewed-by: Matt Caswell <matt at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/8451)

commit eabf91cd11e733142b238c24f7ce39974bcfcb70
Author: Pauli <paul.dale at oracle.com>
Date:   Fri Mar 8 16:33:12 2019 +1000

    generated files
    
    Reviewed-by: Matt Caswell <matt at openssl.org>
    Reviewed-by: Richard Levitte <levitte at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/8451)

commit 7ffbd7ca9696ade5274068c29a8e03217f596e57
Author: Pauli <paul.dale at oracle.com>
Date:   Fri Feb 22 12:21:33 2019 +1000

    OSSL_PARAM helper functions.
    
    Provide a number of functions to allow parameters to be set and
    retrieved in a type safe manner.  Functions are provided for many
    integral types plus double, BIGNUM, UTF8 strings and OCTET strings.
    
    All of the integer functions will widen the parameter data as
    required.  This permits a degree of malleability in the parameter
    definition.  For example a type can be changed from a thirty two bit
    integer to a sixty four bit one without changing application code.
    Only four and eight byte integral sizes are supported here.
    
    A pair of real functions are available for doubles.
    
    A pair of functions is available for BIGNUMs.  These accept any sized
    unsigned integer input and convert to/from a BIGNUM.
    
    For each OCTET and UTF8 strings, four functions are defined.  This
    provide get and set functionality for string and for pointers to
    strings.  The latter avoiding copies but have other inherent risks.
    
    Finally, some utility macros and functions are defined to allow
    OSSL_PARAM definition arrays to be specified in a simple manner.
    There are two macro and one function for most types.  The exception
    being BIGNUM, for which there is one macro and one function.
    
    Reviewed-by: Matt Caswell <matt at openssl.org>
    Reviewed-by: Richard Levitte <levitte at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/8451)

commit 8c4412ed8fe80a8b92549d7e2db1359012074d65
Author: Richard Levitte <levitte at openssl.org>
Date:   Mon Mar 11 21:51:01 2019 +0100

    Rename 'buffer' to 'data' in OSSL_PARAM
    
    The OSSL_PARAM attribute names |buffer| and |buffer_size| may lead to
    confusion, as they may make some think that the memory pointed at is
    an intermediate memory are.  This is not generally the case, so we
    rename |buffer| and |buffer_size| to |data| and |data_size|
    
    Reviewed-by: Matt Caswell <matt at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/8451)

-----------------------------------------------------------------------

Summary of changes:
 crypto/build.info                                  |   2 +-
 crypto/params.c                                    | 725 +++++++++++++++++++++
 crypto/provider_core.c                             |   8 +-
 doc/man3/OSSL_PARAM.pod                            |  88 +--
 doc/man3/OSSL_PARAM_TYPE.pod                       | 312 +++++++++
 include/openssl/core.h                             |  37 +-
 include/openssl/params.h                           | 186 ++++++
 test/build.info                                    |   6 +-
 test/p_test.c                                      |  12 +-
 test/params_api_test.c                             | 627 ++++++++++++++++++
 test/provider_internal_test.c                      |   4 +-
 test/provider_test.c                               |   4 +-
 .../{03-test_property.t => 03-test_params_api.t}   |   2 +-
 test/testutil.h                                    |   9 +
 test/testutil/tests.c                              |   1 +
 util/libcrypto.num                                 |  46 ++
 util/private.num                                   |  15 +
 17 files changed, 2008 insertions(+), 76 deletions(-)
 create mode 100644 crypto/params.c
 create mode 100644 doc/man3/OSSL_PARAM_TYPE.pod
 create mode 100644 include/openssl/params.h
 create mode 100644 test/params_api_test.c
 copy test/recipes/{03-test_property.t => 03-test_params_api.t} (89%)

diff --git a/crypto/build.info b/crypto/build.info
index a1ccad4..6497c2f 100644
--- a/crypto/build.info
+++ b/crypto/build.info
@@ -17,7 +17,7 @@ SOURCE[../libcrypto]=\
         ebcdic.c uid.c o_time.c o_str.c o_dir.c o_fopen.c ctype.c \
         threads_pthread.c threads_win.c threads_none.c getenv.c \
         o_init.c o_fips.c mem_sec.c init.c context.c sparse_array.c \
-        trace.c provider.c \
+        trace.c provider.c params.c \
         {- $target{cpuid_asm_src} -} {- $target{uplink_aux_src} -}
 
 DEPEND[cversion.o]=buildinf.h
diff --git a/crypto/params.c b/crypto/params.c
new file mode 100644
index 0000000..a53d513
--- /dev/null
+++ b/crypto/params.c
@@ -0,0 +1,725 @@
+/*
+ * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright (c) 2019, Oracle and/or its affiliates.  All rights reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <string.h>
+#include <openssl/params.h>
+#include "internal/thread_once.h"
+
+#define SET_RETURN_SIZE(p, sz) \
+    if ((p)->return_size != NULL) \
+        *(p)->return_size = (sz)
+
+const OSSL_PARAM *OSSL_PARAM_locate(const OSSL_PARAM *p, const char *key)
+{
+    if (p != NULL && key != NULL)
+        for (; p->key != NULL; p++)
+            if (strcmp(key, p->key) == 0)
+                return p;
+    return NULL;
+}
+
+static OSSL_PARAM ossl_param_construct(const char *key, unsigned int data_type,
+                                       void *data, size_t data_size,
+                                       size_t *return_size)
+{
+    OSSL_PARAM res;
+
+    res.key = key;
+    res.data_type = data_type;
+    res.data = data;
+    res.data_size = data_size;
+    res.return_size = return_size;
+    return res;
+}
+
+int OSSL_PARAM_get_int(const OSSL_PARAM *p, int *val)
+{
+    if (val == NULL || p == NULL || p->data_type != OSSL_PARAM_INTEGER)
+        return 0;
+
+    switch (p->data_size) {
+    case sizeof(int32_t):
+        if (sizeof(int) >= sizeof(int32_t)) {
+            *val = (int)*(const int32_t *)p->data;
+            return 1;
+        }
+        break;
+    case sizeof(int64_t):
+        if (sizeof(int) >= sizeof(int64_t)) {
+            *val = (int)*(const int64_t *)p->data;
+            return 1;
+        }
+        break;
+    }
+    return 0;
+}
+
+int OSSL_PARAM_set_int(const OSSL_PARAM *p, int val)
+{
+    if (p == NULL)
+        return 0;
+    SET_RETURN_SIZE(p, 0);
+    if (p->data_type != OSSL_PARAM_INTEGER)
+        return 0;
+
+    SET_RETURN_SIZE(p, sizeof(int)); /* Minimum expected size */
+    switch (p->data_size) {
+    case sizeof(int32_t):
+        if (sizeof(int32_t) >= sizeof(int)) {
+            SET_RETURN_SIZE(p, sizeof(int32_t));
+            *(int32_t *)p->data = (int32_t)val;
+            return 1;
+        }
+        break;
+    case sizeof(int64_t):
+        if (sizeof(int64_t) >= sizeof(int)) {
+            SET_RETURN_SIZE(p, sizeof(int64_t));
+            *(int64_t *)p->data = (int64_t)val;
+            return 1;
+        }
+        break;
+    }
+    return 0;
+}
+
+OSSL_PARAM OSSL_PARAM_construct_int(const char *key, int *buf, size_t *rsize)
+{
+    return ossl_param_construct(key, OSSL_PARAM_INTEGER, buf, sizeof(int),
+                                rsize);
+}
+
+int OSSL_PARAM_get_uint(const OSSL_PARAM *p, unsigned int *val)
+{
+    if (val == NULL
+        || p == NULL
+        || (p->data_type != OSSL_PARAM_UNSIGNED_INTEGER))
+        return 0;
+
+    switch (p->data_size) {
+    case sizeof(uint32_t):
+        if (sizeof(unsigned int) >= sizeof(uint32_t)) {
+            *val = (unsigned int)*(const uint32_t *)p->data;
+            return 1;
+        }
+        break;
+    case sizeof(uint64_t):
+        if (sizeof(unsigned int) >= sizeof(uint64_t)) {
+            *val = (unsigned int)*(const uint64_t *)p->data;
+            return 1;
+        }
+        break;
+    }
+    return 0;
+}
+
+int OSSL_PARAM_set_uint(const OSSL_PARAM *p, unsigned int val)
+{
+    if (p == NULL)
+        return 0;
+    SET_RETURN_SIZE(p, 0);
+    if (p->data_type != OSSL_PARAM_UNSIGNED_INTEGER)
+        return 0;
+
+    SET_RETURN_SIZE(p, sizeof(unsigned int)); /* Minimum expected size */
+    switch (p->data_size) {
+    case sizeof(uint32_t):
+        if (sizeof(uint32_t) >= sizeof(unsigned int)) {
+            SET_RETURN_SIZE(p, sizeof(uint32_t));
+            *(uint32_t *)p->data = (uint32_t)val;
+            return 1;
+        }
+        break;
+    case sizeof(uint64_t):
+        if (sizeof(uint64_t) >= sizeof(unsigned int)) {
+            SET_RETURN_SIZE(p, sizeof(uint64_t));
+            *(uint64_t *)p->data = (uint64_t)val;
+            return 1;
+        }
+        break;
+    }
+    return 0;
+}
+
+OSSL_PARAM OSSL_PARAM_construct_uint(const char *key, unsigned int *buf,
+                                     size_t *rsize)
+{
+    return ossl_param_construct(key, OSSL_PARAM_UNSIGNED_INTEGER, buf,
+                                sizeof(unsigned int), rsize);
+}
+
+int OSSL_PARAM_get_long(const OSSL_PARAM *p, long int *val)
+{
+    if (val == NULL || p == NULL || (p->data_type != OSSL_PARAM_INTEGER))
+        return 0;
+
+    switch (p->data_size) {
+    case sizeof(int32_t):
+        if (sizeof(long int) >= sizeof(int32_t)) {
+            *val = (long int)*(const int32_t *)p->data;
+            return 1;
+        } break;
+    case sizeof(int64_t):
+        if (sizeof(long int) >= sizeof(int64_t)) {
+            *val = (long int)*(const int64_t *)p->data;
+            return 1;
+        }
+        break;
+    }
+    return 0;
+}
+
+int OSSL_PARAM_set_long(const OSSL_PARAM *p, long int val)
+{
+    if (p == NULL)
+        return 0;
+    SET_RETURN_SIZE(p, 0);
+    if (p->data_type != OSSL_PARAM_INTEGER)
+        return 0;
+
+    SET_RETURN_SIZE(p, sizeof(long int)); /* Minimum expected size */
+    switch (p->data_size) {
+    case sizeof(int32_t):
+        if (sizeof(int32_t) >= sizeof(long int)) {
+            SET_RETURN_SIZE(p, sizeof(int32_t));
+            *(int32_t *)p->data = (int32_t)val;
+            return 1;
+        }
+        break;
+    case sizeof(int64_t):
+        if (sizeof(int64_t) >= sizeof(long int)) {
+            SET_RETURN_SIZE(p, sizeof(int64_t));
+            *(int64_t *)p->data = (int64_t)val;
+            return 1;
+        }
+        break;
+    }
+    return 0;
+}
+
+OSSL_PARAM OSSL_PARAM_construct_long(const char *key, long int *buf,
+                                     size_t *rsize)
+{
+    return ossl_param_construct(key, OSSL_PARAM_INTEGER, buf, sizeof(long int),
+                                rsize);
+}
+
+int OSSL_PARAM_get_ulong(const OSSL_PARAM *p, unsigned long int *val)
+{
+    if (val == NULL
+        || p == NULL
+        || (p->data_type != OSSL_PARAM_UNSIGNED_INTEGER))
+        return 0;
+
+    switch (p->data_size) {
+    case sizeof(uint32_t):
+        if (sizeof(unsigned long int) >= sizeof(uint32_t)) {
+            *val = (unsigned long int)*(const uint32_t *)p->data;
+            return 1;
+        }
+        break;
+    case sizeof(uint64_t):
+        if (sizeof(unsigned long int) >= sizeof(uint64_t)) {
+            *val = (unsigned long int)*(const uint64_t *)p->data;
+            return 1;
+        }
+        break;
+    }
+    return 0;
+}
+
+int OSSL_PARAM_set_ulong(const OSSL_PARAM *p, unsigned long int val)
+{
+    if (p == NULL)
+        return 0;
+    SET_RETURN_SIZE(p, 0);
+    if (p->data_type != OSSL_PARAM_UNSIGNED_INTEGER)
+        return 0;
+
+    SET_RETURN_SIZE(p, sizeof(unsigned long int)); /* Minimum exp size */
+    switch (p->data_size) {
+    case sizeof(uint32_t):
+        if (sizeof(uint32_t) >= sizeof(unsigned long int)) {
+            SET_RETURN_SIZE(p, sizeof(uint32_t));
+            *(uint32_t *)p->data = (uint32_t)val;
+            return 1;
+        }
+        break;
+    case sizeof(uint64_t):
+        if (sizeof(uint64_t) >= sizeof(unsigned long int)) {
+            SET_RETURN_SIZE(p, sizeof(uint64_t));
+            *(uint64_t *)p->data = (uint64_t)val;
+            return 1;
+        }
+        break;
+    }
+    return 0;
+}
+
+OSSL_PARAM OSSL_PARAM_construct_ulong(const char *key, unsigned long int *buf,
+                                      size_t *rsize)
+{
+    return ossl_param_construct(key, OSSL_PARAM_UNSIGNED_INTEGER, buf,
+                                sizeof(unsigned long int), rsize);
+}
+
+int OSSL_PARAM_get_int32(const OSSL_PARAM *p, int32_t *val)
+{
+    if (val == NULL || p == NULL || (p->data_type != OSSL_PARAM_INTEGER))
+        return 0;
+
+    if (p->data_size == sizeof(int32_t)) {
+        *val = *(const int32_t *)p->data;
+        return 1;
+    }
+    return 0;
+}
+
+int OSSL_PARAM_set_int32(const OSSL_PARAM *p, int32_t val)
+{
+    if (p == NULL)
+        return 0;
+    SET_RETURN_SIZE(p, 0);
+    if (p->data_type != OSSL_PARAM_INTEGER)
+        return 0;
+
+    SET_RETURN_SIZE(p, sizeof(int32_t)); /* Minimum expected size */
+    switch (p->data_size) {
+    case sizeof(int32_t):
+        SET_RETURN_SIZE(p, sizeof(int32_t));
+        *(int32_t *)p->data = val;
+        return 1;
+    case sizeof(int64_t):
+        SET_RETURN_SIZE(p, sizeof(int64_t));
+        *(int64_t *)p->data = (int64_t)val;
+        return 1;
+    }
+    return 0;
+}
+
+OSSL_PARAM OSSL_PARAM_construct_int32(const char *key, int32_t *buf,
+                                      size_t *rsize)
+{
+    return ossl_param_construct(key, OSSL_PARAM_INTEGER, buf,
+                                sizeof(int32_t), rsize);
+}
+
+int OSSL_PARAM_get_uint32(const OSSL_PARAM *p, uint32_t *val)
+{
+    if (val == NULL
+        || p == NULL
+        || (p->data_type != OSSL_PARAM_UNSIGNED_INTEGER))
+        return 0;
+
+    if (p->data_size == sizeof(uint32_t)) {
+        *val = *(const uint32_t *)p->data;
+        return 1;
+    }
+    return 0;
+}
+
+int OSSL_PARAM_set_uint32(const OSSL_PARAM *p, uint32_t val)
+{
+    if (p == NULL) return 0;
+    SET_RETURN_SIZE(p, 0);
+    if (p->data_type != OSSL_PARAM_UNSIGNED_INTEGER)
+        return 0;
+
+    SET_RETURN_SIZE(p, sizeof(uint32_t)); /* Minimum expected size */
+    switch (p->data_size) {
+    case sizeof(uint32_t):
+        SET_RETURN_SIZE(p, sizeof(uint32_t));
+        *(uint32_t *)p->data = val;
+        return 1;
+    case sizeof(uint64_t):
+        SET_RETURN_SIZE(p, sizeof(uint64_t));
+        *(uint64_t *)p->data = (uint64_t)val;
+        return 1;
+    }
+    return 0;
+}
+
+OSSL_PARAM OSSL_PARAM_construct_uint32(const char *key, uint32_t *buf,
+                                       size_t *rsize)
+{
+    return ossl_param_construct(key, OSSL_PARAM_UNSIGNED_INTEGER, buf,
+                                sizeof(uint32_t), rsize);
+}
+
+int OSSL_PARAM_get_int64(const OSSL_PARAM *p, int64_t *val)
+{
+    if (val == NULL || p == NULL || (p->data_type != OSSL_PARAM_INTEGER))
+        return 0;
+
+    switch (p->data_size) {
+    case sizeof(int32_t):
+        *val = (int64_t)*(const int32_t *)p->data;
+        return 1;
+    case sizeof(int64_t):
+        *val = *(const int64_t *)p->data;
+        return 1;
+    }
+    return 0;
+}
+
+int OSSL_PARAM_set_int64(const OSSL_PARAM *p, int64_t val)
+{
+    if (p == NULL)
+        return 0;
+    SET_RETURN_SIZE(p, 0);
+    if (p->data_type != OSSL_PARAM_INTEGER)
+        return 0;
+
+    SET_RETURN_SIZE(p, sizeof(int64_t)); /* Minimum expected size */
+    switch (p->data_size) {
+    case sizeof(int64_t):
+        SET_RETURN_SIZE(p, sizeof(int64_t));
+        *(int64_t *)p->data = val;
+        return 1;
+    }
+    return 0;
+}
+
+OSSL_PARAM OSSL_PARAM_construct_int64(const char *key, int64_t *buf,
+                                      size_t *rsize)
+{
+    return ossl_param_construct(key, OSSL_PARAM_INTEGER, buf, sizeof(int64_t),
+                                rsize);
+}
+
+int OSSL_PARAM_get_uint64(const OSSL_PARAM *p, uint64_t *val)
+{
+    if (val == NULL
+        || p == NULL
+        || (p->data_type != OSSL_PARAM_UNSIGNED_INTEGER))
+        return 0;
+
+    switch (p->data_size) {
+    case sizeof(uint32_t):
+        *val = (uint64_t)*(const uint32_t *)p->data;
+        return 1;
+    case sizeof(uint64_t):
+        *val = *(const uint64_t *)p->data;
+        return 1;
+    }
+    return 0;
+}
+
+int OSSL_PARAM_set_uint64(const OSSL_PARAM *p, uint64_t val)
+{
+    if (p == NULL)
+        return 0;
+    SET_RETURN_SIZE(p, 0);
+    if (p->data_type != OSSL_PARAM_UNSIGNED_INTEGER)
+        return 0;
+
+    SET_RETURN_SIZE(p, sizeof(uint64_t)); /* Minimum expected size */
+    switch (p->data_size) {
+    case sizeof(uint64_t):
+        SET_RETURN_SIZE(p, sizeof(uint64_t));
+        *(uint64_t *)p->data = val;
+        return 1;
+    }
+    return 0;
+}
+
+OSSL_PARAM OSSL_PARAM_construct_uint64(const char *key, uint64_t *buf,
+                                       size_t *rsize) {
+    return ossl_param_construct(key, OSSL_PARAM_UNSIGNED_INTEGER, buf,
+                                sizeof(uint64_t), rsize);
+}
+
+int OSSL_PARAM_get_size_t(const OSSL_PARAM *p, size_t *val)
+{
+    if (val == NULL
+        || p == NULL
+        || p->data_type != OSSL_PARAM_UNSIGNED_INTEGER)
+        return 0;
+
+    switch (p->data_size) {
+    case sizeof(uint32_t):
+        if (sizeof(size_t) >= sizeof(uint32_t)) {
+            *val = (size_t)*(const uint32_t *)p->data;
+            return 1;
+        }
+        break;
+    case sizeof(uint64_t):
+        if (sizeof(size_t) >= sizeof(uint64_t)) {
+            *val = (size_t)*(const uint64_t *)p->data;
+            return 1;
+        }
+        break;
+    }
+    return 0;
+}
+
+int OSSL_PARAM_set_size_t(const OSSL_PARAM *p, size_t val)
+{
+    if (p == NULL)
+        return 0;
+    SET_RETURN_SIZE(p, 0);
+    if (p->data_type != OSSL_PARAM_UNSIGNED_INTEGER)
+        return 0;
+
+    SET_RETURN_SIZE(p, sizeof(size_t)); /* Minimum expected size */
+    switch (p->data_size) {
+    case sizeof(uint32_t):
+        if (sizeof(uint32_t) >= sizeof(size_t)) {
+            SET_RETURN_SIZE(p, sizeof(uint32_t));
+            *(uint32_t *)p->data = (uint32_t)val;
+            return 1;
+        }
+        break;
+    case sizeof(uint64_t):
+        SET_RETURN_SIZE(p, sizeof(uint64_t));
+        if (sizeof(uint64_t) >= sizeof(size_t)) {
+            *(uint64_t *)p->data = (uint64_t)val;
+            return 1;
+        }
+        break;
+    }
+    return 0;
+}
+
+OSSL_PARAM OSSL_PARAM_construct_size_t(const char *key, size_t *buf,
+                                       size_t *rsize)
+{
+    return ossl_param_construct(key, OSSL_PARAM_UNSIGNED_INTEGER, buf,
+                                sizeof(size_t), rsize); }
+
+int OSSL_PARAM_get_BN(const OSSL_PARAM *p, BIGNUM **val)
+{
+    BIGNUM *b;
+
+    if (val == NULL
+        || p == NULL
+        || p->data_type != OSSL_PARAM_UNSIGNED_INTEGER)
+        return 0;
+
+    b = BN_native2bn(p->data, (int)p->data_size, *val);
+    if (b != NULL) {
+        *val = b;
+        return 1;
+    }
+    return 0;
+}
+
+int OSSL_PARAM_set_BN(const OSSL_PARAM *p, const BIGNUM *val)
+{
+    size_t bytes;
+
+    if (p == NULL)
+        return 0;
+    SET_RETURN_SIZE(p, 0);
+    if (val == NULL || p->data_type != OSSL_PARAM_UNSIGNED_INTEGER)
+        return 0;
+
+    bytes = (size_t)BN_num_bytes(val);
+    SET_RETURN_SIZE(p, bytes);
+    return p->data_size >= bytes
+        && BN_bn2nativepad(val, p->data, bytes) >= 0;
+}
+
+OSSL_PARAM OSSL_PARAM_construct_BN(const char *key, unsigned char *buf,
+                                   size_t bsize, size_t *rsize)
+{
+    return ossl_param_construct(key, OSSL_PARAM_UNSIGNED_INTEGER,
+                                buf, bsize, rsize);
+}
+
+int OSSL_PARAM_get_double(const OSSL_PARAM *p, double *val)
+{
+    if (val == NULL || p == NULL || p->data_type != OSSL_PARAM_REAL)
+        return 0;
+
+    switch (p->data_size) {
+    case sizeof(double):
+        *val = *(const double *)p->data;
+        return 1;
+    }
+    return 0;
+}
+
+int OSSL_PARAM_set_double(const OSSL_PARAM *p, double val)
+{
+    if (p == NULL)
+        return 0;
+    SET_RETURN_SIZE(p, 0);
+    if (p->data_type != OSSL_PARAM_REAL)
+        return 0;
+
+    switch (p->data_size) {
+    case sizeof(double):
+        SET_RETURN_SIZE(p, sizeof(double));
+        *(double *)p->data = val;
+        return 1;
+    }
+    return 0;
+}
+
+OSSL_PARAM OSSL_PARAM_construct_double(const char *key, double *buf,
+                                       size_t *rsize)
+{
+    return ossl_param_construct(key, OSSL_PARAM_REAL, buf, sizeof(double),
+                                rsize);
+}
+
+static int get_string_internal(const OSSL_PARAM *p, void **val, size_t max_len,
+                               size_t *used_len, unsigned int type)
+{
+    size_t sz;
+
+    if (val == NULL || p == NULL || p->data_type != type)
+        return 0;
+
+    sz = p->data_size;
+
+    if (used_len != NULL)
+        *used_len = sz;
+
+    if (*val == NULL) {
+        char *const q = OPENSSL_malloc(sz);
+
+        if (q == NULL)
+            return 0;
+        *val = q;
+        memcpy(q, p->data, sz);
+        return 1;
+    }
+    if (max_len < sz)
+        return 0;
+    memcpy(*val, p->data, sz);
+    return 1;
+}
+
+int OSSL_PARAM_get_utf8_string(const OSSL_PARAM *p, char **val, size_t max_len)
+{
+    return get_string_internal(p, (void **)val, max_len, NULL,
+                               OSSL_PARAM_UTF8_STRING);
+}
+
+int OSSL_PARAM_get_octet_string(const OSSL_PARAM *p, void **val, size_t max_len,
+                                size_t *used_len)
+{
+    return get_string_internal(p, val, max_len, used_len,
+                               OSSL_PARAM_OCTET_STRING);
+}
+
+static int set_string_internal(const OSSL_PARAM *p, const void *val, size_t len,
+                               unsigned int type)
+{
+    SET_RETURN_SIZE(p, len);
+    if (p->data_type != type || p->data_size < len)
+        return 0;
+
+    memcpy(p->data, val, len);
+    return 1;
+}
+
+int OSSL_PARAM_set_utf8_string(const OSSL_PARAM *p, const char *val)
+{
+    if (p == NULL)
+        return 0;
+
+    SET_RETURN_SIZE(p, 0);
+    if (val == NULL)
+        return 0;
+    return set_string_internal(p, val, strlen(val) + 1, OSSL_PARAM_UTF8_STRING);
+}
+
+int OSSL_PARAM_set_octet_string(const OSSL_PARAM *p, const void *val,
+                                size_t len)
+{
+    if (p == NULL)
+        return 0;
+
+    SET_RETURN_SIZE(p, 0);
+    if (val == NULL)
+        return 0;
+    return set_string_internal(p, val, len, OSSL_PARAM_OCTET_STRING);
+}
+
+OSSL_PARAM OSSL_PARAM_construct_utf8_string(const char *key, char *buf,
+                                            size_t bsize, size_t *rsize)
+{
+    return ossl_param_construct(key, OSSL_PARAM_UTF8_STRING, buf, bsize,
+                                rsize);
+}
+
+OSSL_PARAM OSSL_PARAM_construct_octet_string(const char *key, void *buf,
+                                             size_t bsize, size_t *rsize)
+{
+    return ossl_param_construct(key, OSSL_PARAM_OCTET_STRING, buf, bsize,
+                                rsize);
+}
+
+static int get_ptr_internal(const OSSL_PARAM *p, const void **val,
+                            size_t *used_len, unsigned int type)
+{
+    if (val == NULL || p == NULL || p->data_type != type)
+        return 0;
+    if (used_len != NULL)
+        *used_len = p->data_size;
+    *val = *(const void **)p->data;
+    return 1;
+}
+
+int OSSL_PARAM_get_utf8_ptr(const OSSL_PARAM *p, const char **val)
+{
+    return get_ptr_internal(p, (const void **)val, NULL, OSSL_PARAM_UTF8_PTR);
+}
+
+int OSSL_PARAM_get_octet_ptr(const OSSL_PARAM *p, const void **val,
+                             size_t *used_len)
+{
+    return get_ptr_internal(p, val, used_len, OSSL_PARAM_OCTET_PTR);
+}
+
+static int set_ptr_internal(const OSSL_PARAM *p, const void *val,
+                            unsigned int type, size_t len)
+{
+    SET_RETURN_SIZE(p, len);
+    if (p->data_type != type)
+        return 0;
+    *(const void **)p->data = val;
+    return 1;
+}
+
+int OSSL_PARAM_set_utf8_ptr(const OSSL_PARAM *p, const char *val)
+{
+    if (p == NULL)
+        return 0;
+    SET_RETURN_SIZE(p, 0);
+    if (val == NULL)
+        return 0;
+    return set_ptr_internal(p, val, OSSL_PARAM_UTF8_PTR, strlen(val) + 1);
+}
+
+int OSSL_PARAM_set_octet_ptr(const OSSL_PARAM *p, const void *val,
+                             size_t used_len)
+{
+    if (p == NULL)
+        return 0;
+    SET_RETURN_SIZE(p, 0);
+    if (val == NULL)
+        return 0;
+    return set_ptr_internal(p, val, OSSL_PARAM_OCTET_PTR, used_len);
+}
+
+OSSL_PARAM OSSL_PARAM_construct_utf8_ptr(const char *key, char **buf,
+                                         size_t *rsize)
+{
+    return ossl_param_construct(key, OSSL_PARAM_UTF8_PTR, buf, 0, rsize);
+}
+
+OSSL_PARAM OSSL_PARAM_construct_octet_ptr(const char *key, void **buf,
+                                          size_t *rsize)
+{
+    return ossl_param_construct(key, OSSL_PARAM_OCTET_PTR, buf, 0, rsize);
+}
diff --git a/crypto/provider_core.c b/crypto/provider_core.c
index b3d44f1..05a6bff 100644
--- a/crypto/provider_core.c
+++ b/crypto/provider_core.c
@@ -381,8 +381,8 @@ int ossl_provider_get_params(const OSSL_PROVIDER *prov,
  * never knows.
  */
 static const OSSL_ITEM param_types[] = {
-    { OSSL_PARAM_UTF8_STRING_PTR, "openssl-version" },
-    { OSSL_PARAM_UTF8_STRING_PTR, "provider-name" },
+    { OSSL_PARAM_UTF8_PTR, "openssl-version" },
+    { OSSL_PARAM_UTF8_PTR, "provider-name" },
     { 0, NULL }
 };
 
@@ -397,11 +397,11 @@ static int core_get_params(const OSSL_PROVIDER *prov, const OSSL_PARAM params[])
 
     for (i = 0; params[i].key != NULL; i++) {
         if (strcmp(params[i].key, "openssl-version") == 0) {
-            *(void **)params[i].buffer = OPENSSL_VERSION_STR;
+            *(void **)params[i].data = OPENSSL_VERSION_STR;
             if (params[i].return_size)
                 *params[i].return_size = sizeof(OPENSSL_VERSION_STR);
         } else if (strcmp(params[i].key, "provider-name") == 0) {
-            *(void **)params[i].buffer = prov->name;
+            *(void **)params[i].data = prov->name;
             if (params[i].return_size)
                 *params[i].return_size = strlen(prov->name) + 1;
         }
diff --git a/doc/man3/OSSL_PARAM.pod b/doc/man3/OSSL_PARAM.pod
index 9d47486..50089b4 100644
--- a/doc/man3/OSSL_PARAM.pod
+++ b/doc/man3/OSSL_PARAM.pod
@@ -11,9 +11,9 @@ OSSL_PARAM - a structure to pass or request object parameters
  typedef struct ossl_param_st OSSL_PARAM;
  struct ossl_param_st {
      const char *key;             /* the name of the parameter */
-     unsigned char data_type;     /* declare what kind of content is in buffer */
-     void *buffer;                /* value being passed in or out */
-     size_t buffer_size;          /* buffer size */
+     unsigned char data_type;     /* declare what kind of content is in data */
+     void *data;                  /* value being passed in or out */
+     size_t data_size;            /* data size */
      size_t *return_size;         /* OPTIONAL: address to content size */
  };
 
@@ -45,8 +45,8 @@ Request parameters of some object.
 The caller (the I<requestor>) sets up the C<OSSL_PARAM> array and
 calls some function (the I<responder>) that has intimate knowledge
 about the object, which can take the internal data of the object and
-copy (possibly convert) that to the buffers prepared by the
-I<requestor>.
+copy (possibly convert) that to the memory prepared by the
+I<requestor> and pointed at with the C<OSSL_PARAM> C<data>.
 
 =back
 
@@ -69,13 +69,13 @@ The C<data_type> is a value that describes the type and organization of
 the data.
 See L</Supported types> below for a description of the types.
 
-=item C<buffer>
+=item C<data>
 
-=item C<buffer_size>
+=item C<data_size>
 
-C<buffer> is a pointer to the memory where the parameter data is (when
+C<data> is a pointer to the memory where the parameter data is (when
 setting parameters) or shall (when requesting parameters) be stored,
-and C<buffer_size> is its size in bytes.
+and C<data_size> is its size in bytes.
 The organization of the data depends on the parameter type and flag.
 
 =item C<return_size>
@@ -83,9 +83,8 @@ The organization of the data depends on the parameter type and flag.
 When an array of C<OSSL_PARAM> is used to request data, the
 I<responder> must set this field to indicate the actual size of the
 parameter data.
-In case the C<buffer_size> is too small for the data, the I<responder>
-must still set this field to indicate the minimum buffer size
-required.
+In case the C<data_size> is too small for the data, the I<responder>
+must still set this field to indicate the minimum data size required.
 
 =back
 
@@ -119,8 +118,6 @@ systems.
 
 =item C<OSSL_PARAM_REAL>
 
-=for comment It's still debated if we need this or not.
-
 The parameter data is a floating point value in native form.
 
 =item C<OSSL_PARAM_UTF8_STRING>
@@ -131,47 +128,50 @@ The parameter data is a printable string.
 
 The parameter data is an arbitrary string of bytes.
 
-=back
-
-Additionally, this flag can be added to any type:
+=item C<OSSL_PARAM_UTF8_PTR>
 
-=over 4
-
-=item C<OSSL_PARAM_POINTER_FLAG>
+The parameter data is a pointer to a printable string.
 
-With this flag, C<buffer> doesn't point directly at the data, but at a
-pointer that points at the data.
+The difference between this and C<OSSL_PARAM_UTF8_STRING> is that C<data>
+doesn't point directly at the data, but to a pointer that points to the data.
 
-This can be used to indicate that constant data is or will be passed,
+This is used to indicate that constant data is or will be passed,
 and there is therefore no need to copy the data that is passed, just
 the pointer to it.
 
-If an C<OSSL_PARAM> with this flag set is used to set a parameter,
-C<buffer_size> must be set to the size of the data, not the size of
-the pointer to the data.
-
-If this C<OSSL_PARAM> is used in a parameter request, C<buffer_size>
-is not relevant.
-However, the I<responder> will set C<*return_size> to the size of the
-data (again, not the size of the pointer to the data).
+C<data_size> must be set to the size of the data, not the size of the
+pointer to the data.
+If this is used in a parameter request,
+C<data_size> is not relevant.  However, the I<responder> will set
+C<*return_size> to the size of the data.
 
-Note that the use of this flag is B<fragile> and can only be safely
+Note that the use of this type is B<fragile> and can only be safely
 used for data that remains constant and in a constant location for a
 long enough duration (such as the life-time of the entity that
 offers these parameters).
 
-=back
+=item C<OSSL_PARAM_OCTET_PTR>
 
-For convenience, these types are provided:
+The parameter data is a pointer to an arbitrary string of bytes.
 
-=over 4
+The difference between this and C<OSSL_PARAM_OCTET_STRING> is that
+C<data> doesn't point directly at the data, but to a pointer that
+points to the data.
 
-=item C<OSSL_PARAM_UTF8_STRING_PTR>
+This is used to indicate that constant data is or will be passed, and
+there is therefore no need to copy the data that is passed, just the
+pointer to it.
 
-=item C<OSSL_PARAM_OCTET_STRING_PTR>
+C<data_size> must be set to the size of the data, not the size of the
+pointer to the data.
+If this is used in a parameter request,
+C<data_size> is not relevant.  However, the I<responder> will set
+C<*return_size> to the size of the data.
 
-These are combinations of C<OSSL_PARAM_UTF8_STRING> as well as
-C<OSSL_PARAM_OCTET_STRING> with C<OSSL_PARAM_POINTER_FLAG>.
+Note that the use of this type is B<fragile> and can only be safely
+used for data that remains constant and in a constant location for a
+long enough duration (such as the life-time of the entity that
+offers these parameters).
 
 =back
 
@@ -197,7 +197,7 @@ enough set of data, that call should succeed.
 =item *
 
 A I<responder> must never change the fields of an C<OSSL_PARAM>, it
-may only change the contents of the buffers that C<buffer> and
+may only change the contents of the memory that C<data> and
 C<return_size> point at.
 
 =item *
@@ -213,7 +213,7 @@ C<OSSL_PARAM_OCTET_STRING>), but this is in no way mandatory.
 
 =item *
 
-If a I<responder> finds that some buffers are too small for the
+If a I<responder> finds that some data sizes are too small for the
 requested data, it must set C<*return_size> for each such
 C<OSSL_PARAM> item to the required size, and eventually return an
 error.
@@ -273,10 +273,10 @@ could fill in the parameters like this:
 
     for (i = 0; params[i].key != NULL; i++) {
         if (strcmp(params[i].key, "foo") == 0) {
-            *(char **)params[i].buffer = "foo value";
+            *(char **)params[i].data = "foo value";
             *params[i].return_size = 10; /* size of "foo value" */
         } else if (strcmp(params[i].key, "bar") == 0) {
-            memcpy(params[1].buffer, "bar value", 10);
+            memcpy(params[1].data, "bar value", 10);
             *params[1].return_size = 10; /* size of "bar value" */
         }
         /* Ignore stuff we don't know */
@@ -284,7 +284,7 @@ could fill in the parameters like this:
 
 =head1 SEE ALSO
 
-L<openssl-core.h(7)>
+L<openssl-core.h(7)>, L<OSSL_PARAM_get_int32_t(3)>
 
 =head1 HISTORY
 
diff --git a/doc/man3/OSSL_PARAM_TYPE.pod b/doc/man3/OSSL_PARAM_TYPE.pod
new file mode 100644
index 0000000..c4ca37a
--- /dev/null
+++ b/doc/man3/OSSL_PARAM_TYPE.pod
@@ -0,0 +1,312 @@
+=pod
+
+=head1 NAME
+
+OSSL_PARAM_TYPE, OSSL_PARAM_utf8_string, OSSL_PARAM_octet_string,
+OSSL_PARAM_utf8_ptr, OSSL_PARAM_octet_ptr, OSSL_PARAM_SIZED_TYPE,
+OSSL_PARAM_SIZED_BN, OSSL_PARAM_SIZED_utf8_string,
+OSSL_PARAM_SIZED_octet_string, OSSL_PARAM_SIZED_utf8_ptr,
+OSSL_PARAM_SIZED_octet_ptr, OSSL_PARAM_END, OSSL_PARAM_construct_TYPE,
+OSSL_PARAM_END,
+OSSL_PARAM_construct_BN, OSSL_PARAM_construct_utf8_string,
+OSSL_PARAM_construct_utf8_ptr, OSSL_PARAM_construct_octet_string,
+OSSL_PARAM_construct_octet_ptr, OSSL_PARAM_locate, OSSL_PARAM_get_TYPE,
+OSSL_PARAM_set_TYPE, OSSL_PARAM_get_BN, OSSL_PARAM_set_BN,
+OSSL_PARAM_get_utf8_string, OSSL_PARAM_set_utf8_string,
+OSSL_PARAM_get_octet_string, OSSL_PARAM_set_octet_string,
+OSSL_PARAM_get_utf8_ptr, OSSL_PARAM_set_utf8_ptr, OSSL_PARAM_get_octet_ptr,
+OSSL_PARAM_set_octet_ptr
+- OSSL_PARAM helpers
+
+=head1 SYNOPSIS
+
+ #include <openssl/params.h>
+
+ #define OSSL_PARAM_TYPE(key, address)
+ #define OSSL_PARAM_utf8_string(key, address, size)
+ #define OSSL_PARAM_octet_string(key, address, size)
+ #define OSSL_PARAM_utf8_ptr(key, address, size)
+ #define OSSL_PARAM_octet_ptr(key, address, size)
+ #define OSSL_PARAM_SIZED_TYPE(key, address, return_size)
+ #define OSSL_PARAM_SIZED_BN(key, address, size, return_size)
+ #define OSSL_PARAM_SIZED_utf8_string(key, address, size, return_size)
+ #define OSSL_PARAM_SIZED_octet_string(key, address, size, return_size)
+ #define OSSL_PARAM_SIZED_utf8_ptr(key, address, size, return_size)
+ #define OSSL_PARAM_SIZED_octet_ptr(key, address, size, return_size)
+ #define OSSL_PARAM_END
+
+ OSSL_PARAM OSSL_PARAM_construct_TYPE(const char *key, TYPE *buf, size_t *ret);
+ OSSL_PARAM OSSL_PARAM_construct_BN(const char *key, unsigned char *buf,
+                                    size_t bsize, size_t *rsize);
+ OSSL_PARAM OSSL_PARAM_construct_utf8_string(const char *key, char *buf,
+                                             size_t bsize, size_t *rsize);
+ OSSL_PARAM OSSL_PARAM_construct_octet_string(const char *key, void *buf,
+                                              size_t bsize, size_t *rsize);
+ OSSL_PARAM OSSL_PARAM_construct_utf8_ptr(const char *key, char **buf,
+                                          size_t *rsize);
+ OSSL_PARAM OSSL_PARAM_construct_octet_ptr(const char *key, void **buf,
+                                           size_t *rsize);
+
+ OSSL_PARAM *OSSL_PARAM_locate(OSSL_PARAM *array, const char *key);
+
+ int OSSL_PARAM_get_TYPE(const OSSL_PARAM *p, const char *key, TYPE *val);
+ int OSSL_PARAM_set_TYPE(const OSSL_PARAM *p, const char *key, TYPE val);
+
+ int OSSL_PARAM_get_BN(const OSSL_PARAM *p, const char *key, BIGNUM **val);
+ int OSSL_PARAM_set_BN(const OSSL_PARAM *p, const char *key, const BIGNUM *val);
+
+ int OSSL_PARAM_get_utf8_string(const OSSL_PARAM *p, char **val,
+                                size_t max_len);
+ int OSSL_PARAM_set_utf8_string(const OSSL_PARAM *p, const char *val);
+
+ int OSSL_PARAM_get_octet_string(const OSSL_PARAM *p, void **val,
+                                 size_t max_len, size_t *used_len);
+ int OSSL_PARAM_set_octet_string(const OSSL_PARAM *p, const void *val,
+                                 size_t len);
+
+ int OSSL_PARAM_get_utf8_ptr(const OSSL_PARAM *p, char **val);
+ int OSSL_PARAM_set_utf8_ptr(const OSSL_PARAM *p, char *val);
+
+ int OSSL_PARAM_get_octet_ptr(const OSSL_PARAM *p, void **val,
+                              size_t *used_len);
+ int OSSL_PARAM_set_octet_ptr(const OSSL_PARAM *p, void *val, size_t used_len);
+
+=head1 DESCRIPTION
+
+A collection of utility functions that simplify and add type safety to the
+OSSL_PARAM arrays.  The following B<TYPE> names are supported:
+
+=over 1
+
+=item *
+
+double
+
+=item *
+
+int
+
+=item *
+
+int32 (int32_t)
+
+=item *
+
+int64 (int64_t)
+
+=item *
+
+long int (long)
+
+=item *
+
+size_t
+
+=item *
+
+uint32 (uint32_t)
+
+=item *
+
+uint64 (uint64_t)
+
+=item *
+
+unsigned int (uint)
+
+=item *
+
+unsigned long int (ulong)
+
+=back
+
+OSSL_PARAM_TYPE() are a series of macros designed to assist initialising an
+array of OSSL_PARAM structures.
+Each of these macros defines a parameter of the specified B<TYPE> with the
+provided B<key> and parameter variable B<address>.
+
+OSSL_PARAM_utf8_string(), OSSL_PARAM_octet_string(), OSSL_PARAM_utf8_ptr(),
+OSSL_PARAM_octet_ptr() are macros that provide support for defining UTF8
+strings and OCTET strings.
+A parameter with name B<key> is defined.
+The storage for this parameter is at B<address> and is of B<size> bytes.
+
+OSSL_PARAM_SIZED_TYPE() are a second series of macros designed to assist with
+the initialisation of OSSL_PARAM structures.
+They are similar to the OSSL_PARAM_TYPE() macros but also include a
+B<return_size> argument which contains the address of a size_t variable which
+will be populated with the actual size of the parameter upon return from a
+OSSL_PARAM_set_TYPE() call.
+
+OSSL_PARAM_SIZED_BN(), OSSL_PARAM_SIZED_utf8_string(),
+OSSL_PARAM_SIZED_octet_string(), OSSL_PARAM_SIZED_utf8_ptr(),
+OSSL_PARAM_SIZED_octet_ptr() are macros that provide support for defining large
+integers, UTF8 string and OCTET strings in an OSSL_PARAM array.
+A parameter with name B<key> is defined.
+The storage for this parameter is at B<address> and is of B<size> bytes.
+The size used by the parameter value, in bytes, is written to B<return_size>.
+
+OSSL_PARAM_END provides an end of parameter list marker.
+This should terminate all OSSL_PARAM arrays.
+
+OSSL_PARAM_construct_TYPE() are a series of functions that create OSSL_PARAM
+records dynamically.
+A parameter with name B<key> is created.
+The parameter will use storage pointed to by B<buf> and return size of B<ret>.
+
+OSSL_PARAM_construct_BN() is a function that constructs a large integer
+OSSL_PARAM structure.
+A parameter with name B<key>, storage B<buf>, size B<bsize> and return
+size B<rsize> is created.
+
+OSSL_PARAM_construct_utf8_string() is a function that constructs a UTF8
+string OSSL_PARAM structure.
+A parameter with name B<key>, storage B<buf>, size B<bsize> and return
+size B<rsize> is created.
+
+OSSL_PARAM_construct_octet_string() is a function that constructs an OCTET
+string OSSL_PARAM structure.
+A parameter with name B<key>, storage B<buf>, size B<bsize> and return
+size B<rsize> is created.
+
+OSSL_PARAM_construct_utf8_ptr() is a function that constructes a UTF string
+pointer OSSL_PARAM structure.
+A parameter with name B<key>, storage pointer B<*buf> and return size B<rsize>
+is created.
+
+OSSL_PARAM_construct_octet_ptr() is a function that constructes an OCTET string
+pointer OSSL_PARAM structure.
+A parameter with name B<key>, storage pointer B<*buf> and return size B<rsize>
+is created.
+
+OSSL_PARAM_locate() is a function that searches an B<array> of parameters for
+the one matching the B<key> name.
+
+OSSL_PARAM_get_TYPE() retrieves a value of type B<TYPE> from the parameter B<p>.
+The value is copied to the address B<val>.
+Type coercion takes place as discussed in the NOTES section.
+
+OSSL_PARAM_set_TYPE() stores a value B<val> of type B<TYPE> into the paramter
+B<p>.
+Type coercion takes place as discussed in the NOTES section.
+
+OSSL_PARAM_get_BN() retrieves a BIGNUM from the parameter pointed to by B<p>.
+The BIGNUM referenced by B<val> is updated and is allocated if B<*val> is
+B<NULL>.
+
+OSSL_PARAM_set_BN() stores the BIGNUM B<val> into the paramater B<p>.
+
+OSSL_PARAM_get_utf8_string() retrieves a UTF8 string from the parameter
+pointed to by B<p>.
+The string is either stored into B<*val> with a length limit of B<max_len> or,
+in the case when B<*val> is B<NULL>, memory is allocated for the string and
+B<max_len> is ignored.
+If memory is allocated by this function, it must be freed by the caller.
+
+OSSL_PARAM_set_utf8_string() sets a UTF8 string from the parameter pointed to
+by B<p> to the value referenced by B<val>.
+
+OSSL_PARAM_get_octet_string() retrieves an OCTET string from the parameter
+pointed to by B<p>.
+The OCTETs are either stored into B<*val> with a length limit of B<max_len> or,
+in the case when B<*val> is B<NULL>, memory is allocated and
+B<max_len> is ignored.
+If memory is allocated by this function, it must be freed by the caller.
+
+OSSL_PARAM_set_octet_string() sets an OCTET string from the parameter
+pointed to by B<p> to the value referenced by B<val>.
+
+OSSL_PARAM_get_utf8_ptr() retrieves the UTF8 string pointer from the parameter
+referenced by B<p> and stores it in B<*val>.
+
+OSSL_PARAM_set_utf8_ptr() sets the UTF8 string pointer in the parameter
+referenced by B<p> to the values B<val>.
+
+OSSL_PARAM_get_octet_ptr() retrieves the OCTET string pointer from the parameter
+referenced by B<p> and stores it in B<*val>.
+The length of the OCTET string is stored in B<*used_len>.
+
+OSSL_PARAM_set_octet_ptr() sets the OCTET string pointer in the parameter
+referenced by B<p> to the values B<val>.
+The length of the OCTET string is provided by B<used_len>.
+
+=head1 RETURN VALUES
+
+OSSL_PARAM_construct_TYPE(), OSSL_PARAM_construct_BN(),
+OSSL_PARAM_construct_utf8_string(), OSSL_PARAM_construct_octet_string(),
+OSSL_PARAM_construct_utf8_ptr() and OSSL_PARAM_construct_octet_ptr()
+return a populated OSSL_PARAM structure.
+
+OSSL_PARAM_locate() returns a pointer to the matching OSSL_PARAM object.
+It returns B<NULL> on error or when no object matching B<key> exists in
+the B<array>.
+
+All other functions return B<1> on success and B<0> on failure.
+
+=head1 NOTES
+
+Integral types will be widened and sign extended as required.
+Apart from that, the functions must be used appropriately for the
+expected type of the parameter.
+
+=head1 EXAMPLES
+
+Reusing the examples from L<OSSL_PARAM(3)> to just show how
+C<OSSL_PARAM> arrays can be handled using the macros and functions
+defined herein.
+
+=head2 Example 1
+
+This example is for setting parameters on some object:
+
+    #include <openssl/core.h>
+
+    const char *foo = "some string";
+    size_t foo_l = strlen(foo) + 1;
+    const char bar[] = "some other string";
+    const OSSL_PARAM set[] = {
+        OSSL_PARAM_utf8_ptr("foo", foo, foo_l),
+        OSSL_PARAM_utf8_string("bar", bar, sizeof(bar)),
+        OSSL_PARAM_END
+    };
+
+=head2 Example 2
+
+This example is for requesting parameters on some object:
+
+    const char *foo = NULL;
+    size_t foo_l;
+    char bar[1024];
+    size_t bar_l;
+    const OSSL_PARAM request[] = {
+        OSSL_PARAM_UTF8_PTR("foo", foo, 0, foo_l),
+        OSSL_PARAM_UTF8_STRING("bar", bar, sizeof(bar), bar_l),
+        OSSL_PARAM_END
+    };
+
+A I<responder> that receives this array (as C<params> in this example)
+could fill in the parameters like this:
+
+    /* const OSSL_PARAM *params */
+
+    OSSL_PARAM_set_utf8_ptr(OSSL_PARAM_locate(params, "foo"), "foo value");
+    OSSL_PARAM_set_utf8_string(OSSL_PARAM_locate(params, "bar"), "bar value");
+
+=head1 SEE ALSO
+
+L<openssl-core.h(7)>, L<OSSL_PARAM(3)>
+
+=head1 HISTORY
+
+These APIs were introduced in OpenSSL 3.0.0.
+
+=head1 COPYRIGHT
+
+Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
+
+Licensed under the Apache License 2.0 (the "License").  You may not use
+this file except in compliance with the License.  You can obtain a copy
+in the file LICENSE in the source distribution or at
+L<https://www.openssl.org/source/license.html>.
+
+=cut
diff --git a/include/openssl/core.h b/include/openssl/core.h
index 15e8843..6edcd99 100644
--- a/include/openssl/core.h
+++ b/include/openssl/core.h
@@ -75,8 +75,8 @@ struct ossl_algorithm_st {
 struct ossl_param_st {
     const char *key;             /* the name of the parameter */
     unsigned int data_type;      /* declare what kind of content is in buffer */
-    void *buffer;                /* value being passed in or out */
-    size_t buffer_size;          /* buffer size */
+    void *data;                  /* value being passed in or out */
+    size_t data_size;            /* data size */
     size_t *return_size;         /* OPTIONAL: address to content size */
 };
 
@@ -111,13 +111,12 @@ struct ossl_param_st {
  * printed as a hexdump.
  */
 # define OSSL_PARAM_OCTET_STRING         5
-
 /*-
- * Pointer flag
+ * OSSL_PARAM_UTF8_PTR
+ * is a pointer to a printable string.  Is expteced to be printed as it is.
  *
- * This flag can be added to any type to signify that the buffer
- * pointer is set to point at a pointer to the data instead of
- * pointing directly at the data.
+ * The difference between this and OSSL_PARAM_UTF8_STRING is that only pointers
+ * are manipulated for this type.
  *
  * This is more relevant for parameter requests, where the responding
  * function doesn't need to copy the data to the provided buffer, but
@@ -126,15 +125,23 @@ struct ossl_param_st {
  * WARNING!  Using these is FRAGILE, as it assumes that the actual
  * data and its location are constant.
  */
-# define OSSL_PARAM_POINTER_FLAG    0x80000000UL
-
-/*
- * Convenience pointer types for strings.
+# define OSSL_PARAM_UTF8_PTR             6
+/*-
+ * OSSL_PARAM_OCTET_PTR
+ * is a pointer to a string of bytes with no further specification.  It is
+ * expected to be printed as a hexdump.
+ *
+ * The difference between this and OSSL_PARAM_OCTET_STRING is that only pointers
+ * are manipulated for this type.
+ *
+ * This is more relevant for parameter requests, where the responding
+ * function doesn't need to copy the data to the provided buffer, but
+ * sets the provided buffer to point at the actual data instead.
+ *
+ * WARNING!  Using these is FRAGILE, as it assumes that the actual
+ * data and its location are constant.
  */
-# define OSSL_PARAM_UTF8_STRING_PTR                     \
-    (OSSL_PARAM_UTF8_STRING|OSSL_PARAM_POINTER_FLAG)
-# define OSSL_PARAM_OCTET_STRING_PTR                    \
-    (OSSL_PARAM_OCTET_STRING|OSSL_PARAM_POINTER_FLAG)
+# define OSSL_PARAM_OCTET_PTR            7
 
 /*-
  * Provider entry point
diff --git a/include/openssl/params.h b/include/openssl/params.h
new file mode 100644
index 0000000..10ed28d
--- /dev/null
+++ b/include/openssl/params.h
@@ -0,0 +1,186 @@
+/*
+ * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright (c) 2019, Oracle and/or its affiliates.  All rights reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#ifndef HEADER_PARAMS_H
+# define HEADER_PARAMS_H
+
+# include <openssl/core.h>
+# include <openssl/bn.h>
+
+# ifdef  __cplusplus
+extern "C" {
+# endif
+
+# define OSSL_PARAM_END \
+    { NULL, 0, NULL, 0, NULL }
+
+# define OSSL_PARAM_DEFN(key, type, addr, sz, rsz)    \
+    { (key), (type), (addr), (sz), (rsz) }
+
+/* Basic parameter types without return sizes */
+# define OSSL_PARAM_int(key, addr) \
+    OSSL_PARAM_DEFN((key), OSSL_PARAM_INTEGER, (addr), sizeof(int), NULL)
+# define OSSL_PARAM_uint(key, addr) \
+    OSSL_PARAM_DEFN((key), OSSL_PARAM_UNSIGNED_INTEGER, (addr), \
+                    sizeof(unsigned int), NULL)
+# define OSSL_PARAM_long(key, addr) \
+    OSSL_PARAM_DEFN((key), OSSL_PARAM_INTEGER, (addr), sizeof(long int), \
+                    NULL)
+# define OSSL_PARAM_ulong(key, addr) \
+    OSSL_PARAM_DEFN((key), OSSL_PARAM_UNSIGNED_INTEGER, (addr), \
+                    sizeof(unsigned long int), NULL)
+# define OSSL_PARAM_int32(key, addr) \
+    OSSL_PARAM_DEFN((key), OSSL_PARAM_INTEGER, (addr), sizeof(int32_t), NULL)
+# define OSSL_PARAM_uint32(key, addr) \
+    OSSL_PARAM_DEFN((key), OSSL_PARAM_UNSIGNED_INTEGER, (addr), \
+                    sizeof(uint32_t), NULL)
+# define OSSL_PARAM_int64(key, addr) \
+    OSSL_PARAM_DEFN((key), OSSL_PARAM_INTEGER, (addr), sizeof(int64_t), NULL)
+# define OSSL_PARAM_uint64(key, addr) \
+    OSSL_PARAM_DEFN((key), OSSL_PARAM_UNSIGNED_INTEGER, (addr), \
+                    sizeof(uint64_t), NULL)
+# define OSSL_PARAM_size_t(key, addr) \
+    OSSL_PARAM_DEFN((key), OSSL_PARAM_UNSIGNED_INTEGER, (addr), sizeof(size_t), \
+               NULL)
+# define OSSL_PARAM_double(key, addr) \
+    OSSL_PARAM_DEFN((key), OSSL_PARAM_REAL, (addr), sizeof(double), NULL)
+
+# define OSSL_PARAM_utf8_string(key, addr, sz) \
+    OSSL_PARAM_DEFN((key), OSSL_PARAM_UTF8_STRING, (addr), sz, NULL)
+# define OSSL_PARAM_octet_string(key, addr, sz) \
+    OSSL_PARAM_DEFN((key), OSSL_PARAM_OCTET_STRING, (addr), sz, NULL)
+
+# define OSSL_PARAM_utf8_ptr(key, addr, sz) \
+    OSSL_PARAM_DEFN((key), OSSL_PARAM_UTF8_PTR, &(addr), sz, NULL)
+# define OSSL_PARAM_octet_ptr(key, addr, sz) \
+    OSSL_PARAM_DEFN((key), OSSL_PARAM_OCTET_PTR, &(addr), sz, NULL)
+
+/* Basic parameter types including return sizes */
+# define OSSL_PARAM_SIZED_int(key, addr, r_sz) \
+    OSSL_PARAM_DEFN((key), OSSL_PARAM_INTEGER, (addr), sizeof(int), &(r_sz))
+# define OSSL_PARAM_SIZED_uint(key, addr, r_sz) \
+    OSSL_PARAM_DEFN((key), OSSL_PARAM_UNSIGNED_INTEGER, (addr), \
+                    sizeof(unsigned int), &(r_sz))
+# define OSSL_PARAM_SIZED_long(key, addr, r_sz) \
+    OSSL_PARAM_DEFN((key), OSSL_PARAM_INTEGER, (addr), sizeof(long int), \
+                    &(r_sz))
+# define OSSL_PARAM_SIZED_ulong(key, addr, r_sz) \
+    OSSL_PARAM_DEFN((key), OSSL_PARAM_UNSIGNED_INTEGER, (addr), \
+                    sizeof(unsigned long int), &(r_sz))
+# define OSSL_PARAM_SIZED_int32(key, addr, r_sz) \
+    OSSL_PARAM_DEFN((key), OSSL_PARAM_INTEGER, (addr), sizeof(int32_t), &(r_sz))
+# define OSSL_PARAM_SIZED_uint32(key, addr, r_sz) \
+    OSSL_PARAM_DEFN((key), OSSL_PARAM_UNSIGNED_INTEGER, (addr), \
+                    sizeof(uint32_t), &(r_sz))
+# define OSSL_PARAM_SIZED_int64(key, addr, r_sz) \
+    OSSL_PARAM_DEFN((key), OSSL_PARAM_INTEGER, (addr), sizeof(int64_t), &(r_sz))
+# define OSSL_PARAM_SIZED_uint64(key, addr, r_sz) \
+    OSSL_PARAM_DEFN((key), OSSL_PARAM_UNSIGNED_INTEGER, (addr), \
+                    sizeof(uint64_t), &(r_sz))
+# define OSSL_PARAM_SIZED_size_t(key, addr, r_sz) \
+    OSSL_PARAM_DEFN((key), OSSL_PARAM_UNSIGNED_INTEGER, (addr), \
+                    sizeof(size_t), &(r_sz))
+# define OSSL_PARAM_SIZED_double(key, addr, r_sz) \
+    OSSL_PARAM_DEFN((key), OSSL_PARAM_REAL, (addr), sizeof(double), &(r_sz))
+
+# define OSSL_PARAM_SIZED_BN(key, addr, sz, r_sz) \
+    OSSL_PARAM_DEFN((key), OSSL_PARAM_UNSIGNED_INTEGER, (addr), sz, \
+                    &(r_sz))
+
+# define OSSL_PARAM_SIZED_utf8_string(key, addr, sz, r_sz) \
+    OSSL_PARAM_DEFN((key), OSSL_PARAM_UTF8_STRING, (addr), sz, &(r_sz))
+# define OSSL_PARAM_SIZED_octet_string(key, addr, sz, r_sz) \
+    OSSL_PARAM_DEFN((key), OSSL_PARAM_OCTET_STRING, (addr), sz, &(r_sz))
+
+# define OSSL_PARAM_SIZED_utf8_ptr(key, addr, sz, r_sz) \
+    OSSL_PARAM_DEFN((key), OSSL_PARAM_UTF8_PTR, &(addr), sz, &(r_sz))
+# define OSSL_PARAM_SIZED_octet_ptr(key, addr, sz, r_sz) \
+    OSSL_PARAM_DEFN((key), OSSL_PARAM_OCTET_PTR, &(addr), sz, &(r_sz))
+
+/* Search an OSSL_PARAM array for a matching name */
+const OSSL_PARAM *OSSL_PARAM_locate(const OSSL_PARAM *p, const char *key);
+
+/* Basic parameter type run-time construction */
+OSSL_PARAM OSSL_PARAM_construct_int(const char *key, int *buf, size_t *ret);
+OSSL_PARAM OSSL_PARAM_construct_uint(const char *key, unsigned int *buf,
+                                     size_t *ret);
+OSSL_PARAM OSSL_PARAM_construct_long(const char *key, long int *buf,
+                                     size_t *ret);
+OSSL_PARAM OSSL_PARAM_construct_ulong(const char *key, unsigned long int *buf,
+                                     size_t *ret);
+OSSL_PARAM OSSL_PARAM_construct_int32(const char *key, int32_t *buf,
+                                      size_t *ret);
+OSSL_PARAM OSSL_PARAM_construct_uint32(const char *key, uint32_t *buf,
+                                      size_t *ret);
+OSSL_PARAM OSSL_PARAM_construct_int64(const char *key, int64_t *buf,
+                                      size_t *ret);
+OSSL_PARAM OSSL_PARAM_construct_uint64(const char *key, uint64_t *buf,
+                                       size_t *ret);
+OSSL_PARAM OSSL_PARAM_construct_size_t(const char *key, size_t *buf,
+                                       size_t *ret);
+OSSL_PARAM OSSL_PARAM_construct_BN(const char *key, unsigned char *buf,
+                                   size_t bsize, size_t *rsize);
+OSSL_PARAM OSSL_PARAM_construct_double(const char *key, double *buf,
+                                       size_t *rsize);
+OSSL_PARAM OSSL_PARAM_construct_utf8_string(const char *key, char *buf,
+                                            size_t bsize, size_t *rsize);
+OSSL_PARAM OSSL_PARAM_construct_utf8_ptr(const char *key, char **buf,
+                                         size_t *rsize);
+OSSL_PARAM OSSL_PARAM_construct_octet_string(const char *key, void *buf,
+                                             size_t bsize, size_t *rsize);
+OSSL_PARAM OSSL_PARAM_construct_octet_ptr(const char *key, void **buf,
+                                          size_t *rsize);
+
+int OSSL_PARAM_get_int(const OSSL_PARAM *p, int *val);
+int OSSL_PARAM_get_uint(const OSSL_PARAM *p, unsigned int *val);
+int OSSL_PARAM_get_long(const OSSL_PARAM *p, long int *val);
+int OSSL_PARAM_get_ulong(const OSSL_PARAM *p, unsigned long int *val);
+int OSSL_PARAM_get_int32(const OSSL_PARAM *p, int32_t *val);
+int OSSL_PARAM_get_uint32(const OSSL_PARAM *p, uint32_t *val);
+int OSSL_PARAM_get_int64(const OSSL_PARAM *p, int64_t *val);
+int OSSL_PARAM_get_uint64(const OSSL_PARAM *p, uint64_t *val);
+int OSSL_PARAM_get_size_t(const OSSL_PARAM *p, size_t *val);
+
+int OSSL_PARAM_set_int(const OSSL_PARAM *p, int val);
+int OSSL_PARAM_set_uint(const OSSL_PARAM *p, unsigned int val);
+int OSSL_PARAM_set_long(const OSSL_PARAM *p, long int val);
+int OSSL_PARAM_set_ulong(const OSSL_PARAM *p, unsigned long int val);
+int OSSL_PARAM_set_int32(const OSSL_PARAM *p, int32_t val);
+int OSSL_PARAM_set_uint32(const OSSL_PARAM *p, uint32_t val);
+int OSSL_PARAM_set_int64(const OSSL_PARAM *p, int64_t val);
+int OSSL_PARAM_set_uint64(const OSSL_PARAM *p, uint64_t val);
+int OSSL_PARAM_set_size_t(const OSSL_PARAM *p, size_t val);
+
+int OSSL_PARAM_get_double(const OSSL_PARAM *p, double *val);
+int OSSL_PARAM_set_double(const OSSL_PARAM *p, double val);
+
+int OSSL_PARAM_get_BN(const OSSL_PARAM *p, BIGNUM **val);
+int OSSL_PARAM_set_BN(const OSSL_PARAM *p, const BIGNUM *val);
+
+int OSSL_PARAM_get_utf8_string(const OSSL_PARAM *p, char **val, size_t max_len);
+int OSSL_PARAM_set_utf8_string(const OSSL_PARAM *p, const char *val);
+
+int OSSL_PARAM_get_octet_string(const OSSL_PARAM *p, void **val, size_t max_len,
+                                size_t *used_len);
+int OSSL_PARAM_set_octet_string(const OSSL_PARAM *p, const void *val,
+                                size_t len);
+
+int OSSL_PARAM_get_utf8_ptr(const OSSL_PARAM *p, const char **val);
+int OSSL_PARAM_set_utf8_ptr(const OSSL_PARAM *p, const char *val);
+
+int OSSL_PARAM_get_octet_ptr(const OSSL_PARAM *p, const void **val,
+                             size_t *used_len);
+int OSSL_PARAM_set_octet_ptr(const OSSL_PARAM *p, const void *val,
+                             size_t used_len);
+
+# ifdef  __cplusplus
+}
+# endif
+#endif
diff --git a/test/build.info b/test/build.info
index 9c721a5..914e5bf 100644
--- a/test/build.info
+++ b/test/build.info
@@ -34,7 +34,7 @@ IF[{- !$disabled{tests} -}]
           bftest ssltest_old dsatest dsa_no_digest_size_test exptest rsa_test \
           evp_test evp_extra_test igetest v3nametest v3ext \
           crltest danetest bad_dtls_test lhash_test sparse_array_test \
-          conf_include_test \
+          conf_include_test params_api_test \
           constant_time_test verify_extra_test clienthellotest \
           packettest asynctest secmemtest srptest memleaktest stack_test \
           dtlsv1listentest ct_test threadstest afalgtest d2i_test \
@@ -307,6 +307,10 @@ IF[{- !$disabled{tests} -}]
   INCLUDE[bioprinttest]=../include ../apps/include
   DEPEND[bioprinttest]=../libcrypto libtestutil.a
 
+  SOURCE[params_api_test]=params_api_test.c
+  INCLUDE[params_api_test]=../include ../apps/include
+  DEPEND[params_api_test]=../libcrypto libtestutil.a
+
   SOURCE[sslapitest]=sslapitest.c ssltestlib.c
   INCLUDE[sslapitest]=../include ../apps/include ..
   DEPEND[sslapitest]=../libcrypto ../libssl libtestutil.a
diff --git a/test/p_test.c b/test/p_test.c
index 6dc0410..9e1ba8e 100644
--- a/test/p_test.c
+++ b/test/p_test.c
@@ -53,9 +53,9 @@ static int p_get_params(const OSSL_PROVIDER *prov, OSSL_PARAM params[])
             static char *opensslv = NULL;
             static char *provname = NULL;
             static OSSL_PARAM counter_request[] = {
-                { "openssl-version", OSSL_PARAM_UTF8_STRING_PTR,
+                { "openssl-version", OSSL_PARAM_UTF8_PTR,
                   &opensslv, sizeof(&opensslv), NULL },
-                { "provider-name", OSSL_PARAM_UTF8_STRING_PTR,
+                { "provider-name", OSSL_PARAM_UTF8_PTR,
                   &provname, sizeof(&provname), NULL},
                 { NULL, 0, NULL, 0, NULL }
             };
@@ -63,8 +63,8 @@ static int p_get_params(const OSSL_PROVIDER *prov, OSSL_PARAM params[])
             size_t buf_l;
 
             if (c_get_params(prov, counter_request)) {
-                const char *versionp = *(void **)counter_request[0].buffer;
-                const char *namep = *(void **)counter_request[1].buffer;
+                const char *versionp = *(void **)counter_request[0].data;
+                const char *namep = *(void **)counter_request[1].data;
                 sprintf(buf, "Hello OpenSSL %.20s, greetings from %s!",
                         versionp, namep);
             } else {
@@ -72,8 +72,8 @@ static int p_get_params(const OSSL_PROVIDER *prov, OSSL_PARAM params[])
             }
 
             *p->return_size = buf_l = strlen(buf) + 1;
-            if (p->buffer_size >= buf_l)
-                strncpy(p->buffer, buf, buf_l);
+            if (p->data_size >= buf_l)
+                strncpy(p->data, buf, buf_l);
             else
                 ok = 0;
         }
diff --git a/test/params_api_test.c b/test/params_api_test.c
new file mode 100644
index 0000000..77b8af4
--- /dev/null
+++ b/test/params_api_test.c
@@ -0,0 +1,627 @@
+/*
+ * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright (c) 2019, Oracle and/or its affiliates.  All rights reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <string.h>
+#include "testutil.h"
+#include "internal/nelem.h"
+#include <openssl/params.h>
+#include <openssl/bn.h>
+
+/* The maximum size of the static buffers used to test most things */
+#define MAX_LEN 20
+
+static void swap_copy(unsigned char *out, const void *in, size_t len)
+{
+    size_t j;
+
+    for (j = 0; j < len; j++)
+        out[j] = ((unsigned char *)in)[len - j - 1];
+}
+
+static void copy_to_le(unsigned char *out, const void *in, size_t len)
+{
+#ifdef B_ENDIAN
+    swap_copy(out, in, len);
+#else
+    memcpy(out, in, len);
+#endif
+}
+
+static void copy_be_to_native(unsigned char *out, const void *in, size_t len)
+{
+#ifdef B_ENDIAN
+    memcpy(out, in, len);
+#else
+    swap_copy(out, in, len);
+#endif
+}
+
+static const struct {
+    size_t len;
+    unsigned char value[MAX_LEN];
+} raw_values[] = {
+    { 4, { 0x38, 0x27, 0xbf, 0x3b } },
+    { 4, { 0x9f, 0x26, 0x48, 0x22 } },
+    { 8, { 0x59, 0xb2, 0x1a, 0xe9, 0x2a, 0xd8, 0x46, 0x40 } },
+    { 8, { 0xb4, 0xae, 0xbd, 0xb4, 0xdd, 0x04, 0xb1, 0x4c } },
+    { 16, { 0x61, 0xe8, 0x7e, 0x31, 0xe9, 0x33, 0x83, 0x3d,
+            0x87, 0x99, 0xc7, 0xd8, 0x5d, 0xa9, 0x8b, 0x42 } },
+    { 16, { 0xee, 0x6e, 0x8b, 0xc3, 0xec, 0xcf, 0x37, 0xcc,
+            0x89, 0x67, 0xf2, 0x68, 0x33, 0xa0, 0x14, 0xb0 } },
+};
+
+static int test_param_type_extra(const OSSL_PARAM *param, unsigned char *cmp,
+                                 size_t width)
+{
+    int32_t i32;
+    int64_t i64;
+    size_t s, sz;
+    unsigned char buf[MAX_LEN];
+    const int bit32 = param->data_size == sizeof(int32_t);
+    const int sizet = bit32 && sizeof(size_t) > sizeof(int32_t);
+    const int signd = param->data_type == OSSL_PARAM_INTEGER;
+
+    if (signd) {
+        if ((bit32 && !TEST_true(OSSL_PARAM_get_int32(param, &i32)))
+            || !TEST_true(OSSL_PARAM_get_int64(param, &i64)))
+            return 0;
+    } else {
+        if ((bit32
+             && !TEST_true(OSSL_PARAM_get_uint32(param, (uint32_t *)&i32)))
+            || !TEST_true(OSSL_PARAM_get_uint64(param, (uint64_t *)&i64))
+            || (sizet && !TEST_true(OSSL_PARAM_get_size_t(param, &s))))
+            return 0;
+    }
+
+    /* Check signed types */
+    if (bit32) {
+        copy_to_le(buf, &i32, sizeof(i32));
+        sz = sizeof(i32) < width ? sizeof(i32) : width;
+        if (!TEST_mem_eq(buf, sz, cmp, sz))
+            return 0;
+    }
+    copy_to_le(buf, &i64, sizeof(i64));
+        sz = sizeof(i64) < width ? sizeof(i64) : width;
+    if (!TEST_mem_eq(buf, sz, cmp, sz))
+        return 0;
+    if (sizet && !signd) {
+        copy_to_le(buf, &s, sizeof(s));
+        sz = sizeof(s) < width ? sizeof(s) : width;
+        if (!TEST_mem_eq(buf, sz, cmp, sz))
+            return 0;
+    }
+
+    /* Check a widening write if possible */
+    if (sizeof(size_t) > width) {
+        if (signd) {
+            if (!TEST_true(OSSL_PARAM_set_int32(param, 12345))
+                || !TEST_true(OSSL_PARAM_get_int64(param, &i64))
+                || !TEST_size_t_eq(i64, 12345))
+                return 0;
+        } else {
+            if (!TEST_true(OSSL_PARAM_set_uint32(param, 12345))
+                || !TEST_true(OSSL_PARAM_get_uint64(param, (uint64_t *)&i64))
+                || !TEST_size_t_eq(i64, 12345))
+                return 0;
+        }
+    }
+    return 1;
+}
+
+/*
+ * The test cases for each of the bastic integral types are similar.
+ * For each type, a param of that type is set and an attempt to read it
+ * get is made.  Finally, the above function is called to verify that
+ * the params can be read as other types.
+ *
+ * All the real work is done via byte buffers which are converted to machine
+ * byte order and to little endian for comparisons.  Narrower values are best
+ * compared using little endian because their values and positions don't
+ * change.
+ */
+
+static int test_param_int(int n)
+{
+    int in, out;
+    unsigned char buf[MAX_LEN], le[MAX_LEN], cmp[sizeof(int)];
+    const size_t len = raw_values[n].len >= sizeof(int) ?
+                       sizeof(int) : raw_values[n].len;
+    OSSL_PARAM param = OSSL_PARAM_int("a", NULL);
+
+    memset(buf, 0, sizeof(buf));
+    memset(le, 0, sizeof(le));
+    copy_be_to_native(buf, raw_values[n].value, len);
+    swap_copy(le, raw_values[n].value, len);
+    memcpy(&in, buf, sizeof(in));
+    param.data = &out;
+    if (!TEST_true(OSSL_PARAM_set_int(&param, in)))
+        return 0;
+    copy_to_le(cmp, &out, sizeof(out));
+    if (!TEST_mem_eq(cmp, len, le, len))
+        return 0;
+    in = 0;
+    param.data = buf;
+    if (!TEST_true(OSSL_PARAM_get_int(&param, &in)))
+        return 0;
+    copy_to_le(cmp, &in, sizeof(in));
+    if (!TEST_mem_eq(cmp, sizeof(in), le, sizeof(in)))
+        return 0;
+    param.data = &out;
+    return test_param_type_extra(&param, le, sizeof(int));
+}
+
+static int test_param_long(int n)
+{
+    long int in, out;
+    unsigned char buf[MAX_LEN], le[MAX_LEN], cmp[sizeof(long int)];
+    const size_t len = raw_values[n].len >= sizeof(long int)
+                       ? sizeof(long int) : raw_values[n].len;
+    OSSL_PARAM param = OSSL_PARAM_long("a", NULL);
+
+    memset(buf, 0, sizeof(buf));
+    memset(le, 0, sizeof(le));
+    copy_be_to_native(buf, raw_values[n].value, len);
+    swap_copy(le, raw_values[n].value, len);
+    memcpy(&in, buf, sizeof(in));
+    param.data = &out;
+    if (!TEST_true(OSSL_PARAM_set_long(&param, in)))
+        return 0;
+    copy_to_le(cmp, &out, sizeof(out));
+    if (!TEST_mem_eq(cmp, len, le, len))
+        return 0;
+    in = 0;
+    param.data = buf;
+    if (!TEST_true(OSSL_PARAM_get_long(&param, &in)))
+        return 0;
+    copy_to_le(cmp, &in, sizeof(in));
+    if (!TEST_mem_eq(cmp, sizeof(in), le, sizeof(in)))
+        return 0;
+    param.data = &out;
+    return test_param_type_extra(&param, le, sizeof(long int));
+}
+
+static int test_param_uint(int n)
+{
+    unsigned int in, out;
+    unsigned char buf[MAX_LEN], le[MAX_LEN], cmp[sizeof(unsigned int)];
+    const size_t len = raw_values[n].len >= sizeof(unsigned int) ? sizeof(unsigned int) : raw_values[n].len;
+    OSSL_PARAM param = OSSL_PARAM_uint("a", NULL);
+    memset(buf, 0, sizeof(buf));
+    memset(le, 0, sizeof(le));
+    copy_be_to_native(buf, raw_values[n].value, len);
+    swap_copy(le, raw_values[n].value, len);
+    memcpy(&in, buf, sizeof(in));
+    param.data = &out;
+    if (!TEST_true(OSSL_PARAM_set_uint(&param, in)))
+        return 0;
+    copy_to_le(cmp, &out, sizeof(out));
+    if (!TEST_mem_eq(cmp, len, le, len))
+        return 0;
+    in = 0;
+    param.data = buf;
+    if (!TEST_true(OSSL_PARAM_get_uint(&param, &in)))
+        return 0;
+    copy_to_le(cmp, &in, sizeof(in));
+    if (!TEST_mem_eq(cmp, sizeof(in), le, sizeof(in)))
+        return 0;
+    param.data = &out;
+    return test_param_type_extra(&param, le, sizeof(unsigned int));
+}
+
+static int test_param_ulong(int n)
+{
+    unsigned long int in, out;
+    unsigned char buf[MAX_LEN], le[MAX_LEN], cmp[sizeof(unsigned long int)];
+    const size_t len = raw_values[n].len >= sizeof(unsigned long int)
+                       ? sizeof(unsigned long int) : raw_values[n].len;
+    OSSL_PARAM param = OSSL_PARAM_ulong("a", NULL);
+    memset(buf, 0, sizeof(buf));
+    memset(le, 0, sizeof(le));
+    copy_be_to_native(buf, raw_values[n].value, len);
+    swap_copy(le, raw_values[n].value, len);
+    memcpy(&in, buf, sizeof(in));
+    param.data = &out;
+    if (!TEST_true(OSSL_PARAM_set_ulong(&param, in)))
+        return 0;
+    copy_to_le(cmp, &out, sizeof(out));
+    if (!TEST_mem_eq(cmp, len, le, len))
+        return 0;
+    in = 0;
+    param.data = buf;
+    if (!TEST_true(OSSL_PARAM_get_ulong(&param, &in)))
+        return 0;
+    copy_to_le(cmp, &in, sizeof(in));
+    if (!TEST_mem_eq(cmp, sizeof(in), le, sizeof(in)))
+        return 0;
+    param.data = &out;
+    return test_param_type_extra(&param, le, sizeof(unsigned long int));
+}
+
+static int test_param_int32(int n)
+{
+    int32_t in, out;
+    unsigned char buf[MAX_LEN], le[MAX_LEN], cmp[sizeof(int32_t)];
+    const size_t len = raw_values[n].len >= sizeof(int32_t)
+                       ? sizeof(int32_t) : raw_values[n].len;
+    OSSL_PARAM param = OSSL_PARAM_int32("a", NULL);
+    memset(buf, 0, sizeof(buf));
+    memset(le, 0, sizeof(le));
+    copy_be_to_native(buf, raw_values[n].value, len);
+    swap_copy(le, raw_values[n].value, len);
+    memcpy(&in, buf, sizeof(in));
+    param.data = &out;
+    if (!TEST_true(OSSL_PARAM_set_int32(&param, in)))
+        return 0;
+    copy_to_le(cmp, &out, sizeof(out));
+    if (!TEST_mem_eq(cmp, len, le, len))
+        return 0;
+    in = 0;
+    param.data = buf;
+    if (!TEST_true(OSSL_PARAM_get_int32(&param, &in)))
+        return 0;
+    copy_to_le(cmp, &in, sizeof(in));
+    if (!TEST_mem_eq(cmp, sizeof(in), le, sizeof(in)))
+        return 0;
+    param.data = &out;
+    return test_param_type_extra(&param, le, sizeof(int32_t));
+}
+
+static int test_param_uint32(int n)
+{
+    uint32_t in, out;
+    unsigned char buf[MAX_LEN], le[MAX_LEN], cmp[sizeof(uint32_t)];
+    const size_t len = raw_values[n].len >= sizeof(uint32_t)
+                       ? sizeof(uint32_t) : raw_values[n].len;
+    OSSL_PARAM param = OSSL_PARAM_uint32("a", NULL);
+    memset(buf, 0, sizeof(buf));
+    memset(le, 0, sizeof(le));
+    copy_be_to_native(buf, raw_values[n].value, len);
+    swap_copy(le, raw_values[n].value, len);
+    memcpy(&in, buf, sizeof(in));
+    param.data = &out;
+    if (!TEST_true(OSSL_PARAM_set_uint32(&param, in)))
+        return 0;
+    copy_to_le(cmp, &out, sizeof(out));
+    if (!TEST_mem_eq(cmp, len, le, len))
+        return 0;
+    in = 0;
+    param.data = buf;
+    if (!TEST_true(OSSL_PARAM_get_uint32(&param, &in)))
+        return 0;
+    copy_to_le(cmp, &in, sizeof(in));
+    if (!TEST_mem_eq(cmp, sizeof(in), le, sizeof(in)))
+        return 0;
+    param.data = &out;
+    return test_param_type_extra(&param, le, sizeof(uint32_t));
+}
+
+static int test_param_int64(int n)
+{
+    int64_t in, out;
+    unsigned char buf[MAX_LEN], le[MAX_LEN], cmp[sizeof(int64_t)];
+    const size_t len = raw_values[n].len >= sizeof(int64_t)
+                       ? sizeof(int64_t) : raw_values[n].len;
+    OSSL_PARAM param = OSSL_PARAM_int64("a", NULL);
+    memset(buf, 0, sizeof(buf));
+    memset(le, 0, sizeof(le));
+    copy_be_to_native(buf, raw_values[n].value, len);
+    swap_copy(le, raw_values[n].value, len);
+    memcpy(&in, buf, sizeof(in));
+    param.data = &out;
+    if (!TEST_true(OSSL_PARAM_set_int64(&param, in)))
+        return 0;
+    copy_to_le(cmp, &out, sizeof(out));
+    if (!TEST_mem_eq(cmp, len, le, len))
+        return 0;
+    in = 0;
+    param.data = buf;
+    if (!TEST_true(OSSL_PARAM_get_int64(&param, &in)))
+        return 0;
+    copy_to_le(cmp, &in, sizeof(in));
+    if (!TEST_mem_eq(cmp, sizeof(in), le, sizeof(in)))
+        return 0;
+    param.data = &out;
+    return test_param_type_extra(&param, le, sizeof(int64_t));
+}
+
+static int test_param_uint64(int n)
+{
+    uint64_t in, out;
+    unsigned char buf[MAX_LEN], le[MAX_LEN], cmp[sizeof(uint64_t)];
+    const size_t len = raw_values[n].len >= sizeof(uint64_t)
+                       ? sizeof(uint64_t) : raw_values[n].len;
+    OSSL_PARAM param = OSSL_PARAM_uint64("a", NULL);
+    memset(buf, 0, sizeof(buf));
+    memset(le, 0, sizeof(le));
+    copy_be_to_native(buf, raw_values[n].value, len);
+    swap_copy(le, raw_values[n].value, len);
+    memcpy(&in, buf, sizeof(in));
+    param.data = &out;
+    if (!TEST_true(OSSL_PARAM_set_uint64(&param, in)))
+        return 0;
+    copy_to_le(cmp, &out, sizeof(out));
+    if (!TEST_mem_eq(cmp, len, le, len))
+        return 0;
+    in = 0;
+    param.data = buf;
+    if (!TEST_true(OSSL_PARAM_get_uint64(&param, &in)))
+        return 0;
+    copy_to_le(cmp, &in, sizeof(in));
+    if (!TEST_mem_eq(cmp, sizeof(in), le, sizeof(in)))
+        return 0;
+    param.data = &out;
+    return test_param_type_extra(&param, le, sizeof(uint64_t));
+}
+
+static int test_param_size_t(int n)
+{
+    size_t in, out;
+    unsigned char buf[MAX_LEN], le[MAX_LEN], cmp[sizeof(size_t)];
+    const size_t len = raw_values[n].len >= sizeof(size_t)
+                       ? sizeof(size_t) : raw_values[n].len;
+    OSSL_PARAM param = OSSL_PARAM_size_t("a", NULL);
+    memset(buf, 0, sizeof(buf));
+    memset(le, 0, sizeof(le));
+    copy_be_to_native(buf, raw_values[n].value, len);
+    swap_copy(le, raw_values[n].value, len);
+    memcpy(&in, buf, sizeof(in));
+    param.data = &out;
+    if (!TEST_true(OSSL_PARAM_set_size_t(&param, in)))
+        return 0;
+    copy_to_le(cmp, &out, sizeof(out));
+    if (!TEST_mem_eq(cmp, len, le, len))
+        return 0;
+    in = 0;
+    param.data = buf;
+    if (!TEST_true(OSSL_PARAM_get_size_t(&param, &in)))
+        return 0;
+    copy_to_le(cmp, &in, sizeof(in));
+    if (!TEST_mem_eq(cmp, sizeof(in), le, sizeof(in)))
+        return 0;
+    param.data = &out;
+    return test_param_type_extra(&param, le, sizeof(size_t));
+}
+
+static int test_param_bignum(int n)
+{
+    unsigned char buf[MAX_LEN], bnbuf[MAX_LEN], le[MAX_LEN];
+    const size_t len = raw_values[n].len;
+    size_t bnsize;
+    BIGNUM *b = NULL, *c = NULL;
+    OSSL_PARAM param = OSSL_PARAM_DEFN("bn", OSSL_PARAM_UNSIGNED_INTEGER,
+                                       NULL, 0, NULL);
+    int ret = 0;
+
+    param.data = bnbuf;
+    param.data_size = len;
+    param.return_size = &bnsize;
+
+    copy_be_to_native(buf, raw_values[n].value, len);
+    swap_copy(le, raw_values[n].value, len);
+    if (!TEST_ptr(b = BN_bin2bn(raw_values[n].value, (int)len, NULL)))
+        goto err;
+
+    if (!TEST_true(OSSL_PARAM_set_BN(&param, b))
+        || !TEST_mem_eq(bnbuf, bnsize, buf, bnsize))
+        goto err;
+    param.data_size = *param.return_size;
+    if (!TEST_true(OSSL_PARAM_get_BN(&param, &c))
+        || !TEST_BN_eq(b, c))
+        goto err;
+
+    ret = 1;
+err:
+    BN_free(b);
+    BN_free(c);
+    return ret;
+}
+
+static int test_param_real(void)
+{
+    double p;
+    OSSL_PARAM param = OSSL_PARAM_double("r", NULL);
+
+    param.data = &p;
+    return TEST_true(OSSL_PARAM_set_double(&param, 3.14159))
+           && TEST_double_eq(p, 3.14159);
+}
+
+/*
+ * The tests are a bit special in that they are trying to do both sides
+ * of the param passing.  This means that the OSSL_PARAM structure needs to
+ * be updated so that a get call matches size with the corresponding set call.
+ * This is not a problem in normal usage because the owner of the OSSL_PARAM
+ * "knows" the size of what it wants to put in and gets the size back via the
+ * return_size pointer when it needs to get data out.  That is, the owner
+ * does not need to call these APIs since it has direct access.
+ *
+ * The result is that the tests need the locate call to return a non-const
+ * pointer at times.  Hence the cast here.
+ */
+static OSSL_PARAM *locate(OSSL_PARAM *p, const char *name)
+{
+    return (OSSL_PARAM *)OSSL_PARAM_locate(p, name);
+}
+
+static int test_param_construct(void)
+{
+    static const char *int_names[] = {
+        "int", "long", "int32", "int64"
+    };
+    static const char *uint_names[] = {
+        "uint", "ulong", "uint32", "uint64", "size_t"
+    };
+    static const unsigned char bn_val[16] = {
+        0xac, 0x75, 0x22, 0x7d, 0x81, 0x06, 0x7a, 0x23,
+        0xa6, 0xed, 0x87, 0xc7, 0xab, 0xf4, 0x73, 0x22
+    };
+    OSSL_PARAM params[20];
+    char buf[100], buf2[100], *bufp, *bufp2;
+    unsigned char ubuf[100];
+    void *vp, *vp2;
+    OSSL_PARAM *p;
+    const OSSL_PARAM *cp;
+    static const OSSL_PARAM pend = OSSL_PARAM_END;
+    int i, n = 0, ret = 0;
+    unsigned int u;
+    long int l;
+    unsigned long int ul;
+    int32_t i32;
+    uint32_t u32;
+    int64_t i64;
+    uint64_t u64;
+    size_t j, k, s, sz;
+    double d, d2;
+    BIGNUM *bn = NULL, *bn2 = NULL;
+
+    params[n++] = OSSL_PARAM_construct_int("int", &i, &sz);
+    params[n++] = OSSL_PARAM_construct_uint("uint", &u, &sz);
+    params[n++] = OSSL_PARAM_construct_long("long", &l, &sz);
+    params[n++] = OSSL_PARAM_construct_ulong("ulong", &ul, &sz);
+    params[n++] = OSSL_PARAM_construct_int32("int32", &i32, &sz);
+    params[n++] = OSSL_PARAM_construct_int64("int64", &i64, &sz);
+    params[n++] = OSSL_PARAM_construct_uint32("uint32", &u32, &sz);
+    params[n++] = OSSL_PARAM_construct_uint64("uint64", &u64, &sz);
+    params[n++] = OSSL_PARAM_construct_size_t("size_t", &s, &sz);
+    params[n++] = OSSL_PARAM_construct_double("double", &d, &sz);
+    params[n++] = OSSL_PARAM_construct_BN("bignum", ubuf, sizeof(ubuf), &sz);
+    params[n++] = OSSL_PARAM_construct_utf8_string("utf8str", buf, sizeof(buf),
+                                                   &sz);
+    params[n++] = OSSL_PARAM_construct_octet_string("octstr", buf, sizeof(buf),
+                                                    &sz);
+    params[n++] = OSSL_PARAM_construct_utf8_ptr("utf8ptr", &bufp, &sz);
+    params[n++] = OSSL_PARAM_construct_octet_ptr("octptr", &vp, &sz);
+    params[n] = pend;
+
+    /* Search failure */
+    if (!TEST_ptr_null(OSSL_PARAM_locate(params, "fnord")))
+        goto err;
+
+    /* All signed integral types */
+    for (j = 0; j < OSSL_NELEM(int_names); j++) {
+        if (!TEST_ptr(cp = OSSL_PARAM_locate(params, int_names[j]))
+            || !TEST_true(OSSL_PARAM_set_int32(cp, (int32_t)(3 + j)))
+            || !TEST_true(OSSL_PARAM_get_int64(cp, &i64))
+            || !TEST_size_t_eq(cp->data_size, sz)
+            || !TEST_size_t_eq((size_t)i64, 3 + j)) {
+            TEST_note("iteration %zu var %s", j + 1, int_names[j]);
+            goto err;
+        }
+    }
+    /* All unsigned integral types */
+    for (j = 0; j < OSSL_NELEM(uint_names); j++) {
+        if (!TEST_ptr(cp = OSSL_PARAM_locate(params, uint_names[j]))
+            || !TEST_true(OSSL_PARAM_set_uint32(cp, (uint32_t)(3 + j)))
+            || !TEST_true(OSSL_PARAM_get_uint64(cp, &u64))
+            || !TEST_size_t_eq(cp->data_size, sz)
+            || !TEST_size_t_eq((size_t)u64, 3 + j)) {
+            TEST_note("iteration %zu var %s", j + 1, uint_names[j]);
+            goto err;
+        }
+    }
+    /* Real */
+    if (!TEST_ptr(cp = OSSL_PARAM_locate(params, "double"))
+        || !TEST_true(OSSL_PARAM_set_double(cp, 3.14))
+        || !TEST_true(OSSL_PARAM_get_double(cp, &d2))
+        || !TEST_size_t_eq(sz, sizeof(double))
+        || !TEST_double_eq(d, d2))
+        goto err;
+    /* UTF8 string */
+    bufp = NULL;
+    if (!TEST_ptr(cp = OSSL_PARAM_locate(params, "utf8str"))
+        || !TEST_true(OSSL_PARAM_set_utf8_string(cp, "abcdef"))
+        || !TEST_size_t_eq(sz, sizeof("abcdef"))
+        || !TEST_true(OSSL_PARAM_get_utf8_string(cp, &bufp, 0))
+        || !TEST_str_eq(bufp, "abcdef"))
+        goto err;
+    OPENSSL_free(bufp);
+    bufp = buf2;
+    if (!TEST_true(OSSL_PARAM_get_utf8_string(cp, &bufp, sizeof(buf2)))
+        || !TEST_str_eq(buf2, "abcdef"))
+        goto err;
+    /* UTF8 pointer */
+    bufp = buf;
+    sz = 0;
+    if (!TEST_ptr(cp = OSSL_PARAM_locate(params, "utf8ptr"))
+        || !TEST_true(OSSL_PARAM_set_utf8_ptr(cp, "tuvwxyz"))
+        || !TEST_size_t_eq(sz, sizeof("tuvwxyz"))
+        || !TEST_str_eq(bufp, "tuvwxyz")
+        || !TEST_true(OSSL_PARAM_get_utf8_ptr(cp, (const char **)&bufp2))
+        || !TEST_ptr_eq(bufp2, bufp))
+        goto err;
+    /* OCTET string */
+    vp = NULL;
+    if (!TEST_ptr(p = locate(params, "octstr"))
+        || !TEST_true(OSSL_PARAM_set_octet_string(p, "abcdefghi",
+                                                  sizeof("abcdefghi")))
+        || !TEST_size_t_eq(sz, sizeof("abcdefghi")))
+        goto err;
+    /* Match the return size to avoid trailing garbage bytes */
+    p->data_size = *p->return_size;
+    if (!TEST_true(OSSL_PARAM_get_octet_string(p, &vp, 0, &s))
+        || !TEST_size_t_eq(s, sizeof("abcdefghi"))
+        || !TEST_mem_eq(vp, sizeof("abcdefghi"),
+                        "abcdefghi", sizeof("abcdefghi")))
+        goto err;
+    OPENSSL_free(vp);
+    vp = buf2;
+    if (!TEST_true(OSSL_PARAM_get_octet_string(p, &vp, sizeof(buf2), &s))
+        || !TEST_size_t_eq(s, sizeof("abcdefghi"))
+        || !TEST_mem_eq(vp, sizeof("abcdefghi"),
+                        "abcdefghi", sizeof("abcdefghi")))
+        goto err;
+    /* OCTET pointer */
+    vp = &l;
+    sz = 0;
+    if (!TEST_ptr(p = locate(params, "octptr"))
+        || !TEST_true(OSSL_PARAM_set_octet_ptr(p, &ul, sizeof(ul)))
+        || !TEST_size_t_eq(sz, sizeof(ul))
+        || !TEST_ptr_eq(vp, &ul))
+        goto err;
+    /* Match the return size to avoid trailing garbage bytes */
+    p->data_size = *p->return_size;
+    if (!TEST_true(OSSL_PARAM_get_octet_ptr(p, (const void **)&vp2, &k))
+        || !TEST_size_t_eq(k, sizeof(ul))
+        || !TEST_ptr_eq(vp2, vp))
+        goto err;
+    /* BIGNUM */
+    if (!TEST_ptr(p = locate(params, "bignum"))
+        || !TEST_ptr(bn = BN_lebin2bn(bn_val, (int)sizeof(bn_val), NULL))
+        || !TEST_true(OSSL_PARAM_set_BN(p, bn))
+        || !TEST_size_t_eq(sz, sizeof(bn_val)))
+        goto err;
+    /* Match the return size to avoid trailing garbage bytes */
+    p->data_size = *p->return_size;
+    if(!TEST_true(OSSL_PARAM_get_BN(p, &bn2))
+        || !TEST_BN_eq(bn, bn2))
+        goto err;
+    ret = 1;
+err:
+    BN_free(bn);
+    BN_free(bn2);
+    return ret;
+}
+
+int setup_tests(void)
+{
+    ADD_ALL_TESTS(test_param_int, OSSL_NELEM(raw_values));
+    ADD_ALL_TESTS(test_param_long, OSSL_NELEM(raw_values));
+    ADD_ALL_TESTS(test_param_uint, OSSL_NELEM(raw_values));
+    ADD_ALL_TESTS(test_param_ulong, OSSL_NELEM(raw_values));
+    ADD_ALL_TESTS(test_param_int32, OSSL_NELEM(raw_values));
+    ADD_ALL_TESTS(test_param_uint32, OSSL_NELEM(raw_values));
+    ADD_ALL_TESTS(test_param_size_t, OSSL_NELEM(raw_values));
+    ADD_ALL_TESTS(test_param_int64, OSSL_NELEM(raw_values));
+    ADD_ALL_TESTS(test_param_uint64, OSSL_NELEM(raw_values));
+    ADD_ALL_TESTS(test_param_bignum, OSSL_NELEM(raw_values));
+    ADD_TEST(test_param_real);
+    ADD_TEST(test_param_construct);
+    return 1;
+}
diff --git a/test/provider_internal_test.c b/test/provider_internal_test.c
index c423808..8ce382e 100644
--- a/test/provider_internal_test.c
+++ b/test/provider_internal_test.c
@@ -37,8 +37,8 @@ static int test_provider(OSSL_PROVIDER *prov)
     ret =
         TEST_true(ossl_provider_activate(prov))
         && TEST_true(ossl_provider_get_params(prov, greeting_request))
-        && TEST_ptr(greeting = greeting_request[0].buffer)
-        && TEST_size_t_gt(greeting_request[0].buffer_size, 0)
+        && TEST_ptr(greeting = greeting_request[0].data)
+        && TEST_size_t_gt(greeting_request[0].data_size, 0)
         && TEST_str_eq(greeting, expected_greeting);
 
     ossl_provider_free(prov);
diff --git a/test/provider_test.c b/test/provider_test.c
index 738cd7b..250eea3 100644
--- a/test/provider_test.c
+++ b/test/provider_test.c
@@ -33,8 +33,8 @@ static int test_provider(const char *name)
     return
         TEST_ptr(prov = OSSL_PROVIDER_load(NULL, name))
         && TEST_true(OSSL_PROVIDER_get_params(prov, greeting_request))
-        && TEST_ptr(greeting = greeting_request[0].buffer)
-        && TEST_size_t_gt(greeting_request[0].buffer_size, 0)
+        && TEST_ptr(greeting = greeting_request[0].data)
+        && TEST_size_t_gt(greeting_request[0].data_size, 0)
         && TEST_str_eq(greeting, expected_greeting)
         && TEST_true(OSSL_PROVIDER_unload(prov));
 }
diff --git a/test/recipes/03-test_property.t b/test/recipes/03-test_params_api.t
similarity index 89%
copy from test/recipes/03-test_property.t
copy to test/recipes/03-test_params_api.t
index 2654215..9e821c9 100644
--- a/test/recipes/03-test_property.t
+++ b/test/recipes/03-test_params_api.t
@@ -9,4 +9,4 @@
 
 use OpenSSL::Test::Simple;
 
-simple_test("test_property", "property_test");
+simple_test("test_params_api", "params_api_test");
diff --git a/test/testutil.h b/test/testutil.h
index ec2f532..7f5db60 100644
--- a/test/testutil.h
+++ b/test/testutil.h
@@ -255,7 +255,9 @@ DECLARE_COMPARISONS(char, char)
 DECLARE_COMPARISONS(unsigned char, uchar)
 DECLARE_COMPARISONS(long, long)
 DECLARE_COMPARISONS(unsigned long, ulong)
+DECLARE_COMPARISONS(double, double)
 DECLARE_COMPARISONS(time_t, time_t)
+
 /*
  * Because this comparison uses a printf format specifier that's not
  * universally known (yet), we provide an option to not have it declared.
@@ -406,6 +408,13 @@ void test_perror(const char *s);
 # define TEST_size_t_gt(a, b) test_size_t_gt(__FILE__, __LINE__, #a, #b, a, b)
 # define TEST_size_t_ge(a, b) test_size_t_ge(__FILE__, __LINE__, #a, #b, a, b)
 
+# define TEST_double_eq(a, b) test_double_eq(__FILE__, __LINE__, #a, #b, a, b)
+# define TEST_double_ne(a, b) test_double_ne(__FILE__, __LINE__, #a, #b, a, b)
+# define TEST_double_lt(a, b) test_double_lt(__FILE__, __LINE__, #a, #b, a, b)
+# define TEST_double_le(a, b) test_double_le(__FILE__, __LINE__, #a, #b, a, b)
+# define TEST_double_gt(a, b) test_double_gt(__FILE__, __LINE__, #a, #b, a, b)
+# define TEST_double_ge(a, b) test_double_ge(__FILE__, __LINE__, #a, #b, a, b)
+
 # define TEST_time_t_eq(a, b) test_time_t_eq(__FILE__, __LINE__, #a, #b, a, b)
 # define TEST_time_t_ne(a, b) test_time_t_ne(__FILE__, __LINE__, #a, #b, a, b)
 # define TEST_time_t_lt(a, b) test_time_t_lt(__FILE__, __LINE__, #a, #b, a, b)
diff --git a/test/testutil/tests.c b/test/testutil/tests.c
index 2ba5b9a..05b0688 100644
--- a/test/testutil/tests.c
+++ b/test/testutil/tests.c
@@ -213,6 +213,7 @@ DEFINE_COMPARISONS(unsigned char, uchar, "%u")
 DEFINE_COMPARISONS(long, long, "%ld")
 DEFINE_COMPARISONS(unsigned long, ulong, "%lu")
 DEFINE_COMPARISONS(size_t, size_t, "%zu")
+DEFINE_COMPARISONS(double, double, "%g")
 
 DEFINE_COMPARISON(void *, ptr, eq, ==, "%p")
 DEFINE_COMPARISON(void *, ptr, ne, !=, "%p")
diff --git a/util/libcrypto.num b/util/libcrypto.num
index 974d918..df59f29 100644
--- a/util/libcrypto.num
+++ b/util/libcrypto.num
@@ -4742,3 +4742,49 @@ OSSL_CRMF_CERTTEMPLATE_get0_issuer      4689	3_0_0	EXIST::FUNCTION:CMP
 OSSL_CRMF_CERTTEMPLATE_fill             4690	3_0_0	EXIST::FUNCTION:CMP
 OSSL_CRMF_ENCRYPTEDVALUE_get1_encCert   4691	3_0_0	EXIST::FUNCTION:CMP
 ERR_load_CRMF_strings                   4692	3_0_0	EXIST::FUNCTION:CMP
+OSSL_PARAM_locate                       4693	3_0_0	EXIST::FUNCTION:
+OSSL_PARAM_construct_int                4694	3_0_0	EXIST::FUNCTION:
+OSSL_PARAM_construct_uint               4695	3_0_0	EXIST::FUNCTION:
+OSSL_PARAM_construct_long               4696	3_0_0	EXIST::FUNCTION:
+OSSL_PARAM_construct_ulong              4697	3_0_0	EXIST::FUNCTION:
+OSSL_PARAM_construct_int32              4698	3_0_0	EXIST::FUNCTION:
+OSSL_PARAM_construct_uint32             4699	3_0_0	EXIST::FUNCTION:
+OSSL_PARAM_construct_int64              4700	3_0_0	EXIST::FUNCTION:
+OSSL_PARAM_construct_uint64             4701	3_0_0	EXIST::FUNCTION:
+OSSL_PARAM_construct_size_t             4702	3_0_0	EXIST::FUNCTION:
+OSSL_PARAM_construct_BN                 4703	3_0_0	EXIST::FUNCTION:
+OSSL_PARAM_construct_double             4704	3_0_0	EXIST::FUNCTION:
+OSSL_PARAM_construct_utf8_string        4705	3_0_0	EXIST::FUNCTION:
+OSSL_PARAM_construct_utf8_ptr           4706	3_0_0	EXIST::FUNCTION:
+OSSL_PARAM_construct_octet_string       4707	3_0_0	EXIST::FUNCTION:
+OSSL_PARAM_construct_octet_ptr          4708	3_0_0	EXIST::FUNCTION:
+OSSL_PARAM_get_int                      4709	3_0_0	EXIST::FUNCTION:
+OSSL_PARAM_get_uint                     4710	3_0_0	EXIST::FUNCTION:
+OSSL_PARAM_get_long                     4711	3_0_0	EXIST::FUNCTION:
+OSSL_PARAM_get_ulong                    4712	3_0_0	EXIST::FUNCTION:
+OSSL_PARAM_get_int32                    4713	3_0_0	EXIST::FUNCTION:
+OSSL_PARAM_get_uint32                   4714	3_0_0	EXIST::FUNCTION:
+OSSL_PARAM_get_int64                    4715	3_0_0	EXIST::FUNCTION:
+OSSL_PARAM_get_uint64                   4716	3_0_0	EXIST::FUNCTION:
+OSSL_PARAM_get_size_t                   4717	3_0_0	EXIST::FUNCTION:
+OSSL_PARAM_set_int                      4718	3_0_0	EXIST::FUNCTION:
+OSSL_PARAM_set_uint                     4719	3_0_0	EXIST::FUNCTION:
+OSSL_PARAM_set_long                     4720	3_0_0	EXIST::FUNCTION:
+OSSL_PARAM_set_ulong                    4721	3_0_0	EXIST::FUNCTION:
+OSSL_PARAM_set_int32                    4722	3_0_0	EXIST::FUNCTION:
+OSSL_PARAM_set_uint32                   4723	3_0_0	EXIST::FUNCTION:
+OSSL_PARAM_set_int64                    4724	3_0_0	EXIST::FUNCTION:
+OSSL_PARAM_set_uint64                   4725	3_0_0	EXIST::FUNCTION:
+OSSL_PARAM_set_size_t                   4726	3_0_0	EXIST::FUNCTION:
+OSSL_PARAM_get_double                   4727	3_0_0	EXIST::FUNCTION:
+OSSL_PARAM_set_double                   4728	3_0_0	EXIST::FUNCTION:
+OSSL_PARAM_get_BN                       4729	3_0_0	EXIST::FUNCTION:
+OSSL_PARAM_set_BN                       4730	3_0_0	EXIST::FUNCTION:
+OSSL_PARAM_get_utf8_string              4731	3_0_0	EXIST::FUNCTION:
+OSSL_PARAM_set_utf8_string              4732	3_0_0	EXIST::FUNCTION:
+OSSL_PARAM_get_octet_string             4733	3_0_0	EXIST::FUNCTION:
+OSSL_PARAM_set_octet_string             4734	3_0_0	EXIST::FUNCTION:
+OSSL_PARAM_get_utf8_ptr                 4735	3_0_0	EXIST::FUNCTION:
+OSSL_PARAM_set_utf8_ptr                 4736	3_0_0	EXIST::FUNCTION:
+OSSL_PARAM_get_octet_ptr                4737	3_0_0	EXIST::FUNCTION:
+OSSL_PARAM_set_octet_ptr                4738	3_0_0	EXIST::FUNCTION:
diff --git a/util/private.num b/util/private.num
index cb1997a..1fbc160 100644
--- a/util/private.num
+++ b/util/private.num
@@ -323,6 +323,21 @@ OpenSSL_add_all_algorithms              define deprecated 1.1.0
 OpenSSL_add_all_ciphers                 define deprecated 1.1.0
 OpenSSL_add_all_digests                 define deprecated 1.1.0
 OpenSSL_add_ssl_algorithms              define
+OSSL_PARAM_utf8_ptr                     define
+OSSL_PARAM_SIZED_BN                     define
+OSSL_PARAM_TYPE                         generic
+OSSL_PARAM_construct_TYPE               generic
+OSSL_PARAM_octet_string                 define
+OSSL_PARAM_SIZED_octet_ptr              define
+OSSL_PARAM_utf8_string                  define
+OSSL_PARAM_octet_ptr                    define
+OSSL_PARAM_SIZED_utf8_ptr               define
+OSSL_PARAM_SIZED_utf8_string            define
+OSSL_PARAM_SIZED_TYPE                   generic
+OSSL_PARAM_get_TYPE                     generic
+OSSL_PARAM_END                          define
+OSSL_PARAM_set_TYPE                     generic
+OSSL_PARAM_SIZED_octet_string           define
 PEM_FLAG_EAY_COMPATIBLE                 define
 PEM_FLAG_ONLY_B64                       define
 PEM_FLAG_SECURE                         define


More information about the openssl-commits mailing list