From patchwork Thu Aug 21 12:30:32 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Robbie King X-Patchwork-Id: 35755 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-pa0-f70.google.com (mail-pa0-f70.google.com [209.85.220.70]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id BF8762055D for ; Thu, 21 Aug 2014 12:31:14 +0000 (UTC) Received: by mail-pa0-f70.google.com with SMTP id lf10sf79374404pab.9 for ; Thu, 21 Aug 2014 05:31:14 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:delivered-to:from:to:date:message-id:in-reply-to :references:subject:precedence:list-id:list-unsubscribe:list-archive :list-post:list-help:list-subscribe:mime-version:errors-to:sender :x-original-sender:x-original-authentication-results:mailing-list :content-type:content-transfer-encoding; bh=RLBj9nF+TfOTie0mq53m0OhtYwRmKllt6U+eKuMwa2s=; b=OiMELMXq/nsKErgRxyusN+uHksEt90Rrk3heDK1K6d3K8UFOo8IX2cLGOxiNL1CGQD CC5pqNV0zfXDlyK/WkOadDPfx6SZmfadHhf3jPokquiMn7hn0DsrGvWTu4A3epzZD1pw M8as8ZqG0Ja0LMSPzdEyvytzencPcT0njEGS2VvyrFAY6dUgFmOM4rAUZRkfNAf9Xx8y few02vVtJW83IOQu0xoWxUhKJamlT8aIbSvm+wR7XoNaaGYbexG1MdR3yLEVIEi+ajN5 JXol84cVJ89k7ct92s8yiSMvuxDVD5/Famlhuid6rpwn20IcLBuca9ysjJD6Tmg4NOYm 3rMg== X-Gm-Message-State: ALoCoQny637FK/7Woc2OWsim9aJP6VB/MElyp1M6vu83WS41zZ7jgI3hAbADIVgwotO/yMpZi95d X-Received: by 10.66.227.37 with SMTP id rx5mr27050941pac.25.1408624274076; Thu, 21 Aug 2014 05:31:14 -0700 (PDT) X-BeenThere: patchwork-forward@linaro.org Received: by 10.140.20.41 with SMTP id 38ls719798qgi.26.gmail; Thu, 21 Aug 2014 05:31:13 -0700 (PDT) X-Received: by 10.52.246.198 with SMTP id xy6mr3416263vdc.7.1408624273952; Thu, 21 Aug 2014 05:31:13 -0700 (PDT) Received: from mail-vc0-x22f.google.com (mail-vc0-x22f.google.com [2607:f8b0:400c:c03::22f]) by mx.google.com with ESMTPS id tb18si12246819vdb.72.2014.08.21.05.31.13 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Thu, 21 Aug 2014 05:31:13 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 2607:f8b0:400c:c03::22f as permitted sender) client-ip=2607:f8b0:400c:c03::22f; Received: by mail-vc0-f175.google.com with SMTP id ik5so10682541vcb.34 for ; Thu, 21 Aug 2014 05:31:13 -0700 (PDT) X-Received: by 10.52.248.42 with SMTP id yj10mr64747vdc.50.1408624273857; Thu, 21 Aug 2014 05:31:13 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.221.45.67 with SMTP id uj3csp131491vcb; Thu, 21 Aug 2014 05:31:13 -0700 (PDT) X-Received: by 10.224.47.6 with SMTP id l6mr89278149qaf.32.1408624273271; Thu, 21 Aug 2014 05:31:13 -0700 (PDT) Received: from ip-10-141-164-156.ec2.internal (lists.linaro.org. [54.225.227.206]) by mx.google.com with ESMTPS id j10si38382423qaf.123.2014.08.21.05.31.12 for (version=TLSv1 cipher=RC4-SHA bits=128/128); Thu, 21 Aug 2014 05:31:13 -0700 (PDT) Received-SPF: none (google.com: lng-odp-bounces@lists.linaro.org does not designate permitted sender hosts) client-ip=54.225.227.206; Received: from localhost ([127.0.0.1] helo=ip-10-141-164-156.ec2.internal) by ip-10-141-164-156.ec2.internal with esmtp (Exim 4.76) (envelope-from ) id 1XKRWK-0004b0-7K; Thu, 21 Aug 2014 12:31:12 +0000 Received: from rcdn-iport-5.cisco.com ([173.37.86.76]) by ip-10-141-164-156.ec2.internal with esmtp (Exim 4.76) (envelope-from ) id 1XKRVu-0004YW-BA for lng-odp@lists.linaro.org; Thu, 21 Aug 2014 12:30:46 +0000 X-IronPort-AV: E=Sophos;i="5.01,909,1400025600"; d="scan'208";a="349218571" Received: from rcdn-core-9.cisco.com ([173.37.93.145]) by rcdn-iport-5.cisco.com with ESMTP; 21 Aug 2014 12:30:41 +0000 Received: from cpp-rtpbld-55.cisco.com (cpp-rtpbld-55.cisco.com [172.18.5.199]) by rcdn-core-9.cisco.com (8.14.5/8.14.5) with ESMTP id s7LCUeSj028070 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Thu, 21 Aug 2014 12:30:41 GMT Received: from cpp-rtpbld-55.cisco.com (localhost.localdomain [127.0.0.1]) by cpp-rtpbld-55.cisco.com (8.13.8/8.13.8) with ESMTP id s7LCUemu012516; Thu, 21 Aug 2014 08:30:40 -0400 Received: (from robking@localhost) by cpp-rtpbld-55.cisco.com (8.13.8/8.13.8/Submit) id s7LCUecB012515; Thu, 21 Aug 2014 08:30:40 -0400 From: Robbie King To: lng-odp@lists.linaro.org Date: Thu, 21 Aug 2014 08:30:32 -0400 Message-Id: <1408624238-12430-8-git-send-email-robking@cisco.com> X-Mailer: git-send-email 1.9.2 In-Reply-To: <1408624238-12430-1-git-send-email-robking@cisco.com> References: <1408624238-12430-1-git-send-email-robking@cisco.com> X-Topics: patch Subject: [lng-odp] [PATCH 07/13] IPsec example app SA/SP/route cache X-BeenThere: lng-odp@lists.linaro.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: , List-Help: , List-Subscribe: , MIME-Version: 1.0 Errors-To: lng-odp-bounces@lists.linaro.org Sender: lng-odp-bounces@lists.linaro.org X-Original-Sender: robking@cisco.com X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 2607:f8b0:400c:c03::22f as permitted sender) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org; dkim=fail header.i=@cisco.com Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 Signed-off-by: Robbie King --- example/ipsec/odp_ipsec_cache.c | 178 +++++++++++++++++++++++++++++++++++++++ example/ipsec/odp_ipsec_cache.h | 127 ++++++++++++++++++++++++++++ 2 files changed, 305 insertions(+), 0 deletions(-) create mode 100644 example/ipsec/odp_ipsec_cache.c create mode 100644 example/ipsec/odp_ipsec_cache.h diff --git a/example/ipsec/odp_ipsec_cache.c b/example/ipsec/odp_ipsec_cache.c new file mode 100644 index 0000000..0ef95b4 --- /dev/null +++ b/example/ipsec/odp_ipsec_cache.c @@ -0,0 +1,178 @@ +/* Copyright (c) 2014, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +#include +#include +#include +#include + +#include + +/** Global pointer to ipsec_cache db */ +ipsec_cache_t *ipsec_cache; + +void init_ipsec_cache(void) +{ + ipsec_cache = odp_shm_reserve("shm_ipsec_cache", + sizeof(ipsec_cache_t), + ODP_CACHE_LINE_SIZE); + if (ipsec_cache == NULL) { + ODP_ERR("Error: shared mem alloc failed.\n"); + exit(EXIT_FAILURE); + } + memset(ipsec_cache, 0, sizeof(*ipsec_cache)); +} + +int create_ipsec_cache_entry(sa_db_entry_t *cipher_sa, + sa_db_entry_t *auth_sa, + crypto_api_mode_e api_mode, + bool in, + odp_queue_t completionq, + odp_buffer_t out_pool) +{ + odp_crypto_session_params_t params; + ipsec_cache_entry_t *entry; + enum odp_crypto_ses_create_err ses_create_rc; + odp_crypto_session_t session; + + /* Verify we have a good entry */ + entry = &ipsec_cache->array[ipsec_cache->index]; + if (MAX_DB <= ipsec_cache->index) + return -1; + + /* Setup parameters and call crypto library to create session */ + params.op = (in) ? ODP_CRYPTO_OP_DECODE : ODP_CRYPTO_OP_ENCODE; + params.auth_cipher_text = TRUE; + if (CRYPTO_API_SYNC == api_mode) { + params.pref_mode = ODP_CRYPTO_SYNC; + params.compl_queue = ODP_QUEUE_INVALID; + params.output_pool = ODP_BUFFER_POOL_INVALID; + } else { + params.pref_mode = ODP_CRYPTO_ASYNC; + params.compl_queue = completionq; + params.output_pool = out_pool; + } + + if (CRYPTO_API_ASYNC_NEW_BUFFER == api_mode) + entry->in_place = FALSE; + else + entry->in_place = TRUE; + + + /* Cipher */ + if (cipher_sa) { + params.cipher_alg = cipher_sa->alg.u.cipher; + params.cipher_key.data = cipher_sa->key.data; + params.cipher_key.length = cipher_sa->key.length; + params.iv.data = entry->state.iv; + params.iv.length = cipher_sa->iv_len; + } else { + params.cipher_alg = ODP_CIPHER_ALG_NULL; + params.iv.data = NULL; + params.iv.length = 0; + } + + /* Auth */ + if (auth_sa) { + params.auth_alg = auth_sa->alg.u.auth; + params.auth_key.data = auth_sa->key.data; + params.auth_key.length = auth_sa->key.length; + } else { + params.auth_alg = ODP_AUTH_ALG_NULL; + } + + /* Generate an IV */ + if (params.iv.length) { + size_t size = params.iv.length; + + odp_hw_random_get(params.iv.data, &size, 1); + } + + /* Synchronous session create for now */ + if (odp_crypto_session_create(¶ms, &session, &ses_create_rc)) + return -1; + if (ODP_CRYPTO_SES_CREATE_ERR_NONE != ses_create_rc) + return -1; + + /* Copy remainder */ + if (cipher_sa) { + entry->src_ip = cipher_sa->src_ip; + entry->dst_ip = cipher_sa->dst_ip; + entry->esp.alg = cipher_sa->alg.u.cipher; + entry->esp.spi = cipher_sa->spi; + entry->esp.block_len = cipher_sa->block_len; + entry->esp.iv_len = cipher_sa->iv_len; + memcpy(&entry->esp.key, &cipher_sa->key, sizeof(ipsec_key_t)); + } + if (auth_sa) { + entry->src_ip = auth_sa->src_ip; + entry->dst_ip = auth_sa->dst_ip; + entry->ah.alg = auth_sa->alg.u.auth; + entry->ah.spi = auth_sa->spi; + entry->ah.icv_len = auth_sa->icv_len; + memcpy(&entry->ah.key, &auth_sa->key, sizeof(ipsec_key_t)); + } + + /* Initialize state */ + entry->state.esp_seq = 0; + entry->state.ah_seq = 0; + entry->state.session = session; + + /* Add entry to the appropriate list */ + ipsec_cache->index++; + if (in) { + entry->next = ipsec_cache->in_list; + ipsec_cache->in_list = entry; + } else { + entry->next = ipsec_cache->out_list; + ipsec_cache->out_list = entry; + } + + return 0; +} + +ipsec_cache_entry_t *find_ipsec_cache_entry_in(uint32_t src_ip, + uint32_t dst_ip, + odp_ahhdr_t *ah, + odp_esphdr_t *esp) +{ + ipsec_cache_entry_t *entry = ipsec_cache->in_list; + + /* Look for a hit */ + for (; NULL != entry; entry = entry->next) { + if ((entry->src_ip != src_ip) || (entry->dst_ip != dst_ip)) + continue; + if (ah && + ((!entry->ah.alg) || + (entry->ah.spi != odp_be_to_cpu_32(ah->spi)))) + continue; + if (esp && + ((!entry->esp.alg) || + (entry->esp.spi != odp_be_to_cpu_32(esp->spi)))) + continue; + break; + } + + return entry; +} + +ipsec_cache_entry_t *find_ipsec_cache_entry_out(uint32_t src_ip, + uint32_t dst_ip, + uint8_t proto ODP_UNUSED) +{ + ipsec_cache_entry_t *entry = ipsec_cache->out_list; + + /* Look for a hit */ + for (; NULL != entry; entry = entry->next) { + if ((entry->src_ip == src_ip) && (entry->dst_ip == dst_ip)) + break; + } + return entry; +} + diff --git a/example/ipsec/odp_ipsec_cache.h b/example/ipsec/odp_ipsec_cache.h new file mode 100644 index 0000000..0b008c3 --- /dev/null +++ b/example/ipsec/odp_ipsec_cache.h @@ -0,0 +1,127 @@ +/* Copyright (c) 2014, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef ODP_IPSEC_CACHE_H_ +#define ODP_IPSEC_CACHE_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +#include +#include + +/** + * Mode specified on command line indicating how to exercise API + */ +typedef enum { + CRYPTO_API_SYNC, /**< Synchronous mode */ + CRYPTO_API_ASYNC_IN_PLACE, /**< Asynchronous in place */ + CRYPTO_API_ASYNC_NEW_BUFFER /**< Asynchronous new buffer */ +} crypto_api_mode_e; + +/** + * IPsec cache data base entry + */ +typedef struct ipsec_cache_entry_s { + struct ipsec_cache_entry_s *next; /**< Next entry on list */ + bool in_place; /**< Crypto API mode */ + uint32_t src_ip; /**< Source v4 address */ + uint32_t dst_ip; /**< Destination v4 address */ + struct { + enum odp_cipher_alg alg; /**< Cipher algorithm */ + uint32_t spi; /**< Cipher SPI */ + uint32_t block_len; /**< Cipher block length */ + uint32_t iv_len; /**< Cipher IV length */ + ipsec_key_t key; /**< Cipher key */ + } esp; + struct { + enum odp_auth_alg alg; /**< Auth algorithm */ + uint32_t spi; /**< Auth SPI */ + uint32_t icv_len; /**< Auth ICV length */ + ipsec_key_t key; /**< Auth key */ + } ah; + + /* Per SA state */ + struct { + odp_crypto_session_t session; /**< Crypto session handle */ + uint32_t esp_seq; /**< ESP TX sequence number */ + uint32_t ah_seq; /**< AH TX sequence number */ + uint8_t iv[32]; /**< ESP IV storage */ + } state; +} ipsec_cache_entry_t; + +/** + * IPsec cache data base global structure + */ +typedef struct ipsec_cache_s { + uint32_t index; /**< Index of next available entry */ + ipsec_cache_entry_t *in_list; /**< List of active input entries*/ + ipsec_cache_entry_t *out_list; /**< List of active output entries*/ + ipsec_cache_entry_t array[MAX_DB]; /**< Entry storage */ +} ipsec_cache_t; + +/** Global pointer to ipsec_cache db */ +extern ipsec_cache_t *ipsec_cache; + +/** Initialize IPsec cache */ +void init_ipsec_cache(void); + +/** + * Create an entry in the IPsec cache + * + * @param cipher_sa Cipher SA DB entry pointer + * @param auth_sa Auth SA DB entry pointer + * @param api_mode Crypto API mode for testing + * @param in Direction (input versus output) + * @param completionq Completion queue + * @param out_pool Output buffer pool + * + * @return 0 if successful else -1 + */ +int create_ipsec_cache_entry(sa_db_entry_t *cipher_sa, + sa_db_entry_t *auth_sa, + crypto_api_mode_e api_mode, + bool in, + odp_queue_t completionq, + odp_buffer_t out_pool); + +/** + * Find a matching IPsec cache entry for input packet + * + * @param src_ip Source IPv4 address + * @param dst_ip Destination IPv4 address + * @param ah Pointer to AH header in packet else NULL + * @param esp Pointer to ESP header in packet else NULL + * + * @return pointer to IPsec cache entry else NULL + */ +ipsec_cache_entry_t *find_ipsec_cache_entry_in(uint32_t src_ip, + uint32_t dst_ip, + odp_ahhdr_t *ah, + odp_esphdr_t *esp); + +/** + * Find a matching IPsec cache entry for output packet + * + * @param src_ip Source IPv4 address + * @param dst_ip Destination IPv4 address + * @param proto IPv4 protocol (currently all protocols match) + * + * @return pointer to IPsec cache entry else NULL + */ +ipsec_cache_entry_t *find_ipsec_cache_entry_out(uint32_t src_ip, + uint32_t dst_ip, + uint8_t proto ODP_UNUSED); + +#ifdef __cplusplus +} +#endif + +#endif