psasim: add the ability to serialise psa_key_production_parameters_t
Signed-off-by: Tom Cosgrove <tom.cosgrove@arm.com>
diff --git a/tests/psa-client-server/psasim/src/psa_sim_generate.pl b/tests/psa-client-server/psasim/src/psa_sim_generate.pl
index 7659215..97e92bc 100755
--- a/tests/psa-client-server/psasim/src/psa_sim_generate.pl
+++ b/tests/psa-client-server/psasim/src/psa_sim_generate.pl
@@ -548,6 +548,13 @@
size_t $n2;
EOF
push(@buffers, $n1); # Add to the list to be free()d at end
+ } elsif ($argtype =~ /^(const )?psa_key_production_parameters_t$/) {
+ my ($n1, $n2) = split(/,\s*/, $argname);
+ print $fh <<EOF;
+ psa_key_production_parameters_t *$n1 = NULL;
+ size_t $n2;
+EOF
+ push(@buffers, $n1); # Add to the list to be free()d at end
} else {
$argname =~ s/^\*//; # Remove any leading *
my $pointer = ($argtype =~ /^psa_\w+_operation_t/) ? "*" : "";
@@ -601,6 +608,15 @@
goto fail;
}
EOF
+ } elsif ($argtype =~ /^(const )?psa_key_production_parameters_t$/) {
+ my ($n1, $n2) = split(/,\s*/, $argname);
+ print $fh <<EOF;
+
+ ok = psasim_deserialise_${argtype}(&pos, &remaining, &$n1, &$n2);
+ if (!ok) {
+ goto fail;
+ }
+EOF
} else {
$argname =~ s/^\*//; # Remove any leading *
my $server_specific = ($argtype =~ /^psa_\w+_operation_t/) ? "server_" : "";
@@ -697,6 +713,14 @@
goto fail;
}
EOF
+ } elsif ($argtype eq "psa_key_production_parameters_t") {
+ print $fh <<EOF;
+
+ ok = psasim_serialise_psa_key_production_parameters_t(&rpos, &rremain, $argname);
+ if (!ok) {
+ goto fail;
+ }
+EOF
} else {
if ($argname =~ /^\*/) {
$argname =~ s/^\*//; # since it's already a pointer
@@ -931,6 +955,9 @@
if ($argtype =~ /^(const )?buffer$/) {
my ($n1, $n2) = split(/,\s*/, $argname);
print $fh " $n1, $n2";
+ } elsif ($argtype =~ /^(const )?psa_key_production_parameters_t$/) {
+ my ($n1, $n2) = split(/,\s*/, $argname);
+ print $fh " $n1, $n2";
} else {
$argname =~ s/^\*/\&/; # Replace leading * with &
if ($is_server && $argtype =~ /^psa_\w+_operation_t/) {
@@ -966,6 +993,10 @@
my $const = length($1) ? "const " : "";
my ($n1, $n2) = split(/,/, $argname);
print $fh " ${const}uint8_t *$n1, size_t $n2";
+ } elsif ($argtype =~ /^(const )?psa_key_production_parameters_t$/) {
+ my $const = length($1) ? "const " : "";
+ my ($n1, $n2) = split(/,/, $argname);
+ print $fh " ${const}psa_key_production_parameters_t *$n1, size_t $n2";
} else {
print $fh " $ctypename$argname";
}
@@ -1056,6 +1087,19 @@
$i++; # We're using the next param here
my $nname = $1;
$name .= ", " . $nname;
+ } elsif ($arg =~ /^((const)\s+)?psa_key_production_parameters_t\s*\*\s*(\w+)$/) {
+ $type = "psa_key_production_parameters_t";
+ $is_output = (length($1) == 0) ? 1 : 0;
+ $type = "const psa_key_production_parameters_t" if !$is_output;
+ $ctype = "";
+ $name = $3;
+ #print("$arg: $name: might be a psa_key_production_parameters_t?\n");
+ die("$arg: not a psa_key_production_parameters_t 1!\n") if $i == $#args;
+ my $next = $args[$i + 1];
+ die("$arg: $func: $name: $next: not a psa_key_production_parameters_t 2!\n") if $next !~ /^size_t\s+(${name}_\w+)$/;
+ $i++; # We're using the next param here
+ my $nname = $1;
+ $name .= ", " . $nname;
} elsif ($arg =~ /^((const)\s+)?(\w+)\s*\*(\w+)$/) {
($type, $name) = ($3, "*" . $4);
$ctype = $1 . $type . " ";
diff --git a/tests/psa-client-server/psasim/src/psa_sim_serialise.pl b/tests/psa-client-server/psasim/src/psa_sim_serialise.pl
index a47b918..6b23f5c 100755
--- a/tests/psa-client-server/psasim/src/psa_sim_serialise.pl
+++ b/tests/psa-client-server/psasim/src/psa_sim_serialise.pl
@@ -60,6 +60,8 @@
for my $type (@types) {
if ($type eq "buffer") {
print declare_buffer_functions();
+ } elsif ($type eq "psa_key_production_parameters_t") {
+ print declare_psa_key_production_parameters_t_functions();
} else {
print declare_needs($type, "");
print declare_serialise($type, "");
@@ -90,6 +92,8 @@
for my $type (@types) {
if ($type eq "buffer") {
print define_buffer_functions();
+ } elsif ($type eq "psa_key_production_parameters_t") {
+ print define_psa_key_production_parameters_t_functions();
} elsif (exists($isa{$type})) {
print define_needs_isa($type, $isa{$type});
print define_serialise_isa($type, $isa{$type});
@@ -273,6 +277,62 @@
EOF
}
+sub declare_psa_key_production_parameters_t_functions
+{
+ return <<'EOF';
+
+/** Return how much space is needed by \c psasim_serialise_psa_key_production_parameters_t()
+ * to serialise a psa_key_production_parameters_t (a structure with a flexible array member).
+ *
+ * \param params Pointer to the struct to be serialised
+ * (needed in case some serialisations are value-
+ * dependent).
+ * \param data_length Number of bytes in the data[] of the struct to be serialised.
+ *
+ * \return The number of bytes needed in the serialisation buffer by
+ * \c psasim_serialise_psa_key_production_parameters_t() to serialise
+ * the specified structure.
+ */
+size_t psasim_serialise_psa_key_production_parameters_t_needs(
+ const psa_key_production_parameters_t *params,
+ size_t buffer_size);
+
+/** Serialise a psa_key_production_parameters_t.
+ *
+ * \param pos[in,out] Pointer to a `uint8_t *` holding current position
+ * in the buffer.
+ * \param remaining[in,out] Pointer to a `size_t` holding number of bytes
+ * remaining in the buffer.
+ * \param params Pointer to the structure to be serialised.
+ * \param data_length Number of bytes in the data[] of the struct to be serialised.
+ *
+ * \return \c 1 on success ("okay"), \c 0 on error.
+ */
+int psasim_serialise_psa_key_production_parameters_t(uint8_t **pos,
+ size_t *remaining,
+ const psa_key_production_parameters_t *params,
+ size_t data_length);
+
+/** Deserialise a psa_key_production_parameters_t.
+ *
+ * \param pos[in,out] Pointer to a `uint8_t *` holding current position
+ * in the serialisation buffer.
+ * \param remaining[in,out] Pointer to a `size_t` holding number of bytes
+ * remaining in the serialisation buffer.
+ * \param params Pointer to a `psa_key_production_parameters_t *` to
+ * receive the address of a newly-allocated structure,
+ * which the caller must `free()`.
+ * \param data_length Pointer to a `size_t` to receive the number of
+ * bytes in the data[] member of the structure deserialised.
+ *
+ * \return \c 1 on success ("okay"), \c 0 on error.
+ */
+int psasim_deserialise_psa_key_production_parameters_t(uint8_t **pos, size_t *remaining,
+ psa_key_production_parameters_t **params,
+ size_t *buffer_length);
+EOF
+}
+
sub h_header
{
return <<'EOF';
@@ -718,6 +778,106 @@
EOF
}
+sub define_psa_key_production_parameters_t_functions
+{
+ return <<'EOF';
+
+#define SER_TAG_SIZE 4
+
+size_t psasim_serialise_psa_key_production_parameters_t_needs(
+ const psa_key_production_parameters_t *params,
+ size_t data_length)
+{
+ /* We will serialise with 4-byte tag = "PKPP" + 4-byte overall length at the beginning,
+ * followed by size_t data_length, then the actual data from the structure.
+ */
+ return SER_TAG_SIZE + sizeof(uint32_t) + sizeof(data_length) + sizeof(*params) + data_length;
+}
+
+int psasim_serialise_psa_key_production_parameters_t(uint8_t **pos,
+ size_t *remaining,
+ const psa_key_production_parameters_t *params,
+ size_t data_length)
+{
+ if (data_length > UINT32_MAX / 2) { /* arbitrary limit */
+ return 0; /* too big to serialise */
+ }
+
+ /* We use 32-bit lengths, which should be enough for any reasonable usage :) */
+ /* (the UINT32_MAX / 2 above is an even more conservative check to avoid overflow here) */
+ uint32_t len = (uint32_t) (sizeof(data_length) + sizeof(*params) + data_length);
+ if (*remaining < SER_TAG_SIZE + sizeof(uint32_t) + len) {
+ return 0;
+ }
+
+ char tag[SER_TAG_SIZE] = "PKPP";
+
+ memcpy(*pos, tag, sizeof(tag));
+ memcpy(*pos + sizeof(tag), &len, sizeof(len));
+ *pos += sizeof(tag) + sizeof(len);
+ *remaining -= sizeof(tag) + sizeof(len);
+
+ memcpy(*pos, &data_length, sizeof(data_length));
+ memcpy(*pos + sizeof(data_length), params, sizeof(*params) + data_length);
+ *pos += sizeof(data_length) + sizeof(*params) + data_length;
+ *remaining -= sizeof(data_length) + sizeof(*params) + data_length;
+
+ return 1;
+}
+
+int psasim_deserialise_psa_key_production_parameters_t(uint8_t **pos,
+ size_t *remaining,
+ psa_key_production_parameters_t **params,
+ size_t *data_length)
+{
+ if (*remaining < SER_TAG_SIZE + sizeof(uint32_t)) {
+ return 0; /* can't even be an empty serialisation */
+ }
+
+ char tag[SER_TAG_SIZE] = "PKPP"; /* expected */
+ uint32_t len;
+
+ memcpy(&len, *pos + sizeof(tag), sizeof(len));
+
+ if (memcmp(*pos, tag, sizeof(tag)) != 0) {
+ return 0; /* wrong tag */
+ }
+
+ *pos += sizeof(tag) + sizeof(len);
+ *remaining -= sizeof(tag) + sizeof(len);
+
+ if (*remaining < sizeof(*data_length)) {
+ return 0; /* missing data_length */
+ }
+ memcpy(data_length, *pos, sizeof(*data_length));
+
+ if ((size_t)len != (sizeof(data_length) + sizeof(**params) + *data_length)) {
+ return 0; /* wrong length */
+ }
+
+ if (*remaining < sizeof(*data_length) + sizeof(**params) + *data_length) {
+ return 0; /* not enough data provided */
+ }
+
+ *pos += sizeof(data_length);
+ *remaining -= sizeof(data_length);
+
+ psa_key_production_parameters_t *out = malloc(sizeof(**params) + *data_length);
+ if (out == NULL) {
+ return 0; /* allocation failure */
+ }
+
+ memcpy(out, *pos, sizeof(*out) + *data_length);
+ *pos += sizeof(*out) + *data_length;
+ *remaining -= sizeof(*out) + *data_length;
+
+ *params = out;
+
+ return 1;
+}
+EOF
+}
+
sub c_header
{
return <<'EOF';