rel_1.6.0 init

This commit is contained in:
guocheng.kgc 2020-06-18 20:06:52 +08:00 committed by shengdong.dsd
commit 27b3e2883d
19359 changed files with 8093121 additions and 0 deletions

View file

@ -0,0 +1,119 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#include "base64.h"
#include <stdio.h>
static const unsigned char encoding_table[] = {
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
'w', 'x', 'y', 'z', '0', '1', '2', '3',
'4', '5', '6', '7', '8', '9', '+', '/'
};
static const unsigned char decoding_table[] = {
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, 62, 0, 0, 0, 63,
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 0, 0, 0, 0, 0, 0,
0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 0, 0, 0, 0, 0,
0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 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, 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, 0, 0, 0, 0, 0, 0, 0
};
static const unsigned char mod_table[] = { 0, 2, 1 };
unsigned char *base64_encode(const unsigned char *input, int input_len,
unsigned char *output, int *output_len)
{
int i, j;
int o_len = 4 * ((input_len + 2) / 3);
if (!input || !output || !output_len) {
return NULL;
}
if (output_len) {
*output_len = o_len;
}
for (i = 0, j = 0; i < input_len;) {
unsigned int octet_a = i < input_len ? input[i++] : 0;
unsigned int octet_b = i < input_len ? input[i++] : 0;
unsigned int octet_c = i < input_len ? input[i++] : 0;
unsigned int triple = (octet_a << 0x10) + (octet_b << 0x08) + octet_c;
output[j++] = encoding_table[(triple >> 18) & 0x3F];
output[j++] = encoding_table[(triple >> 12) & 0x3F];
output[j++] = encoding_table[(triple >> 6) & 0x3F];
output[j++] = encoding_table[(triple >> 0) & 0x3F];
}
for (i = 0; i < mod_table[input_len % 3]; i++) {
output[o_len - 1 - i] = '=';
}
return output;
}
unsigned char *base64_decode(const unsigned char *input, int input_len,
unsigned char *output, int *output_len)
{
int i, j;
int o_len = input_len / 4 * 3;
if (!input || !output || !output_len) {
return NULL;
}
if (input[input_len - 1] == '=') {
o_len--;
}
if (input[input_len - 2] == '=') {
o_len--;
}
if (output_len) {
*output_len = o_len;
}
for (i = 0, j = 0; i < input_len;) {
unsigned int sextet_a = decoding_table[input[i++]];
unsigned int sextet_b = decoding_table[input[i++]];
unsigned int sextet_c = decoding_table[input[i++]];
unsigned int sextet_d = decoding_table[input[i++]];
unsigned int triple = (sextet_a << 18)
+ (sextet_b << 12)
+ (sextet_c << 6)
+ (sextet_d << 0);
if (j < o_len) {
output[j++] = (triple >> 16) & 0xFF;
}
if (j < o_len) {
output[j++] = (triple >> 8) & 0xFF;
}
if (j < o_len) {
output[j++] = (triple >> 0) & 0xFF;
}
}
return output;
}

View file

@ -0,0 +1,48 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#ifndef _BASE64_H_
#define _BASE64_H_
#if defined(__cplusplus) /* If this is a C++ compiler, use C linkage */
extern "C" {
#endif
#include <stdlib.h>
#include <string.h>
/**
* @brief base64 encode
*
* @param[in] input: input byte stream
* @param[in] input_len: input stream length in byte
* @param[out] output: base64 encoded string
* @param[in/out] output_len: [in] for output buffer size, [out] for
* base64 encoded string length
* @Note output buffer is not NULL-terminated
*
* @retval output buffer on success, otherwise NULL will return
*/
unsigned char *base64_encode(const unsigned char *input, int input_len,
unsigned char *output, int *output_len);
/**
* @brief base64 decode
*
* @param[in] input: input byte stream
* @param[in] input_len: input stream length in byte
* @param[out] output: base64 decoded string
* @param[in/out] output_len: [in] for output buffer size, [out] for
* base64 decoded string length
* @Note output buffer is not NULL-terminated
* @retval output buffer on success, otherwise NULL will return
*/
unsigned char *base64_decode(const unsigned char *input, int input_len,
unsigned char *output, int *output_len);
#if defined(__cplusplus) /* If this is a C++ compiler, use C linkage */
}
#endif
#endif

View file

@ -0,0 +1,7 @@
NAME := base64
$(NAME)_TYPE := share
$(NAME)_SOURCES := base64.c
GLOBAL_INCLUDES += .

View file

@ -0,0 +1,5 @@
src = Split('''
base64.c
''')
component = aos_component('base64', src)

View file

@ -0,0 +1,55 @@
#include <string.h>
#include "chip_code.h"
//第4个成员name须与mk或ucube.py中设置的 HOST_MCU_FAMILY 值保持一致
chip_code_st g_chip_codes[] = {
{BEKEN_CHIP_VENDOR, bk7231, "bk7231"}, //0x00010001
{BEKEN_CHIP_VENDOR, bk7231u, "bk7231u"}, //0x00010002
{C_SKY_CHIP_VENDOR, csky, "csky"}, //0x00020003
{CYPRESS_CHIP_VENDOR, cy8c4147, "cy8c4147"}, //0x00030004
{CYPRESS_CHIP_VENDOR, cy8c6347, "cy8c6347"}, //0x00030005
{DAHUA_CHIP_VENDOR, dahua, "dahua"}, //0x00040006
{ESP_CHIP_VENDOR, es8p508x, "es8p508x"}, //0x00050007
{ESP_CHIP_VENDOR, esp32, "esp32"}, //0x00050008
{ESP_CHIP_VENDOR, esp8266, "esp8266"}, //0x00050009
{GD_CHIP_VENDOR, gd32f4xx, "gd32f4xx"}, //0x0006000a
{LINUX_VENDOR, linuxhost, "linux"}, //0x0007000b
{NXP_VENDOR, lpc54102, "lpc54102"}, //0x0008000c
{NXP_VENDOR, mkl27z644, "mkl27z644"}, //0x0008000d
{MICO_CHIP_VENDOR, moc108, "moc108"}, //0x0009000e
{MICO_CHIP_VENDOR, mx1290, "mx1290"}, //0x0009000f
{MICO_CHIP_VENDOR, mx1101, "mx1101"}, //0x00090020
{NORDIC_CHIP_VENDOR, nrf52xxx, "nrf52xxx"}, //0x000a0010
{RENASAS_CHIP_VENDOR, r5f100lea, "r5f100lea"}, //0x000b0011
{RENASAS_CHIP_VENDOR, r5f565ne, "r5f565ne"}, //0x000b0012
{RENASAS_CHIP_VENDOR, r7f0c004, "r7f0c004"}, //0x000b0013
{RDA_CHIP_VENDOR, rda5981x, "rda5981x"}, //0x000c0014
{RDA_CHIP_VENDOR, rda8955, "rda8955"}, //0x000c0015
{REALTEK_CHIP_VENDOR, rtl8710bn, "rtl8710bn"}, //0x000d0016
{STM_CHIP_VENDOR, stm32f4xx, "stm32f4xx"}, //0x000e0017
{STM_CHIP_VENDOR, stm32f4xx_cube, "stm32f4xx_cube"}, //0x000e0018
{STM_CHIP_VENDOR, stm32f7xx, "stm32f7xx"}, //0x000e0019
{STM_CHIP_VENDOR, stm32l0xx, "stm32l0xx"}, //0x000e001a
{STM_CHIP_VENDOR, stm32l475, "stm32l475"}, //0x000e001b
{STM_CHIP_VENDOR, stm32l4xx, "stm32l4xx"}, //0x000e001c
{STM_CHIP_VENDOR, stm32l4xx_cube, "stm32l4xx_cube"}, //0x000e001d
{XRADIO_CHIP_VENDOR, xr871, "xr871"}, //0x000f001e
{MTK_CHIP_VENDOR, mtk6261m, "mtk6261m"}, //0x0010001f
};
chip_code_st *get_chip_code( char *name)
{
UINT32 length = sizeof(g_chip_codes) / sizeof(chip_code_st);
UINT32 i;
for ( i = 0; i < length; i++ ) {
if ( strcmp( g_chip_codes[i].mcu_family_name, name) == 0 ) {
break;
}
}
if ( i >= length ) {
return NULL;
}
return &g_chip_codes[i];
}

View file

@ -0,0 +1,87 @@
#ifndef _CHIP_CODE_H_
#define _CHIP_CODE_H_
#ifndef UINT32
#define UINT32 unsigned int
#endif
#ifndef UINT8
#define UINT8 unsigned char
#endif
#ifndef UINT16
#define UINT16 unsigned short
#endif
#ifndef NULL
#define NULL (void *)0
#endif
enum CHIP_VENDOR {
UNKNOW_CHIP_VENDOR = 0, //全0为无效识别码保留
BEKEN_CHIP_VENDOR,
C_SKY_CHIP_VENDOR,
CYPRESS_CHIP_VENDOR,
DAHUA_CHIP_VENDOR,
ESP_CHIP_VENDOR,
GD_CHIP_VENDOR,
LINUX_VENDOR,
NXP_VENDOR,
MICO_CHIP_VENDOR,
NORDIC_CHIP_VENDOR,
RENASAS_CHIP_VENDOR,
RDA_CHIP_VENDOR,
REALTEK_CHIP_VENDOR,
STM_CHIP_VENDOR,
XRADIO_CHIP_VENDOR,
MTK_CHIP_VENDOR,
CHIP_VENDOR_LIMIT = 0xFFFF
};
enum CHIP_ID {
UNKNOW_CHIP_ID = 0, //全0为无效识别码保留
bk7231 ,
bk7231u ,
csky ,
cy8c4147 ,
cy8c6347 ,
dahua ,
es8p508x ,
esp32 ,
esp8266 ,
gd32f4xx ,
linuxhost,//linux会被编译器认为是一个特殊符号不能使用
lpc54102 ,
mkl27z644,
moc108 ,
mx1290 ,
nrf52xxx ,
r5f100lea,
r5f565ne ,
r7f0c004 ,
rda5981x ,
rda8955 ,
rtl8710bn,
stm32f4xx,
stm32f4xx_cube ,
stm32f7xx,
stm32l0xx,
stm32l475,
stm32l4xx,
stm32l4xx_cube,
xr871,
mtk6261m,
mx1101,
CHIP_ID_LIMIT = 0xFFFF
};
typedef struct __chip_code {
UINT16 vendor;
UINT16 id;
const char *mcu_family_name;
} chip_code_st;
extern chip_code_st g_chip_codes[];
extern chip_code_st *get_chip_code( char *name);
#endif

View file

@ -0,0 +1,4 @@
NAME := chip_code
$(NAME)_SOURCES := chip_code.c
GLOBAL_INCLUDES += .

View file

@ -0,0 +1,6 @@
src = Split('''
chip_code.c
''')
component = aos_component('chip_code', src)
component.add_includes('.')

View file

View file

@ -0,0 +1,258 @@
apps/netutils/json/README.txt
=============================
This directory contains logic taken from the cJSON project:
http://sourceforge.net/projects/cjson/
This corresponds to SVN revision r42 (with lots of changes for NuttX coding
standards). As of r42, the SVN repository was last updated on 2011-10-10
so I presume that the code is stable and there is no risk of maintaining
duplicate logic in the NuttX repository.
Contents
========
o License
o Welcome to cJSON
License
=======
Copyright (c) 2009 Dave Gamble
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
Welcome to cJSON
================
cJSON aims to be the dumbest possible parser that you can get your job done with.
It's a single file of C, and a single header file.
JSON is described best here: http://www.json.org/
It's like XML, but fat-free. You use it to move data around, store things, or just
generally represent your program's state.
First up, how do I build?
Add cJSON.c to your project, and put cJSON.h somewhere in the header search path.
For example, to build the test app:
gcc cJSON.c test.c -o test -lm
./test
As a library, cJSON exists to take away as much legwork as it can, but not get in your way.
As a point of pragmatism (i.e. ignoring the truth), I'm going to say that you can use it
in one of two modes: Auto and Manual. Let's have a quick run-through.
I lifted some JSON from this page: http://www.json.org/fatfree.html
That page inspired me to write cJSON, which is a parser that tries to share the same
philosophy as JSON itself. Simple, dumb, out of the way.
Some JSON:
{
"name": "Jack (\"Bee\") Nimble",
"format": {
"type": "rect",
"width": 1920,
"height": 1080,
"interlace": false,
"frame rate": 24
}
}
Assume that you got this from a file, a webserver, or magic JSON elves, whatever,
you have a char * to it. Everything is a cJSON struct.
Get it parsed:
cJSON *root = cJSON_Parse(my_json_string);
This is an object. We're in C. We don't have objects. But we do have structs.
What's the framerate?
cJSON *format = cJSON_GetObjectItem(root,"format");
int framerate = cJSON_GetObjectItem(format,"frame rate")->valueint;
Want to change the framerate?
cJSON_GetObjectItem(format,"frame rate")->valueint=25;
Back to disk?
char *rendered=cJSON_Print(root);
Finished? Delete the root (this takes care of everything else).
cJSON_Delete(root);
That's AUTO mode. If you're going to use Auto mode, you really ought to check pointers
before you dereference them. If you want to see how you'd build this struct in code?
cJSON *root,*fmt;
root=cJSON_CreateObject();
cJSON_AddItemToObject(root, "name", cJSON_CreateString("Jack (\"Bee\") Nimble"));
cJSON_AddItemToObject(root, "format", fmt=cJSON_CreateObject());
cJSON_AddStringToObject(fmt,"type", "rect");
cJSON_AddNumberToObject(fmt,"width", 1920);
cJSON_AddNumberToObject(fmt,"height", 1080);
cJSON_AddFalseToObject (fmt,"interlace");
cJSON_AddNumberToObject(fmt,"frame rate", 24);
Hopefully we can agree that's not a lot of code? There's no overhead, no unnecessary setup.
Look at test.c for a bunch of nice examples, mostly all ripped off the json.org site, and
a few from elsewhere.
What about manual mode? First up you need some detail.
Let's cover how the cJSON objects represent the JSON data.
cJSON doesn't distinguish arrays from objects in handling; just type.
Each cJSON has, potentially, a child, siblings, value, a name.
The root object has: Object Type and a Child
The Child has name "name", with value "Jack ("Bee") Nimble", and a sibling:
Sibling has type Object, name "format", and a child.
That child has type String, name "type", value "rect", and a sibling:
Sibling has type Number, name "width", value 1920, and a sibling:
Sibling has type Number, name "height", value 1080, and a sibling:
Sibling hs type False, name "interlace", and a sibling:
Sibling has type Number, name "frame rate", value 24
Here's the structure:
typedef struct cJSON {
struct cJSON *next,*prev;
struct cJSON *child;
int type;
char *valuestring;
int valueint;
double valuedouble;
char *string;
} cJSON;
By default all values are 0 unless set by virtue of being meaningful.
next/prev is a doubly linked list of siblings. next takes you to your sibling,
prev takes you back from your sibling to you.
Only objects and arrays have a "child", and it's the head of the doubly linked list.
A "child" entry will have prev==0, but next potentially points on. The last sibling has next=0.
The type expresses Null/True/False/Number/String/Array/Object, all of which are #defined in
cJSON.h
A Number has valueint and valuedouble. If you're expecting an int, read valueint, if not read
valuedouble.
Any entry which is in the linked list which is the child of an object will have a "string"
which is the "name" of the entry. When I said "name" in the above example, that's "string".
"string" is the JSON name for the 'variable name' if you will.
Now you can trivially walk the lists, recursively, and parse as you please.
You can invoke cJSON_Parse to get cJSON to parse for you, and then you can take
the root object, and traverse the structure (which is, formally, an N-tree),
and tokenise as you please. If you wanted to build a callback style parser, this is how
you'd do it (just an example, since these things are very specific):
void parse_and_callback(cJSON *item,const char *prefix)
{
while (item)
{
char *newprefix=malloc(strlen(prefix)+strlen(item->name)+2);
sprintf(newprefix,"%s/%s",prefix,item->name);
int dorecurse=callback(newprefix, item->type, item);
if (item->child && dorecurse) parse_and_callback(item->child,newprefix);
item=item->next;
free(newprefix);
}
}
The prefix process will build you a separated list, to simplify your callback handling.
The 'dorecurse' flag would let the callback decide to handle sub-arrays on it's own, or
let you invoke it per-item. For the item above, your callback might look like this:
int callback(const char *name,int type,cJSON *item)
{
if (!strcmp(name,"name")) { /* populate name */ }
else if (!strcmp(name,"format/type") { /* handle "rect" */ }
else if (!strcmp(name,"format/width") { /* 800 */ }
else if (!strcmp(name,"format/height") { /* 600 */ }
else if (!strcmp(name,"format/interlace") { /* false */ }
else if (!strcmp(name,"format/frame rate") { /* 24 */ }
return 1;
}
Alternatively, you might like to parse iteratively.
You'd use:
void parse_object(cJSON *item)
{
int i; for (i=0;i<cJSON_GetArraySize(item);i++)
{
cJSON *subitem=cJSON_GetArrayItem(item,i);
// handle subitem.
}
}
Or, for PROPER manual mode:
void parse_object(cJSON *item)
{
cJSON *subitem=item->child;
while (subitem)
{
// handle subitem
if (subitem->child) parse_object(subitem->child);
subitem=subitem->next;
}
}
Of course, this should look familiar, since this is just a stripped-down version
of the callback-parser.
This should cover most uses you'll find for parsing. The rest should be possible
to infer.. and if in doubt, read the source! There's not a lot of it! ;)
In terms of constructing JSON data, the example code above is the right way to do it.
You can, of course, hand your sub-objects to other functions to populate.
Also, if you find a use for it, you can manually build the objects.
For instance, suppose you wanted to build an array of objects?
cJSON *objects[24];
cJSON *Create_array_of_anything(cJSON **items,int num)
{
int i;cJSON *prev, *root=cJSON_CreateArray();
for (i=0;i<24;i++)
{
if (!i) root->child=objects[i];
else prev->next=objects[i], objects[i]->prev=prev;
prev=objects[i];
}
return root;
}
and simply: Create_array_of_anything(objects,24);
cJSON doesn't make any assumptions about what order you create things in.
You can attach the objects, as above, and later add children to each
of those objects.
As soon as you call cJSON_Print, it renders the structure to text.
The test.c code shows how to handle a bunch of typical cases. If you uncomment
the code, it'll load, parse and print a bunch of test files, also from json.org,
which are more complex than I'd care to try and stash into a const char array[].
Enjoy cJSON!
- Dave Gamble, Aug 2009

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,828 @@
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "cJSON_Utils.h"
static char* cJSONUtils_strdup(const char* str)
{
size_t len = 0;
char *copy = NULL;
len = strlen(str) + 1;
if (!(copy = (char*)malloc(len)))
{
return NULL;
}
memcpy(copy, str, len);
return copy;
}
static int cJSONUtils_strcasecmp(const char *s1, const char *s2)
{
if (!s1)
{
return (s1 == s2) ? 0 : 1; /* both NULL? */
}
if (!s2)
{
return 1;
}
for(; tolower(*s1) == tolower(*s2); ++s1, ++s2)
{
if(*s1 == 0)
{
return 0;
}
}
return tolower(*(const unsigned char *)s1) - tolower(*(const unsigned char *)s2);
}
/* JSON Pointer implementation: */
static int cJSONUtils_Pstrcasecmp(const char *a, const char *e)
{
if (!a || !e)
{
return (a == e) ? 0 : 1; /* both NULL? */
}
for (; *a && *e && (*e != '/'); a++, e++) /* compare until next '/' */
{
if (*e == '~')
{
/* check for escaped '~' (~0) and '/' (~1) */
if (!((e[1] == '0') && (*a == '~')) && !((e[1] == '1') && (*a == '/')))
{
/* invalid escape sequence or wrong character in *a */
return 1;
}
else
{
e++;
}
}
else if (tolower(*a) != tolower(*e))
{
return 1;
}
}
if (((*e != 0) && (*e != '/')) != (*a != 0))
{
/* one string has ended, the other not */
return 1;
}
return 0;
}
static int cJSONUtils_PointerEncodedstrlen(const char *s)
{
int l = 0;
for (; *s; s++, l++)
{
if ((*s == '~') || (*s == '/'))
{
l++;
}
}
return l;
}
static void cJSONUtils_PointerEncodedstrcpy(char *d, const char *s)
{
for (; *s; s++)
{
if (*s == '/')
{
*d++ = '~';
*d++ = '1';
}
else if (*s == '~')
{
*d++ = '~';
*d++ = '0';
}
else
{
*d++ = *s;
}
}
*d = '\0';
}
char *cJSONUtils_FindPointerFromObjectTo(cJSON *object, cJSON *target)
{
int type = object->type;
int c = 0;
cJSON *obj = 0;
if (object == target)
{
/* found */
return cJSONUtils_strdup("");
}
/* recursively search all children of the object */
for (obj = object->child; obj; obj = obj->next, c++)
{
char *found = cJSONUtils_FindPointerFromObjectTo(obj, target);
if (found)
{
if ((type & 0xFF) == cJSON_Array)
{
/* reserve enough memory for a 64 bit integer + '/' and '\0' */
char *ret = (char*)malloc(strlen(found) + 23);
sprintf(ret, "/%d%s", c, found); /* /<array_index><path> */
free(found);
return ret;
}
else if ((type & 0xFF) == cJSON_Object)
{
char *ret = (char*)malloc(strlen(found) + cJSONUtils_PointerEncodedstrlen(obj->string) + 2);
*ret = '/';
cJSONUtils_PointerEncodedstrcpy(ret + 1, obj->string);
strcat(ret, found);
free(found);
return ret;
}
/* reached leaf of the tree, found nothing */
free(found);
return NULL;
}
}
/* not found */
return NULL;
}
cJSON *cJSONUtils_GetPointer(cJSON *object, const char *pointer)
{
/* follow path of the pointer */
while ((*pointer++ == '/') && object)
{
if ((object->type & 0xFF) == cJSON_Array)
{
int which = 0;
/* parse array index */
while ((*pointer >= '0') && (*pointer <= '9'))
{
which = (10 * which) + (*pointer++ - '0');
}
if (*pointer && (*pointer != '/'))
{
/* not end of string or new path token */
return NULL;
}
object = cJSON_GetArrayItem(object, which);
}
else if ((object->type & 0xFF) == cJSON_Object)
{
object = object->child;
/* GetObjectItem. */
while (object && cJSONUtils_Pstrcasecmp(object->string, pointer))
{
object = object->next;
}
/* skip to the next path token or end of string */
while (*pointer && (*pointer != '/'))
{
pointer++;
}
}
else
{
return NULL;
}
}
return object;
}
/* JSON Patch implementation. */
static void cJSONUtils_InplaceDecodePointerString(char *string)
{
char *s2 = string;
for (; *string; s2++, string++)
{
*s2 = (*string != '~')
? (*string)
: ((*(++string) == '0')
? '~'
: '/');
}
*s2 = '\0';
}
static cJSON *cJSONUtils_PatchDetach(cJSON *object, const char *path)
{
char *parentptr = NULL;
char *childptr = NULL;
cJSON *parent = NULL;
cJSON *ret = NULL;
/* copy path and split it in parent and child */
parentptr = cJSONUtils_strdup(path);
childptr = strrchr(parentptr, '/'); /* last '/' */
if (childptr)
{
/* split strings */
*childptr++ = '\0';
}
parent = cJSONUtils_GetPointer(object, parentptr);
cJSONUtils_InplaceDecodePointerString(childptr);
if (!parent)
{
/* Couldn't find object to remove child from. */
ret = NULL;
}
else if ((parent->type & 0xFF) == cJSON_Array)
{
ret = cJSON_DetachItemFromArray(parent, atoi(childptr));
}
else if ((parent->type & 0xFF) == cJSON_Object)
{
ret = cJSON_DetachItemFromObject(parent, childptr);
}
free(parentptr);
/* return the detachted item */
return ret;
}
static int cJSONUtils_Compare(cJSON *a, cJSON *b)
{
if ((a->type & 0xFF) != (b->type & 0xFF))
{
/* mismatched type. */
return -1;
}
switch (a->type & 0xFF)
{
case cJSON_Number:
/* numeric mismatch. */
return ((a->valueint != b->valueint) || (a->valuedouble != b->valuedouble)) ? -2 : 0;
case cJSON_String:
/* string mismatch. */
return (strcmp(a->valuestring, b->valuestring) != 0) ? -3 : 0;
case cJSON_Array:
for (a = a->child, b = b->child; a && b; a = a->next, b = b->next)
{
int err = cJSONUtils_Compare(a, b);
if (err)
{
return err;
}
}
/* array size mismatch? (one of both children is not NULL) */
return (a || b) ? -4 : 0;
case cJSON_Object:
cJSONUtils_SortObject(a);
cJSONUtils_SortObject(b);
a = a->child;
b = b->child;
while (a && b)
{
int err = 0;
/* compare object keys */
if (cJSONUtils_strcasecmp(a->string, b->string))
{
/* missing member */
return -6;
}
err = cJSONUtils_Compare(a, b);
if (err)
{
return err;
}
a = a->next;
b = b->next;
}
/* object length mismatch (one of both children is not null) */
return (a || b) ? -5 : 0;
default:
break;
}
/* null, true or false */
return 0;
}
static int cJSONUtils_ApplyPatch(cJSON *object, cJSON *patch)
{
cJSON *op = NULL;
cJSON *path = NULL;
cJSON *value = NULL;
cJSON *parent = NULL;
int opcode = 0;
char *parentptr = NULL;
char *childptr = NULL;
op = cJSON_GetObjectItem(patch, "op");
path = cJSON_GetObjectItem(patch, "path");
if (!op || !path)
{
/* malformed patch. */
return 2;
}
/* decode operation */
if (!strcmp(op->valuestring, "add"))
{
opcode = 0;
}
else if (!strcmp(op->valuestring, "remove"))
{
opcode = 1;
}
else if (!strcmp(op->valuestring, "replace"))
{
opcode = 2;
}
else if (!strcmp(op->valuestring, "move"))
{
opcode = 3;
}
else if (!strcmp(op->valuestring, "copy"))
{
opcode = 4;
}
else if (!strcmp(op->valuestring, "test"))
{
/* compare value: {...} with the given path */
return cJSONUtils_Compare(cJSONUtils_GetPointer(object, path->valuestring), cJSON_GetObjectItem(patch, "value"));
}
else
{
/* unknown opcode. */
return 3;
}
/* Remove/Replace */
if ((opcode == 1) || (opcode == 2))
{
/* Get rid of old. */
cJSON_Delete(cJSONUtils_PatchDetach(object, path->valuestring));
if (opcode == 1)
{
/* For Remove, this is job done. */
return 0;
}
}
/* Copy/Move uses "from". */
if ((opcode == 3) || (opcode == 4))
{
cJSON *from = cJSON_GetObjectItem(patch, "from");
if (!from)
{
/* missing "from" for copy/move. */
return 4;
}
if (opcode == 3)
{
/* move */
value = cJSONUtils_PatchDetach(object, from->valuestring);
}
if (opcode == 4)
{
/* copy */
value = cJSONUtils_GetPointer(object, from->valuestring);
}
if (!value)
{
/* missing "from" for copy/move. */
return 5;
}
if (opcode == 4)
{
value = cJSON_Duplicate(value, 1);
}
if (!value)
{
/* out of memory for copy/move. */
return 6;
}
}
else /* Add/Replace uses "value". */
{
value = cJSON_GetObjectItem(patch, "value");
if (!value)
{
/* missing "value" for add/replace. */
return 7;
}
value = cJSON_Duplicate(value, 1);
if (!value)
{
/* out of memory for add/replace. */
return 8;
}
}
/* Now, just add "value" to "path". */
/* split pointer in parent and child */
parentptr = cJSONUtils_strdup(path->valuestring);
childptr = strrchr(parentptr, '/');
if (childptr)
{
*childptr++ = '\0';
}
parent = cJSONUtils_GetPointer(object, parentptr);
cJSONUtils_InplaceDecodePointerString(childptr);
/* add, remove, replace, move, copy, test. */
if (!parent)
{
/* Couldn't find object to add to. */
free(parentptr);
cJSON_Delete(value);
return 9;
}
else if ((parent->type & 0xFF) == cJSON_Array)
{
if (!strcmp(childptr, "-"))
{
cJSON_AddItemToArray(parent, value);
}
else
{
cJSON_InsertItemInArray(parent, atoi(childptr), value);
}
}
else if ((parent->type & 0xFF) == cJSON_Object)
{
cJSON_DeleteItemFromObject(parent, childptr);
cJSON_AddItemToObject(parent, childptr, value);
}
else
{
cJSON_Delete(value);
}
free(parentptr);
return 0;
}
int cJSONUtils_ApplyPatches(cJSON *object, cJSON *patches)
{
int err = 0;
if ((patches->type & 0xFF) != cJSON_Array)
{
/* malformed patches. */
return 1;
}
if (patches)
{
patches = patches->child;
}
while (patches)
{
if ((err = cJSONUtils_ApplyPatch(object, patches)))
{
return err;
}
patches = patches->next;
}
return 0;
}
static void cJSONUtils_GeneratePatch(cJSON *patches, const char *op, const char *path, const char *suffix, cJSON *val)
{
cJSON *patch = cJSON_CreateObject();
cJSON_AddItemToObject(patch, "op", cJSON_CreateString(op));
if (suffix)
{
char *newpath = (char*)malloc(strlen(path) + cJSONUtils_PointerEncodedstrlen(suffix) + 2);
cJSONUtils_PointerEncodedstrcpy(newpath + sprintf(newpath, "%s/", path), suffix);
cJSON_AddItemToObject(patch, "path", cJSON_CreateString(newpath));
free(newpath);
}
else
{
cJSON_AddItemToObject(patch, "path", cJSON_CreateString(path));
}
if (val)
{
cJSON_AddItemToObject(patch, "value", cJSON_Duplicate(val, 1));
}
cJSON_AddItemToArray(patches, patch);
}
void cJSONUtils_AddPatchToArray(cJSON *array, const char *op, const char *path, cJSON *val)
{
cJSONUtils_GeneratePatch(array, op, path, 0, val);
}
static void cJSONUtils_CompareToPatch(cJSON *patches, const char *path, cJSON *from, cJSON *to)
{
if ((from->type & 0xFF) != (to->type & 0xFF))
{
cJSONUtils_GeneratePatch(patches, "replace", path, 0, to);
return;
}
switch ((from->type & 0xFF))
{
case cJSON_Number:
if ((from->valueint != to->valueint) || (from->valuedouble != to->valuedouble))
{
cJSONUtils_GeneratePatch(patches, "replace", path, 0, to);
}
return;
case cJSON_String:
if (strcmp(from->valuestring, to->valuestring) != 0)
{
cJSONUtils_GeneratePatch(patches, "replace", path, 0, to);
}
return;
case cJSON_Array:
{
int c = 0;
char *newpath = (char*)malloc(strlen(path) + 23); /* Allow space for 64bit int. */
/* generate patches for all array elements that exist in "from" and "to" */
for (c = 0, from = from->child, to = to->child; from && to; from = from->next, to = to->next, c++)
{
sprintf(newpath, "%s/%d", path, c); /* path of the current array element */
cJSONUtils_CompareToPatch(patches, newpath, from, to);
}
/* remove leftover elements from 'from' that are not in 'to' */
for (; from; from = from->next, c++)
{
sprintf(newpath, "%d", c);
cJSONUtils_GeneratePatch(patches, "remove", path, newpath, 0);
}
/* add new elements in 'to' that were not in 'from' */
for (; to; to = to->next, c++)
{
cJSONUtils_GeneratePatch(patches, "add", path, "-", to);
}
free(newpath);
return;
}
case cJSON_Object:
{
cJSON *a = NULL;
cJSON *b = NULL;
cJSONUtils_SortObject(from);
cJSONUtils_SortObject(to);
a = from->child;
b = to->child;
/* for all object values in the object with more of them */
while (a || b)
{
int diff = (!a) ? 1 : ((!b) ? -1 : cJSONUtils_strcasecmp(a->string, b->string));
if (!diff)
{
/* both object keys are the same */
char *newpath = (char*)malloc(strlen(path) + cJSONUtils_PointerEncodedstrlen(a->string) + 2);
cJSONUtils_PointerEncodedstrcpy(newpath + sprintf(newpath, "%s/", path), a->string);
/* create a patch for the element */
cJSONUtils_CompareToPatch(patches, newpath, a, b);
free(newpath);
a = a->next;
b = b->next;
}
else if (diff < 0)
{
/* object element doesn't exist in 'to' --> remove it */
cJSONUtils_GeneratePatch(patches, "remove", path, a->string, 0);
a = a->next;
}
else
{
/* object element doesn't exist in 'from' --> add it */
cJSONUtils_GeneratePatch(patches, "add", path, b->string, b);
b = b->next;
}
}
return;
}
default:
break;
}
}
cJSON* cJSONUtils_GeneratePatches(cJSON *from, cJSON *to)
{
cJSON *patches = cJSON_CreateArray();
cJSONUtils_CompareToPatch(patches, "", from, to);
return patches;
}
/* sort lists using mergesort */
static cJSON *cJSONUtils_SortList(cJSON *list)
{
cJSON *first = list;
cJSON *second = list;
cJSON *ptr = list;
if (!list || !list->next)
{
/* One entry is sorted already. */
return list;
}
while (ptr && ptr->next && (cJSONUtils_strcasecmp(ptr->string, ptr->next->string) < 0))
{
/* Test for list sorted. */
ptr = ptr->next;
}
if (!ptr || !ptr->next)
{
/* Leave sorted lists unmodified. */
return list;
}
/* reset ptr to the beginning */
ptr = list;
while (ptr)
{
/* Walk two pointers to find the middle. */
second = second->next;
ptr = ptr->next;
/* advances ptr two steps at a time */
if (ptr)
{
ptr = ptr->next;
}
}
if (second && second->prev)
{
/* Split the lists */
second->prev->next = NULL;
}
/* Recursively sort the sub-lists. */
first = cJSONUtils_SortList(first);
second = cJSONUtils_SortList(second);
list = ptr = NULL;
while (first && second) /* Merge the sub-lists */
{
if (cJSONUtils_strcasecmp(first->string, second->string) < 0)
{
if (!list)
{
/* start merged list with the first element of the first list */
list = ptr = first;
}
else
{
/* add first element of first list to merged list */
ptr->next = first;
first->prev = ptr;
ptr = first;
}
first = first->next;
}
else
{
if (!list)
{
/* start merged list with the first element of the second list */
list = ptr = second;
}
else
{
/* add first element of second list to merged list */
ptr->next = second;
second->prev = ptr;
ptr = second;
}
second = second->next;
}
}
if (first)
{
/* Append rest of first list. */
if (!list)
{
return first;
}
ptr->next = first;
first->prev = ptr;
}
if (second)
{
/* Append rest of second list */
if (!list)
{
return second;
}
ptr->next = second;
second->prev = ptr;
}
return list;
}
void cJSONUtils_SortObject(cJSON *object)
{
object->child = cJSONUtils_SortList(object->child);
}
cJSON* cJSONUtils_MergePatch(cJSON *target, cJSON *patch)
{
if (!patch || ((patch->type & 0xFF) != cJSON_Object))
{
/* scalar value, array or NULL, just duplicate */
cJSON_Delete(target);
return cJSON_Duplicate(patch, 1);
}
if (!target || ((target->type & 0xFF) != cJSON_Object))
{
cJSON_Delete(target);
target = cJSON_CreateObject();
}
patch = patch->child;
while (patch)
{
if ((patch->type & 0xFF) == cJSON_NULL)
{
/* NULL is the indicator to remove a value, see RFC7396 */
cJSON_DeleteItemFromObject(target, patch->string);
}
else
{
cJSON *replaceme = cJSON_DetachItemFromObject(target, patch->string);
cJSON_AddItemToObject(target, patch->string, cJSONUtils_MergePatch(replaceme, patch));
}
patch = patch->next;
}
return target;
}
cJSON *cJSONUtils_GenerateMergePatch(cJSON *from, cJSON *to)
{
cJSON *patch = NULL;
if (!to)
{
/* patch to delete everything */
return cJSON_CreateNull();
}
if (((to->type & 0xFF) != cJSON_Object) || !from || ((from->type & 0xFF) != cJSON_Object))
{
return cJSON_Duplicate(to, 1);
}
cJSONUtils_SortObject(from);
cJSONUtils_SortObject(to);
from = from->child;
to = to->child;
patch = cJSON_CreateObject();
while (from || to)
{
int compare = from ? (to ? strcmp(from->string, to->string) : -1) : 1;
if (compare < 0)
{
/* from has a value that to doesn't have -> remove */
cJSON_AddItemToObject(patch, from->string, cJSON_CreateNull());
from = from->next;
}
else if (compare > 0)
{
/* to has a value that from doesn't have -> add to patch */
cJSON_AddItemToObject(patch, to->string, cJSON_Duplicate(to, 1));
to = to->next;
}
else
{
/* object key exists in both objects */
if (cJSONUtils_Compare(from, to))
{
/* not identical --> generate a patch */
cJSON_AddItemToObject(patch, to->string, cJSONUtils_GenerateMergePatch(from, to));
}
/* next key in the object */
from = from->next;
to = to->next;
}
}
if (!patch->child)
{
cJSON_Delete(patch);
return NULL;
}
return patch;
}

View file

@ -0,0 +1,44 @@
#include "cJSON.h"
/* Implement RFC6901 (https://tools.ietf.org/html/rfc6901) JSON Pointer spec. */
cJSON *cJSONUtils_GetPointer(cJSON *object, const char *pointer);
/* Implement RFC6902 (https://tools.ietf.org/html/rfc6902) JSON Patch spec. */
cJSON* cJSONUtils_GeneratePatches(cJSON *from, cJSON *to);
/* Utility for generating patch array entries. */
void cJSONUtils_AddPatchToArray(cJSON *array, const char *op, const char *path, cJSON *val);
/* Returns 0 for success. */
int cJSONUtils_ApplyPatches(cJSON *object, cJSON *patches);
/*
// Note that ApplyPatches is NOT atomic on failure. To implement an atomic ApplyPatches, use:
//int cJSONUtils_AtomicApplyPatches(cJSON **object, cJSON *patches)
//{
// cJSON *modme = cJSON_Duplicate(*object, 1);
// int error = cJSONUtils_ApplyPatches(modme, patches);
// if (!error)
// {
// cJSON_Delete(*object);
// *object = modme;
// }
// else
// {
// cJSON_Delete(modme);
// }
//
// return error;
//}
// Code not added to library since this strategy is a LOT slower.
*/
/* Implement RFC7386 (https://tools.ietf.org/html/rfc7396) JSON Merge Patch spec. */
/* target will be modified by patch. return value is new ptr for target. */
cJSON* cJSONUtils_MergePatch(cJSON *target, cJSON *patch);
/* generates a patch to move from -> to */
cJSON *cJSONUtils_GenerateMergePatch(cJSON *from, cJSON *to);
/* Given a root object and a target object, construct a pointer from one to the other. */
char *cJSONUtils_FindPointerFromObjectTo(cJSON *object, cJSON *target);
/* Sorts the members of the object into alphabetical order. */
void cJSONUtils_SortObject(cJSON *object);

View file

@ -0,0 +1,8 @@
NAME := cjson
$(NAME)_TYPE := share
GLOBAL_INCLUDES += include
# don't modify to L_CFLAGS, because CONFIG_CJSON_WITHOUT_DOUBLE should enable global
#$(NAME)_CFLAGS += -DCONFIG_CJSON_WITHOUT_DOUBLE
$(NAME)_SOURCES := cJSON.c cJSON_Utils.c

View file

@ -0,0 +1,268 @@
/*
Copyright (c) 2009-2017 Dave Gamble and cJSON contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#ifndef cJSON__h
#define cJSON__h
#ifdef __cplusplus
extern "C" {
#endif
/* project version */
#define CJSON_VERSION_MAJOR 1
#define CJSON_VERSION_MINOR 6
#define CJSON_VERSION_PATCH 0
#include <stddef.h>
/* cJSON Types: */
#define cJSON_Invalid (0)
#define cJSON_False (1 << 0)
#define cJSON_True (1 << 1)
#define cJSON_NULL (1 << 2)
#define cJSON_Number (1 << 3)
#define cJSON_String (1 << 4)
#define cJSON_Array (1 << 5)
#define cJSON_Object (1 << 6)
#define cJSON_Raw (1 << 7) /* raw json */
#define cJSON_IsReference 256
#define cJSON_StringIsConst 512
/* The cJSON structure: */
typedef struct cJSON {
/* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */
struct cJSON* next;
struct cJSON* prev;
/* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */
struct cJSON* child;
/* The type of the item, as above. */
int type;
/* The item's string, if type==cJSON_String and type == cJSON_Raw */
char* valuestring;
#ifdef CJSON_STRING_ZEROCOPY
size_t valuestring_length;
#endif
/* writing to valueint is DEPRECATED, use cJSON_SetNumberValue instead */
int valueint;
/* The item's name string, if this item is the child of, or is in the list of subitems of an object. */
char* string;
#ifdef CJSON_STRING_ZEROCOPY
size_t string_length;
#endif
/* The item's number, if type==cJSON_Number */
double valuedouble;
} cJSON;
typedef struct cJSON_Hooks {
void* (*malloc_fn)(size_t sz);
void (*free_fn)(void* ptr);
} cJSON_Hooks;
typedef int cJSON_bool;
#if !defined(__WINDOWS__) && (defined(WIN32) || defined(WIN64) || defined(_MSC_VER) || defined(_WIN32))
#define __WINDOWS__
#endif
#ifdef __WINDOWS__
/* When compiling for windows, we specify a specific calling convention to avoid issues where we are being called from a project with a different default calling convention. For windows you have 2 define options:
CJSON_HIDE_SYMBOLS - Define this in the case where you don't want to ever dllexport symbols
CJSON_EXPORT_SYMBOLS - Define this on library build when you want to dllexport symbols (default)
CJSON_IMPORT_SYMBOLS - Define this if you want to dllimport symbol
For *nix builds that support visibility attribute, you can define similar behavior by
setting default visibility to hidden by adding
-fvisibility=hidden (for gcc)
or
-xldscope=hidden (for sun cc)
to CFLAGS
then using the CJSON_API_VISIBILITY flag to "export" the same symbols the way CJSON_EXPORT_SYMBOLS does
*/
/* export symbols by default, this is necessary for copy pasting the C and header file */
#if !defined(CJSON_HIDE_SYMBOLS) && !defined(CJSON_IMPORT_SYMBOLS) && !defined(CJSON_EXPORT_SYMBOLS)
#define CJSON_EXPORT_SYMBOLS
#endif
#if defined(CJSON_HIDE_SYMBOLS)
#define CJSON_PUBLIC(type) type __stdcall
#elif defined(CJSON_EXPORT_SYMBOLS)
#define CJSON_PUBLIC(type) __declspec(dllexport) type __stdcall
#elif defined(CJSON_IMPORT_SYMBOLS)
#define CJSON_PUBLIC(type) __declspec(dllimport) type __stdcall
#endif
#else /* !WIN32 */
#if (defined(__GNUC__) || defined(__SUNPRO_CC) || defined (__SUNPRO_C)) && defined(CJSON_API_VISIBILITY)
#define CJSON_PUBLIC(type) __attribute__((visibility("default"))) type
#else
#define CJSON_PUBLIC(type) type
#endif
#endif
/* Limits how deeply nested arrays/objects can be before cJSON rejects to parse them.
* This is to prevent stack overflows. */
#ifndef CJSON_NESTING_LIMIT
#define CJSON_NESTING_LIMIT 1000
#endif
/* returns the version of cJSON as a string */
CJSON_PUBLIC(const char*) cJSON_Version(void);
/* Supply malloc, realloc and free functions to cJSON */
CJSON_PUBLIC(void) cJSON_InitHooks(cJSON_Hooks* hooks);
/* Memory Management: the caller is always responsible to free the results from all variants of cJSON_Parse (with cJSON_Delete) and cJSON_Print (with stdlib free, cJSON_Hooks.free_fn, or cJSON_free as appropriate). The exception is cJSON_PrintPreallocated, where the caller has full responsibility of the buffer. */
/* Supply a block of JSON, and this returns a cJSON object you can interrogate. */
CJSON_PUBLIC(cJSON*) cJSON_Parse(const char* value);
/* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to the final byte parsed. */
/* If you supply a ptr in return_parse_end and parsing fails, then return_parse_end will contain a pointer to the error so will match cJSON_GetErrorPtr(). */
CJSON_PUBLIC(cJSON*) cJSON_ParseWithOpts(const char* value, const char** return_parse_end,
cJSON_bool require_null_terminated);
/* Render a cJSON entity to text for transfer/storage. */
CJSON_PUBLIC(char*) cJSON_Print(const cJSON* item);
/* Render a cJSON entity to text for transfer/storage without any formatting. */
CJSON_PUBLIC(char*) cJSON_PrintUnformatted(const cJSON* item);
/* Render a cJSON entity to text using a buffered strategy. prebuffer is a guess at the final size. guessing well reduces reallocation. fmt=0 gives unformatted, =1 gives formatted */
CJSON_PUBLIC(char*) cJSON_PrintBuffered(const cJSON* item, int prebuffer, cJSON_bool fmt);
/* Render a cJSON entity to text using a buffer already allocated in memory with given length. Returns 1 on success and 0 on failure. */
/* NOTE: cJSON is not always 100% accurate in estimating how much memory it will use, so to be safe allocate 5 bytes more than you actually need */
CJSON_PUBLIC(cJSON_bool) cJSON_PrintPreallocated(cJSON* item, char* buffer, const int length, const cJSON_bool format);
/* Delete a cJSON entity and all subentities. */
CJSON_PUBLIC(void) cJSON_Delete(cJSON* c);
/* Returns the number of items in an array (or object). */
CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON* array);
/* Retrieve item number "item" from array "array". Returns NULL if unsuccessful. */
CJSON_PUBLIC(cJSON*) cJSON_GetArrayItem(const cJSON* array, int index);
/* Get item "string" from object. Case insensitive. */
CJSON_PUBLIC(cJSON*) cJSON_GetObjectItem(const cJSON* const object, const char* const string);
CJSON_PUBLIC(cJSON*) cJSON_GetObjectItemCaseSensitive(const cJSON* const object, const char* const string);
CJSON_PUBLIC(cJSON_bool) cJSON_HasObjectItem(const cJSON* object, const char* string);
/* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */
CJSON_PUBLIC(const char*) cJSON_GetErrorPtr(void);
/* These functions check the type of an item */
CJSON_PUBLIC(cJSON_bool) cJSON_IsInvalid(const cJSON* const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsFalse(const cJSON* const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsTrue(const cJSON* const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsBool(const cJSON* const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsNull(const cJSON* const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsNumber(const cJSON* const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsString(const cJSON* const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsArray(const cJSON* const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsObject(const cJSON* const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsRaw(const cJSON* const item);
/* These calls create a cJSON item of the appropriate type. */
CJSON_PUBLIC(cJSON*) cJSON_CreateNull(void);
CJSON_PUBLIC(cJSON*) cJSON_CreateTrue(void);
CJSON_PUBLIC(cJSON*) cJSON_CreateFalse(void);
CJSON_PUBLIC(cJSON*) cJSON_CreateBool(cJSON_bool boolean);
CJSON_PUBLIC(cJSON*) cJSON_CreateNumber(double num);
CJSON_PUBLIC(cJSON*) cJSON_CreateString(const char* string);
/* raw json */
CJSON_PUBLIC(cJSON*) cJSON_CreateRaw(const char* raw);
CJSON_PUBLIC(cJSON*) cJSON_CreateArray(void);
CJSON_PUBLIC(cJSON*) cJSON_CreateObject(void);
/* These utilities create an Array of count items. */
CJSON_PUBLIC(cJSON*) cJSON_CreateIntArray(const int* numbers, int count);
CJSON_PUBLIC(cJSON*) cJSON_CreateFloatArray(const float* numbers, int count);
CJSON_PUBLIC(cJSON*) cJSON_CreateDoubleArray(const double* numbers, int count);
CJSON_PUBLIC(cJSON*) cJSON_CreateStringArray(const char** strings, int count);
/* Append item to the specified array/object. */
CJSON_PUBLIC(void) cJSON_AddItemToArray(cJSON* array, cJSON* item);
CJSON_PUBLIC(void) cJSON_AddItemToObject(cJSON* object, const char* string, cJSON* item);
/* Use this when string is definitely const (i.e. a literal, or as good as), and will definitely survive the cJSON object.
* WARNING: When this function was used, make sure to always check that (item->type & cJSON_StringIsConst) is zero before
* writing to `item->string` */
CJSON_PUBLIC(void) cJSON_AddItemToObjectCS(cJSON* object, const char* string, cJSON* item);
/* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON. */
CJSON_PUBLIC(void) cJSON_AddItemReferenceToArray(cJSON* array, cJSON* item);
CJSON_PUBLIC(void) cJSON_AddItemReferenceToObject(cJSON* object, const char* string, cJSON* item);
/* Remove/Detatch items from Arrays/Objects. */
CJSON_PUBLIC(cJSON*) cJSON_DetachItemViaPointer(cJSON* parent, cJSON* const item);
CJSON_PUBLIC(cJSON*) cJSON_DetachItemFromArray(cJSON* array, int which);
CJSON_PUBLIC(void) cJSON_DeleteItemFromArray(cJSON* array, int which);
CJSON_PUBLIC(cJSON*) cJSON_DetachItemFromObject(cJSON* object, const char* string);
CJSON_PUBLIC(cJSON*) cJSON_DetachItemFromObjectCaseSensitive(cJSON* object, const char* string);
CJSON_PUBLIC(void) cJSON_DeleteItemFromObject(cJSON* object, const char* string);
CJSON_PUBLIC(void) cJSON_DeleteItemFromObjectCaseSensitive(cJSON* object, const char* string);
/* Update array items. */
CJSON_PUBLIC(void) cJSON_InsertItemInArray(cJSON* array, int which,
cJSON* newitem); /* Shifts pre-existing items to the right. */
CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON* const parent, cJSON* const item, cJSON* replacement);
CJSON_PUBLIC(void) cJSON_ReplaceItemInArray(cJSON* array, int which, cJSON* newitem);
CJSON_PUBLIC(void) cJSON_ReplaceItemInObject(cJSON* object, const char* string, cJSON* newitem);
CJSON_PUBLIC(void) cJSON_ReplaceItemInObjectCaseSensitive(cJSON* object, const char* string, cJSON* newitem);
/* Duplicate a cJSON item */
CJSON_PUBLIC(cJSON*) cJSON_Duplicate(const cJSON* item, cJSON_bool recurse);
/* Duplicate will create a new, identical cJSON item to the one you pass, in new memory that will
need to be released. With recurse!=0, it will duplicate any children connected to the item.
The item->next and ->prev pointers are always zero on return from Duplicate. */
/* Recursively compare two cJSON items for equality. If either a or b is NULL or invalid, they will be considered unequal.
* case_sensitive determines if object keys are treated case sensitive (1) or case insensitive (0) */
CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON* const a, const cJSON* const b, const cJSON_bool case_sensitive);
CJSON_PUBLIC(void) cJSON_Minify(char* json);
/* Macros for creating things quickly. */
#define cJSON_AddNullToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateNull())
#define cJSON_AddTrueToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateTrue())
#define cJSON_AddFalseToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateFalse())
#define cJSON_AddBoolToObject(object,name,b) cJSON_AddItemToObject(object, name, cJSON_CreateBool(b))
#define cJSON_AddNumberToObject(object,name,n) cJSON_AddItemToObject(object, name, cJSON_CreateNumber(n))
#define cJSON_AddStringToObject(object,name,s) cJSON_AddItemToObject(object, name, cJSON_CreateString(s))
#define cJSON_AddRawToObject(object,name,s) cJSON_AddItemToObject(object, name, cJSON_CreateRaw(s))
/* When assigning an integer value, it needs to be propagated to valuedouble too. */
#define cJSON_SetIntValue(object, number) ((object) ? (object)->valueint = (object)->valuedouble = (number) : (number))
/* helper for the cJSON_SetNumberValue macro */
CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON* object, double number);
#define cJSON_SetNumberValue(object, number) ((object != NULL) ? cJSON_SetNumberHelper(object, (double)number) : (number))
/* Macro for iterating over an array or object */
#define cJSON_ArrayForEach(element, array) for(element = (array != NULL) ? (array)->child : NULL; element != NULL; element = element->next)
/* malloc/free objects using the malloc/free functions that have been set with cJSON_InitHooks */
CJSON_PUBLIC(void*) cJSON_malloc(size_t size);
CJSON_PUBLIC(void) cJSON_free(void* object);
#ifdef __cplusplus
}
#endif
#endif

View file

@ -0,0 +1,9 @@
src = Split('''
cJSON.c
cJSON_Utils.c
''')
component = aos_component('cjson', src)
component.add_global_includes('include')

View file

@ -0,0 +1,91 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#include "CheckSumUtils.h"
uint8_t UpdateCRC8(uint8_t crcIn, uint8_t byte)
{
uint8_t crc = crcIn;
uint8_t i;
crc ^= byte;
for (i = 0; i < 8; i++) {
if (crc & 0x01) {
crc = (crc >> 1) ^ 0x8C;
} else {
crc >>= 1;
}
}
return crc;
}
void CRC8_Init( CRC8_Context *inContext )
{
inContext->crc = 0;
}
void CRC8_Update( CRC8_Context *inContext, const void *inSrc, size_t inLen )
{
const uint8_t *src = (const uint8_t *) inSrc;
const uint8_t *srcEnd = src + inLen;
while ( src < srcEnd ) {
inContext->crc = UpdateCRC8(inContext->crc, *src++);
}
}
void CRC8_Final( CRC8_Context *inContext, uint8_t *outResult )
{
//inContext->crc = UpdateCRC8(inContext->crc, 0);
*outResult = inContext->crc & 0xffu;
}
/*******************************************************************************/
uint16_t UpdateCRC16(uint16_t crcIn, uint8_t byte)
{
uint32_t crc = crcIn;
uint32_t in = byte | 0x100;
do {
crc <<= 1;
in <<= 1;
if (in & 0x100) {
++crc;
}
if (crc & 0x10000) {
crc ^= 0x1021;
}
} while (!(in & 0x10000));
return crc & 0xffffu;
}
void CRC16_Init( CRC16_Context *inContext )
{
inContext->crc = 0;
}
void CRC16_Update( CRC16_Context *inContext, const void *inSrc, size_t inLen )
{
const uint8_t *src = (const uint8_t *) inSrc;
const uint8_t *srcEnd = src + inLen;
while ( src < srcEnd ) {
inContext->crc = UpdateCRC16(inContext->crc, *src++);
}
}
void CRC16_Final( CRC16_Context *inContext, uint16_t *outResult )
{
inContext->crc = UpdateCRC16(inContext->crc, 0);
inContext->crc = UpdateCRC16(inContext->crc, 0);
*outResult = inContext->crc & 0xffffu;
}

View file

@ -0,0 +1,117 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#ifndef __CheckSumUtils_h__
#define __CheckSumUtils_h__
#include <stdint.h>
#include <stdbool.h>
#include <stdlib.h>
#include <stdio.h>
/******************CRC-8 XMODEM x8+x5+x4+1******************************
*******************************************************************************/
typedef struct {
uint8_t crc;
} CRC8_Context;
/**
* @brief initialize the CRC8 Context
*
* @param inContext holds CRC8 result
*
* @retval none
*/
void CRC8_Init( CRC8_Context *inContext );
/**
* @brief Caculate the CRC8 result
*
* @param inContext holds CRC8 result during caculation process
* @param inSrc input data
* @param inLen length of input data
*
* @retval none
*/
void CRC8_Update( CRC8_Context *inContext, const void *inSrc, size_t inLen );
/**
* @brief output CRC8 result
*
* @param inContext holds CRC8 result
* @param outResutl holds CRC8 final result
*
* @retval none
*/
void CRC8_Final( CRC8_Context *inContext, uint8_t *outResult );
/**
* @}
*/
/******************CRC-16/XMODEM x16+x12+x5+1******************************
*******************************************************************************/
/**
* @brief caculate the CRC16 result for each byte
*
* @param crcIn The context to save CRC16 result.
* @param byte each byte of input data.
*
* @retval return the CRC16 result
*/
typedef struct {
uint16_t crc;
} CRC16_Context;
/**
* @brief initialize the CRC16 Context
*
* @param inContext holds CRC16 result
*
* @retval none
*/
void CRC16_Init( CRC16_Context *inContext );
/**
* @brief Caculate the CRC16 result
*
* @param inContext holds CRC16 result during caculation process
* @param inSrc input data
* @param inLen length of input data
*
* @retval none
*/
void CRC16_Update( CRC16_Context *inContext, const void *inSrc, size_t inLen );
/**
* @brief output CRC16 result
*
* @param inContext holds CRC16 result
* @param outResutl holds CRC16 final result
*
* @retval none
*/
void CRC16_Final( CRC16_Context *inContext, uint16_t *outResult );
/**
* @}
*/
/**
* @}
*/
#endif //__CheckSumUtils_h__

View file

@ -0,0 +1,50 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#include <stdint.h>
#include "crc.h"
#define CRC16_SEED 0xFFFF
#define POLY16 0x1021
#define CRC32_SEED 0xFFFFFFFF
#define POLY32 0x04C11DB7
/** The poly is 0x1021 (x^16 + x^12 + x^5 + 1) */
uint16_t utils_crc16(uint8_t *buf, uint32_t length)
{
int i;
unsigned short shift = CRC16_SEED, data = 0, val = 0;
for (i = 0; i < length; i++) {
if ((i % 8) == 0) {
data = (*buf++) << 8;
}
val = shift ^ data;
shift = shift << 1;
data = data << 1;
if (val & 0x8000) {
shift = shift ^ POLY16;
}
}
return shift;
}
/** The poly is 0x04C11DB7 (X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X+1) */
uint32_t utils_crc32(uint8_t *buf, uint32_t length)
{
uint8_t i;
uint32_t crc = CRC32_SEED; // Initial value
while (length--) {
crc ^= (uint32_t) (*buf++) << 24; // crc ^=(uint32_t)(*data)<<24; data++;
for (i = 0; i < 8; ++i) {
if (crc & 0x80000000) {
crc = (crc << 1) ^ POLY32;
} else {
crc <<= 1;
}
}
}
return crc;
}

View file

@ -0,0 +1,20 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#ifndef _crc_h_
#define _crc_h_
#include <stdint.h>
#if defined(__cplusplus) /* If this is a C++ compiler, use C linkage */
extern "C"
{
#endif
uint16_t utils_crc16(uint8_t *buf, uint32_t length);
uint32_t utils_crc32(uint8_t *buf, uint32_t length);
#if defined(__cplusplus) /* If this is a C++ compiler, use C linkage */
}
#endif
#endif

View file

@ -0,0 +1,233 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#include <stdio.h>
#include <stdlib.h>
#include "digest_algorithm.h"
#include "md5.h"
#include "sha2.c"
#include "hmac.c"
#include "aos/aos.h"
void *digest_md5_init(void)
{
MD5_CTX *ctx = (MD5_CTX *) aos_malloc(sizeof(MD5_CTX));
if (NULL == ctx) {
return NULL;
}
MD5_Init(ctx);
return ctx;
}
int digest_md5_update(void *md5, const void *data, uint32_t length)
{
MD5_Update(md5, data, length);
return 0;
}
int digest_md5_final(void *md5, unsigned char *digest)
{
MD5_Final(digest, md5);
aos_free(md5);
return 0;
}
int digest_md5(const void *data, uint32_t length, unsigned char *digest)
{
MD5_CTX *ctx = (MD5_CTX *) aos_malloc(sizeof(MD5_CTX));
if (NULL == ctx) {
return -1;
}
MD5_Init(ctx);
MD5_Update(ctx, data, length);
MD5_Final(digest, ctx);
aos_free(ctx);
return 0;
}
int digest_md5_file(const char *path, unsigned char *md5)
{
int bytes;
unsigned char data[512];
unsigned char digest[16];
int i, fd;
fd = aos_open(path, O_RDONLY);
if (fd < 0) {
return -1;
}
MD5_CTX *ctx = (MD5_CTX *) aos_malloc(sizeof(MD5_CTX));
if (NULL == ctx) {
aos_close(fd);
return -1;
}
MD5_Init(ctx);
do {
bytes = aos_read(fd, data, sizeof(data));
if (bytes > 0) {
MD5_Update(ctx, data, bytes);
}
} while (bytes == sizeof(data));
MD5_Final(digest, ctx);
for (i = 0; i < 16; i++) {
sprintf((char *)&md5[i * 2], "%02x", digest[i]);
}
aos_close(fd);
aos_free(ctx);
return 0;
}
void *digest_sha256_init(void)
{
SHA256_CTX *ctx = (SHA256_CTX *) aos_malloc(sizeof(SHA256_CTX));
if (NULL == ctx) {
return NULL;
}
SHA256_Init(ctx);
return ctx;
}
int digest_sha256_update(void *sha256, const void *data, uint32_t length)
{
SHA256_Update(sha256, data, length);
return 0;
}
int digest_sha256_final(void *sha256, unsigned char *digest)
{
SHA256_Final(digest, sha256);
aos_free(sha256);
return 0;
}
int digest_sha256(const void *data, uint32_t length, unsigned char *digest)
{
SHA256_CTX *ctx = (SHA256_CTX *) aos_malloc(sizeof(SHA256_CTX));
if (NULL == ctx) {
return -1;
}
memset(ctx, 0, sizeof(SHA256_CTX));
SHA256_Init(ctx);
SHA256_Update(ctx, data, length);
SHA256_Final(digest, ctx);
aos_free(ctx);
return 0;
}
void *digest_sha384_init(void)
{
SHA384_CTX *ctx = (SHA384_CTX *) aos_malloc(sizeof(SHA384_CTX));
if (NULL == ctx) {
return NULL;
}
SHA384_Init(ctx);
return ctx;
}
int digest_sha384_update(void *sha384, const void *data, uint32_t length)
{
SHA384_Update(sha384, data, length);
return 0;
}
int digest_sha384_final(void *sha384, unsigned char *digest)
{
SHA384_Final(digest, sha384);
aos_free(sha384);
return 0;
}
int digest_sha384(const void *data, uint32_t length, unsigned char *digest)
{
SHA384_CTX *ctx = (SHA384_CTX *) aos_malloc(sizeof(SHA384_CTX));
if (NULL == ctx) {
return -1;
}
SHA384_Init(ctx);
SHA384_Update(ctx, data, length);
SHA384_Final(digest, ctx);
aos_free(ctx);
return 0;
}
void *digest_sha512_init(void)
{
SHA512_CTX *ctx = (SHA512_CTX *) aos_malloc(sizeof(SHA512_CTX));
if (NULL == ctx) {
return NULL;
}
SHA512_Init(ctx);
return ctx;
}
int digest_sha512_update(void *sha512, const void *data, uint32_t length)
{
SHA512_Update(sha512, data, length);
return 0;
}
int digest_sha512_final(void *sha512, unsigned char *digest)
{
SHA512_Final(digest, sha512);
aos_free(sha512);
return 0;
}
int digest_sha512(const void *data, uint32_t length, unsigned char *digest)
{
SHA512_CTX *ctx = (SHA512_CTX *) aos_malloc(sizeof(SHA512_CTX));
if (NULL == ctx) {
return -1;
}
SHA512_Init(ctx);
SHA512_Update(ctx, data, length);
SHA512_Final(digest, ctx);
aos_free(ctx);
return 0;
}
int digest_hmac(enum digest_type type, const unsigned char *data,
uint32_t data_len, const unsigned char *key, uint32_t key_len,
unsigned char *digest)
{
switch (type) {
case DIGEST_TYPE_MD5:
return digest_hmac_md5(data, data_len, key, key_len, digest);
case DIGEST_TYPE_SHA256:
break;
case DIGEST_TYPE_SHA384:
break;
case DIGEST_TYPE_SHA512:
break;
default:
break;
}
return -1;
}

View file

@ -0,0 +1,358 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
//chf, cryptographic hash function
#ifndef __CRY_HASH_FUNC_H__
#define __CRY_HASH_FUNC_H__
#include <stdint.h>
#if defined(__cplusplus) /* If this is a C++ compiler, use C linkage */
extern "C"
{
#endif
/** @defgroup group_chf group_chf
* @ingroup group_external_resource
* @{
*/
/**
* @enum Type of digest.
*/
enum digest_type {
DIGEST_TYPE_MD5, /**< MD5 */
//CHF_SHA1,
DIGEST_TYPE_SHA256, /**< SHA-256 */
DIGEST_TYPE_SHA384, /**< SHA-384 */
DIGEST_TYPE_SHA512, /**< SHA-512 */
};
/** @defgroup group_crypto_hash group_crypto_hash
* @{
*/
/** @defgroup group_crypto_hash_md5 group_crypto_hash_md5
* @{
*/
#define MD5_SIZE_BYTE (16) /*Size of MD5 result in byte*/
#define MD5_SIZE_BIT (128) /*Size of MD5 result in bit*/
/**
* @brief initialize MD5.
*
* @param None.
* @return @n MD5 handle.
* @see None.
* @note None.
*/
void *digest_md5_init(void);
/**
* @brief Hash chunks of data with using MD5 digest type.
*
* @param[in] md5 @n The MD5 handle.
* @param[in] data @n The data to be hashed.
* @param[in] length @n The length of the data, in bytes.
* @return
@verbatim
= 0, success.
= -1, failure.
@endverbatim
* @see None.
* @note None.
*/
int digest_md5_update(void *md5, const void *data, uint32_t length);
/**
* @brief Extract the MD5 result and place in digest.
*
* @param[in] md5 @n The MD5 handle.
* @param[out] digest @n MD5 result.
* @return
@verbatim
= 0, success.
= -1, failure.
@endverbatim
* @see None.
* @note It is the caller that allocate memory space for digest.
*/
int digest_md5_final(void *md5, unsigned char *digest);
/**
* @brief Compute MD5 once.
*
* @param[in] data @n The data to be hashed.
* @param[in] length @n The length of the data, in bytes.
* @param[out] digest @n MD5 result.
*
* @return
@verbatim
= 0, success.
= -1, failure.
@endverbatim
* @see None.
* @note It is the caller that allocate memory space for digest.
*/
int digest_md5(const void *data, uint32_t length, unsigned char *digest);
/**
* @brief Compute the specific file's MD5 value.
*
* @param[in] path @n file path.
* @param[out] digest @n MD5 result.
*
* @return
@verbatim
= 0, success.
= -1, failure.
@endverbatim
* @see None.
* @note It is the caller that allocate memory space for digest.
*/
int digest_md5_file(const char *path, unsigned char *digest);
/** @} */// end of group_crypt_hash_md5
/** @defgroup group_crypto_hash_sha256 group_crypto_hash_sha256
* @{
*/
#define SHA256_SIZE_BYTE (32) /*Size of SHA256 result in byte*/
#define SHA256_SIZE_BIT (256) /*Size of SHA256 result in bit*/
/**
* @brief initialize sha256.
*
* @param None.
* @return @n sha256 handle.
* @see None.
* @note None.
*/
void *digest_sha256_init(void);
/**
* @brief Hash chunks of data with using sha256 digest type.
*
* @param[in] sha256 @n The sha256 handle.
* @param[in] data @n The data to be hashed.
* @param[in] length @n The length of the data, in bytes.
* @return
@verbatim
= 0, success.
= -1, failure.
@endverbatim
* @see None.
* @note None.
*/
int digest_sha256_update(void *sha256, const void *data, uint32_t length);
/**
* @brief Extract the sha256 result and place in digest.
*
* @param[in] sha256 @n The sha256 handle.
* @param[out] digest @n sha256 result.
* @return
@verbatim
= 0, success.
= -1, failure.
@endverbatim
* @see None.
* @note It is the caller that allocate memory space for digest.
*/
int digest_sha256_final(void *sha256, unsigned char *digest);
/**
* @brief Compute sha256 once.
*
* @param[in] data @n The data to be hashed.
* @param[in] length @n The length of the data, in bytes.
* @param[out] digest @n sha256 result.
*
* @return
@verbatim
= 0, success.
= -1, failure.
@endverbatim
* @see None.
* @note It is the caller that allocate memory space for digest.
*/
int digest_sha256(const void *data, uint32_t length, unsigned char *digest);
/** @} */// end of group_crypt_hash_sha256
/** @defgroup group_crypto_hash_sha384 group_crypto_hash_sha384
* @{
*/
#define SHA384_SIZE_BYTE (48) /*Size of SHA384 result in byte*/
#define SHA384_SIZE_BIT (384) /*Size of SHA384 result in bit*/
/**
* @brief initialize sha384.
*
* @param None.
* @return @n sha384 handle.
* @see None.
* @note None.
*/
void *digest_sha384_init(void);
/**
* @brief Hash chunks of data with using sha384 digest type.
*
* @param[in] sha384 @n The sha384 handle.
* @param[in] data @n The data to be hashed.
* @param[in] length @n The length of the data, in bytes.
* @return
@verbatim
= 0, success.
= -1, failure.
@endverbatim
* @see None.
* @note None.
*/
int digest_sha384_update(void *sha384, const void *data, uint32_t length);
/**
* @brief Extract the sha384 result and place in digest.
*
* @param[in] sha384 @n The sha384 handle.
* @param[out] digest @n sha384 result.
* @return
@verbatim
= 0, success.
= -1, failure.
@endverbatim
* @see None.
* @note It is the caller that allocate memory space for digest.
*/
int digest_sha384_final(void *sha384, unsigned char *digest);
/**
* @brief Compute sha384 once.
*
* @param[in] data @n The data to be hashed.
* @param[in] length @n The length of the data, in bytes.
* @param[out] digest @n sha384 result.
*
* @return
@verbatim
= 0, success.
= -1, failure.
@endverbatim
* @see None.
* @note It is the caller that allocate memory space for digest.
*/
int digest_sha384(const void *data, uint32_t length, unsigned char *digest);
/** @} */// end of group_crypt_hash_sha384
/** @defgroup group_crypto_hash_sha512 group_crypto_hash_sha512
* @{
*/
#define SHA512_SIZE_BYTE (64) /*Size of SHA512 result in byte*/
#define SHA512_SIZE_BIT (512) /*Size of SHA512 result in bit*/
/**
* @brief initialize sha512.
*
* @param None.
* @return @n sha512 handle.
* @see None.
* @note None.
*/
void *digest_sha512_init(void);
/**
* @brief Hash chunks of data with using sha512 digest type.
*
* @param[in] sha512 @n The sha512 handle.
* @param[in] data @n The data to be hashed.
* @param[in] length @n The length of the data, in bytes.
* @return
@verbatim
= 0, success.
= -1, failure.
@endverbatim
* @see None.
* @note None.
*/
int digest_sha512_update(void *sha512, const void *data, uint32_t length);
/**
* @brief Extract the sha512 result and place in digest.
*
* @param[in] sha512 @n The sha512 handle.
* @param[out] digest @n sha512 result.
* @return
@verbatim
= 0, success.
= -1, failure.
@endverbatim
* @see None.
* @note It is the caller that allocate memory space for digest.
*/
int digest_sha512_final(void *sha512, unsigned char *digest);
/**
* @brief Compute sha512 once.
*
* @param[in] data @n The data to be hashed.
* @param[in] length @n The length of the data, in bytes.
* @param[out] digest @n sha512 result.
*
* @return
@verbatim
= 0, success.
= -1, failure.
@endverbatim
* @see None.
* @note It is the caller that allocate memory space for digest.
*/
int digest_sha512(const void *data, uint32_t length, unsigned char *digest);
/** @} */// end of group_crypt_hash_sha512
/** @defgroup group_crypto_hash_hmac group_crypto_hash_hmac
* @{
*/
/**
* @brief Compute hmac with specific digest type (MD5, sha256, .etc).
*
* @param[in] digest_type @n Specify the digest type for hmac.
* @param[in] msg @n The data to be hashed.
* @param[in] msg_len @n The length of the data, in bytes.
* @param[in] key @n The hmac key.
* @param[in] key_len @n The length of the hmac key, in bytes.
* @param[out] digest @n hmac result.
*
* @return
@verbatim
= 0, success.
= -1, failure.
@endverbatim
* @see None.
* @note It is the caller that allocate memory space for digest.
*/
int digest_hmac(enum digest_type type,
const unsigned char *msg, uint32_t msg_len,
const unsigned char *key, uint32_t key_len,
unsigned char *digest);
/** @} */// end of group_crypt_hash_hmac
/** @} */// end of group_crypt_hash
#if defined(__cplusplus) /* If this is a C++ compiler, use C linkage */
}
#endif
#endif /* ALINK_AGENT_EXTERNAL_CHF_CHF_H_ */

View file

@ -0,0 +1,5 @@
NAME := digest_algorithm
$(NAME)_TYPE := share
$(NAME)_SOURCES := digest_algorithm.c CheckSumUtils.c crc.c md5.c
GLOBAL_INCLUDES += .

View file

@ -0,0 +1,47 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#include <string.h>
#include "digest_algorithm.h"
static int digest_hmac_md5(const unsigned char *msg, uint32_t msg_len,
const unsigned char *key, uint32_t key_len, unsigned char *digest)
{
void *context;
unsigned char k_ipad[65]; /* inner padding key XORd with ipad */
unsigned char k_opad[65]; /* outer padding* key XORd with opad */
unsigned char tk[16];
int i;
if (key_len > 64) {
void *ctx;
ctx = digest_md5_init();
digest_md5_update(ctx, (uint8_t *) key, key_len);
digest_md5_final(ctx, (uint8_t *) tk);
key = tk;
key_len = 16;
}
memset(k_ipad, 0, sizeof(k_ipad));
memset(k_opad, 0, sizeof(k_opad));
memcpy(k_ipad, key, key_len);
memcpy(k_opad, key, key_len);
for (i = 0; i < 64; i++) {
k_ipad[i] ^= 0x36;
k_opad[i] ^= 0x5c;
}
context = digest_md5_init();
digest_md5_update(context, k_ipad, 64);
digest_md5_update(context, (uint8_t *) msg, msg_len);
digest_md5_final(context, (uint8_t *) digest);
context = digest_md5_init();
digest_md5_update(context, k_opad, 64);
digest_md5_update(context, (uint8_t *) digest, 16);
digest_md5_final(context, (uint8_t *) digest);
return 0;
}

View file

@ -0,0 +1,301 @@
/*
* Copyright (c) 2007, Cameron Rich
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* * Neither the name of the axTLS project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* This file implements the MD5 algorithm as defined in RFC1321
*/
#include <stdint.h>
#include <string.h>
#include "md5.h"
#ifndef STDCALL
#define STDCALL
#endif
#ifndef EXP_FUNC
#define EXP_FUNC
#endif
/* Constants for MD5Transform routine.
*/
#define S11 7
#define S12 12
#define S13 17
#define S14 22
#define S21 5
#define S22 9
#define S23 14
#define S24 20
#define S31 4
#define S32 11
#define S33 16
#define S34 23
#define S41 6
#define S42 10
#define S43 15
#define S44 21
#define MD5_SIZE 16
/* ----- static functions ----- */
static void MD5Transform(uint32_t state[4], const uint8_t block[64]);
static void Encode(uint8_t *output, uint32_t *input, uint32_t len);
static void Decode(uint32_t *output, const uint8_t *input, uint32_t len);
static const uint8_t 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
};
/* F, G, H and I are basic MD5 functions.
*/
#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
#define H(x, y, z) ((x) ^ (y) ^ (z))
#define I(x, y, z) ((y) ^ ((x) | (~z)))
/* ROTATE_LEFT rotates x left n bits. */
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
Rotation is separate from addition to prevent recomputation. */
#define FF(a, b, c, d, x, s, ac) { \
(a) += F ((b), (c), (d)) + (x) + (uint32_t)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define GG(a, b, c, d, x, s, ac) { \
(a) += G ((b), (c), (d)) + (x) + (uint32_t)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define HH(a, b, c, d, x, s, ac) { \
(a) += H ((b), (c), (d)) + (x) + (uint32_t)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define II(a, b, c, d, x, s, ac) { \
(a) += I ((b), (c), (d)) + (x) + (uint32_t)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
/**
* MD5 initialization - begins an MD5 operation, writing a new ctx.
*/
EXP_FUNC void STDCALL MD5_Init(MD5_CTX *ctx)
{
ctx->count[0] = ctx->count[1] = 0;
/* Load magic initialization constants.
*/
ctx->state[0] = 0x67452301;
ctx->state[1] = 0xefcdab89;
ctx->state[2] = 0x98badcfe;
ctx->state[3] = 0x10325476;
}
/**
* Accepts an array of octets as the next portion of the message.
*/
EXP_FUNC void STDCALL MD5_Update(MD5_CTX *ctx, const uint8_t *msg,
int len)
{
uint32_t x;
int i, partLen;
/* Compute number of bytes mod 64 */
x = (uint32_t) ((ctx->count[0] >> 3) & 0x3F);
/* Update number of bits */
if ((ctx->count[0] += ((uint32_t) len << 3)) < ((uint32_t) len << 3)) {
ctx->count[1]++;
}
ctx->count[1] += ((uint32_t) len >> 29);
partLen = 64 - x;
/* Transform as many times as possible. */
if (len >= partLen) {
memcpy(&ctx->buffer[x], msg, partLen);
MD5Transform(ctx->state, ctx->buffer);
for (i = partLen; i + 63 < len; i += 64) {
MD5Transform(ctx->state, &msg[i]);
}
x = 0;
} else {
i = 0;
}
/* Buffer remaining input */
memcpy(&ctx->buffer[x], &msg[i], len - i);
}
/**
* Return the 128-bit message digest into the user's array
*/
EXP_FUNC void STDCALL MD5_Final(uint8_t *digest, MD5_CTX *ctx)
{
uint8_t bits[8];
uint32_t x, padLen;
/* Save number of bits */
Encode(bits, ctx->count, 8);
/* Pad out to 56 mod 64.
*/
x = (uint32_t) ((ctx->count[0] >> 3) & 0x3f);
padLen = (x < 56) ? (56 - x) : (120 - x);
MD5_Update(ctx, PADDING, padLen);
/* Append length (before padding) */
MD5_Update(ctx, bits, 8);
/* Store state in digest */
Encode(digest, ctx->state, MD5_SIZE);
}
/**
* MD5 basic transformation. Transforms state based on block.
*/
static void MD5Transform(uint32_t state[4], const uint8_t block[64])
{
uint32_t a = state[0], b = state[1], c = state[2], d = state[3], x[MD5_SIZE];
Decode(x, block, 64);
/* Round 1 */
FF(a, b, c, d, x[0], S11, 0xd76aa478); /* 1 */
FF(d, a, b, c, x[1], S12, 0xe8c7b756); /* 2 */
FF(c, d, a, b, x[2], S13, 0x242070db); /* 3 */
FF(b, c, d, a, x[3], S14, 0xc1bdceee); /* 4 */
FF(a, b, c, d, x[4], S11, 0xf57c0faf); /* 5 */
FF(d, a, b, c, x[5], S12, 0x4787c62a); /* 6 */
FF(c, d, a, b, x[6], S13, 0xa8304613); /* 7 */
FF(b, c, d, a, x[7], S14, 0xfd469501); /* 8 */
FF(a, b, c, d, x[8], S11, 0x698098d8); /* 9 */
FF(d, a, b, c, x[9], S12, 0x8b44f7af); /* 10 */
FF(c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
FF(b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
FF(a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
FF(d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
FF(c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
FF(b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
/* Round 2 */
GG(a, b, c, d, x[1], S21, 0xf61e2562); /* 17 */
GG(d, a, b, c, x[6], S22, 0xc040b340); /* 18 */
GG(c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
GG(b, c, d, a, x[0], S24, 0xe9b6c7aa); /* 20 */
GG(a, b, c, d, x[5], S21, 0xd62f105d); /* 21 */
GG(d, a, b, c, x[10], S22, 0x2441453); /* 22 */
GG(c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
GG(b, c, d, a, x[4], S24, 0xe7d3fbc8); /* 24 */
GG(a, b, c, d, x[9], S21, 0x21e1cde6); /* 25 */
GG(d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
GG(c, d, a, b, x[3], S23, 0xf4d50d87); /* 27 */
GG(b, c, d, a, x[8], S24, 0x455a14ed); /* 28 */
GG(a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
GG(d, a, b, c, x[2], S22, 0xfcefa3f8); /* 30 */
GG(c, d, a, b, x[7], S23, 0x676f02d9); /* 31 */
GG(b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
/* Round 3 */
HH(a, b, c, d, x[5], S31, 0xfffa3942); /* 33 */
HH(d, a, b, c, x[8], S32, 0x8771f681); /* 34 */
HH(c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
HH(b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
HH(a, b, c, d, x[1], S31, 0xa4beea44); /* 37 */
HH(d, a, b, c, x[4], S32, 0x4bdecfa9); /* 38 */
HH(c, d, a, b, x[7], S33, 0xf6bb4b60); /* 39 */
HH(b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
HH(a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
HH(d, a, b, c, x[0], S32, 0xeaa127fa); /* 42 */
HH(c, d, a, b, x[3], S33, 0xd4ef3085); /* 43 */
HH(b, c, d, a, x[6], S34, 0x4881d05); /* 44 */
HH(a, b, c, d, x[9], S31, 0xd9d4d039); /* 45 */
HH(d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
HH(c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
HH(b, c, d, a, x[2], S34, 0xc4ac5665); /* 48 */
/* Round 4 */
II(a, b, c, d, x[0], S41, 0xf4292244); /* 49 */
II(d, a, b, c, x[7], S42, 0x432aff97); /* 50 */
II(c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
II(b, c, d, a, x[5], S44, 0xfc93a039); /* 52 */
II(a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
II(d, a, b, c, x[3], S42, 0x8f0ccc92); /* 54 */
II(c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
II(b, c, d, a, x[1], S44, 0x85845dd1); /* 56 */
II(a, b, c, d, x[8], S41, 0x6fa87e4f); /* 57 */
II(d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
II(c, d, a, b, x[6], S43, 0xa3014314); /* 59 */
II(b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
II(a, b, c, d, x[4], S41, 0xf7537e82); /* 61 */
II(d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
II(c, d, a, b, x[2], S43, 0x2ad7d2bb); /* 63 */
II(b, c, d, a, x[9], S44, 0xeb86d391); /* 64 */
state[0] += a;
state[1] += b;
state[2] += c;
state[3] += d;
}
/**
* Encodes input (uint32_t) into output (uint8_t). Assumes len is
* a multiple of 4.
*/
static void Encode(uint8_t *output, uint32_t *input, uint32_t len)
{
uint32_t i, j;
for (i = 0, j = 0; j < len; i++, j += 4) {
output[j] = (uint8_t) (input[i] & 0xff);
output[j + 1] = (uint8_t) ((input[i] >> 8) & 0xff);
output[j + 2] = (uint8_t) ((input[i] >> 16) & 0xff);
output[j + 3] = (uint8_t) ((input[i] >> 24) & 0xff);
}
}
/**
* Decodes input (uint8_t) into output (uint32_t). Assumes len is
* a multiple of 4.
*/
static void Decode(uint32_t *output, const uint8_t *input, uint32_t len)
{
uint32_t i, j;
for (i = 0, j = 0; j < len; i++, j += 4) {
output[i] = ((uint32_t) input[j]) | (((uint32_t) input[j + 1]) << 8) | (((
uint32_t) input[j + 2]) << 16) | (((uint32_t) input[j + 3]) << 24);
}
}

View file

@ -0,0 +1,26 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#ifndef _MD5_H_
#define _MD5_H_
#include <stdint.h>
#if defined(__cplusplus) /* If this is a C++ compiler, use C linkage */
extern "C"
{
#endif
typedef struct {
uint32_t state[4]; /* state (ABCD) */
uint32_t count[2]; /* number of bits, modulo 2^64 (lsb first) */
uint8_t buffer[64]; /* input buffer */
} MD5_CTX;
void MD5_Init(MD5_CTX *ctx);
void MD5_Update(MD5_CTX *ctx, const uint8_t *msg, int len);
void MD5_Final(uint8_t *digest, MD5_CTX *ctx);
#if defined(__cplusplus) /* If this is a C++ compiler, use C linkage */
}
#endif
#endif

View file

@ -0,0 +1,851 @@
/*
* FILE: sha2.c
* AUTHOR: Aaron D. Gifford - http://www.aarongifford.com/
*
* Copyright (c) 2000-2001, Aaron D. Gifford
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTOR(S) BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: sha2.c,v 1.1 2001/11/08 00:01:51 adg Exp adg $
*/
#include <stdint.h>
#include <string.h>
extern uint32_t os_be32toh(uint32_t data);
extern uint32_t os_htobe32(uint32_t data);
extern uint64_t os_be64toh(uint64_t data);
extern uint64_t os_htobe64(uint64_t data);
/*** SHA-256/384/512 Various Length Definitions ***********************/
/*** SHA-256/384/512 Various Length Definitions ***********************/
#define SHA256_BLOCK_LENGTH 64
#define SHA256_DIGEST_LENGTH 32
#define SHA256_DIGEST_STRING_LENGTH (SHA256_DIGEST_LENGTH * 2 + 1)
#define SHA384_BLOCK_LENGTH 128
#define SHA384_DIGEST_LENGTH 48
#define SHA384_DIGEST_STRING_LENGTH (SHA384_DIGEST_LENGTH * 2 + 1)
#define SHA512_BLOCK_LENGTH 128
#define SHA512_DIGEST_LENGTH 64
#define SHA512_DIGEST_STRING_LENGTH (SHA512_DIGEST_LENGTH * 2 + 1)
/* NOTE: Most of these are in sha2.h */
#define SHA256_SHORT_BLOCK_LENGTH (SHA256_BLOCK_LENGTH - 8)
#define SHA384_SHORT_BLOCK_LENGTH (SHA384_BLOCK_LENGTH - 16)
#define SHA512_SHORT_BLOCK_LENGTH (SHA512_BLOCK_LENGTH - 16)
typedef uint8_t sha2_byte; /* Exactly 1 byte */
typedef uint32_t sha2_word32; /* Exactly 4 bytes */
typedef uint64_t sha2_word64; /* Exactly 8 bytes */
typedef struct _SHA256_CTX {
uint32_t state[8];
uint64_t bitcount;
uint8_t buffer[SHA256_BLOCK_LENGTH];
} SHA256_CTX;
typedef struct _SHA512_CTX {
uint64_t state[8];
uint64_t bitcount[2];
uint8_t buffer[SHA512_BLOCK_LENGTH];
} SHA512_CTX;
typedef SHA512_CTX SHA384_CTX;
static void SHA256_Init(SHA256_CTX *);
static void SHA256_Update(SHA256_CTX *, const uint8_t *, uint32_t);
static void SHA256_Final(uint8_t[SHA256_DIGEST_LENGTH], SHA256_CTX *);
static void SHA384_Init(SHA384_CTX *);
static void SHA384_Update(SHA384_CTX *, const uint8_t *, uint32_t);
static void SHA384_Final(uint8_t[SHA384_DIGEST_LENGTH], SHA384_CTX *);
static void SHA512_Init(SHA512_CTX *);
static void SHA512_Update(SHA512_CTX *, const uint8_t *, uint32_t);
static void SHA512_Final(uint8_t[SHA512_DIGEST_LENGTH], SHA512_CTX *);
/*
* Macro for incrementally adding the unsigned 64-bit integer n to the
* unsigned 128-bit integer (represented using a two-element array of
* 64-bit words):
*/
#define ADDINC128(w,n) { \
(w)[0] += (sha2_word64)(n); \
if ((w)[0] < (n)) { \
(w)[1]++; \
} \
}
#define MEMSET_BZERO(p,l) memset((p), 0, (l))
#define MEMCPY_BCOPY(d,s,l) memcpy((d), (s), (l))
/*** THE SIX LOGICAL FUNCTIONS ****************************************/
/*
* Bit shifting and rotation (used by the six SHA-XYZ logical functions:
*
* NOTE: The naming of R and S appears backwards here (R is a SHIFT and
* S is a ROTATION) because the SHA-256/384/512 description document
* (see http://csrc.nist.gov/cryptval/shs/sha256-384-512.pdf) uses this
* same "backwards" definition.
*/
/* Shift-right (used in SHA-256, SHA-384, and SHA-512): */
#define R(b,x) ((x) >> (b))
/* 32-bit Rotate-right (used in SHA-256): */
#define _S32(b,x) (((x) >> (b)) | ((x) << (32 - (b))))
/* 64-bit Rotate-right (used in SHA-384 and SHA-512): */
#define S64(b,x) (((x) >> (b)) | ((x) << (64 - (b))))
/* Two of six logical functions used in SHA-256, SHA-384, and SHA-512: */
#define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z)))
#define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
/* Four of six logical functions used in SHA-256: */
#define Sigma0_256(x) (_S32(2, (x)) ^ _S32(13, (x)) ^ _S32(22, (x)))
#define Sigma1_256(x) (_S32(6, (x)) ^ _S32(11, (x)) ^ _S32(25, (x)))
#define sigma0_256(x) (_S32(7, (x)) ^ _S32(18, (x)) ^ R(3 , (x)))
#define sigma1_256(x) (_S32(17, (x)) ^ _S32(19, (x)) ^ R(10, (x)))
/* Four of six logical functions used in SHA-384 and SHA-512: */
#define Sigma0_512(x) (S64(28, (x)) ^ S64(34, (x)) ^ S64(39, (x)))
#define Sigma1_512(x) (S64(14, (x)) ^ S64(18, (x)) ^ S64(41, (x)))
#define sigma0_512(x) (S64( 1, (x)) ^ S64( 8, (x)) ^ R( 7, (x)))
#define sigma1_512(x) (S64(19, (x)) ^ S64(61, (x)) ^ R( 6, (x)))
/*** INTERNAL FUNCTION PROTOTYPES *************************************/
/* NOTE: These should not be accessed directly from outside this
* library -- they are intended for private internal visibility/use
* only.
*/
static void SHA512_Last(SHA512_CTX *);
static void SHA256_Transform(SHA256_CTX *, const sha2_word32 *);
static void SHA512_Transform(SHA512_CTX *, const sha2_word64 *);
/*** SHA-XYZ INITIAL HASH VALUES AND CONSTANTS ************************/
/* Hash constant words K for SHA-256: */
static const sha2_word32 K256[64] = {
0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL,
0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL,
0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL,
0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL,
0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL,
0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL,
0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL,
0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL,
0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL,
0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL,
0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL,
0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL,
0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL
};
/* Initial hash value H for SHA-256: */
static const sha2_word32 sha256_initial_hash_value[8] = {
0x6a09e667UL,
0xbb67ae85UL,
0x3c6ef372UL,
0xa54ff53aUL,
0x510e527fUL,
0x9b05688cUL,
0x1f83d9abUL,
0x5be0cd19UL
};
/* Hash constant words K for SHA-384 and SHA-512: */
static const sha2_word64 K512[80] = {
0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL,
0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL,
0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,
0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL,
0xd807aa98a3030242ULL, 0x12835b0145706fbeULL,
0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL,
0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL,
0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL,
0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL,
0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL,
0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL,
0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL,
0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL,
0x06ca6351e003826fULL, 0x142929670a0e6e70ULL,
0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL,
0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL,
0x81c2c92e47edaee6ULL, 0x92722c851482353bULL,
0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL,
0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL,
0xd192e819d6ef5218ULL, 0xd69906245565a910ULL,
0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL,
0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL,
0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL,
0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL,
0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL,
0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL,
0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL,
0xca273eceea26619cULL, 0xd186b8c721c0c207ULL,
0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL,
0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL,
0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
0x28db77f523047d84ULL, 0x32caab7b40c72493ULL,
0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL,
0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL,
0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL
};
/* Initial hash value H for SHA-384 */
static const sha2_word64 sha384_initial_hash_value[8] = {
0xcbbb9d5dc1059ed8ULL,
0x629a292a367cd507ULL,
0x9159015a3070dd17ULL,
0x152fecd8f70e5939ULL,
0x67332667ffc00b31ULL,
0x8eb44a8768581511ULL,
0xdb0c2e0d64f98fa7ULL,
0x47b5481dbefa4fa4ULL
};
/* Initial hash value H for SHA-512 */
static const sha2_word64 sha512_initial_hash_value[8] = {
0x6a09e667f3bcc908ULL,
0xbb67ae8584caa73bULL,
0x3c6ef372fe94f82bULL,
0xa54ff53a5f1d36f1ULL,
0x510e527fade682d1ULL,
0x9b05688c2b3e6c1fULL,
0x1f83d9abfb41bd6bULL,
0x5be0cd19137e2179ULL
};
static inline int os_is_big_endian(void)
{
uint32_t data = 0xFF000000;
if (0xFF == *(uint8_t *) & data) {
return 1; //big endian
}
return 0; //little endian
}
//reverse byte order
static inline uint32_t reverse_32bit(uint32_t data)
{
data = (data >> 16) | (data << 16);
return ((data & 0xff00ff00UL) >> 8) | ((data & 0x00ff00ffUL) << 8);
}
uint32_t os_htole32(uint32_t data)
{
if (os_is_big_endian()) {
return reverse_32bit(data);
}
return data;
}
static inline uint64_t reverse_64bit(uint64_t data)
{
data = (data >> 32) | (data << 32);
data = ((data & 0xff00ff00ff00ff00ULL) >> 8) | ((data & 0x00ff00ff00ff00ffULL)
<< 8);
return ((data & 0xffff0000ffff0000ULL) >> 16) | ((data & 0x0000ffff0000ffffULL)
<< 16);
}
//big endian to host byte order
uint32_t os_be32toh(uint32_t data)
{
return os_htobe32(data);
}
//host byte order to big endian
uint32_t os_htobe32(uint32_t data)
{
if (os_is_big_endian()) {
return data;
}
return reverse_32bit(data);
}
//host to big endian
uint64_t os_htobe64(uint64_t data)
{
if (os_is_big_endian()) {
return data;
}
return reverse_64bit(data);
}
//big endian to host
uint64_t os_be64toh(uint64_t data)
{
return os_htobe64(data);
}
/*** SHA-256: *********************************************************/
static void SHA256_Init(SHA256_CTX *context)
{
if (context == (SHA256_CTX *) 0) {
return;
}
MEMCPY_BCOPY(context->state, sha256_initial_hash_value, SHA256_DIGEST_LENGTH);
MEMSET_BZERO(context->buffer, SHA256_BLOCK_LENGTH);
context->bitcount = 0;
}
static void SHA256_Transform(SHA256_CTX *context, const sha2_word32 *data)
{
sha2_word32 a, b, c, d, e, f, g, h, s0, s1;
sha2_word32 T1, T2, *W256;
int j;
W256 = (sha2_word32 *) context->buffer;
/* Initialize registers with the prev. intermediate value */
a = context->state[0];
b = context->state[1];
c = context->state[2];
d = context->state[3];
e = context->state[4];
f = context->state[5];
g = context->state[6];
h = context->state[7];
j = 0;
do {
/* Copy data while converting to host byte order */
W256[j] = os_htobe32(*data++);
/* Apply the SHA-256 compression function to update a..h */
T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + W256[j];
T2 = Sigma0_256(a) + Maj(a, b, c);
h = g;
g = f;
f = e;
e = d + T1;
d = c;
c = b;
b = a;
a = T1 + T2;
j++;
} while (j < 16);
do {
/* Part of the message block expansion: */
s0 = W256[(j + 1) & 0x0f];
s0 = sigma0_256(s0);
s1 = W256[(j + 14) & 0x0f];
s1 = sigma1_256(s1);
/* Apply the SHA-256 compression function to update a..h */
T1 = h + Sigma1_256(e) + Ch(e, f,
g) + K256[j] + (W256[j & 0x0f] += s1 + W256[(j + 9) & 0x0f] + s0);
T2 = Sigma0_256(a) + Maj(a, b, c);
h = g;
g = f;
f = e;
e = d + T1;
d = c;
c = b;
b = a;
a = T1 + T2;
j++;
} while (j < 64);
/* Compute the current intermediate hash value */
context->state[0] += a;
context->state[1] += b;
context->state[2] += c;
context->state[3] += d;
context->state[4] += e;
context->state[5] += f;
context->state[6] += g;
context->state[7] += h;
/* Clean up */
a = b = c = d = e = f = g = h = T1 = T2 = 0;
}
static void SHA256_Update(SHA256_CTX *context, const sha2_byte *data,
uint32_t len)
{
unsigned int os_freespace, usedspace;
if (len == 0) {
/* Calling with no data is valid - we do nothing */
return;
}
/* Sanity check: */
if (context == NULL || data == NULL) {
return;
}
usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH;
if (usedspace > 0) {
/* Calculate how much os_free space is available in the buffer */
os_freespace = SHA256_BLOCK_LENGTH - usedspace;
if (len >= os_freespace) {
/* Fill the buffer completely and process it */
MEMCPY_BCOPY(&context->buffer[usedspace], data, os_freespace);
context->bitcount += os_freespace << 3;
len -= os_freespace;
data += os_freespace;
SHA256_Transform(context, (sha2_word32 *) context->buffer);
} else {
/* The buffer is not yet full */
MEMCPY_BCOPY(&context->buffer[usedspace], data, len);
context->bitcount += len << 3;
/* Clean up: */
usedspace = os_freespace = 0;
return;
}
}
while (len >= SHA256_BLOCK_LENGTH) {
/* Process as many complete blocks as we can */
SHA256_Transform(context, (sha2_word32 *) data);
context->bitcount += SHA256_BLOCK_LENGTH << 3;
len -= SHA256_BLOCK_LENGTH;
data += SHA256_BLOCK_LENGTH;
}
if (len > 0) {
/* There's left-overs, so save 'em */
MEMCPY_BCOPY(context->buffer, data, len);
context->bitcount += len << 3;
}
/* Clean up: */
usedspace = os_freespace = 0;
}
static void SHA256_Final(sha2_byte digest[], SHA256_CTX *context)
{
sha2_word32 *d = (sha2_word32 *) digest;
unsigned int usedspace;
/* Sanity check: */
if (context == NULL) {
return;
}
/* If no digest buffer is passed, we don't bother doing this: */
if (digest != (sha2_byte *) 0) {
usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH;
context->bitcount = os_htobe64(context->bitcount);
if (usedspace > 0) {
/* Begin padding with a 1 bit: */
context->buffer[usedspace++] = 0x80;
if (usedspace <= SHA256_SHORT_BLOCK_LENGTH) {
/* Set-up for the last transform: */
MEMSET_BZERO(&context->buffer[usedspace],
SHA256_SHORT_BLOCK_LENGTH - usedspace);
} else {
if (usedspace < SHA256_BLOCK_LENGTH) {
MEMSET_BZERO(&context->buffer[usedspace], SHA256_BLOCK_LENGTH - usedspace);
}
/* Do second-to-last transform: */
SHA256_Transform(context, (sha2_word32 *) context->buffer);
/* And set-up for the last transform: */
MEMSET_BZERO(context->buffer, SHA256_SHORT_BLOCK_LENGTH);
}
} else {
/* Set-up for the last transform: */
MEMSET_BZERO(context->buffer, SHA256_SHORT_BLOCK_LENGTH);
/* Begin padding with a 1 bit: */
*context->buffer = 0x80;
}
/* Set the bit count: */
*(sha2_word64 *) & context->buffer[SHA256_SHORT_BLOCK_LENGTH] =
context->bitcount;
/* Final transform: */
SHA256_Transform(context, (sha2_word32 *) context->buffer);
{
/* Convert TO host byte order */
int j;
for (j = 0; j < 8; j++) {
context->state[j] = os_be32toh(context->state[j]);
*d++ = context->state[j];
}
}
}
/* Clean up state data: */
MEMSET_BZERO(context, sizeof(*context));
usedspace = 0;
}
/*** SHA-512: *********************************************************/
static void SHA512_Init(SHA512_CTX *context)
{
if (context == (SHA512_CTX *) 0) {
return;
}
MEMCPY_BCOPY(context->state, sha512_initial_hash_value, SHA512_DIGEST_LENGTH);
MEMSET_BZERO(context->buffer, SHA512_BLOCK_LENGTH);
context->bitcount[0] = context->bitcount[1] = 0;
}
static void SHA512_Transform(SHA512_CTX *context, const sha2_word64 *data)
{
sha2_word64 a, b, c, d, e, f, g, h, s0, s1;
sha2_word64 T1, T2, *W512 = (sha2_word64 *) context->buffer;
int j;
/* Initialize registers with the prev. intermediate value */
a = context->state[0];
b = context->state[1];
c = context->state[2];
d = context->state[3];
e = context->state[4];
f = context->state[5];
g = context->state[6];
h = context->state[7];
j = 0;
do {
/* Convert TO host byte order */
W512[j] = os_be64toh(*data++);
T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + W512[j];
T2 = Sigma0_512(a) + Maj(a, b, c);
h = g;
g = f;
f = e;
e = d + T1;
d = c;
c = b;
b = a;
a = T1 + T2;
j++;
} while (j < 16);
do {
/* Part of the message block expansion: */
s0 = W512[(j + 1) & 0x0f];
s0 = sigma0_512(s0);
s1 = W512[(j + 14) & 0x0f];
s1 = sigma1_512(s1);
/* Apply the SHA-512 compression function to update a..h */
T1 = h + Sigma1_512(e) + Ch(e, f,
g) + K512[j] + (W512[j & 0x0f] += s1 + W512[(j + 9) & 0x0f] + s0);
T2 = Sigma0_512(a) + Maj(a, b, c);
h = g;
g = f;
f = e;
e = d + T1;
d = c;
c = b;
b = a;
a = T1 + T2;
j++;
} while (j < 80);
/* Compute the current intermediate hash value */
context->state[0] += a;
context->state[1] += b;
context->state[2] += c;
context->state[3] += d;
context->state[4] += e;
context->state[5] += f;
context->state[6] += g;
context->state[7] += h;
/* Clean up */
a = b = c = d = e = f = g = h = T1 = T2 = 0;
}
static void SHA512_Update(SHA512_CTX *context, const sha2_byte *data,
uint32_t len)
{
unsigned int os_freespace, usedspace;
if (len == 0) {
/* Calling with no data is valid - we do nothing */
return;
}
/* Sanity check: */
if (context == NULL || data == NULL) {
return;
}
usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH;
if (usedspace > 0) {
/* Calculate how much os_free space is available in the buffer */
os_freespace = SHA512_BLOCK_LENGTH - usedspace;
if (len >= os_freespace) {
/* Fill the buffer completely and process it */
MEMCPY_BCOPY(&context->buffer[usedspace], data, os_freespace);
ADDINC128(context->bitcount, os_freespace << 3);
len -= os_freespace;
data += os_freespace;
SHA512_Transform(context, (sha2_word64 *) context->buffer);
} else {
/* The buffer is not yet full */
MEMCPY_BCOPY(&context->buffer[usedspace], data, len);
ADDINC128(context->bitcount, len << 3);
/* Clean up: */
usedspace = os_freespace = 0;
return;
}
}
while (len >= SHA512_BLOCK_LENGTH) {
/* Process as many complete blocks as we can */
SHA512_Transform(context, (sha2_word64 *) data);
ADDINC128(context->bitcount, SHA512_BLOCK_LENGTH << 3);
len -= SHA512_BLOCK_LENGTH;
data += SHA512_BLOCK_LENGTH;
}
if (len > 0) {
/* There's left-overs, so save 'em */
MEMCPY_BCOPY(context->buffer, data, len);
ADDINC128(context->bitcount, len << 3);
}
/* Clean up: */
usedspace = os_freespace = 0;
}
static void SHA512_Last(SHA512_CTX *context)
{
unsigned int usedspace;
usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH;
context->bitcount[0] = os_htobe64(context->bitcount[0]);
context->bitcount[1] = os_htobe64(context->bitcount[1]);
if (usedspace > 0) {
/* Begin padding with a 1 bit: */
context->buffer[usedspace++] = 0x80;
if (usedspace <= SHA512_SHORT_BLOCK_LENGTH) {
/* Set-up for the last transform: */
MEMSET_BZERO(&context->buffer[usedspace],
SHA512_SHORT_BLOCK_LENGTH - usedspace);
} else {
if (usedspace < SHA512_BLOCK_LENGTH) {
MEMSET_BZERO(&context->buffer[usedspace], SHA512_BLOCK_LENGTH - usedspace);
}
/* Do second-to-last transform: */
SHA512_Transform(context, (sha2_word64 *) context->buffer);
/* And set-up for the last transform: */
MEMSET_BZERO(context->buffer, SHA512_BLOCK_LENGTH - 2);
}
} else {
/* Prepare for final transform: */
MEMSET_BZERO(context->buffer, SHA512_SHORT_BLOCK_LENGTH);
/* Begin padding with a 1 bit: */
*context->buffer = 0x80;
}
/* Store the length of input data (in bits): */
*(sha2_word64 *) & context->buffer[SHA512_SHORT_BLOCK_LENGTH] =
context->bitcount[1];
*(sha2_word64 *) & context->buffer[SHA512_SHORT_BLOCK_LENGTH + 8] =
context->bitcount[0];
/* Final transform: */
SHA512_Transform(context, (sha2_word64 *) context->buffer);
}
static void SHA512_Final(sha2_byte digest[], SHA512_CTX *context)
{
sha2_word64 *d = (sha2_word64 *) digest;
/* Sanity check: */
if (context == NULL) {
return;
}
/* If no digest buffer is passed, we don't bother doing this: */
if (digest != (sha2_byte *) 0) {
SHA512_Last(context);
/* Save the hash data for output: */
{
/* Convert TO host byte order */
int j;
for (j = 0; j < 8; j++) {
context->state[j] = os_be64toh(context->state[j]);
*d++ = context->state[j];
}
}
}
/* Zero out state data */
MEMSET_BZERO(context, sizeof(*context));
}
/*** SHA-384: *********************************************************/
static void SHA384_Init(SHA384_CTX *context)
{
if (context == (SHA384_CTX *) 0) {
return;
}
MEMCPY_BCOPY(context->state, sha384_initial_hash_value, SHA512_DIGEST_LENGTH);
MEMSET_BZERO(context->buffer, SHA384_BLOCK_LENGTH);
context->bitcount[0] = context->bitcount[1] = 0;
}
static void SHA384_Update(SHA384_CTX *context, const sha2_byte *data,
uint32_t len)
{
SHA512_Update((SHA512_CTX *) context, data, len);
}
static void SHA384_Final(sha2_byte digest[], SHA384_CTX *context)
{
sha2_word64 *d = (sha2_word64 *) digest;
/* Sanity check: */
if (context == NULL) {
return;
}
/* If no digest buffer is passed, we don't bother doing this: */
if (digest != (sha2_byte *) 0) {
SHA512_Last((SHA512_CTX *) context);
/* Save the hash data for output: */
{
/* Convert TO host byte order */
int j;
for (j = 0; j < 6; j++) {
context->state[j] = os_be64toh(context->state[j]);
*d++ = context->state[j];
}
}
}
/* Zero out state data */
MEMSET_BZERO(context, sizeof(context));
}
#if 0
/*
* Constant used by SHA256/384/512_End() functions for converting the
* digest to a readable hexadecimal character string:
*/
static const char *sha2_hex_digits = "0123456789abcdef";
static char *SHA256_End(SHA256_CTX *context, char buffer[])
{
sha2_byte digest[SHA256_DIGEST_LENGTH], *d = digest;
int i;
/* Sanity check: */
OS_ASSERT(context != (SHA256_CTX *) 0, NULL);
if (buffer != (char *)0) {
SHA256_Final(digest, context);
for (i = 0; i < SHA256_DIGEST_LENGTH; i++) {
*buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4];
*buffer++ = sha2_hex_digits[*d & 0x0f];
d++;
}
*buffer = (char)0;
} else {
MEMSET_BZERO(context, sizeof(context));
}
MEMSET_BZERO(digest, SHA256_DIGEST_LENGTH);
return buffer;
}
static char *SHA512_End(SHA512_CTX *context, char buffer[])
{
sha2_byte digest[SHA512_DIGEST_LENGTH], *d = digest;
int i;
/* Sanity check: */
OS_ASSERT(context != (SHA512_CTX *) 0, NULL);
if (buffer != (char *)0) {
SHA512_Final(digest, context);
for (i = 0; i < SHA512_DIGEST_LENGTH; i++) {
*buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4];
*buffer++ = sha2_hex_digits[*d & 0x0f];
d++;
}
*buffer = (char)0;
} else {
MEMSET_BZERO(context, sizeof(context));
}
MEMSET_BZERO(digest, SHA512_DIGEST_LENGTH);
return buffer;
}
static char *SHA384_End(SHA384_CTX *context, char buffer[])
{
sha2_byte digest[SHA384_DIGEST_LENGTH], *d = digest;
int i;
/* Sanity check: */
OS_ASSERT(context != (SHA384_CTX *) 0, NULL);
if (buffer != (char *)0) {
SHA384_Final(digest, context);
for (i = 0; i < SHA384_DIGEST_LENGTH; i++) {
*buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4];
*buffer++ = sha2_hex_digits[*d & 0x0f];
d++;
}
*buffer = (char)0;
} else {
MEMSET_BZERO(context, sizeof(context));
}
MEMSET_BZERO(digest, SHA384_DIGEST_LENGTH);
return buffer;
}
#endif

View file

@ -0,0 +1,8 @@
src = Split('''
CheckSumUtils.c
crc.c
digest_algorithm.c
md5.c
''')
component = aos_component('digest_algorithm', src)

View file

@ -0,0 +1,452 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#include <aos/aos.h>
#include "hashtable.h"
#define MODULE "hashtable"
/*the hashtable hander*/
typedef struct {
int cnt;//the count of hashtable items .
aos_mutex_t lock;
ht_item_t *item;
} ht_t;
//refs to: https://en.wikipedia.org/wiki/Jenkins_hash_function
static unsigned int _hash_func(const unsigned char *key, unsigned int length)
{
unsigned int i = 0;
unsigned int hash = 0;
while (i != length) {
hash += key[i++];
hash += hash << 10;
hash ^= hash >> 6;
}
hash += hash << 3;
hash ^= hash >> 11;
hash += hash << 15;
return hash;
}
/**
* @brief hash table module initiation.
*
* @param[in] max_cnt: the count of hashtable items you want.
*
* @retval hashtable hander on success, otherwise NULL will be returned
*/
void *ht_init(int max_cnt)
{
ht_t *p = NULL;
int len = max_cnt * sizeof(ht_item_t);
if (max_cnt <= 0) {
return NULL;
}
p = aos_malloc(sizeof(ht_t));
if (NULL == p) {
return NULL;
}
memset(p, 0, sizeof(ht_t));
p->item = aos_malloc(len);
if (NULL == p->item) {
aos_free(p);
return NULL;
}
memset(p->item, 0, len);
aos_mutex_new(&p->lock);
p->cnt = max_cnt;
//LOGD(MODULE,"create hashtable : <malloc>%p, item: <malloc>: %p\n", p, p->item);
return p;
}
/**
* @brief lock the @ht hashtable .
*
* @param[in] ht: the hander of hashtable.
*
*/
void ht_lock(void *ht)
{
ht_t *p = (ht_t *)ht;
if (p) {
aos_mutex_lock(&p->lock, AOS_WAIT_FOREVER);
}
}
/**
* @brief unlock the @ht hashtable after you find/add/delete/delete_r.
*
* @param[in] ht: the hander of hashtable.
*/
void ht_unlock(void *ht)
{
ht_t *p = (ht_t *)ht;
if (p) {
aos_mutex_unlock(&p->lock);
}
}
static ht_item_t *_ht_find_lockless(void *ht, const void *key,
unsigned int key_len)
{
unsigned int pos = 0;
ht_t *pt = (ht_t *)ht;
if (!ht || !key || key_len <= 0) {
return NULL;
}
pos = _hash_func((const unsigned char *)key, key_len) % pt->cnt;
return (pt->item + pos);//users should check the pointer to get all the values.
}
/**
* @brief find the item in the @ht whose key is @key in lockless mode, this maybe
* more efficient.
*
* @param[in] ht: the hander of hashtable.
* key: the key of the item you want to find.
* key_len: the length of @key, if @key is string, @key_len must be strlen(key)+1.
* @param[out]val: the memory to store the found val.
* size_val: the size of returned val
* @retval the pointer to value on success, otherwise NULL will be returned
*/
void *ht_find_lockless(void *ht, const void *key, unsigned int key_len,
void *val, int *size_val)
{
ht_item_t *p = _ht_find_lockless(ht, key, key_len);
void *ret = NULL;
while (p) {
if (p->key && !memcmp(p->key, key, key_len)) {
ret = p->val;
break;
}
p = p->next;
}
if (ret && val && size_val) {
memcpy(val, ret, p->size_val > *size_val ? *size_val : p->size_val);
*size_val = p->size_val;
}
return ret;
}
/**
* @brief find the item in the @ht whose key is @key .
*
* @param[in] ht: the hander of hashtable.
* key: the key of the item you want to find.
* key_len: the length of @key, if @key is string, @key_len must be strlen(key)+1.
* @param[out]val: the memory to store the found val.
* size_val: the size of returned val
* @retval the pointer to @ht_item_t on success, otherwise NULL will be returned
*/
void *ht_find(void *ht, const void *key, unsigned int key_len, void *val,
int *size_val)
{
void *ret = NULL;
ht_lock(ht);
ret = ht_find_lockless(ht, key, key_len, val, size_val);
ht_unlock(ht);
return ret;
}
/**
* @brief add the item in the @ht whose key is @key and value is @val in lockless mode.
*
* @param[in] ht: the hander of hashtable.
* key: the key of the item you want to add.
* key_len: the length of @key.
* val: the value of the item you want to add.
* size_val: the length of the @val.
* @note: the @key and @val will be re-malloced and stored in the hashtable.
* @retval 0 on success, otherwise -1 will be returned
*/
int ht_add_lockless(void *ht, const void *key, unsigned int len_key,
const void *val, unsigned int size_val)
{
ht_item_t *p_item = NULL;
ht_item_t *p_tmp = NULL;
ht_item_t *new_tb = NULL;
if (!ht || !key || !val || len_key <= 0 || size_val <= 0) {
return -1;
}
p_item = _ht_find_lockless(ht, key, len_key);
if (!p_item->key) {
p_item->key = aos_malloc(len_key);
if (!p_item->key) {
return -1;
}
memcpy(p_item->key, key, len_key);
p_item->val = aos_malloc(size_val);
if (!p_item->val) {
aos_free(p_item->key);
p_item->key = NULL;
return -1;
}
memcpy(p_item->val, val, size_val);
p_item->size_val = size_val;
//LOGD(MODULE,"key: <aos_malloc>%p, val: <aos_malloc>%p\n", p_item->key, p_item->val);
return 0;
}
//conflict: add to it's next item in the list.
p_tmp = p_item;
while (p_tmp) {
if (NULL != p_tmp->key && !memcmp(p_tmp->key, key, len_key)) {
//LOGD(MODULE,"repeated key , aos_free last val: %p, aos_malloc\n", p_tmp->val);
aos_free(p_tmp->val);
p_tmp->val = NULL;
p_tmp->val = aos_malloc(size_val);
if (!p_item->val) {
aos_free(p_tmp);
LOGE(MODULE, "failed to aos_malloc new value.\n");
return -1;
}
p_item->size_val = size_val;
memcpy(p_item->val, val, size_val);
return 0;//repeated key , just update it
}
p_item = p_tmp;
p_tmp = p_tmp->next;
}
new_tb = (ht_item_t *)aos_malloc(sizeof(ht_item_t));
if (!new_tb) {
return -1;
}
memset(new_tb, 0, sizeof(ht_item_t));
new_tb->key = aos_malloc(len_key);
if (!new_tb->key) {
aos_free(new_tb);
return -1;
}
memcpy(new_tb->key, key, len_key);
new_tb->val = aos_malloc(size_val);
if (!new_tb->val) {
aos_free(new_tb->key);
aos_free(new_tb);
return -1;
}
new_tb->size_val = size_val;
memcpy(new_tb->val, val, size_val);
p_item->next = new_tb;
//LOGD(MODULE,"conflict key: <aos_malloc>%p, val: <aos_malloc>%p,node: <aos_malloc>%p, before: %p\n", new_tb->key, new_tb->val, new_tb, p_item);
return 0;
}
/**
* @brief add the item in the @ht whose key is @key and value is @val.
*
* @param[in] ht: the hander of hashtable.
* key: the key of the item you want to add.
* key_len: the length of @key.
* val: the value of the item you want to add.
* size_val: the length of the @val.
* @note: the @key and @val will be re-malloced and stored in the hashtable.
* @retval 0 on success, otherwise -1 will be returned
*/
int ht_add(void *ht, const void *key, unsigned int len_key, const void *val,
unsigned int size_val)
{
int ret = 0;
ht_lock(ht);
ret = ht_add_lockless(ht, key, len_key, val, size_val);
ht_unlock(ht);
return ret;
}
static int _ht_del_node(void *ht_item, const void *key, unsigned int len_key)
{
ht_item_t *p_tmp = NULL;
ht_item_t *next = NULL;
ht_item_t *parent = NULL; // the root node or previous node
int flag = 0;
int ret = -1;
if (!ht_item) {
return ret;
}
parent = (ht_item_t *)ht_item;
while (parent) {
if (parent->key && parent->val &&
(!key || !memcmp(parent->key, key, len_key))) {
next = parent->next;//store its next item befroe aos_free.
//LOGD(MODULE,"del key: <aos_free>%p, val: <aos_free>%p,node: %p ,<%s>current: %p, next: %p\n",
// parent->key, parent->val,!flag ? NULL : parent, !flag ? "" : "aos_free", parent, next);
aos_free(parent->key);
parent->key = NULL;
aos_free(parent->val);
parent->val = NULL;
ret = 0;
if (1 == flag) {//just aos_free the added item not the root item.
aos_free(parent);
p_tmp->next = next;
} else {
p_tmp = parent;
}
if (key) {
break;
}
parent = next;
} else {
p_tmp = parent;
parent = parent->next;
}
flag = 1;
}
return ret;
}
/**
* @brief delete the items in the @ht whose key is @key in lockless mode.
*
* @param[in] ht: the hander of hashtable.
* key: the key of the item you want to delete.
* key_len: the length of @key.
* @note: the @key and @val will be freed in the hashtable when found.
* @retval 0 on success, otherwise -1 will be returned
*/
int ht_del_lockless(void *ht, const void *key, unsigned int len_key)
{
return _ht_del_node(_ht_find_lockless(ht, key, len_key), key, len_key);
}
/**
* @brief delete the items in the @ht whose key is @key.
*
* @param[in] ht: the hander of hashtable.
* key: the key of the item you want to delete.
* key_len: the length of @key.
* @note: the @key and @val will be freed in the hashtable when found.
* @retval 0 on success, otherwise -1 will be returned
*/
int ht_del(void *ht, const void *key, unsigned int len_key)
{
int ret = 0;
ht_lock(ht);
ret = ht_del_lockless(ht, key, len_key);
ht_unlock(ht);
return ret;
}
/**
* @brief polling the hashtable @ht and invoke the inte_func @func
*
* @param[in] ht: the hander of hashtable.
* @param[in] func: the deal function.
*
*/
void ht_iterator_lockless(void *ht, iter_func func, void *extra)
{
int i = 0;
ht_t *pt = ht;
ht_item_t *item = NULL;
if (!pt || !func) {
return;
}
for (i = 0; i < pt->cnt; i++) {
item = pt->item + i;
while (item) {
if (item->key && item->val) {
func(item->key, item->val, extra);
}
item = item->next;
}
}
}
/**
* @brief delete all the items in the @ht.
*
* @param[in] ht: the hander of hashtable.
*
* @note: the @key and @val will be freed in the hashtable.
* @retval 0 on success, otherwise -1 will be returned
*/
int ht_clear_lockless(void *ht)
{
ht_t *pt = ht;
int i = 0;
if (!ht) {
return -1;
}
for (i = 0; i < pt->cnt; i++) {
_ht_del_node(pt->item + i, NULL, 0);
}
return 0;
}
/**
* @brief delete all the items in the @ht.
*
* @param[in] ht: the hander of hashtable.
*
* @note: the @key and @val will be freed in the hashtable.
* @retval 0 on success, otherwise -1 will be returned
*/
int ht_clear(void *ht)
{
int ret = 0;
ht_lock(ht);
ret = ht_clear_lockless(ht);
ht_unlock(ht);
return ret;
}
/**
* @brief delete all the items in the @ht and release memory.
*
* @param[in] ht: the hander of hashtable.
*
* @retval 0 on success, otherwise -1 will be returned
*/
int ht_destroy(void *ht)
{
ht_t *pt = (ht_t *)ht;
if (!pt) {
return -1;
}
ht_lock(pt);
ht_clear_lockless(pt);
//LOGD(MODULE,"destroy hashtable: <aos_free>%p. <aos_free>%p \n", pt, pt->item);
aos_free(pt->item);
ht_unlock(pt);
aos_mutex_free(&pt->lock);
aos_free(pt);
return 0;
}

View file

@ -0,0 +1,177 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#ifndef __HASH_TABLE__
#define __HASH_TABLE__
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "aos/aos.h"
#if defined(__cplusplus) /* If this is a C++ compiler, use C linkage */
extern "C" {
#endif
typedef struct hash_item {
void *key;
void *val;
int size_val;
struct hash_item *next;
} ht_item_t;
/**
* @brief hash table module initiation.
*
* @param[in] max_cnt: the count of hashtable items you want.
*
* @retval hashtable hander on success, otherwise NULL will be returned
*/
void *ht_init(int max_cnt);
/**
* @brief lock the @ht hashtable. you may invoke this interface when you
* find/add/delete hashtable in lockless mode.
*
* @param[in] ht: the hander of hashtable.
*
*/
void ht_lock(void *ht);
/**
* @brief unlock the @ht hashtable.
*
* @param[in] ht: the hander of hashtable.
*/
void ht_unlock(void *ht);
/**
* @brief find the item in the @ht whose key is @key in lockless mode, this maybe
* more efficient.
*
* @param[in] ht: the hander of hashtable.
* key: the key of the item you want to find.
* key_len: the length of @key, if @key is string, @key_len must be strlen(key)+1.
* @param[out]val: the memory to store the found val.
* size_val: the size of returned val
* @retval the pointer to value on success, otherwise NULL will be returned
*/
void *ht_find_lockless(void *ht, const void *key, unsigned int key_len,
void *val, int *size_val);
/**
* @brief find the item in the @ht whose key is @key .
*
* @param[in] ht: the hander of hashtable.
* key: the key of the item you want to find.
* key_len: the length of @key, if @key is string, @key_len must be strlen(key)+1.
* @param[out]val: the memory to store the found val.
* size_val: the size of returned val
* @retval the pointer to @ht_item_t on success, otherwise NULL will be returned
*/
void *ht_find(void *ht, const void *key, unsigned int key_len, void *val,
int *size_val);
/**
* @brief add the item in the @ht whose key is @key and value is @val in lockless
* mode, this maybe more efficient.
*
* @param[in] ht: the hander of hashtable.
* key: the key of the item you want to add.
* key_len: the length of @key, if @key is string, @key_len must be strlen(key)+1.
* val: the value of the item you want to add.
* size_val: the length of the @val, if @val is string, @size_val must be strlen(val)+1.
* @note: the @key and @val will be re-malloced and stored in the hashtable.
* @retval 0 on success, otherwise -1 will be returned
*/
int ht_add_lockless(void *ht, const void *key, unsigned int len_key,
const void *val, unsigned int size_val);
/**
* @brief add the item in the @ht whose key is @key and value is @val.
*
* @param[in] ht: the hander of hashtable.
* key: the key of the item you want to add.
* key_len: the length of @key, if @key is string, @key_len must be strlen(key)+1.
* val: the value of the item you want to add.
* size_val: the length of the @val, if @val is string, @size_val must be strlen(val)+1.
* @note: the @key and @val will be re-malloced and stored in the hashtable.
* @retval 0 on success, otherwise -1 will be returned
*/
int ht_add(void *ht, const void *key, unsigned int len_key, const void *val,
unsigned int size_val);
/**
* @brief delete the items in the @ht whose key is @key in lockless mode.
*
* @param[in] ht: the hander of hashtable.
* key: the key of the item you want to delete.
* key_len: the length of @key, if @key is string, @key_len must be strlen(key)+1.
* @note: the @key and @val will be freed in the hashtable when found.
* @retval 0 on success, otherwise -1 will be returned
*/
int ht_del_lockless(void *ht, const void *key, unsigned int len_key);
/**
* @brief delete the items in the @ht whose key is @key.
*
* @param[in] ht: the hander of hashtable.
* key: the key of the item you want to delete.
* key_len: the length of @key, if @key is string, @key_len must be strlen(key)+1.
* @note: the @key and @val will be freed in the hashtable when found.
* @note: the @key and @val will be freed in the hashtable when found, this interface delete all the items whose key
* is matched, compared to @ht_del_strict.
* @retval 0 on success, otherwise -1 will be returned
*/
int ht_del(void *ht, const void *key, unsigned int len_key);
/*the function to be invoked while polling the hashtable*/
typedef void *(*iter_func)(void *key, void *val, void *extra);
/**
* @brief polling the hashtable @ht and invoke the inte_func @func
*
* @param[in] ht: the hander of hashtable.
* @param[in] func: the deal function.
*
*/
void ht_iterator_lockless(void *ht, iter_func func, void *extra);
/**
* @brief delete all the items in the @ht in lockless mode.
*
* @param[in] ht: the hander of hashtable.
*
* @note: the @key and @val will be freed in the hashtable.
* @retval 0 on success, otherwise -1 will be returned
*/
int ht_clear_lockless(void *ht);
/**
* @brief delete all the items in the @ht.
*
* @param[in] ht: the hander of hashtable.
*
* @note: the @key and @val will be freed in the hashtable.
* @retval 0 on success, otherwise -1 will be returned
*/
int ht_clear(void *ht);
/**
* @brief delete all the items in the @ht and release memory.
*
* @param[in] ht: the hander of hashtable.
*
* @retval 0 on success, otherwise -1 will be returned
*/
int ht_destroy(void *ht);
#if defined(__cplusplus) /* If this is a C++ compiler, use C linkage */
}
#endif
#endif

View file

@ -0,0 +1,6 @@
NAME := hashtable
$(NAME)_TYPE := share
$(NAME)_SOURCES := hashtable.c
$(NAME)_INCLUDES := ../../framework/protocol/alink/os/
GLOBAL_INCLUDES += .

View file

@ -0,0 +1,6 @@
src = Split('''
hashtable.c
''')
component = aos_component('hashtable', src)
component.add_includes('../../framework/protocol/alink/os/')

View file

@ -0,0 +1,90 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#pragma once
#include <stddef.h>
#ifdef __cplusplus
extern "C"
{
#endif
/******************************************************
* Macros
******************************************************/
#ifndef WEAK
#ifndef __MINGW32__
#define WEAK __attribute__((weak))
#else
/* MinGW doesn't support weak */
#define WEAK
#endif
#endif
#ifndef USED
#define USED __attribute__((used))
#endif
#ifndef MAY_BE_UNUSED
#define MAY_BE_UNUSED __attribute__((unused))
#endif
#ifndef NORETURN
#define NORETURN __attribute__((noreturn))
#endif
#ifndef ALIGNED
#define ALIGNED(size) __attribute__((aligned(size)))
#endif
#ifndef SECTION
#define SECTION(name) __attribute__((section(name)))
#endif
#ifndef NEVER_INLINE
#define NEVER_INLINE __attribute__((noinline))
#endif
#ifndef ALWAYS_INLINE
#define ALWAYS_INLINE __attribute__((always_inline))
#endif
/******************************************************
* Constants
******************************************************/
/******************************************************
* Enumerations
******************************************************/
/******************************************************
* Type Definitions
******************************************************/
/******************************************************
* Structures
******************************************************/
/******************************************************
* Global Variables
******************************************************/
/******************************************************
* Function Declarations
******************************************************/
void *memrchr( const void *s, int c, size_t n );
/* Windows doesn't come with support for strlcpy */
#ifdef WIN32
size_t strlcpy (char *dest, const char *src, size_t size);
#endif /* WIN32 */
#ifdef __cplusplus
} /* extern "C" */
#endif

View file

@ -0,0 +1,128 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#include <string.h>
#include <stdio.h>
#include <sys/time.h>
#include "k_config.h"
int errno;
#if defined (__CC_ARM) && defined(__MICROLIB)
void __aeabi_assert(const char *expr, const char *file, int line)
{
while (1);
}
extern long long krhino_sys_time_get(void);
int gettimeofday(struct timeval *tv, void *tzp)
{
uint64_t t = krhino_sys_time_get();
tv->tv_sec = t / 1000;
tv->tv_usec = (t % 1000) * 1000;
return 0;
}
#if (RHINO_CONFIG_MM_TLF > 0)
#define AOS_UNSIGNED_INT_MSB (1u << (sizeof(unsigned int) * 8 - 1))
extern void *aos_malloc(unsigned int size);
extern void aos_alloc_trace(void *addr, size_t allocator);
extern void aos_free(void *mem);
extern void *aos_realloc(void *mem, unsigned int size);
extern int32_t aos_uart_send(void *data, uint32_t size, uint32_t timeout);
void *malloc(size_t size)
{
void *mem;
#if (RHINO_CONFIG_MM_DEBUG > 0u && RHINO_CONFIG_GCC_RETADDR > 0u)
mem = aos_malloc(size | AOS_UNSIGNED_INT_MSB);
#else
mem = aos_malloc(size);
#endif
return mem;
}
void free(void *mem)
{
aos_free(mem);
}
void *realloc(void *old, size_t newlen)
{
void *mem;
#if (RHINO_CONFIG_MM_DEBUG > 0u && RHINO_CONFIG_GCC_RETADDR > 0u)
mem = aos_realloc(old, newlen | AOS_UNSIGNED_INT_MSB);
#else
mem = aos_realloc(old, newlen);
#endif
return mem;
}
void *calloc(size_t len, size_t elsize)
{
void *mem;
#if (RHINO_CONFIG_MM_DEBUG > 0u && RHINO_CONFIG_GCC_RETADDR > 0u)
mem = aos_malloc((elsize * len) | AOS_UNSIGNED_INT_MSB);
#else
mem = aos_malloc(elsize * len);
#endif
if (mem) {
memset(mem, 0, elsize * len);
}
return mem;
}
char * strdup(const char *s)
{
size_t len = strlen(s) +1;
void *dup_str = aos_malloc(len);
if (dup_str == NULL)
return NULL;
return (char *)memcpy(dup_str, s, len);
}
#pragma weak fputc
int fputc(int ch, FILE *f)
{
/* Send data. */
return aos_uart_send((uint8_t *)(&ch), 1, 1000);
}
#endif
//referred from ota_socket.o
void bzero()
{
}
//referred from ssl_cli.o
time_t time(time_t *t)
{
return 0;
}
//referred from aos_network.o
int accept(int sock, long *addr, long *addrlen)
{
return 0;
}
int listen(int sock, int backlog)
{
return 0;
}
//referred from timing.o
unsigned int alarm(unsigned int seconds)
{
return 0;
}
#endif

View file

@ -0,0 +1,5 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#include "sys/fcntl.h"

View file

@ -0,0 +1,157 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#ifndef _SYS_ERRNO_H__
#define _SYS_ERRNO_H__
#define EPERM 1 /* Operation not permitted */
#define ENOENT 2 /* No such file or directory */
#define ESRCH 3 /* No such process */
#define EINTR 4 /* Interrupted system call */
#define EIO 5 /* I/O error */
#define ENXIO 6 /* No such device or address */
#define E2BIG 7 /* Arg list too long */
#define ENOEXEC 8 /* Exec format error */
#define EBADF 9 /* Bad file number */
#define ECHILD 10 /* No child processes */
#define EAGAIN 11 /* Try again */
#define ENOMEM 12 /* Out of memory */
#define EACCES 13 /* Permission denied */
#define EFAULT 14 /* Bad address */
#define ENOTBLK 15 /* Block device required */
#define EBUSY 16 /* Device or resource busy */
#define EEXIST 17 /* File exists */
#define EXDEV 18 /* Cross-device link */
#define ENODEV 19 /* No such device */
#define ENOTDIR 20 /* Not a directory */
#define EISDIR 21 /* Is a directory */
#define EINVAL 22 /* Invalid argument */
#define ENFILE 23 /* File table overflow */
#define EMFILE 24 /* Too many open files */
#define ENOTTY 25 /* Not a typewriter */
#define ETXTBSY 26 /* Text file busy */
#define EFBIG 27 /* File too large */
#define ENOSPC 28 /* No space left on device */
#define ESPIPE 29 /* Illegal seek */
#define EROFS 30 /* Read-only file system */
#define EMLINK 31 /* Too many links */
#define EPIPE 32 /* Broken pipe */
#define EDOM 33 /* Math argument out of domain of func */
#define ERANGE 34 /* Math result not representable */
#define EDEADLK 35 /* Resource deadlock would occur */
#define ENAMETOOLONG 36 /* File name too long */
#define ENOLCK 37 /* No record locks available */
#define ENOSYS 38 /* Function not implemented */
#define ENOTEMPTY 39 /* Directory not empty */
#define ELOOP 40 /* Too many symbolic links encountered */
#define EWOULDBLOCK EAGAIN /* Operation would block */
#define ENOMSG 42 /* No message of desired type */
#define EIDRM 43 /* Identifier removed */
#define ECHRNG 44 /* Channel number out of range */
#define EL2NSYNC 45 /* Level 2 not synchronized */
#define EL3HLT 46 /* Level 3 halted */
#define EL3RST 47 /* Level 3 reset */
#define ELNRNG 48 /* Link number out of range */
#define EUNATCH 49 /* Protocol driver not attached */
#define ENOCSI 50 /* No CSI structure available */
#define EL2HLT 51 /* Level 2 halted */
#define EBADE 52 /* Invalid exchange */
#define EBADR 53 /* Invalid request descriptor */
#define EXFULL 54 /* Exchange full */
#define ENOANO 55 /* No anode */
#define EBADRQC 56 /* Invalid request code */
#define EBADSLT 57 /* Invalid slot */
#define EDEADLOCK EDEADLK
#define EBFONT 59 /* Bad font file format */
#define ENOSTR 60 /* Device not a stream */
#define ENODATA 61 /* No data available */
#define ETIME 62 /* Timer expired */
#define ENOSR 63 /* Out of streams resources */
#define ENONET 64 /* Machine is not on the network */
#define ENOPKG 65 /* Package not installed */
#define EREMOTE 66 /* Object is remote */
#define ENOLINK 67 /* Link has been severed */
#define EADV 68 /* Advertise error */
#define ESRMNT 69 /* Srmount error */
#define ECOMM 70 /* Communication error on send */
#define EPROTO 71 /* Protocol error */
#define EMULTIHOP 72 /* Multihop attempted */
#define EDOTDOT 73 /* RFS specific error */
#define EBADMSG 74 /* Not a data message */
#define EOVERFLOW 75 /* Value too large for defined data type */
#define ENOTUNIQ 76 /* Name not unique on network */
#define EBADFD 77 /* File descriptor in bad state */
#define EREMCHG 78 /* Remote address changed */
#define ELIBACC 79 /* Can not access a needed shared library */
#define ELIBBAD 80 /* Accessing a corrupted shared library */
#define ELIBSCN 81 /* .lib section in a.out corrupted */
#define ELIBMAX 82 /* Attempting to link in too many shared libraries */
#define ELIBEXEC 83 /* Cannot exec a shared library directly */
#define EILSEQ 84 /* Illegal byte sequence */
#define ERESTART 85 /* Interrupted system call should be restarted */
#define ESTRPIPE 86 /* Streams pipe error */
#define EUSERS 87 /* Too many users */
#define ENOTSOCK 88 /* Socket operation on non-socket */
#define EDESTADDRREQ 89 /* Destination address required */
#define EMSGSIZE 90 /* Message too long */
#define EPROTOTYPE 91 /* Protocol wrong type for socket */
#define ENOPROTOOPT 92 /* Protocol not available */
#define EPROTONOSUPPORT 93 /* Protocol not supported */
#define ESOCKTNOSUPPORT 94 /* Socket type not supported */
#define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */
#define EPFNOSUPPORT 96 /* Protocol family not supported */
#define EAFNOSUPPORT 97 /* Address family not supported by protocol */
#define EADDRINUSE 98 /* Address already in use */
#define EADDRNOTAVAIL 99 /* Cannot assign requested address */
#define ENETDOWN 100 /* Network is down */
#define ENETUNREACH 101 /* Network is unreachable */
#define ENETRESET 102 /* Network dropped connection because of reset */
#define ECONNABORTED 103 /* Software caused connection abort */
#define ECONNRESET 104 /* Connection reset by peer */
#define ENOBUFS 105 /* No buffer space available */
#define EISCONN 106 /* Transport endpoint is already connected */
#define ENOTCONN 107 /* Transport endpoint is not connected */
#define ESHUTDOWN 108 /* Cannot send after transport endpoint shutdown */
#define ETOOMANYREFS 109 /* Too many references: cannot splice */
#define ETIMEDOUT 110 /* Connection timed out */
#define ECONNREFUSED 111 /* Connection refused */
#define EHOSTDOWN 112 /* Host is down */
#define EHOSTUNREACH 113 /* No route to host */
#define EALREADY 114 /* Operation already in progress */
#define EINPROGRESS 115 /* Operation now in progress */
#define ESTALE 116 /* Stale NFS file handle */
#define EUCLEAN 117 /* Structure needs cleaning */
#define ENOTNAM 118 /* Not a XENIX named type file */
#define ENAVAIL 119 /* No XENIX semaphores available */
#define EISNAM 120 /* Is a named type file */
#define EREMOTEIO 121 /* Remote I/O error */
#define EDQUOT 122 /* Quota exceeded */
#define ENOMEDIUM 123 /* No medium found */
#define EMEDIUMTYPE 124 /* Wrong medium type */
#define ENSROK 0 /* DNS server returned answer with no data */
#define ENSRNODATA 160 /* DNS server returned answer with no data */
#define ENSRFORMERR 161 /* DNS server claims query was misformatted */
#define ENSRSERVFAIL 162 /* DNS server returned general failure */
#define ENSRNOTFOUND 163 /* Domain name not found */
#define ENSRNOTIMP 164 /* DNS server does not implement requested operation */
#define ENSRREFUSED 165 /* DNS server refused query */
#define ENSRBADQUERY 166 /* Misformatted DNS query */
#define ENSRBADNAME 167 /* Misformatted domain name */
#define ENSRBADFAMILY 168 /* Unsupported address family */
#define ENSRBADRESP 169 /* Misformatted DNS reply */
#define ENSRCONNREFUSED 170 /* Could not contact DNS servers */
#define ENSRTIMEOUT 171 /* Timeout while contacting DNS servers */
#define ENSROF 172 /* End of file */
#define ENSRFILE 173 /* Error reading file */
#define ENSRNOMEM 174 /* Out of memory */
#define ENSRDESTRUCTION 175 /* Application terminated lookup */
#define ENSRQUERYDOMAINTOOLONG 176 /* Domain name is too long */
#define ENSRCNAMELOOP 177 /* Domain name is too long */
#endif /* _SYS_ERROR_H */

View file

@ -0,0 +1,60 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#ifndef LIBC_FCNTL_H__
#define LIBC_FCNTL_H__
#define O_RDONLY 00
#define O_WRONLY 01
#define O_RDWR 02
#define O_CREAT 0100
#define O_EXCL 0200
#define O_NOCTTY 0400
#define O_TRUNC 01000
#define O_APPEND 02000
#define O_NONBLOCK 04000
#define O_DSYNC 010000
#define O_SYNC 04010000
#define O_RSYNC 04010000
#define O_BINARY 0100000
#define O_DIRECTORY 0200000
#define O_NOFOLLOW 0400000
#define O_CLOEXEC 02000000
#define O_ASYNC 020000
#define O_DIRECT 040000
#define O_LARGEFILE 0100000
#define O_NOATIME 01000000
#define O_PATH 010000000
#define O_TMPFILE 020200000
#define O_NDELAY O_NONBLOCK
#define O_SEARCH O_PATH
#define O_EXEC O_PATH
#define O_ACCMODE (03|O_SEARCH)
#define F_DUPFD 0
#define F_GETFD 1
#define F_SETFD 2
#define F_GETFL 3
#define F_SETFL 4
#define F_SETOWN 8
#define F_GETOWN 9
#define F_SETSIG 10
#define F_GETSIG 11
#define F_GETLK 12
#define F_SETLK 13
#define F_SETLKW 14
#define F_SETOWN_EX 15
#define F_GETOWN_EX 16
#define F_GETOWNER_UIDS 17
#endif

View file

@ -0,0 +1,33 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#ifndef _SYS_SELECT_H__
#define _SYS_SELECT_H__
#ifndef FD_SETSIZE
#define FD_SETSIZE 32
#endif
#define NBBY 8 /* number of bits in a byte */
typedef long fd_mask;
#define NFDBITS (sizeof (fd_mask) * NBBY) /* bits per mask */
#ifndef howmany
#define howmany(x,y) (((x)+((y)-1))/(y))
#endif
/* We use a macro for fd_set so that including Sockets.h afterwards
can work. */
typedef struct _types_fd_set {
fd_mask fds_bits[howmany(FD_SETSIZE, NFDBITS)];
} _types_fd_set;
#define fd_set _types_fd_set
#define FD_SET(n, p) ((p)->fds_bits[(n)/NFDBITS] |= (1L << ((n) % NFDBITS)))
#define FD_CLR(n, p) ((p)->fds_bits[(n)/NFDBITS] &= ~(1L << ((n) % NFDBITS)))
#define FD_ISSET(n, p) ((p)->fds_bits[(n)/NFDBITS] & (1L << ((n) % NFDBITS)))
#define FD_ZERO(p) memset((void*)(p), 0, sizeof(*(p)))
#endif

View file

@ -0,0 +1,52 @@
#ifndef _SIGNAL_H_
#define _SIGNAL_H_
typedef void (*SIG_FUNC)(int);
#define SIGHUP 1
#define SIGINT 2
#define SIGQUIT 3
#define SIGILL 4
#define SIGTRAP 5
#define SIGABRT 6
#define SIGEMT 7
#define SIGFPE 8
#define SIGKILL 9
#define SIGBUS 10
#define SIGSEGV 11
#define SIGSYS 12
#define SIGPIPE 13
#define SIGALRM 14
#define SIGTERM 15
#define SIGURG 16
#define SIGSTOP 17
#define SIGTSTP 18
#define SIGCONT 19
#define SIGCHLD 20
#define SIGTTIN 21
#define SIGTTOU 22
#define SIGIO 23
#define SIGXCPU 24
#define SIGXFSZ 25
#define SIGVTALRM 26
#define SIGPROF 27
#define SIGWINCH 28
#define SIGINFO 29
#define SIGUSR1 30
#define SIGUSR2 31
#define SIGSCAN 32
#define SIGASSOC 33
#define SIGDISASSOC 34
#define SIGDEAUTH 35
#define SIGPOLL SIGIO
#define SIGPWR SIGINFO
#define SIGIOT SIGABRT
extern void signal(int sig_num, SIG_FUNC func);
extern unsigned int alarm(unsigned int seconds);
#endif
// eof

View file

@ -0,0 +1,57 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#ifndef _SYS_STAT_H__
#define _SYS_STAT_H__
#define S_IFMT 00170000
#define S_IFSOCK 0140000
#define S_IFLNK 0120000
#define S_IFREG 0100000
#define S_IFBLK 0060000
#define S_IFDIR 0040000
#define S_IFCHR 0020000
#define S_IFIFO 0010000
#define S_ISUID 0004000
#define S_ISGID 0002000
#define S_ISVTX 0001000
#define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
#define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
#define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK)
#define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
#define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK)
#define S_IRWXU 00700
#define S_IRUSR 00400
#define S_IWUSR 00200
#define S_IXUSR 00100
#define S_IRWXG 00070
#define S_IRGRP 00040
#define S_IWGRP 00020
#define S_IXGRP 00010
#define S_IRWXO 00007
#define S_IROTH 00004
#define S_IWOTH 00002
#define S_IXOTH 00001
/* stat structure */
#include <stdint.h>
#include <time.h>
struct stat
{
struct rt_device* st_dev;
uint16_t st_mode;
uint32_t st_size;
time_t st_mtime;
uint32_t st_blksize;
};
#endif

View file

@ -0,0 +1,49 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#ifndef _SYS_TIME_H_
#define _SYS_TIME_H_
#include <time.h>
#include <sys/types.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifndef _TIMEVAL_DEFINED
#define _TIMEVAL_DEFINED
/*
* Structure returned by gettimeofday(2) system call,
* and used in other calls.
*/
struct timeval {
long tv_sec; /* seconds */
long tv_usec; /* and microseconds */
};
#endif /* _TIMEVAL_DEFINED */
#ifndef _TIMESPEC_DEFINED
#define _TIMESPEC_DEFINED
/*
* Structure defined by POSIX.1b to be like a timeval.
*/
struct timespec {
time_t tv_sec; /* seconds */
long tv_nsec; /* and nanoseconds */
};
#endif /* _TIMESPEC_DEFINED */
struct timezone {
int tz_minuteswest; /* minutes west of Greenwich */
int tz_dsttime; /* type of dst correction */
};
int gettimeofday(struct timeval *tp, void *ignore);
#ifdef __cplusplus
}
#endif
#endif /* _SYS_TIME_H_ */

View file

@ -0,0 +1,25 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#ifndef _SYS_TYPES_H
#define _SYS_TYPES_H
#include <stdint.h>
typedef uint32_t clockid_t;
typedef uint32_t key_t; /* Used for interprocess communication. */
typedef uint32_t pid_t; /* Used for process IDs and process group IDs. */
typedef signed long ssize_t; /* Used for a count of bytes or an error indication. */
typedef long long off_t;
typedef long suseconds_t;
#ifndef PATH_MAX
#define PATH_MAX 1024
#endif
#if __BSD_VISIBLE
#include <sys/select.h>
#endif
#endif /* _SYS_TYPES_H */

View file

@ -0,0 +1,9 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#ifndef _SYS_UNISTD_H
#define _SYS_UNISTD_H
#endif /* _SYS_UNISTD_H */

View file

@ -0,0 +1,5 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#include "sys/unistd.h"

View file

@ -0,0 +1,90 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#pragma once
#include <stddef.h>
#ifdef __cplusplus
extern "C"
{
#endif
/******************************************************
* Macros
******************************************************/
#ifndef WEAK
#ifndef __MINGW32__
#define WEAK __attribute__((weak))
#else
/* MinGW doesn't support weak */
#define WEAK
#endif
#endif
#ifndef USED
#define USED __attribute__((used))
#endif
#ifndef MAY_BE_UNUSED
#define MAY_BE_UNUSED __attribute__((unused))
#endif
#ifndef NORETURN
#define NORETURN __attribute__((noreturn))
#endif
#ifndef ALIGNED
#define ALIGNED(size) __attribute__((aligned(size)))
#endif
#ifndef SECTION
#define SECTION(name) __attribute__((section(name)))
#endif
#ifndef NEVER_INLINE
#define NEVER_INLINE __attribute__((noinline))
#endif
#ifndef ALWAYS_INLINE
#define ALWAYS_INLINE __attribute__((always_inline))
#endif
/******************************************************
* Constants
******************************************************/
/******************************************************
* Enumerations
******************************************************/
/******************************************************
* Type Definitions
******************************************************/
/******************************************************
* Structures
******************************************************/
/******************************************************
* Global Variables
******************************************************/
/******************************************************
* Function Declarations
******************************************************/
void *memrchr( const void *s, int c, size_t n );
/* Windows doesn't come with support for strlcpy */
#ifdef WIN32
size_t strlcpy (char *dest, const char *src, size_t size);
#endif /* WIN32 */
#ifdef __cplusplus
} /* extern "C" */
#endif

View file

@ -0,0 +1,5 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#include "sys/fcntl.h"

View file

@ -0,0 +1,143 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#ifdef __ICCARM__
#include <stdarg.h>
#include <sys/types.h>
#include <time.h>
#include <stdio.h>
int errno;
extern void *aos_malloc(unsigned int size);
extern void aos_alloc_trace(void *addr, size_t allocator);
extern void aos_free(void *mem);
extern void *aos_realloc(void *mem, unsigned int size);
extern long long aos_now_ms(void);
__ATTRIBUTES void *malloc(unsigned int size)
{
void *mem;
#if (RHINO_CONFIG_MM_DEBUG > 0u && RHINO_CONFIG_GCC_RETADDR > 0u)
mem = aos_malloc(size | AOS_UNSIGNED_INT_MSB);
#else
mem = aos_malloc(size);
#endif
return mem;
}
__ATTRIBUTES void *realloc(void *old, unsigned int newlen)
{
void *mem;
#if (RHINO_CONFIG_MM_DEBUG > 0u && RHINO_CONFIG_GCC_RETADDR > 0u)
mem = aos_realloc(old, newlen | AOS_UNSIGNED_INT_MSB);
#else
mem = aos_realloc(old, newlen);
#endif
return mem;
}
__ATTRIBUTES void *calloc(size_t len, size_t elsize)
{
void *mem;
#if (RHINO_CONFIG_MM_DEBUG > 0u && RHINO_CONFIG_GCC_RETADDR > 0u)
mem = aos_malloc((elsize * len) | AOS_UNSIGNED_INT_MSB);
#else
mem = aos_malloc(elsize * len);
#endif
if (mem) {
memset(mem, 0, elsize * len);
}
return mem;
}
__ATTRIBUTES void free(void *mem)
{
aos_free(mem);
}
__ATTRIBUTES time_t time(time_t *tod)
{
uint64_t t = aos_now_ms();
return (time_t)(t / 1000);
}
int *__errno _PARAMS ((void))
{
return 0;
}
void __assert_func(const char * a, int b, const char * c, const char *d)
{
while (1);
}
/*TO DO*/
#pragma weak __write
size_t __write(int handle, const unsigned char *buffer, size_t size)
{
if (buffer == 0)
{
/*
* This means that we should flush internal buffers. Since we don't we just return.
* (Remember, "handle" == -1 means that all handles should be flushed.)
*/
return 0;
}
/* This function only writes to "standard out" and "standard err" for all other file handles it returns failure. */
if ((handle != 1) && (handle != 2))
{
return ((size_t)-1);
}
/* Send data. */
aos_uart_send(buffer, size, 1000);
return size;
}
void bzero()
{
}
void __lseek()
{
}
void __close()
{
}
int remove(char const *p)
{
return 0;
}
void gettimeofday()
{
}
void getopt()
{
}
void optarg()
{
}
#endif

View file

@ -0,0 +1,102 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
/* This header file provides the reentrancy. */
/* The reentrant system calls here serve two purposes:
1) Provide reentrant versions of the system calls the ANSI C library
requires.
2) Provide these system calls in a namespace clean way.
It is intended that *all* system calls that the ANSI C library needs
be declared here. It documents them all in one place. All library access
to the system is via some form of these functions.
The target may provide the needed syscalls by any of the following:
1) Define the reentrant versions of the syscalls directly.
(eg: _open_r, _close_r, etc.). Please keep the namespace clean.
When you do this, set "syscall_dir" to "syscalls" and add
-DREENTRANT_SYSCALLS_PROVIDED to newlib_cflags in configure.host.
2) Define namespace clean versions of the system calls by prefixing
them with '_' (eg: _open, _close, etc.). Technically, there won't be
true reentrancy at the syscall level, but the library will be namespace
clean.
When you do this, set "syscall_dir" to "syscalls" in configure.host.
3) Define or otherwise provide the regular versions of the syscalls
(eg: open, close, etc.). The library won't be reentrant nor namespace
clean, but at least it will work.
When you do this, add -DMISSING_SYSCALL_NAMES to newlib_cflags in
configure.host.
4) Define or otherwise provide the regular versions of the syscalls,
and do not supply functional interfaces for any of the reentrant
calls. With this method, the reentrant syscalls are redefined to
directly call the regular system call without the reentrancy argument.
When you do this, specify both -DREENTRANT_SYSCALLS_PROVIDED and
-DMISSING_SYSCALL_NAMES via newlib_cflags in configure.host and do
not specify "syscall_dir".
Stubs of the reentrant versions of the syscalls exist in the libc/reent
source directory and are provided if REENTRANT_SYSCALLS_PROVIDED isn't
defined. These stubs call the native system calls: _open, _close, etc.
if MISSING_SYSCALL_NAMES is *not* defined, otherwise they call the
non-underscored versions: open, close, etc. when MISSING_SYSCALL_NAMES
*is* defined.
By default, newlib functions call the reentrant syscalls internally,
passing a reentrancy structure as an argument. This reentrancy structure
contains data that is thread-specific. For example, the errno value is
kept in the reentrancy structure. If multiple threads exist, each will
keep a separate errno value which is intuitive since the application flow
cannot check for failure reliably otherwise.
The reentrant syscalls are either provided by the platform, by the
libc/reent stubs, or in the case of both MISSING_SYSCALL_NAMES and
REENTRANT_SYSCALLS_PROVIDED being defined, the calls are redefined to
simply call the regular syscalls with no reentrancy struct argument.
A single-threaded application does not need to worry about the reentrancy
structure. It is used internally.
A multi-threaded application needs either to manually manage reentrancy
structures or use dynamic reentrancy.
Manually managing reentrancy structures entails calling special reentrant
versions of newlib functions that have an additional reentrancy argument.
For example, _printf_r. By convention, the first argument is the
reentrancy structure. By default, the normal version of the function
uses the default reentrancy structure: _REENT. The reentrancy structure
is passed internally, eventually to the reentrant syscalls themselves.
How the structures are stored and accessed in this model is up to the
application.
Dynamic reentrancy is specified by the __DYNAMIC_REENT__ flag. This
flag denotes setting up a macro to replace _REENT with a function call
to __getreent(). This function needs to be implemented by the platform
and it is meant to return the reentrancy structure for the current
thread. When the regular C functions (e.g. printf) go to call internal
routines with the default _REENT structure, they end up calling with
the reentrancy structure for the thread. Thus, application code does not
need to call the _r routines nor worry about reentrancy structures. */
/* WARNING: All identifiers here must begin with an underscore. This file is
included by stdio.h and others and we therefore must only use identifiers
in the namespace allotted to us. */
#ifndef _REENT_H_
#ifdef __cplusplus
extern "C" {
#endif
#define _REENT_H_
#include <sys/reent.h>
#ifdef __cplusplus
}
#endif
#endif /* _REENT_H_ */

View file

@ -0,0 +1,158 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#ifndef _SYS_ERRNO_H__
#define _SYS_ERRNO_H__
#define EPERM 1 /* Operation not permitted */
#define ENOENT 2 /* No such file or directory */
#define ESRCH 3 /* No such process */
#define EINTR 4 /* Interrupted system call */
#define EIO 5 /* I/O error */
#define ENXIO 6 /* No such device or address */
#define E2BIG 7 /* Arg list too long */
#define ENOEXEC 8 /* Exec format error */
#define EBADF 9 /* Bad file number */
#define ECHILD 10 /* No child processes */
#define EAGAIN 11 /* Try again */
#define ENOMEM 12 /* Out of memory */
#define EACCES 13 /* Permission denied */
#define EFAULT 14 /* Bad address */
#define ENOTBLK 15 /* Block device required */
#define EBUSY 16 /* Device or resource busy */
#define EEXIST 17 /* File exists */
#define EXDEV 18 /* Cross-device link */
#define ENODEV 19 /* No such device */
#define ENOTDIR 20 /* Not a directory */
#define EISDIR 21 /* Is a directory */
#define EINVAL 22 /* Invalid argument */
#define ENFILE 23 /* File table overflow */
#define EMFILE 24 /* Too many open files */
#define ENOTTY 25 /* Not a typewriter */
#define ETXTBSY 26 /* Text file busy */
#define EFBIG 27 /* File too large */
#define ENOSPC 28 /* No space left on device */
#define ESPIPE 29 /* Illegal seek */
#define EROFS 30 /* Read-only file system */
#define EMLINK 31 /* Too many links */
#define EPIPE 32 /* Broken pipe */
#define EDOM 33 /* Math argument out of domain of func */
#define ERANGE 34 /* Math result not representable */
#define EDEADLK 35 /* Resource deadlock would occur */
#define ENAMETOOLONG 36 /* File name too long */
#define ENOLCK 37 /* No record locks available */
#define ENOSYS 38 /* Function not implemented */
#define ENOTEMPTY 39 /* Directory not empty */
#define ELOOP 40 /* Too many symbolic links encountered */
#define EWOULDBLOCK EAGAIN /* Operation would block */
#define ENOMSG 42 /* No message of desired type */
#define EIDRM 43 /* Identifier removed */
#define ECHRNG 44 /* Channel number out of range */
#define EL2NSYNC 45 /* Level 2 not synchronized */
#define EL3HLT 46 /* Level 3 halted */
#define EL3RST 47 /* Level 3 reset */
#define ELNRNG 48 /* Link number out of range */
#define EUNATCH 49 /* Protocol driver not attached */
#define ENOCSI 50 /* No CSI structure available */
#define EL2HLT 51 /* Level 2 halted */
#define EBADE 52 /* Invalid exchange */
#define EBADR 53 /* Invalid request descriptor */
#define EXFULL 54 /* Exchange full */
#define ENOANO 55 /* No anode */
#define EBADRQC 56 /* Invalid request code */
#define EBADSLT 57 /* Invalid slot */
#define EDEADLOCK EDEADLK
#define EBFONT 59 /* Bad font file format */
#define ENOSTR 60 /* Device not a stream */
#define ENODATA 61 /* No data available */
#define ETIME 62 /* Timer expired */
#define ENOSR 63 /* Out of streams resources */
#define ENONET 64 /* Machine is not on the network */
#define ENOPKG 65 /* Package not installed */
#define EREMOTE 66 /* Object is remote */
#define ENOLINK 67 /* Link has been severed */
#define EADV 68 /* Advertise error */
#define ESRMNT 69 /* Srmount error */
#define ECOMM 70 /* Communication error on send */
#define EPROTO 71 /* Protocol error */
#define EMULTIHOP 72 /* Multihop attempted */
#define EDOTDOT 73 /* RFS specific error */
#define EBADMSG 74 /* Not a data message */
#define EOVERFLOW 75 /* Value too large for defined data type */
#define ENOTUNIQ 76 /* Name not unique on network */
#define EBADFD 77 /* File descriptor in bad state */
#define EREMCHG 78 /* Remote address changed */
#define ELIBACC 79 /* Can not access a needed shared library */
#define ELIBBAD 80 /* Accessing a corrupted shared library */
#define ELIBSCN 81 /* .lib section in a.out corrupted */
#define ELIBMAX 82 /* Attempting to link in too many shared libraries */
#define ELIBEXEC 83 /* Cannot exec a shared library directly */
#define EILSEQ 84 /* Illegal byte sequence */
#define ERESTART 85 /* Interrupted system call should be restarted */
#define ESTRPIPE 86 /* Streams pipe error */
#define EUSERS 87 /* Too many users */
#define ENOTSOCK 88 /* Socket operation on non-socket */
#define EDESTADDRREQ 89 /* Destination address required */
#define EMSGSIZE 90 /* Message too long */
#define EPROTOTYPE 91 /* Protocol wrong type for socket */
#define ENOPROTOOPT 92 /* Protocol not available */
#define EPROTONOSUPPORT 93 /* Protocol not supported */
#define ESOCKTNOSUPPORT 94 /* Socket type not supported */
#define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */
#define EPFNOSUPPORT 96 /* Protocol family not supported */
#define EAFNOSUPPORT 97 /* Address family not supported by protocol */
#define EADDRINUSE 98 /* Address already in use */
#define EADDRNOTAVAIL 99 /* Cannot assign requested address */
#define ENETDOWN 100 /* Network is down */
#define ENETUNREACH 101 /* Network is unreachable */
#define ENETRESET 102 /* Network dropped connection because of reset */
#define ECONNABORTED 103 /* Software caused connection abort */
#define ECONNRESET 104 /* Connection reset by peer */
#define ENOBUFS 105 /* No buffer space available */
#define EISCONN 106 /* Transport endpoint is already connected */
#define ENOTCONN 107 /* Transport endpoint is not connected */
#define ESHUTDOWN 108 /* Cannot send after transport endpoint shutdown */
#define ETOOMANYREFS 109 /* Too many references: cannot splice */
#define ETIMEDOUT 110 /* Connection timed out */
#define ECONNREFUSED 111 /* Connection refused */
#define EHOSTDOWN 112 /* Host is down */
#define EHOSTUNREACH 113 /* No route to host */
#define EALREADY 114 /* Operation already in progress */
#define EINPROGRESS 115 /* Operation now in progress */
#define ESTALE 116 /* Stale NFS file handle */
#define EUCLEAN 117 /* Structure needs cleaning */
#define ENOTNAM 118 /* Not a XENIX named type file */
#define ENAVAIL 119 /* No XENIX semaphores available */
#define EISNAM 120 /* Is a named type file */
#define EREMOTEIO 121 /* Remote I/O error */
#define EDQUOT 122 /* Quota exceeded */
#define ENOMEDIUM 123 /* No medium found */
#define EMEDIUMTYPE 124 /* Wrong medium type */
#define ENSROK 0 /* DNS server returned answer with no data */
#define ENOTSUP 134 /* Not supported */
#define ENSRNODATA 160 /* DNS server returned answer with no data */
#define ENSRFORMERR 161 /* DNS server claims query was misformatted */
#define ENSRSERVFAIL 162 /* DNS server returned general failure */
#define ENSRNOTFOUND 163 /* Domain name not found */
#define ENSRNOTIMP 164 /* DNS server does not implement requested operation */
#define ENSRREFUSED 165 /* DNS server refused query */
#define ENSRBADQUERY 166 /* Misformatted DNS query */
#define ENSRBADNAME 167 /* Misformatted domain name */
#define ENSRBADFAMILY 168 /* Unsupported address family */
#define ENSRBADRESP 169 /* Misformatted DNS reply */
#define ENSRCONNREFUSED 170 /* Could not contact DNS servers */
#define ENSRTIMEOUT 171 /* Timeout while contacting DNS servers */
#define ENSROF 172 /* End of file */
#define ENSRFILE 173 /* Error reading file */
#define ENSRNOMEM 174 /* Out of memory */
#define ENSRDESTRUCTION 175 /* Application terminated lookup */
#define ENSRQUERYDOMAINTOOLONG 176 /* Domain name is too long */
#define ENSRCNAMELOOP 177 /* Domain name is too long */
#endif /* _SYS_ERROR_H */

View file

@ -0,0 +1,60 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#ifndef LIBC_FCNTL_H__
#define LIBC_FCNTL_H__
#define O_RDONLY 00
#define O_WRONLY 01
#define O_RDWR 02
#define O_CREAT 0100
#define O_EXCL 0200
#define O_NOCTTY 0400
#define O_TRUNC 01000
#define O_APPEND 02000
#define O_NONBLOCK 04000
#define O_DSYNC 010000
#define O_SYNC 04010000
#define O_RSYNC 04010000
#define O_BINARY 0100000
#define O_DIRECTORY 0200000
#define O_NOFOLLOW 0400000
#define O_CLOEXEC 02000000
#define O_ASYNC 020000
#define O_DIRECT 040000
#define O_LARGEFILE 0100000
#define O_NOATIME 01000000
#define O_PATH 010000000
#define O_TMPFILE 020200000
#define O_NDELAY O_NONBLOCK
#define O_SEARCH O_PATH
#define O_EXEC O_PATH
#define O_ACCMODE (03|O_SEARCH)
#define F_DUPFD 0
#define F_GETFD 1
#define F_SETFD 2
#define F_GETFL 3
#define F_SETFL 4
#define F_SETOWN 8
#define F_GETOWN 9
#define F_SETSIG 10
#define F_GETSIG 11
#define F_GETLK 12
#define F_SETLK 13
#define F_SETLKW 14
#define F_SETOWN_EX 15
#define F_GETOWN_EX 16
#define F_GETOWNER_UIDS 17
#endif

View file

@ -0,0 +1,31 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
/* This header file provides the reentrancy. */
/* WARNING: All identifiers here must begin with an underscore. This file is
included by stdio.h and others and we therefore must only use identifiers
in the namespace allotted to us. */
#ifndef _SYS_REENT_H_
#ifdef __cplusplus
extern "C" {
#endif
#define _SYS_REENT_H_
#include <errno.h>
/* This version of _reent is laid out with "int"s in pairs, to help
* ports with 16-bit int's but 32-bit pointers, align nicely. */
struct _reent
{
/* As an exception to the above put _errno first for binary
compatibility with non _REENT_SMALL targets. */
int _errno; /* local copy of errno */
};
#ifdef __cplusplus
}
#endif
#endif /* _SYS_REENT_H_ */

View file

@ -0,0 +1,33 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#ifndef _SYS_SELECT_H__
#define _SYS_SELECT_H__
#ifndef FD_SETSIZE
#define FD_SETSIZE 32
#endif
#define NBBY 8 /* number of bits in a byte */
typedef long fd_mask;
#define NFDBITS (sizeof (fd_mask) * NBBY) /* bits per mask */
#ifndef howmany
#define howmany(x,y) (((x)+((y)-1))/(y))
#endif
/* We use a macro for fd_set so that including Sockets.h afterwards
can work. */
typedef struct _types_fd_set {
fd_mask fds_bits[howmany(FD_SETSIZE, NFDBITS)];
} _types_fd_set;
#define fd_set _types_fd_set
#define FD_SET(n, p) ((p)->fds_bits[(n)/NFDBITS] |= (1L << ((n) % NFDBITS)))
#define FD_CLR(n, p) ((p)->fds_bits[(n)/NFDBITS] &= ~(1L << ((n) % NFDBITS)))
#define FD_ISSET(n, p) ((p)->fds_bits[(n)/NFDBITS] & (1L << ((n) % NFDBITS)))
#define FD_ZERO(p) memset((void*)(p), 0, sizeof(*(p)))
#endif

View file

@ -0,0 +1,52 @@
#ifndef _SIGNAL_H_
#define _SIGNAL_H_
typedef void (*SIG_FUNC)(int);
#define SIGHUP 1
#define SIGINT 2
#define SIGQUIT 3
#define SIGILL 4
#define SIGTRAP 5
#define SIGABRT 6
#define SIGEMT 7
#define SIGFPE 8
#define SIGKILL 9
#define SIGBUS 10
#define SIGSEGV 11
#define SIGSYS 12
#define SIGPIPE 13
#define SIGALRM 14
#define SIGTERM 15
#define SIGURG 16
#define SIGSTOP 17
#define SIGTSTP 18
#define SIGCONT 19
#define SIGCHLD 20
#define SIGTTIN 21
#define SIGTTOU 22
#define SIGIO 23
#define SIGXCPU 24
#define SIGXFSZ 25
#define SIGVTALRM 26
#define SIGPROF 27
#define SIGWINCH 28
#define SIGINFO 29
#define SIGUSR1 30
#define SIGUSR2 31
#define SIGSCAN 32
#define SIGASSOC 33
#define SIGDISASSOC 34
#define SIGDEAUTH 35
#define SIGPOLL SIGIO
#define SIGPWR SIGINFO
#define SIGIOT SIGABRT
extern void signal(int sig_num, SIG_FUNC func);
extern unsigned int alarm(unsigned int seconds);
#endif
// eof

View file

@ -0,0 +1,57 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#ifndef _SYS_STAT_H__
#define _SYS_STAT_H__
#define S_IFMT 00170000
#define S_IFSOCK 0140000
#define S_IFLNK 0120000
#define S_IFREG 0100000
#define S_IFBLK 0060000
#define S_IFDIR 0040000
#define S_IFCHR 0020000
#define S_IFIFO 0010000
#define S_ISUID 0004000
#define S_ISGID 0002000
#define S_ISVTX 0001000
#define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
#define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
#define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK)
#define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
#define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK)
#define S_IRWXU 00700
#define S_IRUSR 00400
#define S_IWUSR 00200
#define S_IXUSR 00100
#define S_IRWXG 00070
#define S_IRGRP 00040
#define S_IWGRP 00020
#define S_IXGRP 00010
#define S_IRWXO 00007
#define S_IROTH 00004
#define S_IWOTH 00002
#define S_IXOTH 00001
/* stat structure */
#include <stdint.h>
#include <time.h>
struct stat
{
struct rt_device* st_dev;
uint16_t st_mode;
uint32_t st_size;
time_t st_mtime;
uint32_t st_blksize;
};
#endif

View file

@ -0,0 +1,49 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#ifndef _SYS_TIME_H_
#define _SYS_TIME_H_
#include <time.h>
#include <sys/types.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifndef _TIMEVAL_DEFINED
#define _TIMEVAL_DEFINED
/*
* Structure returned by gettimeofday(2) system call,
* and used in other calls.
*/
struct timeval {
long tv_sec; /* seconds */
long tv_usec; /* and microseconds */
};
#endif /* _TIMEVAL_DEFINED */
#ifndef _TIMESPEC_DEFINED
#define _TIMESPEC_DEFINED
/*
* Structure defined by POSIX.1b to be like a timeval.
*/
struct timespec {
time_t tv_sec; /* seconds */
long tv_nsec; /* and nanoseconds */
};
#endif /* _TIMESPEC_DEFINED */
struct timezone {
int tz_minuteswest; /* minutes west of Greenwich */
int tz_dsttime; /* type of dst correction */
};
int gettimeofday(struct timeval *tp, void *ignore);
#ifdef __cplusplus
}
#endif
#endif /* _SYS_TIME_H_ */

View file

@ -0,0 +1,33 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#ifndef _SYS_TYPES_H
#define _SYS_TYPES_H
#include <stdint.h>
#ifndef _PARAMS
#define _PARAMS(paramlist) paramlist
#endif
#define _CLOCK_T_ uint32_t
#define STDOUT_FILENO 1
#define STDERR_FILENO 2
typedef uint32_t clockid_t;
typedef uint32_t key_t; /* Used for interprocess communication. */
typedef uint32_t pid_t; /* Used for process IDs and process group IDs. */
typedef signed long ssize_t; /* Used for a count of bytes or an error indication. */
typedef long long off_t;
typedef long suseconds_t;
typedef uint32_t _off_t;
typedef uint32_t _ssize_t;
#ifndef PATH_MAX
#define PATH_MAX 1024
#endif
#if __BSD_VISIBLE
#include <sys/select.h>
#endif
#endif /* _SYS_TYPES_H */

View file

@ -0,0 +1,9 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#ifndef _SYS_UNISTD_H
#define _SYS_UNISTD_H
#endif /* _SYS_UNISTD_H */

View file

@ -0,0 +1,5 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#include "sys/unistd.h"

View file

@ -0,0 +1,15 @@
NAME := newlib_stub
ifeq ($(COMPILER),armcc)
$(NAME)_TYPE := share
$(NAME)_SOURCES := compilers/armlibc/armcc_libc.c
GLOBAL_INCLUDES += compilers/armlibc
else ifeq ($(COMPILER),iar)
$(NAME)_TYPE := share
GLOBAL_INCLUDES += compilers/iar
$(NAME)_SOURCES := compilers/iar/iar_libc.c
else ifneq ($(HOST_MCU_FAMILY),linux)
$(NAME)_TYPE := share
$(NAME)_MBINS_TYPE := share
$(NAME)_SOURCES := newlib_stub.c
endif

View file

@ -0,0 +1,246 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#include <reent.h>
#include <sys/errno.h>
#include <sys/unistd.h>
#include <sys/time.h>
#include <k_api.h>
#include <aos/aos.h>
#include "hal/soc/soc.h"
#ifdef AOS_BINS
extern uart_dev_t uart_0;
#endif
int _execve_r(struct _reent *ptr, const char *name, char *const *argv, char *const *env)
{
ptr->_errno = ENOTSUP;
return -1;
}
int _fcntl_r(struct _reent *ptr, int fd, int cmd, int arg)
{
ptr->_errno = ENOTSUP;
return -1;
}
int _fork_r(struct _reent *ptr)
{
ptr->_errno = ENOTSUP;
return -1;
}
int _getpid_r(struct _reent *ptr)
{
ptr->_errno = ENOTSUP;
return 0;
}
int _isatty_r(struct _reent *ptr, int fd)
{
if (fd >= 0 && fd < 3) {
return 1;
}
ptr->_errno = ENOTSUP;
return -1;
}
int _kill_r(struct _reent *ptr, int pid, int sig)
{
ptr->_errno = ENOTSUP;
return -1;
}
int _link_r(struct _reent *ptr, const char *old, const char *new)
{
ptr->_errno = ENOTSUP;
return -1;
}
_off_t _lseek_r(struct _reent *ptr, int fd, _off_t pos, int whence)
{
ptr->_errno = ENOTSUP;
return 0;
}
int _mkdir_r(struct _reent *ptr, const char *name, int mode)
{
ptr->_errno = ENOTSUP;
return 0;
}
int _open_r(struct _reent *ptr, const char *file, int flags, int mode)
{
ptr->_errno = ENOTSUP;
return 0;
}
int _close_r(struct _reent *ptr, int fd)
{
ptr->_errno = ENOTSUP;
return 0;
}
_ssize_t _read_r(struct _reent *ptr, int fd, void *buf, size_t nbytes)
{
ptr->_errno = ENOTSUP;
return 0;
}
/*
* implement _write_r here
*/
_ssize_t _write_r(struct _reent *ptr, int fd, const void *buf, size_t nbytes)
{
const char *tmp = buf;
int i;
switch (fd) {
case STDOUT_FILENO: /*stdout*/
case STDERR_FILENO: /* stderr */
break;
default:
set_errno(EBADF);
return -1;
}
for (i = 0; i < nbytes; i++) {
if (*tmp == '\n') {
#ifdef AOS_BINS
hal_uart_send(&uart_0, (void *)"\r", 1, 0);
#else
aos_uart_send((void *)"\r", 1, 0);
#endif
}
#ifdef AOS_BINS
hal_uart_send(&uart_0, (void *)tmp, 1, 0);
#else
aos_uart_send((void *)tmp, 1, 0);
#endif
tmp ++;
}
return nbytes;
}
int _fstat_r(struct _reent *ptr, int fd, struct stat *pstat)
{
ptr->_errno = ENOTSUP;
return -1;
}
int _rename_r(struct _reent *ptr, const char *old, const char *new)
{
ptr->_errno = ENOTSUP;
return 0;
}
void *_sbrk_r(struct _reent *ptr, ptrdiff_t incr)
{
ptr->_errno = ENOTSUP;
return NULL;
}
int _stat_r(struct _reent *ptr, const char *file, struct stat *pstat)
{
ptr->_errno = ENOTSUP;
return 0;
}
_CLOCK_T_ _times_r(struct _reent *ptr, struct tms *ptms)
{
ptr->_errno = ENOTSUP;
return -1;
}
int _unlink_r(struct _reent *ptr, const char *file)
{
ptr->_errno = ENOTSUP;
return 0;
}
int _wait_r(struct _reent *ptr, int *status)
{
ptr->_errno = ENOTSUP;
return -1;
}
int _gettimeofday_r(struct _reent *ptr, struct timeval *tv, void *__tzp)
{
uint64_t t = aos_now_ms();
tv->tv_sec = t / 1000;
tv->tv_usec = (t % 1000) * 1000;
return 0;
}
void *_malloc_r(struct _reent *ptr, size_t size)
{
void *mem;
#if (RHINO_CONFIG_MM_DEBUG > 0u && RHINO_CONFIG_GCC_RETADDR > 0u)
mem = aos_malloc(size | AOS_UNSIGNED_INT_MSB);
aos_alloc_trace(mem, (size_t)__builtin_return_address(0));
#else
mem = aos_malloc(size);
#endif
return mem;
}
void *_realloc_r(struct _reent *ptr, void *old, size_t newlen)
{
void *mem;
#if (RHINO_CONFIG_MM_DEBUG > 0u && RHINO_CONFIG_GCC_RETADDR > 0u)
mem = aos_realloc(old, newlen | AOS_UNSIGNED_INT_MSB);
aos_alloc_trace(mem, (size_t)__builtin_return_address(0));
#else
mem = aos_realloc(old, newlen);
#endif
return mem;
}
void *_calloc_r(struct _reent *ptr, size_t size, size_t len)
{
void *mem;
#if (RHINO_CONFIG_MM_DEBUG > 0u && RHINO_CONFIG_GCC_RETADDR > 0u)
mem = aos_malloc((size * len) | AOS_UNSIGNED_INT_MSB);
aos_alloc_trace(mem, (size_t)__builtin_return_address(0));
#else
mem = aos_malloc(size * len);
#endif
if (mem) {
bzero(mem, size * len);
}
return mem;
}
void _free_r(struct _reent *ptr, void *addr)
{
aos_free(addr);
}
void _exit(int status)
{
while (1);
}
void _system(const char *s)
{
return;
}
void abort(void)
{
while (1);
}

View file

@ -0,0 +1,25 @@
src = []
include_tmp = []
if aos_global_config.compiler == 'armcc':
src = Split('''
compilers/armlibc/armcc_libc.c
''')
include_tmp = Split('''
compilers/armlibc
''')
elif aos_global_config.compiler == 'iar':
src = Split('''
compilers/iar/iar_libc.c
''')
include_tmp = Split('''
compilers/iar
''')
elif aos_global_config.board != 'linuxhost':
src = Split('''
newlib_stub.c
''')
component = aos_component('newlib_stub', src)
for i in include_tmp:
component.add_global_includes(i)

View file

@ -0,0 +1,210 @@
/*
* Copyright (C) 2015-2019 Alibaba Group Holding Limited
*/
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <aos/aos.h>
unsigned int aos_log_level = AOS_LL_V_DEBUG | AOS_LL_V_INFO | AOS_LL_V_WARN | AOS_LL_V_ERROR | AOS_LL_V_FATAL;
aos_mutex_t log_mutex;
#ifndef csp_printf
__attribute__((weak)) int csp_printf(const char *fmt, ...)
{
va_list args;
int ret;
#ifdef AOS_DISABLE_ALL_LOGS
if (0 == log_get_enable_aos_log_flag()) return;
#endif
ret = aos_mutex_lock(&log_mutex, AOS_WAIT_FOREVER);
if (ret == 0)
{
va_start(args, fmt);
ret = vprintf(fmt, args);
va_end(args);
fflush(stdout);
}
aos_mutex_unlock(&log_mutex);
return ret;
}
#endif
#if defined(LOG_SIMPLE)
void log_print_simple(unsigned int log_level, const char *fmt, ...)
{
va_list args;
int ret;
char level_prt;
#ifdef AOS_DISABLE_ALL_LOGS
if (0 == log_get_enable_aos_log_flag()) return;
#endif
if ((aos_log_level & log_level) == 0)
{
return;
}
switch (log_level)
{
case AOS_LL_V_ALL:
level_prt = 'A';
break;
case AOS_LL_V_FATAL:
level_prt = 'F';
break;
case AOS_LL_V_ERROR:
level_prt = 'E';
break;
case AOS_LL_V_WARN:
level_prt = 'W';
break;
case AOS_LL_V_INFO:
level_prt = 'I';
break;
case AOS_LL_V_DEBUG:
level_prt = 'D';
break;
default:
level_prt = ' ';
}
ret = aos_mutex_lock(&log_mutex, AOS_WAIT_FOREVER);
if (ret != 0)
{
return;
}
printf("[%06d]<%c> ", (unsigned)aos_now_ms(), level_prt);
va_start(args, fmt);
ret = vprintf(fmt, args);
va_end(args);
fflush(stdout);
printf("\r\n");
aos_mutex_unlock(&log_mutex);
}
#endif
void aos_set_log_level(aos_log_level_t log_level)
{
unsigned int value = 0;
switch (log_level)
{
case AOS_LL_NONE:
value |= AOS_LL_V_NONE;
break;
case AOS_LL_DEBUG:
value |= AOS_LL_V_DEBUG;
case AOS_LL_INFO:
value |= AOS_LL_V_INFO;
case AOS_LL_WARN:
value |= AOS_LL_V_WARN;
case AOS_LL_ERROR:
value |= AOS_LL_V_ERROR;
case AOS_LL_FATAL:
value |= AOS_LL_V_FATAL;
break;
default:
break;
}
aos_log_level = value;
}
static void log_cmd(char *buf, int len, int argc, char **argv)
{
const char *lvls[] = {
[AOS_LL_NONE] = "N",
[AOS_LL_FATAL] = "F",
[AOS_LL_ERROR] = "E",
[AOS_LL_WARN] = "W",
[AOS_LL_INFO] = "I",
[AOS_LL_DEBUG] = "D",
};
if (argc < 2)
{
aos_cli_printf("cur level: %02x\r\n", aos_get_log_level());
return;
}
int i;
for (i = 0; i < sizeof(lvls) / sizeof(lvls[0]); i++)
{
if (strncmp(lvls[i], argv[1], strlen(lvls[i]) + 1) != 0)
continue;
aos_set_log_level((aos_log_level_t)i);
aos_cli_printf("set level success\r\n");
return;
}
aos_cli_printf("set level fail\r\n");
}
struct cli_command log_cli_cmd[] = {
{"lvl", "Set loglevel. lvl [N/F/E/W/I/D]", log_cmd}};
/* log init with cli */
void log_cli_init(void)
{
aos_log_level = AOS_LL_V_DEBUG | AOS_LL_V_INFO | AOS_LL_V_WARN | AOS_LL_V_ERROR | AOS_LL_V_FATAL;
aos_cli_register_commands(&log_cli_cmd[0], sizeof(log_cli_cmd) / sizeof(struct cli_command));
aos_mutex_new(&log_mutex);
}
/* log init without cli */
void log_no_cli_init(void)
{
aos_mutex_new(&log_mutex);
}
#ifdef AOS_DISABLE_ALL_LOGS
static char enable_aos_log_flag = 0;
extern int cli_service_start(void);
static int aos_uart_getchar(char *inbuf, int timeout)
{
if (aos_uart_recv(inbuf, 1, NULL, timeout) == 0)
{
return 1;
}
else
{
return 0;
}
}
char log_get_enable_aos_log_flag(void)
{
return enable_aos_log_flag;
}
int log_check_uart_input(int timeout)
{
int ch = 0;
if (aos_uart_getchar((char*)&ch, timeout) == 1)
{
if ((0 != ch) && (isprint((int)ch) || iscntrl((int)ch)))
{
enable_aos_log_flag = 1;
printf("%d\r\n", ch);
#ifdef CONFIG_AOS_CLI
cli_service_start();
#endif
}
}
return 0;
}
#endif

View file

@ -0,0 +1,7 @@
NAME := log
$(NAME)_TYPE := share
$(NAME)_MBINS_TYPE := share
$(NAME)_SOURCES := log.c
GLOBAL_CFLAGS += -DLOG_SIMPLE

View file

@ -0,0 +1,4 @@
src = Split('''
log.c
''')
aos_component('log', src)

View file

@ -0,0 +1,41 @@
Note: This is just a template, so feel free to use/remove the unnecessary things
### Description
- Type: Bug | Enhancement\Feature Request | Question
- Priority: Blocker | Major | Minor
---------------------------------------------------------------
## Bug
**OS**
Mbed OS|linux|windows|
**mbed TLS build:**
Version: x.x.x or git commit id
OS version: x.x.x
Configuration: please attach config.h file where possible
Compiler and options (if you used a pre-built binary, please indicate how you obtained it):
Additional environment information:
**Peer device TLS stack and version**
OpenSSL|GnuTls|Chrome|NSS(Firefox)|SecureChannel (IIS/Internet Explorer/Edge)|Other
Version:
**Expected behavior**
**Actual behavior**
**Steps to reproduce**
----------------------------------------------------------------
## Enhancement\Feature Request
**Justification - why does the library need this feature?**
**Suggested enhancement**
-----------------------------------------------------------------
## Question
**Please first check for answers in the [Mbed TLS knowledge Base](https://tls.mbed.org/kb), and preferably file an issue in the [Mbed TLS support forum](https://forums.mbed.com/c/mbed-tls)**

View file

@ -0,0 +1,39 @@
Notes:
* Pull requests cannot be accepted until:
- The submitter has [accepted the online agreement here with a click through](https://developer.mbed.org/contributor_agreement/)
or for companies or those that do not wish to create an mbed account, a slightly different agreement can be found [here](https://www.mbed.com/en/about-mbed/contributor-license-agreements/)
- The PR follows the [mbed TLS coding standards](https://tls.mbed.org/kb/development/mbedtls-coding-standards)
* This is just a template, so feel free to use/remove the unnecessary things
## Description
A few sentences describing the overall goals of the pull request's commits.
## Status
**READY/IN DEVELOPMENT/HOLD**
## Requires Backporting
When there is a bug fix, it should be backported to all maintained and supported branches.
Changes do not have to be backported if:
- This PR is a new feature\enhancement
- This PR contains changes in the API. If this is true, and there is a need for the fix to be backported, the fix should be handled differently in the legacy branch
Yes | NO
Which branch?
## Migrations
If there is any API change, what's the incentive and logic for it.
YES | NO
## Additional comments
Any additional information that could be of interest
## Todos
- [ ] Tests
- [ ] Documentation
- [ ] Changelog updated
- [ ] Backported
## Steps to test or reproduce
Outline the steps to test or reproduce the PR here.

28
Living_SDK/utility/mbedtls/.gitignore vendored Normal file
View file

@ -0,0 +1,28 @@
CMakeCache.txt
CMakeFiles
CTestTestfile.cmake
cmake_install.cmake
Testing
Coverage
*.gcno
*.gcda
# generated by scripts/memory.sh
massif-*
# MSVC files generated by CMake:
/*.sln
/*.vcxproj
/*.filters
# MSVC build artifacts:
*.exe
*.pdb
*.ilk
*.lib
# Python build artifacts:
*.pyc
# CMake generates *.dir/ folders for in-tree builds (used by MSVC projects), ignore all of those:
*.dir/

View file

@ -0,0 +1,425 @@
[MASTER]
# A comma-separated list of package or module names from where C extensions may
# be loaded. Extensions are loading into the active Python interpreter and may
# run arbitrary code
extension-pkg-whitelist=
# Add files or directories to the blacklist. They should be base names, not
# paths.
ignore=CVS
# Add files or directories matching the regex patterns to the blacklist. The
# regex matches against base names, not paths.
ignore-patterns=
# Python code to execute, usually for sys.path manipulation such as
# pygtk.require().
#init-hook=
# Use multiple processes to speed up Pylint.
jobs=1
# List of plugins (as comma separated values of python modules names) to load,
# usually to register additional checkers.
load-plugins=
# Pickle collected data for later comparisons.
persistent=yes
# Specify a configuration file.
#rcfile=
# Allow loading of arbitrary C extensions. Extensions are imported into the
# active Python interpreter and may run arbitrary code.
unsafe-load-any-extension=no
[MESSAGES CONTROL]
# Only show warnings with the listed confidence levels. Leave empty to show
# all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED
confidence=
# Disable the message, report, category or checker with the given id(s). You
# can either give multiple identifiers separated by comma (,) or put this
# option multiple times (only on the command line, not in the configuration
# file where it should appear only once).You can also use "--disable=all" to
# disable everything first and then reenable specific checks. For example, if
# you want to run only the similarities checker, you can use "--disable=all
# --enable=similarities". If you want to run only the classes checker, but have
# no Warning level messages displayed, use"--disable=all --enable=classes
# --disable=W"
disable=print-statement,parameter-unpacking,unpacking-in-except,old-raise-syntax,backtick,long-suffix,old-ne-operator,old-octal-literal,import-star-module-level,raw-checker-failed,bad-inline-option,locally-disabled,locally-enabled,file-ignored,suppressed-message,useless-suppression,deprecated-pragma,apply-builtin,basestring-builtin,buffer-builtin,cmp-builtin,coerce-builtin,execfile-builtin,file-builtin,long-builtin,raw_input-builtin,reduce-builtin,standarderror-builtin,unicode-builtin,xrange-builtin,coerce-method,delslice-method,getslice-method,setslice-method,no-absolute-import,old-division,dict-iter-method,dict-view-method,next-method-called,metaclass-assignment,indexing-exception,raising-string,reload-builtin,oct-method,hex-method,nonzero-method,cmp-method,input-builtin,round-builtin,intern-builtin,unichr-builtin,map-builtin-not-iterating,zip-builtin-not-iterating,range-builtin-not-iterating,filter-builtin-not-iterating,using-cmp-argument,eq-without-hash,div-method,idiv-method,rdiv-method,exception-message-attribute,invalid-str-codec,sys-max-int,bad-python3-import,deprecated-string-function,deprecated-str-translate-call
# Enable the message, report, category or checker with the given id(s). You can
# either give multiple identifier separated by comma (,) or put this option
# multiple time (only on the command line, not in the configuration file where
# it should appear only once). See also the "--disable" option for examples.
enable=
[REPORTS]
# Python expression which should return a note less than 10 (10 is the highest
# note). You have access to the variables errors warning, statement which
# respectively contain the number of errors / warnings messages and the total
# number of statements analyzed. This is used by the global evaluation report
# (RP0004).
evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10)
# Template used to display messages. This is a python new-style format string
# used to format the message information. See doc for all details
#msg-template=
# Set the output format. Available formats are text, parseable, colorized, json
# and msvs (visual studio).You can also give a reporter class, eg
# mypackage.mymodule.MyReporterClass.
output-format=text
# Tells whether to display a full report or only the messages
reports=no
# Activate the evaluation score.
score=yes
[REFACTORING]
# Maximum number of nested blocks for function / method body
max-nested-blocks=5
[SIMILARITIES]
# Ignore comments when computing similarities.
ignore-comments=yes
# Ignore docstrings when computing similarities.
ignore-docstrings=yes
# Ignore imports when computing similarities.
ignore-imports=no
# Minimum lines number of a similarity.
min-similarity-lines=4
[FORMAT]
# Expected format of line ending, e.g. empty (any line ending), LF or CRLF.
expected-line-ending-format=
# Regexp for a line that is allowed to be longer than the limit.
ignore-long-lines=^\s*(# )?<?https?://\S+>?$
# Number of spaces of indent required inside a hanging or continued line.
indent-after-paren=4
# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1
# tab).
indent-string=' '
# Maximum number of characters on a single line.
max-line-length=79
# Maximum number of lines in a module
max-module-lines=2000
# List of optional constructs for which whitespace checking is disabled. `dict-
# separator` is used to allow tabulation in dicts, etc.: {1 : 1,\n222: 2}.
# `trailing-comma` allows a space between comma and closing bracket: (a, ).
# `empty-line` allows space-only lines.
no-space-check=trailing-comma,dict-separator
# Allow the body of a class to be on the same line as the declaration if body
# contains single statement.
single-line-class-stmt=no
# Allow the body of an if to be on the same line as the test if there is no
# else.
single-line-if-stmt=no
[BASIC]
# Naming hint for argument names
argument-name-hint=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$
# Regular expression matching correct argument names
argument-rgx=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$
# Naming hint for attribute names
attr-name-hint=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$
# Regular expression matching correct attribute names
attr-rgx=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$
# Bad variable names which should always be refused, separated by a comma
bad-names=foo,bar,baz,toto,tutu,tata
# Naming hint for class attribute names
class-attribute-name-hint=([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$
# Regular expression matching correct class attribute names
class-attribute-rgx=([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$
# Naming hint for class names
class-name-hint=[A-Z_][a-zA-Z0-9]+$
# Regular expression matching correct class names
class-rgx=[A-Z_][a-zA-Z0-9]+$
# Naming hint for constant names
const-name-hint=(([A-Z_][A-Z0-9_]*)|(__.*__))$
# Regular expression matching correct constant names
const-rgx=(([A-Z_][A-Z0-9_]*)|(__.*__))$
# Minimum line length for functions/classes that require docstrings, shorter
# ones are exempt.
docstring-min-length=-1
# Naming hint for function names
function-name-hint=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$
# Regular expression matching correct function names
function-rgx=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$
# Good variable names which should always be accepted, separated by a comma
good-names=i,j,k,ex,Run,_
# Include a hint for the correct naming format with invalid-name
include-naming-hint=no
# Naming hint for inline iteration names
inlinevar-name-hint=[A-Za-z_][A-Za-z0-9_]*$
# Regular expression matching correct inline iteration names
inlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$
# Naming hint for method names
method-name-hint=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$
# Regular expression matching correct method names
method-rgx=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$
# Naming hint for module names
module-name-hint=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$
# Regular expression matching correct module names
module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$
# Colon-delimited sets of names that determine each other's naming style when
# the name regexes allow several styles.
name-group=
# Regular expression which should only match function or class names that do
# not require a docstring.
no-docstring-rgx=^_
# List of decorators that produce properties, such as abc.abstractproperty. Add
# to this list to register other decorators that produce valid properties.
property-classes=abc.abstractproperty
# Naming hint for variable names
variable-name-hint=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$
# Regular expression matching correct variable names
variable-rgx=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$
[TYPECHECK]
# List of decorators that produce context managers, such as
# contextlib.contextmanager. Add to this list to register other decorators that
# produce valid context managers.
contextmanager-decorators=contextlib.contextmanager
# List of members which are set dynamically and missed by pylint inference
# system, and so shouldn't trigger E1101 when accessed. Python regular
# expressions are accepted.
generated-members=
# Tells whether missing members accessed in mixin class should be ignored. A
# mixin class is detected if its name ends with "mixin" (case insensitive).
ignore-mixin-members=yes
# This flag controls whether pylint should warn about no-member and similar
# checks whenever an opaque object is returned when inferring. The inference
# can return multiple potential results while evaluating a Python object, but
# some branches might not be evaluated, which results in partial inference. In
# that case, it might be useful to still emit no-member and other checks for
# the rest of the inferred objects.
ignore-on-opaque-inference=yes
# List of class names for which member attributes should not be checked (useful
# for classes with dynamically set attributes). This supports the use of
# qualified names.
ignored-classes=optparse.Values,thread._local,_thread._local
# List of module names for which member attributes should not be checked
# (useful for modules/projects where namespaces are manipulated during runtime
# and thus existing member attributes cannot be deduced by static analysis. It
# supports qualified module names, as well as Unix pattern matching.
ignored-modules=
# Show a hint with possible names when a member name was not found. The aspect
# of finding the hint is based on edit distance.
missing-member-hint=yes
# The minimum edit distance a name should have in order to be considered a
# similar match for a missing member name.
missing-member-hint-distance=1
# The total number of similar names that should be taken in consideration when
# showing a hint for a missing member.
missing-member-max-choices=1
[VARIABLES]
# List of additional names supposed to be defined in builtins. Remember that
# you should avoid to define new builtins when possible.
additional-builtins=
# Tells whether unused global variables should be treated as a violation.
allow-global-unused-variables=yes
# List of strings which can identify a callback function by name. A callback
# name must start or end with one of those strings.
callbacks=cb_,_cb
# A regular expression matching the name of dummy variables (i.e. expectedly
# not used).
dummy-variables-rgx=_+$|(_[a-zA-Z0-9_]*[a-zA-Z0-9]+?$)|dummy|^ignored_|^unused_
# Argument names that match this expression will be ignored. Default to name
# with leading underscore
ignored-argument-names=_.*|^ignored_|^unused_
# Tells whether we should check for unused import in __init__ files.
init-import=no
# List of qualified module names which can have objects that can redefine
# builtins.
redefining-builtins-modules=six.moves,future.builtins
[SPELLING]
# Spelling dictionary name. Available dictionaries: none. To make it working
# install python-enchant package.
spelling-dict=
# List of comma separated words that should not be checked.
spelling-ignore-words=
# A path to a file that contains private dictionary; one word per line.
spelling-private-dict-file=
# Tells whether to store unknown words to indicated private dictionary in
# --spelling-private-dict-file option instead of raising a message.
spelling-store-unknown-words=no
[MISCELLANEOUS]
# List of note tags to take in consideration, separated by a comma.
notes=FIXME,XXX,TODO
[LOGGING]
# Logging modules to check that the string format arguments are in logging
# function parameter format
logging-modules=logging
[CLASSES]
# List of method names used to declare (i.e. assign) instance attributes.
defining-attr-methods=__init__,__new__,setUp
# List of member names, which should be excluded from the protected access
# warning.
exclude-protected=_asdict,_fields,_replace,_source,_make
# List of valid names for the first argument in a class method.
valid-classmethod-first-arg=cls
# List of valid names for the first argument in a metaclass class method.
valid-metaclass-classmethod-first-arg=mcs
[DESIGN]
# Maximum number of arguments for function / method
max-args=5
# Maximum number of attributes for a class (see R0902).
max-attributes=7
# Maximum number of boolean expressions in a if statement
max-bool-expr=5
# Maximum number of branch for function / method body
max-branches=12
# Maximum number of locals for function / method body
max-locals=15
# Maximum number of parents for a class (see R0901).
max-parents=7
# Maximum number of public methods for a class (see R0904).
max-public-methods=20
# Maximum number of return / yield for function / method body
max-returns=6
# Maximum number of statements in function / method body
max-statements=50
# Minimum number of public methods for a class (see R0903).
min-public-methods=2
[IMPORTS]
# Allow wildcard imports from modules that define __all__.
allow-wildcard-with-all=no
# Analyse import fallback blocks. This can be used to support both Python 2 and
# 3 compatible code, which means that the block might have code that exists
# only in one or another interpreter, leading to false positives when analysed.
analyse-fallback-blocks=no
# Deprecated modules which should not be used, separated by a comma
deprecated-modules=regsub,TERMIOS,Bastion,rexec
# Create a graph of external dependencies in the given file (report RP0402 must
# not be disabled)
ext-import-graph=
# Create a graph of every (i.e. internal and external) dependencies in the
# given file (report RP0402 must not be disabled)
import-graph=
# Create a graph of internal dependencies in the given file (report RP0402 must
# not be disabled)
int-import-graph=
# Force import order to recognize a module as part of the standard
# compatibility libraries.
known-standard-library=
# Force import order to recognize a module as part of a third party library.
known-third-party=enchant
[EXCEPTIONS]
# Exceptions that will emit a warning when being caught. Defaults to
# "Exception"
overgeneral-exceptions=Exception

View file

@ -0,0 +1,47 @@
language: c
compiler:
- clang
- gcc
sudo: false
cache: ccache
# blocklist
branches:
except:
- development-psa
- coverity_scan
script:
- tests/scripts/recursion.pl library/*.c
- tests/scripts/check-generated-files.sh
- tests/scripts/check-doxy-blocks.pl
- tests/scripts/check-names.sh
- tests/scripts/check-files.py
- tests/scripts/doxygen.sh
- cmake -D CMAKE_BUILD_TYPE:String="Check" .
- make
- make test
- programs/test/selftest
- OSSL_NO_DTLS=1 tests/compat.sh
- tests/ssl-opt.sh -e '\(DTLS\|SCSV\).*openssl'
- tests/scripts/test-ref-configs.pl
- tests/scripts/curves.pl
- tests/scripts/key-exchanges.pl
after_failure:
- tests/scripts/travis-log-failure.sh
env:
global:
secure: "barHldniAfXyoWOD/vcO+E6/Xm4fmcaUoC9BeKW+LwsHqlDMLvugaJnmLXkSpkbYhVL61Hzf3bo0KPJn88AFc5Rkf8oYHPjH4adMnVXkf3B9ghHCgznqHsAH3choo6tnPxaFgOwOYmLGb382nQxfE5lUdvnM/W/psQjWt66A1+k="
addons:
apt:
packages:
- doxygen
- graphviz
coverity_scan:
project:
name: "ARMmbed/mbedtls"
notification_email: simon.butcher@arm.com
build_command_prepend:
build_command: make
branch_pattern: coverity_scan

View file

@ -0,0 +1,234 @@
cmake_minimum_required(VERSION 2.6)
if(TEST_CPP)
project("mbed TLS" C CXX)
else()
project("mbed TLS" C)
endif()
option(USE_PKCS11_HELPER_LIBRARY "Build mbed TLS with the pkcs11-helper library." OFF)
option(ENABLE_ZLIB_SUPPORT "Build mbed TLS with zlib library." OFF)
option(ENABLE_PROGRAMS "Build mbed TLS programs." ON)
option(UNSAFE_BUILD "Allow unsafe builds. These builds ARE NOT SECURE." OFF)
string(REGEX MATCH "Clang" CMAKE_COMPILER_IS_CLANG "${CMAKE_C_COMPILER_ID}")
string(REGEX MATCH "GNU" CMAKE_COMPILER_IS_GNU "${CMAKE_C_COMPILER_ID}")
string(REGEX MATCH "IAR" CMAKE_COMPILER_IS_IAR "${CMAKE_C_COMPILER_ID}")
string(REGEX MATCH "MSVC" CMAKE_COMPILER_IS_MSVC "${CMAKE_C_COMPILER_ID}")
# the test suites currently have compile errors with MSVC
if(CMAKE_COMPILER_IS_MSVC)
option(ENABLE_TESTING "Build mbed TLS tests." OFF)
else()
option(ENABLE_TESTING "Build mbed TLS tests." ON)
endif()
# Warning string - created as a list for compatibility with CMake 2.8
set(WARNING_BORDER "*******************************************************\n")
set(NULL_ENTROPY_WARN_L1 "**** WARNING! MBEDTLS_TEST_NULL_ENTROPY defined!\n")
set(NULL_ENTROPY_WARN_L2 "**** THIS BUILD HAS NO DEFINED ENTROPY SOURCES\n")
set(NULL_ENTROPY_WARN_L3 "**** AND IS *NOT* SUITABLE FOR PRODUCTION USE\n")
set(NULL_ENTROPY_WARNING "${WARNING_BORDER}"
"${NULL_ENTROPY_WARN_L1}"
"${NULL_ENTROPY_WARN_L2}"
"${NULL_ENTROPY_WARN_L3}"
"${WARNING_BORDER}")
set(CTR_DRBG_128_BIT_KEY_WARN_L1 "**** WARNING! MBEDTLS_CTR_DRBG_USE_128_BIT_KEY defined!\n")
set(CTR_DRBG_128_BIT_KEY_WARN_L2 "**** Using 128-bit keys for CTR_DRBG limits the security of generated\n")
set(CTR_DRBG_128_BIT_KEY_WARN_L3 "**** keys and operations that use random values generated to 128-bit security\n")
set(CTR_DRBG_128_BIT_KEY_WARNING "${WARNING_BORDER}"
"${CTR_DRBG_128_BIT_KEY_WARN_L1}"
"${CTR_DRBG_128_BIT_KEY_WARN_L2}"
"${CTR_DRBG_128_BIT_KEY_WARN_L3}"
"${WARNING_BORDER}")
find_package(PythonInterp)
find_package(Perl)
if(PERL_FOUND)
# If 128-bit keys are configured for CTR_DRBG, display an appropriate warning
execute_process(COMMAND ${PERL_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/scripts/config.pl -f ${CMAKE_CURRENT_SOURCE_DIR}/include/mbedtls/config.h get MBEDTLS_CTR_DRBG_USE_128_BIT_KEY
RESULT_VARIABLE result)
if(${result} EQUAL 0)
message(WARNING ${CTR_DRBG_128_BIT_KEY_WARNING})
endif()
# If NULL Entropy is configured, display an appropriate warning
execute_process(COMMAND ${PERL_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/scripts/config.pl -f ${CMAKE_CURRENT_SOURCE_DIR}/include/mbedtls/config.h get MBEDTLS_TEST_NULL_ENTROPY
RESULT_VARIABLE result)
if(${result} EQUAL 0)
message(WARNING ${NULL_ENTROPY_WARNING})
if(NOT UNSAFE_BUILD)
message(FATAL_ERROR "\
\n\
Warning! You have enabled MBEDTLS_TEST_NULL_ENTROPY. \
This option is not safe for production use and negates all security \
It is intended for development use only. \
\n\
To confirm you want to build with this option, re-run cmake with the \
option: \n\
cmake -DUNSAFE_BUILD=ON ")
return()
endif()
endif()
endif()
set(CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE}
CACHE STRING "Choose the type of build: None Debug Release Coverage ASan ASanDbg MemSan MemSanDbg Check CheckFull"
FORCE)
# Create a symbolic link from ${base_name} in the binary directory
# to the corresponding path in the source directory.
function(link_to_source base_name)
# Get OS dependent path to use in `execute_process`
file(TO_NATIVE_PATH "${CMAKE_CURRENT_BINARY_DIR}/${base_name}" link)
file(TO_NATIVE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/${base_name}" target)
if (NOT EXISTS ${link})
if (CMAKE_HOST_UNIX)
set(command ln -s ${target} ${link})
else()
if (IS_DIRECTORY ${target})
set(command cmd.exe /c mklink /j ${link} ${target})
else()
set(command cmd.exe /c mklink /h ${link} ${target})
endif()
endif()
execute_process(COMMAND ${command}
RESULT_VARIABLE result
ERROR_VARIABLE output)
if (NOT ${result} EQUAL 0)
message(FATAL_ERROR "Could not create symbolic link for: ${target} --> ${output}")
endif()
endif()
endfunction(link_to_source)
string(REGEX MATCH "Clang" CMAKE_COMPILER_IS_CLANG "${CMAKE_C_COMPILER_ID}")
if(CMAKE_COMPILER_IS_GNU)
# some warnings we want are not available with old GCC versions
# note: starting with CMake 2.8 we could use CMAKE_C_COMPILER_VERSION
execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpversion
OUTPUT_VARIABLE GCC_VERSION)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -W -Wdeclaration-after-statement -Wwrite-strings")
if (GCC_VERSION VERSION_GREATER 4.5 OR GCC_VERSION VERSION_EQUAL 4.5)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wlogical-op")
endif()
if (GCC_VERSION VERSION_GREATER 4.8 OR GCC_VERSION VERSION_EQUAL 4.8)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wshadow")
endif()
set(CMAKE_C_FLAGS_RELEASE "-O2")
set(CMAKE_C_FLAGS_DEBUG "-O0 -g3")
set(CMAKE_C_FLAGS_COVERAGE "-O0 -g3 --coverage")
set(CMAKE_C_FLAGS_ASAN "-Werror -fsanitize=address -fno-common -O3")
set(CMAKE_C_FLAGS_ASANDBG "-Werror -fsanitize=address -fno-common -O1 -g3 -fno-omit-frame-pointer -fno-optimize-sibling-calls ")
set(CMAKE_C_FLAGS_CHECK "-Werror -Os")
set(CMAKE_C_FLAGS_CHECKFULL "${CMAKE_C_FLAGS_CHECK} -Wcast-qual")
endif(CMAKE_COMPILER_IS_GNU)
if(CMAKE_COMPILER_IS_CLANG)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -W -Wdeclaration-after-statement -Wwrite-strings -Wpointer-arith -Wimplicit-fallthrough -Wshadow")
set(CMAKE_C_FLAGS_RELEASE "-O2")
set(CMAKE_C_FLAGS_DEBUG "-O0 -g3")
set(CMAKE_C_FLAGS_COVERAGE "-O0 -g3 --coverage")
set(CMAKE_C_FLAGS_ASAN "-Werror -fsanitize=address -fno-common -fsanitize=undefined -fno-sanitize-recover=all -O3")
set(CMAKE_C_FLAGS_ASANDBG "-Werror -fsanitize=address -fno-common -fsanitize=undefined -fno-sanitize-recover=all -O1 -g3 -fno-omit-frame-pointer -fno-optimize-sibling-calls ")
set(CMAKE_C_FLAGS_MEMSAN "-Werror -fsanitize=memory -O3")
set(CMAKE_C_FLAGS_MEMSANDBG "-Werror -fsanitize=memory -O1 -g3 -fno-omit-frame-pointer -fno-optimize-sibling-calls -fsanitize-memory-track-origins=2")
set(CMAKE_C_FLAGS_CHECK "-Werror -Os")
endif(CMAKE_COMPILER_IS_CLANG)
if(CMAKE_COMPILER_IS_IAR)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --warn_about_c_style_casts --warnings_are_errors -Ohz")
endif(CMAKE_COMPILER_IS_IAR)
if(CMAKE_COMPILER_IS_MSVC)
# Strictest warnings, and treat as errors
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /W3")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /WX")
endif(CMAKE_COMPILER_IS_MSVC)
if(CMAKE_BUILD_TYPE STREQUAL "Coverage")
if(CMAKE_COMPILER_IS_GNU OR CMAKE_COMPILER_IS_CLANG)
set(CMAKE_SHARED_LINKER_FLAGS "--coverage")
endif(CMAKE_COMPILER_IS_GNU OR CMAKE_COMPILER_IS_CLANG)
endif(CMAKE_BUILD_TYPE STREQUAL "Coverage")
if(LIB_INSTALL_DIR)
else()
set(LIB_INSTALL_DIR lib)
endif()
include_directories(include/)
if(ENABLE_ZLIB_SUPPORT)
find_package(ZLIB)
if(ZLIB_FOUND)
include_directories(${ZLIB_INCLUDE_DIR})
endif(ZLIB_FOUND)
endif(ENABLE_ZLIB_SUPPORT)
add_subdirectory(library)
add_subdirectory(include)
if(ENABLE_PROGRAMS)
add_subdirectory(programs)
endif()
ADD_CUSTOM_TARGET(apidoc
COMMAND doxygen mbedtls.doxyfile
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/doxygen)
if(ENABLE_TESTING)
enable_testing()
add_subdirectory(tests)
# additional convenience targets for Unix only
if(UNIX)
ADD_CUSTOM_TARGET(covtest
COMMAND make test
COMMAND programs/test/selftest
COMMAND tests/compat.sh
COMMAND tests/ssl-opt.sh
)
ADD_CUSTOM_TARGET(lcov
COMMAND rm -rf Coverage
COMMAND lcov --capture --initial --directory library/CMakeFiles/mbedtls.dir -o files.info
COMMAND lcov --capture --directory library/CMakeFiles/mbedtls.dir -o tests.info
COMMAND lcov --add-tracefile files.info --add-tracefile tests.info -o all.info
COMMAND lcov --remove all.info -o final.info '*.h'
COMMAND gendesc tests/Descriptions.txt -o descriptions
COMMAND genhtml --title "mbed TLS" --description-file descriptions --keep-descriptions --legend --no-branch-coverage -o Coverage final.info
COMMAND rm -f files.info tests.info all.info final.info descriptions
)
ADD_CUSTOM_TARGET(memcheck
COMMAND sed -i.bak s+/usr/bin/valgrind+`which valgrind`+ DartConfiguration.tcl
COMMAND ctest -O memcheck.log -D ExperimentalMemCheck
COMMAND tail -n1 memcheck.log | grep 'Memory checking results:' > /dev/null
COMMAND rm -f memcheck.log
COMMAND mv DartConfiguration.tcl.bak DartConfiguration.tcl
)
endif(UNIX)
endif()
# Make scripts needed for testing available in an out-of-source build.
if (NOT ${CMAKE_CURRENT_BINARY_DIR} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR})
link_to_source(scripts)
# Copy (don't link) DartConfiguration.tcl, needed for memcheck, to
# keep things simple with the sed commands in the memcheck target.
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/DartConfiguration.tcl
${CMAKE_CURRENT_BINARY_DIR}/DartConfiguration.tcl COPYONLY)
endif()

View file

@ -0,0 +1,95 @@
Contributing
============
We gratefully accept bug reports and contributions from the community. There are some requirements we need to fulfill in order to be able to integrate contributions:
- As with any open source project, contributions will be reviewed by the project team and community and may need some modifications to be accepted.
- The contribution should not break API or ABI, unless there is a real justification for that. If there is an API change, the contribution, if accepted, will be merged only when there will be a major release.
Contributor License Agreement (CLA)
-----------------------------------
- All contributions, whether large or small, require a Contributor's License Agreement (CLA) to be accepted. This is because source code can possibly fall under copyright law and we need your consent to share in the ownership of the copyright.
- To accept the Contributors License Agreement (CLA), individual contributors can do this by creating an Mbed account and [accepting the online agreement here with a click through](https://developer.mbed.org/contributor_agreement/). Alternatively, for contributions from corporations, or those that do not wish to create an Mbed account, a slightly different agreement can be found [here](https://www.mbed.com/en/about-mbed/contributor-license-agreements/). This agreement should be signed and returned to Arm as described in the instructions given.
Coding Standards
----------------
- We would ask that contributions conform to [our coding standards](https://tls.mbed.org/kb/development/mbedtls-coding-standards), and that contributions are fully tested before submission, as mentioned in the [Tests](#tests) and [Continuous Integration](#continuous-integration-tests) sections.
- The code should be written in a clean and readable style.
- The code should be written in a portable generic way, that will benefit the whole community, and not only your own needs.
- The code should be secure, and will be reviewed from a security point of view as well.
Making a Contribution
---------------------
1. [Check for open issues](https://github.com/ARMmbed/mbedtls/issues) or [start a discussion](https://tls.mbed.org/discussions) around a feature idea or a bug.
1. Fork the [Mbed TLS repository on GitHub](https://github.com/ARMmbed/mbedtls) to start making your changes. As a general rule, you should use the ["development" branch](https://github.com/ARMmbed/mbedtls/tree/development) as a basis.
1. Write a test which shows that the bug was fixed or that the feature works as expected.
1. Send a pull request (PR) and work with us until it gets merged and published. Contributions may need some modifications, so a few rounds of review and fixing may be necessary. We will include your name in the ChangeLog :)
1. For quick merging, the contribution should be short, and concentrated on a single feature or topic. The larger the contribution is, the longer it would take to review it and merge it.
1. Mbed TLS is released under the Apache license, and as such, all the added files should include the Apache license header.
API/ABI Compatibility
---------------------
The project aims to minimise the impact on users upgrading to newer versions of the library and it should not be necessary for a user to make any changes to their own code to work with a newer version of the library. Unless the user has made an active decision to use newer features, a newer generation of the library or a change has been necessary due to a security issue or other significant software defect, no modifications to their own code should be necessary. To achieve this, API compatibility is maintained between different versions of Mbed TLS on the main development branch and in LTS (Long Term Support) branches.
To minimise such disruption to users, where a change to the interface is required, all changes to the ABI or API, even on the main development branch where new features are added, need to be justifiable by either being a significant enhancement, new feature or bug fix which is best resolved by an interface change.
Where changes to an existing interface are necessary, functions in the public interface which need to be changed, are marked as 'deprecated'. This is done with the preprocessor symbols `MBEDTLS_DEPRECATED_WARNING` and `MBEDTLS_DEPRECATED_REMOVED`. Then, a new function with a new name but similar if not identical behaviour to the original function containing the necessary changes should be created alongside the existing deprecated function.
When a build is made with the deprecation preprocessor symbols defined, a compiler warning will be generated to warn a user that the function will be removed at some point in the future, notifying users that they should change from the older deprecated function to the newer function at their own convenience.
Therefore, no changes are permitted to the definition of functions in the public interface which will change the API. Instead the interface can only be changed by its extension. As described above, if a function needs to be changed, a new function needs to be created alongside it, with a new name, and whatever change is necessary, such as a new parameter or the addition of a return value.
Periodically, the library will remove deprecated functions from the library which will be a breaking change in the API, but such changes will be made only in a planned, structured way that gives sufficient notice to users of the library.
Long Term Support Branches
--------------------------
Mbed TLS maintains several LTS (Long Term Support) branches, which are maintained continuously for a given period. The LTS branches are provided to allow users of the library to have a maintained, stable version of the library which contains only security fixes and fixes for other defects, without encountering additional features or API extensions which may introduce issues or change the code size or RAM usage, which can be significant considerations on some platforms. To allow users to take advantage of the LTS branches, these branches maintain backwards compatibility for both the public API and ABI.
When backporting to these branches please observe the following rules:
1. Any change to the library which changes the API or ABI cannot be backported.
2. All bug fixes that correct a defect that is also present in an LTS branch must be backported to that LTS branch. If a bug fix introduces a change to the API such as a new function, the fix should be reworked to avoid the API change. API changes without very strong justification are unlikely to be accepted.
3. If a contribution is a new feature or enhancement, no backporting is required. Exceptions to this may be addtional test cases or quality improvements such as changes to build or test scripts.
It would be highly appreciated if contributions are backported to LTS branches in addition to the [development branch](https://github.com/ARMmbed/mbedtls/tree/development) by contributors.
Currently maintained LTS branches are:
1. [mbedtls-2.1](https://github.com/ARMmbed/mbedtls/tree/mbedtls-2.1)
2. [mbedtls-2.7](https://github.com/ARMmbed/mbedtls/tree/mbedtls-2.7)
Tests
-----
As mentioned, tests that show the correctness of the feature or bug fix should be added to the pull request, if no such tests exist.
Mbed TLS includes a comprehensive set of test suites in the `tests/` directory that are dynamically generated to produce the actual test source files (e.g. `test_suite_mpi.c`). These files are generated from a `function file` (e.g. `suites/test_suite_mpi.function`) and a `data file` (e.g. `suites/test_suite_mpi.data`). The function file contains the test functions. The data file contains the test cases, specified as parameters that will be passed to the test function.
[A Knowledge Base article describing how to add additional tests is available on the Mbed TLS website](https://tls.mbed.org/kb/development/test_suites).
A test script `tests/scripts/basic-build-test.sh` is available to show test coverage of the library. New code contributions should provide a similar level of code coverage to that which already exists for the library.
Sample applications, if needed, should be modified as well.
Continuous Integration Tests
----------------------------
Once a PR has been made, the Continuous Integration (CI) tests are triggered and run. You should follow the result of the CI tests, and fix failures.
It is advised to enable the [githooks scripts](https://github.com/ARMmbed/mbedtls/tree/development/tests/git-scripts) prior to pushing your changes, for catching some of the issues as early as possible.
Documentation
-------------
Mbed TLS is well documented, but if you think documentation is needed, speak out!
1. All interfaces should be documented through Doxygen. New APIs should introduce Doxygen documentation.
2. Complex parts in the code should include comments.
3. If needed, a Readme file is advised.
4. If a [Knowledge Base (KB)](https://tls.mbed.org/kb) article should be added, write this as a comment in the PR description.
5. A [ChangeLog](https://github.com/ARMmbed/mbedtls/blob/development/ChangeLog) entry should be added for this contribution.

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,9 @@
config AOS_COMP_MBEDTLS
bool "mbedtls"
default n
help
AliOS Things Mbed TLS layer
if AOS_COMP_MBEDTLS
# Configurations for component mbedtls
endif

View file

@ -0,0 +1,4 @@
Site: localhost
BuildName: mbed TLS-test
CoverageCommand: /usr/bin/gcov
MemoryCheckCommand: /usr/bin/valgrind

View file

@ -0,0 +1,2 @@
Unless specifically indicated otherwise in a file, files are licensed
under the Apache 2.0 license, as can be found in: apache-2.0.txt

View file

@ -0,0 +1,122 @@
DESTDIR=/usr/local
PREFIX=mbedtls_
.SILENT:
.PHONY: all no_test programs lib tests install uninstall clean test check covtest lcov apidoc apidoc_clean
all: programs tests
$(MAKE) post_build
no_test: programs
programs: lib
$(MAKE) -C programs
lib:
$(MAKE) -C library
tests: lib
$(MAKE) -C tests
ifndef WINDOWS
install: no_test
mkdir -p $(DESTDIR)/include/mbedtls
cp -rp include/mbedtls $(DESTDIR)/include
mkdir -p $(DESTDIR)/lib
cp -RP library/libmbedtls.* $(DESTDIR)/lib
cp -RP library/libmbedx509.* $(DESTDIR)/lib
cp -RP library/libmbedcrypto.* $(DESTDIR)/lib
mkdir -p $(DESTDIR)/bin
for p in programs/*/* ; do \
if [ -x $$p ] && [ ! -d $$p ] ; \
then \
f=$(PREFIX)`basename $$p` ; \
cp $$p $(DESTDIR)/bin/$$f ; \
fi \
done
uninstall:
rm -rf $(DESTDIR)/include/mbedtls
rm -f $(DESTDIR)/lib/libmbedtls.*
rm -f $(DESTDIR)/lib/libmbedx509.*
rm -f $(DESTDIR)/lib/libmbedcrypto.*
for p in programs/*/* ; do \
if [ -x $$p ] && [ ! -d $$p ] ; \
then \
f=$(PREFIX)`basename $$p` ; \
rm -f $(DESTDIR)/bin/$$f ; \
fi \
done
endif
WARNING_BORDER =*******************************************************\n
NULL_ENTROPY_WARN_L1=**** WARNING! MBEDTLS_TEST_NULL_ENTROPY defined! ****\n
NULL_ENTROPY_WARN_L2=**** THIS BUILD HAS NO DEFINED ENTROPY SOURCES ****\n
NULL_ENTROPY_WARN_L3=**** AND IS *NOT* SUITABLE FOR PRODUCTION USE ****\n
NULL_ENTROPY_WARNING=\n$(WARNING_BORDER)$(NULL_ENTROPY_WARN_L1)$(NULL_ENTROPY_WARN_L2)$(NULL_ENTROPY_WARN_L3)$(WARNING_BORDER)
WARNING_BORDER_LONG =**********************************************************************************\n
CTR_DRBG_128_BIT_KEY_WARN_L1=**** WARNING! MBEDTLS_CTR_DRBG_USE_128_BIT_KEY defined! ****\n
CTR_DRBG_128_BIT_KEY_WARN_L2=**** Using 128-bit keys for CTR_DRBG limits the security of generated ****\n
CTR_DRBG_128_BIT_KEY_WARN_L3=**** keys and operations that use random values generated to 128-bit security ****\n
CTR_DRBG_128_BIT_KEY_WARNING=\n$(WARNING_BORDER_LONG)$(CTR_DRBG_128_BIT_KEY_WARN_L1)$(CTR_DRBG_128_BIT_KEY_WARN_L2)$(CTR_DRBG_128_BIT_KEY_WARN_L3)$(WARNING_BORDER_LONG)
# Post build steps
post_build:
ifndef WINDOWS
# If 128-bit keys are configured for CTR_DRBG, display an appropriate warning
-scripts/config.pl get MBEDTLS_CTR_DRBG_USE_128_BIT_KEY && ([ $$? -eq 0 ]) && \
echo '$(CTR_DRBG_128_BIT_KEY_WARNING)'
# If NULL Entropy is configured, display an appropriate warning
-scripts/config.pl get MBEDTLS_TEST_NULL_ENTROPY && ([ $$? -eq 0 ]) && \
echo '$(NULL_ENTROPY_WARNING)'
endif
clean:
$(MAKE) -C library clean
$(MAKE) -C programs clean
$(MAKE) -C tests clean
ifndef WINDOWS
find . \( -name \*.gcno -o -name \*.gcda -o -name \*.info \) -exec rm {} +
endif
check: lib tests
$(MAKE) -C tests check
test: check
ifndef WINDOWS
# note: for coverage testing, build with:
# make CFLAGS='--coverage -g3 -O0'
covtest:
$(MAKE) check
programs/test/selftest
tests/compat.sh
tests/ssl-opt.sh
lcov:
rm -rf Coverage
lcov --capture --initial --directory library -o files.info
lcov --capture --directory library -o tests.info
lcov --add-tracefile files.info --add-tracefile tests.info -o all.info
lcov --remove all.info -o final.info '*.h'
gendesc tests/Descriptions.txt -o descriptions
genhtml --title "mbed TLS" --description-file descriptions --keep-descriptions --legend --no-branch-coverage -o Coverage final.info
rm -f files.info tests.info all.info final.info descriptions
apidoc:
mkdir -p apidoc
cd doxygen && doxygen mbedtls.doxyfile
apidoc_clean:
rm -rf apidoc
endif

View file

@ -0,0 +1,187 @@
README for Mbed TLS
===================
Configuration
-------------
Mbed TLS should build out of the box on most systems. Some platform specific options are available in the fully documented configuration file `include/mbedtls/config.h`, which is also the place where features can be selected. This file can be edited manually, or in a more programmatic way using the Perl script `scripts/config.pl` (use `--help` for usage instructions).
Compiler options can be set using conventional environment variables such as `CC` and `CFLAGS` when using the Make and CMake build system (see below).
Compiling
---------
There are currently three active build systems used within Mbed TLS releases:
- GNU Make
- CMake
- Microsoft Visual Studio (Microsoft Visual Studio 2010 or later)
The main systems used for development are CMake and GNU Make. Those systems are always complete and up-to-date. The others should reflect all changes present in the CMake and Make build system, although features may not be ported there automatically.
The Make and CMake build systems create three libraries: libmbedcrypto, libmbedx509, and libmbedtls. Note that libmbedtls depends on libmbedx509 and libmbedcrypto, and libmbedx509 depends on libmbedcrypto. As a result, some linkers will expect flags to be in a specific order, for example the GNU linker wants `-lmbedtls -lmbedx509 -lmbedcrypto`. Also, when loading shared libraries using dlopen(), you'll need to load libmbedcrypto first, then libmbedx509, before you can load libmbedtls.
### Make
We require GNU Make. To build the library and the sample programs, GNU Make and a C compiler are sufficient. Some of the more advanced build targets require some Unix/Linux tools.
We intentionally only use a minimum of functionality in the makefiles in order to keep them as simple and independent of different toolchains as possible, to allow users to more easily move between different platforms. Users who need more features are recommended to use CMake.
In order to build from the source code using GNU Make, just enter at the command line:
make
In order to run the tests, enter:
make check
The tests need Perl to be built and run. If you don't have Perl installed, you can skip building the tests with:
make no_test
You'll still be able to run a much smaller set of tests with:
programs/test/selftest
In order to build for a Windows platform, you should use `WINDOWS_BUILD=1` if the target is Windows but the build environment is Unix-like (for instance when cross-compiling, or compiling from an MSYS shell), and `WINDOWS=1` if the build environment is a Windows shell (for instance using mingw32-make) (in that case some targets will not be available).
Setting the variable `SHARED` in your environment will build shared libraries in addition to the static libraries. Setting `DEBUG` gives you a debug build. You can override `CFLAGS` and `LDFLAGS` by setting them in your environment or on the make command line; compiler warning options may be overridden separately using `WARNING_CFLAGS`. Some directory-specific options (for example, `-I` directives) are still preserved.
Please note that setting `CFLAGS` overrides its default value of `-O2` and setting `WARNING_CFLAGS` overrides its default value (starting with `-Wall -W`), so if you just want to add some warning options to the default ones, you can do so by setting `CFLAGS=-O2 -Werror` for example. Setting `WARNING_CFLAGS` is useful when you want to get rid of its default content (for example because your compiler doesn't accept `-Wall` as an option). Directory-specific options cannot be overriden from the command line.
Depending on your platform, you might run into some issues. Please check the Makefiles in `library/`, `programs/` and `tests/` for options to manually add or remove for specific platforms. You can also check [the Mbed TLS Knowledge Base](https://tls.mbed.org/kb) for articles on your platform or issue.
In case you find that you need to do something else as well, please let us know what, so we can add it to the [Mbed TLS Knowledge Base](https://tls.mbed.org/kb).
### CMake
In order to build the source using CMake in a separate directory (recommended), just enter at the command line:
mkdir /path/to/build_dir && cd /path/to/build_dir
cmake /path/to/mbedtls_source
make
In order to run the tests, enter:
make test
The test suites need Perl to be built. If you don't have Perl installed, you'll want to disable the test suites with:
cmake -DENABLE_TESTING=Off /path/to/mbedtls_source
If you disabled the test suites, but kept the programs enabled, you can still run a much smaller set of tests with:
programs/test/selftest
To configure CMake for building shared libraries, use:
cmake -DUSE_SHARED_MBEDTLS_LIBRARY=On /path/to/mbedtls_source
There are many different build modes available within the CMake buildsystem. Most of them are available for gcc and clang, though some are compiler-specific:
- `Release`. This generates the default code without any unnecessary information in the binary files.
- `Debug`. This generates debug information and disables optimization of the code.
- `Coverage`. This generates code coverage information in addition to debug information.
- `ASan`. This instruments the code with AddressSanitizer to check for memory errors. (This includes LeakSanitizer, with recent version of gcc and clang.) (With recent version of clang, this mode also instruments the code with UndefinedSanitizer to check for undefined behaviour.)
- `ASanDbg`. Same as ASan but slower, with debug information and better stack traces.
- `MemSan`. This instruments the code with MemorySanitizer to check for uninitialised memory reads. Experimental, needs recent clang on Linux/x86\_64.
- `MemSanDbg`. Same as MemSan but slower, with debug information, better stack traces and origin tracking.
- `Check`. This activates the compiler warnings that depend on optimization and treats all warnings as errors.
Switching build modes in CMake is simple. For debug mode, enter at the command line:
cmake -D CMAKE_BUILD_TYPE=Debug /path/to/mbedtls_source
To list other available CMake options, use:
cmake -LH
Note that, with CMake, you can't adjust the compiler or its flags after the
initial invocation of cmake. This means that `CC=your_cc make` and `make
CC=your_cc` will *not* work (similarly with `CFLAGS` and other variables).
These variables need to be adjusted when invoking cmake for the first time,
for example:
CC=your_cc cmake /path/to/mbedtls_source
If you already invoked cmake and want to change those settings, you need to
remove the build directory and create it again.
Note that it is possible to build in-place; this will however overwrite the
provided Makefiles (see `scripts/tmp_ignore_makefiles.sh` if you want to
prevent `git status` from showing them as modified). In order to do so, from
the Mbed TLS source directory, use:
cmake .
make
If you want to change `CC` or `CFLAGS` afterwards, you will need to remove the
CMake cache. This can be done with the following command using GNU find:
find . -iname '*cmake*' -not -name CMakeLists.txt -exec rm -rf {} +
You can now make the desired change:
CC=your_cc cmake .
make
Regarding variables, also note that if you set CFLAGS when invoking cmake,
your value of CFLAGS doesn't override the content provided by cmake (depending
on the build mode as seen above), it's merely prepended to it.
### Microsoft Visual Studio
The build files for Microsoft Visual Studio are generated for Visual Studio 2010.
The solution file `mbedTLS.sln` contains all the basic projects needed to build the library and all the programs. The files in tests are not generated and compiled, as these need a perl environment as well. However, the selftest program in `programs/test/` is still available.
Example programs
----------------
We've included example programs for a lot of different features and uses in [`programs/`](programs/README.md). Most programs only focus on a single feature or usage scenario, so keep that in mind when copying parts of the code.
Tests
-----
Mbed TLS includes an elaborate test suite in `tests/` that initially requires Perl to generate the tests files (e.g. `test\_suite\_mpi.c`). These files are generated from a `function file` (e.g. `suites/test\_suite\_mpi.function`) and a `data file` (e.g. `suites/test\_suite\_mpi.data`). The `function file` contains the test functions. The `data file` contains the test cases, specified as parameters that will be passed to the test function.
For machines with a Unix shell and OpenSSL (and optionally GnuTLS) installed, additional test scripts are available:
- `tests/ssl-opt.sh` runs integration tests for various TLS options (renegotiation, resumption, etc.) and tests interoperability of these options with other implementations.
- `tests/compat.sh` tests interoperability of every ciphersuite with other implementations.
- `tests/scripts/test-ref-configs.pl` test builds in various reduced configurations.
- `tests/scripts/key-exchanges.pl` test builds in configurations with a single key exchange enabled
- `tests/scripts/all.sh` runs a combination of the above tests, plus some more, with various build options (such as ASan, full `config.h`, etc).
Configurations
--------------
We provide some non-standard configurations focused on specific use cases in the `configs/` directory. You can read more about those in `configs/README.txt`
Porting Mbed TLS
----------------
Mbed TLS can be ported to many different architectures, OS's and platforms. Before starting a port, you may find the following Knowledge Base articles useful:
- [Porting Mbed TLS to a new environment or OS](https://tls.mbed.org/kb/how-to/how-do-i-port-mbed-tls-to-a-new-environment-OS)
- [What external dependencies does Mbed TLS rely on?](https://tls.mbed.org/kb/development/what-external-dependencies-does-mbedtls-rely-on)
- [How do I configure Mbed TLS](https://tls.mbed.org/kb/compiling-and-building/how-do-i-configure-mbedtls)
Contributing
------------
We gratefully accept bug reports and contributions from the community. There are some requirements we need to fulfill in order to be able to integrate contributions:
- All contributions, whether large or small require a Contributor's License Agreement (CLA) to be accepted. This is because source code can possibly fall under copyright law and we need your consent to share in the ownership of the copyright.
- We would ask that contributions conform to [our coding standards](https://tls.mbed.org/kb/development/mbedtls-coding-standards), and that contributions should be fully tested before submission.
- As with any open source project, contributions will be reviewed by the project team and community and may need some modifications to be accepted.
To accept the Contributors Licence Agreement (CLA), individual contributors can do this by creating an Mbed account and [accepting the online agreement here with a click through](https://os.mbed.com/contributor_agreement/). Alternatively, for contributions from corporations, or those that do not wish to create an Mbed account, a slightly different agreement can be found [here](https://www.mbed.com/en/about-mbed/contributor-license-agreements/). This agreement should be signed and returned to Arm as described in the instructions given.
### Making a Contribution
1. [Check for open issues](https://github.com/ARMmbed/mbedtls/issues) or [start a discussion](https://forums.mbed.com/c/mbed-tls) around a feature idea or a bug.
2. Fork the [Mbed TLS repository on GitHub](https://github.com/ARMmbed/mbedtls) to start making your changes. As a general rule, you should use the "development" branch as a basis.
3. Write a test which shows that the bug was fixed or that the feature works as expected.
4. Send a pull request and bug us until it gets merged and published. Contributions may need some modifications, so work with us to get your change accepted. We will include your name in the ChangeLog :)

View file

@ -0,0 +1,14 @@
## Introduction
This Mbed TLS layer is ported from the open source Mbed TLS, and we only modified the needed parts
to adapt to AliOS Things, so this layer provides the same APIs and features as the open source
Mbed TLS. For details, please refer to https://tls.mbed.org/ .
The major modification for porting Mbed TLS includes:
- provides our network socket APIs in aos/library/net_sockets.c
- provides our threading mutex APIs in aos/library/threading_alt.c
- provides our memory management APIs in aos/library/platform.c
- provides our configuration in include/mbedtls/config.h
## Dependencies
N/A

View file

@ -0,0 +1,30 @@
/*
* Copyright (C) 2018 Alibaba Group Holding Limited
*/
#ifndef MBEDTLS_THREADING_ALT_H
#define MBEDTLS_THREADING_ALT_H
#include <stdlib.h>
#include <aos/kernel.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct
{
aos_mutex_t mutex;
char is_valid;
} mbedtls_threading_mutex_t;
void threading_mutex_init( mbedtls_threading_mutex_t *mutex );
void threading_mutex_free( mbedtls_threading_mutex_t *mutex );
int threading_mutex_lock( mbedtls_threading_mutex_t *mutex );
int threading_mutex_unlock( mbedtls_threading_mutex_t *mutex );
#ifdef __cplusplus
}
#endif
#endif /* MBEDTLS_THREADING_ALT_H */

View file

@ -0,0 +1,395 @@
/*
* TCP/IP or UDP/IP networking functions
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#if !defined(MBEDTLS_NET_C)
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include "mbedtls/net_sockets.h"
#if defined(STM32_USE_SPI_WIFI)
#include "stm32_wifi.h"
#define WIFI_WRITE_TIMEOUT 200
#define WIFI_READ_TIMEOUT 200
#define WIFI_PAYLOAD_SIZE ES_WIFI_PAYLOAD_SIZE
#define WIFI_READ_RETRY_TIME 5
void mbedtls_net_init( mbedtls_net_context *ctx )
{
ctx->fd = -1;
}
int mbedtls_net_connect( mbedtls_net_context *ctx, const char *host, const char *port, int proto )
{
WIFI_Status_t ret;
WIFI_Protocol_t type;
uint8_t ip_addr[4];
ret = WIFI_GetHostAddress( (char *)host, ip_addr );
if( ret != WIFI_STATUS_OK )
return( MBEDTLS_ERR_NET_UNKNOWN_HOST );
type = ( proto == MBEDTLS_NET_PROTO_UDP ?
WIFI_UDP_PROTOCOL : WIFI_TCP_PROTOCOL );
ret = WIFI_OpenClientConnection( 0, type, "", ip_addr, atoi(port), 0 );
if( ret != WIFI_STATUS_OK )
return( MBEDTLS_ERR_NET_CONNECT_FAILED );
ctx->fd = 0;
return( ret );
}
int mbedtls_net_recv( void *ctx, unsigned char *buf, size_t len )
{
WIFI_Status_t ret;
uint16_t recv_size;
int fd = ((mbedtls_net_context *) ctx)->fd;
if (fd < 0)
return( MBEDTLS_ERR_NET_INVALID_CONTEXT );
if ( len > WIFI_PAYLOAD_SIZE )
len = WIFI_PAYLOAD_SIZE;
int err_count = 0;
do
{
ret = WIFI_ReceiveData( (uint8_t)fd,
buf, (uint16_t)len,
&recv_size, WIFI_READ_TIMEOUT );
if( ret != WIFI_STATUS_OK )
return( MBEDTLS_ERR_NET_RECV_FAILED );
if( recv_size == 0 )
{
if( err_count == WIFI_READ_RETRY_TIME )
return( MBEDTLS_ERR_SSL_WANT_READ );
else
err_count++;
}
} while( ( ret == WIFI_STATUS_OK ) && ( recv_size == 0 ) );
return( recv_size );
}
int mbedtls_net_recv_timeout( void *ctx, unsigned char *buf, size_t len,
uint32_t timeout )
{
WIFI_Status_t ret;
uint16_t recv_size;
int fd = ((mbedtls_net_context *) ctx)->fd;
if( fd < 0 )
return( MBEDTLS_ERR_NET_INVALID_CONTEXT );
if( len > WIFI_PAYLOAD_SIZE )
len = WIFI_PAYLOAD_SIZE;
int err_count = 0;
do
{
ret = WIFI_ReceiveData( (uint8_t)fd,
buf, (uint16_t)len,
&recv_size, WIFI_READ_TIMEOUT );
if( ret != WIFI_STATUS_OK )
return( MBEDTLS_ERR_NET_RECV_FAILED );
if( recv_size == 0 )
{
if( err_count == WIFI_READ_RETRY_TIME )
return( MBEDTLS_ERR_SSL_WANT_READ );
else
err_count++;
}
} while( ( ret == WIFI_STATUS_OK ) && ( recv_size == 0 ) );
return( recv_size );
}
int mbedtls_net_send( void *ctx, const unsigned char *buf, size_t len )
{
WIFI_Status_t ret;
uint16_t send_size;
uint16_t once_len;
uint8_t *pdata = (uint8_t *)buf;
uint16_t send_total = 0;
int fd = ((mbedtls_net_context *) ctx)->fd;
if( fd < 0 )
return( MBEDTLS_ERR_NET_INVALID_CONTEXT );
do
{
if( len > WIFI_PAYLOAD_SIZE )
{
once_len = WIFI_PAYLOAD_SIZE;
len -= WIFI_PAYLOAD_SIZE;
}
else
{
once_len = len;
len = 0;
}
ret = WIFI_SendData( (uint8_t)fd,
pdata, once_len,
&send_size, WIFI_WRITE_TIMEOUT );
if( ret != WIFI_STATUS_OK )
return( MBEDTLS_ERR_NET_SEND_FAILED );
pdata += once_len;
send_total += send_size;
} while ( len > 0 );
return( send_total );
}
void mbedtls_net_free( mbedtls_net_context *ctx )
{
WIFI_Status_t ret;
if (ctx->fd == -1)
return;
ret = WIFI_CloseClientConnection( (uint32_t)ctx->fd );
if( ret != WIFI_STATUS_OK )
return;
ctx->fd = -1;
}
#else /* STM32_USE_SPI_WIFI */
#include <fcntl.h>
#include <unistd.h>
#include <aos/errno.h>
#include <aos/network.h>
void mbedtls_net_init( mbedtls_net_context *ctx )
{
ctx->fd = -1;
}
int mbedtls_net_connect( mbedtls_net_context *ctx, const char *host, const char *port, int proto )
{
int ret;
struct addrinfo hints, *addr_list, *cur;
memset( &hints, 0, sizeof( hints ) );
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = proto == MBEDTLS_NET_PROTO_UDP ? SOCK_DGRAM : SOCK_STREAM;
hints.ai_protocol = proto == MBEDTLS_NET_PROTO_UDP ? IPPROTO_UDP : IPPROTO_TCP;
if( getaddrinfo( host, port, &hints, &addr_list ) != 0 )
return( MBEDTLS_ERR_NET_UNKNOWN_HOST );
ret = MBEDTLS_ERR_NET_UNKNOWN_HOST;
for( cur = addr_list; cur != NULL; cur = cur->ai_next )
{
ctx->fd = (int) socket( cur->ai_family,
cur->ai_socktype, cur->ai_protocol );
if( ctx->fd < 0 )
{
ret = MBEDTLS_ERR_NET_SOCKET_FAILED;
continue;
}
do
{
ret = connect( ctx->fd, cur->ai_addr, cur->ai_addrlen );
if( ret == 0 )
goto out;
else
{
if (errno == EINTR)
continue;
break;
}
} while( 1 );
close( ctx->fd );
ret = MBEDTLS_ERR_NET_CONNECT_FAILED;
}
out:
freeaddrinfo( addr_list );
return( ret );
}
static int net_would_block( const mbedtls_net_context *ctx )
{
int err = errno;
/*
* Never return 'WOULD BLOCK' on a non-blocking socket
*/
if( ( fcntl( ctx->fd, F_GETFL, 0) & O_NONBLOCK ) != O_NONBLOCK )
{
errno = err;
return( 0 );
}
switch( errno = err )
{
#if defined EAGAIN
case EAGAIN:
#endif
#if defined EWOULDBLOCK && EWOULDBLOCK != EAGAIN
case EWOULDBLOCK:
#endif
return( 1 );
}
return( 0 );
}
int mbedtls_net_set_block( mbedtls_net_context *ctx )
{
int flags;
flags = fcntl( ctx->fd, F_GETFL, 0 );
flags &= ~O_NONBLOCK;
return fcntl( ctx->fd, F_SETFL, flags );
}
int mbedtls_net_set_nonblock( mbedtls_net_context *ctx )
{
int flags;
flags = fcntl( ctx->fd, F_GETFL, 0 );
flags |= O_NONBLOCK;
return fcntl( ctx->fd, F_SETFL, flags );
}
int mbedtls_net_recv( void *ctx, unsigned char *buf, size_t len )
{
int ret;
int fd = ((mbedtls_net_context *) ctx)->fd;
if( fd < 0 )
return( MBEDTLS_ERR_NET_INVALID_CONTEXT );
ret = (int) read( fd, buf, len );
if( ret < 0 )
{
if( net_would_block( ctx ) != 0 )
return( MBEDTLS_ERR_SSL_WANT_READ );
if( errno == EPIPE || errno == ECONNRESET )
return( MBEDTLS_ERR_NET_CONN_RESET );
if( errno == EINTR )
return( MBEDTLS_ERR_SSL_WANT_READ );
return( MBEDTLS_ERR_NET_RECV_FAILED );
}
return( ret );
}
int mbedtls_net_recv_timeout( void *ctx, unsigned char *buf, size_t len,
uint32_t timeout )
{
int ret;
struct timeval tv;
fd_set read_fds;
int fd = ((mbedtls_net_context *) ctx)->fd;
if( fd < 0 )
return( MBEDTLS_ERR_NET_INVALID_CONTEXT );
FD_ZERO( &read_fds );
FD_SET( fd, &read_fds );
tv.tv_sec = timeout / 1000;
tv.tv_usec = ( timeout % 1000 ) * 1000;
ret = select( fd + 1, &read_fds, NULL, NULL, timeout == 0 ? NULL : &tv );
if( ret == 0 )
return( MBEDTLS_ERR_SSL_TIMEOUT );
if( ret < 0 )
{
if( errno == EINTR )
return( MBEDTLS_ERR_SSL_WANT_READ );
return( MBEDTLS_ERR_NET_RECV_FAILED );
}
return( mbedtls_net_recv( ctx, buf, len ) );
}
int mbedtls_net_send(void *ctx, const unsigned char *buf, size_t len)
{
int ret;
int fd = ((mbedtls_net_context *) ctx)->fd;
if( fd < 0 )
return( MBEDTLS_ERR_NET_INVALID_CONTEXT );
ret = (int) write( fd, buf, len );
if( ret < 0 )
{
if( net_would_block( ctx ) != 0 )
return( MBEDTLS_ERR_SSL_WANT_WRITE );
if( errno == EPIPE || errno == ECONNRESET )
return( MBEDTLS_ERR_NET_CONN_RESET );
if( errno == EINTR )
return( MBEDTLS_ERR_SSL_WANT_WRITE );
return( MBEDTLS_ERR_NET_SEND_FAILED );
}
return ret;
}
void mbedtls_net_free( mbedtls_net_context *ctx )
{
if( ctx->fd == -1 )
return;
shutdown( ctx->fd, 2 );
close( ctx->fd );
ctx->fd = -1;
}
#endif /* STM32_USE_SPI_WIFI */
#endif /* MBEDTLS_NET_C */

View file

@ -0,0 +1,80 @@
/*
* Copyright (C) 2015-2018 Alibaba Group Holding Limited
*/
/* This file provides implementation of common (libc) functions that is defined
* in platform abstraction layer for AliOS Things.
*/
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#if defined(MBEDTLS_PLATFORM_C)
#include <stdlib.h>
#include <string.h>
#include <aos/kernel.h>
#if defined(MBEDTLS_PLATFORM_MEMORY)
#if defined(XTENSA_MALLOC_IRAM)
extern void *iram_heap_malloc( size_t xWantedSize );
extern void iram_heap_free( void *pv );
extern int iram_heap_check_addr( void *addr );
void * aos_mbedtls_calloc( size_t n, size_t size )
{
void *buf = NULL;
if( ( n == 0 ) || ( size == 0 ) )
return( NULL );
buf = iram_heap_malloc( n * size );
if( buf == NULL )
buf = malloc( n * size );
if( buf == NULL )
return( NULL );
else
memset( buf, 0, n * size );
return( buf );
}
void aos_mbedtls_free( void *ptr )
{
if( ptr == NULL )
return;
if( iram_heap_check_addr( ptr ) == 1 )
iram_heap_free( ptr );
else
free( ptr );
}
#else /*XTENSA_MALLOC_IRAM*/
void * aos_mbedtls_calloc( size_t n, size_t size )
{
void *buf = NULL;
buf = aos_malloc(n * size);
if( buf == NULL )
return( NULL );
else
memset(buf, 0, n * size);
return( buf );
}
void aos_mbedtls_free( void *ptr )
{
if( ptr == NULL )
return;
aos_free( ptr );
}
#endif /*XTENSA_MALLOC_IRAM*/
#endif /*MBEDTLS_PLATFORM_MEMORY*/
#endif /*MBEDTLS_PLATFORM_C*/

View file

@ -0,0 +1,57 @@
/*
* Copyright (C) 2018 Alibaba Group Holding Limited
*/
/* This file provides threading mutex implementation for AliOS Things. */
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#if defined(MBEDTLS_THREADING_ALT)
#include <aos/kernel.h>
#include "mbedtls/threading.h"
void threading_mutex_init( mbedtls_threading_mutex_t *mutex )
{
if( mutex == NULL || mutex->is_valid )
return;
mutex->is_valid = ( aos_mutex_new( &mutex->mutex ) == 0 );
}
void threading_mutex_free( mbedtls_threading_mutex_t *mutex )
{
if( mutex == NULL || !mutex->is_valid )
return;
aos_mutex_free( &mutex->mutex );
mutex->is_valid = 0;
}
int threading_mutex_lock( mbedtls_threading_mutex_t *mutex )
{
if( mutex == NULL || !mutex->is_valid )
return( MBEDTLS_ERR_THREADING_BAD_INPUT_DATA );
if( aos_mutex_lock( &mutex->mutex, AOS_WAIT_FOREVER ) != 0 )
return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
return( 0 );
}
int threading_mutex_unlock( mbedtls_threading_mutex_t *mutex )
{
if( mutex == NULL || ! mutex->is_valid )
return( MBEDTLS_ERR_THREADING_BAD_INPUT_DATA );
if( aos_mutex_unlock( &mutex->mutex ) != 0 )
return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
return( 0 );
}
#endif /* MBEDTLS_THREADING_ALT */

View file

@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View file

@ -0,0 +1,44 @@
# Purpose:
# - To test and prove that a new commit in the mbed TLS repository builds
# and integrates with mbed-os properly.
# AND
# - To test and prove that the current development head of mbed TLS builds
# and integrates with the current mbed-os master branch.
#
# The script fetches all the prerequisites and builds the mbed TLS 'tls-client'
# example. This script is triggered by every commit and once each night and the
# exact behaviour depends on how it was triggered:
# - If it is a nightly build then it builds the mbed TLS development head with
# mbed-os master.
# - If it was triggered by the commit, then it builds the example with mbed TLS
# at that commit and mbed-os at the commit pointed by mbed-os.lib in the
# example repository.
test:
override:
- cd ../mbed-os-example-tls/tls-client/ && mbed compile -m K64F -t GCC_ARM -c
dependencies:
pre:
# Install gcc-arm
- cd .. && wget "https://launchpad.net/gcc-arm-embedded/4.9/4.9-2015-q3-update/+download/gcc-arm-none-eabi-4_9-2015q3-20150921-linux.tar.bz2"
- cd .. && tar -xvjf gcc-arm-none-eabi-4_9-2015q3-20150921-linux.tar.bz2
- ln -s ../gcc-arm-none-eabi-4_9-2015q3/bin/* ../bin/
# Install mbed-cli
- cd ../ && git clone https://github.com/ARMmbed/mbed-cli.git
- cd ../mbed-cli && sudo -H pip install -e .
# Get the sample application
- cd ../ && git clone git@github.com:ARMmbed/mbed-os-example-tls.git
# Get mbed-os
- cd ../mbed-os-example-tls/tls-client && mbed deploy
# Update mbed-os to master only if it is a nightly build
- >
if [ -n "${RUN_NIGHTLY_BUILD}" ]; then
cd ../mbed-os-example-tls/tls-client/mbed-os/ && mbed update master;
fi
# Import mbedtls current revision
- ln -s ../../../../../../../mbedtls/ ../mbed-os-example-tls/tls-client/mbed-os/features/mbedtls/importer/TARGET_IGNORE/mbedtls
- cd ../mbed-os-example-tls/tls-client/mbed-os/features/mbedtls/importer/ && make
override:
# Install the missing python packages
- cd ../mbed-os-example-tls/tls-client/mbed-os/ && sudo -H pip install -r requirements.txt

View file

@ -0,0 +1,26 @@
This directory contains example configuration files.
The examples are generally focused on a particular usage case (eg, support for
a restricted number of ciphersuites) and aim at minimizing resource usage for
this target. They can be used as a basis for custom configurations.
These files are complete replacements for the default config.h. To use one of
them, you can pick one of the following methods:
1. Replace the default file include/mbedtls/config.h with the chosen one.
(Depending on your compiler, you may need to adjust the line with
#include "mbedtls/check_config.h" then.)
2. Define MBEDTLS_CONFIG_FILE and adjust the include path accordingly.
For example, using make:
CFLAGS="-I$PWD/configs -DMBEDTLS_CONFIG_FILE='<foo.h>'" make
Or, using cmake:
find . -iname '*cmake*' -not -name CMakeLists.txt -exec rm -rf {} +
CFLAGS="-I$PWD/configs -DMBEDTLS_CONFIG_FILE='<foo.h>'" cmake .
make
Note that the second method also works if you want to keep your custom
configuration file outside the mbed TLS tree.

View file

@ -0,0 +1,88 @@
/**
* \file config-ccm-psk-tls1_2.h
*
* \brief Minimal configuration for TLS 1.2 with PSK and AES-CCM ciphersuites
*/
/*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
/*
* Minimal configuration for TLS 1.2 with PSK and AES-CCM ciphersuites
* Distinguishing features:
* - no bignum, no PK, no X509
* - fully modern and secure (provided the pre-shared keys have high entropy)
* - very low record overhead with CCM-8
* - optimized for low RAM usage
*
* See README.txt for usage instructions.
*/
#ifndef MBEDTLS_CONFIG_H
#define MBEDTLS_CONFIG_H
/* System support */
//#define MBEDTLS_HAVE_TIME /* Optionally used in Hello messages */
/* Other MBEDTLS_HAVE_XXX flags irrelevant for this configuration */
/* mbed TLS feature support */
#define MBEDTLS_KEY_EXCHANGE_PSK_ENABLED
#define MBEDTLS_SSL_PROTO_TLS1_2
/* mbed TLS modules */
#define MBEDTLS_AES_C
#define MBEDTLS_CCM_C
#define MBEDTLS_CIPHER_C
#define MBEDTLS_CTR_DRBG_C
#define MBEDTLS_ENTROPY_C
#define MBEDTLS_MD_C
#define MBEDTLS_NET_C
#define MBEDTLS_SHA256_C
#define MBEDTLS_SSL_CLI_C
#define MBEDTLS_SSL_SRV_C
#define MBEDTLS_SSL_TLS_C
/* Save RAM at the expense of ROM */
#define MBEDTLS_AES_ROM_TABLES
/* Save some RAM by adjusting to your exact needs */
#define MBEDTLS_PSK_MAX_LEN 16 /* 128-bits keys are generally enough */
/*
* You should adjust this to the exact number of sources you're using: default
* is the "platform_entropy_poll" source, but you may want to add other ones
* Minimum is 2 for the entropy test suite.
*/
#define MBEDTLS_ENTROPY_MAX_SOURCES 2
/*
* Use only CCM_8 ciphersuites, and
* save ROM and a few bytes of RAM by specifying our own ciphersuite list
*/
#define MBEDTLS_SSL_CIPHERSUITES \
MBEDTLS_TLS_PSK_WITH_AES_256_CCM_8, \
MBEDTLS_TLS_PSK_WITH_AES_128_CCM_8
/*
* Save RAM at the expense of interoperability: do this only if you control
* both ends of the connection! (See comments in "mbedtls/ssl.h".)
* The optimal size here depends on the typical size of records.
*/
#define MBEDTLS_SSL_MAX_CONTENT_LEN 1024
#include "mbedtls/check_config.h"
#endif /* MBEDTLS_CONFIG_H */

View file

@ -0,0 +1,78 @@
/**
* \file config-mini-tls1_1.h
*
* \brief Minimal configuration for TLS 1.1 (RFC 4346)
*/
/*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
/*
* Minimal configuration for TLS 1.1 (RFC 4346), implementing only the
* required ciphersuite: MBEDTLS_TLS_RSA_WITH_3DES_EDE_CBC_SHA
*
* See README.txt for usage instructions.
*/
#ifndef MBEDTLS_CONFIG_H
#define MBEDTLS_CONFIG_H
/* System support */
#define MBEDTLS_HAVE_ASM
#define MBEDTLS_HAVE_TIME
/* mbed TLS feature support */
#define MBEDTLS_CIPHER_MODE_CBC
#define MBEDTLS_PKCS1_V15
#define MBEDTLS_KEY_EXCHANGE_RSA_ENABLED
#define MBEDTLS_SSL_PROTO_TLS1_1
/* mbed TLS modules */
#define MBEDTLS_AES_C
#define MBEDTLS_ASN1_PARSE_C
#define MBEDTLS_ASN1_WRITE_C
#define MBEDTLS_BIGNUM_C
#define MBEDTLS_CIPHER_C
#define MBEDTLS_CTR_DRBG_C
#define MBEDTLS_DES_C
#define MBEDTLS_ENTROPY_C
#define MBEDTLS_MD_C
#define MBEDTLS_MD5_C
#define MBEDTLS_NET_C
#define MBEDTLS_OID_C
#define MBEDTLS_PK_C
#define MBEDTLS_PK_PARSE_C
#define MBEDTLS_RSA_C
#define MBEDTLS_SHA1_C
#define MBEDTLS_SHA256_C
#define MBEDTLS_SSL_CLI_C
#define MBEDTLS_SSL_SRV_C
#define MBEDTLS_SSL_TLS_C
#define MBEDTLS_X509_CRT_PARSE_C
#define MBEDTLS_X509_USE_C
/* For test certificates */
#define MBEDTLS_BASE64_C
#define MBEDTLS_CERTS_C
#define MBEDTLS_PEM_PARSE_C
/* For testing with compat.sh */
#define MBEDTLS_FS_IO
#include "mbedtls/check_config.h"
#endif /* MBEDTLS_CONFIG_H */

View file

@ -0,0 +1,92 @@
/**
* \file config-no-entropy.h
*
* \brief Minimal configuration of features that do not require an entropy source
*/
/*
* Copyright (C) 2016, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
/*
* Minimal configuration of features that do not require an entropy source
* Distinguishing reatures:
* - no entropy module
* - no TLS protocol implementation available due to absence of an entropy
* source
*
* See README.txt for usage instructions.
*/
#ifndef MBEDTLS_CONFIG_H
#define MBEDTLS_CONFIG_H
/* System support */
#define MBEDTLS_HAVE_ASM
#define MBEDTLS_HAVE_TIME
/* mbed TLS feature support */
#define MBEDTLS_CIPHER_MODE_CBC
#define MBEDTLS_CIPHER_PADDING_PKCS7
#define MBEDTLS_REMOVE_ARC4_CIPHERSUITES
#define MBEDTLS_ECP_DP_SECP256R1_ENABLED
#define MBEDTLS_ECP_DP_SECP384R1_ENABLED
#define MBEDTLS_ECP_DP_CURVE25519_ENABLED
#define MBEDTLS_ECP_NIST_OPTIM
#define MBEDTLS_ECDSA_DETERMINISTIC
#define MBEDTLS_PK_RSA_ALT_SUPPORT
#define MBEDTLS_PKCS1_V15
#define MBEDTLS_PKCS1_V21
#define MBEDTLS_SELF_TEST
#define MBEDTLS_VERSION_FEATURES
#define MBEDTLS_X509_CHECK_KEY_USAGE
#define MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE
/* mbed TLS modules */
#define MBEDTLS_AES_C
#define MBEDTLS_ASN1_PARSE_C
#define MBEDTLS_ASN1_WRITE_C
#define MBEDTLS_BASE64_C
#define MBEDTLS_BIGNUM_C
#define MBEDTLS_CCM_C
#define MBEDTLS_CIPHER_C
#define MBEDTLS_ECDSA_C
#define MBEDTLS_ECP_C
#define MBEDTLS_ERROR_C
#define MBEDTLS_GCM_C
#define MBEDTLS_HMAC_DRBG_C
#define MBEDTLS_MD_C
#define MBEDTLS_OID_C
#define MBEDTLS_PEM_PARSE_C
#define MBEDTLS_PK_C
#define MBEDTLS_PK_PARSE_C
#define MBEDTLS_PK_WRITE_C
#define MBEDTLS_PLATFORM_C
#define MBEDTLS_RSA_C
#define MBEDTLS_SHA256_C
#define MBEDTLS_SHA512_C
#define MBEDTLS_VERSION_C
#define MBEDTLS_X509_USE_C
#define MBEDTLS_X509_CRT_PARSE_C
#define MBEDTLS_X509_CRL_PARSE_C
//#define MBEDTLS_CMAC_C
/* Miscellaneous options */
#define MBEDTLS_AES_ROM_TABLES
#include "check_config.h"
#endif /* MBEDTLS_CONFIG_H */

View file

@ -0,0 +1,117 @@
/**
* \file config-suite-b.h
*
* \brief Minimal configuration for TLS NSA Suite B Profile (RFC 6460)
*/
/*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
/*
* Minimal configuration for TLS NSA Suite B Profile (RFC 6460)
*
* Distinguishing features:
* - no RSA or classic DH, fully based on ECC
* - optimized for low RAM usage
*
* Possible improvements:
* - if 128-bit security is enough, disable secp384r1 and SHA-512
* - use embedded certs in DER format and disable PEM_PARSE_C and BASE64_C
*
* See README.txt for usage instructions.
*/
#ifndef MBEDTLS_CONFIG_H
#define MBEDTLS_CONFIG_H
/* System support */
#define MBEDTLS_HAVE_ASM
#define MBEDTLS_HAVE_TIME
/* mbed TLS feature support */
#define MBEDTLS_ECP_DP_SECP256R1_ENABLED
#define MBEDTLS_ECP_DP_SECP384R1_ENABLED
#define MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
#define MBEDTLS_SSL_PROTO_TLS1_2
/* mbed TLS modules */
#define MBEDTLS_AES_C
#define MBEDTLS_ASN1_PARSE_C
#define MBEDTLS_ASN1_WRITE_C
#define MBEDTLS_BIGNUM_C
#define MBEDTLS_CIPHER_C
#define MBEDTLS_CTR_DRBG_C
#define MBEDTLS_ECDH_C
#define MBEDTLS_ECDSA_C
#define MBEDTLS_ECP_C
#define MBEDTLS_ENTROPY_C
#define MBEDTLS_GCM_C
#define MBEDTLS_MD_C
#define MBEDTLS_NET_C
#define MBEDTLS_OID_C
#define MBEDTLS_PK_C
#define MBEDTLS_PK_PARSE_C
#define MBEDTLS_SHA256_C
#define MBEDTLS_SHA512_C
#define MBEDTLS_SSL_CLI_C
#define MBEDTLS_SSL_SRV_C
#define MBEDTLS_SSL_TLS_C
#define MBEDTLS_X509_CRT_PARSE_C
#define MBEDTLS_X509_USE_C
/* For test certificates */
#define MBEDTLS_BASE64_C
#define MBEDTLS_CERTS_C
#define MBEDTLS_PEM_PARSE_C
/* Save RAM at the expense of ROM */
#define MBEDTLS_AES_ROM_TABLES
/* Save RAM by adjusting to our exact needs */
#define MBEDTLS_ECP_MAX_BITS 384
#define MBEDTLS_MPI_MAX_SIZE 48 // 384 bits is 48 bytes
/* Save RAM at the expense of speed, see ecp.h */
#define MBEDTLS_ECP_WINDOW_SIZE 2
#define MBEDTLS_ECP_FIXED_POINT_OPTIM 0
/* Significant speed benefit at the expense of some ROM */
#define MBEDTLS_ECP_NIST_OPTIM
/*
* You should adjust this to the exact number of sources you're using: default
* is the "mbedtls_platform_entropy_poll" source, but you may want to add other ones.
* Minimum is 2 for the entropy test suite.
*/
#define MBEDTLS_ENTROPY_MAX_SOURCES 2
/* Save ROM and a few bytes of RAM by specifying our own ciphersuite list */
#define MBEDTLS_SSL_CIPHERSUITES \
MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, \
MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
/*
* Save RAM at the expense of interoperability: do this only if you control
* both ends of the connection! (See coments in "mbedtls/ssl.h".)
* The minimum size here depends on the certificate chain used as well as the
* typical size of records.
*/
#define MBEDTLS_SSL_MAX_CONTENT_LEN 1024
#include "mbedtls/check_config.h"
#endif /* MBEDTLS_CONFIG_H */

View file

@ -0,0 +1,94 @@
/**
* \file config-thread.h
*
* \brief Minimal configuration for using TLS as part of Thread
*/
/*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
/*
* Minimal configuration for using TLS a part of Thread
* http://threadgroup.org/
*
* Distinguishing features:
* - no RSA or classic DH, fully based on ECC
* - no X.509
* - support for experimental EC J-PAKE key exchange
*
* See README.txt for usage instructions.
*/
#ifndef MBEDTLS_CONFIG_H
#define MBEDTLS_CONFIG_H
/* System support */
#define MBEDTLS_HAVE_ASM
/* mbed TLS feature support */
#define MBEDTLS_AES_ROM_TABLES
#define MBEDTLS_ECP_DP_SECP256R1_ENABLED
#define MBEDTLS_ECP_NIST_OPTIM
#define MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED
#define MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
#define MBEDTLS_SSL_PROTO_TLS1_2
#define MBEDTLS_SSL_PROTO_DTLS
#define MBEDTLS_SSL_DTLS_ANTI_REPLAY
#define MBEDTLS_SSL_DTLS_HELLO_VERIFY
#define MBEDTLS_SSL_EXPORT_KEYS
/* mbed TLS modules */
#define MBEDTLS_AES_C
#define MBEDTLS_ASN1_PARSE_C
#define MBEDTLS_ASN1_WRITE_C
#define MBEDTLS_BIGNUM_C
#define MBEDTLS_CCM_C
#define MBEDTLS_CIPHER_C
#define MBEDTLS_CTR_DRBG_C
#define MBEDTLS_CMAC_C
#define MBEDTLS_ECJPAKE_C
#define MBEDTLS_ECP_C
#define MBEDTLS_ENTROPY_C
#define MBEDTLS_HMAC_DRBG_C
#define MBEDTLS_MD_C
#define MBEDTLS_OID_C
#define MBEDTLS_PK_C
#define MBEDTLS_PK_PARSE_C
#define MBEDTLS_SHA256_C
#define MBEDTLS_SSL_COOKIE_C
#define MBEDTLS_SSL_CLI_C
#define MBEDTLS_SSL_SRV_C
#define MBEDTLS_SSL_TLS_C
/* For tests using ssl-opt.sh */
#define MBEDTLS_NET_C
#define MBEDTLS_TIMING_C
/* Save RAM at the expense of ROM */
#define MBEDTLS_AES_ROM_TABLES
/* Save RAM by adjusting to our exact needs */
#define MBEDTLS_ECP_MAX_BITS 256
#define MBEDTLS_MPI_MAX_SIZE 32 // 256 bits is 32 bytes
/* Save ROM and a few bytes of RAM by specifying our own ciphersuite list */
#define MBEDTLS_SSL_CIPHERSUITES MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8
#include "mbedtls/check_config.h"
#endif /* MBEDTLS_CONFIG_H */

View file

@ -0,0 +1,72 @@
/**
* \file doc_encdec.h
*
* \brief Encryption/decryption module documentation file.
*/
/*
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
/**
* @addtogroup encdec_module Encryption/decryption module
*
* The Encryption/decryption module provides encryption/decryption functions.
* One can differentiate between symmetric and asymmetric algorithms; the
* symmetric ones are mostly used for message confidentiality and the asymmetric
* ones for key exchange and message integrity.
* Some symmetric algorithms provide different block cipher modes, mainly
* Electronic Code Book (ECB) which is used for short (64-bit) messages and
* Cipher Block Chaining (CBC) which provides the structure needed for longer
* messages. In addition the Cipher Feedback Mode (CFB-128) stream cipher mode,
* Counter mode (CTR) and Galois Counter Mode (GCM) are implemented for
* specific algorithms.
*
* All symmetric encryption algorithms are accessible via the generic cipher layer
* (see \c mbedtls_cipher_setup()).
*
* The asymmetric encryptrion algorithms are accessible via the generic public
* key layer (see \c mbedtls_pk_init()).
*
* The following algorithms are provided:
* - Symmetric:
* - AES (see \c mbedtls_aes_crypt_ecb(), \c mbedtls_aes_crypt_cbc(), \c mbedtls_aes_crypt_cfb128() and
* \c mbedtls_aes_crypt_ctr()).
* - ARCFOUR (see \c mbedtls_arc4_crypt()).
* - Blowfish / BF (see \c mbedtls_blowfish_crypt_ecb(), \c mbedtls_blowfish_crypt_cbc(),
* \c mbedtls_blowfish_crypt_cfb64() and \c mbedtls_blowfish_crypt_ctr())
* - Camellia (see \c mbedtls_camellia_crypt_ecb(), \c mbedtls_camellia_crypt_cbc(),
* \c mbedtls_camellia_crypt_cfb128() and \c mbedtls_camellia_crypt_ctr()).
* - DES/3DES (see \c mbedtls_des_crypt_ecb(), \c mbedtls_des_crypt_cbc(), \c mbedtls_des3_crypt_ecb()
* and \c mbedtls_des3_crypt_cbc()).
* - GCM (AES-GCM and CAMELLIA-GCM) (see \c mbedtls_gcm_init())
* - XTEA (see \c mbedtls_xtea_crypt_ecb()).
* - Asymmetric:
* - Diffie-Hellman-Merkle (see \c mbedtls_dhm_read_public(), \c mbedtls_dhm_make_public()
* and \c mbedtls_dhm_calc_secret()).
* - RSA (see \c mbedtls_rsa_public() and \c mbedtls_rsa_private()).
* - Elliptic Curves over GF(p) (see \c mbedtls_ecp_point_init()).
* - Elliptic Curve Digital Signature Algorithm (ECDSA) (see \c mbedtls_ecdsa_init()).
* - Elliptic Curve Diffie Hellman (ECDH) (see \c mbedtls_ecdh_init()).
*
* This module provides encryption/decryption which can be used to provide
* secrecy.
*
* It also provides asymmetric key functions which can be used for
* confidentiality, integrity, authentication and non-repudiation.
*/

View file

@ -0,0 +1,44 @@
/**
* \file doc_hashing.h
*
* \brief Hashing module documentation file.
*/
/*
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
/**
* @addtogroup hashing_module Hashing module
*
* The Message Digest (MD) or Hashing module provides one-way hashing
* functions. Such functions can be used for creating a hash message
* authentication code (HMAC) when sending a message. Such a HMAC can be used
* in combination with a private key for authentication, which is a message
* integrity control.
*
* All hash algorithms can be accessed via the generic MD layer (see
* \c mbedtls_md_setup())
*
* The following hashing-algorithms are provided:
* - MD2, MD4, MD5 128-bit one-way hash functions by Ron Rivest.
* - SHA-1, SHA-256, SHA-384/512 160-bit or more one-way hash functions by
* NIST and NSA.
*
* This module provides one-way hashing which can be used for authentication.
*/

View file

@ -0,0 +1,96 @@
/**
* \file doc_mainpage.h
*
* \brief Main page documentation file.
*/
/*
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
/**
* @mainpage mbed TLS v2.16.0 source code documentation
*
* This documentation describes the internal structure of mbed TLS. It was
* automatically generated from specially formatted comment blocks in
* mbed TLS's source code using Doxygen. (See
* http://www.stack.nl/~dimitri/doxygen/ for more information on Doxygen)
*
* mbed TLS has a simple setup: it provides the ingredients for an SSL/TLS
* implementation. These ingredients are listed as modules in the
* \ref mainpage_modules "Modules section". This "Modules section" introduces
* the high-level module concepts used throughout this documentation.\n
* Some examples of mbed TLS usage can be found in the \ref mainpage_examples
* "Examples section".
*
* @section mainpage_modules Modules
*
* mbed TLS supports SSLv3 up to TLSv1.2 communication by providing the
* following:
* - TCP/IP communication functions: listen, connect, accept, read/write.
* - SSL/TLS communication functions: init, handshake, read/write.
* - X.509 functions: CRT, CRL and key handling
* - Random number generation
* - Hashing
* - Encryption/decryption
*
* Above functions are split up neatly into logical interfaces. These can be
* used separately to provide any of the above functions or to mix-and-match
* into an SSL server/client solution that utilises a X.509 PKI. Examples of
* such implementations are amply provided with the source code.
*
* Note that mbed TLS does not provide a control channel or (multiple) session
* handling without additional work from the developer.
*
* @section mainpage_examples Examples
*
* Example server setup:
*
* \b Prerequisites:
* - X.509 certificate and private key
* - session handling functions
*
* \b Setup:
* - Load your certificate and your private RSA key (X.509 interface)
* - Setup the listening TCP socket (TCP/IP interface)
* - Accept incoming client connection (TCP/IP interface)
* - Initialise as an SSL-server (SSL/TLS interface)
* - Set parameters, e.g. authentication, ciphers, CA-chain, key exchange
* - Set callback functions RNG, IO, session handling
* - Perform an SSL-handshake (SSL/TLS interface)
* - Read/write data (SSL/TLS interface)
* - Close and cleanup (all interfaces)
*
* Example client setup:
*
* \b Prerequisites:
* - X.509 certificate and private key
* - X.509 trusted CA certificates
*
* \b Setup:
* - Load the trusted CA certificates (X.509 interface)
* - Load your certificate and your private RSA key (X.509 interface)
* - Setup a TCP/IP connection (TCP/IP interface)
* - Initialise as an SSL-client (SSL/TLS interface)
* - Set parameters, e.g. authentication mode, ciphers, CA-chain, session
* - Set callback functions RNG, IO
* - Perform an SSL-handshake (SSL/TLS interface)
* - Verify the server certificate (SSL/TLS interface)
* - Write/read data (SSL/TLS interface)
* - Close and cleanup (all interfaces)
*/

View file

@ -0,0 +1,46 @@
/**
* \file doc_rng.h
*
* \brief Random number generator (RNG) module documentation file.
*/
/*
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
/**
* @addtogroup rng_module Random number generator (RNG) module
*
* The Random number generator (RNG) module provides random number
* generation, see \c mbedtls_ctr_drbg_random().
*
* The block-cipher counter-mode based deterministic random
* bit generator (CTR_DBRG) as specified in NIST SP800-90. It needs an external
* source of entropy. For these purposes \c mbedtls_entropy_func() can be used.
* This is an implementation based on a simple entropy accumulator design.
*
* The other number generator that is included is less strong and uses the
* HAVEGE (HArdware Volatile Entropy Gathering and Expansion) software heuristic
* which considered unsafe for primary usage, but provides additional random
* to the entropy pool if enables.
*
* Meaning that there seems to be no practical algorithm that can guess
* the next bit with a probability larger than 1/2 in an output sequence.
*
* This module can be used to generate random numbers.
*/

View file

@ -0,0 +1,51 @@
/**
* \file doc_ssltls.h
*
* \brief SSL/TLS communication module documentation file.
*/
/*
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
/**
* @addtogroup ssltls_communication_module SSL/TLS communication module
*
* The SSL/TLS communication module provides the means to create an SSL/TLS
* communication channel.
*
* The basic provisions are:
* - initialise an SSL/TLS context (see \c mbedtls_ssl_init()).
* - perform an SSL/TLS handshake (see \c mbedtls_ssl_handshake()).
* - read/write (see \c mbedtls_ssl_read() and \c mbedtls_ssl_write()).
* - notify a peer that connection is being closed (see \c mbedtls_ssl_close_notify()).
*
* Many aspects of such a channel are set through parameters and callback
* functions:
* - the endpoint role: client or server.
* - the authentication mode. Should verification take place.
* - the Host-to-host communication channel. A TCP/IP module is provided.
* - the random number generator (RNG).
* - the ciphers to use for encryption/decryption.
* - session control functions.
* - X.509 parameters for certificate-handling and key exchange.
*
* This module can be used to create an SSL/TLS server and client and to provide a basic
* framework to setup and communicate through an SSL/TLS communication channel.\n
* Note that you need to provide for several aspects yourself as mentioned above.
*/

View file

@ -0,0 +1,46 @@
/**
* \file doc_tcpip.h
*
* \brief TCP/IP communication module documentation file.
*/
/*
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
/**
* @addtogroup tcpip_communication_module TCP/IP communication module
*
* The TCP/IP communication module provides for a channel of
* communication for the \link ssltls_communication_module SSL/TLS communication
* module\endlink to use.
* In the TCP/IP-model it provides for communication up to the Transport
* (or Host-to-host) layer.
* SSL/TLS resides on top of that, in the Application layer, and makes use of
* its basic provisions:
* - listening on a port (see \c mbedtls_net_bind()).
* - accepting a connection (through \c mbedtls_net_accept()).
* - read/write (through \c mbedtls_net_recv()/\c mbedtls_net_send()).
* - close a connection (through \c mbedtls_net_close()).
*
* This way you have the means to, for example, implement and use an UDP or
* IPSec communication solution as a basis.
*
* This module can be used at server- and clientside to provide a basic
* means of communication over the internet.
*/

View file

@ -0,0 +1,45 @@
/**
* \file doc_x509.h
*
* \brief X.509 module documentation file.
*/
/*
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
/**
* @addtogroup x509_module X.509 module
*
* The X.509 module provides X.509 support for reading, writing and verification
* of certificates.
* In summary:
* - X.509 certificate (CRT) reading (see \c mbedtls_x509_crt_parse(),
* \c mbedtls_x509_crt_parse_der(), \c mbedtls_x509_crt_parse_file()).
* - X.509 certificate revocation list (CRL) reading (see
* \c mbedtls_x509_crl_parse(), \c mbedtls_x509_crl_parse_der(),
* and \c mbedtls_x509_crl_parse_file()).
* - X.509 certificate signature verification (see \c
* mbedtls_x509_crt_verify() and \c mbedtls_x509_crt_verify_with_profile().
* - X.509 certificate writing and certificate request writing (see
* \c mbedtls_x509write_crt_der() and \c mbedtls_x509write_csr_der()).
*
* This module can be used to build a certificate authority (CA) chain and
* verify its signature. It is also used to generate Certificate Signing
* Requests and X.509 certificates just as a CA would do.
*/

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,4 @@
Makefile
*.sln
*.vcxproj
mbedtls/check_config

View file

@ -0,0 +1,16 @@
option(INSTALL_MBEDTLS_HEADERS "Install mbed TLS headers." ON)
if(INSTALL_MBEDTLS_HEADERS)
file(GLOB headers "mbedtls/*.h")
install(FILES ${headers}
DESTINATION include/mbedtls
PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ)
endif(INSTALL_MBEDTLS_HEADERS)
# Make config.h available in an out-of-source build. ssl-opt.sh requires it.
if (NOT ${CMAKE_CURRENT_BINARY_DIR} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR})
link_to_source(mbedtls)
endif()

Some files were not shown because too many files have changed in this diff Show more