feat add soft sm3
This commit is contained in:
parent
3fbfb12294
commit
1cf9d96dd1
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,3 +1,5 @@
|
|||||||
|
out/
|
||||||
|
compile_commands.json
|
||||||
Makefile.in
|
Makefile.in
|
||||||
build*
|
build*
|
||||||
.vscode
|
.vscode
|
||||||
|
1148
AWSM/src/AWSM.c
1148
AWSM/src/AWSM.c
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
257
AWSMServer/src/map.c
Normal file
257
AWSMServer/src/map.c
Normal file
@ -0,0 +1,257 @@
|
|||||||
|
#include "map.h"
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
struct cell {
|
||||||
|
struct cell *next;
|
||||||
|
void *value;
|
||||||
|
char key[];
|
||||||
|
} cell;
|
||||||
|
|
||||||
|
struct map {
|
||||||
|
struct cell **elems;
|
||||||
|
int capacity;
|
||||||
|
int size;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Internal helper functions. Implemented at the bottom of this file.
|
||||||
|
static unsigned int hash(const char *key);
|
||||||
|
static void extend_if_necessary(map m);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new, empty map.
|
||||||
|
*
|
||||||
|
* The returned map has dynamically allocated memory associated with it, and
|
||||||
|
* this memory must be reclaimed after use with `map_destroy`.
|
||||||
|
*/
|
||||||
|
map map_create() {
|
||||||
|
|
||||||
|
// Allocate space for the map's primary data structure. More space will be
|
||||||
|
// allocated in the future when values are added to the map.
|
||||||
|
map m = malloc(sizeof(map));
|
||||||
|
assert(m != NULL);
|
||||||
|
m->elems = calloc(1, sizeof(struct cell *));
|
||||||
|
assert(m->elems != NULL);
|
||||||
|
|
||||||
|
// Initialize metadata. The map starts with capacity for one entry.
|
||||||
|
m->capacity = 1;
|
||||||
|
m->size = 0;
|
||||||
|
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Free the memory used for a map after use.
|
||||||
|
*
|
||||||
|
* Note that this routine does not free any memory that was allocated for the
|
||||||
|
* values stored in the map. That memory must be freed by the client as
|
||||||
|
* appropriate.
|
||||||
|
*/
|
||||||
|
void map_destroy(map m) {
|
||||||
|
|
||||||
|
// Loop over each cell in the map and free it.
|
||||||
|
for (int i = 0; i < m->capacity; i += 1) {
|
||||||
|
struct cell *curr = m->elems[i];
|
||||||
|
while (curr != NULL) {
|
||||||
|
struct cell *next = curr->next;
|
||||||
|
free(curr);
|
||||||
|
curr = next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free(m->elems);
|
||||||
|
free(m);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the size of a map.
|
||||||
|
*/
|
||||||
|
int map_size(const map m) { return m->size; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether a map contains a given key.
|
||||||
|
*
|
||||||
|
* Keys are case-sensitive.
|
||||||
|
*/
|
||||||
|
bool map_contains(const map m, const char *key) {
|
||||||
|
int b = hash(key) % m->capacity;
|
||||||
|
|
||||||
|
// Search linearly for a matching key through the appropriate linked list.
|
||||||
|
for (struct cell *curr = m->elems[b]; curr != NULL; curr = curr->next) {
|
||||||
|
if (strcmp(curr->key, key) == 0)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the value for a given key within a map.
|
||||||
|
*
|
||||||
|
* This will add a new key if it does not exist. If the key already exists, the
|
||||||
|
* new value will replace the old one.
|
||||||
|
*/
|
||||||
|
void map_set(map m, const char *key, void *value) {
|
||||||
|
int b = hash(key) % m->capacity;
|
||||||
|
|
||||||
|
// First, look for an existing entry with the given key in the map. If it
|
||||||
|
// exists, simply update its value.
|
||||||
|
for (struct cell *curr = m->elems[b]; curr != NULL; curr = curr->next) {
|
||||||
|
if (strcmp(curr->key, key) == 0) {
|
||||||
|
curr->value = value;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extend_if_necessary(m);
|
||||||
|
b = hash(key) % m->capacity;
|
||||||
|
|
||||||
|
// No existing key was found, so insert it as a new entry at the head of the
|
||||||
|
// list.
|
||||||
|
struct cell *new = malloc(sizeof(struct cell) + strlen(key) + 1);
|
||||||
|
new->next = m->elems[b];
|
||||||
|
new->value = value;
|
||||||
|
strcpy(new->key, key);
|
||||||
|
m->elems[b] = new;
|
||||||
|
m->size += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the value for a given key in a map.
|
||||||
|
*
|
||||||
|
* Crashes if the map does not contain the given key.
|
||||||
|
*/
|
||||||
|
void *map_get(const map m, const char *key) {
|
||||||
|
int b = hash(key) % m->capacity;
|
||||||
|
|
||||||
|
// Search linearly for a matching key through the appropriate linked list.
|
||||||
|
for (struct cell *curr = m->elems[b]; curr != NULL; curr = curr->next) {
|
||||||
|
if (strcmp(curr->key, key) == 0)
|
||||||
|
return curr->value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Key not found.
|
||||||
|
bool key_found = false;
|
||||||
|
assert(key_found);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove a key and its value from a map.
|
||||||
|
*
|
||||||
|
* Crashes if the map does not already contain the key.
|
||||||
|
*/
|
||||||
|
void *map_remove(map m, const char *key) {
|
||||||
|
int b = hash(key) % m->capacity;
|
||||||
|
|
||||||
|
// Here, use a double pointer to make removal easier.
|
||||||
|
struct cell **curr;
|
||||||
|
for (curr = &m->elems[b]; *curr != NULL; curr = &(*curr)->next) {
|
||||||
|
if (strcmp((*curr)->key, key) == 0) {
|
||||||
|
|
||||||
|
// Bridge the linked list accross the removed element.
|
||||||
|
struct cell *found = *curr;
|
||||||
|
*curr = (*curr)->next;
|
||||||
|
|
||||||
|
void *value = found->value;
|
||||||
|
free(found);
|
||||||
|
m->size -= 1;
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Key not found.
|
||||||
|
bool key_found = false;
|
||||||
|
assert(key_found);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the "first" key (arbitrarily ordered) in a map. If the map is empty,
|
||||||
|
* returns NULL.
|
||||||
|
*/
|
||||||
|
const char *map_first(map m) {
|
||||||
|
|
||||||
|
// Find and return the first cell in the first non-empty bucket.
|
||||||
|
for (int i = 0; i < m->capacity; i += 1) {
|
||||||
|
if (m->elems[i] != NULL) {
|
||||||
|
return m->elems[i]->key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the next key after a given key within a map.
|
||||||
|
*
|
||||||
|
* Used for iteration. Returns NULL if there are no more keys. Note that the
|
||||||
|
* provided `key` must have been returned from a previous call to `map_first`
|
||||||
|
* or `map_next`. Passing other strings produces undefined behavior.
|
||||||
|
*/
|
||||||
|
const char *map_next(map m, const char *key) {
|
||||||
|
|
||||||
|
// First, get a reference to the current cell and check its successor.
|
||||||
|
struct cell *curr = (void *)(key - sizeof(struct cell));
|
||||||
|
if (curr->next != NULL) {
|
||||||
|
return curr->next->key;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If no immediate successor exists, begin searching the rest of the buckets.
|
||||||
|
int b = hash(key) % m->capacity;
|
||||||
|
for (int i = b + 1; i < m->capacity; i += 1) {
|
||||||
|
if (m->elems[i] != NULL) {
|
||||||
|
return m->elems[i]->key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// No more keys.
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal helper; hash a string key.
|
||||||
|
*/
|
||||||
|
static unsigned int hash(const char *key) {
|
||||||
|
unsigned int hash = -1;
|
||||||
|
while (*key) {
|
||||||
|
hash *= 31;
|
||||||
|
hash ^= (unsigned char)*key;
|
||||||
|
key += 1;
|
||||||
|
}
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Grow the capacity of the hash map by a factor of two, only when the map's
|
||||||
|
* load becomes greater than one.
|
||||||
|
*/
|
||||||
|
static void extend_if_necessary(map m) {
|
||||||
|
if (m->size == m->capacity) {
|
||||||
|
|
||||||
|
// Save old values first, since all map entries will need to be copied over.
|
||||||
|
int capacity = m->capacity;
|
||||||
|
struct cell **elems = m->elems;
|
||||||
|
|
||||||
|
// Doubling the capacity when necessary allows for an amortized constant
|
||||||
|
// runtime for extension.
|
||||||
|
m->capacity *= 2;
|
||||||
|
m->elems = calloc(m->capacity, sizeof(struct cell *));
|
||||||
|
|
||||||
|
for (int i = 0; i < capacity; i += 1) {
|
||||||
|
struct cell *curr = elems[i];
|
||||||
|
while (curr != NULL) {
|
||||||
|
struct cell *next = curr->next;
|
||||||
|
|
||||||
|
// Move the entry from the old data structure to the new.
|
||||||
|
int b = hash(curr->key) % m->capacity;
|
||||||
|
curr->next = m->elems[b];
|
||||||
|
m->elems[b] = curr;
|
||||||
|
|
||||||
|
curr = next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free(elems);
|
||||||
|
}
|
||||||
|
}
|
84
AWSMServer/src/map.h
Normal file
84
AWSMServer/src/map.h
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
#ifndef __MAP_H
|
||||||
|
#define __MAP_H
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hash map implementation for C.
|
||||||
|
*
|
||||||
|
* This hash map uses strings as keys, and allows association of any arbitrary
|
||||||
|
* value type through the use of `void *` pointers. Additionally, this
|
||||||
|
* implementation leaves memory management of stored values to the client (for
|
||||||
|
* example, destroying a map using `map_destroy` will free the memory for the
|
||||||
|
* map itself, but it will not free memory that was used to store its values).
|
||||||
|
*/
|
||||||
|
typedef struct map *map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new, empty map.
|
||||||
|
*
|
||||||
|
* The returned map has dynamically allocated memory associated with it, and
|
||||||
|
* this memory must be reclaimed after use with `map_destroy`.
|
||||||
|
*/
|
||||||
|
map map_create();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Free the memory used for a map after use.
|
||||||
|
*
|
||||||
|
* Note that this routine does not free any memory that was allocated for the
|
||||||
|
* values stored in the map. That memory must be freed by the client as
|
||||||
|
* appropriate.
|
||||||
|
*/
|
||||||
|
void map_destroy(map m);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the size of a map.
|
||||||
|
*/
|
||||||
|
int map_size(const map m);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether a map contains a given key.
|
||||||
|
*
|
||||||
|
* Keys are case-sensitive.
|
||||||
|
*/
|
||||||
|
bool map_contains(const map m, const char *key);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the value for a given key within a map.
|
||||||
|
*
|
||||||
|
* This will add a new key if it does not exist. If the key already exists, the
|
||||||
|
* new value will replace the old one.
|
||||||
|
*/
|
||||||
|
void map_set(map m, const char *key, void *value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the value for a given key in a map.
|
||||||
|
*
|
||||||
|
* Crashes if the map does not contain the given key.
|
||||||
|
*/
|
||||||
|
void *map_get(const map m, const char *key);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove a key and return its value from a map.
|
||||||
|
*
|
||||||
|
* Crashes if the map does not already contain the key.
|
||||||
|
*/
|
||||||
|
void *map_remove(map m, const char *key);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Iterate over a map's keys.
|
||||||
|
*
|
||||||
|
* Usage:
|
||||||
|
*
|
||||||
|
* for (char *key = map_first(m); key != NULL; key = map_next(m, key)) {
|
||||||
|
* ...
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* Note that the `key` passed to `map_next` must have come from a previous call
|
||||||
|
* to `map_first` or `map_next`. Passing strings from other sources produces
|
||||||
|
* undefined behavior.
|
||||||
|
*/
|
||||||
|
const char *map_first(map m);
|
||||||
|
const char *map_next(map m, const char *key);
|
||||||
|
|
||||||
|
#endif
|
829
AWSMServer/src/sm2sm3_enc/big.c
Normal file
829
AWSMServer/src/sm2sm3_enc/big.c
Normal file
@ -0,0 +1,829 @@
|
|||||||
|
#include "typedef.h"
|
||||||
|
#include "big.h"
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
u64 m_low;
|
||||||
|
u64 m_high;
|
||||||
|
} uint128_t;
|
||||||
|
|
||||||
|
void vli_clear(u64 *vli, u8 ndigits)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < ndigits; ++i) {
|
||||||
|
vli[i] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns true if vli == 0, false otherwise. */
|
||||||
|
int vli_is_zero(u64 *vli, u8 ndigits)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < ndigits; ++i) {
|
||||||
|
if (vli[i])
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns nonzero if bit bit of vli is set. */
|
||||||
|
u64 vli_test_bit(u64 *vli, u8 bit, u8 ndigits)
|
||||||
|
{
|
||||||
|
return (vli[bit/64] & ((u64)1 << (bit % 64)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Counts the number of 64-bit "digits" in vli. */
|
||||||
|
u32 vli_num_digits(u64 *vli, u8 ndigits)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
/* Search from the end until we find a non-zero digit.
|
||||||
|
* We do it in reverse because we expect that most digits will
|
||||||
|
* be nonzero.
|
||||||
|
*/
|
||||||
|
for (i = ndigits - 1; i >= 0 && vli[i] == 0; --i);
|
||||||
|
|
||||||
|
return (i + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Counts the number of bits required for vli. */
|
||||||
|
u32 vli_num_bits(u64 *vli, u8 ndigits)
|
||||||
|
{
|
||||||
|
u32 i, num_digits;
|
||||||
|
u64 digit;
|
||||||
|
|
||||||
|
num_digits = vli_num_digits(vli, ndigits);
|
||||||
|
if (num_digits == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
digit = vli[num_digits - 1];
|
||||||
|
for (i = 0; digit; ++i)
|
||||||
|
digit >>= 1;
|
||||||
|
|
||||||
|
return ((num_digits - 1) * 64 + i);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Sets dest = src. */
|
||||||
|
void vli_set(u64 *dest, u64 *src, u8 ndigits)
|
||||||
|
{
|
||||||
|
u32 i;
|
||||||
|
|
||||||
|
for (i = 0; i < ndigits; ++i)
|
||||||
|
dest[i] = src[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns sign of left - right. */
|
||||||
|
int vli_cmp(u64 *left, u64 *right, u8 ndigits)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = ndigits - 1; i >= 0; --i) {
|
||||||
|
if (left[i] > right[i])
|
||||||
|
return 1;
|
||||||
|
else if (left[i] < right[i])
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Computes result = in << c, returning carry. Can modify in place
|
||||||
|
* (if result == in). 0 < shift < 64.
|
||||||
|
*/
|
||||||
|
u64 vli_lshift(u64 *result, u64 *in, u32 shift, u8 ndigits)
|
||||||
|
{
|
||||||
|
u64 carry = 0;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < ndigits; ++i) {
|
||||||
|
u64 temp = in[i];
|
||||||
|
result[i] = (temp << shift) | carry;
|
||||||
|
carry = shift ? temp >> (64 - shift) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return carry;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Computes result = in >> c, returning carry. Can modify in place
|
||||||
|
* (if result == in). 0 < shift < 64.
|
||||||
|
*/
|
||||||
|
u64 vli_rshift(u64 *result, u64 *in, u32 shift, u8 ndigits)
|
||||||
|
{
|
||||||
|
u64 carry = 0;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = ndigits -1; i >= 0; --i) {
|
||||||
|
u64 temp = in[i];
|
||||||
|
result[i] = (temp >> shift) | carry;
|
||||||
|
carry = shift ? temp << (64 - shift) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return carry;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Computes result = left + right, returning carry. Can modify in place. */
|
||||||
|
u64 vli_add(u64 *result, u64 *left, u64 *right, u8 ndigits)
|
||||||
|
{
|
||||||
|
u64 carry = 0;
|
||||||
|
u32 i;
|
||||||
|
|
||||||
|
for (i = 0; i < ndigits; ++i) {
|
||||||
|
u64 sum;
|
||||||
|
|
||||||
|
sum = left[i] + right[i] + carry;
|
||||||
|
if (sum != left[i]) {
|
||||||
|
carry = (sum < left[i]);
|
||||||
|
}
|
||||||
|
result[i] = sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
return carry;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Computes result = left - right, returning borrow. Can modify in place. */
|
||||||
|
u64 vli_sub(u64 *result, u64 *left, u64 *right, u8 ndigits)
|
||||||
|
{
|
||||||
|
u64 borrow = 0;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < ndigits; ++i) {
|
||||||
|
u64 diff;
|
||||||
|
|
||||||
|
diff = left[i] - right[i] - borrow;
|
||||||
|
if (diff != left[i])
|
||||||
|
borrow = (diff > left[i]);
|
||||||
|
|
||||||
|
result[i] = diff;
|
||||||
|
}
|
||||||
|
|
||||||
|
return borrow;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint128_t mul_64_64(u64 left, u64 right)
|
||||||
|
{
|
||||||
|
u64 a0 = left & 0xffffffffull;
|
||||||
|
u64 a1 = left >> 32;
|
||||||
|
u64 b0 = right & 0xffffffffull;
|
||||||
|
u64 b1 = right >> 32;
|
||||||
|
u64 m0 = a0 * b0;
|
||||||
|
u64 m1 = a0 * b1;
|
||||||
|
u64 m2 = a1 * b0;
|
||||||
|
u64 m3 = a1 * b1;
|
||||||
|
uint128_t result;
|
||||||
|
|
||||||
|
m2 += (m0 >> 32);
|
||||||
|
m2 += m1;
|
||||||
|
|
||||||
|
/* Overflow */
|
||||||
|
if (m2 < m1)
|
||||||
|
m3 += 0x100000000ull;
|
||||||
|
|
||||||
|
result.m_low = (m0 & 0xffffffffull) | (m2 << 32);
|
||||||
|
result.m_high = m3 + (m2 >> 32);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint128_t add_128_128(uint128_t a, uint128_t b)
|
||||||
|
{
|
||||||
|
uint128_t result;
|
||||||
|
|
||||||
|
result.m_low = a.m_low + b.m_low;
|
||||||
|
result.m_high = a.m_high + b.m_high + (result.m_low < a.m_low);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static u64 vli_add_digit_mul(u64 *result, u64 *b, u64 c, u64 *d, u8 digits)
|
||||||
|
{
|
||||||
|
uint128_t mul;
|
||||||
|
u64 carry;
|
||||||
|
u32 i;
|
||||||
|
|
||||||
|
if (c == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
carry = 0;
|
||||||
|
for (i = 0; i < digits; i++) {
|
||||||
|
mul = mul_64_64(c, d[i]);
|
||||||
|
if ((result[i] = b[i] + carry) < carry) {
|
||||||
|
carry = 1;
|
||||||
|
} else {
|
||||||
|
carry = 0;
|
||||||
|
}
|
||||||
|
if ((result[i] += mul.m_low) < mul.m_low) {
|
||||||
|
carry++;
|
||||||
|
}
|
||||||
|
carry += mul.m_high;
|
||||||
|
}
|
||||||
|
|
||||||
|
return carry;
|
||||||
|
}
|
||||||
|
|
||||||
|
void bn_mult(u64 *result, u64 *left, u64 *right, u8 ndigits)
|
||||||
|
{
|
||||||
|
u64 t[2*128];
|
||||||
|
u32 bdigits, cdigits, i;
|
||||||
|
|
||||||
|
vli_clear(t, 2*ndigits);
|
||||||
|
|
||||||
|
bdigits = vli_num_digits(left, ndigits);
|
||||||
|
cdigits = vli_num_digits(right, ndigits);
|
||||||
|
|
||||||
|
for(i=0; i<bdigits; i++) {
|
||||||
|
t[i+cdigits] += vli_add_digit_mul(&t[i], &t[i], left[i], right, cdigits);
|
||||||
|
}
|
||||||
|
|
||||||
|
vli_set(result, t, 2*ndigits);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define BN_DIGIT_BITS 32
|
||||||
|
#define BN_MAX_DIGIT 0xFFFFFFFF
|
||||||
|
static u32 vli_sub_digit_mult(u32 *a, u32 *b, u32 c, u32 *d, u32 digits)
|
||||||
|
{
|
||||||
|
u64 result;
|
||||||
|
u32 borrow, rh, rl;
|
||||||
|
u32 i;
|
||||||
|
|
||||||
|
if(c == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
borrow = 0;
|
||||||
|
for(i=0; i<digits; i++) {
|
||||||
|
result = (u64)c * d[i];
|
||||||
|
rl = result & BN_MAX_DIGIT;
|
||||||
|
rh = (result >> BN_DIGIT_BITS) & BN_MAX_DIGIT;
|
||||||
|
if((a[i] = b[i] - borrow) > (BN_MAX_DIGIT - borrow)) {
|
||||||
|
borrow = 1;
|
||||||
|
} else {
|
||||||
|
borrow = 0;
|
||||||
|
}
|
||||||
|
if((a[i] -= rl) > (BN_MAX_DIGIT - rl)) {
|
||||||
|
borrow++;
|
||||||
|
}
|
||||||
|
borrow += rh;
|
||||||
|
}
|
||||||
|
|
||||||
|
return borrow;
|
||||||
|
}
|
||||||
|
|
||||||
|
static u32 bn_digit_bits(u32 a)
|
||||||
|
{
|
||||||
|
u32 i;
|
||||||
|
|
||||||
|
for(i = 0; i< sizeof(a) * 8; i++) {
|
||||||
|
if(a == 0) break;
|
||||||
|
a >>= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
void bn_div(u32 *a, u32 *b, u32 *c, u32 cdigits, u32 *d, u32 ddigits)
|
||||||
|
{
|
||||||
|
u32 ai, t, cc[128+1], dd[128/2];
|
||||||
|
u32 dddigits, shift;
|
||||||
|
u64 tmp;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
dddigits = ddigits;
|
||||||
|
|
||||||
|
shift = BN_DIGIT_BITS - bn_digit_bits(d[dddigits-1]);
|
||||||
|
vli_clear((u64*)cc, dddigits/2);
|
||||||
|
cc[cdigits] = vli_lshift((u64*)cc, (u64*)c, shift, cdigits/2);
|
||||||
|
vli_lshift((u64*)dd, (u64*)d, shift, dddigits/2);
|
||||||
|
t = dd[dddigits-1];
|
||||||
|
|
||||||
|
vli_clear((u64*)a, cdigits/2);
|
||||||
|
i = cdigits - dddigits;
|
||||||
|
for(; i>=0; i--) {
|
||||||
|
if(t == BN_MAX_DIGIT) {
|
||||||
|
ai = cc[i+dddigits];
|
||||||
|
} else {
|
||||||
|
tmp = cc[i+dddigits-1];
|
||||||
|
tmp += (u64)cc[i+dddigits] << BN_DIGIT_BITS;
|
||||||
|
ai = tmp / (t + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
cc[i+dddigits] -= vli_sub_digit_mult(&cc[i], &cc[i], ai, dd, dddigits);
|
||||||
|
while(cc[i+dddigits] || (vli_cmp((u64*)&cc[i], (u64*)dd, dddigits/2) >= 0)) {
|
||||||
|
ai++;
|
||||||
|
cc[i+dddigits] -= vli_sub((u64*)&cc[i], (u64*)&cc[i], (u64*)dd, dddigits/2);
|
||||||
|
}
|
||||||
|
a[i] = ai;
|
||||||
|
}
|
||||||
|
|
||||||
|
vli_rshift((u64*)b, (u64*)cc, shift, dddigits/2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void vli_div(u64 *result, u64 *remainder, u64 *left, u64 cdigits, u64 *right, u8 ddigits)
|
||||||
|
{
|
||||||
|
bn_div((u32*)result, (u32*)remainder, (u32*)left, cdigits*2, (u32*)right, ddigits*2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void bn_mod(u64 *result, u64 *left, u64 *right, u8 ndigits)
|
||||||
|
{
|
||||||
|
u64 t[2*128];
|
||||||
|
|
||||||
|
vli_div(t, result, left, ndigits*2, right, ndigits);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _vli_mult(u64 *result, u64 *left, u64 *right, u8 ndigits)
|
||||||
|
{
|
||||||
|
uint128_t r01 = { 0, 0 };
|
||||||
|
u64 r2 = 0;
|
||||||
|
unsigned int i, k;
|
||||||
|
|
||||||
|
/* Compute each digit of result in sequence, maintaining the
|
||||||
|
* carries.
|
||||||
|
*/
|
||||||
|
for (k = 0; k < ndigits * 2 - 1; k++) {
|
||||||
|
unsigned int min;
|
||||||
|
|
||||||
|
if (k < ndigits)
|
||||||
|
min = 0;
|
||||||
|
else
|
||||||
|
min = (k + 1) - ndigits;
|
||||||
|
|
||||||
|
for (i = min; i <= k && i < ndigits; i++) {
|
||||||
|
uint128_t product;
|
||||||
|
|
||||||
|
product = mul_64_64(left[i], right[k - i]);
|
||||||
|
|
||||||
|
r01 = add_128_128(r01, product);
|
||||||
|
r2 += (r01.m_high < product.m_high);
|
||||||
|
}
|
||||||
|
|
||||||
|
result[k] = r01.m_low;
|
||||||
|
r01.m_low = r01.m_high;
|
||||||
|
r01.m_high = r2;
|
||||||
|
r2 = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
result[ndigits * 2 - 1] = r01.m_low;
|
||||||
|
}
|
||||||
|
|
||||||
|
void vli_mult(u64 *result, u64 *left, u64 *right, u8 ndigits)
|
||||||
|
{
|
||||||
|
#if 1
|
||||||
|
bn_mult(result, left, right, ndigits);
|
||||||
|
#else
|
||||||
|
_vli_mult(result, left, right, ndigits);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void vli_square(u64 *result, u64 *left, u8 ndigits)
|
||||||
|
{
|
||||||
|
uint128_t r01 = { 0, 0 };
|
||||||
|
u64 r2 = 0;
|
||||||
|
int i, k;
|
||||||
|
|
||||||
|
for (k = 0; k < ndigits * 2 - 1; k++) {
|
||||||
|
unsigned int min;
|
||||||
|
|
||||||
|
if (k < ndigits)
|
||||||
|
min = 0;
|
||||||
|
else
|
||||||
|
min = (k + 1) - ndigits;
|
||||||
|
|
||||||
|
for (i = min; i <= k && i <= k - i; i++) {
|
||||||
|
uint128_t product;
|
||||||
|
|
||||||
|
product = mul_64_64(left[i], left[k - i]);
|
||||||
|
|
||||||
|
if (i < k - i) {
|
||||||
|
r2 += product.m_high >> 63;
|
||||||
|
product.m_high = (product.m_high << 1) |
|
||||||
|
(product.m_low >> 63);
|
||||||
|
product.m_low <<= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
r01 = add_128_128(r01, product);
|
||||||
|
r2 += (r01.m_high < product.m_high);
|
||||||
|
}
|
||||||
|
|
||||||
|
result[k] = r01.m_low;
|
||||||
|
r01.m_low = r01.m_high;
|
||||||
|
r01.m_high = r2;
|
||||||
|
r2 = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
result[ndigits * 2 - 1] = r01.m_low;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Computes result = (left + right) % mod.
|
||||||
|
Assumes that left < mod and right < mod, result != mod. */
|
||||||
|
void vli_mod_add(u64 *result, u64 *left, u64 *right, u64 *mod, u8 ndigits)
|
||||||
|
{
|
||||||
|
u64 carry;
|
||||||
|
|
||||||
|
carry = vli_add(result, left, right, ndigits);
|
||||||
|
/* result > mod (result = mod + remainder), so subtract mod to
|
||||||
|
* get remainder.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if(carry || vli_cmp(result, mod, ndigits) >= 0) {
|
||||||
|
/* result > mod (result = mod + remainder), so subtract mod to get remainder. */
|
||||||
|
vli_sub(result, result, mod, ndigits);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Computes result = (left - right) % mod.
|
||||||
|
* Assumes that left < mod and right < mod, result != mod.
|
||||||
|
*/
|
||||||
|
void vli_mod_sub(u64 *result, u64 *left, u64 *right, u64 *mod, u8 ndigits)
|
||||||
|
{
|
||||||
|
u64 borrow;
|
||||||
|
|
||||||
|
borrow = vli_sub(result, left, right, ndigits);
|
||||||
|
/* In this case, result == -diff == (max int) - diff.
|
||||||
|
* Since -x % d == d - x, we can get the correct result from
|
||||||
|
* result + mod (with overflow).
|
||||||
|
*/
|
||||||
|
if(borrow)
|
||||||
|
vli_add(result, result, mod, ndigits);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Computes result = product % curve_prime
|
||||||
|
* from http://www.nsa.gov/ia/_files/nist-routines.pdf
|
||||||
|
*/
|
||||||
|
void vli_mmod_fast_nist_256(u64 *result, u64 *product, u64 *curve_prime, u8 ndigits)
|
||||||
|
{
|
||||||
|
u64 tmp[2 * 128];
|
||||||
|
int carry;
|
||||||
|
|
||||||
|
/* t */
|
||||||
|
vli_set(result, product, ndigits);
|
||||||
|
|
||||||
|
/* s1 */
|
||||||
|
tmp[0] = 0;
|
||||||
|
tmp[1] = product[5] & 0xffffffff00000000ull;
|
||||||
|
tmp[2] = product[6];
|
||||||
|
tmp[3] = product[7];
|
||||||
|
carry = vli_lshift(tmp, tmp, 1, ndigits);
|
||||||
|
carry += vli_add(result, result, tmp, ndigits);
|
||||||
|
|
||||||
|
/* s2 */
|
||||||
|
tmp[1] = product[6] << 32;
|
||||||
|
tmp[2] = (product[6] >> 32) | (product[7] << 32);
|
||||||
|
tmp[3] = product[7] >> 32;
|
||||||
|
carry += vli_lshift(tmp, tmp, 1, ndigits);
|
||||||
|
carry += vli_add(result, result, tmp, ndigits);
|
||||||
|
|
||||||
|
/* s3 */
|
||||||
|
tmp[0] = product[4];
|
||||||
|
tmp[1] = product[5] & 0xffffffff;
|
||||||
|
tmp[2] = 0;
|
||||||
|
tmp[3] = product[7];
|
||||||
|
carry += vli_add(result, result, tmp, ndigits);
|
||||||
|
|
||||||
|
/* s4 */
|
||||||
|
tmp[0] = (product[4] >> 32) | (product[5] << 32);
|
||||||
|
tmp[1] = (product[5] >> 32) | (product[6] & 0xffffffff00000000ull);
|
||||||
|
tmp[2] = product[7];
|
||||||
|
tmp[3] = (product[6] >> 32) | (product[4] << 32);
|
||||||
|
carry += vli_add(result, result, tmp, ndigits);
|
||||||
|
|
||||||
|
/* d1 */
|
||||||
|
tmp[0] = (product[5] >> 32) | (product[6] << 32);
|
||||||
|
tmp[1] = (product[6] >> 32);
|
||||||
|
tmp[2] = 0;
|
||||||
|
tmp[3] = (product[4] & 0xffffffff) | (product[5] << 32);
|
||||||
|
carry -= vli_sub(result, result, tmp, ndigits);
|
||||||
|
|
||||||
|
/* d2 */
|
||||||
|
tmp[0] = product[6];
|
||||||
|
tmp[1] = product[7];
|
||||||
|
tmp[2] = 0;
|
||||||
|
tmp[3] = (product[4] >> 32) | (product[5] & 0xffffffff00000000ull);
|
||||||
|
carry -= vli_sub(result, result, tmp, ndigits);
|
||||||
|
|
||||||
|
/* d3 */
|
||||||
|
tmp[0] = (product[6] >> 32) | (product[7] << 32);
|
||||||
|
tmp[1] = (product[7] >> 32) | (product[4] << 32);
|
||||||
|
tmp[2] = (product[4] >> 32) | (product[5] << 32);
|
||||||
|
tmp[3] = (product[6] << 32);
|
||||||
|
carry -= vli_sub(result, result, tmp, ndigits);
|
||||||
|
|
||||||
|
/* d4 */
|
||||||
|
tmp[0] = product[7];
|
||||||
|
tmp[1] = product[4] & 0xffffffff00000000ull;
|
||||||
|
tmp[2] = product[5];
|
||||||
|
tmp[3] = product[6] & 0xffffffff00000000ull;
|
||||||
|
carry -= vli_sub(result, result, tmp, ndigits);
|
||||||
|
|
||||||
|
if (carry < 0) {
|
||||||
|
do {
|
||||||
|
carry += vli_add(result, result, curve_prime, ndigits);
|
||||||
|
} while (carry < 0);
|
||||||
|
} else {
|
||||||
|
while (carry || vli_cmp(curve_prime, result, ndigits) != 1){
|
||||||
|
carry -= vli_sub(result, result, curve_prime, ndigits);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void vli_mmod_fast_sm2_256(u64 *result, u64 *_product, u64 *mod, u8 ndigits)
|
||||||
|
{
|
||||||
|
u32 tmp1[8];
|
||||||
|
u32 tmp2[8];
|
||||||
|
u32 tmp3[8];
|
||||||
|
u32 *product = (u32 *)_product;
|
||||||
|
int carry = 0;
|
||||||
|
|
||||||
|
vli_set(result, (u64 *)product, ndigits);
|
||||||
|
vli_clear((u64 *)tmp1, ndigits);
|
||||||
|
vli_clear((u64 *)tmp2, ndigits);
|
||||||
|
vli_clear((u64 *)tmp3, ndigits);
|
||||||
|
|
||||||
|
/* Y0 */
|
||||||
|
tmp1[0] = tmp1[3] = tmp1[7] = product[8];
|
||||||
|
tmp2[2] = product[8];
|
||||||
|
carry += vli_add(result, result, (u64 *)tmp1, ndigits);
|
||||||
|
carry -= vli_sub(result, result, (u64 *)tmp2, ndigits);
|
||||||
|
|
||||||
|
/* Y1 */
|
||||||
|
tmp1[0] = tmp1[1] = tmp1[4] = tmp1[7] = product[9];
|
||||||
|
tmp1[3] = 0;
|
||||||
|
tmp2[2] = product[9];
|
||||||
|
carry += vli_add(result, result, (u64 *)tmp1, ndigits);
|
||||||
|
carry -= vli_sub(result, result, (u64 *)tmp2, ndigits);
|
||||||
|
|
||||||
|
/* Y2 */
|
||||||
|
tmp1[0] = tmp1[1] = tmp1[5] = tmp1[7] = product[10];
|
||||||
|
tmp1[4] = 0;
|
||||||
|
carry += vli_add(result, result, (u64 *)tmp1, ndigits);
|
||||||
|
|
||||||
|
/* Y3 */
|
||||||
|
tmp1[0] = tmp1[1] = tmp1[3] = tmp1[6] = tmp1[7] = product[11];
|
||||||
|
tmp1[5] = 0;
|
||||||
|
carry += vli_add(result, result, (u64 *)tmp1, ndigits);
|
||||||
|
|
||||||
|
/* Y4 */
|
||||||
|
tmp1[0] = tmp1[1] = tmp1[3] = tmp1[4] = tmp1[7] = tmp3[7] = product[12];
|
||||||
|
tmp1[6] = 0;
|
||||||
|
carry += vli_add(result, result, (u64 *)tmp1, ndigits);
|
||||||
|
carry += vli_add(result, result, (u64 *)tmp3, ndigits);
|
||||||
|
|
||||||
|
/* Y5 */
|
||||||
|
tmp1[0] = tmp1[1] = tmp1[3] = tmp1[4] = tmp1[5] = tmp1[7] = product[13];
|
||||||
|
tmp2[2] = product[13];
|
||||||
|
tmp3[0] = tmp3[3] = tmp3[7] = product[13];
|
||||||
|
carry += vli_add(result, result, (u64 *)tmp1, ndigits);
|
||||||
|
carry += vli_add(result, result, (u64 *)tmp3, ndigits);
|
||||||
|
carry -= vli_sub(result, result, (u64 *)tmp2, ndigits);
|
||||||
|
|
||||||
|
/* Y6 */
|
||||||
|
tmp1[0] = tmp1[1] = tmp1[3] = tmp1[4] = tmp1[5] = tmp1[6] = tmp1[7] = product[14];
|
||||||
|
tmp2[2] = product[14];
|
||||||
|
tmp3[0] = tmp3[1] = tmp3[4] = tmp3[7] = product[14];
|
||||||
|
tmp3[3] = 0;
|
||||||
|
carry += vli_add(result, result, (u64 *)tmp1, ndigits);
|
||||||
|
carry += vli_add(result, result, (u64 *)tmp3, ndigits);
|
||||||
|
carry -= vli_sub(result, result, (u64 *)tmp2, ndigits);
|
||||||
|
|
||||||
|
/* Y7 */
|
||||||
|
tmp1[0] = tmp1[1] = tmp1[3] = tmp1[4] = tmp1[5] = tmp1[6] = tmp1[7] = product[15];
|
||||||
|
tmp3[0] = tmp3[1] = tmp3[5] = product[15];
|
||||||
|
tmp3[4] = 0;
|
||||||
|
tmp3[7] = 0;
|
||||||
|
tmp2[7] = product[15];
|
||||||
|
tmp2[2] = 0;
|
||||||
|
carry += vli_lshift((u64 *)tmp2, (u64 *)tmp2, 1, ndigits);
|
||||||
|
carry += vli_add(result, result, (u64 *)tmp1, ndigits);
|
||||||
|
carry += vli_add(result, result, (u64 *)tmp3, ndigits);
|
||||||
|
carry += vli_add(result, result, (u64 *)tmp2, ndigits);
|
||||||
|
if (carry < 0) {
|
||||||
|
do {
|
||||||
|
carry += vli_add(result, result, mod, ndigits);
|
||||||
|
} while(carry < 0);
|
||||||
|
} else {
|
||||||
|
while (carry || vli_cmp(mod, result, ndigits) != 1)
|
||||||
|
{
|
||||||
|
carry -= vli_sub(result, result, mod, ndigits);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Computes result = (product) % mod. */
|
||||||
|
void _vli_mod(u64 *result, u64 *product, u64 *mod, u8 ndigits)
|
||||||
|
{
|
||||||
|
u64 modMultiple[2 * 128];
|
||||||
|
u32 digitShift, bitShift;
|
||||||
|
u32 productBits;
|
||||||
|
u32 modBits = vli_num_bits(mod, ndigits);
|
||||||
|
|
||||||
|
productBits = vli_num_bits(product + ndigits, ndigits);
|
||||||
|
if (productBits) {
|
||||||
|
productBits += ndigits * 64;
|
||||||
|
} else {
|
||||||
|
productBits = vli_num_bits(product, ndigits);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (productBits < modBits) {
|
||||||
|
/* product < mod. */
|
||||||
|
vli_set(result, product, ndigits);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Shift mod by (leftBits - modBits). This multiplies mod by the largest
|
||||||
|
power of two possible while still resulting in a number less than left. */
|
||||||
|
vli_clear(modMultiple, ndigits);
|
||||||
|
vli_clear(modMultiple + ndigits, ndigits);
|
||||||
|
digitShift = (productBits - modBits) / 64;
|
||||||
|
bitShift = (productBits - modBits) % 64;
|
||||||
|
if (bitShift) {
|
||||||
|
modMultiple[digitShift + ndigits] = vli_lshift(modMultiple + digitShift, mod, bitShift, ndigits);
|
||||||
|
} else {
|
||||||
|
vli_set(modMultiple + digitShift, mod, ndigits);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Subtract all multiples of mod to get the remainder. */
|
||||||
|
vli_clear(result, ndigits);
|
||||||
|
result[0] = 1; /* Use result as a temp var to store 1 (for subtraction) */
|
||||||
|
while (productBits > ndigits * 64 || vli_cmp(modMultiple, mod, ndigits) >= 0)
|
||||||
|
{
|
||||||
|
u64 carry;
|
||||||
|
int cmp = vli_cmp(modMultiple + ndigits, product + ndigits, ndigits);
|
||||||
|
if (cmp < 0 || (cmp == 0 && vli_cmp(modMultiple, product, ndigits) <= 0)) {
|
||||||
|
if (vli_sub(product, product, modMultiple, ndigits))
|
||||||
|
{
|
||||||
|
/* borrow */
|
||||||
|
vli_sub(product + ndigits, product + ndigits, result, ndigits);
|
||||||
|
}
|
||||||
|
vli_sub(product + ndigits, product + ndigits, modMultiple + ndigits, ndigits);
|
||||||
|
}
|
||||||
|
carry = (modMultiple[ndigits] & 0x01) << 63;
|
||||||
|
vli_rshift(modMultiple + ndigits, modMultiple + ndigits, 1, ndigits);
|
||||||
|
vli_rshift(modMultiple, modMultiple, 1, ndigits);
|
||||||
|
modMultiple[ndigits-1] |= carry;
|
||||||
|
|
||||||
|
--productBits;
|
||||||
|
}
|
||||||
|
vli_set(result, product, ndigits);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Computes result = (product) % mod. */
|
||||||
|
void vli_mod(u64 *result, u64 *product, u64 *mod, u8 ndigits)
|
||||||
|
{
|
||||||
|
bn_mod(result, product, mod, ndigits);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Computes result = (left * right) % curve->p. */
|
||||||
|
void vli_mod_mult_fast(u64 *result, u64 *left, u64 *right, u64 *mod, u8 ndigits)
|
||||||
|
{
|
||||||
|
u64 product[2 * 128];
|
||||||
|
|
||||||
|
vli_mult(product, left, right, ndigits);
|
||||||
|
vli_mod(result, product, mod, ndigits);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Computes result = left^2 % curve->p. */
|
||||||
|
void vli_mod_square_fast(u64 *result, u64 *left, u64 *mod, u8 ndigits)
|
||||||
|
{
|
||||||
|
u64 product[2 * 128];
|
||||||
|
|
||||||
|
vli_square(product, left, ndigits);
|
||||||
|
|
||||||
|
vli_mod(result, product, mod, ndigits);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Computes result = (left * right) % mod. */
|
||||||
|
void vli_mod_mult(u64 *result, u64 *left, u64 *right, u64 *mod, u8 ndigits)
|
||||||
|
{
|
||||||
|
u64 product[2 * 1024];
|
||||||
|
|
||||||
|
vli_mult(product, left, right, ndigits);
|
||||||
|
vli_mod(result, product, mod, ndigits);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Computes result = left^2 % mod. */
|
||||||
|
void vli_mod_square(u64 *result, u64 *left, u64 *mod, u8 ndigits)
|
||||||
|
{
|
||||||
|
u64 product[2 * 128];
|
||||||
|
|
||||||
|
vli_square(product, left, ndigits);
|
||||||
|
vli_mod(result, product, mod, ndigits);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define DIGIT_2MSB(x) (u64)(((x) >> (VLI_DIGIT_BITS - 2)) & 0x03)
|
||||||
|
/* Computes result = left^p % mod. */
|
||||||
|
void vli_mod_exp(u64 *result, u64 *left, u64 *p, u64 *mod, u8 ndigits)
|
||||||
|
{
|
||||||
|
u64 bpower[3][128], t[128];
|
||||||
|
u64 ci_bits, ci;
|
||||||
|
u32 j, s;
|
||||||
|
u32 digits;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
vli_set(bpower[0], left, ndigits);
|
||||||
|
vli_mod_mult(bpower[1], bpower[0], left, mod, ndigits);
|
||||||
|
vli_mod_mult(bpower[2], bpower[1], left, mod, ndigits);
|
||||||
|
vli_clear(t, ndigits);
|
||||||
|
t[0] = 1;
|
||||||
|
|
||||||
|
digits = vli_num_digits(p , ndigits);
|
||||||
|
|
||||||
|
i = digits - 1;
|
||||||
|
for ( ; i >= 0; i--) {
|
||||||
|
ci = p[i];
|
||||||
|
ci_bits = VLI_DIGIT_BITS;
|
||||||
|
|
||||||
|
if (i == (digits - 1)) {
|
||||||
|
while (!DIGIT_2MSB(ci)) {
|
||||||
|
ci <<= 2;
|
||||||
|
ci_bits -= 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for( j = 0; j < ci_bits; j += 2) {
|
||||||
|
vli_mod_mult(t, t, t, mod, ndigits);
|
||||||
|
vli_mod_mult(t, t, t, mod, ndigits);
|
||||||
|
if ((s = DIGIT_2MSB(ci)) != 0) {
|
||||||
|
vli_mod_mult(t, t, bpower[s-1], mod, ndigits);
|
||||||
|
}
|
||||||
|
ci <<= 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vli_set(result, t, ndigits);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define EVEN(vli) (!(vli[0] & 1))
|
||||||
|
/* Computes result = (1 / p_input) % mod. All VLIs are the same size.
|
||||||
|
* See "From Euclid's GCD to Montgomery Multiplication to the Great Divide"
|
||||||
|
* https://labs.oracle.com/techrep/2001/smli_tr-2001-95.pdf
|
||||||
|
*/
|
||||||
|
void vli_mod_inv(u64 *result, u64 *input, u64 *mod, u8 ndigits)
|
||||||
|
{
|
||||||
|
u64 a[128], b[128];
|
||||||
|
u64 u[128], v[128];
|
||||||
|
u64 carry;
|
||||||
|
int cmp_result;
|
||||||
|
|
||||||
|
if (vli_is_zero(input, ndigits)) {
|
||||||
|
vli_clear(result, ndigits);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
vli_set(a, input, ndigits);
|
||||||
|
vli_set(b, mod, ndigits);
|
||||||
|
vli_clear(u, ndigits);
|
||||||
|
u[0] = 1;
|
||||||
|
vli_clear(v, ndigits);
|
||||||
|
|
||||||
|
while ((cmp_result = vli_cmp(a, b, ndigits)) != 0) {
|
||||||
|
carry = 0;
|
||||||
|
|
||||||
|
if (EVEN(a)) {
|
||||||
|
vli_rshift(a, a, 1, ndigits);
|
||||||
|
|
||||||
|
if (!EVEN(u))
|
||||||
|
carry = vli_add(u, u, mod, ndigits);
|
||||||
|
|
||||||
|
vli_rshift(u, u, 1, ndigits);
|
||||||
|
if (carry)
|
||||||
|
u[ndigits - 1] |= 0x8000000000000000ull;
|
||||||
|
} else if (EVEN(b)) {
|
||||||
|
vli_rshift(b, b, 1, ndigits);
|
||||||
|
|
||||||
|
if (!EVEN(v))
|
||||||
|
carry = vli_add(v, v, mod, ndigits);
|
||||||
|
|
||||||
|
vli_rshift(v, v, 1, ndigits);
|
||||||
|
if (carry)
|
||||||
|
v[ndigits - 1] |= 0x8000000000000000ull;
|
||||||
|
} else if (cmp_result > 0) {
|
||||||
|
vli_sub(a, a, b, ndigits);
|
||||||
|
vli_rshift(a, a, 1, ndigits);
|
||||||
|
|
||||||
|
if (vli_cmp(u, v, ndigits) < 0)
|
||||||
|
vli_add(u, u, mod, ndigits);
|
||||||
|
|
||||||
|
vli_sub(u, u, v, ndigits);
|
||||||
|
if (!EVEN(u))
|
||||||
|
carry = vli_add(u, u, mod, ndigits);
|
||||||
|
|
||||||
|
vli_rshift(u, u, 1, ndigits);
|
||||||
|
if (carry)
|
||||||
|
u[ndigits - 1] |= 0x8000000000000000ull;
|
||||||
|
} else {
|
||||||
|
vli_sub(b, b, a, ndigits);
|
||||||
|
vli_rshift(b, b, 1, ndigits);
|
||||||
|
|
||||||
|
if (vli_cmp(v, u, ndigits) < 0)
|
||||||
|
vli_add(v, v, mod, ndigits);
|
||||||
|
|
||||||
|
vli_sub(v, v, u, ndigits);
|
||||||
|
if (!EVEN(v))
|
||||||
|
carry = vli_add(v, v, mod, ndigits);
|
||||||
|
|
||||||
|
vli_rshift(v, v, 1, ndigits);
|
||||||
|
if (carry)
|
||||||
|
v[ndigits - 1] |= 0x8000000000000000ull;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vli_set(result, u, ndigits);
|
||||||
|
}
|
88
AWSMServer/src/sm2sm3_enc/big.h
Normal file
88
AWSMServer/src/sm2sm3_enc/big.h
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
#ifndef _BIG_H_
|
||||||
|
#define _BIG_H_
|
||||||
|
|
||||||
|
#include "typedef.h"
|
||||||
|
|
||||||
|
#define VLI_DIGIT_BITS 64
|
||||||
|
#define VLI_DIGIT_BYTES (VLI_DIGIT_BITS/8)
|
||||||
|
|
||||||
|
void vli_clear(u64 *vli, u8 ndigits);
|
||||||
|
|
||||||
|
/* Returns true if vli == 0, false otherwise. */
|
||||||
|
int vli_is_zero(u64 *vli, u8 ndigits);
|
||||||
|
|
||||||
|
/* Returns nonzero if bit bit of vli is set. */
|
||||||
|
u64 vli_test_bit(u64 *vli, u8 bit, u8 ndigits);
|
||||||
|
|
||||||
|
/* Counts the number of 8-bit "digits" in vli. */
|
||||||
|
u32 vli_num_digits(u64 *vli, u8 ndigits);
|
||||||
|
|
||||||
|
/* Counts the number of bits required for vli. */
|
||||||
|
u32 vli_num_bits(u64 *vli, u8 ndigits);
|
||||||
|
/* Sets dest = src. */
|
||||||
|
|
||||||
|
void vli_set(u64 *dest, u64 *src, u8 ndigits);
|
||||||
|
|
||||||
|
/* Returns sign of left - right. */
|
||||||
|
int vli_cmp(u64 *left, u64 *right, u8 ndigits);
|
||||||
|
|
||||||
|
/* Computes result = in << c, returning carry. Can modify in place
|
||||||
|
* (if result == in). 0 < shift < 8.
|
||||||
|
*/
|
||||||
|
u64 vli_lshift(u64 *result, u64 *in, u32 shift, u8 ndigits);
|
||||||
|
|
||||||
|
/* Computes result = (left * right) % curve->p. */
|
||||||
|
void vli_mod_mult_fast(u64 *result, u64 *left, u64 *right, u64 *mod, u8 ndigits);
|
||||||
|
|
||||||
|
/* Computes result = left^2 % curve->p. */
|
||||||
|
void vli_mod_square_fast(u64 *result, u64 *left, u64 *mod, u8 ndigits);
|
||||||
|
|
||||||
|
/* Computes result = in >> c, returning carry. Can modify in place
|
||||||
|
* (if result == in). 0 < shift < 64.
|
||||||
|
*/
|
||||||
|
u64 vli_rshift(u64 *result, u64 *in, u32 shift, u8 ndigits);
|
||||||
|
|
||||||
|
/* Computes result = left + right, returning carry. Can modify in place. */
|
||||||
|
u64 vli_add(u64 *result, u64 *left, u64 *right, u8 ndigits);
|
||||||
|
|
||||||
|
/* Computes result = left - right, returning borrow. Can modify in place. */
|
||||||
|
u64 vli_sub(u64 *result, u64 *left, u64 *right, u8 ndigits);
|
||||||
|
|
||||||
|
/* Computes result = left * right. */
|
||||||
|
void vli_mult(u64 *result, u64 *left, u64 *right, u8 ndigits);
|
||||||
|
|
||||||
|
/* Computes result = left^2. */
|
||||||
|
void vli_square(u64 *result, u64 *left, u8 ndigits);
|
||||||
|
|
||||||
|
/* Computes result = (left + right) % mod.
|
||||||
|
Assumes that left < mod and right < mod, result != mod. */
|
||||||
|
void vli_mod_add(u64 *result, u64 *left, u64 *right, u64 *mod, u8 ndigits);
|
||||||
|
|
||||||
|
/* Computes result = (left - right) % mod.
|
||||||
|
Assumes that left < mod and right < mod, result != mod. */
|
||||||
|
void vli_mod_sub(u64 *result, u64 *left, u64 *right, u64 *mod, u8 ndigits);
|
||||||
|
|
||||||
|
/* Computes result = (left * right) % mod. */
|
||||||
|
void vli_mod_mult(u64 *result, u64 *left, u64 *right, u64 *mod, u8 ndigits);
|
||||||
|
|
||||||
|
/* Computes result = left^2 % mod. */
|
||||||
|
void vli_mod_square(u64 *result, u64 *left, u64 *mod, u8 ndigits);
|
||||||
|
|
||||||
|
/* Computes result = left^p % mod. */
|
||||||
|
void vli_mod_exp(u64 *result, u64 *left, u64 *p, u64 *mod, u8 ndigits);
|
||||||
|
|
||||||
|
/* Computes result = (product) % mod. */
|
||||||
|
void vli_mod(u64 *result, u64 *product, u64 *mod, u8 ndigits);
|
||||||
|
|
||||||
|
/* Computes result = (1 / input) % mod. All VLIs are the same size.
|
||||||
|
* See "From Euclid's GCD to Montgomery Multiplication to the Great Divide"
|
||||||
|
* https://labs.oracle.com/techrep/2001/smli_tr-2001-95.pdf
|
||||||
|
*/
|
||||||
|
void vli_mod_inv(u64 *result, u64 *input, u64 *mod, u8 ndigits);
|
||||||
|
|
||||||
|
/* Computes result = (left / right).
|
||||||
|
* remainder = (left % right).
|
||||||
|
*/
|
||||||
|
void vli_div(u64 *result, u64 *remainder, u64 *left, u64 cdigits, u64 *right, u8 ddigits);
|
||||||
|
|
||||||
|
#endif
|
352
AWSMServer/src/sm2sm3_enc/ecc.c
Normal file
352
AWSMServer/src/sm2sm3_enc/ecc.c
Normal file
@ -0,0 +1,352 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include "typedef.h"
|
||||||
|
#include "ecc.h"
|
||||||
|
#include "big.h"
|
||||||
|
|
||||||
|
static u64 cpu_to_be64(u64 x)
|
||||||
|
{
|
||||||
|
u64 r;
|
||||||
|
int i, len;
|
||||||
|
char *p, *q;
|
||||||
|
|
||||||
|
len = sizeof(x);
|
||||||
|
q = (char *)&x + len - 1;
|
||||||
|
p = (char *)&r;
|
||||||
|
|
||||||
|
for (i = 0; i < len; i++)
|
||||||
|
{
|
||||||
|
*p = *q;
|
||||||
|
p++;
|
||||||
|
q--;
|
||||||
|
}
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
static u64 be64_to_cpu(u64 x)
|
||||||
|
{
|
||||||
|
u64 r;
|
||||||
|
int i, len;
|
||||||
|
char *p, *q;
|
||||||
|
|
||||||
|
len = sizeof(x);
|
||||||
|
q = (char *)&x + len - 1;
|
||||||
|
p = (char *)&r;
|
||||||
|
|
||||||
|
for (i = 0; i < len; i++)
|
||||||
|
{
|
||||||
|
*p = *q;
|
||||||
|
p++;
|
||||||
|
q--;
|
||||||
|
}
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns 1 if point is the point at infinity, 0 otherwise. */
|
||||||
|
int ecc_point_is_zero(struct ecc_curve *curve, ecc_point *point)
|
||||||
|
{
|
||||||
|
return (vli_is_zero(point->x, curve->ndigits)
|
||||||
|
&& vli_is_zero(point->y, curve->ndigits));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Double in place */
|
||||||
|
void ecc_point_double_jacobian(struct ecc_curve *curve, u64 *X1, u64 *Y1, u64 *Z1)
|
||||||
|
{
|
||||||
|
/* t1 = X, t2 = Y, t3 = Z */
|
||||||
|
u64 t4[ECC_MAX_DIGITS];
|
||||||
|
u64 t5[ECC_MAX_DIGITS];
|
||||||
|
|
||||||
|
if(vli_is_zero(Z1, curve->ndigits))
|
||||||
|
return;
|
||||||
|
|
||||||
|
vli_mod_square_fast(t4, Y1, curve->p, curve->ndigits); /* t4 = y1^2 */
|
||||||
|
vli_mod_mult_fast(t5, X1, t4, curve->p, curve->ndigits); /* t5 = x1*y1^2 = A */
|
||||||
|
vli_mod_square_fast(t4, t4, curve->p, curve->ndigits); /* t4 = y1^4 */
|
||||||
|
vli_mod_mult_fast(Y1, Y1, Z1, curve->p, curve->ndigits); /* t2 = y1*z1 = z3 */
|
||||||
|
vli_mod_square_fast(Z1, Z1, curve->p, curve->ndigits); /* t3 = z1^2 */
|
||||||
|
|
||||||
|
vli_mod_add(X1, X1, Z1, curve->p, curve->ndigits); /* t1 = x1 + z1^2 */
|
||||||
|
vli_mod_add(Z1, Z1, Z1, curve->p, curve->ndigits); /* t3 = 2*z1^2 */
|
||||||
|
vli_mod_sub(Z1, X1, Z1, curve->p, curve->ndigits); /* t3 = x1 - z1^2 */
|
||||||
|
vli_mod_mult_fast(X1, X1, Z1, curve->p, curve->ndigits); /* t1 = x1^2 - z1^4 */
|
||||||
|
|
||||||
|
vli_mod_add(Z1, X1, X1, curve->p, curve->ndigits); /* t3 = 2*(x1^2 - z1^4) */
|
||||||
|
vli_mod_add(X1, X1, Z1, curve->p, curve->ndigits); /* t1 = 3*(x1^2 - z1^4) */
|
||||||
|
if (vli_test_bit(X1, 0, curve->ndigits)) {
|
||||||
|
u64 carry = vli_add(X1, X1, curve->p, curve->ndigits);
|
||||||
|
vli_rshift(X1, X1, 1, curve->ndigits);
|
||||||
|
X1[ECC_MAX_DIGITS-1] |= carry << 63;
|
||||||
|
} else {
|
||||||
|
vli_rshift(X1, X1, 1, curve->ndigits);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* t1 = 3/2*(x1^2 - z1^4) = B */
|
||||||
|
vli_mod_square_fast(Z1, X1, curve->p, curve->ndigits); /* t3 = B^2 */
|
||||||
|
vli_mod_sub(Z1, Z1, t5, curve->p, curve->ndigits); /* t3 = B^2 - A */
|
||||||
|
vli_mod_sub(Z1, Z1, t5, curve->p, curve->ndigits); /* t3 = B^2 - 2A = x3 */
|
||||||
|
vli_mod_sub(t5, t5, Z1, curve->p, curve->ndigits); /* t5 = A - x3 */
|
||||||
|
vli_mod_mult_fast(X1, X1, t5, curve->p, curve->ndigits); /* t1 = B * (A - x3) */
|
||||||
|
vli_mod_sub(t4, X1, t4, curve->p, curve->ndigits); /* t4 = B * (A - x3) - y1^4 = y3 */
|
||||||
|
|
||||||
|
vli_set(X1, Z1, curve->ndigits);
|
||||||
|
vli_set(Z1, Y1, curve->ndigits);
|
||||||
|
vli_set(Y1, t4, curve->ndigits);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Modify (x1, y1) => (x1 * z^2, y1 * z^3) */
|
||||||
|
void apply_z(struct ecc_curve *curve, u64 *X1, u64 *Y1, u64 *Z)
|
||||||
|
{
|
||||||
|
u64 t1[ECC_MAX_DIGITS];
|
||||||
|
|
||||||
|
vli_mod_square_fast(t1, Z, curve->p, curve->ndigits); /* z^2 */
|
||||||
|
vli_mod_mult_fast(X1, X1, t1, curve->p, curve->ndigits); /* x1 * z^2 */
|
||||||
|
vli_mod_mult_fast(t1, t1, Z, curve->p, curve->ndigits); /* z^3 */
|
||||||
|
vli_mod_mult_fast(Y1, Y1, t1, curve->p, curve->ndigits); /* y1 * z^3 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* P = (x1, y1) => 2P, (x2, y2) => P' */
|
||||||
|
void XYcZ_initial_double(struct ecc_curve *curve, u64 *X1, u64 *Y1, u64 *X2, u64 *Y2, u64 *initialZ)
|
||||||
|
{
|
||||||
|
u64 z[ECC_MAX_DIGITS];
|
||||||
|
|
||||||
|
vli_set(X2, X1, curve->ndigits);
|
||||||
|
vli_set(Y2, Y1, curve->ndigits);
|
||||||
|
|
||||||
|
if (initialZ) {
|
||||||
|
vli_set(z, initialZ, curve->ndigits);
|
||||||
|
} else {
|
||||||
|
vli_clear(z, curve->ndigits);
|
||||||
|
z[0] = 1;
|
||||||
|
}
|
||||||
|
apply_z(curve, X1, Y1, z);
|
||||||
|
|
||||||
|
ecc_point_double_jacobian(curve, X1, Y1, z);
|
||||||
|
|
||||||
|
apply_z(curve, X2, Y2, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Input P = (x1, y1, Z), Q = (x2, y2, Z)
|
||||||
|
Output P' = (x1', y1', Z3), P + Q = (x3, y3, Z3)
|
||||||
|
or P => P', Q => P + Q
|
||||||
|
*/
|
||||||
|
void XYcZ_add(struct ecc_curve *curve, u64 *X1, u64 *Y1, u64 *X2, u64 *Y2)
|
||||||
|
{
|
||||||
|
/* t1 = X1, t2 = Y1, t3 = X2, t4 = Y2 */
|
||||||
|
u64 t5[ECC_MAX_DIGITS];
|
||||||
|
|
||||||
|
vli_mod_sub(t5, X2, X1, curve->p, curve->ndigits); /* t5 = x2 - x1 */
|
||||||
|
vli_mod_square_fast(t5, t5, curve->p, curve->ndigits); /* t5 = (x2 - x1)^2 = A */
|
||||||
|
vli_mod_mult_fast(X1, X1, t5, curve->p, curve->ndigits); /* t1 = x1*A = B */
|
||||||
|
vli_mod_mult_fast(X2, X2, t5, curve->p, curve->ndigits); /* t3 = x2*A = C */
|
||||||
|
vli_mod_sub(Y2, Y2, Y1, curve->p, curve->ndigits); /* t4 = y2 - y1 */
|
||||||
|
vli_mod_square_fast(t5, Y2, curve->p, curve->ndigits); /* t5 = (y2 - y1)^2 = D */
|
||||||
|
|
||||||
|
vli_mod_sub(t5, t5, X1, curve->p, curve->ndigits); /* t5 = D - B */
|
||||||
|
vli_mod_sub(t5, t5, X2, curve->p, curve->ndigits); /* t5 = D - B - C = x3 */
|
||||||
|
vli_mod_sub(X2, X2, X1, curve->p, curve->ndigits); /* t3 = C - B */
|
||||||
|
vli_mod_mult_fast(Y1, Y1, X2, curve->p, curve->ndigits); /* t2 = y1*(C - B) */
|
||||||
|
vli_mod_sub(X2, X1, t5, curve->p, curve->ndigits); /* t3 = B - x3 */
|
||||||
|
vli_mod_mult_fast(Y2, Y2, X2, curve->p, curve->ndigits); /* t4 = (y2 - y1)*(B - x3) */
|
||||||
|
vli_mod_sub(Y2, Y2, Y1, curve->p, curve->ndigits); /* t4 = y3 */
|
||||||
|
|
||||||
|
vli_set(X2, t5, curve->ndigits);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Input P = (x1, y1, Z), Q = (x2, y2, Z)
|
||||||
|
* Output P + Q = (x3, y3, Z3), P - Q = (x3', y3', Z3)
|
||||||
|
* or P => P - Q, Q => P + Q
|
||||||
|
*/
|
||||||
|
void XYcZ_addC(struct ecc_curve *curve, u64 *X1, u64 *Y1, u64 *X2, u64 *Y2)
|
||||||
|
{
|
||||||
|
/* t1 = X1, t2 = Y1, t3 = X2, t4 = Y2 */
|
||||||
|
u64 t5[ECC_MAX_DIGITS];
|
||||||
|
u64 t6[ECC_MAX_DIGITS];
|
||||||
|
u64 t7[ECC_MAX_DIGITS];
|
||||||
|
|
||||||
|
vli_mod_sub(t5, X2, X1, curve->p, curve->ndigits); /* t5 = x2 - x1 */
|
||||||
|
vli_mod_square_fast(t5, t5, curve->p, curve->ndigits); /* t5 = (x2 - x1)^2 = A */
|
||||||
|
vli_mod_mult_fast(X1, X1, t5, curve->p, curve->ndigits); /* t1 = x1*A = B */
|
||||||
|
vli_mod_mult_fast(X2, X2, t5, curve->p, curve->ndigits); /* t3 = x2*A = C */
|
||||||
|
vli_mod_add(t5, Y2, Y1, curve->p, curve->ndigits); /* t4 = y2 + y1 */
|
||||||
|
vli_mod_sub(Y2, Y2, Y1, curve->p, curve->ndigits); /* t4 = y2 - y1 */
|
||||||
|
|
||||||
|
vli_mod_sub(t6, X2, X1, curve->p, curve->ndigits); /* t6 = C - B */
|
||||||
|
vli_mod_mult_fast(Y1, Y1, t6, curve->p, curve->ndigits); /* t2 = y1 * (C - B) */
|
||||||
|
vli_mod_add(t6, X1, X2, curve->p, curve->ndigits); /* t6 = B + C */
|
||||||
|
vli_mod_square_fast(X2, Y2, curve->p, curve->ndigits); /* t3 = (y2 - y1)^2 */
|
||||||
|
vli_mod_sub(X2, X2, t6, curve->p, curve->ndigits); /* t3 = x3 */
|
||||||
|
|
||||||
|
vli_mod_sub(t7, X1, X2, curve->p, curve->ndigits); /* t7 = B - x3 */
|
||||||
|
vli_mod_mult_fast(Y2, Y2, t7, curve->p, curve->ndigits); /* t4 = (y2 - y1)*(B - x3) */
|
||||||
|
vli_mod_sub(Y2, Y2, Y1, curve->p, curve->ndigits); /* t4 = y3 */
|
||||||
|
|
||||||
|
vli_mod_square_fast(t7, t5, curve->p, curve->ndigits); /* t7 = (y2 + y1)^2 = F */
|
||||||
|
vli_mod_sub(t7, t7, t6, curve->p, curve->ndigits); /* t7 = x3' */
|
||||||
|
vli_mod_sub(t6, t7, X1, curve->p, curve->ndigits); /* t6 = x3' - B */
|
||||||
|
vli_mod_mult_fast(t6, t6, t5, curve->p, curve->ndigits); /* t6 = (y2 + y1)*(x3' - B) */
|
||||||
|
vli_mod_sub(Y1, t6, Y1, curve->p, curve->ndigits); /* t2 = y3' */
|
||||||
|
|
||||||
|
vli_set(X1, t7, curve->ndigits);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ecc_point_mult(struct ecc_curve *curve, ecc_point *result, ecc_point *point, u64 *scalar, u64 *initialZ)
|
||||||
|
{
|
||||||
|
/* R0 and R1 */
|
||||||
|
u64 Rx[2][ECC_MAX_DIGITS];
|
||||||
|
u64 Ry[2][ECC_MAX_DIGITS];
|
||||||
|
u64 z[ECC_MAX_DIGITS];
|
||||||
|
int i, nb;
|
||||||
|
|
||||||
|
vli_set(Rx[1], point->x, curve->ndigits);
|
||||||
|
vli_set(Ry[1], point->y, curve->ndigits);
|
||||||
|
|
||||||
|
XYcZ_initial_double(curve, Rx[1], Ry[1], Rx[0], Ry[0], initialZ);
|
||||||
|
|
||||||
|
for (i = vli_num_bits(scalar, curve->ndigits) - 2; i > 0; --i) {
|
||||||
|
nb = !vli_test_bit(scalar, i, curve->ndigits);
|
||||||
|
XYcZ_addC(curve, Rx[1-nb], Ry[1-nb], Rx[nb], Ry[nb]);
|
||||||
|
XYcZ_add(curve, Rx[nb], Ry[nb], Rx[1-nb], Ry[1-nb]);
|
||||||
|
}
|
||||||
|
|
||||||
|
nb = !vli_test_bit(scalar, 0, curve->ndigits);
|
||||||
|
XYcZ_addC(curve, Rx[1-nb], Ry[1-nb], Rx[nb], Ry[nb]);
|
||||||
|
|
||||||
|
/* Find final 1/Z value. */
|
||||||
|
vli_mod_sub(z, Rx[1], Rx[0], curve->p, curve->ndigits); /* X1 - X0 */
|
||||||
|
vli_mod_mult_fast(z, z, Ry[1-nb], curve->p, curve->ndigits); /* Yb * (X1 - X0) */
|
||||||
|
vli_mod_mult_fast(z, z, point->x, curve->p, curve->ndigits); /* xP * Yb * (X1 - X0) */
|
||||||
|
vli_mod_inv(z, z, curve->p, curve->ndigits); /* 1 / (xP * Yb * (X1 - X0)) */
|
||||||
|
vli_mod_mult_fast(z, z, point->y, curve->p, curve->ndigits); /* yP / (xP * Yb * (X1 - X0)) */
|
||||||
|
vli_mod_mult_fast(z, z, Rx[1-nb], curve->p, curve->ndigits); /* Xb * yP / (xP * Yb * (X1 - X0)) */
|
||||||
|
/* End 1/Z calculation */
|
||||||
|
|
||||||
|
XYcZ_add(curve, Rx[nb], Ry[nb], Rx[1-nb], Ry[1-nb]);
|
||||||
|
|
||||||
|
apply_z(curve, Rx[0], Ry[0], z);
|
||||||
|
|
||||||
|
vli_set(result->x, Rx[0], curve->ndigits);
|
||||||
|
vli_set(result->y, Ry[0], curve->ndigits);
|
||||||
|
}
|
||||||
|
|
||||||
|
static u32 max(u32 a, u32 b)
|
||||||
|
{
|
||||||
|
return (a > b ? a : b);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ecc_point_mult2(struct ecc_curve *curve, ecc_point *result, ecc_point *g, ecc_point *p, u64 *s, u64 *t)
|
||||||
|
{
|
||||||
|
u64 tx[ECC_MAX_DIGITS];
|
||||||
|
u64 ty[ECC_MAX_DIGITS];
|
||||||
|
u64 tz[ECC_MAX_DIGITS];
|
||||||
|
u64 z[ECC_MAX_DIGITS];
|
||||||
|
ecc_point sum;
|
||||||
|
u64 *rx;
|
||||||
|
u64 *ry;
|
||||||
|
int i;
|
||||||
|
ecc_point *points[4] = {NULL, g, p, &sum};
|
||||||
|
u32 numBits;
|
||||||
|
ecc_point *point;
|
||||||
|
|
||||||
|
rx = result->x;
|
||||||
|
ry = result->y;
|
||||||
|
|
||||||
|
/* Calculate sum = G + Q. */
|
||||||
|
vli_set(sum.x, p->x, curve->ndigits);
|
||||||
|
vli_set(sum.y, p->y, curve->ndigits);
|
||||||
|
vli_set(tx, g->x, curve->ndigits);
|
||||||
|
vli_set(ty, g->y, curve->ndigits);
|
||||||
|
|
||||||
|
vli_mod_sub(z, sum.x, tx, curve->p, curve->ndigits); /* Z = x2 - x1 */
|
||||||
|
XYcZ_add(curve, tx, ty, sum.x, sum.y);
|
||||||
|
vli_mod_inv(z, z, curve->p, curve->ndigits); /* Z = 1/Z */
|
||||||
|
apply_z(curve, sum.x, sum.y, z);
|
||||||
|
|
||||||
|
numBits = max(vli_num_bits(s, curve->ndigits), vli_num_bits(t, curve->ndigits));
|
||||||
|
|
||||||
|
point = points[(!!vli_test_bit(s, numBits-1, curve->ndigits))
|
||||||
|
| ((!!vli_test_bit(t, numBits-1, curve->ndigits)) << 1)];
|
||||||
|
vli_set(rx, point->x, curve->ndigits);
|
||||||
|
vli_set(ry, point->y, curve->ndigits);
|
||||||
|
vli_clear(z, curve->ndigits);
|
||||||
|
z[0] = 1;
|
||||||
|
|
||||||
|
for (i = numBits - 2; i >= 0; --i) {
|
||||||
|
int index;
|
||||||
|
ecc_point *point;
|
||||||
|
ecc_point_double_jacobian(curve, rx, ry, z);
|
||||||
|
|
||||||
|
index = (!!vli_test_bit(s, i, curve->ndigits)) | ((!!vli_test_bit(t, i, curve->ndigits)) << 1);
|
||||||
|
point = points[index];
|
||||||
|
if(point) {
|
||||||
|
vli_set(tx, point->x, curve->ndigits);
|
||||||
|
vli_set(ty, point->y, curve->ndigits);
|
||||||
|
apply_z(curve, tx, ty, z);
|
||||||
|
vli_mod_sub(tz, rx, tx, curve->p, curve->ndigits); /* Z = x2 - x1 */
|
||||||
|
XYcZ_add(curve, tx, ty, rx, ry);
|
||||||
|
vli_mod_mult_fast(z, z, tz, curve->p, curve->ndigits);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vli_mod_inv(z, z, curve->p, curve->ndigits); /* Z = 1/Z */
|
||||||
|
apply_z(curve, rx, ry, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ecc_point_add(struct ecc_curve *curve, ecc_point *result, ecc_point *left, ecc_point *right)
|
||||||
|
{
|
||||||
|
u64 x1[ECC_MAX_DIGITS];
|
||||||
|
u64 y1[ECC_MAX_DIGITS];
|
||||||
|
u64 x2[ECC_MAX_DIGITS];
|
||||||
|
u64 y2[ECC_MAX_DIGITS];
|
||||||
|
u64 z[ECC_MAX_DIGITS];
|
||||||
|
|
||||||
|
vli_set(x1, left->x, curve->ndigits);
|
||||||
|
vli_set(y1, left->y, curve->ndigits);
|
||||||
|
vli_set(x2, right->x, curve->ndigits);
|
||||||
|
vli_set(y2, right->y, curve->ndigits);
|
||||||
|
|
||||||
|
vli_mod_sub(z, x2, x1, curve->p, curve->ndigits); /* Z = x2 - x1 */
|
||||||
|
|
||||||
|
XYcZ_add(curve, x1, y1, x2, y2);
|
||||||
|
vli_mod_inv(z, z, curve->p, curve->ndigits); /* Z = 1/Z */
|
||||||
|
apply_z(curve, x2,y2, z);
|
||||||
|
|
||||||
|
vli_set(result->x, x2, curve->ndigits);
|
||||||
|
vli_set(result->y, y2, curve->ndigits);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ecc_bytes2native(u64 *native, void *bytes, u8 ndigits)
|
||||||
|
{
|
||||||
|
u64 *_bytes = (u64*)bytes;
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for (i = 0; i < ndigits/2; ++i) {
|
||||||
|
if (native == _bytes) {
|
||||||
|
u64 temp;
|
||||||
|
temp = be64_to_cpu(native[i]);
|
||||||
|
native[i] = be64_to_cpu(_bytes[ndigits - i - 1]);
|
||||||
|
_bytes[ndigits - i - 1] = temp;
|
||||||
|
}else {
|
||||||
|
native[i] = be64_to_cpu(_bytes[ndigits - i - 1]);
|
||||||
|
native[ndigits - i - 1] = be64_to_cpu(_bytes[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ecc_native2bytes(void *bytes, u64 *native, u8 ndigits)
|
||||||
|
{
|
||||||
|
u64 *_bytes = (u64*)bytes;
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for (i = 0; i < ndigits/2; ++i) {
|
||||||
|
if (_bytes == native) {
|
||||||
|
u64 temp;
|
||||||
|
temp = cpu_to_be64(_bytes[ndigits - i - 1]);
|
||||||
|
_bytes[ndigits - i - 1] = cpu_to_be64(native[i]);
|
||||||
|
native[i] = temp;
|
||||||
|
} else {
|
||||||
|
_bytes[i] = cpu_to_be64(native[ndigits - i - 1]);
|
||||||
|
_bytes[ndigits - i - 1] = cpu_to_be64(native[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
64
AWSMServer/src/sm2sm3_enc/ecc.h
Normal file
64
AWSMServer/src/sm2sm3_enc/ecc.h
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
#ifndef _ECC_H_
|
||||||
|
#define _ECC_H_
|
||||||
|
|
||||||
|
#include "typedef.h"
|
||||||
|
|
||||||
|
#define ECC_WORDSIZE 8
|
||||||
|
#define ECC_NUMBITS 256
|
||||||
|
#define ECC_NUMWORD (ECC_NUMBITS/ECC_WORDSIZE) //32
|
||||||
|
|
||||||
|
#define ECC_MAX_DIGITS 4
|
||||||
|
|
||||||
|
#define SWAP(a,b) { u32 t = a; a = b; b = t;}
|
||||||
|
|
||||||
|
/*
|
||||||
|
#define digit2str16(x, y) { \
|
||||||
|
(y)[0] = (u64)((x >> 8 ) & 0x000000FF); \
|
||||||
|
(y)[1] = (u64)((x >> 0 ) & 0x000000FF); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define str2digit16(y, x) { \
|
||||||
|
x = ((((u16)(y)[0]) & 0x000000FF) << 8) | \
|
||||||
|
((((u16)(y)[1]) & 0x000000FF) << 0 ); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define digit2str32(x, y) { \
|
||||||
|
(y)[0] = (u64)((x >> 24) & 0x000000FF); \
|
||||||
|
(y)[1] = (u64)((x >> 16) & 0x000000FF); \
|
||||||
|
(y)[2] = (u64)((x >> 8 ) & 0x000000FF); \
|
||||||
|
(y)[3] = (u64)((x >> 0 ) & 0x000000FF); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define str2digit32(y, x) { \
|
||||||
|
x = ((((u32)(y)[0]) & 0x000000FF) << 24) | \
|
||||||
|
((((u32)(y)[1]) & 0x000000FF) << 16) | \
|
||||||
|
((((u32)(y)[2]) & 0x000000FF) << 8 ) | \
|
||||||
|
((((u32)(y)[3]) & 0x000000FF) << 0 ); \
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef struct ecc_point
|
||||||
|
{
|
||||||
|
u64 x[ECC_MAX_DIGITS];
|
||||||
|
u64 y[ECC_MAX_DIGITS];
|
||||||
|
} ecc_point;
|
||||||
|
|
||||||
|
struct ecc_curve {
|
||||||
|
u8 ndigits;
|
||||||
|
struct ecc_point g;
|
||||||
|
u64 p[ECC_MAX_DIGITS];
|
||||||
|
u64 n[ECC_MAX_DIGITS];
|
||||||
|
u64 h[ECC_MAX_DIGITS];
|
||||||
|
u64 a[ECC_MAX_DIGITS];
|
||||||
|
u64 b[ECC_MAX_DIGITS];
|
||||||
|
};
|
||||||
|
|
||||||
|
void ecc_bytes2native(u64 *native, void *bytes, u8 ndigits);
|
||||||
|
void ecc_native2bytes(void *bytes, u64 *native, u8 ndigits);
|
||||||
|
|
||||||
|
void ecc_point_add(struct ecc_curve *curve, ecc_point *result, ecc_point *x, ecc_point *y);
|
||||||
|
void ecc_point_mult(struct ecc_curve *curve, ecc_point *result, ecc_point *point, u64 *scalar, u64 *initialZ);
|
||||||
|
void ecc_point_mult2(struct ecc_curve *curve, ecc_point *result, ecc_point *g, ecc_point *p, u64 *s, u64 *t);
|
||||||
|
int ecc_point_is_zero(struct ecc_curve *curve, ecc_point *point);
|
||||||
|
|
||||||
|
#endif
|
28
AWSMServer/src/sm2sm3_enc/random.c
Normal file
28
AWSMServer/src/sm2sm3_enc/random.c
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "typedef.h"
|
||||||
|
|
||||||
|
int vli_get_random(u8 *data, u32 len)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
if (len >= 4)
|
||||||
|
{
|
||||||
|
for (i = 0; i < len / 4; i++)
|
||||||
|
{
|
||||||
|
r = rand();
|
||||||
|
memcpy(data + i * 4, &r, 4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (len % 4)
|
||||||
|
{
|
||||||
|
r = rand();
|
||||||
|
memcpy(data + i * 4, &r, len % 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
10
AWSMServer/src/sm2sm3_enc/random.h
Normal file
10
AWSMServer/src/sm2sm3_enc/random.h
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
|
||||||
|
#ifndef _RANDOM_H_
|
||||||
|
#define _RANDOM_H_
|
||||||
|
|
||||||
|
#include "typedef.h"
|
||||||
|
|
||||||
|
|
||||||
|
int vli_get_random(u8 *p_data, u32 len);
|
||||||
|
|
||||||
|
#endif
|
537
AWSMServer/src/sm2sm3_enc/sm2.c
Normal file
537
AWSMServer/src/sm2sm3_enc/sm2.c
Normal file
@ -0,0 +1,537 @@
|
|||||||
|
#include <fcntl.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "big.h"
|
||||||
|
#include "ecc.h"
|
||||||
|
#include "sm2.h"
|
||||||
|
#include "sm3.h"
|
||||||
|
|
||||||
|
struct ecc_curve sm2_curve = {
|
||||||
|
ECC_MAX_DIGITS,
|
||||||
|
{
|
||||||
|
{0x715A4589334C74C7ull, 0x8FE30BBFF2660BE1ull, 0x5F9904466A39C994ull, 0x32C4AE2C1F198119ull},
|
||||||
|
{0x02DF32E52139F0A0ull, 0xD0A9877CC62A4740ull, 0x59BDCEE36B692153ull, 0xBC3736A2F4F6779Cull},
|
||||||
|
},
|
||||||
|
{0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFF00000000ull, 0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFEFFFFFFFFull},
|
||||||
|
{0x53BBF40939D54123ull, 0x7203DF6B21C6052Bull, 0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFEFFFFFFFFull},
|
||||||
|
{
|
||||||
|
0x0000000000000001ull,
|
||||||
|
0x0000000000000000ull,
|
||||||
|
0x0000000000000000ull,
|
||||||
|
0x0000000000000000ull,
|
||||||
|
},
|
||||||
|
{0xFFFFFFFFFFFFFFFCull, 0xFFFFFFFF00000000ull, 0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFEFFFFFFFFull},
|
||||||
|
{0xDDBCBD414D940E93ull, 0xF39789F515AB8F92ull, 0x4D5A9E4BCF6509A7ull, 0x28E9FA9E9D9F5E34ull},
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
sm2_w(u64 *result, u64 *x)
|
||||||
|
{
|
||||||
|
result[0] = x[0];
|
||||||
|
result[1] = x[1];
|
||||||
|
result[1] |= 0x80;
|
||||||
|
result[2] = 0;
|
||||||
|
result[3] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
sm3_kdf(u8 *Z, u32 zlen, u8 *K, u32 klen)
|
||||||
|
{
|
||||||
|
u32 ct = 0x00000001;
|
||||||
|
u8 ct_char[32];
|
||||||
|
u8 *hash = K;
|
||||||
|
u32 i, t;
|
||||||
|
struct sm3_ctx md[1];
|
||||||
|
|
||||||
|
t = klen / ECC_NUMWORD;
|
||||||
|
//s4: K=Ha1||Ha2||...
|
||||||
|
for (i = 0; i < t; i++) {
|
||||||
|
//s2: Hai=Hv(Z||ct)
|
||||||
|
sm3_init(md);
|
||||||
|
sm3_update(md, Z, zlen);
|
||||||
|
put_unaligned_be32(ct, ct_char);
|
||||||
|
sm3_update(md, ct_char, 4);
|
||||||
|
sm3_final(md, hash);
|
||||||
|
hash += 32;
|
||||||
|
ct++;
|
||||||
|
}
|
||||||
|
|
||||||
|
t = klen % ECC_NUMBITS;
|
||||||
|
if (t) {
|
||||||
|
sm3_init(md);
|
||||||
|
sm3_update(md, Z, zlen);
|
||||||
|
put_unaligned_be32(ct, ct_char);
|
||||||
|
sm3_update(md, ct_char, 4);
|
||||||
|
sm3_final(md, ct_char);
|
||||||
|
memcpy(hash, ct_char, t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
sm3_z(u8 *id, u32 idlen, ecc_point *pub, u8 *hash)
|
||||||
|
{
|
||||||
|
u8 a[ECC_NUMWORD];
|
||||||
|
u8 b[ECC_NUMWORD];
|
||||||
|
u8 x[ECC_NUMWORD];
|
||||||
|
u8 y[ECC_NUMWORD];
|
||||||
|
u8 idlen_char[2];
|
||||||
|
struct sm3_ctx md[1];
|
||||||
|
|
||||||
|
put_unaligned_be16(idlen << 3, idlen_char);
|
||||||
|
|
||||||
|
ecc_bytes2native((u64 *) a, sm2_curve.a, sm2_curve.ndigits);
|
||||||
|
ecc_bytes2native((u64 *) b, sm2_curve.b, sm2_curve.ndigits);
|
||||||
|
ecc_bytes2native((u64 *) x, sm2_curve.g.x, sm2_curve.ndigits);
|
||||||
|
ecc_bytes2native((u64 *) y, sm2_curve.g.y, sm2_curve.ndigits);
|
||||||
|
|
||||||
|
sm3_init(md);
|
||||||
|
sm3_update(md, idlen_char, 2);
|
||||||
|
sm3_update(md, id, idlen);
|
||||||
|
sm3_update(md, a, ECC_NUMWORD);
|
||||||
|
sm3_update(md, b, ECC_NUMWORD);
|
||||||
|
sm3_update(md, x, ECC_NUMWORD);
|
||||||
|
sm3_update(md, y, ECC_NUMWORD);
|
||||||
|
sm3_update(md, (u8 *) pub->x, ECC_NUMWORD);
|
||||||
|
sm3_update(md, (u8 *) pub->y, ECC_NUMWORD);
|
||||||
|
sm3_final(md, hash);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
sm2_valid_public_key(ecc_point *publicKey)
|
||||||
|
{
|
||||||
|
u64 na[ECC_MAX_DIGITS] = {3}; /* a mod p = (-3) mod p */
|
||||||
|
u64 tmp1[ECC_MAX_DIGITS];
|
||||||
|
u64 tmp2[ECC_MAX_DIGITS];
|
||||||
|
|
||||||
|
if (ecc_point_is_zero(&sm2_curve, publicKey)) return 1;
|
||||||
|
|
||||||
|
if (vli_cmp(sm2_curve.p, publicKey->x, sm2_curve.ndigits) != 1
|
||||||
|
|| vli_cmp(sm2_curve.p, publicKey->y, sm2_curve.ndigits) != 1)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
/* tmp1 = y^2 */
|
||||||
|
vli_mod_square_fast(tmp1, publicKey->y, sm2_curve.p, sm2_curve.ndigits);
|
||||||
|
/* tmp2 = x^2 */
|
||||||
|
vli_mod_square_fast(tmp2, publicKey->x, sm2_curve.p, sm2_curve.ndigits);
|
||||||
|
/* tmp2 = x^2 + a = x^2 - 3 */
|
||||||
|
vli_mod_sub(tmp2, tmp2, na, sm2_curve.p, sm2_curve.ndigits);
|
||||||
|
/* tmp2 = x^3 + ax */
|
||||||
|
vli_mod_mult_fast(tmp2, tmp2, publicKey->x, sm2_curve.p, sm2_curve.ndigits);
|
||||||
|
/* tmp2 = x^3 + ax + b */
|
||||||
|
vli_mod_add(tmp2, tmp2, sm2_curve.b, sm2_curve.p, sm2_curve.ndigits);
|
||||||
|
|
||||||
|
/* Make sure that y^2 == x^3 + ax + b */
|
||||||
|
if (vli_cmp(tmp1, tmp2, sm2_curve.ndigits) != 0) return 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
sm2_make_prikey(u8 *prikey)
|
||||||
|
{
|
||||||
|
ecc_point pub[1];
|
||||||
|
u64 pri[ECC_MAX_DIGITS];
|
||||||
|
int i = 10;
|
||||||
|
|
||||||
|
do {
|
||||||
|
vli_get_random((u8 *) pri, ECC_NUMWORD);
|
||||||
|
if (vli_cmp(sm2_curve.n, pri, sm2_curve.ndigits) != 1) { vli_sub(pri, pri, sm2_curve.n, sm2_curve.ndigits); }
|
||||||
|
|
||||||
|
/* The private key cannot be 0 (mod p). */
|
||||||
|
if (!vli_is_zero(pri, sm2_curve.ndigits)) {
|
||||||
|
ecc_native2bytes(prikey, pri, sm2_curve.ndigits);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
} while (i--);
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
sm2_make_pubkey(u8 *prikey, ecc_point *pubkey)
|
||||||
|
{
|
||||||
|
ecc_point pub[1];
|
||||||
|
u64 pri[ECC_MAX_DIGITS];
|
||||||
|
|
||||||
|
ecc_bytes2native(pri, prikey, sm2_curve.ndigits);
|
||||||
|
ecc_point_mult(&sm2_curve, pub, &sm2_curve.g, pri, NULL);
|
||||||
|
ecc_native2bytes(pubkey->x, pub->x, sm2_curve.ndigits);
|
||||||
|
ecc_native2bytes(pubkey->y, pub->y, sm2_curve.ndigits);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
sm2_make_keypair(u8 *prikey, ecc_point *pubkey)
|
||||||
|
{
|
||||||
|
sm2_make_prikey(prikey);
|
||||||
|
sm2_make_pubkey(prikey, pubkey);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
sm2_point_mult(ecc_point *G, u8 *k, ecc_point *P)
|
||||||
|
{
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
ecc_point G_[1];
|
||||||
|
ecc_point P_[1];
|
||||||
|
u64 k_[ECC_MAX_DIGITS];
|
||||||
|
|
||||||
|
ecc_bytes2native(k_, k, sm2_curve.ndigits);
|
||||||
|
ecc_bytes2native(G_->x, G->x, sm2_curve.ndigits);
|
||||||
|
ecc_bytes2native(G_->y, G->y, sm2_curve.ndigits);
|
||||||
|
|
||||||
|
ecc_point_mult(&sm2_curve, P_, G_, k_, NULL);
|
||||||
|
|
||||||
|
ecc_native2bytes(P->x, P_->x, sm2_curve.ndigits);
|
||||||
|
ecc_native2bytes(P->y, P_->y, sm2_curve.ndigits);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
sm2_sign(u8 *r_, u8 *s_, u8 *prikey, u8 *hash_)
|
||||||
|
{
|
||||||
|
u64 k[ECC_MAX_DIGITS];
|
||||||
|
u64 one[ECC_MAX_DIGITS] = {1};
|
||||||
|
u64 random[ECC_MAX_DIGITS];
|
||||||
|
u64 pri[ECC_MAX_DIGITS];
|
||||||
|
u64 hash[ECC_MAX_DIGITS];
|
||||||
|
u64 r[ECC_MAX_DIGITS];
|
||||||
|
u64 s[ECC_MAX_DIGITS];
|
||||||
|
|
||||||
|
ecc_point p;
|
||||||
|
|
||||||
|
ecc_bytes2native(pri, prikey, sm2_curve.ndigits);
|
||||||
|
ecc_bytes2native(hash, hash_, sm2_curve.ndigits);
|
||||||
|
|
||||||
|
vli_get_random((u8 *) random, ECC_NUMWORD);
|
||||||
|
if (vli_is_zero(random, sm2_curve.ndigits)) {
|
||||||
|
/* The random number must not be 0. */
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
vli_set(k, random, sm2_curve.ndigits);
|
||||||
|
if (vli_cmp(sm2_curve.n, k, sm2_curve.ndigits) != 1) { vli_sub(k, k, sm2_curve.n, sm2_curve.ndigits); }
|
||||||
|
|
||||||
|
/* tmp = k * G */
|
||||||
|
ecc_point_mult(&sm2_curve, &p, &sm2_curve.g, k, NULL);
|
||||||
|
|
||||||
|
/* r = x1 + e (mod n) */
|
||||||
|
vli_mod_add(r, p.x, hash, sm2_curve.n, sm2_curve.ndigits);
|
||||||
|
if (vli_cmp(sm2_curve.n, r, sm2_curve.ndigits) != 1) { vli_sub(r, r, sm2_curve.n, sm2_curve.ndigits); }
|
||||||
|
|
||||||
|
if (vli_is_zero(r, sm2_curve.ndigits)) {
|
||||||
|
/* If r == 0, fail (need a different random number). */
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* s = r*d */
|
||||||
|
vli_mod_mult(s, r, pri, sm2_curve.n, sm2_curve.ndigits);
|
||||||
|
/* k-r*d */
|
||||||
|
vli_mod_sub(s, k, s, sm2_curve.n, sm2_curve.ndigits);
|
||||||
|
/* 1+d */
|
||||||
|
vli_mod_add(pri, pri, one, sm2_curve.n, sm2_curve.ndigits);
|
||||||
|
/* (1+d)' */
|
||||||
|
vli_mod_inv(pri, pri, sm2_curve.n, sm2_curve.ndigits);
|
||||||
|
/* (1+d)'*(k-r*d) */
|
||||||
|
vli_mod_mult(s, pri, s, sm2_curve.n, sm2_curve.ndigits);
|
||||||
|
|
||||||
|
ecc_native2bytes(r_, r, sm2_curve.ndigits);
|
||||||
|
ecc_native2bytes(s_, s, sm2_curve.ndigits);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
sm2_verify(ecc_point *pubkey, u8 *hash_, u8 *r_, u8 *s_)
|
||||||
|
{
|
||||||
|
ecc_point result;
|
||||||
|
ecc_point pub[1];
|
||||||
|
u64 t[ECC_MAX_DIGITS];
|
||||||
|
u64 r[ECC_MAX_DIGITS];
|
||||||
|
u64 s[ECC_MAX_DIGITS];
|
||||||
|
u64 hash[ECC_MAX_DIGITS];
|
||||||
|
|
||||||
|
ecc_bytes2native(pub->x, pubkey->x, sm2_curve.ndigits);
|
||||||
|
ecc_bytes2native(pub->y, pubkey->y, sm2_curve.ndigits);
|
||||||
|
ecc_bytes2native(r, r_, sm2_curve.ndigits);
|
||||||
|
ecc_bytes2native(s, s_, sm2_curve.ndigits);
|
||||||
|
ecc_bytes2native(hash, hash_, sm2_curve.ndigits);
|
||||||
|
|
||||||
|
if (vli_is_zero(r, sm2_curve.ndigits) || vli_is_zero(s, sm2_curve.ndigits)) {
|
||||||
|
/* r, s must not be 0. */
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vli_cmp(sm2_curve.n, r, sm2_curve.ndigits) != 1 || vli_cmp(sm2_curve.n, s, sm2_curve.ndigits) != 1) {
|
||||||
|
/* r, s must be < n. */
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
vli_mod_add(t, r, s, sm2_curve.n, sm2_curve.ndigits);// r + s
|
||||||
|
if (t == 0) return -1;
|
||||||
|
|
||||||
|
ecc_point_mult2(&sm2_curve, &result, &sm2_curve.g, pub, s, t);
|
||||||
|
|
||||||
|
/* v = x1 + e (mod n) */
|
||||||
|
vli_mod_add(result.x, result.x, hash, sm2_curve.n, sm2_curve.ndigits);
|
||||||
|
|
||||||
|
if (vli_cmp(sm2_curve.n, result.x, sm2_curve.ndigits) != 1) {
|
||||||
|
vli_sub(result.x, result.x, sm2_curve.n, sm2_curve.ndigits);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Accept only if v == r. */
|
||||||
|
return vli_cmp(result.x, r, sm2_curve.ndigits);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
sm2_shared_point(u8 *selfPriKey,
|
||||||
|
u8 *selfTempPriKey,
|
||||||
|
ecc_point *selfTempPubKey,
|
||||||
|
ecc_point *otherPubKey,
|
||||||
|
ecc_point *otherTempPubKey,
|
||||||
|
ecc_point *key)
|
||||||
|
{
|
||||||
|
ecc_point selfTempPub;
|
||||||
|
ecc_point otherTempPub;
|
||||||
|
ecc_point otherPub;
|
||||||
|
ecc_point U[1];
|
||||||
|
|
||||||
|
u64 selfTempPri[ECC_MAX_DIGITS];
|
||||||
|
u64 selfPri[ECC_MAX_DIGITS];
|
||||||
|
u64 temp1[ECC_MAX_DIGITS];
|
||||||
|
u64 temp2[ECC_MAX_DIGITS];
|
||||||
|
u64 tA[ECC_MAX_DIGITS];
|
||||||
|
|
||||||
|
ecc_bytes2native(selfTempPri, selfTempPriKey, sm2_curve.ndigits);
|
||||||
|
ecc_bytes2native(selfPri, selfPriKey, sm2_curve.ndigits);
|
||||||
|
ecc_bytes2native(selfTempPub.x, selfTempPubKey->x, sm2_curve.ndigits);
|
||||||
|
ecc_bytes2native(selfTempPub.y, selfTempPubKey->y, sm2_curve.ndigits);
|
||||||
|
ecc_bytes2native(otherTempPub.x, otherTempPubKey->x, sm2_curve.ndigits);
|
||||||
|
ecc_bytes2native(otherTempPub.y, otherTempPubKey->y, sm2_curve.ndigits);
|
||||||
|
ecc_bytes2native(otherPub.x, otherPubKey->x, sm2_curve.ndigits);
|
||||||
|
ecc_bytes2native(otherPub.y, otherPubKey->y, sm2_curve.ndigits);
|
||||||
|
|
||||||
|
/***********x1_=2^w+x2 & (2^w-1)*************/
|
||||||
|
sm2_w(temp1, selfTempPub.x);
|
||||||
|
/***********tA=(dA+x1_*rA)mod n *************/
|
||||||
|
vli_mod_mult(temp1, selfTempPri, temp1, sm2_curve.n, sm2_curve.ndigits);
|
||||||
|
vli_mod_add(tA, selfPri, temp1, sm2_curve.n, sm2_curve.ndigits);
|
||||||
|
/***********x2_=2^w+x2 & (2^w-1)*************/
|
||||||
|
if (sm2_valid_public_key(&otherTempPub) != 0) return -1;
|
||||||
|
sm2_w(temp2, otherTempPub.x);
|
||||||
|
/**************U=[h*tA](PB+[x2_]RB)**********/
|
||||||
|
/* U=[x2_]RB */
|
||||||
|
ecc_point_mult(&sm2_curve, U, &otherTempPub, temp2, NULL);
|
||||||
|
/*U=PB+U*/
|
||||||
|
ecc_point_add(&sm2_curve, U, &otherPub, U);
|
||||||
|
/*tA=tA*h */
|
||||||
|
vli_mod_mult(tA, tA, sm2_curve.h, sm2_curve.n, sm2_curve.ndigits);
|
||||||
|
ecc_point_mult(&sm2_curve, U, U, tA, NULL);
|
||||||
|
|
||||||
|
ecc_native2bytes(key->x, U->x, sm2_curve.ndigits);
|
||||||
|
ecc_native2bytes(key->y, U->y, sm2_curve.ndigits);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
sm2_shared_key(ecc_point *point, u8 *ZA, u8 *ZB, u32 keyLen, u8 *key)
|
||||||
|
{
|
||||||
|
u8 Z[ECC_NUMWORD * 4];
|
||||||
|
memcpy(Z, point->x, ECC_NUMWORD);
|
||||||
|
memcpy(Z + ECC_NUMWORD, point->y, ECC_NUMWORD);
|
||||||
|
memcpy(Z + ECC_NUMWORD * 2, ZA, ECC_NUMWORD);
|
||||||
|
memcpy(Z + ECC_NUMWORD * 3, ZB, ECC_NUMWORD);
|
||||||
|
sm3_kdf(Z, ECC_NUMWORD * 4, key, keyLen);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****hash = Hash(Ux||ZA||ZB||x1||y1||x2||y2)****/
|
||||||
|
int
|
||||||
|
ECC_Key_ex_hash1(u8 *x, ecc_point *RA, ecc_point *RB, u8 ZA[], u8 ZB[], u8 *hash)
|
||||||
|
{
|
||||||
|
struct sm3_ctx md[1];
|
||||||
|
|
||||||
|
sm3_init(md);
|
||||||
|
sm3_update(md, x, ECC_NUMWORD);
|
||||||
|
sm3_update(md, ZA, ECC_NUMWORD);
|
||||||
|
sm3_update(md, ZB, ECC_NUMWORD);
|
||||||
|
sm3_update(md, (u8 *) RA->x, ECC_NUMWORD);
|
||||||
|
sm3_update(md, (u8 *) RA->y, ECC_NUMWORD);
|
||||||
|
sm3_update(md, (u8 *) RB->x, ECC_NUMWORD);
|
||||||
|
sm3_update(md, (u8 *) RB->y, ECC_NUMWORD);
|
||||||
|
sm3_final(md, (u8 *) hash);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****SA = Hash(temp||Uy||Hash)****/
|
||||||
|
int
|
||||||
|
ECC_Key_ex_hash2(u8 temp, u8 *y, u8 *hash, u8 *SA)
|
||||||
|
{
|
||||||
|
struct sm3_ctx md[1];
|
||||||
|
|
||||||
|
sm3_init(md);
|
||||||
|
sm3_update(md, &temp, 1);
|
||||||
|
sm3_update(md, y, ECC_NUMWORD);
|
||||||
|
sm3_update(md, hash, ECC_NUMWORD);
|
||||||
|
sm3_final(md, SA);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
ECC_KeyEx_Init_I(u8 *pri, ecc_point *pub)
|
||||||
|
{
|
||||||
|
return sm2_make_pubkey(pri, pub);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
ECC_KeyEx_Re_I(u8 *rb,
|
||||||
|
u8 *dB,
|
||||||
|
ecc_point *RA,
|
||||||
|
ecc_point *PA,
|
||||||
|
u8 *ZA,
|
||||||
|
u8 *ZB,
|
||||||
|
u8 *K,
|
||||||
|
u32 klen,
|
||||||
|
ecc_point *RB,
|
||||||
|
ecc_point *V,
|
||||||
|
u8 *SB)
|
||||||
|
{
|
||||||
|
u8 Z[ECC_NUMWORD * 2 + ECC_NUMBITS / 4] = {0};
|
||||||
|
u8 hash[ECC_NUMWORD], S1[ECC_NUMWORD];
|
||||||
|
u8 temp = 0x02;
|
||||||
|
|
||||||
|
//--------B2: RB=[rb]G=(x2,y2)--------
|
||||||
|
sm2_make_pubkey(rb, RB);
|
||||||
|
/********************************************/
|
||||||
|
sm2_shared_point(dB, rb, RB, PA, RA, V);
|
||||||
|
//------------B7:KB=KDF(VX,VY,ZA,ZB,KLEN)----------
|
||||||
|
memcpy(Z, V->x, ECC_NUMWORD);
|
||||||
|
memcpy(Z + ECC_NUMWORD, (u8 *) V->y, ECC_NUMWORD);
|
||||||
|
memcpy(Z + ECC_NUMWORD * 2, ZA, ECC_NUMWORD);
|
||||||
|
memcpy(Z + ECC_NUMWORD * 3, ZB, ECC_NUMWORD);
|
||||||
|
sm3_kdf(Z, ECC_NUMWORD * 4, K, klen);
|
||||||
|
//---------------B8:(optional) SB=hash(0x02||Vy||HASH(Vx||ZA||ZB||x1||y1||x2||y2)-------------
|
||||||
|
ECC_Key_ex_hash1((u8 *) V->x, RA, RB, ZA, ZB, hash);
|
||||||
|
ECC_Key_ex_hash2(temp, (u8 *) V->y, hash, SB);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
ECC_KeyEx_Init_II(u8 *ra,
|
||||||
|
u8 *dA,
|
||||||
|
ecc_point *RA,
|
||||||
|
ecc_point *RB,
|
||||||
|
ecc_point *PB,
|
||||||
|
u8 ZA[],
|
||||||
|
u8 ZB[],
|
||||||
|
u8 SB[],
|
||||||
|
u8 K[],
|
||||||
|
u32 klen,
|
||||||
|
u8 SA[])
|
||||||
|
{
|
||||||
|
u8 Z[ECC_NUMWORD * 2 + ECC_NUMWORD * 2] = {0};
|
||||||
|
u8 hash[ECC_NUMWORD], S1[ECC_NUMWORD];
|
||||||
|
u8 temp[2] = {0x02, 0x03};
|
||||||
|
ecc_point U[1];
|
||||||
|
|
||||||
|
/********************************************/
|
||||||
|
sm2_shared_point(dA, ra, RA, PB, RB, U);
|
||||||
|
/************KA=KDF(UX,UY,ZA,ZB,KLEN)**********/
|
||||||
|
memcpy(Z, U->x, ECC_NUMWORD);
|
||||||
|
memcpy(Z + ECC_NUMWORD, U->y, ECC_NUMWORD);
|
||||||
|
memcpy(Z + ECC_NUMWORD * 2, ZA, ECC_NUMWORD);
|
||||||
|
memcpy(Z + ECC_NUMWORD * 2 + ECC_NUMWORD, ZB, ECC_NUMWORD);
|
||||||
|
sm3_kdf(Z, ECC_NUMWORD * 2 + ECC_NUMWORD * 2, K, klen);
|
||||||
|
/****S1 = Hash(0x02||Uy||Hash(Ux||ZA||ZB||x1||y1||x2||y2))****/
|
||||||
|
ECC_Key_ex_hash1((u8 *) U->x, RA, RB, ZA, ZB, hash);
|
||||||
|
ECC_Key_ex_hash2(temp[0], (u8 *) U->y, hash, S1);
|
||||||
|
/*test S1=SB?*/
|
||||||
|
if (memcmp(S1, SB, ECC_NUMWORD) != 0) return -1;
|
||||||
|
/*SA = Hash(0x03||yU||Hash(xU||ZA||ZB||x1||y1||x2||y2)) */
|
||||||
|
ECC_Key_ex_hash2(temp[1], (u8 *) U->y, hash, SA);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
ECC_KeyEx_Re_II(ecc_point *V, ecc_point *RA, ecc_point *RB, u8 ZA[], u8 ZB[], u8 SA[])
|
||||||
|
{
|
||||||
|
u8 hash[ECC_NUMWORD];
|
||||||
|
u8 S2[ECC_NUMWORD];
|
||||||
|
u8 temp = 0x03;
|
||||||
|
|
||||||
|
/*S2 = Hash(0x03||Vy||Hash(Vx||ZA||ZB||x1||y1||x2||y2))*/
|
||||||
|
ECC_Key_ex_hash1((u8 *) V->x, RA, RB, ZA, ZB, hash);
|
||||||
|
ECC_Key_ex_hash2(temp, (u8 *) V->y, hash, S2);
|
||||||
|
|
||||||
|
if (memcmp(S2, SA, ECC_NUMWORD) != 0) return -1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
do_sm2_verify(char *pubkey, char *data_addr, int data_len, char *sign_addr)
|
||||||
|
{
|
||||||
|
int ret = -1;
|
||||||
|
struct sm3_ctx sm3_ctx;
|
||||||
|
unsigned char ios_hash[32];
|
||||||
|
u8 ios_Z[ECC_NUMWORD];
|
||||||
|
ecc_point ios_pub;
|
||||||
|
unsigned char sign_data[64];
|
||||||
|
|
||||||
|
memcpy(&ios_pub, pubkey, 64);
|
||||||
|
|
||||||
|
ret = sm3_init(&sm3_ctx);
|
||||||
|
sm3_z((u8 *) "1234567812345678", 16, &ios_pub, ios_Z);
|
||||||
|
sm3_update(&sm3_ctx, ios_Z, ECC_NUMWORD);
|
||||||
|
sm3_update(&sm3_ctx, (const u8 *) data_addr, data_len);
|
||||||
|
sm3_final(&sm3_ctx, ios_hash);
|
||||||
|
memcpy(sign_data, sign_addr, 64);
|
||||||
|
|
||||||
|
ret = sm2_verify((ecc_point *) pubkey, ios_hash, sign_data, sign_data + 32);
|
||||||
|
if (ret) {
|
||||||
|
printf("verify err ret = %d\n", ret);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
do_sm2_sign(char *prikey, char *pubkey, char *data_addr, int data_len, char *sign_addr)
|
||||||
|
{
|
||||||
|
int ret = -1;
|
||||||
|
struct sm3_ctx sm3_ctx;
|
||||||
|
unsigned char ios_hash[32];
|
||||||
|
u8 ios_Z[ECC_NUMWORD];
|
||||||
|
ecc_point ios_pub;
|
||||||
|
unsigned char sign_data[64];
|
||||||
|
|
||||||
|
memcpy(&ios_pub, pubkey, 64);
|
||||||
|
|
||||||
|
ret = sm3_init(&sm3_ctx);
|
||||||
|
sm3_z((u8 *) "1234567812345678", 16, &ios_pub, ios_Z);
|
||||||
|
sm3_update(&sm3_ctx, ios_Z, ECC_NUMWORD);
|
||||||
|
sm3_update(&sm3_ctx, data_addr, data_len);
|
||||||
|
sm3_final(&sm3_ctx, ios_hash);
|
||||||
|
//hexdump("hash", ios_hash, 32);
|
||||||
|
|
||||||
|
ret = sm2_sign(sign_data, sign_data + 32, prikey, ios_hash);
|
||||||
|
if (ret) {
|
||||||
|
printf("sign err ret = %d\n", ret);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
memcpy(sign_addr, sign_data, 64);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
39
AWSMServer/src/sm2sm3_enc/sm2.h
Normal file
39
AWSMServer/src/sm2sm3_enc/sm2.h
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
#ifndef _SM2_H_
|
||||||
|
#define _SM2_H_
|
||||||
|
|
||||||
|
#include "ecc.h"
|
||||||
|
#include "typedef.h"
|
||||||
|
|
||||||
|
int vli_get_random(u8 *data, u32 len);
|
||||||
|
|
||||||
|
int sm2_make_prikey(u8 *prikey);
|
||||||
|
int sm2_make_pubkey(u8 *prikey, ecc_point *pubkey);
|
||||||
|
int sm2_make_keypair(u8 *prikey, ecc_point *pubkey);
|
||||||
|
int sm2_sign(u8 *r, u8 *s, u8 *pri, u8 *hash);
|
||||||
|
static int sm2_verify(ecc_point *pubkey, u8 *hash, u8 *r, u8 *s);
|
||||||
|
|
||||||
|
int sm2_encrypt(ecc_point *pubKey, u8 *M, u32 Mlen, u8 *C, u32 *Clen);
|
||||||
|
int sm2_decrypt(u8 *prikey, u8 *C, u32 Clen, u8 *M, u32 *Mlen);
|
||||||
|
|
||||||
|
static void sm3_z(u8 *id, u32 idlen, ecc_point *pub, u8 *hash);
|
||||||
|
int sm2_shared_point(u8 *selfPriKey, u8 *selfTempPriKey,
|
||||||
|
ecc_point *selfTempPubKey, ecc_point *otherPubKey,
|
||||||
|
ecc_point *otherTempPubKey, ecc_point *key);
|
||||||
|
int sm2_shared_key(ecc_point *point, u8 *ZA, u8 *ZB, u32 keyLen, u8 *key);
|
||||||
|
int sm2_point_mult(ecc_point *G, u8 *k, ecc_point *P);
|
||||||
|
|
||||||
|
int ECC_KeyEx_Init_I(u8 *pri, ecc_point *pub);
|
||||||
|
|
||||||
|
int ECC_KeyEx_Re_I(u8 *rb, u8 *dB, ecc_point *RA, ecc_point *PA, u8 *ZA, u8 *ZB,
|
||||||
|
u8 *K, u32 klen, ecc_point *RB, ecc_point *V, u8 *hash);
|
||||||
|
|
||||||
|
int ECC_KeyEx_Init_II(u8 *ra, u8 *dA, ecc_point *RA, ecc_point *RB,
|
||||||
|
ecc_point *PB, u8 ZA[], u8 ZB[], u8 SB[], u8 K[],
|
||||||
|
u32 klen, u8 SA[]);
|
||||||
|
|
||||||
|
int ECC_KeyEx_Re_II(ecc_point *V, ecc_point *RA, ecc_point *RB, u8 ZA[],
|
||||||
|
u8 ZB[], u8 SA[]);
|
||||||
|
int do_sm2_sign(char *prikey, char *pubkey, char *data_addr, int data_len,
|
||||||
|
char *sign_addr);
|
||||||
|
|
||||||
|
#endif /* _SM2_H_ */
|
248
AWSMServer/src/sm2sm3_enc/sm3.c
Normal file
248
AWSMServer/src/sm2sm3_enc/sm3.c
Normal file
@ -0,0 +1,248 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "typedef.h"
|
||||||
|
#include "sm3.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 32-bit integer manipulation macros (big endian)
|
||||||
|
*/
|
||||||
|
#ifndef GET_ULONG_BE
|
||||||
|
#define GET_ULONG_BE(n,b,i) \
|
||||||
|
{ \
|
||||||
|
(n) = ( (u32) (b)[(i) ] << 24 ) \
|
||||||
|
| ( (u32) (b)[(i) + 1] << 16 ) \
|
||||||
|
| ( (u32) (b)[(i) + 2] << 8 ) \
|
||||||
|
| ( (u32) (b)[(i) + 3] ); \
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef PUT_ULONG_BE
|
||||||
|
#define PUT_ULONG_BE(n,b,i) \
|
||||||
|
{ \
|
||||||
|
(b)[(i) ] = (u8) ( (n) >> 24 ); \
|
||||||
|
(b)[(i) + 1] = (u8) ( (n) >> 16 ); \
|
||||||
|
(b)[(i) + 2] = (u8) ( (n) >> 8 ); \
|
||||||
|
(b)[(i) + 3] = (u8) ( (n) ); \
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SM3 context setup
|
||||||
|
*/
|
||||||
|
int sm3_init(struct sm3_ctx *ctx)
|
||||||
|
{
|
||||||
|
ctx->total[0] = 0;
|
||||||
|
ctx->total[1] = 0;
|
||||||
|
|
||||||
|
ctx->state[0] = 0x7380166F;
|
||||||
|
ctx->state[1] = 0x4914B2B9;
|
||||||
|
ctx->state[2] = 0x172442D7;
|
||||||
|
ctx->state[3] = 0xDA8A0600;
|
||||||
|
ctx->state[4] = 0xA96F30BC;
|
||||||
|
ctx->state[5] = 0x163138AA;
|
||||||
|
ctx->state[6] = 0xE38DEE4D;
|
||||||
|
ctx->state[7] = 0xB0FB0E4E;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void sm3_process(struct sm3_ctx *ctx, u8 data[64])
|
||||||
|
{
|
||||||
|
u32 SS1, SS2, TT1, TT2, W[68],W1[64];
|
||||||
|
u32 A, B, C, D, E, F, G, H;
|
||||||
|
u32 T[64];
|
||||||
|
u32 Temp1,Temp2,Temp3,Temp4,Temp5;
|
||||||
|
int j;
|
||||||
|
|
||||||
|
for(j = 0; j < 16; j++)
|
||||||
|
T[j] = 0x79CC4519;
|
||||||
|
for(j =16; j < 64; j++)
|
||||||
|
T[j] = 0x7A879D8A;
|
||||||
|
|
||||||
|
GET_ULONG_BE( W[ 0], data, 0 );
|
||||||
|
GET_ULONG_BE( W[ 1], data, 4 );
|
||||||
|
GET_ULONG_BE( W[ 2], data, 8 );
|
||||||
|
GET_ULONG_BE( W[ 3], data, 12 );
|
||||||
|
GET_ULONG_BE( W[ 4], data, 16 );
|
||||||
|
GET_ULONG_BE( W[ 5], data, 20 );
|
||||||
|
GET_ULONG_BE( W[ 6], data, 24 );
|
||||||
|
GET_ULONG_BE( W[ 7], data, 28 );
|
||||||
|
GET_ULONG_BE( W[ 8], data, 32 );
|
||||||
|
GET_ULONG_BE( W[ 9], data, 36 );
|
||||||
|
GET_ULONG_BE( W[10], data, 40 );
|
||||||
|
GET_ULONG_BE( W[11], data, 44 );
|
||||||
|
GET_ULONG_BE( W[12], data, 48 );
|
||||||
|
GET_ULONG_BE( W[13], data, 52 );
|
||||||
|
GET_ULONG_BE( W[14], data, 56 );
|
||||||
|
GET_ULONG_BE( W[15], data, 60 );
|
||||||
|
|
||||||
|
#define FF0(x,y,z) ( (x) ^ (y) ^ (z))
|
||||||
|
#define FF1(x,y,z) (((x) & (y)) | ( (x) & (z)) | ( (y) & (z)))
|
||||||
|
|
||||||
|
#define GG0(x,y,z) ( (x) ^ (y) ^ (z))
|
||||||
|
#define GG1(x,y,z) (((x) & (y)) | ( (~(x)) & (z)) )
|
||||||
|
|
||||||
|
|
||||||
|
#define SHL(x,n) (((x) & 0xFFFFFFFF) << n)
|
||||||
|
#define ROTL(x,n) (SHL((x),n) | ((x) >> (32 - n)))
|
||||||
|
//#define ROTL(x,n) (SHL((x),n) | ((x) >> (32 - n%32)))
|
||||||
|
|
||||||
|
#define P0(x) ((x) ^ ROTL((x),9) ^ ROTL((x),17))
|
||||||
|
#define P1(x) ((x) ^ ROTL((x),15) ^ ROTL((x),23))
|
||||||
|
|
||||||
|
for(j = 16; j < 68; j++ )
|
||||||
|
{
|
||||||
|
//W[j] = P1( W[j-16] ^ W[j-9] ^ ROTL(W[j-3],15)) ^ ROTL(W[j - 13],7 ) ^ W[j-6];
|
||||||
|
//Why thd release's result is different with the debug's ?
|
||||||
|
//Below is okay. Interesting, Perhaps VC6 has a bug of Optimizaiton.
|
||||||
|
|
||||||
|
Temp1 = W[j-16] ^ W[j-9];
|
||||||
|
Temp2 = ROTL(W[j-3],15);
|
||||||
|
Temp3 = Temp1 ^ Temp2;
|
||||||
|
Temp4 = P1(Temp3);
|
||||||
|
Temp5 = ROTL(W[j - 13],7 ) ^ W[j-6];
|
||||||
|
W[j] = Temp4 ^ Temp5;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(j = 0; j < 64; j++)
|
||||||
|
{
|
||||||
|
W1[j] = W[j] ^ W[j+4];
|
||||||
|
}
|
||||||
|
|
||||||
|
A = ctx->state[0];
|
||||||
|
B = ctx->state[1];
|
||||||
|
C = ctx->state[2];
|
||||||
|
D = ctx->state[3];
|
||||||
|
E = ctx->state[4];
|
||||||
|
F = ctx->state[5];
|
||||||
|
G = ctx->state[6];
|
||||||
|
H = ctx->state[7];
|
||||||
|
|
||||||
|
for(j =0; j < 16; j++)
|
||||||
|
{
|
||||||
|
SS1 = ROTL((ROTL(A,12) + E + ROTL(T[j],j)), 7);
|
||||||
|
SS2 = SS1 ^ ROTL(A,12);
|
||||||
|
TT1 = FF0(A,B,C) + D + SS2 + W1[j];
|
||||||
|
TT2 = GG0(E,F,G) + H + SS1 + W[j];
|
||||||
|
D = C;
|
||||||
|
C = ROTL(B,9);
|
||||||
|
B = A;
|
||||||
|
A = TT1;
|
||||||
|
H = G;
|
||||||
|
G = ROTL(F,19);
|
||||||
|
F = E;
|
||||||
|
E = P0(TT2);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(j =16; j < 64; j++)
|
||||||
|
{
|
||||||
|
SS1 = ROTL((ROTL(A,12) + E + ROTL(T[j],j)), 7);
|
||||||
|
SS2 = SS1 ^ ROTL(A,12);
|
||||||
|
TT1 = FF1(A,B,C) + D + SS2 + W1[j];
|
||||||
|
TT2 = GG1(E,F,G) + H + SS1 + W[j];
|
||||||
|
D = C;
|
||||||
|
C = ROTL(B,9);
|
||||||
|
B = A;
|
||||||
|
A = TT1;
|
||||||
|
H = G;
|
||||||
|
G = ROTL(F,19);
|
||||||
|
F = E;
|
||||||
|
E = P0(TT2);
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx->state[0] ^= A;
|
||||||
|
ctx->state[1] ^= B;
|
||||||
|
ctx->state[2] ^= C;
|
||||||
|
ctx->state[3] ^= D;
|
||||||
|
ctx->state[4] ^= E;
|
||||||
|
ctx->state[5] ^= F;
|
||||||
|
ctx->state[6] ^= G;
|
||||||
|
ctx->state[7] ^= H;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SM3 process buffer
|
||||||
|
*/
|
||||||
|
int sm3_update(struct sm3_ctx *ctx, const u8 *input, u32 ilen)
|
||||||
|
{
|
||||||
|
u32 left;
|
||||||
|
int fill;
|
||||||
|
|
||||||
|
if( ilen <= 0 )
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
left = ctx->total[0] & 0x3F;
|
||||||
|
fill = 64 - left;
|
||||||
|
|
||||||
|
ctx->total[0] += ilen;
|
||||||
|
ctx->total[0] &= 0xFFFFFFFF;
|
||||||
|
|
||||||
|
if( ctx->total[0] < (u32) ilen )
|
||||||
|
ctx->total[1]++;
|
||||||
|
|
||||||
|
if( left && ilen >= fill )
|
||||||
|
{
|
||||||
|
memcpy( (void *) (ctx->buffer + left),
|
||||||
|
(void *) input, fill );
|
||||||
|
sm3_process( ctx, ctx->buffer );
|
||||||
|
input += fill;
|
||||||
|
ilen -= fill;
|
||||||
|
left = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
while( ilen >= 64 )
|
||||||
|
{
|
||||||
|
sm3_process( ctx, (u8*)input );
|
||||||
|
input += 64;
|
||||||
|
ilen -= 64;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ilen > 0 )
|
||||||
|
{
|
||||||
|
memcpy( (void *) (ctx->buffer + left),
|
||||||
|
(void *) input, ilen );
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static u8 sm3_padding[64] =
|
||||||
|
{
|
||||||
|
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SM3 final digest
|
||||||
|
*/
|
||||||
|
int sm3_final(struct sm3_ctx *ctx, u8 *output)
|
||||||
|
{
|
||||||
|
u32 last, padn;
|
||||||
|
u32 high, low;
|
||||||
|
u8 msglen[8];
|
||||||
|
|
||||||
|
high = ( ctx->total[0] >> 29 )
|
||||||
|
| ( ctx->total[1] << 3 );
|
||||||
|
low = ( ctx->total[0] << 3 );
|
||||||
|
|
||||||
|
PUT_ULONG_BE( high, msglen, 0 );
|
||||||
|
PUT_ULONG_BE( low, msglen, 4 );
|
||||||
|
|
||||||
|
last = ctx->total[0] & 0x3F;
|
||||||
|
padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
|
||||||
|
|
||||||
|
sm3_update(ctx, (const u8 *)sm3_padding, padn );
|
||||||
|
sm3_update(ctx, msglen, 8 );
|
||||||
|
|
||||||
|
PUT_ULONG_BE( ctx->state[0], output, 0 );
|
||||||
|
PUT_ULONG_BE( ctx->state[1], output, 4 );
|
||||||
|
PUT_ULONG_BE( ctx->state[2], output, 8 );
|
||||||
|
PUT_ULONG_BE( ctx->state[3], output, 12 );
|
||||||
|
PUT_ULONG_BE( ctx->state[4], output, 16 );
|
||||||
|
PUT_ULONG_BE( ctx->state[5], output, 20 );
|
||||||
|
PUT_ULONG_BE( ctx->state[6], output, 24 );
|
||||||
|
PUT_ULONG_BE( ctx->state[7], output, 28 );
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
20
AWSMServer/src/sm2sm3_enc/sm3.h
Normal file
20
AWSMServer/src/sm2sm3_enc/sm3.h
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
#ifndef _SM3_H_
|
||||||
|
#define _SM3_H_
|
||||||
|
|
||||||
|
#include "typedef.h"
|
||||||
|
|
||||||
|
#define SM3_DATA_LEN 32
|
||||||
|
|
||||||
|
struct sm3_ctx {
|
||||||
|
u32 total[2]; /*!< number of bytes processed */
|
||||||
|
u32 state[8]; /*!< intermediate digest state */
|
||||||
|
u8 buffer[64]; /*!< data block being processed */
|
||||||
|
u8 ipad[64]; /*!< HMAC: inner padding */
|
||||||
|
u8 opad[64]; /*!< HMAC: outer padding */
|
||||||
|
};
|
||||||
|
|
||||||
|
int sm3_init(struct sm3_ctx *ctx);
|
||||||
|
int sm3_update(struct sm3_ctx *ctx, const u8 *input, u32 ilen);
|
||||||
|
int sm3_final(struct sm3_ctx *ctx, u8 *output);
|
||||||
|
|
||||||
|
#endif /* _SM3_H_ */
|
356
AWSMServer/src/sm2sm3_enc/sm4_enc.c
Normal file
356
AWSMServer/src/sm2sm3_enc/sm4_enc.c
Normal file
@ -0,0 +1,356 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#define SM4_KEY_SCHEDULE 32
|
||||||
|
|
||||||
|
typedef struct SM4_KEY_st {
|
||||||
|
unsigned int rk[SM4_KEY_SCHEDULE];
|
||||||
|
} SM4_KEY;
|
||||||
|
|
||||||
|
typedef void (*block128_f) (const unsigned char in[16],
|
||||||
|
unsigned char out[16], const void *key);
|
||||||
|
|
||||||
|
static const unsigned char SM4_S[256] = {
|
||||||
|
0xD6, 0x90, 0xE9, 0xFE, 0xCC, 0xE1, 0x3D, 0xB7, 0x16, 0xB6, 0x14, 0xC2,
|
||||||
|
0x28, 0xFB, 0x2C, 0x05, 0x2B, 0x67, 0x9A, 0x76, 0x2A, 0xBE, 0x04, 0xC3,
|
||||||
|
0xAA, 0x44, 0x13, 0x26, 0x49, 0x86, 0x06, 0x99, 0x9C, 0x42, 0x50, 0xF4,
|
||||||
|
0x91, 0xEF, 0x98, 0x7A, 0x33, 0x54, 0x0B, 0x43, 0xED, 0xCF, 0xAC, 0x62,
|
||||||
|
0xE4, 0xB3, 0x1C, 0xA9, 0xC9, 0x08, 0xE8, 0x95, 0x80, 0xDF, 0x94, 0xFA,
|
||||||
|
0x75, 0x8F, 0x3F, 0xA6, 0x47, 0x07, 0xA7, 0xFC, 0xF3, 0x73, 0x17, 0xBA,
|
||||||
|
0x83, 0x59, 0x3C, 0x19, 0xE6, 0x85, 0x4F, 0xA8, 0x68, 0x6B, 0x81, 0xB2,
|
||||||
|
0x71, 0x64, 0xDA, 0x8B, 0xF8, 0xEB, 0x0F, 0x4B, 0x70, 0x56, 0x9D, 0x35,
|
||||||
|
0x1E, 0x24, 0x0E, 0x5E, 0x63, 0x58, 0xD1, 0xA2, 0x25, 0x22, 0x7C, 0x3B,
|
||||||
|
0x01, 0x21, 0x78, 0x87, 0xD4, 0x00, 0x46, 0x57, 0x9F, 0xD3, 0x27, 0x52,
|
||||||
|
0x4C, 0x36, 0x02, 0xE7, 0xA0, 0xC4, 0xC8, 0x9E, 0xEA, 0xBF, 0x8A, 0xD2,
|
||||||
|
0x40, 0xC7, 0x38, 0xB5, 0xA3, 0xF7, 0xF2, 0xCE, 0xF9, 0x61, 0x15, 0xA1,
|
||||||
|
0xE0, 0xAE, 0x5D, 0xA4, 0x9B, 0x34, 0x1A, 0x55, 0xAD, 0x93, 0x32, 0x30,
|
||||||
|
0xF5, 0x8C, 0xB1, 0xE3, 0x1D, 0xF6, 0xE2, 0x2E, 0x82, 0x66, 0xCA, 0x60,
|
||||||
|
0xC0, 0x29, 0x23, 0xAB, 0x0D, 0x53, 0x4E, 0x6F, 0xD5, 0xDB, 0x37, 0x45,
|
||||||
|
0xDE, 0xFD, 0x8E, 0x2F, 0x03, 0xFF, 0x6A, 0x72, 0x6D, 0x6C, 0x5B, 0x51,
|
||||||
|
0x8D, 0x1B, 0xAF, 0x92, 0xBB, 0xDD, 0xBC, 0x7F, 0x11, 0xD9, 0x5C, 0x41,
|
||||||
|
0x1F, 0x10, 0x5A, 0xD8, 0x0A, 0xC1, 0x31, 0x88, 0xA5, 0xCD, 0x7B, 0xBD,
|
||||||
|
0x2D, 0x74, 0xD0, 0x12, 0xB8, 0xE5, 0xB4, 0xB0, 0x89, 0x69, 0x97, 0x4A,
|
||||||
|
0x0C, 0x96, 0x77, 0x7E, 0x65, 0xB9, 0xF1, 0x09, 0xC5, 0x6E, 0xC6, 0x84,
|
||||||
|
0x18, 0xF0, 0x7D, 0xEC, 0x3A, 0xDC, 0x4D, 0x20, 0x79, 0xEE, 0x5F, 0x3E,
|
||||||
|
0xD7, 0xCB, 0x39, 0x48
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SM4_SBOX_T[j] == L(SM4_SBOX[j]).
|
||||||
|
*/
|
||||||
|
static const unsigned int SM4_SBOX_T[256] = {
|
||||||
|
0x8ED55B5B, 0xD0924242, 0x4DEAA7A7, 0x06FDFBFB, 0xFCCF3333, 0x65E28787,
|
||||||
|
0xC93DF4F4, 0x6BB5DEDE, 0x4E165858, 0x6EB4DADA, 0x44145050, 0xCAC10B0B,
|
||||||
|
0x8828A0A0, 0x17F8EFEF, 0x9C2CB0B0, 0x11051414, 0x872BACAC, 0xFB669D9D,
|
||||||
|
0xF2986A6A, 0xAE77D9D9, 0x822AA8A8, 0x46BCFAFA, 0x14041010, 0xCFC00F0F,
|
||||||
|
0x02A8AAAA, 0x54451111, 0x5F134C4C, 0xBE269898, 0x6D482525, 0x9E841A1A,
|
||||||
|
0x1E061818, 0xFD9B6666, 0xEC9E7272, 0x4A430909, 0x10514141, 0x24F7D3D3,
|
||||||
|
0xD5934646, 0x53ECBFBF, 0xF89A6262, 0x927BE9E9, 0xFF33CCCC, 0x04555151,
|
||||||
|
0x270B2C2C, 0x4F420D0D, 0x59EEB7B7, 0xF3CC3F3F, 0x1CAEB2B2, 0xEA638989,
|
||||||
|
0x74E79393, 0x7FB1CECE, 0x6C1C7070, 0x0DABA6A6, 0xEDCA2727, 0x28082020,
|
||||||
|
0x48EBA3A3, 0xC1975656, 0x80820202, 0xA3DC7F7F, 0xC4965252, 0x12F9EBEB,
|
||||||
|
0xA174D5D5, 0xB38D3E3E, 0xC33FFCFC, 0x3EA49A9A, 0x5B461D1D, 0x1B071C1C,
|
||||||
|
0x3BA59E9E, 0x0CFFF3F3, 0x3FF0CFCF, 0xBF72CDCD, 0x4B175C5C, 0x52B8EAEA,
|
||||||
|
0x8F810E0E, 0x3D586565, 0xCC3CF0F0, 0x7D196464, 0x7EE59B9B, 0x91871616,
|
||||||
|
0x734E3D3D, 0x08AAA2A2, 0xC869A1A1, 0xC76AADAD, 0x85830606, 0x7AB0CACA,
|
||||||
|
0xB570C5C5, 0xF4659191, 0xB2D96B6B, 0xA7892E2E, 0x18FBE3E3, 0x47E8AFAF,
|
||||||
|
0x330F3C3C, 0x674A2D2D, 0xB071C1C1, 0x0E575959, 0xE99F7676, 0xE135D4D4,
|
||||||
|
0x661E7878, 0xB4249090, 0x360E3838, 0x265F7979, 0xEF628D8D, 0x38596161,
|
||||||
|
0x95D24747, 0x2AA08A8A, 0xB1259494, 0xAA228888, 0x8C7DF1F1, 0xD73BECEC,
|
||||||
|
0x05010404, 0xA5218484, 0x9879E1E1, 0x9B851E1E, 0x84D75353, 0x00000000,
|
||||||
|
0x5E471919, 0x0B565D5D, 0xE39D7E7E, 0x9FD04F4F, 0xBB279C9C, 0x1A534949,
|
||||||
|
0x7C4D3131, 0xEE36D8D8, 0x0A020808, 0x7BE49F9F, 0x20A28282, 0xD4C71313,
|
||||||
|
0xE8CB2323, 0xE69C7A7A, 0x42E9ABAB, 0x43BDFEFE, 0xA2882A2A, 0x9AD14B4B,
|
||||||
|
0x40410101, 0xDBC41F1F, 0xD838E0E0, 0x61B7D6D6, 0x2FA18E8E, 0x2BF4DFDF,
|
||||||
|
0x3AF1CBCB, 0xF6CD3B3B, 0x1DFAE7E7, 0xE5608585, 0x41155454, 0x25A38686,
|
||||||
|
0x60E38383, 0x16ACBABA, 0x295C7575, 0x34A69292, 0xF7996E6E, 0xE434D0D0,
|
||||||
|
0x721A6868, 0x01545555, 0x19AFB6B6, 0xDF914E4E, 0xFA32C8C8, 0xF030C0C0,
|
||||||
|
0x21F6D7D7, 0xBC8E3232, 0x75B3C6C6, 0x6FE08F8F, 0x691D7474, 0x2EF5DBDB,
|
||||||
|
0x6AE18B8B, 0x962EB8B8, 0x8A800A0A, 0xFE679999, 0xE2C92B2B, 0xE0618181,
|
||||||
|
0xC0C30303, 0x8D29A4A4, 0xAF238C8C, 0x07A9AEAE, 0x390D3434, 0x1F524D4D,
|
||||||
|
0x764F3939, 0xD36EBDBD, 0x81D65757, 0xB7D86F6F, 0xEB37DCDC, 0x51441515,
|
||||||
|
0xA6DD7B7B, 0x09FEF7F7, 0xB68C3A3A, 0x932FBCBC, 0x0F030C0C, 0x03FCFFFF,
|
||||||
|
0xC26BA9A9, 0xBA73C9C9, 0xD96CB5B5, 0xDC6DB1B1, 0x375A6D6D, 0x15504545,
|
||||||
|
0xB98F3636, 0x771B6C6C, 0x13ADBEBE, 0xDA904A4A, 0x57B9EEEE, 0xA9DE7777,
|
||||||
|
0x4CBEF2F2, 0x837EFDFD, 0x55114444, 0xBDDA6767, 0x2C5D7171, 0x45400505,
|
||||||
|
0x631F7C7C, 0x50104040, 0x325B6969, 0xB8DB6363, 0x220A2828, 0xC5C20707,
|
||||||
|
0xF531C4C4, 0xA88A2222, 0x31A79696, 0xF9CE3737, 0x977AEDED, 0x49BFF6F6,
|
||||||
|
0x992DB4B4, 0xA475D1D1, 0x90D34343, 0x5A124848, 0x58BAE2E2, 0x71E69797,
|
||||||
|
0x64B6D2D2, 0x70B2C2C2, 0xAD8B2626, 0xCD68A5A5, 0xCB955E5E, 0x624B2929,
|
||||||
|
0x3C0C3030, 0xCE945A5A, 0xAB76DDDD, 0x867FF9F9, 0xF1649595, 0x5DBBE6E6,
|
||||||
|
0x35F2C7C7, 0x2D092424, 0xD1C61717, 0xD66FB9B9, 0xDEC51B1B, 0x94861212,
|
||||||
|
0x78186060, 0x30F3C3C3, 0x897CF5F5, 0x5CEFB3B3, 0xD23AE8E8, 0xACDF7373,
|
||||||
|
0x794C3535, 0xA0208080, 0x9D78E5E5, 0x56EDBBBB, 0x235E7D7D, 0xC63EF8F8,
|
||||||
|
0x8BD45F5F, 0xE7C82F2F, 0xDD39E4E4, 0x68492121 };
|
||||||
|
|
||||||
|
static unsigned int rotl(unsigned int a, unsigned char n)
|
||||||
|
{
|
||||||
|
return (a << n) | (a >> (32 - n));
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned int load_u32_be(const unsigned char *b, unsigned int n)
|
||||||
|
{
|
||||||
|
return ((unsigned int)b[4 * n] << 24) |
|
||||||
|
((unsigned int)b[4 * n + 1] << 16) |
|
||||||
|
((unsigned int)b[4 * n + 2] << 8) |
|
||||||
|
((unsigned int)b[4 * n + 3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void store_u32_be(unsigned int v, unsigned char *b)
|
||||||
|
{
|
||||||
|
b[0] = (unsigned char)(v >> 24);
|
||||||
|
b[1] = (unsigned char)(v >> 16);
|
||||||
|
b[2] = (unsigned char)(v >> 8);
|
||||||
|
b[3] = (unsigned char)(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned int SM4_T_slow(unsigned int X)
|
||||||
|
{
|
||||||
|
unsigned int t = 0;
|
||||||
|
|
||||||
|
t |= ((unsigned int)SM4_S[(unsigned char)(X >> 24)]) << 24;
|
||||||
|
t |= ((unsigned int)SM4_S[(unsigned char)(X >> 16)]) << 16;
|
||||||
|
t |= ((unsigned int)SM4_S[(unsigned char)(X >> 8)]) << 8;
|
||||||
|
t |= SM4_S[(unsigned char)X];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* L linear transform
|
||||||
|
*/
|
||||||
|
return t ^ rotl(t, 2) ^ rotl(t, 10) ^ rotl(t, 18) ^ rotl(t, 24);
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned int SM4_T(unsigned int X)
|
||||||
|
{
|
||||||
|
return SM4_SBOX_T[(unsigned char)(X >> 24)] ^
|
||||||
|
rotl(SM4_SBOX_T[(unsigned char)(X >> 16)], 24) ^
|
||||||
|
rotl(SM4_SBOX_T[(unsigned char)(X >> 8)], 16) ^
|
||||||
|
rotl(SM4_SBOX_T[(unsigned char)X], 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int SM4_set_key(const unsigned char *key, SM4_KEY *ks)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Family Key
|
||||||
|
*/
|
||||||
|
static const unsigned int FK[4] =
|
||||||
|
{ 0xa3b1bac6, 0x56aa3350, 0x677d9197, 0xb27022dc };
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Constant Key
|
||||||
|
*/
|
||||||
|
static const unsigned int CK[32] = {
|
||||||
|
0x00070E15, 0x1C232A31, 0x383F464D, 0x545B6269,
|
||||||
|
0x70777E85, 0x8C939AA1, 0xA8AFB6BD, 0xC4CBD2D9,
|
||||||
|
0xE0E7EEF5, 0xFC030A11, 0x181F262D, 0x343B4249,
|
||||||
|
0x50575E65, 0x6C737A81, 0x888F969D, 0xA4ABB2B9,
|
||||||
|
0xC0C7CED5, 0xDCE3EAF1, 0xF8FF060D, 0x141B2229,
|
||||||
|
0x30373E45, 0x4C535A61, 0x686F767D, 0x848B9299,
|
||||||
|
0xA0A7AEB5, 0xBCC3CAD1, 0xD8DFE6ED, 0xF4FB0209,
|
||||||
|
0x10171E25, 0x2C333A41, 0x484F565D, 0x646B7279
|
||||||
|
};
|
||||||
|
|
||||||
|
unsigned int K[4];
|
||||||
|
int i;
|
||||||
|
|
||||||
|
K[0] = load_u32_be(key, 0) ^ FK[0];
|
||||||
|
K[1] = load_u32_be(key, 1) ^ FK[1];
|
||||||
|
K[2] = load_u32_be(key, 2) ^ FK[2];
|
||||||
|
K[3] = load_u32_be(key, 3) ^ FK[3];
|
||||||
|
|
||||||
|
for (i = 0; i != SM4_KEY_SCHEDULE; ++i) {
|
||||||
|
unsigned int X = K[(i + 1) % 4] ^ K[(i + 2) % 4] ^ K[(i + 3) % 4] ^ CK[i];
|
||||||
|
unsigned int t = 0;
|
||||||
|
|
||||||
|
t |= ((unsigned int)SM4_S[(unsigned char)(X >> 24)]) << 24;
|
||||||
|
t |= ((unsigned int)SM4_S[(unsigned char)(X >> 16)]) << 16;
|
||||||
|
t |= ((unsigned int)SM4_S[(unsigned char)(X >> 8)]) << 8;
|
||||||
|
t |= SM4_S[(unsigned char)X];
|
||||||
|
|
||||||
|
t = t ^ rotl(t, 13) ^ rotl(t, 23);
|
||||||
|
K[i % 4] ^= t;
|
||||||
|
ks->rk[i] = K[i % 4];
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define SM4_RNDS(k0, k1, k2, k3, F) \
|
||||||
|
do { \
|
||||||
|
B0 ^= F(B1 ^ B2 ^ B3 ^ ks->rk[k0]); \
|
||||||
|
B1 ^= F(B0 ^ B2 ^ B3 ^ ks->rk[k1]); \
|
||||||
|
B2 ^= F(B0 ^ B1 ^ B3 ^ ks->rk[k2]); \
|
||||||
|
B3 ^= F(B0 ^ B1 ^ B2 ^ ks->rk[k3]); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
static void SM4_encrypt(const unsigned char *in, unsigned char *out, const SM4_KEY *ks)
|
||||||
|
{
|
||||||
|
unsigned int B0 = load_u32_be(in, 0);
|
||||||
|
unsigned int B1 = load_u32_be(in, 1);
|
||||||
|
unsigned int B2 = load_u32_be(in, 2);
|
||||||
|
unsigned int B3 = load_u32_be(in, 3);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Uses byte-wise sbox in the first and last rounds to provide some
|
||||||
|
* protection from cache based side channels.
|
||||||
|
*/
|
||||||
|
SM4_RNDS( 0, 1, 2, 3, SM4_T_slow);
|
||||||
|
SM4_RNDS( 4, 5, 6, 7, SM4_T);
|
||||||
|
SM4_RNDS( 8, 9, 10, 11, SM4_T);
|
||||||
|
SM4_RNDS(12, 13, 14, 15, SM4_T);
|
||||||
|
SM4_RNDS(16, 17, 18, 19, SM4_T);
|
||||||
|
SM4_RNDS(20, 21, 22, 23, SM4_T);
|
||||||
|
SM4_RNDS(24, 25, 26, 27, SM4_T);
|
||||||
|
SM4_RNDS(28, 29, 30, 31, SM4_T_slow);
|
||||||
|
|
||||||
|
store_u32_be(B3, out);
|
||||||
|
store_u32_be(B2, out + 4);
|
||||||
|
store_u32_be(B1, out + 8);
|
||||||
|
store_u32_be(B0, out + 12);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SM4_decrypt(const unsigned char *in, unsigned char *out, const SM4_KEY *ks)
|
||||||
|
{
|
||||||
|
unsigned int B0 = load_u32_be(in, 0);
|
||||||
|
unsigned int B1 = load_u32_be(in, 1);
|
||||||
|
unsigned int B2 = load_u32_be(in, 2);
|
||||||
|
unsigned int B3 = load_u32_be(in, 3);
|
||||||
|
|
||||||
|
SM4_RNDS(31, 30, 29, 28, SM4_T_slow);
|
||||||
|
SM4_RNDS(27, 26, 25, 24, SM4_T);
|
||||||
|
SM4_RNDS(23, 22, 21, 20, SM4_T);
|
||||||
|
SM4_RNDS(19, 18, 17, 16, SM4_T);
|
||||||
|
SM4_RNDS(15, 14, 13, 12, SM4_T);
|
||||||
|
SM4_RNDS(11, 10, 9, 8, SM4_T);
|
||||||
|
SM4_RNDS( 7, 6, 5, 4, SM4_T);
|
||||||
|
SM4_RNDS( 3, 2, 1, 0, SM4_T_slow);
|
||||||
|
|
||||||
|
store_u32_be(B3, out);
|
||||||
|
store_u32_be(B2, out + 4);
|
||||||
|
store_u32_be(B1, out + 8);
|
||||||
|
store_u32_be(B0, out + 12);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void CRYPTO_ofb128_encrypt(const unsigned char *in, unsigned char *out,
|
||||||
|
size_t len, const void *key,
|
||||||
|
unsigned char ivec[16], int *num, block128_f block)
|
||||||
|
{
|
||||||
|
unsigned int n;
|
||||||
|
size_t l = 0;
|
||||||
|
|
||||||
|
n = *num;
|
||||||
|
|
||||||
|
while (l < len) {
|
||||||
|
if (n == 0) {
|
||||||
|
(*block) (ivec, ivec, key);
|
||||||
|
}
|
||||||
|
out[l] = in[l] ^ ivec[n];
|
||||||
|
++l;
|
||||||
|
n = (n + 1) % 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
*num = n;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int sm4_init_key(const unsigned char *key, SM4_KEY *ks)
|
||||||
|
{
|
||||||
|
SM4_set_key(key, ks);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void sm4_ofb128_encrypt(const unsigned char *in, unsigned char *out,
|
||||||
|
size_t length, const SM4_KEY *key,
|
||||||
|
unsigned char *ivec)
|
||||||
|
{
|
||||||
|
int num = 0;
|
||||||
|
|
||||||
|
CRYPTO_ofb128_encrypt(in, out, length, key, ivec, &num, (block128_f)SM4_encrypt);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void do_sm4_ofb_encrypt(const char *in_buff, int in_len, char *out_buff, int *out_len, const char *key, const char *iv)
|
||||||
|
{
|
||||||
|
SM4_KEY ks;
|
||||||
|
char ivec[16];
|
||||||
|
|
||||||
|
memset(&ks, 0, sizeof(SM4_KEY));
|
||||||
|
memcpy(ivec, iv, 16);
|
||||||
|
sm4_init_key(key, &ks);
|
||||||
|
sm4_ofb128_encrypt(in_buff, out_buff, in_len, &ks, ivec);
|
||||||
|
*out_len = in_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void do_sm4_ecb_decrypt(const char *in_buff, char *out_buff, const char *key)
|
||||||
|
{
|
||||||
|
SM4_KEY ks;
|
||||||
|
|
||||||
|
memset(&ks, 0, sizeof(SM4_KEY));
|
||||||
|
sm4_init_key(key, &ks);
|
||||||
|
SM4_decrypt(in_buff, out_buff, &ks);
|
||||||
|
//hexdump("in_buff", in_buff, 16);
|
||||||
|
//hexdump("out_buff", out_buff, 16);
|
||||||
|
//hexdump("key", key, 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
void do_sm4_ecb_encrypt(const char *in_buff, char *out_buff, const char *key)
|
||||||
|
{
|
||||||
|
SM4_KEY ks;
|
||||||
|
|
||||||
|
memset(&ks, 0, sizeof(SM4_KEY));
|
||||||
|
sm4_init_key(key, &ks);
|
||||||
|
SM4_encrypt(in_buff, out_buff, &ks);
|
||||||
|
//hexdump("in_buff", in_buff, 16);
|
||||||
|
//hexdump("out_buff", out_buff, 16);
|
||||||
|
//hexdump("key", key, 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
void hexdump(char *title, const unsigned char *s, int l)
|
||||||
|
{
|
||||||
|
int n = 0, j = 0;
|
||||||
|
char buff[1024];
|
||||||
|
memset(buff, 0, sizeof(buff));
|
||||||
|
|
||||||
|
printf("%s len = %d\n", title ? title : "NULL", l);
|
||||||
|
|
||||||
|
for (; n < l; ++n)
|
||||||
|
{
|
||||||
|
if ((n % 16) == 0)
|
||||||
|
{
|
||||||
|
if (j)
|
||||||
|
{
|
||||||
|
printf("%s\n", buff);
|
||||||
|
j = 0;
|
||||||
|
memset(buff, 0, sizeof(buff));
|
||||||
|
}
|
||||||
|
j += sprintf(buff + j, "%04x ", n);
|
||||||
|
}
|
||||||
|
j += sprintf(buff + j, "0x%02x,", s[n]);
|
||||||
|
}
|
||||||
|
if (j)
|
||||||
|
printf("%s\n", buff);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv)
|
||||||
|
{
|
||||||
|
unsigned char in[] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, \
|
||||||
|
0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, \
|
||||||
|
0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, \
|
||||||
|
0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10};
|
||||||
|
unsigned char key[] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, \
|
||||||
|
0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10};
|
||||||
|
unsigned char iv[] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, \
|
||||||
|
0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10};
|
||||||
|
unsigned char check[] = {0x69, 0x3d, 0x9a, 0x53, 0x5b, 0xad, 0x5b, 0xb1, \
|
||||||
|
0x78, 0x6f, 0x53, 0xd7, 0x25, 0x3a, 0x70, 0x56, \
|
||||||
|
0xf2, 0x07, 0x5d, 0x28, 0xb5, 0x23, 0x5f, 0x58, \
|
||||||
|
0xd5, 0x00, 0x27, 0xe4, 0x17, 0x7d, 0x2b, 0xce};
|
||||||
|
char buff[128] = {0};
|
||||||
|
int len = sizeof(buff);
|
||||||
|
|
||||||
|
do_sm4_ofb_encrypt(in, 32, buff, &len, key, iv);
|
||||||
|
|
||||||
|
hexdump("enc", buff, 32);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
900
AWSMServer/src/sm2sm3_enc/svac_enc.c
Normal file
900
AWSMServer/src/sm2sm3_enc/svac_enc.c
Normal file
@ -0,0 +1,900 @@
|
|||||||
|
#include <assert.h>
|
||||||
|
#include <malloc.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
// #include "svac_enc.h"
|
||||||
|
#include "sm2.h"
|
||||||
|
#include "sm3.h"
|
||||||
|
|
||||||
|
#define PRINT_ERR printf
|
||||||
|
#define PRINT_INFO printf
|
||||||
|
|
||||||
|
#define MAGIC_VALUE 0x12121111
|
||||||
|
|
||||||
|
#define NALU_MAX_NUM 100
|
||||||
|
|
||||||
|
#define VKEK_CACHE_NUM 30
|
||||||
|
#define HASH_CACHE_NUM 512
|
||||||
|
|
||||||
|
#define SM4_OFB 0
|
||||||
|
#define SM1_OFB 1
|
||||||
|
#define SM4_ECB 2
|
||||||
|
#define SM3_HASH 3
|
||||||
|
#define SM2_SIGN 4
|
||||||
|
|
||||||
|
/* svac2.0 p45 */
|
||||||
|
#define SVAC_NO_IDR_SLICE 1
|
||||||
|
#define SVAC_IDR_SLICE 2
|
||||||
|
#define SVAC_NO_IDR_SLICE_EXT 3
|
||||||
|
#define SVAC_IDR_SLICE_EXT 4
|
||||||
|
#define SVAC_SUR_SLICE 5
|
||||||
|
#define SVAC_SEI_SLICE 6
|
||||||
|
#define SVAC_SPS_SLICE 7
|
||||||
|
#define SVAC_PPS_SLICE 8
|
||||||
|
#define SVAC_SEC_SLICE 9
|
||||||
|
#define SVAC_AUTH_SLICE 10
|
||||||
|
|
||||||
|
struct nalu_data {
|
||||||
|
char *addr;
|
||||||
|
char *out_addr;
|
||||||
|
int len;
|
||||||
|
int out_len;
|
||||||
|
int encryption_idc;
|
||||||
|
int authentication_idc;
|
||||||
|
int type;
|
||||||
|
int need_add_racing_code;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct vkek_info {
|
||||||
|
char vkek[16];
|
||||||
|
char version[32];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct sec_param {
|
||||||
|
/* <20><>ȫ<EFBFBD><C8AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
||||||
|
int encrypt_flag; //<2F>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD>
|
||||||
|
int encrypt_type; //<2F><><EFBFBD><EFBFBD><EFBFBD>㷨
|
||||||
|
int auth_flag; //<2F>Ƿ<EFBFBD>ǩ<EFBFBD><C7A9>
|
||||||
|
int auth_type; //ǩ<><C7A9><EFBFBD>㷨
|
||||||
|
int hash_type; //ɢ<><C9A2><EFBFBD>㷨
|
||||||
|
int vek_flag; //<2F>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD>evek
|
||||||
|
int vek_encrypt_type; //vek<65><6B><EFBFBD><EFBFBD><EFBFBD>㷨
|
||||||
|
char evek[32]; //evek
|
||||||
|
int vek_len; //vek<65><6B><EFBFBD><EFBFBD>
|
||||||
|
char vkek_version[128];//vkek version
|
||||||
|
int version_len; //vkek version<6F><6E><EFBFBD><EFBFBD>
|
||||||
|
int iv_flag; //<2F>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD>iv
|
||||||
|
char iv[32]; //iv
|
||||||
|
int iv_len; //iv<69><76><EFBFBD><EFBFBD>
|
||||||
|
int only_IDR; // sign only for idr
|
||||||
|
int hash_period; // sign period frame
|
||||||
|
};
|
||||||
|
|
||||||
|
struct hash_cache {
|
||||||
|
/* һ<><D2BB>gop<6F><70><EFBFBD>256֡ */
|
||||||
|
char hash[32];
|
||||||
|
int frame_num;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct svac_handle {
|
||||||
|
int magic;
|
||||||
|
|
||||||
|
/* sm2 <20><>Կ */
|
||||||
|
char sm2_pubkey[64];
|
||||||
|
/* sm2 <20><>Կ<EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD> */
|
||||||
|
int sm_pubkey_flag;
|
||||||
|
|
||||||
|
char sm2_prikey[32];
|
||||||
|
int sm_prikey_flag;
|
||||||
|
|
||||||
|
char vek[16];
|
||||||
|
char iv[16];
|
||||||
|
|
||||||
|
/* process tmp data */
|
||||||
|
struct nalu_data nalu[NALU_MAX_NUM];
|
||||||
|
int nalu_num;
|
||||||
|
int frame_num;
|
||||||
|
|
||||||
|
int sign_frame_num;
|
||||||
|
char sign[128];
|
||||||
|
int sign_len;
|
||||||
|
|
||||||
|
/* current frame is IDR frame */
|
||||||
|
int idr_flag;
|
||||||
|
/* current frame <20><><EFBFBD><EFBFBD> sec nalu */
|
||||||
|
int sec_nalu_flag;
|
||||||
|
/* current frame <20><><EFBFBD><EFBFBD> auth nalu */
|
||||||
|
int auth_nalu_flag;
|
||||||
|
|
||||||
|
/* <20><>ǰʹ<C7B0>õİ<C3B5>ȫ<EFBFBD><C8AB><EFBFBD><EFBFBD> */
|
||||||
|
struct sec_param curr_param;
|
||||||
|
/* <20><><EFBFBD>յ<EFBFBD><D5B5>İ<EFBFBD>ȫ<EFBFBD><C8AB><EFBFBD><EFBFBD> */
|
||||||
|
struct sec_param new_param;
|
||||||
|
/* <20><>ȫ<EFBFBD><C8AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>±<EFBFBD>ʶ<EFBFBD><CAB6><EFBFBD>µ<EFBFBD>GOP<4F><50>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD> */
|
||||||
|
int sec_param_update_flag;
|
||||||
|
|
||||||
|
int vkek_start;
|
||||||
|
struct vkek_info vkek_list[VKEK_CACHE_NUM];
|
||||||
|
int find_vkek_flag;
|
||||||
|
|
||||||
|
char idr_hash[32];
|
||||||
|
struct hash_cache cache[HASH_CACHE_NUM];
|
||||||
|
int cache_idx;// 0 ~ HASH_CACHE_NUM - 1
|
||||||
|
|
||||||
|
char camera_id[64]; //<2F><><EFBFBD><EFBFBD>id
|
||||||
|
char camera_idc[19];//֤<><D6A4>id
|
||||||
|
};
|
||||||
|
|
||||||
|
#define CHECK_HANDLE(h) \
|
||||||
|
do { \
|
||||||
|
if (!h || h->magic != MAGIC_VALUE) { \
|
||||||
|
PRINT_ERR("handle is error!\n"); \
|
||||||
|
return -1; \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
void hexdump(char *title, const unsigned char *s, int l);
|
||||||
|
int do_sm2_sign(char *prikey, char *pubkey, char *data_addr, int data_len, char *sign_addr);
|
||||||
|
int do_base64_encode(unsigned char *dst, int *dlen, unsigned char *src, int slen);
|
||||||
|
|
||||||
|
static unsigned int
|
||||||
|
write_bits(unsigned char data, unsigned int write_len, unsigned char *addr, unsigned int offset)
|
||||||
|
{
|
||||||
|
unsigned int offset_in_bytes = offset & 7;
|
||||||
|
unsigned int offset_of_bytes = offset / 8;
|
||||||
|
|
||||||
|
/* if need write twice */
|
||||||
|
if (offset_in_bytes && offset_in_bytes + write_len > 8) {
|
||||||
|
unsigned int second_write_len = offset_in_bytes + write_len - 8;
|
||||||
|
|
||||||
|
/* clean the bits which will been writen */
|
||||||
|
addr[offset_of_bytes] &= ~((1 << (8 - offset_in_bytes)) - 1);
|
||||||
|
/* write the first byte */
|
||||||
|
addr[offset_of_bytes] |= (data & ((1 << write_len) - 1)) >> second_write_len;
|
||||||
|
/* write the second byte */
|
||||||
|
addr[offset_of_bytes + 1] &= ((1 << (8 - second_write_len)) - 1);
|
||||||
|
addr[offset_of_bytes + 1] |= (data & ((1 << second_write_len) - 1)) << (8 - second_write_len);
|
||||||
|
} else {
|
||||||
|
data &= ((1 << write_len) - 1);
|
||||||
|
addr[offset_of_bytes] &= ~(((1 << write_len) - 1) << (8 - write_len - offset_in_bytes));
|
||||||
|
addr[offset_of_bytes] |= data << (8 - write_len - offset_in_bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
return offset + write_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned int
|
||||||
|
write_long_data_bits(unsigned int data, unsigned int write_len, unsigned char *addr, unsigned int offset)
|
||||||
|
{
|
||||||
|
unsigned int ret_offset = 0;
|
||||||
|
|
||||||
|
if (write_len <= 8)
|
||||||
|
ret_offset = write_bits((unsigned char) data, write_len, addr, offset);
|
||||||
|
else {
|
||||||
|
int i;
|
||||||
|
int loop;
|
||||||
|
unsigned int first_write_len = write_len & 7;
|
||||||
|
|
||||||
|
/* <20><><EFBFBD><EFBFBD>һ<EFBFBD>ֽڵĵ<DAB5>first_write_len<65><6E><EFBFBD><EFBFBD>*/
|
||||||
|
if (first_write_len)
|
||||||
|
offset =
|
||||||
|
write_bits((unsigned char) ((data >> (write_len - first_write_len)) & ((1 << first_write_len) - 1)),
|
||||||
|
first_write_len, addr, offset);
|
||||||
|
|
||||||
|
loop = (write_len - first_write_len) / 8;
|
||||||
|
ret_offset = offset;
|
||||||
|
|
||||||
|
for (i = 0; i < loop; i++)
|
||||||
|
ret_offset = write_bits((unsigned char) ((data >> ((loop - i - 1) * 8)) & 0xff), 8, addr, ret_offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret_offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned int
|
||||||
|
write_string_bits(unsigned char *p, unsigned int write_len, unsigned char *addr, unsigned int offset)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
unsigned int len = 0;
|
||||||
|
|
||||||
|
while (len < write_len) {
|
||||||
|
if (write_len - len > 8) {
|
||||||
|
offset = write_bits(p[i], 8, addr, offset);
|
||||||
|
len += 8;
|
||||||
|
} else {
|
||||||
|
offset = write_bits(p[i], write_len - len, addr, offset);
|
||||||
|
len += write_len - len;
|
||||||
|
}
|
||||||
|
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if find a nal, return the next address; if it's the end, return NULL */
|
||||||
|
static char *
|
||||||
|
findNal(char *buf, int *frame_len, char **nal_start, int *nal_len)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
char *start = NULL;
|
||||||
|
int len = 0;
|
||||||
|
|
||||||
|
*nal_start = NULL;
|
||||||
|
*nal_len = 0;
|
||||||
|
|
||||||
|
/* parsing each NALU */
|
||||||
|
for (i = 0; i < (int) (*frame_len - 3); i++) {
|
||||||
|
if (buf[i] == 0x00 && buf[i + 1] == 0x00 && buf[i + 2] == 0x00 && buf[i + 3] == 0x01) {
|
||||||
|
/* not the first loop */
|
||||||
|
if (start) {
|
||||||
|
len = buf + i - start;
|
||||||
|
*nal_start = start;
|
||||||
|
*nal_len = len;
|
||||||
|
*frame_len -= i;
|
||||||
|
return buf + i;
|
||||||
|
}
|
||||||
|
start = buf + i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (start) len = buf + *frame_len - start;
|
||||||
|
|
||||||
|
*nal_start = start;
|
||||||
|
*nal_len = len;
|
||||||
|
*frame_len = 0;
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
svac_parse_nalu(struct svac_handle *h, char *frame_data, int frame_len)
|
||||||
|
{
|
||||||
|
char *ptr, *start = NULL;
|
||||||
|
int nal_len, frame_len_left = frame_len;
|
||||||
|
|
||||||
|
ptr = frame_data;
|
||||||
|
|
||||||
|
do {
|
||||||
|
start = NULL;
|
||||||
|
nal_len = 0;
|
||||||
|
ptr = findNal(ptr, &frame_len_left, &start, &nal_len);
|
||||||
|
if (start) {
|
||||||
|
memset(&h->nalu[h->nalu_num], 0, sizeof(struct nalu_data));
|
||||||
|
|
||||||
|
h->nalu[h->nalu_num].addr = start;
|
||||||
|
h->nalu[h->nalu_num].len = nal_len;
|
||||||
|
h->nalu[h->nalu_num].encryption_idc = start[4] & 0x2 ? 1 : 0;//svac2.0 p21
|
||||||
|
h->nalu[h->nalu_num].authentication_idc = start[4] & 0x1; //svac2.0 p21
|
||||||
|
h->nalu[h->nalu_num].type = (start[4] >> 2) & 0xf; //svac2.0 p21
|
||||||
|
|
||||||
|
if (SVAC_IDR_SLICE == h->nalu[h->nalu_num].type)
|
||||||
|
h->idr_flag = 1;
|
||||||
|
else if (SVAC_SEC_SLICE == h->nalu[h->nalu_num].type)
|
||||||
|
h->sec_nalu_flag = 1;
|
||||||
|
else if (SVAC_AUTH_SLICE == h->nalu[h->nalu_num].type)
|
||||||
|
h->auth_nalu_flag = 1;
|
||||||
|
else if (SVAC_PPS_SLICE == h->nalu[h->nalu_num].type) {
|
||||||
|
/* pps<70>ĵ<EFBFBD>һ<EFBFBD><D2BB><EFBFBD>ֽ<EFBFBD><D6BD><EFBFBD>֡<EFBFBD><D6A1> svac2.0 p23 */
|
||||||
|
h->frame_num = (unsigned char) start[5];
|
||||||
|
//PRINT_INFO("frame %d\n", h->frame_num);
|
||||||
|
}
|
||||||
|
|
||||||
|
//printf("nalu %d len %d type %d auth_idc %d enc_idc %d\n", h->nalu_num, nal_len, h->nalu[h->nalu_num].type, h->nalu[h->nalu_num].authentication_idc, h->nalu[h->nalu_num].encryption_idc);
|
||||||
|
|
||||||
|
h->nalu_num++;
|
||||||
|
}
|
||||||
|
} while (frame_len_left);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* <20><><EFBFBD><EFBFBD> svac <20>ľ<EFBFBD><C4BE><EFBFBD><EFBFBD><EFBFBD> */
|
||||||
|
static int
|
||||||
|
do_add_racing_Code(char *ptr, int *len, int offset)
|
||||||
|
{
|
||||||
|
int i, find = 0, start = offset;
|
||||||
|
unsigned int inlen = *len;
|
||||||
|
|
||||||
|
for (i = start; i < inlen - 2; i++) {
|
||||||
|
if (ptr[i] == 0 && ptr[i + 1] == 0 && !(ptr[i + 2] & 0xfc)) {
|
||||||
|
find = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (find) {
|
||||||
|
unsigned int code_num = 0, zero_count = 0;
|
||||||
|
char *tmp = (char *) malloc(*len + 4096 * 5);
|
||||||
|
|
||||||
|
memcpy(tmp, ptr, start);
|
||||||
|
|
||||||
|
for (i = start; i < inlen; i++) {
|
||||||
|
if (zero_count == 2 && !(ptr[i] & 0xfc)) {
|
||||||
|
tmp[i + code_num] = 3;
|
||||||
|
code_num++;
|
||||||
|
i--;
|
||||||
|
zero_count = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ptr[i] == 0)
|
||||||
|
zero_count++;
|
||||||
|
else
|
||||||
|
zero_count = 0;
|
||||||
|
tmp[i + code_num] = ptr[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(ptr, tmp, inlen + code_num);
|
||||||
|
*len = inlen + code_num;
|
||||||
|
//PRINT_INFO("code_num %d\n", code_num);
|
||||||
|
free(tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
return find;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ȥ<><C8A5> svac <20>ľ<EFBFBD><C4BE><EFBFBD><EFBFBD><EFBFBD> */
|
||||||
|
static int
|
||||||
|
do_remove_racing_code(char *ptr, int *len, int offset)
|
||||||
|
{
|
||||||
|
int i, find = 0, start;
|
||||||
|
unsigned int inlen;
|
||||||
|
|
||||||
|
inlen = *len;
|
||||||
|
start = offset;
|
||||||
|
|
||||||
|
for (i = start; i < inlen - 2; i++) {
|
||||||
|
if (ptr[i] == 0 && ptr[i + 1] == 0 && ptr[i + 2] == 0x3) {
|
||||||
|
find = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (find) {
|
||||||
|
unsigned int code_num = 0, zero_count = 0;
|
||||||
|
|
||||||
|
for (i = start; i < inlen; i++) {
|
||||||
|
if (zero_count == 2 && ptr[i] == 3) {
|
||||||
|
code_num++;
|
||||||
|
zero_count = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ptr[i] == 0)
|
||||||
|
zero_count++;
|
||||||
|
else
|
||||||
|
zero_count = 0;
|
||||||
|
ptr[i - code_num] = ptr[i];
|
||||||
|
}
|
||||||
|
*len = inlen - code_num;
|
||||||
|
}
|
||||||
|
|
||||||
|
return find;
|
||||||
|
}
|
||||||
|
|
||||||
|
void do_sm4_ecb_encrypt(const char *in_buff, char *out_buff, const char *key);
|
||||||
|
|
||||||
|
static int
|
||||||
|
enc_vek(struct svac_handle *h)
|
||||||
|
{
|
||||||
|
do_sm4_ecb_encrypt(h->vek, h->curr_param.evek, h->vkek_list[0].vkek);
|
||||||
|
h->curr_param.vek_len = 16;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
calc_nalu_hash(struct svac_handle *h)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
struct sm3_ctx ctx;
|
||||||
|
char hash[32];
|
||||||
|
struct hash_cache *cache;
|
||||||
|
|
||||||
|
if (!h->curr_param.auth_flag) return 0;
|
||||||
|
|
||||||
|
for (i = 0; i < h->nalu_num; i++) {
|
||||||
|
if (h->nalu[i].authentication_idc) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* û<><C3BB>ǩ<EFBFBD><C7A9><EFBFBD><EFBFBD>nalu */
|
||||||
|
if (i >= h->nalu_num) return 0;
|
||||||
|
|
||||||
|
memset(hash, 0, sizeof(hash));
|
||||||
|
sm3_init(&ctx);
|
||||||
|
|
||||||
|
for (i = 0; i < h->nalu_num; i++) {
|
||||||
|
if (!h->nalu[i].authentication_idc) continue;
|
||||||
|
|
||||||
|
sm3_update(&ctx, h->nalu[i].addr + 4, h->nalu[i].len - 4);
|
||||||
|
//printf("calc_nalu_hash nalu %d len %d\n", i, h->nalu[i].len - 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
sm3_final(&ctx, hash);
|
||||||
|
|
||||||
|
if (!h->frame_num) memcpy(h->idr_hash, hash, 32);
|
||||||
|
|
||||||
|
cache = &h->cache[h->cache_idx];
|
||||||
|
memcpy(cache->hash, hash, 32);
|
||||||
|
cache->frame_num = h->frame_num;
|
||||||
|
h->cache_idx = (h->cache_idx + 1) % HASH_CACHE_NUM;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void do_sm4_ofb_encrypt(const char *in_buff, int in_len, char *out_buff, int *out_len, const char *key, const char *iv);
|
||||||
|
|
||||||
|
static int
|
||||||
|
do_dec_and_copy(int encrypt_type,
|
||||||
|
const char *in_buff,
|
||||||
|
int in_len,
|
||||||
|
char *out_buff,
|
||||||
|
int *out_len,
|
||||||
|
const char *key,
|
||||||
|
const char *iv)
|
||||||
|
{
|
||||||
|
if (encrypt_type == SM4_OFB) {
|
||||||
|
do_sm4_ofb_encrypt(in_buff, in_len, out_buff, out_len, key, iv);
|
||||||
|
} else if (encrypt_type == SM1_OFB) {
|
||||||
|
PRINT_ERR("unsupport SM1 now!\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
make_bypass_frame(struct svac_handle *h, char *out_buff, int *out_len)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
*out_len = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < h->nalu_num; i++) {
|
||||||
|
if (h->nalu[i].type == SVAC_SEC_SLICE) continue;
|
||||||
|
memcpy(out_buff + *out_len, h->nalu[i].addr, h->nalu[i].len);
|
||||||
|
*out_len += h->nalu[i].len;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
update_new_enc_param(struct svac_handle *h)
|
||||||
|
{
|
||||||
|
memcpy(&h->curr_param, &h->new_param, sizeof(struct sec_param));
|
||||||
|
//printf("h->new_param.enc %d\n", h->new_param.encrypt_flag);
|
||||||
|
h->sec_param_update_flag = 0;
|
||||||
|
|
||||||
|
if (h->curr_param.encrypt_flag) {
|
||||||
|
char vek[16];
|
||||||
|
char iv[16];
|
||||||
|
|
||||||
|
vli_get_random(vek, 16);
|
||||||
|
vli_get_random(iv, 16);
|
||||||
|
|
||||||
|
memcpy(h->vek, vek, 16);
|
||||||
|
memcpy(h->iv, iv, 16);
|
||||||
|
enc_vek(h);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
SvacEncCreate(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
struct svac_handle *h;
|
||||||
|
|
||||||
|
h = (struct svac_handle *) malloc(sizeof(struct svac_handle));
|
||||||
|
if (!h) return NULL;
|
||||||
|
|
||||||
|
memset(h, 0, sizeof(struct svac_handle));
|
||||||
|
h->magic = MAGIC_VALUE;
|
||||||
|
|
||||||
|
for (i = 0; i < HASH_CACHE_NUM; i++) h->cache[i].frame_num = -1;
|
||||||
|
|
||||||
|
return (void *) h;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
SvacEncSetVkek(void *handle, char *vkek, char *version, int verion_len)
|
||||||
|
{
|
||||||
|
struct svac_handle *h = (struct svac_handle *) handle;
|
||||||
|
|
||||||
|
CHECK_HANDLE(h);
|
||||||
|
|
||||||
|
if (!vkek || !version) return -1;
|
||||||
|
|
||||||
|
memcpy(h->vkek_list[0].vkek, vkek, 16);
|
||||||
|
memset(h->vkek_list[0].version, 0, sizeof(h->vkek_list[0].version));
|
||||||
|
memcpy(h->vkek_list[0].version, version, verion_len);
|
||||||
|
h->find_vkek_flag = 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
SvacEncSetKeyPair(void *handle, char *sm2_prikey, char *sm2_pubkey)
|
||||||
|
{
|
||||||
|
struct svac_handle *h = (struct svac_handle *) handle;
|
||||||
|
|
||||||
|
CHECK_HANDLE(h);
|
||||||
|
|
||||||
|
if (!sm2_prikey || !sm2_pubkey) return -1;
|
||||||
|
|
||||||
|
hexdump("sm2_prikey", sm2_prikey, 32);
|
||||||
|
hexdump("sm2_pubkey", sm2_pubkey, 64);
|
||||||
|
|
||||||
|
memcpy(h->sm2_prikey, sm2_prikey, 32);
|
||||||
|
memcpy(h->sm2_pubkey, sm2_pubkey, 64);
|
||||||
|
h->sm_prikey_flag = 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
SvacEncSetIpcId(void *handle, char *id)
|
||||||
|
{
|
||||||
|
struct svac_handle *h = (struct svac_handle *) handle;
|
||||||
|
|
||||||
|
CHECK_HANDLE(h);
|
||||||
|
|
||||||
|
memset(h->camera_id, 0, sizeof(h->camera_id));
|
||||||
|
memcpy(h->camera_id, id, strlen(id));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
SvacEncSetCertId(void *handle, char *cert_id)
|
||||||
|
{
|
||||||
|
struct svac_handle *h = (struct svac_handle *) handle;
|
||||||
|
int serial_len = 0;
|
||||||
|
|
||||||
|
CHECK_HANDLE(h);
|
||||||
|
|
||||||
|
if (!cert_id) return -1;
|
||||||
|
|
||||||
|
serial_len = strlen(cert_id);
|
||||||
|
if (serial_len > 19) serial_len = 19;
|
||||||
|
|
||||||
|
memset(h->camera_idc, 0, sizeof(h->camera_idc));
|
||||||
|
memcpy(h->camera_idc + 19 - serial_len, cert_id, serial_len);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
SvacEncSetLevel(void *handle, char level)
|
||||||
|
{
|
||||||
|
struct svac_handle *h = (struct svac_handle *) handle;
|
||||||
|
|
||||||
|
h->new_param.encrypt_flag = 0;
|
||||||
|
h->new_param.encrypt_type = SM4_OFB;
|
||||||
|
h->new_param.auth_flag = 0;
|
||||||
|
h->new_param.auth_type = SM2_SIGN;
|
||||||
|
h->new_param.hash_type = SM3_HASH;
|
||||||
|
h->new_param.only_IDR = 1;
|
||||||
|
h->new_param.hash_period = 0;
|
||||||
|
|
||||||
|
if (level == 'b' || level == 'B') {
|
||||||
|
h->new_param.auth_flag = 1;
|
||||||
|
} else if (level == 'c' || level == 'C') {
|
||||||
|
h->new_param.encrypt_flag = 1;
|
||||||
|
h->new_param.auth_flag = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
h->sec_param_update_flag = 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
write_security_nalu_data(struct svac_handle *h, unsigned char *ptr, unsigned int *len)
|
||||||
|
{
|
||||||
|
unsigned int offset = 0;
|
||||||
|
unsigned int l = *len;
|
||||||
|
|
||||||
|
/* write encryption_flag */
|
||||||
|
offset = write_bits(h->curr_param.encrypt_flag, 1, ptr + l, offset);
|
||||||
|
/* write authentication_flag */
|
||||||
|
offset = write_bits(h->curr_param.auth_flag, 1, ptr + l, offset);
|
||||||
|
|
||||||
|
if (h->curr_param.encrypt_flag) {
|
||||||
|
unsigned char tmp;
|
||||||
|
|
||||||
|
/* write encryption_type */
|
||||||
|
if (h->curr_param.encrypt_type == SM1_OFB)
|
||||||
|
tmp = 0;
|
||||||
|
else
|
||||||
|
tmp = 1;
|
||||||
|
|
||||||
|
offset = write_bits(tmp, 4, ptr + l, offset);
|
||||||
|
/* write vek_flag */
|
||||||
|
offset = write_bits(1, 1, ptr + l, offset);
|
||||||
|
/* write iv_flag */
|
||||||
|
offset = write_bits(1, 1, ptr + l, offset);
|
||||||
|
|
||||||
|
if (1) {
|
||||||
|
/* write vek_encryption_type */
|
||||||
|
tmp = 1;
|
||||||
|
offset = write_bits(tmp, 4, ptr + l, offset);
|
||||||
|
/* write evek_length_minus1 */
|
||||||
|
offset = write_bits(h->curr_param.vek_len - 1, 8, ptr + l, offset);
|
||||||
|
/* write evek */
|
||||||
|
offset = write_string_bits(h->curr_param.evek, h->curr_param.vek_len * 8, ptr + l, offset);
|
||||||
|
/* write vkek_verion_length_minus1 */
|
||||||
|
offset = write_bits(strlen(h->vkek_list[0].version) - 1, 8, ptr + l, offset);
|
||||||
|
/* write vkek_version */
|
||||||
|
offset = write_string_bits(h->vkek_list[0].version, strlen(h->vkek_list[0].version) * 8, ptr + l, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (1) {
|
||||||
|
/* write iv_length_minus1 */
|
||||||
|
offset = write_bits(16 - 1, 8, ptr + l, offset);
|
||||||
|
/* write iv */
|
||||||
|
offset = write_string_bits(h->iv, 16 * 8, ptr + l, offset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (h->curr_param.auth_flag) {
|
||||||
|
offset = write_bits(0, 2, ptr + l, offset);
|
||||||
|
offset = write_bits(h->curr_param.only_IDR, 1, ptr + l, offset);
|
||||||
|
offset = write_bits(0, 2, ptr + l, offset);
|
||||||
|
offset = write_bits(h->curr_param.hash_period - 1, 8, ptr + l, offset);
|
||||||
|
offset = write_string_bits(h->camera_idc, 152, ptr + l, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (h->curr_param.encrypt_flag || h->curr_param.auth_flag)
|
||||||
|
offset = write_string_bits(h->camera_id, 160, ptr + l, offset);
|
||||||
|
|
||||||
|
offset = write_bits(1, 1, ptr + l, offset);
|
||||||
|
if (offset & 7) offset = write_bits(0, 8 - (offset & 7), ptr + l, offset);
|
||||||
|
|
||||||
|
assert(!(offset & 7));
|
||||||
|
l += offset / 8;
|
||||||
|
|
||||||
|
*len = l;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
create_security_nalu(struct svac_handle *h, char *ptr, int *len)
|
||||||
|
{
|
||||||
|
unsigned int save_len = 0;
|
||||||
|
unsigned int l = *len;
|
||||||
|
|
||||||
|
ptr[l] = 0x00;
|
||||||
|
l++;
|
||||||
|
ptr[l] = 0x00;
|
||||||
|
l++;
|
||||||
|
ptr[l] = 0x00;
|
||||||
|
l++;
|
||||||
|
ptr[l] = 0x01;
|
||||||
|
l++;
|
||||||
|
|
||||||
|
ptr[l] = SVAC_SEC_SLICE << 2 | 0xc0;
|
||||||
|
l++;
|
||||||
|
write_security_nalu_data(h, ptr, &l);
|
||||||
|
*len = l;
|
||||||
|
|
||||||
|
do_add_racing_Code(ptr, &l, save_len + 4 + 1);
|
||||||
|
*len = l;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
write_auth_nalu_data(struct svac_handle *h, unsigned char *ptr, unsigned int *len)
|
||||||
|
{
|
||||||
|
unsigned int offset = 0;
|
||||||
|
unsigned int l = *len;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* write frame_num */
|
||||||
|
offset = write_bits(h->sign_frame_num, 8, ptr + l, offset);
|
||||||
|
/* write authentication_data_length_minus1 */
|
||||||
|
offset = write_bits((unsigned int) (h->sign_len - 1), 8, ptr + l, offset);
|
||||||
|
/* write authentication_data */
|
||||||
|
for (i = 0; i < (int) h->sign_len; i++) offset = write_bits(h->sign[i], 8, ptr + l, offset);
|
||||||
|
|
||||||
|
/* write rbsp_trailing_bits() */
|
||||||
|
offset = write_bits(1, 1, ptr + l, offset);
|
||||||
|
if (offset & 7) offset = write_bits(0, 8 - (offset & 7), ptr + l, offset);
|
||||||
|
|
||||||
|
l += offset / 8;
|
||||||
|
*len = l;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
create_auth_nalu(struct svac_handle *h, char *ptr, int *len)
|
||||||
|
{
|
||||||
|
unsigned int save_len;
|
||||||
|
unsigned int l = *len;
|
||||||
|
|
||||||
|
save_len = l;
|
||||||
|
//printf("======= %s ==========\n", __FUNCTION__);
|
||||||
|
|
||||||
|
ptr[l] = 0x00;
|
||||||
|
l++;
|
||||||
|
ptr[l] = 0x00;
|
||||||
|
l++;
|
||||||
|
ptr[l] = 0x00;
|
||||||
|
l++;
|
||||||
|
ptr[l] = 0x01;
|
||||||
|
l++;
|
||||||
|
|
||||||
|
ptr[l] = SVAC_AUTH_SLICE << 2 | 0xc0;
|
||||||
|
l++;
|
||||||
|
write_auth_nalu_data(h, ptr, &l);
|
||||||
|
*len = l;
|
||||||
|
|
||||||
|
do_add_racing_Code(ptr, &l, save_len + 4 + 1);
|
||||||
|
*len = l;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
make_enc_frame(struct svac_handle *h, char *out_buff, int *out_data_len)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int out_offset = 0;
|
||||||
|
int out_nalu_len;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
*out_data_len = 0;
|
||||||
|
|
||||||
|
if (h->idr_flag) { create_security_nalu(h, out_buff, &out_offset); }
|
||||||
|
|
||||||
|
for (i = 0; i < h->nalu_num; i++) {
|
||||||
|
if (((h->nalu[i].type != SVAC_IDR_SLICE) && (h->nalu[i].type != SVAC_NO_IDR_SLICE))
|
||||||
|
|| (!h->curr_param.encrypt_flag)) {
|
||||||
|
memcpy(out_buff + out_offset, h->nalu[i].addr, h->nalu[i].len);
|
||||||
|
h->nalu[i].out_addr = out_buff + out_offset;
|
||||||
|
|
||||||
|
//out_buff[out_offset + 4] &= 0xfc;
|
||||||
|
out_nalu_len = h->nalu[i].len;
|
||||||
|
if (h->nalu[i].need_add_racing_code) do_add_racing_Code(out_buff + out_offset, &out_nalu_len, 5);
|
||||||
|
out_offset += out_nalu_len;
|
||||||
|
|
||||||
|
h->nalu[i].out_len = out_nalu_len;
|
||||||
|
} else {
|
||||||
|
int enc_len;
|
||||||
|
int out_len;
|
||||||
|
|
||||||
|
if (!h->find_vkek_flag) {
|
||||||
|
PRINT_ERR("Not find vkek [%s]! skip dec frame!\n", h->curr_param.vkek_version);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!h->nalu[i].need_add_racing_code) {
|
||||||
|
do_remove_racing_code(h->nalu[i].addr, &h->nalu[i].len, 5);
|
||||||
|
h->nalu[i].need_add_racing_code = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(out_buff + out_offset, h->nalu[i].addr, 5);
|
||||||
|
enc_len = h->nalu[i].len - 1 - 5;
|
||||||
|
h->nalu[i].out_addr = out_buff + out_offset;
|
||||||
|
|
||||||
|
ret = do_dec_and_copy(h->curr_param.encrypt_type, h->nalu[i].addr + 5, enc_len, out_buff + out_offset + 5,
|
||||||
|
&out_len, h->vek, h->iv);
|
||||||
|
if (ret) return -1;
|
||||||
|
|
||||||
|
memcpy(out_buff + out_offset + enc_len + 5, h->nalu[i].addr + 5 + enc_len, 1);
|
||||||
|
|
||||||
|
out_buff[out_offset + 4] |= 0x2;
|
||||||
|
out_nalu_len = h->nalu[i].len;
|
||||||
|
|
||||||
|
do_add_racing_Code(out_buff + out_offset, &out_nalu_len, 5);
|
||||||
|
out_offset += out_nalu_len;
|
||||||
|
h->nalu[i].out_len = out_nalu_len;
|
||||||
|
}
|
||||||
|
//PRINT_INFO("out_nalu_len %d out_offset %d\n", out_nalu_len, out_offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
*out_data_len += out_offset;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
calc_frame_hash(struct svac_handle *h, char *out_buff, int *out_data_len)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
struct sm3_ctx ctx;
|
||||||
|
|
||||||
|
sm3_init(&ctx);
|
||||||
|
|
||||||
|
for (i = 0; i < h->nalu_num; i++) {
|
||||||
|
if ((h->nalu[i].type == SVAC_IDR_SLICE) || (h->nalu[i].type == SVAC_NO_IDR_SLICE)) {
|
||||||
|
h->nalu[i].out_addr[4] |= 1;
|
||||||
|
sm3_update(&ctx, h->nalu[i].out_addr + 4, h->nalu[i].out_len - 4);
|
||||||
|
//printf("calc_frame_hash nalu %d len %d\n", i, h->nalu[i].out_len - 4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sm3_final(&ctx, h->idr_hash);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
calc_idr_sign_data(struct svac_handle *h)
|
||||||
|
{
|
||||||
|
char sign[64];
|
||||||
|
int sign_len = 64;
|
||||||
|
|
||||||
|
do_sm2_sign(h->sm2_prikey, h->sm2_pubkey, h->idr_hash, 32, sign);
|
||||||
|
h->sign_len = 64;
|
||||||
|
|
||||||
|
h->sign_len = sizeof(h->sign);
|
||||||
|
do_base64_encode(h->sign, &h->sign_len, sign, sign_len);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
make_auth_nal(struct svac_handle *h, char *out_buff, int *out_data_len)
|
||||||
|
{
|
||||||
|
if (!h->curr_param.auth_flag) return 0;
|
||||||
|
|
||||||
|
if (h->curr_param.only_IDR && h->idr_flag) {
|
||||||
|
calc_frame_hash(h, out_buff, out_data_len);
|
||||||
|
calc_idr_sign_data(h);
|
||||||
|
create_auth_nalu(h, out_buff, out_data_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
SvacEncProcess(void *handle, char *in_buff, int in_len, char *out_buff, int *out_len)
|
||||||
|
{
|
||||||
|
struct svac_handle *h = (struct svac_handle *) handle;
|
||||||
|
|
||||||
|
CHECK_HANDLE(h);
|
||||||
|
|
||||||
|
if (!in_buff || !out_buff || !out_len) return -1;
|
||||||
|
|
||||||
|
h->nalu_num = 0;
|
||||||
|
h->idr_flag = 0;
|
||||||
|
h->sec_nalu_flag = 0;
|
||||||
|
h->auth_nalu_flag = 0;
|
||||||
|
|
||||||
|
svac_parse_nalu(h, in_buff, in_len);
|
||||||
|
|
||||||
|
if (!h->nalu_num) {
|
||||||
|
PRINT_ERR("Not find nalu start code!\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (h->idr_flag && h->sec_param_update_flag) update_new_enc_param(h);
|
||||||
|
|
||||||
|
/* <20><><EFBFBD><EFBFBD><EFBFBD>a<EFBFBD><61><EFBFBD><EFBFBD><EFBFBD><EFBFBD> bypass */
|
||||||
|
if (!h->curr_param.auth_flag && !h->curr_param.encrypt_flag) return make_bypass_frame(h, out_buff, out_len);
|
||||||
|
|
||||||
|
make_enc_frame(h, out_buff, out_len);
|
||||||
|
make_auth_nal(h, out_buff, out_len);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
SvacEncRelease(void *handle)
|
||||||
|
{
|
||||||
|
struct svac_handle *h = (struct svac_handle *) handle;
|
||||||
|
|
||||||
|
CHECK_HANDLE(h);
|
||||||
|
|
||||||
|
free(h);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
151
AWSMServer/src/sm2sm3_enc/typedef.h
Normal file
151
AWSMServer/src/sm2sm3_enc/typedef.h
Normal file
@ -0,0 +1,151 @@
|
|||||||
|
#ifndef __TYPEDEF_H__
|
||||||
|
#define __TYPEDEF_H__
|
||||||
|
|
||||||
|
typedef int s32;
|
||||||
|
typedef unsigned int u32;
|
||||||
|
typedef unsigned char u8;
|
||||||
|
typedef unsigned short u16;
|
||||||
|
typedef short s16;
|
||||||
|
typedef char s8;
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
typedef __int64 s64;
|
||||||
|
#else
|
||||||
|
typedef long long s64;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
typedef unsigned __int64 u64;
|
||||||
|
#else
|
||||||
|
typedef unsigned long long u64;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static u16 __get_unaligned_le16(const u8 *p)
|
||||||
|
{
|
||||||
|
return p[0] | p[1] << 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
static u32 __get_unaligned_le32(const u8 *p)
|
||||||
|
{
|
||||||
|
return p[0] | p[1] << 8 | p[2] << 16 | p[3] << 24;
|
||||||
|
}
|
||||||
|
|
||||||
|
static u64 __get_unaligned_le64(const u8 *p)
|
||||||
|
{
|
||||||
|
return (u64)__get_unaligned_le32(p + 4) << 32 |
|
||||||
|
__get_unaligned_le32(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __put_unaligned_le16(u16 val, u8 *p)
|
||||||
|
{
|
||||||
|
*p++ = val;
|
||||||
|
*p++ = val >> 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __put_unaligned_le32(u32 val, u8 *p)
|
||||||
|
{
|
||||||
|
__put_unaligned_le16(val >> 16, p + 2);
|
||||||
|
__put_unaligned_le16(val, p);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __put_unaligned_le64(u64 val, u8 *p)
|
||||||
|
{
|
||||||
|
__put_unaligned_le32(val >> 32, p + 4);
|
||||||
|
__put_unaligned_le32(val, p);
|
||||||
|
}
|
||||||
|
|
||||||
|
static u16 get_unaligned_le16(const void *p)
|
||||||
|
{
|
||||||
|
return __get_unaligned_le16((const u8 *)p);
|
||||||
|
}
|
||||||
|
|
||||||
|
static u32 get_unaligned_le32(const void *p)
|
||||||
|
{
|
||||||
|
return __get_unaligned_le32((const u8 *)p);
|
||||||
|
}
|
||||||
|
|
||||||
|
static u64 get_unaligned_le64(const void *p)
|
||||||
|
{
|
||||||
|
return __get_unaligned_le64((const u8 *)p);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void put_unaligned_le16(u16 val, void *p)
|
||||||
|
{
|
||||||
|
__put_unaligned_le16(val, p);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void put_unaligned_le32(u32 val, void *p)
|
||||||
|
{
|
||||||
|
__put_unaligned_le32(val, p);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void put_unaligned_le64(u64 val, void *p)
|
||||||
|
{
|
||||||
|
__put_unaligned_le64(val, p);
|
||||||
|
}
|
||||||
|
|
||||||
|
static u16 __get_unaligned_be16(const u8 *p)
|
||||||
|
{
|
||||||
|
return p[0] << 8 | p[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
static u32 __get_unaligned_be32(const u8 *p)
|
||||||
|
{
|
||||||
|
return p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3];
|
||||||
|
}
|
||||||
|
|
||||||
|
static u64 __get_unaligned_be64(const u8 *p)
|
||||||
|
{
|
||||||
|
return (u64)__get_unaligned_be32(p) << 32 |
|
||||||
|
__get_unaligned_be32(p + 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __put_unaligned_be16(u16 val, u8 *p)
|
||||||
|
{
|
||||||
|
*p++ = val >> 8;
|
||||||
|
*p++ = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __put_unaligned_be32(u32 val, u8 *p)
|
||||||
|
{
|
||||||
|
__put_unaligned_be16(val >> 16, p);
|
||||||
|
__put_unaligned_be16(val, p + 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __put_unaligned_be64(u64 val, u8 *p)
|
||||||
|
{
|
||||||
|
__put_unaligned_be32(val >> 32, p);
|
||||||
|
__put_unaligned_be32(val, p + 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
static u16 get_unaligned_be16(const void *p)
|
||||||
|
{
|
||||||
|
return __get_unaligned_be16((const u8 *)p);
|
||||||
|
}
|
||||||
|
|
||||||
|
static u32 get_unaligned_be32(const void *p)
|
||||||
|
{
|
||||||
|
return __get_unaligned_be32((const u8 *)p);
|
||||||
|
}
|
||||||
|
|
||||||
|
static u64 get_unaligned_be64(const void *p)
|
||||||
|
{
|
||||||
|
return __get_unaligned_be64((const u8 *)p);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void put_unaligned_be16(u16 val, void *p)
|
||||||
|
{
|
||||||
|
__put_unaligned_be16(val, p);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void put_unaligned_be32(u32 val, void *p)
|
||||||
|
{
|
||||||
|
__put_unaligned_be32(val, p);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void put_unaligned_be64(u64 val, void *p)
|
||||||
|
{
|
||||||
|
__put_unaligned_be64(val, p);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -1,23 +1,18 @@
|
|||||||
CMAKE_MINIMUM_REQUIRED(VERSION 3.10)
|
cmake_minimum_required(VERSION 3.10)
|
||||||
PROJECT(AWSMRPC)
|
project(AWSMRPC)
|
||||||
|
|
||||||
OPTION(SUBPROJECT "Using SubProject" ON)
|
option(SUBPROJECT "Using SubProject" ON)
|
||||||
|
|
||||||
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3")
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3")
|
||||||
|
|
||||||
INCLUDE_DIRECTORIES(
|
include_directories(PUBLIC ${CMAKE_SOURCE_DIR}/utils)
|
||||||
PUBLIC
|
|
||||||
${CMAKE_SOURCE_DIR}/utils)
|
|
||||||
|
|
||||||
LINK_DIRECTORIES(${PROJECT_NAME}
|
link_directories(${PROJECT_NAME} PUBLIC ${CMAKE_SOURCE_DIR}/lib)
|
||||||
PUBLIC
|
|
||||||
${CMAKE_SOURCE_DIR}/lib)
|
|
||||||
|
|
||||||
ADD_SUBDIRECTORY(utils/VSConfig)
|
add_subdirectory(utils/VSConfig)
|
||||||
ADD_SUBDIRECTORY(utils/VSClock)
|
add_subdirectory(utils/VSClock)
|
||||||
ADD_SUBDIRECTORY(utils/ZMQLayout)
|
add_subdirectory(utils/ZMQLayout)
|
||||||
ADD_SUBDIRECTORY(utils/AWSMProtobuf)
|
add_subdirectory(utils/AWSMProtobuf)
|
||||||
|
|
||||||
ADD_SUBDIRECTORY(AWSMServer)
|
|
||||||
ADD_SUBDIRECTORY(AWSM)
|
|
||||||
|
|
||||||
|
add_subdirectory(AWSMServer)
|
||||||
|
add_subdirectory(AWSM)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user