diff options
Diffstat (limited to 'src/framework/common/data_struct')
-rw-r--r-- | src/framework/common/data_struct/eprb_tree.c | 492 | ||||
-rw-r--r-- | src/framework/common/data_struct/list.c | 163 | ||||
-rw-r--r-- | src/framework/common/data_struct/pidinfo.c | 125 | ||||
-rw-r--r-- | src/framework/common/data_struct/sha256.c | 397 |
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 |