diff options
author | Janne Peltonen <janne.peltonen@nokia.com> | 2022-02-17 16:45:29 +0200 |
---|---|---|
committer | Petri Savolainen <petri.savolainen@nokia.com> | 2022-02-25 13:59:18 +0200 |
commit | 562d9a69328bbb6a94159eaeff2af652268366e6 (patch) | |
tree | baa0078fbe863a80e929764efbfeb502849fafd7 /example | |
parent | 11db078594a86f3af9d6a27382692e179504a209 (diff) |
example: ipsec_crypto: fix crypto capability checking
Check that the used algorithm as well as key length etc are supported
before trying to create a crypto session. Give up if the used ODP
implementation supports the algorithm in bit mode since the code expects
byte mode and would pass incorrect auth_range to an implementation which
works in bit mode.
Signed-off-by: Janne Peltonen <janne.peltonen@nokia.com>
Reviewed-by: Jere Leppänen <jere.leppanen@nokia.com>
Diffstat (limited to 'example')
-rw-r--r-- | example/ipsec_api/odp_ipsec.c | 7 | ||||
-rw-r--r-- | example/ipsec_crypto/odp_ipsec.c | 117 | ||||
-rw-r--r-- | example/ipsec_crypto/odp_ipsec_sa_db.c | 7 |
3 files changed, 130 insertions, 1 deletions
diff --git a/example/ipsec_api/odp_ipsec.c b/example/ipsec_api/odp_ipsec.c index d7d78c41b..c277a5a22 100644 --- a/example/ipsec_api/odp_ipsec.c +++ b/example/ipsec_api/odp_ipsec.c @@ -1396,3 +1396,10 @@ static void usage(char *progname) "\n", NO_PATH(progname), NO_PATH(progname) ); } + +odp_bool_t sa_config_supported(const sa_db_entry_t *sa_entry); + +odp_bool_t sa_config_supported(const sa_db_entry_t *sa_entry ODP_UNUSED) +{ + return true; +} diff --git a/example/ipsec_crypto/odp_ipsec.c b/example/ipsec_crypto/odp_ipsec.c index 2520d9fa1..7b1123c5c 100644 --- a/example/ipsec_crypto/odp_ipsec.c +++ b/example/ipsec_crypto/odp_ipsec.c @@ -1,5 +1,5 @@ /* Copyright (c) 2013-2018, Linaro Limited - * Copyright (c) 2021, Nokia + * Copyright (c) 2021-2022, Nokia * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause @@ -100,6 +100,7 @@ typedef struct { int num_polled_queues; /* Stop workers if set to 1 */ odp_atomic_u32_t exit_threads; + odp_crypto_capability_t crypto_capa; } global_data_t; /* helper funcs */ @@ -1292,6 +1293,7 @@ main(int argc, char *argv[]) memset(global, 0, sizeof(global_data_t)); global->shm = shm; odp_atomic_init_u32(&global->exit_threads, 0); + global->crypto_capa = crypto_capa; /* Configure scheduler */ odp_schedule_config(NULL); @@ -1684,3 +1686,116 @@ static void usage(char *progname) "\n", NO_PATH(progname), NO_PATH(progname) ); } + +static odp_bool_t cipher_supported(odp_cipher_alg_t alg, const sa_db_entry_t *sa) +{ + const odp_crypto_cipher_algos_t *algos = &global->crypto_capa.ciphers; + odp_bool_t alg_ok = true; + int num; + + switch (alg) { + case ODP_CIPHER_ALG_NULL: + if (!algos->bit.null) + alg_ok = false; + break; + case ODP_CIPHER_ALG_3DES_CBC: + if (!algos->bit.trides_cbc) + alg_ok = false; + break; + default: + alg_ok = false; + break; + } + if (!alg_ok) { + printf("ERROR: cipher algorithm not supported\n"); + return false; + } + + num = odp_crypto_cipher_capability(alg, NULL, 0); + if (num < 0) { + printf("ERROR: odp_crypto_cipher_capability() failed\n"); + return false; + } + odp_crypto_cipher_capability_t cipher_capa[num]; + + (void)odp_crypto_cipher_capability(alg, cipher_capa, num); + for (int n = 0; n < num; n++) { + odp_crypto_cipher_capability_t *capa = &cipher_capa[n]; + + if (capa->key_len == sa->key.length && + capa->iv_len == sa->iv_len) { + if (capa->bit_mode && alg != ODP_CIPHER_ALG_NULL) { + printf("ERROR: bit mode cipher not supported\n"); + return false; + } + return true; + } + } + printf("ERROR: cipher key length or IV length not supported\n"); + return false; +} + +static odp_bool_t auth_supported(odp_auth_alg_t alg, const sa_db_entry_t *sa) +{ + const odp_crypto_auth_algos_t *algos = &global->crypto_capa.auths; + odp_bool_t alg_ok = true; + int num; + + switch (alg) { + case ODP_AUTH_ALG_NULL: + if (!algos->bit.null) + alg_ok = false; + break; + case ODP_AUTH_ALG_MD5_HMAC: + if (!algos->bit.md5_hmac) + alg_ok = false; + break; + case ODP_AUTH_ALG_SHA1_HMAC: + if (!algos->bit.sha1_hmac) + alg_ok = false; + break; + case ODP_AUTH_ALG_SHA256_HMAC: + if (!algos->bit.sha256_hmac) + alg_ok = false; + break; + default: + alg_ok = false; + break; + } + if (!alg_ok) { + printf("ERROR: auth algorithm not supported\n"); + return false; + } + + num = odp_crypto_auth_capability(alg, NULL, 0); + if (num < 0) { + printf("ERROR: odp_crypto_auth_capability() failed\n"); + return false; + } + odp_crypto_auth_capability_t auth_capa[num]; + + (void)odp_crypto_auth_capability(alg, auth_capa, num); + for (int n = 0; n < num; n++) { + odp_crypto_auth_capability_t *capa = &auth_capa[n]; + + if (capa->digest_len == sa->icv_len && + capa->key_len == sa->key.length && + capa->iv_len == 0) { + if (capa->bit_mode && alg != ODP_AUTH_ALG_NULL) { + printf("ERROR: bit mode auth not supported\n"); + return false; + } + return true; + } + } + printf("ERROR: auth ICV length or key length not supported\n"); + return false; +} + +odp_bool_t sa_config_supported(const sa_db_entry_t *sa); + +odp_bool_t sa_config_supported(const sa_db_entry_t *sa) +{ + return sa->alg.cipher ? cipher_supported(sa->alg.u.cipher, sa) + : auth_supported(sa->alg.u.auth, sa); +} diff --git a/example/ipsec_crypto/odp_ipsec_sa_db.c b/example/ipsec_crypto/odp_ipsec_sa_db.c index 0d60cbc7a..22593bd00 100644 --- a/example/ipsec_crypto/odp_ipsec_sa_db.c +++ b/example/ipsec_crypto/odp_ipsec_sa_db.c @@ -17,6 +17,8 @@ #include <odp_ipsec_sa_db.h> +odp_bool_t sa_config_supported(const sa_db_entry_t *sa); + /** Global pointer to sa db */ static sa_db_t *sa_db; @@ -163,6 +165,11 @@ int create_sa_db_entry(char *input, odp_bool_t cipher) return -1; } + if (!sa_config_supported(entry)) { + free(local); + return -1; + } + /* Add route to the list */ sa_db->index++; entry->next = sa_db->list; |