MatrixSSL 3.8.3 Open

This commit is contained in:
J Harper
2016-04-15 15:12:52 -07:00
parent 2a1158838b
commit 5b09e8e149
315 changed files with 94773 additions and 0 deletions

44
core/Makefile Executable file
View File

@@ -0,0 +1,44 @@
#
# Makefile for core static library
#
# Copyright (c) 2013-2016 INSIDE Secure Corporation. All Rights Reserved.
#
MATRIXSSL_ROOT:=..
include $(MATRIXSSL_ROOT)/common.mk
SRC:=\
memset_s.c \
corelib.c \
$(OSDEP)/osdep.c
ASM:=memset_s.s
# Generated files
STATIC:=libcore_s.a
all: compile
compile: $(ASM) $(OBJS) $(STATIC)
# Special rule to build memset_s function without optimization
memset_s.o: memset_s.c
$(CC) -O0 -Wall -ffunction-sections -fdata-sections -o $@ -c $<
# Generate the (.s) assembly file to verify zero is being performed
$(ASM): memset_s.c
$(CC) -O0 -g -fverbose-asm -S $<
# Additional Dependencies
$(OBJS): $(MATRIXSSL_ROOT)/common.mk Makefile *.h
# Build the static library
# Redirect stderr to null so we don't see the 'empty file' warnings
$(STATIC): $(OBJS)
$(AR) -rcuv $@ $^ 2>/dev/null
clean:
rm -f $(STATIC) $(OBJS) $(ASM)

509
core/POSIX/osdep.c Normal file
View File

@@ -0,0 +1,509 @@
/**
* @file osdep.c
* @version $Format:%h%d$
*
* POSIX layer.
* Mac OSX 10.5
* Linux
*/
/*
* Copyright (c) 2013-2016 INSIDE Secure Corporation
* Copyright (c) PeerSec Networks, 2002-2011
* All Rights Reserved
*
* The latest version of this code is available at http://www.matrixssl.org
*
* This software is open source; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This General Public License does NOT permit incorporating this software
* into proprietary programs. If you are unable to comply with the GPL, a
* commercial license for this software may be purchased from INSIDE at
* http://www.insidesecure.com/
*
* This program is distributed in WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* http://www.gnu.org/copyleft/gpl.html
*/
/******************************************************************************/
#include "../coreApi.h"
#ifdef POSIX
/******************************************************************************/
/*
Universal system POSIX headers and then PScore/coreApi.h
OS-specific header includes should be added to PScore/osdep.h
*/
#include <stdlib.h> /* abort() */
#include <fcntl.h> /* open(), O_RDONLY, ect... */
#include <unistd.h> /* close() */
#include <errno.h> /* errno */
#include <sys/time.h> /* gettimeofday */
/******************************************************************************/
/*
TIME FUNCTIONS
*/
#ifndef USE_HIGHRES_TIME
/******************************************************************************/
/*
Module open and close
*/
int osdepTimeOpen(void)
{
psTime_t lt;
/*
Just a check that gettimeofday is functioning
*/
if (gettimeofday(&lt, NULL) < 0) {
return PS_FAILURE;
}
return PS_SUCCESS;
}
void osdepTimeClose(void)
{
}
/*
PScore Public API implementations
This function always returns seconds/ticks AND OPTIONALLY populates
whatever psTime_t happens to be on the given platform.
*/
int32 psGetTime(psTime_t *t, void *userPtr)
{
psTime_t lt;
if (t == NULL) {
if (gettimeofday(&lt, NULL) < 0) {
return PS_FAILURE;
}
return lt.tv_sec;
}
if (gettimeofday(t, NULL) < 0) {
return PS_FAILURE;
}
return t->tv_sec;
}
int32 psDiffMsecs(psTime_t then, psTime_t now, void *userPtr)
{
if (now.tv_usec < then.tv_usec) {
now.tv_sec--;
now.tv_usec += 1000000; /* borrow 1 second worth of usec */
}
return (int32)((now.tv_sec - then.tv_sec) * 1000) +
((now.tv_usec - then.tv_usec)/ 1000);
}
int32 psCompareTime(psTime_t a, psTime_t b, void *userPtr)
{
/*
Time comparison. 1 if 'a' is less than or equal. 0 if 'a' is greater
*/
if (a.tv_sec < b.tv_sec) {
return 1;
}
if (a.tv_sec == b.tv_sec && a.tv_usec <= b.tv_usec) {
return 1;
}
return 0;
}
#else /* USE_HIGHRES_TIME */
/******************************************************************************/
#ifdef __APPLE__
/* MAC OS X */
#include <mach/mach_time.h>
static mach_timebase_info_data_t hiresFreq;
int osdepTimeOpen(void)
{
mach_timebase_info(&hiresFreq);
return PS_SUCCESS;
}
void osdepTimeClose(void)
{
}
int32 psGetTime(psTime_t *t, void *userPtr)
{
psTime_t lt;
if (t == NULL) {
t = &lt;
}
*t = mach_absolute_time();
return (int32)((*t * hiresFreq.numer) / (hiresFreq.denom * 1000000000L));
}
int32 psDiffMsecs(psTime_t then, psTime_t now, void *userPtr)
{
return (int32)(((now - then) * hiresFreq.numer) / (hiresFreq.denom * 1000000));
}
int64_t psDiffUsecs(psTime_t then, psTime_t now)
{
return (int64_t)(((now - then) * hiresFreq.numer) / (hiresFreq.denom * 1000));
}
int32 psCompareTime(psTime_t a, psTime_t b, void *userPtr)
{
return a <= b ? 1 : 0;
}
/******************************************************************************/
#else /* !APPLE, !tile */
/******************************************************************************/
/* LINUX */
int osdepTimeOpen(void)
{
return PS_SUCCESS;
}
void osdepTimeClose(void)
{
}
int32 psGetTime(psTime_t *t, void *userPtr)
{
psTime_t lt;
if (t == NULL) {
t = &lt;
}
clock_gettime(CLOCK_MONOTONIC, t);
return t->tv_sec;
}
int32 psDiffMsecs(psTime_t then, psTime_t now, void *userPtr)
{
if (now.tv_nsec < then.tv_nsec) {
now.tv_sec--;
now.tv_nsec += 1000000000L; /* borrow 1 second worth of nsec */
}
return (int32)((now.tv_sec - then.tv_sec) * 1000) +
((now.tv_nsec - then.tv_nsec)/ 1000000);
}
int64_t psDiffUsecs(psTime_t then, psTime_t now)
{
if (now.tv_nsec < then.tv_nsec) {
now.tv_sec--;
now.tv_nsec += 1000000000L; /* borrow 1 second worth of nsec */
}
return (int32)((now.tv_sec - then.tv_sec) * 1000) +
((now.tv_nsec - then.tv_nsec)/ 1000);
}
int32 psCompareTime(psTime_t a, psTime_t b, void *userPtr)
{
/* Time comparison. 1 if 'a' is less than or equal. 0 if 'a' is greater */
if (a.tv_sec < b.tv_sec) {
return 1;
}
if (a.tv_sec == b.tv_sec && a.tv_nsec <= b.tv_nsec) {
return 1;
}
return 0;
}
#endif /* !APPLE */
#endif /* USE_HIGHRES_TIME */
/******************************************************************************/
#ifdef USE_MULTITHREADING
/******************************************************************************/
/*
MUTEX FUNCTIONS
*/
/******************************************************************************/
static pthread_mutexattr_t attr;
/*
Module open and close
*/
int osdepMutexOpen(void)
{
int32 rc;
if ((rc = pthread_mutexattr_init(&attr)) < 0) {
psErrorInt("pthread_mutexattr_init failed %d\n", rc);
return PS_PLATFORM_FAIL;
}
return PS_SUCCESS;
}
int osdepMutexClose(void)
{
if (pthread_mutexattr_destroy(&attr) != 0) {
psTraceCore("pthread_mutex_destroy failed\n");
}
return PS_SUCCESS;
}
/*
PScore Public API implementations
*/
int32 psCreateMutex(psMutex_t *mutex)
{
int32 err;
if ((err = pthread_mutex_init(mutex, &attr)) != 0) {
psTraceIntCore("pthread_mutex_init failed %d\n", err);
return PS_PLATFORM_FAIL;
}
return PS_SUCCESS;
}
int32 psLockMutex(psMutex_t *mutex)
{
if (pthread_mutex_lock(mutex) != 0) {
psTraceCore("pthread_mutex_lock failed\n");
return PS_PLATFORM_FAIL;
}
return PS_SUCCESS;
}
int32 psUnlockMutex(psMutex_t *mutex)
{
if (pthread_mutex_unlock(mutex) != 0) {
psTraceCore("pthread_mutex_unlock failed\n");
return PS_PLATFORM_FAIL;
}
return PS_SUCCESS;
}
void psDestroyMutex(psMutex_t *mutex)
{
pthread_mutex_destroy(mutex);
}
#endif /* USE_MULTITHREADING */
/******************************************************************************/
/******************************************************************************/
/*
ENTROPY FUNCTIONS
*/
/******************************************************************************/
#define MAX_RAND_READS 1024
static int32 urandfd = -1;
static int32 randfd = -1;
/*
Module open and close
*/
int osdepEntropyOpen(void)
{
/*
Open /dev/random access non-blocking.
*/
if ((urandfd = open("/dev/urandom", O_RDONLY)) < 0) {
psErrorInt("open of urandom failed %d\n", urandfd);
return PS_PLATFORM_FAIL;
}
/*
For platforms that don't have /dev/random, just assign it to urandom
*/
if ((randfd = open("/dev/random", O_RDONLY | O_NONBLOCK)) < 0) {
randfd=urandfd;
}
return PS_SUCCESS;
}
void osdepEntropyClose(void)
{
if (randfd != urandfd) {
close(randfd);
}
close(urandfd);
}
/*
PScore Public API implementations
*/
int32 psGetEntropy(unsigned char *bytes, uint32 size, void *userPtr)
{
/*
Read from /dev/random non-blocking first, then from urandom if it would
block. Also, handle file closure case and re-open.
*/
int32 rc, sanity, retry, readBytes;
unsigned char *where = bytes;
sanity = retry = rc = readBytes = 0;
while (size) {
if ((rc = read(randfd, where, size)) < 0 || sanity > MAX_RAND_READS) {
if (errno == EINTR) {
if (sanity > MAX_RAND_READS) {
psTraceCore("psGetEntropy failed randfd sanity\n");
return PS_PLATFORM_FAIL;
}
sanity++;
continue;
} else if (errno == EAGAIN) {
break;
} else if (errno == EBADF && retry == 0) {
close(randfd);
if ((randfd = open("/dev/random", O_RDONLY | O_NONBLOCK)) < 0) {
break;
}
retry++;
continue;
} else {
break;
}
}
readBytes += rc;
where += rc;
size -= rc;
}
sanity = retry = 0;
while (size) {
if ((rc = read(urandfd, where, size)) < 0 || sanity > MAX_RAND_READS) {
if (errno == EINTR) {
if (sanity > MAX_RAND_READS) {
psTraceCore("psGetEntropy failed urandfd sanity\n");
return PS_PLATFORM_FAIL;
}
sanity++;
continue;
} else if (errno == EBADF && retry == 0) {
close(urandfd);
if ((urandfd =
open("/dev/urandom", O_RDONLY | O_NONBLOCK)) < 0) {
psTraceCore("psGetEntropy failed urandom open\n");
return PS_PLATFORM_FAIL;
}
retry++;
continue;
} else {
psTraceIntCore("psGetEntropy fail errno %d\n", errno);
return PS_PLATFORM_FAIL;
}
}
readBytes += rc;
where += rc;
size -= rc;
}
return readBytes;
}
/******************************************************************************/
/******************************************************************************/
/*
RAW TRACE FUNCTIONS
*/
/******************************************************************************/
int osdepTraceOpen(void)
{
return PS_SUCCESS;
}
void osdepTraceClose(void)
{
}
void _psTrace(const char *msg)
{
printf("%s", msg);
}
/* message should contain one %s, unless value is NULL */
void _psTraceStr(const char *message, const char *value)
{
if (value) {
printf(message, value);
} else {
printf("%s", message);
}
}
/* message should contain one %d */
void _psTraceInt(const char *message, int32 value)
{
printf(message, value);
}
/* message should contain one %p */
void _psTracePtr(const char *message, const void *value)
{
printf(message, value);
}
/******************************************************************************/
#ifdef HALT_ON_PS_ERROR
/******************************************************************************/
/*
POSIX - abort() on psError when HALT_ON_PS_ERROR enabled
*/
void osdepBreak(void)
{
abort();
}
#endif /* HALT_ON_PS_ERROR */
#ifdef MATRIX_USE_FILE_SYSTEM
/******************************************************************************/
/*
FILE APIs
*/
/**
Allocate a buffer and read in a file.
@note Caller must free 'buf' parameter on success.
Callers do not need to free buf on function failure.
*/
int32 psGetFileBuf(psPool_t *pool, const char *fileName, unsigned char **buf,
int32 *bufLen)
{
FILE *fp;
struct stat fstat;
size_t tmp = 0;
*bufLen = 0;
*buf = NULL;
if (fileName == NULL) {
return PS_ARG_FAIL;
}
if ((stat(fileName, &fstat) != 0) || (fp = fopen(fileName, "r")) == NULL) {
psTraceStrCore("Unable to open %s\n", (char*)fileName);
return PS_PLATFORM_FAIL;
}
*buf = psMalloc(pool, (size_t)(fstat.st_size + 1));
if (*buf == NULL) {
return PS_MEM_FAIL;
}
memset(*buf, 0x0, (size_t)fstat.st_size + 1);
while (((tmp = fread(*buf + *bufLen, sizeof(char), 512, fp)) > 0) &&
(*bufLen < fstat.st_size)) {
*bufLen += (int32)tmp;
}
fclose(fp);
return PS_SUCCESS;
}
#endif /* MATRIX_USE_FILE_SYSTEM */
#endif /* POSIX */
/******************************************************************************/

278
core/WIN32/osdep.c Normal file
View File

@@ -0,0 +1,278 @@
/**
* @file osdep.c
* @version $Format:%h%d$
*
* WIN32 platform PScore .
*/
/*
* Copyright (c) 2013-2016 INSIDE Secure Corporation
* Copyright (c) PeerSec Networks, 2002-2011
* All Rights Reserved
*
* The latest version of this code is available at http://www.matrixssl.org
*
* This software is open source; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This General Public License does NOT permit incorporating this software
* into proprietary programs. If you are unable to comply with the GPL, a
* commercial license for this software may be purchased from INSIDE at
* http://www.insidesecure.com/
*
* This program is distributed in WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* http://www.gnu.org/copyleft/gpl.html
*/
/******************************************************************************/
#include "../coreApi.h"
#ifdef WIN32
#include <windows.h>
/******************************************************************************/
/* TIME */
static LARGE_INTEGER hiresStart; /* zero-time */
static LARGE_INTEGER hiresFreq; /* tics per second */
int osdepTimeOpen(void)
{
if (QueryPerformanceFrequency(&hiresFreq) == PS_FALSE) {
return PS_FAILURE;
}
if (QueryPerformanceCounter(&hiresStart) == PS_FALSE) {
return PS_FAILURE;
}
return PS_SUCCESS;
}
void osdepTimeClose(void)
{
}
/* PScore Public API implementations */
int32 psGetTime(psTime_t *t, void *userPtr)
{
psTime_t lt;
__int64 diff;
int32 d;
if (t == NULL) {
QueryPerformanceCounter(&lt);
diff = lt.QuadPart - hiresStart.QuadPart;
d = (int32)((diff * 1000) / hiresFreq.QuadPart);
return d;
}
QueryPerformanceCounter(t);
diff = t->QuadPart - hiresStart.QuadPart;
d = (int32)((diff * 1000) / hiresFreq.QuadPart);
return d;
}
int32 psDiffMsecs(psTime_t then, psTime_t now, void *userPtr)
{
__int64 diff;
diff = now.QuadPart - then.QuadPart;
return (int32)((diff*1000) / hiresFreq.QuadPart);
}
int32 psCompareTime(psTime_t a, psTime_t b, void *userPtr)
{
if (a.QuadPart <= b.QuadPart) {
return 1;
}
return 0;
}
/******************************************************************************/
/* MUTEX */
#ifdef USE_MULTITHREADING
int osdepMutexOpen(void)
{
return PS_SUCCESS;
}
int osdepMutexClose(void)
{
return PS_SUCCESS;
}
/* PScore Public API implementations */
int32 psCreateMutex(psMutex_t *mutex)
{
InitializeCriticalSection(mutex);
return PS_SUCCESS;
}
int32 psLockMutex(psMutex_t *mutex)
{
EnterCriticalSection(mutex);
return PS_SUCCESS;
}
int32 psUnlockMutex(psMutex_t *mutex)
{
LeaveCriticalSection(mutex);
return PS_SUCCESS;
}
void psDestroyMutex(psMutex_t *mutex)
{
DeleteCriticalSection(mutex);
}
#endif /* USE_MULTITHREADING */
/******************************************************************************/
/* ENTROPY */
static HCRYPTPROV hProv; /* Crypto context for random bytes */
int osdepEntropyOpen(void)
{
if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL,
CRYPT_VERIFYCONTEXT)) {
return PS_FAILURE;
}
return PS_SUCCESS;
}
void osdepEntropyClose(void)
{
CryptReleaseContext(hProv, 0);
}
int32 psGetEntropy(unsigned char *bytes, uint32 size, void *userPtr)
{
if (CryptGenRandom(hProv, size, bytes)) {
return size;
}
return PS_FAILURE;
}
/******************************************************************************/
/* TRACE */
int osdepTraceOpen(void)
{
return PS_SUCCESS;
}
void osdepTraceClose(void)
{
}
void _psTrace(const char *msg)
{
printf(msg);
}
/* Message should contain one %s, unless value is NULL */
void _psTraceStr(const char *message, const char *value)
{
if (value) {
printf(message, value);
} else {
printf(message);
}
}
/* message should contain one %d */
void _psTraceInt(const char *message, int32 value)
{
printf(message, value);
}
/* message should contain one %p */
void _psTracePtr(const char *message, const void *value)
{
printf(message, value);
}
/******************************************************************************/
/* DEBUGGING */
#ifdef HALT_ON_PS_ERROR
void osdepBreak(void)
{
/* System halt on psError (and assert) */
DebugBreak();
}
#endif /* HALT_ON_PS_ERROR */
/******************************************************************************/
/* FILE SYSTEM */
#ifdef MATRIX_USE_FILE_SYSTEM
/*
Memory info:
Caller must free 'buf' parameter on success
Callers do not need to free buf on function failure
*/
int32 psGetFileBuf(psPool_t *pool, const char *fileName, unsigned char **buf,
int32 *bufLen)
{
DWORD dwAttributes;
HANDLE hFile;
int32 size;
DWORD tmp = 0;
*bufLen = 0;
*buf = NULL;
dwAttributes = GetFileAttributesA(fileName);
if (dwAttributes != 0xFFFFFFFF && dwAttributes & FILE_ATTRIBUTE_DIRECTORY) {
psTraceStrCore("Unable to find %s\n", (char*)fileName);
return PS_PLATFORM_FAIL;
}
/* Open an existing file read-only (we are not actually creating) */
if ((hFile = CreateFileA(fileName, GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, NULL)) == INVALID_HANDLE_VALUE) {
psTraceStrCore("Unable to open %s\n", (char*)fileName);
return PS_PLATFORM_FAIL;
}
size = GetFileSize(hFile, NULL);
*buf = psMalloc(pool, size + 1);
if (*buf == NULL) {
CloseHandle(hFile);
return PS_MEM_FAIL;
}
memset(*buf, 0x0, size + 1);
while (*bufLen < size) {
if (ReadFile(hFile, *buf + *bufLen,
(size - *bufLen > 512 ? 512 : size - *bufLen),
&tmp, NULL) == FALSE) {
psFree(*buf, pool);
psTraceStrCore("Unable to read %s\n", (char*)fileName);
CloseHandle(hFile);
return PS_PLATFORM_FAIL;
}
*bufLen += (int32)tmp;
}
CloseHandle(hFile);
return PS_SUCCESS;
}
#endif /* MATRIX_USE_FILE_SYSTEM */
#endif /* WIN32 */
/******************************************************************************/

237
core/coreApi.h Normal file
View File

@@ -0,0 +1,237 @@
/**
* @file coreApi.h
* @version $Format:%h%d$
*
* Prototypes for the Matrix core public APIs.
*/
/*
* Copyright (c) 2013-2016 INSIDE Secure Corporation
* Copyright (c) PeerSec Networks, 2002-2011
* All Rights Reserved
*
* The latest version of this code is available at http://www.matrixssl.org
*
* This software is open source; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This General Public License does NOT permit incorporating this software
* into proprietary programs. If you are unable to comply with the GPL, a
* commercial license for this software may be purchased from INSIDE at
* http://www.insidesecure.com/
*
* This program is distributed in WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* http://www.gnu.org/copyleft/gpl.html
*/
/******************************************************************************/
#ifndef _h_PS_COREAPI
#define _h_PS_COREAPI
#ifdef __cplusplus
extern "C" {
#endif
#include "coreConfig.h" /* Must be first included */
#include "osdep.h"
#include "list.h"
#include "psmalloc.h"
/******************************************************************************/
/*
psCore return codes
*/
#define PS_CORE_IS_OPEN 1
/******************************************************************************/
/*
Universal return codes
*/
#define PS_SUCCESS 0
#define PS_FAILURE -1
#define PS_FAIL PS_FAILURE /* Just another name */
/* NOTE: Failure return codes MUST be < 0 */
/* NOTE: The range for core error codes should be between -2 and -29 */
#define PS_ARG_FAIL -6 /* Failure due to bad function param */
#define PS_PLATFORM_FAIL -7 /* Failure as a result of system call error */
#define PS_MEM_FAIL -8 /* Failure to allocate requested memory */
#define PS_LIMIT_FAIL -9 /* Failure on sanity/limit tests */
#define PS_UNSUPPORTED_FAIL -10 /* Unimplemented feature error */
#define PS_DISABLED_FEATURE_FAIL -11 /* Incorrect #define toggle for feature */
#define PS_PROTOCOL_FAIL -12 /* A protocol error occurred */
#define PS_TIMEOUT_FAIL -13 /* A timeout occurred and MAY be an error */
#define PS_INTERRUPT_FAIL -14 /* An interrupt occurred and MAY be an error */
#define PS_PENDING -15 /* In process. Not necessarily an error */
#define PS_EAGAIN -16 /* Try again later. Not necessarily an error */
#define PS_TRUE 1
#define PS_FALSE 0
/******************************************************************************/
/* Public structures */
/******************************************************************************/
/*
psBuf_t
Empty buffer:
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|
^
\end
\start
\buf
size = 16
len = (end - start) = 0
Buffer with data:
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
|.|.|a|b|c|d|e|f|g|h|i|j|.|.|.|.|
^ ^ ^
| | \end
| \start
\buf
size = 16
len = (end - start) = 10
Read from start pointer
Write to end pointer
Free from buf pointer
*/
typedef struct {
unsigned char *buf; /* Pointer to the start of the buffer */
unsigned char *start; /* Pointer to start of valid data */
unsigned char *end; /* Pointer to first byte of invalid data */
int32 size; /* Size of buffer in bytes */
} psBuf_t;
/******************************************************************************/
#ifdef MATRIX_USE_FILE_SYSTEM
#define FILESYSTEM_CONFIG_STR "Y"
#else
#define FILESYSTEM_CONFIG_STR "N"
#endif
#define PSMALLOC_CONFIG_STR "N"
#ifdef USE_MULTITHREADING
#define MULTITHREAD_CONFIG_STR "Y"
#else
#define MULTITHREAD_CONFIG_STR "N"
#endif
#define PSCORE_CONFIG \
"Y" \
FILESYSTEM_CONFIG_STR \
PSMALLOC_CONFIG_STR \
MULTITHREAD_CONFIG_STR
/******************************************************************************/
/* Public APIs */
#include <time.h>
/******************************************************************************/
PSPUBLIC int32 psCoreOpen(const char *config);
PSPUBLIC void psCoreClose(void);
PSPUBLIC void psBurnStack(uint32 len);
PSPUBLIC int32 memcmpct(const void *s1, const void *s2, size_t len);
/******************************************************************************/
/*
Public interface to OS-dependant core functionality
OS/osdep.c must implement the below functions
*/
PSPUBLIC int32 psGetEntropy(unsigned char *bytes, uint32 size,
void *userPtr);
PSPUBLIC int32 psGetTime(psTime_t *t, void *userPtr);
PSPUBLIC int32 psDiffMsecs(psTime_t then, psTime_t now, void *userPtr);
/* psCompareTime is no longer used */
PSPUBLIC int32 psCompareTime(psTime_t a, psTime_t b, void *userPtr);
#ifdef MATRIX_USE_FILE_SYSTEM
PSPUBLIC int32 psGetFileBuf(psPool_t *pool, const char *fileName,
unsigned char **buf, int32 *bufLen);
#endif /* MATRIX_USE_FILE_SYSTEM */
#ifdef USE_MULTITHREADING
PSPUBLIC int32 psCreateMutex(psMutex_t *mutex);
PSPUBLIC int32 psLockMutex(psMutex_t *mutex);
PSPUBLIC int32 psUnlockMutex(psMutex_t *mutex);
PSPUBLIC void psDestroyMutex(psMutex_t *mutex);
#else
#define psCreateMutex(A) (PS_SUCCESS)
#define psLockMutex(A) (PS_SUCCESS)
#define psUnlockMutex(A) (PS_SUCCESS)
#define psDestroyMutex(A)
#endif /* USE_MULTITHREADING */
/******************************************************************************/
/*
Internal list helpers
*/
extern int32 psParseList(psPool_t *pool, char *list, const char separator,
psList_t **items);
extern void psFreeList(psList_t *list, psPool_t *pool);
/******************************************************************************/
/*
Statistics helpers
*/
/** Number of samples to store take for running average. */
#define STAT_AVG_SAMPLES 32
typedef struct {
uint32_t h; /**< High water */
uint32_t a[STAT_AVG_SAMPLES]; /**< Values */
uint32_t atot; /**< Running total of a[] values */
uint16_t ai; /**< Most recent index into a[] */
uint16_t an; /**< Current number of valid entries in a[] */
} psAvgStat_t;
__inline static void STAT_INC_AVG(psAvgStat_t *s, uint32_t val)
{
/* Update high water */
if (val > s->h) {
s->h = val;
}
if (s->an < STAT_AVG_SAMPLES) {
/* Update total number of stats, if not at max */
s->an++;
} else {
/* Subtract the oldest value from the running total, if we're replacing */
s->atot -= s->a[s->ai];
}
/* Point to next entry, replace it and increment running total */
s->ai = (s->ai + 1) % STAT_AVG_SAMPLES;
s->a[s->ai] = val;
s->atot += val;
}
__inline static uint32_t STAT_AVG(psAvgStat_t *s)
{
return (s->atot / s->an);
}
__inline static uint32_t STAT_HIGH(psAvgStat_t *s)
{
return s->h;
}
#ifdef __cplusplus
}
#endif
#endif /* _h_PS_COREAPI */
/******************************************************************************/

77
core/coreConfig.h Normal file
View File

@@ -0,0 +1,77 @@
/**
* @file coreConfig.h
* @version $Format:%h%d$
*
* Configuration settings for Matrix core module.
*/
/*
* Copyright (c) 2013-2016 INSIDE Secure Corporation
* Copyright (c) PeerSec Networks, 2002-2011
* All Rights Reserved
*
* The latest version of this code is available at http://www.matrixssl.org
*
* This software is open source; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This General Public License does NOT permit incorporating this software
* into proprietary programs. If you are unable to comply with the GPL, a
* commercial license for this software may be purchased from INSIDE at
* http://www.insidesecure.com/
*
* This program is distributed in WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* http://www.gnu.org/copyleft/gpl.html
*/
/******************************************************************************/
#ifndef _h_PS_CORECONFIG
#define _h_PS_CORECONFIG
/******************************************************************************/
/* Configurable features */
/******************************************************************************/
/**
Enable various levels of trace.
When these option is turned off, messages are silently
discarded and their text does not take space in the binary image.
*/
//#define USE_CORE_TRACE
#ifndef NO_CORE_ERROR
#define USE_CORE_ERROR
#endif
#ifndef NO_CORE_ASSERT
#define USE_CORE_ASSERT
#endif
/**
If enabled, calls to the psError set of APIs will perform a platform
abort on the exeutable to aid in debugging.
*/
#ifdef DEBUG
//#define HALT_ON_PS_ERROR /* NOT RECOMMENDED FOR PRODUCTION BUILDS */
#endif
/**
Include the psCoreOsdepMutex family of APIs
*/
#ifndef NO_MULTITHREADING
//#define USE_MULTITHREADING
#endif /* NO_MULTITHREADING */
#endif /* _h_PS_CORECONFIG */
/******************************************************************************/

314
core/corelib.c Normal file
View File

@@ -0,0 +1,314 @@
/**
* @file corelib.c
* @version $Format:%h%d$
*
* Open and Close APIs and utilities for Matrix core library.
*/
/*
* Copyright (c) 2013-2016 INSIDE Secure Corporation
* Copyright (c) PeerSec Networks, 2002-2011
* All Rights Reserved
*
* The latest version of this code is available at http://www.matrixssl.org
*
* This software is open source; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This General Public License does NOT permit incorporating this software
* into proprietary programs. If you are unable to comply with the GPL, a
* commercial license for this software may be purchased from INSIDE at
* http://www.insidesecure.com/
*
* This program is distributed in WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* http://www.gnu.org/copyleft/gpl.html
*/
/******************************************************************************/
#include "coreApi.h"
/******************************************************************************/
/*
Open (initialize) the Core module
The config param should always be passed as:
PSCORE_CONFIG
*/
static char g_config[32] = "N";
/******************************************************************************/
int32 psCoreOpen(const char *config)
{
if (*g_config == 'Y') {
return PS_CORE_IS_OPEN;
}
strncpy(g_config, PSCORE_CONFIG, sizeof(g_config) - 1);
if (strncmp(g_config, config, strlen(PSCORE_CONFIG)) != 0) {
psErrorStr( "Core config mismatch.\n" \
"Library: " PSCORE_CONFIG\
"\nCurrent: %s\n", config);
return -1;
}
if (osdepTimeOpen() < 0) {
psTraceCore("osdepTimeOpen failed\n");
return PS_FAILURE;
}
if (osdepEntropyOpen() < 0) {
psTraceCore("osdepEntropyOpen failed\n");
osdepTimeClose();
return PS_FAILURE;
}
#ifdef USE_MULTITHREADING
if (osdepMutexOpen() < 0) {
psTraceCore("osdepMutexOpen failed\n");
osdepEntropyClose();
osdepTimeClose();
return PS_FAILURE;
}
#endif /* USE_MULTITHREADING */
return PS_SUCCESS;
}
/******************************************************************************/
void psCoreClose(void)
{
if (*g_config == 'Y') {
*g_config = 'N';
#ifdef USE_MULTITHREADING
osdepMutexClose();
#endif /* USE_MULTITHREADING */
osdepEntropyClose();
osdepTimeClose();
}
}
/******************************************************************************/
/**
Constant time memory comparison - like memcmp but w/o data dependent branch.
@security SECURITY - Should be used when comparing values that use or have
been derived or have been decrypted/encrypted/signed from secret information.
@param[in] s1 Pointer to first buffer to compare
@param[in] s2 Pointer to first buffer to compare
@param[in] len number of bytes to compare in s1 and s2
@return 0 on successful match, nonzero on failure.
*/
int32 memcmpct(const void *s1, const void *s2, size_t len)
{
int xor = 0;
while(len > 0) {
len--;
xor |= ((unsigned char *)s1)[len] ^ ((unsigned char *)s2)[len];
}
return xor;
}
/******************************************************************************/
/*
ERROR FUNCTIONS
Tap into platform trace and break execution if DEBUG compile
Modules should tie themselves to these low levels
with compile-time defines
*/
void _psError(const char *msg)
{
_psTrace(msg);
_psTrace("\n");
#ifdef HALT_ON_PS_ERROR
osdepBreak();
#endif
}
void _psErrorInt(const char *msg, int32 val)
{
_psTraceInt(msg, val);
_psTrace("\n");
#ifdef HALT_ON_PS_ERROR
osdepBreak();
#endif
}
void _psErrorStr(const char *msg, const char *val)
{
_psTraceStr(msg, val);
_psTrace("\n");
#ifdef HALT_ON_PS_ERROR
osdepBreak();
#endif
}
/*
copy 'len' bytes from 'b' to 's', converting all to printable characters
*/
static void mem2str(char *s, const unsigned char *b, uint32 len)
{
for (; len > 0; len--) {
if (*b > 31 && *b < 127) {
*s = *b;
} else {
*s = '.';
}
b++;
s++;
}
}
void psTraceBytes(const char *tag, const unsigned char *p, int l)
{
char s[17];
int i;
s[16] = '\0';
if (tag) {
_psTraceStr("psTraceBytes(%s, ", tag);
_psTraceInt("%d);", l);
} else {
_psTrace("\"");
}
for (i = 0; i < l; i++) {
if (!(i & 0xF)) {
if (tag) {
if (i != 0) {
mem2str(s, p - 16, 16);
_psTraceStr(" %s", s);
}
#ifdef _LP64
_psTraceInt("\n0x%08x:", (int64)p);
#else
_psTraceInt("\n0x%04x:", (int32)p);
#endif
} else {
_psTrace("\"\n\"");
}
}
if (tag) {
_psTraceInt("%02x ", *p++);
} else {
_psTraceInt("\\x%02x", *p++);
}
}
if (tag) {
memset(s, 0x0, 16);
i = l & 0xF;
mem2str(s, p - i, (unsigned int)i);
for (;i < 16; i++) {
_psTrace(" ");
}
_psTraceStr(" %s", s);
_psTrace("\n");
} else {
_psTrace("\"\n");
}
}
/******************************************************************************/
/*
Creates a simple linked list from a given stream and separator char
Memory info:
Callers do not have to free 'items' on function failure.
*/
int32 psParseList(psPool_t *pool, char *list, const char separator,
psList_t **items)
{
psList_t *litems, *start, *prev;
uint32 itemLen, listLen;
char *tmp;
*items = NULL;
prev = NULL;
listLen = (int32)strlen(list) + 1;
if (listLen == 1) {
return PS_ARG_FAIL;
}
start = litems = psMalloc(pool, sizeof(psList_t));
if (litems == NULL) {
return PS_MEM_FAIL;
}
memset(litems, 0, sizeof(psList_t));
while (listLen > 0) {
itemLen = 0;
tmp = list;
if (litems == NULL) {
litems = psMalloc(pool, sizeof(psList_t));
if (litems == NULL) {
psFreeList(start, pool);
return PS_MEM_FAIL;
}
memset(litems, 0, sizeof(psList_t));
prev->next = litems;
}
while (*list != separator && *list != '\0') {
itemLen++;
listLen--;
list++;
}
litems->item = psMalloc(pool, itemLen + 1);
if (litems->item == NULL) {
psFreeList(start, pool);
return PS_MEM_FAIL;
}
litems->len = itemLen;
memset(litems->item, 0x0, itemLen + 1);
memcpy(litems->item, tmp, itemLen);
list++;
listLen--;
prev = litems;
litems = litems->next;
}
*items = start;
return PS_SUCCESS;
}
void psFreeList(psList_t *list, psPool_t *pool)
{
psList_t *next, *current;
if (list == NULL) {
return;
}
current = list;
while (current) {
next = current->next;
if (current->item) {
psFree(current->item, pool);
}
psFree(current, pool);
current = next;
}
}
/******************************************************************************/
/*
Clear the stack deeper than the caller to erase any potential secrets
or keys.
*/
void psBurnStack(uint32 len)
{
unsigned char buf[32];
memset_s(buf, sizeof(buf), 0x0, sizeof(buf));
if (len > (uint32)sizeof(buf)) {
psBurnStack(len - sizeof(buf));
}
}
/******************************************************************************/

168
core/list.h Normal file
View File

@@ -0,0 +1,168 @@
/**
* @file list.h
* @version $Format:%h%d$
*
* List utilities.
*/
/*
* Copyright (c) 2013-2016 INSIDE Secure Corporation
* Copyright (c) PeerSec Networks, 2002-2011
* All Rights Reserved
*
* The latest version of this code is available at http://www.matrixssl.org
*
* This software is open source; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This General Public License does NOT permit incorporating this software
* into proprietary programs. If you are unable to comply with the GPL, a
* commercial license for this software may be purchased from INSIDE at
* http://www.insidesecure.com/
*
* This program is distributed in WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* http://www.gnu.org/copyleft/gpl.html
*/
/******************************************************************************/
#ifndef _h_PS_COREUTIL
#define _h_PS_COREUTIL
/********************************** Defines ***********************************/
/*
* Fast circular doubly-linked list and branchless macro-functions.
* Provides a struct-independent way to have a small head and hang a list
* of structs off of it. Examples of use:
*
* typedef struct {
* int bar;
* DLListEntry List;
* } foo;
*
* Define foo list head:
* DLListEntry FooListHead;
*
* Init for list head:
* DLListInit(&FooListHead);
*
* Define and init list head:
* DEFINE_DLLIST(FooListHead);
* or
* static DEFINE_DLLIST(FooListHead);
*
* Insert *pMyFoo after the head:
* foo *pMyFoo;
* pMyFoo = malloc(sizeof(foo));
* DLListInsertHead(&FooListHead, &pMyFoo->List);
*
* Do the same but place at tail:
* DLListInsertTail(&FooListHead, &pMyFoo->List);
*
* Given a foo that you know is in a list, detach it from the list:
* DLListRemove(&pMyFoo->List);
*
* Detach and return the list entry for the head item:
* DLListEntry *pList;
* pList = DLListGetHead(&FooListHead);
* pMyFoo = DLListGetContainer(pList, foo, List);
*
* Iterate the entire list:
* DLListEntry *pList;
* pList = FooListHead.pNext;
* while (pList != &FooListHead) {
* pCurFoo = DLListGetContainer(pList, foo, List);
* ... (do something with the current foo)
* pList = pList->pNext;
* }
*
* Iterate the entire list, removing each item (e.g. on all-list destruction):
* DLListEntry *pList;
* while (!DLListIsEmpty(&FooListHead)) {
* pList = DLListGetHead(&FooListHead);
* pMyFoo = DLListGetContainer(pList, foo, List);
* DestroyFoo(pMyFoo);
* free(pMyFoo);
* }
*/
typedef struct _DLListEntry {
struct _DLListEntry *pNext, *pPrev;
} DLListEntry;
#define DEFINE_DLLIST(x) DLListEntry x = { .pNext = &x, .pPrev = &x };
#define DLListInit(__pList) \
(__pList)->pNext = (__pList)->pPrev = (__pList)
/* Inserts an item as the first item of the list */
#define DLListInsertHead(__pHead, __pNode) { \
psAssert((__pHead) != (__pNode)); \
(__pNode)->pNext = (__pHead)->pNext; \
(__pNode)->pPrev = (__pHead); \
(__pHead)->pNext->pPrev = (__pNode); \
(__pHead)->pNext = (__pNode); \
}
/* Inserts an item as the last in the list */
#define DLListInsertTail(__pHead, __pNode) { \
psAssert((__pHead) != (__pNode)); \
(__pNode)->pNext = (__pHead); \
(__pNode)->pPrev = (__pHead)->pPrev; \
(__pHead)->pPrev->pNext = (__pNode); \
(__pHead)->pPrev = (__pNode); \
}
/* Detaches node from current position in the list. */
#define DLListRemove(__pNode) { \
(__pNode)->pNext->pPrev = (__pNode)->pPrev; \
(__pNode)->pPrev->pNext = (__pNode)->pNext; \
}
#define DLListIsEmpty(__pHead) ((__pHead)->pNext == (__pHead))
/*
Gets the pointer to the containing object given the DLList pointer,
the type name of the struct, and the name of the DLList field within
the struct.
*/
#define DLListGetContainer(__pDLList, __ContainerType, __DLListFieldName) \
((__ContainerType *)((char *)(__pDLList) - \
(long)(&((__ContainerType *)0)->__DLListFieldName)))
/*
Detaches first list item after the head and returns a pointer to it.
List must not be empty.
*/
#define DLListGetHead(__pHead) \
(__pHead)->pNext; \
(__pHead)->pNext->pNext->pPrev = (__pHead); \
(__pHead)->pNext = (__pHead)->pNext->pNext;
/*
Detaches list list item before the head and returns a pointer to it.
List must not be empty.
*/
#define DLListGetTail(__pHead) \
(__pHead)->pPrev; \
(__pHead)->pPrev->pPrev->pNext = (__pHead); \
(__pHead)->pPrev = (__pHead)->pPrev->pPrev;
/******************************************************************************/
/*
Simpler, single linked list
*/
typedef struct psList {
unsigned char *item;
struct psList *next;
uint16_t len;
} psList_t;
#endif /* _h_PS_COREUTIL */
/******************************************************************************/

84
core/memset_s.c Normal file
View File

@@ -0,0 +1,84 @@
/**
* @file memset_s.c
* @version $Format:%h%d$
*
* Secure memset api that will not be optimized out by compiler.
*/
/*
* Copyright (c) 2013-2016 INSIDE Secure Corporation
* Copyright (c) PeerSec Networks, 2002-2011
* All Rights Reserved
*
* The latest version of this code is available at http://www.matrixssl.org
*
* This software is open source; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This General Public License does NOT permit incorporating this software
* into proprietary programs. If you are unable to comply with the GPL, a
* commercial license for this software may be purchased from INSIDE at
* http://www.insidesecure.com/
*
* This program is distributed in WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* http://www.gnu.org/copyleft/gpl.html
*/
/******************************************************************************/
/**
Implementation of C11 API for platforms that do not have it.
In contrast to the memset(3) function, calls to memset_s() will never be
"optimised away" by a compiler. This property is required by the follow-
ing sentences in section K.3.7.4.1 of ISO/IEC 9899:2011 ("ISO C11"):
Unlike memset(), any call to the memset_s() function shall be evalu-
ated strictly according to the rules of the abstract machine as
described in (5.1.2.3). That is, any call to the memset_s() function
shall assume that the memory indicated by s and n may be accessible
in the future and thus must contain the values indicated by c.
On Mac OS X, this api is natively implemented.
On Windows, this api is mapped to SecureZeroMemory()
*/
#if !defined(_WIN32) && !defined(__APPLE__)
#ifdef __OPTIMIZE__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpragmas"
#pragma GCC push_options
#pragma GCC optimize("O0")
#define NO_OPTIM __attribute__((noinline)) __attribute__((optimize("O0")))
#else
#define NO_OPTIM
#endif
#include <string.h>
typedef size_t rsize_t;
typedef int errno_t;
errno_t NO_OPTIM memset_s(void *s, rsize_t smax, int c, rsize_t n)
{
if (n > smax) {
n = smax;
}
memset(s, c, n);
return ((unsigned char volatile *)s)[0];
}
#ifdef __OPTIMIZE__
#pragma GCC pop_options
#pragma GCC diagnostic pop
#endif
#undef NO_OPTIM
#endif /* !WIN && ! APPLE */
/******************************************************************************/

425
core/osdep.h Normal file
View File

@@ -0,0 +1,425 @@
/**
* @file osdep.h
* @version $Format:%h%d$
*
* Operating System and Hardware Abstraction Layer.
*/
/*
* Copyright (c) 2013-2016 INSIDE Secure Corporation
* Copyright (c) PeerSec Networks, 2002-2011
* All Rights Reserved
*
* The latest version of this code is available at http://www.matrixssl.org
*
* This software is open source; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This General Public License does NOT permit incorporating this software
* into proprietary programs. If you are unable to comply with the GPL, a
* commercial license for this software may be purchased from INSIDE at
* http://www.insidesecure.com/
*
* This program is distributed in WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* http://www.gnu.org/copyleft/gpl.html
*/
/******************************************************************************/
#ifndef _h_PS_PLATFORM
#define _h_PS_PLATFORM
/******************************************************************************/
/*
Platform detection based on compiler settings
@see http://sourceforge.net/p/predef/wiki/Home/
*/
/* Determine the operating system (if any) */
#if defined(__linux__) /* Linux and Android */
#define POSIX
#define LINUX
#define MATRIX_USE_FILE_SYSTEM
#elif defined(__APPLE__) && defined(__MACH__) /* Mac OS X */
#define POSIX
#define OSX
#define HAVE_NATIVE_INT64
#define MATRIX_USE_FILE_SYSTEM
#elif defined(_WIN32) /* Windows */
#ifndef WIN32
#define WIN32
#endif
#define HAVE_NATIVE_INT64
#define MATRIX_USE_FILE_SYSTEM
#endif
/* For others such as FREERTOS, define in build system */
/* Use packed attribute on compilers that support it */
#if defined(__GNUC__) || defined(__clang__)
#define PACKED __attribute__((__packed__))
#else
#define PACKED
#endif
/* Determine which assembly language optimizations we can use */
#if defined(__GNUC__) || defined(__clang__) /* Only supporting gcc-like */
#if defined(__x86_64__)
#define PSTM_X86_64
#define PSTM_64BIT /* Supported by architecture */
#elif defined(__i386__)
#define PSTM_X86
#elif defined(__arm__)
#define PSTM_ARM
//__aarch64__ /* 64 bit arm */
//__thumb__ /* Thumb mode */
#elif defined(__mips__)
#if defined(__mips64)
#define PSTM_64BIT
#else
#define PSTM_MIPS /* MIPS assembly supported on 32 bit only */
#endif
#endif
#endif /* GNUC/CLANG */
/* Try to determine if the compiler/platform supports 64 bit integer ops */
#if !defined(HAVE_NATIVE_INT64) && defined(__SIZEOF_LONG_LONG__)
#define HAVE_NATIVE_INT64 /* Supported by compiler */
#endif
/* Detect endian based on platform */
#if (defined __LITTLE_ENDIAN__ || defined __i386__ || defined __x86_64__ || \
defined _M_X64 || defined _M_IX86 || \
defined __ARMEL__ || defined __MIPSEL__)
#define __ORDER_LITTLE_ENDIAN__ 1234
#define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__
#elif (defined __BIG_ENDIAN__ || defined __MIPSEB__)
#define __ORDER_BIG_ENDIAN__ 4321
#define __BYTE_ORDER__ __ORDER_BIG_ENDIAN__
#endif
#ifdef __BYTE_ORDER__ /* Newer GCC and LLVM */
#if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
#define ENDIAN_LITTLE
#else
#define ENDIAN_BIG
#endif
#ifdef PSTM_64BIT
#define ENDIAN_64BITWORD
#else
#define ENDIAN_32BITWORD
#endif
#else
#if (defined(_MSC_VER) && defined(WIN32)) || \
(defined(__GNUC__) && (defined(__DJGPP__) || defined(__CYGWIN__) || \
defined(__MINGW32__) || defined(__i386__)))
#define ENDIAN_LITTLE
#define ENDIAN_32BITWORD
#else
#warning "Cannot determine endianness, using neutral"
#endif
/* #define ENDIAN_LITTLE */
/* #define ENDIAN_BIG */
/* #define ENDIAN_32BITWORD */
/* #define ENDIAN_64BITWORD */
#endif
#if (defined(ENDIAN_BIG) || defined(ENDIAN_LITTLE)) && \
!(defined(ENDIAN_32BITWORD) || defined(ENDIAN_64BITWORD))
#error You must specify a word size as well as endianness
#endif
#if !(defined(ENDIAN_BIG) || defined(ENDIAN_LITTLE))
#define ENDIAN_NEUTRAL
#endif
/******************************************************************************/
/*
APIs that must be implemented on every platform
*/
#ifdef WIN32
#ifdef _LIB /* Static library */
#define PSPUBLIC extern
#else
#ifdef _USRDLL /* DLL */
#define PSPUBLIC extern __declspec(dllexport)
#else
#define PSPUBLIC extern __declspec(dllimport)
#endif
#endif
#else
#define PSPUBLIC extern
#endif /* !WIN32 */
extern int osdepTraceOpen(void);
extern void osdepTraceClose(void);
extern int osdepTimeOpen(void);
extern void osdepTimeClose(void);
extern int osdepEntropyOpen(void);
extern void osdepEntropyClose(void);
#ifdef HALT_ON_PS_ERROR
extern void osdepBreak(void);
#endif
#ifndef min
#define min(a,b) (((a) < (b)) ? (a) : (b))
#endif /* min */
/******************************************************************************/
/*
If the Makefile specifies that MatrixSSL does not currently have
a layer for the given OS, or the port is to "bare metal" hardware,
do basic defines here and include externally provided file "matrixos.h".
In addition, if building for such a platform, a C file defining the above
functions must be linked with the final executable.
*/
#ifdef PS_UNSUPPORTED_OS
#include "matrixos.h"
#else
/******************************************************************************/
/*
Supported Platforms below. The implementations of the apis are in
platform specific directories, such as core/POSIX and core/ECOS
POSIX define is used for Linux and Mac OS X
*/
#include <stdio.h>
#ifndef POSIX
#if defined(LINUX) || defined(OSX)
#define POSIX
#endif
#endif
#if defined(POSIX)
#include <stdint.h>
typedef int32_t int32;
typedef uint32_t uint32;
typedef int16_t int16;
typedef uint16_t uint16;
typedef uint8_t uint8;
#ifdef HAVE_NATIVE_INT64
typedef int64_t int64;
typedef uint64_t uint64;
#endif
#elif defined(WIN32)
#include <windows.h>
#define strcasecmp lstrcmpiA
#define snprintf _snprintf
typedef signed long int32;
typedef unsigned long uint32;
typedef signed short int16;
typedef unsigned short uint16;
typedef unsigned char uint8;
typedef signed long int32_t;
typedef unsigned long uint32_t;
typedef signed short int16_t;
typedef unsigned short uint16_t;
typedef unsigned char uint8_t;
typedef signed char int8_t;
#ifdef HAVE_NATIVE_INT64
typedef unsigned long long uint64;
typedef signed long long int64;
typedef unsigned long long uint64_t;
typedef signed long long int64_t;
#endif
#elif defined(METAL)
typedef signed long int32;
typedef unsigned long uint32;
typedef signed short int16;
typedef unsigned short uint16;
#ifdef HAVE_NATIVE_INT64
typedef unsigned long long uint64;
typedef signed long long int64;
#endif
#elif defined (NUCLEUS)
#include <stdint.h>
typedef int32_t int32;
typedef uint32_t uint32;
typedef int16_t int16;
typedef uint16_t uint16;
typedef uint8_t uint8;
#ifdef HAVE_NATIVE_INT64
typedef int64_t int64;
typedef uint64_t uint64;
#endif
#endif
/******************************************************************************/
/*
Secure memset/memzero
*/
#if defined(WIN32)
#undef memset_s
#define memset_s(A,B,C,D) SecureZeroMemory(A,D)
#elif defined(OSX)
#define __STDC_WANT_LIB_EXT1__ 1
#include <string.h>
#else
#include <string.h>
typedef size_t rsize_t;
typedef int errno_t;
extern errno_t memset_s(void *s, rsize_t smax, int c, rsize_t n);
#endif
#define memzero_s(S,N) memset_s(S, N, 0x0, N)
/******************************************************************************/
/*
Hardware Abstraction Layer
*/
/* Hardware Abstraction Layer - define functions in HAL directory */
#if defined(POSIX) || defined(WIN32) || defined(ECOS) || defined(FREERTOS) || defined(NUCLEUS)
#define halOpen() 0
#define halClose()
#define halAlert()
#else
extern int halOpen(void);
extern void halAlert(void);
extern void halClose(void);
#endif /* HAL */
/******************************************************************************/
/*
OS-specific psTime_t types
Make psTime_t an opaque time value.
*/
#if defined(__x86_64__)
#define USE_HIGHRES_TIME
#endif
#if defined(POSIX)
#ifndef USE_HIGHRES_TIME
#include <sys/time.h>
#include <time.h>
typedef struct timeval psTime_t;
#else
#if defined(__APPLE__) || defined(__tile__)
typedef uint64_t psTime_t;
#else
#include <time.h>
typedef struct timespec psTime_t;
#endif
extern int64_t psDiffUsecs(psTime_t then, psTime_t now);
#endif
#elif defined(WIN32)
typedef LARGE_INTEGER psTime_t;
#elif defined(METAL)
typedef unsigned int psTime_t;
#elif defined(NUCLEUS)
typedef uint64_t psTime_t;
#elif defined(VXWORKS)
typedef struct {
long sec;
long usec;
} psTime_t;
#endif
/******************************************************************************/
/*
Raw trace and error
*/
PSPUBLIC void _psTrace(const char *msg);
PSPUBLIC void _psTraceInt(const char *msg, int32 val);
PSPUBLIC void _psTraceStr(const char *msg, const char *val);
PSPUBLIC void _psTracePtr(const char *message, const void *value);
PSPUBLIC void psTraceBytes(const char *tag, const unsigned char *p, int l);
PSPUBLIC void _psError(const char *msg);
PSPUBLIC void _psErrorInt(const char *msg, int32 val);
PSPUBLIC void _psErrorStr(const char *msg, const char *val);
/******************************************************************************/
/*
Core trace
*/
#ifndef USE_CORE_TRACE
#define psTraceCore(x)
#define psTraceStrCore(x, y)
#define psTraceIntCore(x, y)
#define psTracePtrCore(x, y)
#else
#define psTraceCore(x) _psTrace(x)
#define psTraceStrCore(x, y) _psTraceStr(x, y)
#define psTraceIntCore(x, y) _psTraceInt(x, y)
#define psTracePtrCore(x, y) _psTracePtr(x, y)
#endif /* USE_CORE_TRACE */
/******************************************************************************/
/*
HALT_ON_PS_ERROR define at compile-time determines whether to halt on
psAssert and psError calls
*/
#ifdef USE_CORE_ASSERT
#define psAssert(C) if (C) ; else \
{halAlert();_psTraceStr("psAssert %s", __FILE__);_psTraceInt(":%d ", __LINE__);\
_psError(#C);}
#else
#define psAssert(C) if (C) ; else do { /* assert ignored. */} while (0)
#endif
#ifdef USE_CORE_ERROR
#define psError(a) \
halAlert();_psTraceStr("psError %s", __FILE__);_psTraceInt(":%d ", __LINE__); \
_psError(a);
#define psErrorStr(a,b) \
halAlert();_psTraceStr("psError %s", __FILE__);_psTraceInt(":%d ", __LINE__); \
_psErrorStr(a,b)
#define psErrorInt(a,b) \
halAlert();_psTraceStr("psError %s", __FILE__);_psTraceInt(":%d ", __LINE__); \
_psErrorInt(a,b)
#else
#define psError(a) do { /* error ignored. */} while (0)
#define psErrorStr(a,b) do { /* error ignored. */} while (0)
#define psErrorInt(a,b) do { /* error ignored. */} while (0)
#endif
/******************************************************************************/
/*
OS specific file system apis
*/
#ifdef MATRIX_USE_FILE_SYSTEM
#ifdef POSIX
#include <sys/stat.h>
#endif /* POSIX */
#endif /* MATRIX_USE_FILE_SYSTEM */
/******************************************************************************/
/*
Defines to make library multithreading safe
*/
#ifdef USE_MULTITHREADING
extern int32 osdepMutexOpen(void);
extern int32 osdepMutexClose(void);
#if defined(WIN32)
typedef CRITICAL_SECTION psMutex_t;
#elif defined(POSIX)
#include <string.h>
#include <pthread.h>
typedef pthread_mutex_t psMutex_t;
#elif defined(VXWORKS)
#include "semLib.h"
typedef SEM_ID psMutex_t;
#else
#error psMutex_t must be defined
#endif /* OS specific mutex */
#endif /* USE_MULTITHREADING */
/******************************************************************************/
#endif /* !PS_UNSUPPORTED_OS */
#endif /* _h_PS_PLATFORM */

79
core/psmalloc.h Normal file
View File

@@ -0,0 +1,79 @@
/**
* @file psmalloc.h
* @version $Format:%h%d$
*
* Header for psMalloc functions.
*/
/*
* Copyright (c) 2013-2016 INSIDE Secure Corporation
* Copyright (c) PeerSec Networks, 2002-2011
* All Rights Reserved
*
* The latest version of this code is available at http://www.matrixssl.org
*
* This software is open source; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This General Public License does NOT permit incorporating this software
* into proprietary programs. If you are unable to comply with the GPL, a
* commercial license for this software may be purchased from INSIDE at
* http://www.insidesecure.com/
*
* This program is distributed in WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* http://www.gnu.org/copyleft/gpl.html
*/
/******************************************************************************/
#ifndef _h_PS_MALLOC
#define _h_PS_MALLOC
/******************************************************************************/
/*
*/
#ifdef PS_UNSUPPORTED_OS
#include "matrixos.h"
#else
/******************************************************************************/
/*
*/
#include <string.h> /* memset, memcpy */
#define MATRIX_NO_POOL (void *)0x0
/******************************************************************************/
/*
Native memory routines
*/
#include <stdlib.h> /* malloc, free, etc... */
#define MAX_MEMORY_USAGE 0
#define psOpenMalloc() 0
#define psCloseMalloc()
#define psDefineHeap(A, B)
#define psAddPoolCache(A, B)
#define psMalloc(A, B) malloc(B)
#define psCalloc(A, B, C) calloc(B, C)
#define psMallocNoPool malloc
#define psRealloc(A, B, C) realloc(A, B)
#define psFree(A, B) free(A)
#define psMemset memset
#define psMemcpy memcpy
typedef int32 psPool_t;
/******************************************************************************/
#endif /* !PS_UNSUPPORTED_OS */
#endif /* _h_PS_MALLOC */
/******************************************************************************/