/*
* Copyright 2019-2021 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 "internal/endian.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];
}
/*
* A memory copy that converts the native byte ordering either to or from
* little endian format.
*
* On a little endian machine copying either is just a memcpy(3), on a
* big endian machine copying from native to or from little endian involves
* byte reversal.
*/
static void le_copy(unsigned char *out, size_t outlen,
const void *in, size_t inlen)
{
DECLARE_IS_ENDIAN;
if (IS_LITTLE_ENDIAN) {
memcpy(out, in, outlen);
} else {
if (outlen < inlen)
in = (const char *)in + inlen - outlen;
swap_copy(out, in, outlen);
}
}
static const struct {
size_t len;
unsigned char value[MAX_LEN];
} raw_values[] = {
{ 1, { 0x47 } },
{ 1, { 0xd0 } },
{ 2, { 0x01, 0xe9 } },
{ 2, { 0xff, 0x53 } },
{ 3, { 0x16, 0xff, 0x7c } },
{ 3, { 0xa8, 0x9c, 0x0e } },
{ 4, { 0x38, 0x27, 0xbf, 0x3b } },
{ 4, { 0x9f, 0x26, 0x48, 0x22 } },
{ 5, { 0x30, 0x65, 0xfa, 0xe4, 0x81 } },
{ 5, { 0xd1, 0x76, 0x01, 0x1b, 0xcd } },
{ 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(OSSL_PARAM *param, const 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 = param->data_size <= sizeof(size_t);
const int signd = param->data_type == OSSL_PARAM_INTEGER;
/*
* Set the unmodified sentinel directly because there is no param array
* for these tests.
*/
param->return_size = OSSL_PARAM_UNMODIFIED;
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;
}
if (!TEST_false(OSSL_PARAM_modified(param)))
return 0;
/* Check signed types */
if (bit32) {
le_copy(buf, sizeof(i32), &i32, sizeof(i32));
sz = sizeof(i32) < width ? sizeof(i32) : width;
if (!TEST_mem_eq(buf, sz, cmp, sz))
return 0;
}
le_copy(buf, sizeof(i64), &i64, sizeof(i64));
sz = sizeof(i64) < width ? sizeof(i64) : width;
if (!TEST_mem_eq(buf, sz, cmp, sz))
return 0;
if (sizet && !signd) {
le_copy(buf, sizeof(s), &s, sizeof(s));
sz = sizeof(s) < width ? sizeof(s) : width;
if (!TEST_mem_eq(buf, sz, cmp, sz))
return