examples/fips_validation: add asymmetric validation
Add support for asymmetric crypto validation starting with RSA. For the generation of crypto values which is multiprecision in math, openssl library is used only for this purpose. Signed-off-by: Gowrishankar Muthukrishnan <gmuthukrishn@marvell.com> Acked-by: Brian Dooley <brian.dooley@intel.com>
This commit is contained in:
parent
63e1fbc343
commit
36128a67c2
@ -226,6 +226,12 @@ if jansson_dep.found()
|
||||
dpdk_conf.set('RTE_HAS_JANSSON', 1)
|
||||
endif
|
||||
|
||||
# check for OpenSSL
|
||||
openssl_dep = dependency('openssl', required: false, method: 'pkg-config')
|
||||
if openssl_dep.found()
|
||||
dpdk_conf.set('RTE_HAS_OPENSSL', 1)
|
||||
endif
|
||||
|
||||
# check for pcap
|
||||
pcap_dep = dependency('libpcap', required: false, method: 'pkg-config')
|
||||
pcap_lib = is_windows ? 'wpcap' : 'pcap'
|
||||
|
@ -278,6 +278,11 @@ New Features
|
||||
Added support for lookaside sessions in event mode.
|
||||
See the :doc:`../sample_app_ug/ipsec_secgw` for more details.
|
||||
|
||||
* **Updated FIPS validation sample application.**
|
||||
|
||||
Added support for asymmetric crypto algorithms.
|
||||
See the :doc:`../sample_app_ug/fips_validation` for more details.
|
||||
|
||||
* **Rewritten pmdinfo script.**
|
||||
|
||||
The ``dpdk-pmdinfo.py`` script was rewritten to produce valid JSON only.
|
||||
|
@ -68,6 +68,7 @@ ACVP
|
||||
* SHA (1, 256, 384, 512) - AFT, MCT
|
||||
* TDES-CBC - AFT, MCT
|
||||
* TDES-ECB - AFT, MCT
|
||||
* RSA
|
||||
|
||||
|
||||
Application Information
|
||||
|
@ -477,6 +477,8 @@ fips_test_parse_one_json_vector_set(void)
|
||||
else if (strstr(algo_str, "TDES-CBC") ||
|
||||
strstr(algo_str, "TDES-ECB"))
|
||||
info.algo = FIPS_TEST_ALGO_TDES;
|
||||
else if (strstr(algo_str, "RSA"))
|
||||
info.algo = FIPS_TEST_ALGO_RSA;
|
||||
else
|
||||
return -EINVAL;
|
||||
|
||||
|
@ -44,6 +44,7 @@ enum fips_test_algorithms {
|
||||
FIPS_TEST_ALGO_HMAC,
|
||||
FIPS_TEST_ALGO_TDES,
|
||||
FIPS_TEST_ALGO_SHA,
|
||||
FIPS_TEST_ALGO_RSA,
|
||||
FIPS_TEST_ALGO_MAX
|
||||
};
|
||||
|
||||
@ -57,6 +58,9 @@ enum file_types {
|
||||
enum fips_test_op {
|
||||
FIPS_TEST_ENC_AUTH_GEN = 1,
|
||||
FIPS_TEST_DEC_AUTH_VERIF,
|
||||
FIPS_TEST_ASYM_KEYGEN,
|
||||
FIPS_TEST_ASYM_SIGGEN,
|
||||
FIPS_TEST_ASYM_SIGVER
|
||||
};
|
||||
|
||||
#define MAX_LINE_PER_VECTOR 16
|
||||
@ -80,11 +84,22 @@ struct fips_test_vector {
|
||||
struct fips_val aad;
|
||||
} aead;
|
||||
};
|
||||
struct {
|
||||
struct fips_val seed;
|
||||
struct fips_val signature;
|
||||
struct fips_val e;
|
||||
struct fips_val n;
|
||||
struct fips_val d;
|
||||
struct fips_val p;
|
||||
struct fips_val q;
|
||||
struct fips_val dp;
|
||||
struct fips_val dq;
|
||||
struct fips_val qinv;
|
||||
} rsa;
|
||||
|
||||
struct fips_val pt;
|
||||
struct fips_val ct;
|
||||
struct fips_val iv;
|
||||
|
||||
enum rte_crypto_op_status status;
|
||||
};
|
||||
|
||||
@ -141,6 +156,12 @@ enum fips_sha_test_types {
|
||||
SHA_MCT
|
||||
};
|
||||
|
||||
enum fips_rsa_test_types {
|
||||
RSA_AFT = 0,
|
||||
RSA_GDT,
|
||||
RSA_KAT
|
||||
};
|
||||
|
||||
struct aesavs_interim_data {
|
||||
enum fips_aesavs_test_types test_type;
|
||||
uint32_t cipher_algo;
|
||||
@ -167,8 +188,9 @@ struct ccm_interim_data {
|
||||
};
|
||||
|
||||
struct sha_interim_data {
|
||||
enum fips_sha_test_types test_type;
|
||||
/* keep algo always on top as it is also used in asym digest */
|
||||
enum rte_crypto_auth_algorithm algo;
|
||||
enum fips_sha_test_types test_type;
|
||||
};
|
||||
|
||||
struct gcm_interim_data {
|
||||
@ -185,6 +207,14 @@ struct xts_interim_data {
|
||||
enum xts_tweak_modes tweak_mode;
|
||||
};
|
||||
|
||||
struct rsa_interim_data {
|
||||
enum rte_crypto_auth_algorithm auth;
|
||||
uint16_t modulo;
|
||||
uint16_t saltlen;
|
||||
enum rte_crypto_rsa_padding_type padding;
|
||||
enum rte_crypto_rsa_priv_key_type privkey;
|
||||
};
|
||||
|
||||
#ifdef USE_JANSSON
|
||||
/*
|
||||
* Maximum length of buffer to hold any json string.
|
||||
@ -230,6 +260,7 @@ struct fips_test_interim_info {
|
||||
struct sha_interim_data sha_data;
|
||||
struct gcm_interim_data gcm_data;
|
||||
struct xts_interim_data xts_data;
|
||||
struct rsa_interim_data rsa_data;
|
||||
} interim_info;
|
||||
|
||||
enum fips_test_op op;
|
||||
@ -305,6 +336,9 @@ parse_test_sha_json_test_type(void);
|
||||
|
||||
int
|
||||
parse_test_tdes_json_init(void);
|
||||
|
||||
int
|
||||
parse_test_rsa_json_init(void);
|
||||
#endif /* USE_JANSSON */
|
||||
|
||||
int
|
||||
@ -366,11 +400,14 @@ update_info_vec(uint32_t count);
|
||||
|
||||
typedef int (*fips_test_one_case_t)(void);
|
||||
typedef int (*fips_prepare_op_t)(void);
|
||||
typedef int (*fips_prepare_xform_t)(struct rte_crypto_sym_xform *);
|
||||
typedef int (*fips_prepare_sym_xform_t)(struct rte_crypto_sym_xform *);
|
||||
typedef int (*fips_prepare_asym_xform_t)(struct rte_crypto_asym_xform *);
|
||||
|
||||
struct fips_test_ops {
|
||||
fips_prepare_xform_t prepare_xform;
|
||||
fips_prepare_op_t prepare_op;
|
||||
fips_prepare_sym_xform_t prepare_sym_xform;
|
||||
fips_prepare_asym_xform_t prepare_asym_xform;
|
||||
fips_prepare_op_t prepare_sym_op;
|
||||
fips_prepare_op_t prepare_asym_op;
|
||||
fips_test_one_case_t test;
|
||||
};
|
||||
|
||||
|
@ -81,12 +81,12 @@ parser_read_gcm_pt_len(const char *key, char *src,
|
||||
|
||||
if (vec.pt.len == 0) {
|
||||
info.interim_info.gcm_data.is_gmac = 1;
|
||||
test_ops.prepare_op = prepare_auth_op;
|
||||
test_ops.prepare_xform = prepare_gmac_xform;
|
||||
test_ops.prepare_sym_op = prepare_auth_op;
|
||||
test_ops.prepare_sym_xform = prepare_gmac_xform;
|
||||
} else {
|
||||
info.interim_info.gcm_data.is_gmac = 0;
|
||||
test_ops.prepare_op = prepare_aead_op;
|
||||
test_ops.prepare_xform = prepare_gcm_xform;
|
||||
test_ops.prepare_sym_op = prepare_aead_op;
|
||||
test_ops.prepare_sym_xform = prepare_gcm_xform;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
519
examples/fips_validation/fips_validation_rsa.c
Normal file
519
examples/fips_validation/fips_validation_rsa.c
Normal file
@ -0,0 +1,519 @@
|
||||
/* SPDX-License-Identifier: BSD-3-Clause
|
||||
* Copyright(C) 2022 Marvell.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifdef USE_OPENSSL
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/rand.h>
|
||||
#endif /* USE_OPENSSL */
|
||||
|
||||
#include <rte_cryptodev.h>
|
||||
#include <rte_malloc.h>
|
||||
|
||||
#include "fips_validation.h"
|
||||
|
||||
#define TESTTYPE_JSON_STR "testType"
|
||||
#define SIGTYPE_JSON_STR "sigType"
|
||||
#define MOD_JSON_STR "modulo"
|
||||
#define HASH_JSON_STR "hashAlg"
|
||||
#define SALT_JSON_STR "saltLen"
|
||||
#define E_JSON_STR "e"
|
||||
#define N_JSON_STR "n"
|
||||
|
||||
#define SEED_JSON_STR "seed"
|
||||
#define MSG_JSON_STR "message"
|
||||
#define SIG_JSON_STR "signature"
|
||||
|
||||
#ifdef USE_JANSSON
|
||||
struct {
|
||||
uint8_t type;
|
||||
const char *desc;
|
||||
} rsa_test_types[] = {
|
||||
{RSA_AFT, "AFT"},
|
||||
{RSA_GDT, "GDT"},
|
||||
{RSA_KAT, "KAT"},
|
||||
};
|
||||
|
||||
struct {
|
||||
enum rte_crypto_auth_algorithm auth;
|
||||
const char *desc;
|
||||
} rsa_auth_algs[] = {
|
||||
{RTE_CRYPTO_AUTH_SHA1, "SHA-1"},
|
||||
{RTE_CRYPTO_AUTH_SHA224, "SHA2-224"},
|
||||
{RTE_CRYPTO_AUTH_SHA256, "SHA2-256"},
|
||||
{RTE_CRYPTO_AUTH_SHA384, "SHA2-384"},
|
||||
{RTE_CRYPTO_AUTH_SHA512, "SHA2-512"},
|
||||
};
|
||||
|
||||
struct {
|
||||
enum rte_crypto_rsa_padding_type padding;
|
||||
const char *desc;
|
||||
} rsa_padding_types[] = {
|
||||
{RTE_CRYPTO_RSA_PADDING_NONE, "none"},
|
||||
{RTE_CRYPTO_RSA_PADDING_PKCS1_5, "pkcs1v1.5"},
|
||||
{RTE_CRYPTO_RSA_PADDING_OAEP, "oaep"},
|
||||
{RTE_CRYPTO_RSA_PADDING_PSS, "pss"},
|
||||
};
|
||||
|
||||
#ifdef USE_OPENSSL
|
||||
static int
|
||||
prepare_vec_rsa(void)
|
||||
{
|
||||
BIGNUM *p = NULL, *q = NULL, *n = NULL, *d = NULL, *e = NULL;
|
||||
BIGNUM *dp = NULL, *dq = NULL, *qinv = NULL;
|
||||
BIGNUM *r0, *r1, *r2, *r3, *r4;
|
||||
BIGNUM *m = NULL, *r = NULL;
|
||||
int bits, ret = -1, i;
|
||||
char modbuf[8], *buf;
|
||||
BN_CTX *ctx = NULL;
|
||||
unsigned long pid;
|
||||
|
||||
/* Seed PRNG */
|
||||
if (vec.rsa.seed.val) {
|
||||
writeback_hex_str("", info.one_line_text, &vec.rsa.seed);
|
||||
RAND_seed((char *)info.one_line_text, strlen(info.one_line_text));
|
||||
} else {
|
||||
pid = getpid();
|
||||
RAND_seed(&pid, sizeof(pid));
|
||||
}
|
||||
|
||||
if (!RAND_status())
|
||||
return -1;
|
||||
|
||||
/* Check if e is known already */
|
||||
if (vec.rsa.e.val) {
|
||||
writeback_hex_str("", info.one_line_text, &vec.rsa.e);
|
||||
ret = BN_hex2bn(&e, info.one_line_text);
|
||||
if ((uint32_t)ret != strlen(info.one_line_text))
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* BN context initialization */
|
||||
ctx = BN_CTX_new();
|
||||
if (!ctx)
|
||||
goto err;
|
||||
|
||||
BN_CTX_start(ctx);
|
||||
r0 = BN_CTX_get(ctx);
|
||||
r1 = BN_CTX_get(ctx);
|
||||
r2 = BN_CTX_get(ctx);
|
||||
r3 = BN_CTX_get(ctx);
|
||||
r4 = BN_CTX_get(ctx);
|
||||
if (!r4)
|
||||
goto err;
|
||||
|
||||
/* Calculate bit length for prime numbers */
|
||||
m = BN_new();
|
||||
if (!m)
|
||||
goto err;
|
||||
|
||||
snprintf(modbuf, sizeof(modbuf), "%d", info.interim_info.rsa_data.modulo);
|
||||
if (!BN_dec2bn(&m, modbuf))
|
||||
goto err;
|
||||
|
||||
r = BN_new();
|
||||
if (!r)
|
||||
goto err;
|
||||
|
||||
if (!BN_rshift1(r, m))
|
||||
goto err;
|
||||
|
||||
buf = BN_bn2dec(r);
|
||||
bits = atoi(buf);
|
||||
|
||||
p = BN_new();
|
||||
if (!p)
|
||||
goto err;
|
||||
|
||||
q = BN_new();
|
||||
if (!q)
|
||||
goto err;
|
||||
|
||||
n = BN_new();
|
||||
if (!n)
|
||||
goto err;
|
||||
|
||||
d = BN_new();
|
||||
if (!d)
|
||||
goto err;
|
||||
|
||||
/* Generate p and q suitably for RSA */
|
||||
for (i = 0; i < 10; i++) {
|
||||
uint8_t j = 0;
|
||||
|
||||
if (!BN_generate_prime_ex(p, bits, 0, NULL, NULL, NULL))
|
||||
goto err;
|
||||
|
||||
do {
|
||||
RAND_add(&j, sizeof(j), 1);
|
||||
if (!BN_generate_prime_ex(q, bits, 0, NULL, NULL, NULL))
|
||||
goto err;
|
||||
|
||||
} while ((BN_cmp(p, q) == 0) && (j++ < 100));
|
||||
|
||||
if (j >= 100) {
|
||||
RTE_LOG(ERR, USER1, "Error: insufficient %d retries to generate q", j);
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* pq */
|
||||
if (!BN_mul(n, p, q, ctx))
|
||||
goto err;
|
||||
|
||||
/* p-1 */
|
||||
if (!BN_sub(r1, p, BN_value_one()))
|
||||
goto err;
|
||||
|
||||
/* q-1 */
|
||||
if (!BN_sub(r2, q, BN_value_one()))
|
||||
goto err;
|
||||
|
||||
/* (p-1 * q-1) */
|
||||
if (!BN_mul(r0, r1, r2, ctx))
|
||||
goto err;
|
||||
|
||||
/* gcd(p-1, q-1)*/
|
||||
if (!BN_gcd(r3, r1, r2, ctx))
|
||||
goto err;
|
||||
|
||||
/* lcm(p-1, q-1) */
|
||||
if (!BN_div(r4, r, r0, r3, ctx))
|
||||
goto err;
|
||||
|
||||
/* check if div and rem are non-zero */
|
||||
if (!r4 || !r)
|
||||
goto err;
|
||||
|
||||
/* 0 < e < lcm */
|
||||
if (!e) {
|
||||
int k = 0;
|
||||
|
||||
e = BN_new();
|
||||
do {
|
||||
RAND_add(&k, sizeof(k), 1);
|
||||
if (!BN_rand(e, 32, 1, 1))
|
||||
goto err;
|
||||
|
||||
if (!BN_gcd(r3, e, r4, ctx))
|
||||
goto err;
|
||||
|
||||
if (BN_is_one(r3))
|
||||
break;
|
||||
} while (k++ < 10);
|
||||
|
||||
if (k >= 10) {
|
||||
RTE_LOG(ERR, USER1, "Error: insufficient %d retries to generate e",
|
||||
k);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
/* (de) mod lcm == 1 */
|
||||
if (!BN_mod_inverse(d, e, r4, ctx))
|
||||
goto err;
|
||||
|
||||
if (!BN_gcd(r3, r1, e, ctx))
|
||||
goto err;
|
||||
|
||||
if (!BN_gcd(r4, r2, e, ctx))
|
||||
goto err;
|
||||
|
||||
/* check if gcd(p-1, e) and gcd(q-1, e) are 1 */
|
||||
if (BN_is_one(r3) && BN_is_one(r4))
|
||||
break;
|
||||
}
|
||||
|
||||
if (i >= 10) {
|
||||
RTE_LOG(ERR, USER1, "Error: insufficient %d retries to generate p and q", i);
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* d mod (p-1) */
|
||||
dp = BN_new();
|
||||
if (!dp)
|
||||
goto err;
|
||||
|
||||
if (!BN_mod(dp, d, r1, ctx))
|
||||
goto err;
|
||||
|
||||
/* d mod (q-1) */
|
||||
dq = BN_new();
|
||||
if (!dq)
|
||||
goto err;
|
||||
|
||||
if (!BN_mod(dq, d, r2, ctx))
|
||||
goto err;
|
||||
|
||||
/* modinv of q and p */
|
||||
qinv = BN_new();
|
||||
if (!qinv)
|
||||
goto err;
|
||||
|
||||
if (!BN_mod_inverse(qinv, q, p, ctx))
|
||||
goto err;
|
||||
|
||||
parse_uint8_hex_str("", BN_bn2hex(e), &vec.rsa.e);
|
||||
parse_uint8_hex_str("", BN_bn2hex(p), &vec.rsa.p);
|
||||
parse_uint8_hex_str("", BN_bn2hex(q), &vec.rsa.q);
|
||||
parse_uint8_hex_str("", BN_bn2hex(n), &vec.rsa.n);
|
||||
parse_uint8_hex_str("", BN_bn2hex(d), &vec.rsa.d);
|
||||
parse_uint8_hex_str("", BN_bn2hex(dp), &vec.rsa.dp);
|
||||
parse_uint8_hex_str("", BN_bn2hex(dq), &vec.rsa.dq);
|
||||
parse_uint8_hex_str("", BN_bn2hex(qinv), &vec.rsa.qinv);
|
||||
|
||||
ret = 0;
|
||||
err:
|
||||
BN_CTX_end(ctx);
|
||||
BN_CTX_free(ctx);
|
||||
BN_free(m);
|
||||
BN_free(r);
|
||||
BN_free(p);
|
||||
BN_free(q);
|
||||
BN_free(n);
|
||||
BN_free(d);
|
||||
BN_free(e);
|
||||
return ret;
|
||||
}
|
||||
#else
|
||||
static int
|
||||
prepare_vec_rsa(void)
|
||||
{
|
||||
/*
|
||||
* Generate RSA values.
|
||||
*/
|
||||
return -ENOTSUP;
|
||||
}
|
||||
#endif /* USE_OPENSSL */
|
||||
|
||||
static int
|
||||
parse_test_rsa_json_interim_writeback(struct fips_val *val)
|
||||
{
|
||||
RTE_SET_USED(val);
|
||||
|
||||
if (info.op == FIPS_TEST_ASYM_SIGGEN) {
|
||||
json_t *obj;
|
||||
|
||||
/* For siggen tests, RSA values can be created soon after
|
||||
* the test group data are parsed.
|
||||
*/
|
||||
if (vec.rsa.e.val) {
|
||||
rte_free(vec.rsa.e.val);
|
||||
vec.rsa.e.val = NULL;
|
||||
}
|
||||
|
||||
if (prepare_vec_rsa() < 0)
|
||||
return -1;
|
||||
|
||||
writeback_hex_str("", info.one_line_text, &vec.rsa.n);
|
||||
obj = json_string(info.one_line_text);
|
||||
json_object_set_new(json_info.json_write_group, "n", obj);
|
||||
|
||||
writeback_hex_str("", info.one_line_text, &vec.rsa.e);
|
||||
obj = json_string(info.one_line_text);
|
||||
json_object_set_new(json_info.json_write_group, "e", obj);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
parse_test_rsa_json_writeback(struct fips_val *val)
|
||||
{
|
||||
json_t *tcId;
|
||||
|
||||
RTE_SET_USED(val);
|
||||
|
||||
tcId = json_object_get(json_info.json_test_case, "tcId");
|
||||
|
||||
json_info.json_write_case = json_object();
|
||||
json_object_set(json_info.json_write_case, "tcId", tcId);
|
||||
|
||||
if (info.op == FIPS_TEST_ASYM_KEYGEN) {
|
||||
json_t *obj;
|
||||
|
||||
writeback_hex_str("", info.one_line_text, &vec.rsa.seed);
|
||||
obj = json_string(info.one_line_text);
|
||||
json_object_set_new(json_info.json_write_case, "seed", obj);
|
||||
|
||||
writeback_hex_str("", info.one_line_text, &vec.rsa.n);
|
||||
obj = json_string(info.one_line_text);
|
||||
json_object_set_new(json_info.json_write_case, "n", obj);
|
||||
|
||||
writeback_hex_str("", info.one_line_text, &vec.rsa.e);
|
||||
obj = json_string(info.one_line_text);
|
||||
json_object_set_new(json_info.json_write_case, "e", obj);
|
||||
|
||||
writeback_hex_str("", info.one_line_text, &vec.rsa.p);
|
||||
obj = json_string(info.one_line_text);
|
||||
json_object_set_new(json_info.json_write_case, "p", obj);
|
||||
|
||||
writeback_hex_str("", info.one_line_text, &vec.rsa.q);
|
||||
obj = json_string(info.one_line_text);
|
||||
json_object_set_new(json_info.json_write_case, "q", obj);
|
||||
|
||||
writeback_hex_str("", info.one_line_text, &vec.rsa.d);
|
||||
obj = json_string(info.one_line_text);
|
||||
json_object_set_new(json_info.json_write_case, "d", obj);
|
||||
} else if (info.op == FIPS_TEST_ASYM_SIGGEN) {
|
||||
json_t *obj;
|
||||
|
||||
writeback_hex_str("", info.one_line_text, &vec.rsa.signature);
|
||||
obj = json_string(info.one_line_text);
|
||||
json_object_set_new(json_info.json_write_case, "signature", obj);
|
||||
} else if (info.op == FIPS_TEST_ASYM_SIGVER) {
|
||||
if (vec.status == RTE_CRYPTO_OP_STATUS_SUCCESS)
|
||||
json_object_set_new(json_info.json_write_case, "testPassed", json_true());
|
||||
else
|
||||
json_object_set_new(json_info.json_write_case, "testPassed", json_false());
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
parse_interim_str(const char *key, char *src, struct fips_val *val)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
RTE_SET_USED(val);
|
||||
|
||||
if (strcmp(key, SIGTYPE_JSON_STR) == 0) {
|
||||
for (i = 0; i < RTE_DIM(rsa_padding_types); i++)
|
||||
if (strstr(src, rsa_padding_types[i].desc)) {
|
||||
info.interim_info.rsa_data.padding = rsa_padding_types[i].padding;
|
||||
break;
|
||||
}
|
||||
|
||||
if (i >= RTE_DIM(rsa_padding_types))
|
||||
return -EINVAL;
|
||||
|
||||
} else if (strcmp(key, MOD_JSON_STR) == 0) {
|
||||
info.interim_info.rsa_data.modulo = atoi(src);
|
||||
} else if (strcmp(key, HASH_JSON_STR) == 0) {
|
||||
for (i = 0; i < RTE_DIM(rsa_auth_algs); i++)
|
||||
if (strstr(src, rsa_auth_algs[i].desc)) {
|
||||
info.interim_info.rsa_data.auth = rsa_auth_algs[i].auth;
|
||||
break;
|
||||
}
|
||||
|
||||
if (i >= RTE_DIM(rsa_auth_algs))
|
||||
return -EINVAL;
|
||||
|
||||
} else if (strcmp(key, SALT_JSON_STR) == 0) {
|
||||
info.interim_info.rsa_data.saltlen = atoi(src);
|
||||
} else if (strcmp(key, TESTTYPE_JSON_STR) == 0) {
|
||||
for (i = 0; i < RTE_DIM(rsa_test_types); i++)
|
||||
if (strstr(src, rsa_test_types[i].desc)) {
|
||||
info.parse_writeback = parse_test_rsa_json_writeback;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!info.parse_writeback || i >= RTE_DIM(rsa_test_types))
|
||||
return -EINVAL;
|
||||
|
||||
} else {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
parse_keygen_e_str(const char *key, char *src, struct fips_val *val)
|
||||
{
|
||||
parse_uint8_hex_str(key, src, val);
|
||||
|
||||
/* For keygen tests, key "e" can be the end of input data
|
||||
* to generate RSA values.
|
||||
*/
|
||||
return prepare_vec_rsa();
|
||||
}
|
||||
|
||||
struct fips_test_callback rsa_keygen_interim_json_vectors[] = {
|
||||
{MOD_JSON_STR, parse_interim_str, NULL},
|
||||
{HASH_JSON_STR, parse_interim_str, NULL},
|
||||
{TESTTYPE_JSON_STR, parse_interim_str, NULL},
|
||||
{NULL, NULL, NULL} /**< end pointer */
|
||||
};
|
||||
|
||||
struct fips_test_callback rsa_siggen_interim_json_vectors[] = {
|
||||
{SIGTYPE_JSON_STR, parse_interim_str, NULL},
|
||||
{MOD_JSON_STR, parse_interim_str, NULL},
|
||||
{HASH_JSON_STR, parse_interim_str, NULL},
|
||||
{SALT_JSON_STR, parse_interim_str, NULL},
|
||||
{TESTTYPE_JSON_STR, parse_interim_str, NULL},
|
||||
{NULL, NULL, NULL} /**< end pointer */
|
||||
};
|
||||
|
||||
struct fips_test_callback rsa_sigver_interim_json_vectors[] = {
|
||||
{SIGTYPE_JSON_STR, parse_interim_str, NULL},
|
||||
{MOD_JSON_STR, parse_interim_str, NULL},
|
||||
{HASH_JSON_STR, parse_interim_str, NULL},
|
||||
{SALT_JSON_STR, parse_interim_str, NULL},
|
||||
{N_JSON_STR, parse_uint8_hex_str, &vec.rsa.n},
|
||||
{E_JSON_STR, parse_uint8_hex_str, &vec.rsa.e},
|
||||
{TESTTYPE_JSON_STR, parse_interim_str, NULL},
|
||||
{NULL, NULL, NULL} /**< end pointer */
|
||||
};
|
||||
|
||||
struct fips_test_callback rsa_keygen_json_vectors[] = {
|
||||
{SEED_JSON_STR, parse_uint8_hex_str, &vec.rsa.seed},
|
||||
{E_JSON_STR, parse_keygen_e_str, &vec.rsa.e},
|
||||
{NULL, NULL, NULL} /**< end pointer */
|
||||
};
|
||||
|
||||
struct fips_test_callback rsa_siggen_json_vectors[] = {
|
||||
{MSG_JSON_STR, parse_uint8_hex_str, &vec.pt},
|
||||
{NULL, NULL, NULL} /**< end pointer */
|
||||
};
|
||||
|
||||
struct fips_test_callback rsa_sigver_json_vectors[] = {
|
||||
{MSG_JSON_STR, parse_uint8_hex_str, &vec.pt},
|
||||
{SIG_JSON_STR, parse_uint8_hex_str, &vec.rsa.signature},
|
||||
{NULL, NULL, NULL} /**< end pointer */
|
||||
};
|
||||
|
||||
int
|
||||
parse_test_rsa_json_init(void)
|
||||
{
|
||||
json_t *keyfmt_obj = json_object_get(json_info.json_vector_set, "keyFormat");
|
||||
json_t *mode_obj = json_object_get(json_info.json_vector_set, "mode");
|
||||
const char *keyfmt_str = json_string_value(keyfmt_obj);
|
||||
const char *mode_str = json_string_value(mode_obj);
|
||||
|
||||
info.callbacks = NULL;
|
||||
info.parse_writeback = NULL;
|
||||
info.interim_callbacks = NULL;
|
||||
info.parse_interim_writeback = NULL;
|
||||
|
||||
if (strcmp(mode_str, "keyGen") == 0) {
|
||||
info.op = FIPS_TEST_ASYM_KEYGEN;
|
||||
info.callbacks = rsa_keygen_json_vectors;
|
||||
info.interim_callbacks = rsa_keygen_interim_json_vectors;
|
||||
} else if (strcmp(mode_str, "sigGen") == 0) {
|
||||
info.op = FIPS_TEST_ASYM_SIGGEN;
|
||||
info.callbacks = rsa_siggen_json_vectors;
|
||||
info.interim_callbacks = rsa_siggen_interim_json_vectors;
|
||||
info.parse_interim_writeback = parse_test_rsa_json_interim_writeback;
|
||||
} else if (strcmp(mode_str, "sigVer") == 0) {
|
||||
info.op = FIPS_TEST_ASYM_SIGVER;
|
||||
info.callbacks = rsa_sigver_json_vectors;
|
||||
info.interim_callbacks = rsa_sigver_interim_json_vectors;
|
||||
} else {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
info.interim_info.rsa_data.privkey = RTE_RSA_KEY_TYPE_QT;
|
||||
if (keyfmt_str != NULL && strcmp(keyfmt_str, "standard") == 0)
|
||||
info.interim_info.rsa_data.privkey = RTE_RSA_KEY_TYPE_EXP;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* USE_JANSSON */
|
@ -37,6 +37,8 @@ enum {
|
||||
OPT_CRYPTODEV_BK_DIR_KEY_NUM,
|
||||
#define OPT_USE_JSON "use-json"
|
||||
OPT_USE_JSON_NUM,
|
||||
#define OPT_CRYPTODEV_ASYM "asymmetric"
|
||||
OPT_CRYPTODEV_ASYM_NUM,
|
||||
};
|
||||
|
||||
struct fips_test_vector vec;
|
||||
@ -51,34 +53,140 @@ struct cryptodev_fips_validate_env {
|
||||
const char *rsp_path;
|
||||
uint32_t is_path_folder;
|
||||
uint8_t dev_id;
|
||||
struct rte_mempool *mpool;
|
||||
struct fips_sym_env {
|
||||
struct rte_mempool *sess_mpool;
|
||||
struct rte_mempool *op_pool;
|
||||
struct rte_cryptodev_sym_session *sess;
|
||||
struct rte_crypto_op *op;
|
||||
} sym;
|
||||
struct fips_asym_env {
|
||||
struct rte_mempool *sess_mpool;
|
||||
struct rte_mempool *op_pool;
|
||||
struct rte_cryptodev_asym_session *sess;
|
||||
struct rte_crypto_op *op;
|
||||
} asym;
|
||||
struct rte_crypto_op *op;
|
||||
uint8_t dev_support_sgl;
|
||||
uint16_t mbuf_data_room;
|
||||
struct rte_mempool *mpool;
|
||||
struct rte_mempool *sess_mpool;
|
||||
struct rte_mempool *op_pool;
|
||||
struct rte_mbuf *mbuf;
|
||||
uint8_t *digest;
|
||||
uint16_t digest_len;
|
||||
struct rte_crypto_op *op;
|
||||
void *sess;
|
||||
bool is_asym_test;
|
||||
uint16_t self_test;
|
||||
struct fips_dev_broken_test_config *broken_test_config;
|
||||
} env;
|
||||
|
||||
static int
|
||||
cryptodev_fips_validate_app_int(void)
|
||||
cryptodev_fips_validate_app_sym_init(void)
|
||||
{
|
||||
uint32_t sess_sz = rte_cryptodev_sym_get_private_session_size(
|
||||
env.dev_id);
|
||||
struct rte_cryptodev_info dev_info;
|
||||
struct fips_sym_env *sym = &env.sym;
|
||||
int ret;
|
||||
|
||||
rte_cryptodev_info_get(env.dev_id, &dev_info);
|
||||
if (dev_info.feature_flags & RTE_CRYPTODEV_FF_IN_PLACE_SGL)
|
||||
env.dev_support_sgl = 1;
|
||||
else
|
||||
env.dev_support_sgl = 0;
|
||||
|
||||
ret = -ENOMEM;
|
||||
sym->sess_mpool = rte_cryptodev_sym_session_pool_create(
|
||||
"FIPS_SYM_SESS_MEMPOOL", 16, sess_sz, 0, 0, rte_socket_id());
|
||||
if (!sym->sess_mpool)
|
||||
goto error_exit;
|
||||
|
||||
sym->op_pool = rte_crypto_op_pool_create(
|
||||
"FIPS_OP_SYM_POOL",
|
||||
RTE_CRYPTO_OP_TYPE_SYMMETRIC,
|
||||
1, 0,
|
||||
16,
|
||||
rte_socket_id());
|
||||
if (!sym->op_pool)
|
||||
goto error_exit;
|
||||
|
||||
sym->op = rte_crypto_op_alloc(sym->op_pool, RTE_CRYPTO_OP_TYPE_SYMMETRIC);
|
||||
if (!sym->op)
|
||||
goto error_exit;
|
||||
|
||||
return 0;
|
||||
|
||||
error_exit:
|
||||
rte_mempool_free(sym->sess_mpool);
|
||||
rte_mempool_free(sym->op_pool);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
cryptodev_fips_validate_app_sym_uninit(void)
|
||||
{
|
||||
struct fips_sym_env *sym = &env.sym;
|
||||
|
||||
rte_pktmbuf_free(env.mbuf);
|
||||
rte_crypto_op_free(sym->op);
|
||||
rte_cryptodev_sym_session_free(env.dev_id, sym->sess);
|
||||
rte_mempool_free(sym->sess_mpool);
|
||||
rte_mempool_free(sym->op_pool);
|
||||
}
|
||||
|
||||
static int
|
||||
cryptodev_fips_validate_app_asym_init(void)
|
||||
{
|
||||
struct fips_asym_env *asym = &env.asym;
|
||||
int ret;
|
||||
|
||||
ret = -ENOMEM;
|
||||
asym->sess_mpool = rte_cryptodev_asym_session_pool_create(
|
||||
"FIPS_ASYM_SESS_MEMPOOL", 16, 0, 0, rte_socket_id());
|
||||
if (!asym->sess_mpool)
|
||||
goto error_exit;
|
||||
|
||||
asym->op_pool = rte_crypto_op_pool_create(
|
||||
"FIPS_OP_ASYM_POOL",
|
||||
RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
|
||||
1, 0,
|
||||
16,
|
||||
rte_socket_id());
|
||||
if (!asym->op_pool)
|
||||
goto error_exit;
|
||||
|
||||
asym->op = rte_crypto_op_alloc(asym->op_pool, RTE_CRYPTO_OP_TYPE_ASYMMETRIC);
|
||||
if (!asym->op)
|
||||
goto error_exit;
|
||||
|
||||
return 0;
|
||||
|
||||
error_exit:
|
||||
rte_mempool_free(asym->sess_mpool);
|
||||
rte_mempool_free(asym->op_pool);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
cryptodev_fips_validate_app_asym_uninit(void)
|
||||
{
|
||||
struct fips_asym_env *asym = &env.asym;
|
||||
|
||||
rte_crypto_op_free(asym->op);
|
||||
rte_cryptodev_asym_session_free(env.dev_id, asym->sess);
|
||||
rte_mempool_free(asym->sess_mpool);
|
||||
rte_mempool_free(asym->op_pool);
|
||||
}
|
||||
|
||||
static int
|
||||
cryptodev_fips_validate_app_init(void)
|
||||
{
|
||||
struct rte_cryptodev_config conf = {rte_socket_id(), 1, 0};
|
||||
struct rte_cryptodev_qp_conf qp_conf = {128, NULL};
|
||||
struct rte_cryptodev_info dev_info;
|
||||
uint32_t sess_sz = rte_cryptodev_sym_get_private_session_size(
|
||||
env.dev_id);
|
||||
uint32_t nb_mbufs = UINT16_MAX / env.mbuf_data_room + 1;
|
||||
int ret;
|
||||
|
||||
if (env.self_test) {
|
||||
ret = fips_dev_self_test(env.dev_id, env.broken_test_config);
|
||||
if (ret < 0) {
|
||||
rte_cryptodev_stop(env.dev_id);
|
||||
rte_cryptodev_close(env.dev_id);
|
||||
|
||||
return ret;
|
||||
@ -89,45 +197,24 @@ cryptodev_fips_validate_app_int(void)
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
rte_cryptodev_info_get(env.dev_id, &dev_info);
|
||||
if (dev_info.feature_flags & RTE_CRYPTODEV_FF_IN_PLACE_SGL)
|
||||
env.dev_support_sgl = 1;
|
||||
else
|
||||
env.dev_support_sgl = 0;
|
||||
|
||||
ret = -ENOMEM;
|
||||
env.mpool = rte_pktmbuf_pool_create("FIPS_MEMPOOL", nb_mbufs,
|
||||
0, 0, sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM +
|
||||
env.mbuf_data_room, rte_socket_id());
|
||||
if (!env.mpool)
|
||||
return ret;
|
||||
|
||||
ret = rte_cryptodev_queue_pair_setup(env.dev_id, 0, &qp_conf,
|
||||
rte_socket_id());
|
||||
ret = cryptodev_fips_validate_app_sym_init();
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = -ENOMEM;
|
||||
|
||||
env.sess_mpool = rte_cryptodev_sym_session_pool_create(
|
||||
"FIPS_SESS_MEMPOOL", 16, sess_sz, 0, 0,
|
||||
rte_socket_id());
|
||||
if (!env.sess_mpool)
|
||||
goto error_exit;
|
||||
|
||||
env.op_pool = rte_crypto_op_pool_create(
|
||||
"FIPS_OP_POOL",
|
||||
RTE_CRYPTO_OP_TYPE_SYMMETRIC,
|
||||
1, 0,
|
||||
16,
|
||||
rte_socket_id());
|
||||
if (!env.op_pool)
|
||||
goto error_exit;
|
||||
if (env.is_asym_test) {
|
||||
ret = cryptodev_fips_validate_app_asym_init();
|
||||
if (ret < 0)
|
||||
goto error_exit;
|
||||
}
|
||||
|
||||
env.op = rte_crypto_op_alloc(env.op_pool, RTE_CRYPTO_OP_TYPE_SYMMETRIC);
|
||||
if (!env.op)
|
||||
goto error_exit;
|
||||
|
||||
qp_conf.mp_session = env.sess_mpool;
|
||||
qp_conf.mp_session = env.sym.sess_mpool;
|
||||
|
||||
ret = rte_cryptodev_queue_pair_setup(env.dev_id, 0, &qp_conf,
|
||||
rte_socket_id());
|
||||
@ -141,23 +228,21 @@ cryptodev_fips_validate_app_int(void)
|
||||
return 0;
|
||||
|
||||
error_exit:
|
||||
|
||||
rte_mempool_free(env.mpool);
|
||||
rte_mempool_free(env.sess_mpool);
|
||||
rte_mempool_free(env.op_pool);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
cryptodev_fips_validate_app_uninit(void)
|
||||
{
|
||||
rte_pktmbuf_free(env.mbuf);
|
||||
rte_crypto_op_free(env.op);
|
||||
rte_cryptodev_sym_session_free(env.dev_id, env.sess);
|
||||
cryptodev_fips_validate_app_sym_uninit();
|
||||
|
||||
if (env.is_asym_test)
|
||||
cryptodev_fips_validate_app_asym_uninit();
|
||||
|
||||
rte_mempool_free(env.mpool);
|
||||
rte_mempool_free(env.sess_mpool);
|
||||
rte_mempool_free(env.op_pool);
|
||||
rte_cryptodev_stop(env.dev_id);
|
||||
rte_cryptodev_close(env.dev_id);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -253,6 +338,8 @@ cryptodev_fips_validate_parse_args(int argc, char **argv)
|
||||
NULL, OPT_CRYPTODEV_BK_ID_NUM},
|
||||
{OPT_CRYPTODEV_BK_DIR_KEY, required_argument,
|
||||
NULL, OPT_CRYPTODEV_BK_DIR_KEY_NUM},
|
||||
{OPT_CRYPTODEV_ASYM, no_argument,
|
||||
NULL, OPT_CRYPTODEV_ASYM_NUM},
|
||||
{NULL, 0, 0, 0}
|
||||
};
|
||||
|
||||
@ -365,6 +452,10 @@ cryptodev_fips_validate_parse_args(int argc, char **argv)
|
||||
}
|
||||
break;
|
||||
|
||||
case OPT_CRYPTODEV_ASYM_NUM:
|
||||
env.is_asym_test = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
cryptodev_fips_validate_usage(prgname);
|
||||
return -EINVAL;
|
||||
@ -405,7 +496,7 @@ main(int argc, char *argv[])
|
||||
if (ret < 0)
|
||||
rte_exit(EXIT_FAILURE, "Failed to parse arguments!\n");
|
||||
|
||||
ret = cryptodev_fips_validate_app_int();
|
||||
ret = cryptodev_fips_validate_app_init();
|
||||
if (ret < 0) {
|
||||
RTE_LOG(ERR, USER1, "Error %i: Failed init\n", ret);
|
||||
return -1;
|
||||
@ -644,7 +735,7 @@ prepare_cipher_op(void)
|
||||
sym->cipher.data.length = vec.ct.len;
|
||||
}
|
||||
|
||||
rte_crypto_op_attach_sym_session(env.op, env.sess);
|
||||
rte_crypto_op_attach_sym_session(env.op, env.sym.sess);
|
||||
|
||||
sym->m_src = env.mbuf;
|
||||
sym->cipher.data.offset = 0;
|
||||
@ -707,7 +798,7 @@ prepare_auth_op(void)
|
||||
memcpy(env.digest, vec.cipher_auth.digest.val,
|
||||
vec.cipher_auth.digest.len);
|
||||
|
||||
rte_crypto_op_attach_sym_session(env.op, env.sess);
|
||||
rte_crypto_op_attach_sym_session(env.op, env.sym.sess);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -763,7 +854,55 @@ prepare_aead_op(void)
|
||||
sym->aead.aad.data = vec.aead.aad.val;
|
||||
sym->aead.aad.phys_addr = rte_malloc_virt2iova(sym->aead.aad.data);
|
||||
|
||||
rte_crypto_op_attach_sym_session(env.op, env.sess);
|
||||
rte_crypto_op_attach_sym_session(env.op, env.sym.sess);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
prepare_rsa_op(void)
|
||||
{
|
||||
struct rte_crypto_asym_op *asym;
|
||||
struct fips_val msg;
|
||||
|
||||
__rte_crypto_op_reset(env.op, RTE_CRYPTO_OP_TYPE_ASYMMETRIC);
|
||||
|
||||
asym = env.op->asym;
|
||||
asym->rsa.padding.type = info.interim_info.rsa_data.padding;
|
||||
asym->rsa.padding.hash = info.interim_info.rsa_data.auth;
|
||||
|
||||
if (env.digest) {
|
||||
msg.val = env.digest;
|
||||
msg.len = env.digest_len;
|
||||
} else {
|
||||
msg.val = vec.pt.val;
|
||||
msg.len = vec.pt.len;
|
||||
}
|
||||
|
||||
if (info.op == FIPS_TEST_ASYM_SIGGEN) {
|
||||
asym->rsa.op_type = RTE_CRYPTO_ASYM_OP_SIGN;
|
||||
asym->rsa.message.data = msg.val;
|
||||
asym->rsa.message.length = msg.len;
|
||||
|
||||
if (vec.rsa.signature.val)
|
||||
rte_free(vec.rsa.signature.val);
|
||||
|
||||
vec.rsa.signature.val = rte_zmalloc(NULL, vec.rsa.n.len, 0);
|
||||
vec.rsa.signature.len = vec.rsa.n.len;
|
||||
asym->rsa.sign.data = vec.rsa.signature.val;
|
||||
asym->rsa.sign.length = 0;
|
||||
} else if (info.op == FIPS_TEST_ASYM_SIGVER) {
|
||||
asym->rsa.op_type = RTE_CRYPTO_ASYM_OP_VERIFY;
|
||||
asym->rsa.message.data = msg.val;
|
||||
asym->rsa.message.length = msg.len;
|
||||
asym->rsa.sign.data = vec.rsa.signature.val;
|
||||
asym->rsa.sign.length = vec.rsa.signature.len;
|
||||
} else {
|
||||
RTE_LOG(ERR, USER1, "Invalid op %d\n", info.op);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rte_crypto_op_attach_asym_session(env.op, env.asym.sess);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1154,6 +1293,87 @@ prepare_xts_xform(struct rte_crypto_sym_xform *xform)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
prepare_rsa_xform(struct rte_crypto_asym_xform *xform)
|
||||
{
|
||||
const struct rte_cryptodev_asymmetric_xform_capability *cap;
|
||||
struct rte_cryptodev_asym_capability_idx cap_idx;
|
||||
struct rte_cryptodev_info dev_info;
|
||||
|
||||
xform->xform_type = RTE_CRYPTO_ASYM_XFORM_RSA;
|
||||
xform->next = NULL;
|
||||
|
||||
cap_idx.type = xform->xform_type;
|
||||
cap = rte_cryptodev_asym_capability_get(env.dev_id, &cap_idx);
|
||||
if (!cap) {
|
||||
RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
|
||||
env.dev_id);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
switch (info.op) {
|
||||
case FIPS_TEST_ASYM_SIGGEN:
|
||||
if (!rte_cryptodev_asym_xform_capability_check_optype(cap,
|
||||
RTE_CRYPTO_ASYM_OP_SIGN)) {
|
||||
RTE_LOG(ERR, USER1, "PMD %s xform_op %u\n",
|
||||
info.device_name, RTE_CRYPTO_ASYM_OP_SIGN);
|
||||
return -EPERM;
|
||||
}
|
||||
break;
|
||||
case FIPS_TEST_ASYM_SIGVER:
|
||||
if (!rte_cryptodev_asym_xform_capability_check_optype(cap,
|
||||
RTE_CRYPTO_ASYM_OP_VERIFY)) {
|
||||
RTE_LOG(ERR, USER1, "PMD %s xform_op %u\n",
|
||||
info.device_name, RTE_CRYPTO_ASYM_OP_VERIFY);
|
||||
return -EPERM;
|
||||
}
|
||||
break;
|
||||
case FIPS_TEST_ASYM_KEYGEN:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
rte_cryptodev_info_get(env.dev_id, &dev_info);
|
||||
xform->rsa.key_type = info.interim_info.rsa_data.privkey;
|
||||
switch (xform->rsa.key_type) {
|
||||
case RTE_RSA_KEY_TYPE_QT:
|
||||
if (!(dev_info.feature_flags & RTE_CRYPTODEV_FF_RSA_PRIV_OP_KEY_QT)) {
|
||||
RTE_LOG(ERR, USER1, "PMD %s does not support QT key type\n",
|
||||
info.device_name);
|
||||
return -EPERM;
|
||||
}
|
||||
xform->rsa.qt.p.data = vec.rsa.p.val;
|
||||
xform->rsa.qt.p.length = vec.rsa.p.len;
|
||||
xform->rsa.qt.q.data = vec.rsa.q.val;
|
||||
xform->rsa.qt.q.length = vec.rsa.q.len;
|
||||
xform->rsa.qt.dP.data = vec.rsa.dp.val;
|
||||
xform->rsa.qt.dP.length = vec.rsa.dp.len;
|
||||
xform->rsa.qt.dQ.data = vec.rsa.dq.val;
|
||||
xform->rsa.qt.dQ.length = vec.rsa.dq.len;
|
||||
xform->rsa.qt.qInv.data = vec.rsa.qinv.val;
|
||||
xform->rsa.qt.qInv.length = vec.rsa.qinv.len;
|
||||
break;
|
||||
case RTE_RSA_KEY_TYPE_EXP:
|
||||
if (!(dev_info.feature_flags & RTE_CRYPTODEV_FF_RSA_PRIV_OP_KEY_EXP)) {
|
||||
RTE_LOG(ERR, USER1, "PMD %s does not support EXP key type\n",
|
||||
info.device_name);
|
||||
return -EPERM;
|
||||
}
|
||||
xform->rsa.d.data = vec.rsa.d.val;
|
||||
xform->rsa.d.length = vec.rsa.d.len;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
xform->rsa.e.data = vec.rsa.e.val;
|
||||
xform->rsa.e.length = vec.rsa.e.len;
|
||||
xform->rsa.n.data = vec.rsa.n.val;
|
||||
xform->rsa.n.length = vec.rsa.n.len;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
get_writeback_data(struct fips_val *val)
|
||||
{
|
||||
@ -1200,25 +1420,25 @@ get_writeback_data(struct fips_val *val)
|
||||
}
|
||||
|
||||
static int
|
||||
fips_run_test(void)
|
||||
fips_run_sym_test(void)
|
||||
{
|
||||
struct rte_crypto_sym_xform xform = {0};
|
||||
uint16_t n_deqd;
|
||||
int ret;
|
||||
|
||||
ret = test_ops.prepare_xform(&xform);
|
||||
if (!test_ops.prepare_sym_xform || !test_ops.prepare_sym_op)
|
||||
return -EINVAL;
|
||||
|
||||
ret = test_ops.prepare_sym_xform(&xform);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
env.sess = rte_cryptodev_sym_session_create(env.dev_id, &xform,
|
||||
env.sess_mpool);
|
||||
if (!env.sess) {
|
||||
RTE_LOG(ERR, USER1, "Error %i: Init session\n",
|
||||
ret);
|
||||
goto exit;
|
||||
}
|
||||
env.sym.sess = rte_cryptodev_sym_session_create(env.dev_id, &xform,
|
||||
env.sym.sess_mpool);
|
||||
if (!env.sym.sess)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = test_ops.prepare_op();
|
||||
ret = test_ops.prepare_sym_op();
|
||||
if (ret < 0) {
|
||||
RTE_LOG(ERR, USER1, "Error %i: Prepare op\n",
|
||||
ret);
|
||||
@ -1234,21 +1454,91 @@ fips_run_test(void)
|
||||
do {
|
||||
struct rte_crypto_op *deqd_op;
|
||||
|
||||
n_deqd = rte_cryptodev_dequeue_burst(env.dev_id, 0, &deqd_op,
|
||||
1);
|
||||
n_deqd = rte_cryptodev_dequeue_burst(env.dev_id, 0, &deqd_op, 1);
|
||||
} while (n_deqd == 0);
|
||||
|
||||
vec.status = env.op->status;
|
||||
|
||||
exit:
|
||||
if (env.sess) {
|
||||
rte_cryptodev_sym_session_free(env.dev_id, env.sess);
|
||||
env.sess = NULL;
|
||||
rte_cryptodev_sym_session_free(env.dev_id, env.sym.sess);
|
||||
env.sym.sess = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
fips_run_asym_test(void)
|
||||
{
|
||||
struct rte_crypto_asym_xform xform = {0};
|
||||
struct rte_crypto_asym_op *asym;
|
||||
struct rte_crypto_op *deqd_op;
|
||||
int ret;
|
||||
|
||||
if (info.op == FIPS_TEST_ASYM_KEYGEN) {
|
||||
RTE_SET_USED(asym);
|
||||
ret = 0;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (!test_ops.prepare_asym_xform || !test_ops.prepare_asym_op)
|
||||
return -EINVAL;
|
||||
|
||||
asym = env.op->asym;
|
||||
ret = test_ops.prepare_asym_xform(&xform);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = rte_cryptodev_asym_session_create(env.dev_id, &xform, env.asym.sess_mpool,
|
||||
(void *)&env.asym.sess);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = test_ops.prepare_asym_op();
|
||||
if (ret < 0) {
|
||||
RTE_LOG(ERR, USER1, "Error %i: Prepare op\n", ret);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (rte_cryptodev_enqueue_burst(env.dev_id, 0, &env.op, 1) < 1) {
|
||||
RTE_LOG(ERR, USER1, "Error: Failed enqueue\n");
|
||||
ret = -1;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
while (rte_cryptodev_dequeue_burst(env.dev_id, 0, &deqd_op, 1) == 0)
|
||||
rte_pause();
|
||||
|
||||
vec.status = env.op->status;
|
||||
|
||||
exit:
|
||||
if (env.asym.sess)
|
||||
rte_cryptodev_asym_session_free(env.dev_id, env.asym.sess);
|
||||
|
||||
env.asym.sess = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
fips_run_test(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
env.op = env.sym.op;
|
||||
if (env.is_asym_test) {
|
||||
vec.cipher_auth.digest.len = parse_test_sha_hash_size(
|
||||
info.interim_info.rsa_data.auth);
|
||||
test_ops.prepare_sym_xform = prepare_sha_xform;
|
||||
test_ops.prepare_sym_op = prepare_auth_op;
|
||||
ret = fips_run_sym_test();
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
} else {
|
||||
return fips_run_sym_test();
|
||||
}
|
||||
|
||||
env.op = env.asym.op;
|
||||
return fips_run_asym_test();
|
||||
}
|
||||
|
||||
static int
|
||||
fips_generic_test(void)
|
||||
{
|
||||
@ -1271,9 +1561,11 @@ fips_generic_test(void)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = get_writeback_data(&val);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
if (!env.is_asym_test) {
|
||||
ret = get_writeback_data(&val);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
switch (info.file_type) {
|
||||
case FIPS_TYPE_REQ:
|
||||
@ -1823,65 +2115,70 @@ init_test_ops(void)
|
||||
case FIPS_TEST_ALGO_AES_CBC:
|
||||
case FIPS_TEST_ALGO_AES_CTR:
|
||||
case FIPS_TEST_ALGO_AES:
|
||||
test_ops.prepare_op = prepare_cipher_op;
|
||||
test_ops.prepare_xform = prepare_aes_xform;
|
||||
test_ops.prepare_sym_op = prepare_cipher_op;
|
||||
test_ops.prepare_sym_xform = prepare_aes_xform;
|
||||
if (info.interim_info.aes_data.test_type == AESAVS_TYPE_MCT)
|
||||
test_ops.test = fips_mct_aes_test;
|
||||
else
|
||||
test_ops.test = fips_generic_test;
|
||||
break;
|
||||
case FIPS_TEST_ALGO_HMAC:
|
||||
test_ops.prepare_op = prepare_auth_op;
|
||||
test_ops.prepare_xform = prepare_hmac_xform;
|
||||
test_ops.prepare_sym_op = prepare_auth_op;
|
||||
test_ops.prepare_sym_xform = prepare_hmac_xform;
|
||||
test_ops.test = fips_generic_test;
|
||||
break;
|
||||
case FIPS_TEST_ALGO_TDES:
|
||||
test_ops.prepare_op = prepare_cipher_op;
|
||||
test_ops.prepare_xform = prepare_tdes_xform;
|
||||
test_ops.prepare_sym_op = prepare_cipher_op;
|
||||
test_ops.prepare_sym_xform = prepare_tdes_xform;
|
||||
if (info.interim_info.tdes_data.test_type == TDES_MCT)
|
||||
test_ops.test = fips_mct_tdes_test;
|
||||
else
|
||||
test_ops.test = fips_generic_test;
|
||||
break;
|
||||
case FIPS_TEST_ALGO_AES_GMAC:
|
||||
test_ops.prepare_op = prepare_auth_op;
|
||||
test_ops.prepare_xform = prepare_gmac_xform;
|
||||
test_ops.prepare_sym_op = prepare_auth_op;
|
||||
test_ops.prepare_sym_xform = prepare_gmac_xform;
|
||||
test_ops.test = fips_generic_test;
|
||||
break;
|
||||
case FIPS_TEST_ALGO_AES_GCM:
|
||||
test_ops.prepare_op = prepare_aead_op;
|
||||
test_ops.prepare_xform = prepare_gcm_xform;
|
||||
test_ops.prepare_sym_op = prepare_aead_op;
|
||||
test_ops.prepare_sym_xform = prepare_gcm_xform;
|
||||
test_ops.test = fips_generic_test;
|
||||
break;
|
||||
case FIPS_TEST_ALGO_AES_CMAC:
|
||||
test_ops.prepare_op = prepare_auth_op;
|
||||
test_ops.prepare_xform = prepare_cmac_xform;
|
||||
test_ops.prepare_sym_op = prepare_auth_op;
|
||||
test_ops.prepare_sym_xform = prepare_cmac_xform;
|
||||
test_ops.test = fips_generic_test;
|
||||
break;
|
||||
case FIPS_TEST_ALGO_AES_CCM:
|
||||
test_ops.prepare_op = prepare_aead_op;
|
||||
test_ops.prepare_xform = prepare_ccm_xform;
|
||||
test_ops.prepare_sym_op = prepare_aead_op;
|
||||
test_ops.prepare_sym_xform = prepare_ccm_xform;
|
||||
test_ops.test = fips_generic_test;
|
||||
break;
|
||||
case FIPS_TEST_ALGO_SHA:
|
||||
test_ops.prepare_op = prepare_auth_op;
|
||||
test_ops.prepare_xform = prepare_sha_xform;
|
||||
test_ops.prepare_sym_op = prepare_auth_op;
|
||||
test_ops.prepare_sym_xform = prepare_sha_xform;
|
||||
if (info.interim_info.sha_data.test_type == SHA_MCT)
|
||||
test_ops.test = fips_mct_sha_test;
|
||||
else
|
||||
test_ops.test = fips_generic_test;
|
||||
break;
|
||||
case FIPS_TEST_ALGO_AES_XTS:
|
||||
test_ops.prepare_op = prepare_cipher_op;
|
||||
test_ops.prepare_xform = prepare_xts_xform;
|
||||
test_ops.prepare_sym_op = prepare_cipher_op;
|
||||
test_ops.prepare_sym_xform = prepare_xts_xform;
|
||||
test_ops.test = fips_generic_test;
|
||||
break;
|
||||
case FIPS_TEST_ALGO_RSA:
|
||||
test_ops.prepare_asym_op = prepare_rsa_op;
|
||||
test_ops.prepare_asym_xform = prepare_rsa_xform;
|
||||
test_ops.test = fips_generic_test;
|
||||
break;
|
||||
default:
|
||||
if (strstr(info.file_name, "TECB") ||
|
||||
strstr(info.file_name, "TCBC")) {
|
||||
info.algo = FIPS_TEST_ALGO_TDES;
|
||||
test_ops.prepare_op = prepare_cipher_op;
|
||||
test_ops.prepare_xform = prepare_tdes_xform;
|
||||
test_ops.prepare_sym_op = prepare_cipher_op;
|
||||
test_ops.prepare_sym_xform = prepare_tdes_xform;
|
||||
if (info.interim_info.tdes_data.test_type == TDES_MCT)
|
||||
test_ops.test = fips_mct_tdes_test;
|
||||
else
|
||||
@ -2049,6 +2346,9 @@ fips_test_one_test_group(void)
|
||||
case FIPS_TEST_ALGO_TDES:
|
||||
ret = parse_test_tdes_json_init();
|
||||
break;
|
||||
case FIPS_TEST_ALGO_RSA:
|
||||
ret = parse_test_rsa_json_init();
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ sources = files(
|
||||
'fips_validation_ccm.c',
|
||||
'fips_validation_sha.c',
|
||||
'fips_validation_xts.c',
|
||||
'fips_validation_rsa.c',
|
||||
'fips_dev_self_test.c',
|
||||
'main.c',
|
||||
)
|
||||
@ -26,3 +27,8 @@ if dpdk_conf.has('RTE_HAS_JANSSON')
|
||||
ext_deps += jansson_dep
|
||||
cflags += '-DUSE_JANSSON'
|
||||
endif
|
||||
|
||||
if dpdk_conf.has('RTE_HAS_OPENSSL')
|
||||
ext_deps += openssl_dep
|
||||
cflags += '-DUSE_OPENSSL'
|
||||
endif
|
||||
|
Loading…
Reference in New Issue
Block a user