summaryrefslogtreecommitdiffstats
path: root/src/framework/common/data_struct
diff options
context:
space:
mode:
Diffstat (limited to 'src/framework/common/data_struct')
-rw-r--r--src/framework/common/data_struct/eprb_tree.c492
-rw-r--r--src/framework/common/data_struct/list.c163
-rw-r--r--src/framework/common/data_struct/pidinfo.c125
-rw-r--r--src/framework/common/data_struct/sha256.c397
4 files changed, 1177 insertions, 0 deletions
diff --git a/src/framework/common/data_struct/eprb_tree.c b/src/framework/common/data_struct/eprb_tree.c
new file mode 100644
index 0000000..c8af17c
--- /dev/null
+++ b/src/framework/common/data_struct/eprb_tree.c
@@ -0,0 +1,492 @@
+/*
+*
+* Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at:
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#include "eprb_tree.h"
+
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+extern "C" {
+/* *INDENT-ON* */
+#endif
+
+/*
+ * This function returns the first node (in sort order) of the tree.
+ */
+struct ep_rb_node *
+ep_rb_first (const struct ep_rb_root *root)
+{
+ if (NULL == root)
+ return NULL;
+
+ struct ep_rb_node *n;
+ n = (struct ep_rb_node *) ADDR_SHTOL (root->rb_node);
+
+ if (!n)
+ {
+ return NULL;
+ }
+
+ while (n->rb_left)
+ {
+ n = (struct ep_rb_node *) ADDR_SHTOL (n->rb_left);
+ }
+
+ return n;
+}
+
+void
+__ep_rb_rotate_left (struct ep_rb_node *X, struct ep_rb_root *root)
+{
+ /**************************
+ * rotate Node X to left *
+ **************************/
+ struct ep_rb_node *Y = (struct ep_rb_node *) ADDR_SHTOL (X->rb_right);
+
+ /* estblish X->Right link */
+ X->rb_right = Y->rb_left;
+
+ if (Y->rb_left != NULL)
+ {
+ ((struct ep_rb_node *) ADDR_SHTOL (Y->rb_left))->rb_parent =
+ (struct ep_rb_node *) ADDR_LTOSH_EXT (X);
+ }
+
+ /* estblish Y->Parent link */
+ Y->rb_parent = X->rb_parent;
+
+ if (X->rb_parent)
+ {
+ struct ep_rb_node *xParent =
+ (struct ep_rb_node *) ADDR_SHTOL (X->rb_parent);
+
+ if (X == ADDR_SHTOL (xParent->rb_left))
+ {
+ xParent->rb_left = (struct ep_rb_node *) ADDR_LTOSH_EXT (Y);
+ }
+ else
+ {
+ xParent->rb_right = (struct ep_rb_node *) ADDR_LTOSH_EXT (Y);
+ }
+ }
+ else
+ {
+ root->rb_node = (struct ep_rb_node *) ADDR_LTOSH_EXT (Y);
+ }
+
+ /* link X and Y */
+ Y->rb_left = (struct ep_rb_node *) ADDR_LTOSH_EXT (X);
+ X->rb_parent = (struct ep_rb_node *) ADDR_LTOSH_EXT (Y);
+
+ return;
+}
+
+void
+__ep_rb_rotate_right (struct ep_rb_node *X, struct ep_rb_root *root)
+{
+ /****************************
+ * rotate Node X to right *
+ ****************************/
+ struct ep_rb_node *Y = (struct ep_rb_node *) ADDR_SHTOL (X->rb_left);
+
+ /* estblish X->Left link */
+ X->rb_left = Y->rb_right;
+
+ if (Y->rb_right != NULL)
+ {
+ ((struct ep_rb_node *) ADDR_SHTOL (Y->rb_right))->rb_parent =
+ (struct ep_rb_node *) ADDR_LTOSH_EXT (X);
+ }
+
+ /* estblish Y->Parent link */
+ Y->rb_parent = X->rb_parent;
+
+ if (X->rb_parent)
+ {
+ struct ep_rb_node *xParent =
+ (struct ep_rb_node *) ADDR_SHTOL (X->rb_parent);
+
+ if (X == (struct ep_rb_node *) ADDR_SHTOL (xParent->rb_right))
+ {
+ xParent->rb_right = (struct ep_rb_node *) ADDR_LTOSH_EXT (Y);
+ }
+ else
+ {
+ xParent->rb_left = (struct ep_rb_node *) ADDR_LTOSH_EXT (Y);
+ }
+ }
+ else
+ {
+ root->rb_node = (struct ep_rb_node *) ADDR_LTOSH_EXT (Y);
+ }
+
+ /* link X and Y */
+ Y->rb_right = (struct ep_rb_node *) ADDR_LTOSH_EXT (X);
+ X->rb_parent = (struct ep_rb_node *) ADDR_LTOSH_EXT (Y);
+
+ return;
+}
+
+#define EP_RBTREE_PARENT(X) ((struct ep_rb_node*) ADDR_SHTOL((X)->rb_parent))
+#define EP_RBTREE_GRANDF(X) EP_RBTREE_PARENT(EP_RBTREE_PARENT(X))
+
+/* X, Y are for application */
+void
+ep_rb_insert_color (struct ep_rb_node *X, struct ep_rb_root *root)
+{
+ /*************************************
+ * maintain red-black tree balance *
+ * after inserting node X *
+ *************************************/
+ /* check red-black properties */
+ while (X != (struct ep_rb_node *) ADDR_SHTOL (root->rb_node)
+ && EP_RBTREE_PARENT (X)->color == EP_RB_RED)
+ {
+ /* we have a violation */
+ if (X->rb_parent == EP_RBTREE_GRANDF (X)->rb_left)
+ {
+ struct ep_rb_node *Y =
+ (struct ep_rb_node *) ADDR_SHTOL (EP_RBTREE_GRANDF (X)->rb_right);
+
+ if (Y && Y->color == EP_RB_RED)
+ {
+
+ /* uncle is red */
+ EP_RBTREE_PARENT (X)->color = EP_RB_BLACK;
+ Y->color = EP_RB_BLACK;
+ EP_RBTREE_GRANDF (X)->color = EP_RB_RED;
+ X = EP_RBTREE_GRANDF (X);
+ }
+ else
+ {
+
+ /* uncle is black */
+ if (X ==
+ (struct ep_rb_node *)
+ ADDR_SHTOL (EP_RBTREE_PARENT (X)->rb_right))
+ {
+ /* make X a left child */
+ X = EP_RBTREE_PARENT (X);
+ __ep_rb_rotate_left (X, root);
+ }
+
+ /* recolor and rotate */
+ EP_RBTREE_PARENT (X)->color = EP_RB_BLACK;
+ EP_RBTREE_GRANDF (X)->color = EP_RB_RED;
+ __ep_rb_rotate_right (EP_RBTREE_GRANDF (X), root);
+ }
+ }
+ else
+ {
+ /* miror image of above code */
+ struct ep_rb_node *Y =
+ (struct ep_rb_node *) ADDR_SHTOL (EP_RBTREE_GRANDF (X)->rb_left);
+
+ if (Y && (Y->color == EP_RB_RED))
+ {
+
+ /* uncle is red */
+ EP_RBTREE_PARENT (X)->color = EP_RB_BLACK;
+ Y->color = EP_RB_BLACK;
+ EP_RBTREE_GRANDF (X)->color = EP_RB_RED;
+ X = EP_RBTREE_GRANDF (X);
+ }
+ else
+ {
+
+ /* uncle is black */
+ if (X ==
+ (struct ep_rb_node *)
+ ADDR_SHTOL (EP_RBTREE_PARENT (X)->rb_left))
+ {
+ X = EP_RBTREE_PARENT (X);
+ __ep_rb_rotate_right (X, root);
+ }
+
+ EP_RBTREE_PARENT (X)->color = EP_RB_BLACK;
+ EP_RBTREE_GRANDF (X)->color = EP_RB_RED;
+ __ep_rb_rotate_left (EP_RBTREE_GRANDF (X), root);
+ }
+ }
+ }
+
+ ((struct ep_rb_node *) ADDR_SHTOL (root->rb_node))->color = EP_RB_BLACK;
+
+ return;
+}
+
+void
+__ep_rb_erase_color (struct ep_rb_node *X, struct ep_rb_node *Parent,
+ struct ep_rb_root *root)
+{
+ /*************************************
+ * maintain red-black tree balance *
+ * after deleting node X *
+ *************************************/
+ while (X != (struct ep_rb_node *) ADDR_SHTOL (root->rb_node)
+ && (!X || X->color == EP_RB_BLACK))
+ {
+
+ if (Parent == NULL)
+ {
+ break;
+ }
+
+ if (X == (struct ep_rb_node *) ADDR_SHTOL (Parent->rb_left))
+ {
+ struct ep_rb_node *W =
+ (struct ep_rb_node *) ADDR_SHTOL (Parent->rb_right);
+
+ if (W->color == EP_RB_RED)
+ {
+ W->color = EP_RB_BLACK;
+ Parent->color = EP_RB_RED; /* Parent != NIL? */
+ __ep_rb_rotate_left (Parent, root);
+ W = (struct ep_rb_node *) ADDR_SHTOL (Parent->rb_right);
+ }
+
+ if ((!W->rb_left
+ || ((struct ep_rb_node *) ADDR_SHTOL (W->rb_left))->color ==
+ EP_RB_BLACK) && (!W->rb_right
+ || ((struct ep_rb_node *)
+ ADDR_SHTOL (W->rb_right))->color ==
+ EP_RB_BLACK))
+ {
+ W->color = EP_RB_RED;
+ X = Parent;
+ Parent = (struct ep_rb_node *) ADDR_SHTOL (X->rb_parent);
+ }
+ else
+ {
+ if (!W->rb_right
+ || ((struct ep_rb_node *) ADDR_SHTOL (W->rb_right))->color
+ == EP_RB_BLACK)
+ {
+ if (W->rb_left != NULL)
+ {
+ ((struct ep_rb_node *) ADDR_SHTOL (W->rb_left))->color
+ = EP_RB_BLACK;
+ }
+
+ W->color = EP_RB_RED;
+ __ep_rb_rotate_right (W, root);
+ W = (struct ep_rb_node *) ADDR_SHTOL (Parent->rb_right);
+ }
+
+ W->color = Parent->color;
+ Parent->color = EP_RB_BLACK;
+
+ if (((struct ep_rb_node *) ADDR_SHTOL (W->rb_right))->color !=
+ EP_RB_BLACK)
+ {
+ ((struct ep_rb_node *) ADDR_SHTOL (W->rb_right))->color =
+ EP_RB_BLACK;
+ }
+
+ __ep_rb_rotate_left (Parent, root);
+ X = (struct ep_rb_node *) ADDR_SHTOL (root->rb_node);
+ break;
+ }
+ }
+ else
+ {
+
+ struct ep_rb_node *W =
+ (struct ep_rb_node *) ADDR_SHTOL (Parent->rb_left);
+
+ if (W->color == EP_RB_RED)
+ {
+ W->color = EP_RB_BLACK;
+ Parent->color = EP_RB_RED; /* Parent != NIL? */
+ __ep_rb_rotate_right (Parent, root);
+ W = (struct ep_rb_node *) ADDR_SHTOL (Parent->rb_left);
+ }
+
+ if ((!W->rb_left
+ || (((struct ep_rb_node *) ADDR_SHTOL (W->rb_left))->color ==
+ EP_RB_BLACK)) && (!W->rb_right
+ ||
+ (((struct ep_rb_node *)
+ ADDR_SHTOL (W->rb_right))->color ==
+ EP_RB_BLACK)))
+ {
+ W->color = EP_RB_RED;
+ X = Parent;
+ Parent = (struct ep_rb_node *) ADDR_SHTOL (X->rb_parent);
+ }
+ else
+ {
+ if (!W->rb_left
+ || ((struct ep_rb_node *) ADDR_SHTOL (W->rb_left))->color
+ == EP_RB_BLACK)
+ {
+ if (W->rb_right != NULL)
+ {
+ ((struct ep_rb_node *)
+ ADDR_SHTOL (W->rb_right))->color = EP_RB_BLACK;
+ }
+
+ W->color = EP_RB_RED;
+ __ep_rb_rotate_left (W, root);
+ W = (struct ep_rb_node *) ADDR_SHTOL (Parent->rb_left);
+ }
+
+ W->color = Parent->color;
+ Parent->color = EP_RB_BLACK;
+
+ if (((struct ep_rb_node *) ADDR_SHTOL (W->rb_left))->color !=
+ EP_RB_BLACK)
+ {
+ ((struct ep_rb_node *) ADDR_SHTOL (W->rb_left))->color =
+ EP_RB_BLACK;
+ }
+
+ __ep_rb_rotate_right (Parent, root);
+ X = (struct ep_rb_node *) ADDR_SHTOL (root->rb_node);
+ break;
+ }
+ }
+ }
+
+ if (X)
+ {
+ X->color = EP_RB_BLACK;
+ }
+
+ return;
+}
+
+void
+ep_rb_erase (struct ep_rb_node *node, struct ep_rb_root *root)
+{
+ struct ep_rb_node *child, *parent;
+ int color;
+
+ if (!node->rb_left)
+ {
+ child = (struct ep_rb_node *) ADDR_SHTOL (node->rb_right);
+ }
+ else if (!node->rb_right)
+ {
+ child = (struct ep_rb_node *) ADDR_SHTOL (node->rb_left);
+ }
+ else
+ {
+ struct ep_rb_node *old = node, *left;
+
+ node = (struct ep_rb_node *) ADDR_SHTOL (node->rb_right);
+
+ while ((left =
+ (struct ep_rb_node *) ADDR_SHTOL (node->rb_left)) != NULL)
+ {
+ node = left;
+ }
+
+ if (old->rb_parent)
+ {
+ struct ep_rb_node *oldParent =
+ (struct ep_rb_node *) ADDR_SHTOL (old->rb_parent);
+
+ if (oldParent->rb_left ==
+ (struct ep_rb_node *) ADDR_LTOSH_EXT (old))
+ {
+ oldParent->rb_left =
+ (struct ep_rb_node *) ADDR_LTOSH_EXT (node);
+ }
+ else
+ {
+ oldParent->rb_right =
+ (struct ep_rb_node *) ADDR_LTOSH_EXT (node);
+ }
+ }
+ else
+ {
+ root->rb_node = (struct ep_rb_node *) ADDR_LTOSH_EXT (node);
+ }
+
+ child = (struct ep_rb_node *) ADDR_SHTOL (node->rb_right);
+ parent = (struct ep_rb_node *) ADDR_SHTOL (node->rb_parent);
+ color = node->color;
+
+ if (parent == old)
+ {
+ parent = node;
+ }
+ else
+ {
+ if (child)
+ {
+ child->rb_parent =
+ (struct ep_rb_node *) ADDR_LTOSH_EXT (parent);
+ }
+
+ parent->rb_left = (struct ep_rb_node *) ADDR_LTOSH_EXT (child);
+
+ node->rb_right = old->rb_right;
+ ((struct ep_rb_node *) ADDR_SHTOL (old->rb_right))->rb_parent =
+ (struct ep_rb_node *) ADDR_LTOSH_EXT (node);
+ }
+
+ node->color = old->color;
+ node->rb_parent = old->rb_parent;
+ node->rb_left = old->rb_left;
+ ((struct ep_rb_node *) ADDR_SHTOL (old->rb_left))->rb_parent =
+ (struct ep_rb_node *) ADDR_LTOSH_EXT (node);
+
+ if (color == EP_RB_BLACK)
+ {
+ __ep_rb_erase_color (child, parent, root);
+ }
+
+ return;
+
+ }
+
+ parent = (struct ep_rb_node *) ADDR_SHTOL (node->rb_parent);
+ color = node->color;
+
+ if (child)
+ {
+ child->rb_parent = (struct ep_rb_node *) ADDR_LTOSH_EXT (parent);
+ }
+
+ if (parent)
+ {
+ if (parent->rb_left == (struct ep_rb_node *) ADDR_LTOSH_EXT (node))
+ {
+ parent->rb_left = (struct ep_rb_node *) ADDR_LTOSH_EXT (child);
+ }
+ else
+ {
+ parent->rb_right = (struct ep_rb_node *) ADDR_LTOSH_EXT (child);
+ }
+ }
+ else
+ {
+ root->rb_node = (struct ep_rb_node *) ADDR_LTOSH_EXT (child);
+ }
+
+ if (color == EP_RB_BLACK)
+ {
+ __ep_rb_erase_color (child, parent, root);
+ }
+ return;
+}
+
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+}
+/* *INDENT-ON* */
+#endif
diff --git a/src/framework/common/data_struct/list.c b/src/framework/common/data_struct/list.c
new file mode 100644
index 0000000..7645640
--- /dev/null
+++ b/src/framework/common/data_struct/list.c
@@ -0,0 +1,163 @@
+/*
+*
+* Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at:
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#include "list.h"
+
+/**
+ * list_empty - tests whether a list is empty
+ * @head: the list to test.
+ */
+inline int
+list_empty (const struct list_head *head)
+{
+ return head->next == head;
+}
+
+inline void
+list_del (struct list_head *entry)
+{
+ if (entry->prev == NULL || entry->next == NULL)
+ {
+ return;
+ }
+ entry->next->prev = entry->prev;
+ entry->prev->next = entry->next;
+ entry->next = NULL;
+ entry->prev = NULL;
+}
+
+/*get the first element of the list, need to check if list empty or not before calling this.*/
+inline struct list_head *
+list_get_first (struct list_head *head)
+{
+ return head->next;
+}
+
+inline void
+list_add (struct list_head *newp, struct list_head *head)
+{
+ head->next->prev = newp;
+ newp->next = head->next;
+ newp->prev = head;
+ head->next = newp;
+}
+
+inline void
+list_link (struct list_head *newhead, struct list_head *head)
+{
+ struct list_head *tmp;
+
+ newhead->prev->next = head;
+ head->prev->next = newhead;
+
+ tmp = newhead->prev;
+ newhead->prev = head->prev;
+ head->prev = tmp;
+}
+
+inline void
+list_add_tail (struct list_head *newp, struct list_head *head)
+{
+ list_add (newp, head->prev);
+}
+
+inline void
+hlist_del_init (struct hlist_node *n)
+{
+ struct hlist_node *next = n->next;
+ struct hlist_node **pprev = n->pprev;
+
+ if (pprev == NULL && next == NULL)
+ {
+ return;
+ }
+
+ if (pprev)
+ {
+ *pprev = next;
+ }
+
+ if (next)
+ {
+ next->pprev = pprev;
+ }
+
+ n->next = NULL;
+ n->pprev = NULL;
+}
+
+/**
+ * next must be != NULL
+ * add n node before next node
+ *
+ * @n: new node
+ * @next: node in the hlist
+ */
+inline void
+hlist_add_before (struct hlist_node *n, struct hlist_node *next)
+{
+ n->pprev = next->pprev;
+ n->next = next;
+ next->pprev = &n->next;
+ *(n->pprev) = n;
+}
+
+/**
+ * next must be != NULL
+ * add n node after next node
+ * actual behavior is add after n
+ * @n: node in the hlist
+ * @next: new node
+ */
+inline void
+hlist_add_after (struct hlist_node *n, struct hlist_node *next)
+{
+ next->next = n->next;
+ n->next = next;
+ next->pprev = &n->next;
+ if (next->next)
+ {
+ next->next->pprev = &next->next;
+ }
+}
+
+/* add after the head */
+inline void
+hlist_add_head (struct hlist_node *n, struct hlist_head *h)
+{
+ struct hlist_node *first = h->first;
+
+ n->next = first;
+ if (first)
+ {
+ first->pprev = &n->next;
+ }
+
+ h->first = n;
+ n->pprev = &h->first;
+}
+
+inline int
+hlist_unhashed (const struct hlist_node *h)
+{
+ return !h->pprev;
+}
+
+inline int
+hlist_empty (const struct hlist_head *h)
+{
+ return !h->first;
+}
diff --git a/src/framework/common/data_struct/pidinfo.c b/src/framework/common/data_struct/pidinfo.c
new file mode 100644
index 0000000..08e551f
--- /dev/null
+++ b/src/framework/common/data_struct/pidinfo.c
@@ -0,0 +1,125 @@
+/*
+*
+* Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at:
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#include "pidinfo.h"
+#include "nstack_securec.h"
+
+inline i32
+nsfw_pidinfo_init (nsfw_pidinfo * pidinfo)
+{
+ int retVal =
+ MEMSET_S (pidinfo, sizeof (nsfw_pidinfo), 0, sizeof (nsfw_pidinfo));
+ if (EOK != retVal)
+ {
+ return -1;
+ }
+
+ return 0;
+}
+
+inline int
+nsfw_add_pid (nsfw_pidinfo * pidinfo, u32 pid)
+{
+ u32 i;
+
+ for (i = 0; i < NSFW_MAX_FORK_NUM; i++)
+ {
+ if ((0 == pidinfo->apid[i])
+ && (__sync_bool_compare_and_swap (&pidinfo->apid[i], 0, pid)))
+ {
+ if (pidinfo->used_size < i + 1)
+ {
+ pidinfo->used_size = i + 1;
+ }
+ return 0;
+ }
+ }
+ return -1;
+}
+
+inline int
+nsfw_del_pid (nsfw_pidinfo * pidinfo, u32 pid)
+{
+ u32 i;
+
+ for (i = 0; i < pidinfo->used_size && i < NSFW_MAX_FORK_NUM; i++)
+ {
+ if (pid == pidinfo->apid[i])
+ {
+ pidinfo->apid[i] = 0;
+ return 0;
+ }
+ }
+ return -1;
+}
+
+inline int
+nsfw_del_last_pid (nsfw_pidinfo * pidinfo, u32 pid)
+{
+ u32 i;
+ int count = 0;
+ int deleted = 0;
+ for (i = 0; i < pidinfo->used_size && i < NSFW_MAX_FORK_NUM; i++)
+ {
+ if (pid == pidinfo->apid[i])
+ {
+ pidinfo->apid[i] = 0;
+ deleted = 1;
+ continue;
+ }
+
+ if (pidinfo->apid[i] != 0)
+ {
+ ++count;
+ }
+ }
+
+ if (!deleted)
+ {
+ return -1;
+ }
+
+ return count;
+}
+
+inline int
+nsfw_pid_exist (nsfw_pidinfo * pidinfo, u32 pid)
+{
+ u32 i;
+
+ for (i = 0; i < pidinfo->used_size && i < NSFW_MAX_FORK_NUM; i++)
+ {
+ if (pid == pidinfo->apid[i])
+ {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+inline int
+nsfw_pidinfo_empty (nsfw_pidinfo * pidinfo)
+{
+ u32 i;
+ for (i = 0; i < pidinfo->used_size && i < NSFW_MAX_FORK_NUM; i++)
+ {
+ if (pidinfo->apid[i] != 0)
+ {
+ return 0;
+ }
+ }
+ return 1;
+}
diff --git a/src/framework/common/data_struct/sha256.c b/src/framework/common/data_struct/sha256.c
new file mode 100644
index 0000000..504b365
--- /dev/null
+++ b/src/framework/common/data_struct/sha256.c
@@ -0,0 +1,397 @@
+/*
+*
+* Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at:
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+/*Possible access of out-of-bounds pointer:
+ The algorithms has been tested on purify. So no
+ out of bounds access possible.*/
+
+/*Possible creation of out-of-bounds pointer
+ No Out of bounds pointers are created.- false positive.*/
+
+#include <string.h> /* for mem copy function etc. */
+#include "sha256.h"
+#include "nstack_securec.h"
+#include "types.h"
+#include "nstack_log.h"
+
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+extern "C" {
+/* *INDENT-ON* */
+#endif
+
+#define rotl32(x,n) (((x) << n) | ((x) >> (32 - n)))
+#define rotr32(x,n) (((x) >> n) | ((x) << (32 - n)))
+
+#if !defined(bswap_32)
+#define bswap_32(x) ((rotr32((x), 24) & 0x00ff00ff) | (rotr32((x), 8) & 0xff00ff00))
+#endif
+
+#ifdef LITTLE_ENDIAN
+#define SWAP_BYTES
+#else
+#undef SWAP_BYTES
+#endif
+
+#define ch(x,y,z) ((z) ^ ((x) & ((y) ^ (z))))
+#define maj(x,y,z) (((x) & (y)) | ((z) & ((x) ^ (y))))
+
+ /* round transforms for SHA256 and SHA512 compression functions */
+
+#define vf(n,i) v[(n - i) & 7]
+
+#define hf(i) (p[i & 15] += \
+ g_1(p[(i + 14) & 15]) + p[(i + 9) & 15] + g_0(p[(i + 1) & 15]))
+
+#define v_cycle(i,j) \
+{ \
+ vf(7,i) += (j ? hf(i) : p[i]) + k_0[i+j] \
+ + s_1(vf(4,i)) + ch(vf(4,i),vf(5,i),vf(6,i)); \
+ vf(3,i) += vf(7,i); \
+ vf(7,i) += s_0(vf(0,i))+ maj(vf(0,i),vf(1,i),vf(2,i)); \
+}
+
+#define SHA256_MASK (SHA256_BLOCK_SIZE - 1)
+
+#if defined(SWAP_BYTES)
+#define bsw_32(p,n) \
+{ \
+ u32 _i = (n); \
+ while (_i--) \
+ { \
+ ((u32*)p)[_i] = bswap_32(((u32*)p)[_i]); \
+ } \
+}
+
+#else
+#define bsw_32(p,n)
+#endif
+
+#define s_0(x) (rotr32((x), 2) ^ rotr32((x), 13) ^ rotr32((x), 22))
+#define s_1(x) (rotr32((x), 6) ^ rotr32((x), 11) ^ rotr32((x), 25))
+#define g_0(x) (rotr32((x), 7) ^ rotr32((x), 18) ^ ((x) >> 3))
+#define g_1(x) (rotr32((x), 17) ^ rotr32((x), 19) ^ ((x) >> 10))
+#define k_0 k256
+
+/* rotated SHA256 round definition. Rather than swapping variables as in */
+/* FIPS-180, different variables are 'rotated' on each round, returning */
+/* to their starting positions every eight rounds */
+
+#define q(n) v##n
+
+#define one_cycle(a,b,c,d,e,f,g,h,k,w) \
+ q(h) += s_1(q(e)) + ch(q(e), q(f), q(g)) + k + w; \
+ q(d) += q(h); q(h) += s_0(q(a)) + maj(q(a), q(b), q(c))
+
+/*
+Description: SHA256 mixing data
+Value Range: None
+Access: Used to mix with data to create SHA256 key.
+Remarks:
+*/
+static const u32 k256[64] = {
+ 010242427630, 016115642221, 026560175717, 035155355645,
+ 07125541133, 013174210761, 022217701244, 025307057325,
+ 033001725230, 02240655401, 04414302676, 012503076703,
+ 016257456564, 020067530776, 023367003247, 030146770564,
+ 034446664701, 035757443606, 01760316706, 04403120714,
+ 05572226157, 011235102252, 013454124734, 016676304332,
+ 023017450522, 025014343155, 026000623710, 027726277707,
+ 030670005763, 032551710507, 0662461521, 02412224547,
+ 04755605205, 05606620470, 011513066774, 012316006423,
+ 014502471524, 016632405273, 020160544456, 022234426205,
+ 024257764241, 025006463113, 030222705560, 030733050643,
+ 032144564031, 032646203044, 036403432605, 02032520160,
+ 03151140426, 03615666010, 04722073514, 06454136265,
+ 07107006263, 011666125112, 013347145117, 015013467763,
+ 016443701356, 017051261557, 020462074024, 021461601010,
+ 022057577772, 024424066353, 027676321767, 030634274362,
+};
+
+/* Compile 64 bytes of hash data into SHA256 digest value */
+/* NOTE: this routine assumes that the byte order in the */
+/* ctx->wbuf[] at this point is such that low address bytes */
+/* in the ORIGINAL byte stream will go into the high end of */
+/* words on BOTH big and little endian systems */
+
+#define v_ v
+#define ptr p
+
+/*===========================================================================*\
+ Function :Sha256_compile__
+ Description : This function generates the digest value for SHA256.
+ Compile 64 bytes of hash data into SHA256 digest value
+ Calls : mem copy - Secure mem copy function.
+ Called by :
+ Return : This is a static internal function which doesn't return any value.
+ Parameters :
+ SHA256_CTX ctx[1] -
+ Note : this routine assumes that the byte order in the
+ ctx->wbuf[] at this point is such that low address bytes in
+ the ORIGINAL byte stream will go into the high end of
+ words on BOTH big and little endian systems.
+\*===========================================================================*/
+NSTACK_STATIC void
+Sha256_compile__ (SHA256_CTX ctx[1])
+{
+
+ /* macros defined above to this function i.e. v_ and ptr should not be removed */
+ /* v_cycle - for 0 to 15 */
+ u32 j;
+ u32 *ptr = ctx->wbuf;
+ u32 v_[8];
+
+ int ret = MEMCPY_S (v_, 8 * sizeof (u32), ctx->hash, 8 * sizeof (u32));
+ if (EOK != ret)
+ {
+ NSPOL_LOGERR ("MEMCPY_S failed");
+ return;
+ }
+
+ for (j = 0; j < 64; j += 16)
+ {
+ /*v_cycle operations from 0 to 15 */
+ v_cycle (0, j);
+ v_cycle (1, j);
+ v_cycle (2, j);
+ v_cycle (3, j);
+ v_cycle (4, j);
+ v_cycle (5, j);
+ v_cycle (6, j);
+ v_cycle (7, j);
+ v_cycle (8, j);
+ v_cycle (9, j);
+ v_cycle (10, j);
+ v_cycle (11, j);
+ v_cycle (12, j);
+ v_cycle (13, j);
+ v_cycle (14, j);
+ v_cycle (15, j);
+ }
+
+ /* update the context */
+ ctx->hash[0] += v_[0];
+ ctx->hash[1] += v_[1];
+ ctx->hash[2] += v_[2];
+ ctx->hash[3] += v_[3];
+ ctx->hash[4] += v_[4];
+ ctx->hash[5] += v_[5];
+ ctx->hash[6] += v_[6];
+ ctx->hash[7] += v_[7];
+
+ return;
+}
+
+#undef v_
+#undef ptr
+
+/* SHA256 hash data in an array of bytes into hash buffer */
+/* and call the hash_compile function as required. */
+
+/*===========================================================================*\
+ Function :Sha256_upd
+ Description :
+ Calls :
+ Called by :
+ Return :void -
+ Parameters :
+ SHA256_CTX ctx[1] -
+ const unsigned char data[] -
+ size_t len -
+ Note :
+\*===========================================================================*/
+void
+Sha256_upd (SHA256_CTX ctx[1], const u8 data[], size_t len)
+{
+ u32 pos = (u32) (ctx->count[0] & SHA256_MASK);
+ u32 space = SHA256_BLOCK_SIZE - pos;
+ const u8 *sp = data;
+ int ret;
+
+ if ((ctx->count[0] += (u32) len) < len)
+ {
+ ++(ctx->count[1]);
+ }
+
+ while (len >= space)
+ {
+
+ /* tranfer whole blocks while possible */
+ ret = MEMCPY_S (((u8 *) ctx->wbuf) + pos, space, sp, space);
+ if (EOK != ret)
+ {
+ NSPOL_LOGERR ("MEMCPY_S failed");
+ return;
+ }
+
+ sp += space;
+ len -= space;
+ space = SHA256_BLOCK_SIZE;
+ pos = 0;
+ bsw_32 (ctx->wbuf, SHA256_BLOCK_SIZE >> 2);
+ Sha256_compile__ (ctx);
+ }
+
+ if (len != 0)
+ {
+ ret = MEMCPY_S (((u8 *) ctx->wbuf) + pos, (u32) len, sp, (u32) len);
+ if (EOK != ret)
+ {
+ NSPOL_LOGERR ("MEMCPY_S failed");
+ return;
+ }
+ }
+
+ return;
+}
+
+/* SHA256 Final padding and digest calculation */
+
+/*===========================================================================*\
+ Function :SHA_fin1
+ Description :
+ Calls :
+ Called by :
+ Return :void -
+ Parameters :
+ unsigned char hval[] -
+ SHA256_CTX ctx[1] -
+ const unsigned int hlen -
+ Note :
+\*===========================================================================*/
+NSTACK_STATIC void
+SHA_fin1 (u8 hval[], SHA256_CTX ctx[1], const unsigned int hlen)
+{
+ u32 i = (u32) (ctx->count[0] & SHA256_MASK);
+
+ /* Not unusal shift operation. Checked with purify. */
+
+ /*put bytes in the buffer in an order in which references to */
+ /*32-bit words will put bytes with lower addresses into the */
+ /*top of 32 bit words on BOTH big and little endian machines */
+ bsw_32 (ctx->wbuf, (i + 3) >> 2);
+
+ /*we now need to mask valid bytes and add the padding which is */
+ /*a single 1 bit and as many zero bits as necessary. Note that */
+ /*we can always add the first padding byte here because the */
+ /*buffer always has at least one empty slot */
+ ctx->wbuf[i >> 2] &= (u32) 0xffffff80 << 8 * (~i & 3);
+ ctx->wbuf[i >> 2] |= (u32) 0x00000080 << 8 * (~i & 3);
+
+ /* we need 9 or more empty positions, one for the padding byte */
+ /* (above) and eight for the length count. If there is not */
+ /* enough space pad and empty the buffer */
+ if (i > SHA256_BLOCK_SIZE - 9)
+ {
+ if (i < 60)
+ {
+ ctx->wbuf[15] = 0;
+ }
+
+ Sha256_compile__ (ctx);
+ i = 0;
+ }
+ else
+ {
+ /* compute a word index for the empty buffer positions */
+ i = (i >> 2) + 1;
+ }
+
+ while (i < 14)
+ {
+ /* and zero pad all but last two positions */
+ ctx->wbuf[i++] = 0;
+ }
+
+ /* the following 32-bit length fields are assembled in the */
+ /* wrong byte order on little endian machines but this is */
+ /* corrected later since they are only ever used as 32-bit */
+ /* word values. */
+ ctx->wbuf[14] = (ctx->count[1] << 3) | (ctx->count[0] >> 29);
+ ctx->wbuf[15] = ctx->count[0] << 3;
+ Sha256_compile__ (ctx);
+
+ /* extract the hash value as bytes in case the hash buffer is */
+ /* mislaigned for 32-bit words */
+ for (i = 0; i < hlen; ++i)
+ {
+ hval[i] = (u8) (ctx->hash[i >> 2] >> (8 * (~i & 3)));
+ }
+
+ return;
+}
+
+/*
+Description: Internal data for SHA256 digest calculation
+Value Range: None
+Access: Used to store internal data for SHA256 digest calculation
+Remarks:
+*/
+static const u32 g_i256[] = {
+ 0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A,
+ 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19
+};
+
+/*===========================================================================*\
+ Function :Sha256_set
+ Description :
+ Calls :
+ Called by :
+ Return :void -
+ Parameters :
+ SHA256_CTX ctx[1] -
+ Note :
+\*===========================================================================*/
+void
+Sha256_set (SHA256_CTX ctx[1])
+{
+ int ret;
+ ctx->count[0] = ctx->count[1] = 0;
+
+ ret = MEMCPY_S (ctx->hash, sizeof (ctx->hash), g_i256, sizeof (g_i256));
+ if (EOK != ret)
+ {
+ NSPOL_LOGERR ("MEMCPY_S failed");
+ return;
+ }
+
+ return;
+}
+
+/*===========================================================================*\
+ Function :Sha256_fin
+ Description :
+ Calls :
+ Called by :
+ Return :void -
+ Parameters :
+ SHA256_CTX ctx[1] -
+ unsigned char hval[] -
+ Note :
+\*===========================================================================*/
+void
+Sha256_fin (SHA256_CTX ctx[1], u8 hval[])
+{
+ SHA_fin1 (hval, ctx, SHA256_DIGEST_SIZE);
+
+ return;
+}
+
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+}
+/* *INDENT-ON* */
+#endif