diff mbox

[09/13] IPsec example SA DB

Message ID 1408624238-12430-10-git-send-email-robking@cisco.com
State New
Headers show

Commit Message

Robbie King Aug. 21, 2014, 12:30 p.m. UTC
Signed-off-by: Robbie King <robking@cisco.com>
---
 example/ipsec/odp_ipsec_sa_db.c |  162 +++++++++++++++++++++++++++++++++++++++
 example/ipsec/odp_ipsec_sa_db.h |   77 ++++++++++++++++++
 2 files changed, 239 insertions(+), 0 deletions(-)
 create mode 100644 example/ipsec/odp_ipsec_sa_db.c
 create mode 100644 example/ipsec/odp_ipsec_sa_db.h
diff mbox

Patch

diff --git a/example/ipsec/odp_ipsec_sa_db.c b/example/ipsec/odp_ipsec_sa_db.c
new file mode 100644
index 0000000..f7c0f3c
--- /dev/null
+++ b/example/ipsec/odp_ipsec_sa_db.c
@@ -0,0 +1,162 @@ 
+/* Copyright (c) 2014, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier:     BSD-3-Clause
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <odp.h>
+#include <odp_align.h>
+#include <odp_crypto.h>
+
+#include <odp_ipsec_sa_db.h>
+
+/** Global pointer to sa db */
+static sa_db_t *sa_db;
+
+void init_sa_db(void)
+{
+	sa_db = odp_shm_reserve("shm_sa_db",
+				sizeof(sa_db_t),
+				ODP_CACHE_LINE_SIZE);
+	if (sa_db == NULL) {
+		ODP_ERR("Error: shared mem alloc failed.\n");
+		exit(EXIT_FAILURE);
+	}
+	memset(sa_db, 0, sizeof(*sa_db));
+}
+
+int create_sa_db_entry(char *input, bool cipher)
+{
+	int pos;
+	char *local, *str, *save;
+	sa_db_entry_t *entry = &sa_db->array[sa_db->index];
+
+	/* Verify we have a good entry */
+	if (MAX_DB <= sa_db->index)
+		return -1;
+
+	/* Make a local copy */
+	local = malloc(strlen(input) + 1);
+	if (local == NULL)
+		return -1;
+	strcpy(local, input);
+
+	/* Set cipher versus auth */
+	entry->alg.cipher = cipher;
+
+	/* count the number of tokens separated by ',' */
+	for (str = local, save = NULL, pos = 0;; str = NULL, pos++) {
+		char *token = strtok_r(str, ":", &save);
+
+		/* Check for no more tokens */
+		if (token == NULL)
+			break;
+
+		/* Parse based on postion */
+		switch (pos) {
+		case 0:
+			parse_ipv4_string(token, &entry->src_ip, NULL);
+			break;
+		case 1:
+			parse_ipv4_string(token, &entry->dst_ip, NULL);
+			break;
+		case 2:
+			if (cipher) {
+				if (0 == strcmp(token, "3des")) {
+					entry->alg.u.cipher =
+						ODP_CIPHER_ALG_3DES_CBC;
+					entry->block_len  = 8;
+					entry->iv_len     = 8;
+				} else {
+					entry->alg.u.cipher =
+						ODP_CIPHER_ALG_NULL;
+				}
+			} else {
+				if (0 == strcmp(token, "md5")) {
+					entry->alg.u.auth =
+						ODP_AUTH_ALG_MD5_96;
+					entry->icv_len    = 12;
+				} else {
+					entry->alg.u.auth = ODP_AUTH_ALG_NULL;
+				}
+			}
+			break;
+		case 3:
+			entry->spi = strtol(token, NULL, 16);
+			break;
+		case 4:
+			parse_key_string(token,
+					 &entry->key,
+					 &entry->alg);
+			break;
+		default:
+			return -1;
+		}
+	}
+
+	/* Verify all positions filled */
+	if (5 != pos)
+		return -1;
+
+	/* Add route to the list */
+	sa_db->index++;
+	entry->next = sa_db->list;
+	sa_db->list = entry;
+
+	return 0;
+}
+
+void dump_sa_db(void)
+{
+	sa_db_entry_t *entry;
+
+	printf("\n"
+	       "Security association table\n"
+	       "--------------------------\n");
+
+	for (entry = sa_db->list; NULL != entry; entry = entry->next) {
+		uint32_t idx;
+		char src_ip_str[32];
+		char dst_ip_str[32];
+		uint8_t *p = entry->key.data;
+
+
+		printf(" %s %s %s %X %d ",
+		       entry->alg.cipher ? "esp" : "ah ",
+		       ipv4_addr_str(src_ip_str, entry->src_ip),
+		       ipv4_addr_str(dst_ip_str, entry->dst_ip),
+		       entry->spi,
+		       entry->alg.cipher ?
+		       (int)entry->alg.u.cipher :
+		       (int)entry->alg.u.auth);
+
+		/* Brute force key display */
+		for (idx = 0; idx < entry->key.length; idx++)
+			printf("%02X", *p++);
+
+		printf("\n");
+	}
+}
+
+sa_db_entry_t *find_sa_db_entry(ip_addr_range_t *src,
+				ip_addr_range_t *dst,
+				bool cipher)
+{
+	sa_db_entry_t *entry = NULL;
+
+	/* Scan all entries and return first match */
+	for (entry = sa_db->list; NULL != entry; entry = entry->next) {
+		if (cipher != entry->alg.cipher)
+			continue;
+		if (!match_ip_range(entry->src_ip, src))
+			continue;
+		if (!match_ip_range(entry->dst_ip, dst))
+			continue;
+		break;
+	}
+	return entry;
+}
+
diff --git a/example/ipsec/odp_ipsec_sa_db.h b/example/ipsec/odp_ipsec_sa_db.h
new file mode 100644
index 0000000..fa9180a
--- /dev/null
+++ b/example/ipsec/odp_ipsec_sa_db.h
@@ -0,0 +1,77 @@ 
+/* Copyright (c) 2014, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier:     BSD-3-Clause
+ */
+
+#ifndef ODP_IPSEC_SA_DB_H_
+#define ODP_IPSEC_SA_DB_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <odp_ipsec_misc.h>
+
+/**
+ * Security Assocation (SA) data base entry
+ */
+typedef struct sa_db_entry_s {
+	struct sa_db_entry_s *next;      /**< Next entry on list */
+	uint32_t              src_ip;    /**< Source IPv4 address */
+	uint32_t              dst_ip;    /**< Desitnation IPv4 address */
+	uint32_t              spi;       /**< Security Parameter Index */
+	ipsec_alg_t           alg;       /**< Cipher/auth algorithm */
+	ipsec_key_t           key;       /**< Cipher/auth key */
+	uint32_t              block_len; /**< Cipher block length */
+	uint32_t              iv_len;    /**< Initialization Vector length */
+	uint32_t              icv_len;   /**< Integrity Check Value length */
+} sa_db_entry_t;
+
+/**
+ * Security Assocation (SA) data base global structure
+ */
+typedef struct sa_db_s {
+	uint32_t         index;          /**< Index of next available entry */
+	sa_db_entry_t   *list;           /**< List of active entries */
+	sa_db_entry_t    array[MAX_DB];  /**< Entry storage */
+} sa_db_t;
+
+/** Initialize SA database global control structure */
+void init_sa_db(void);
+
+/**
+ * Create an SA DB entry
+ *
+ * String is of the format "SrcIP:DstIP:Alg:SPI:Key"
+ *
+ * @param input  Pointer to string describing SA
+ * @param cipher TRUE if cipher else FALSE for auth
+ *
+ * @return 0 if successful else -1
+ */
+int create_sa_db_entry(char *input, bool cipher);
+/**
+ * Display the SA DB
+ */
+void dump_sa_db(void);
+
+/**
+ * Find a matching SA DB entry
+ *
+ * @param src    Pointer to source subnet/range
+ * @param dst    Pointer to destination subnet/range
+ * @param cipher TRUE if cipher else FALSE for auth
+ *
+ * @return pointer to SA DB entry else NULL
+ */
+sa_db_entry_t *find_sa_db_entry(ip_addr_range_t *src,
+				ip_addr_range_t *dst,
+				bool cipher);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+