motify compile link error

motify compile link error
This commit is contained in:
ant 2016-09-18 09:03:25 +08:00
parent 923914edae
commit 03e74a8e50
5418 changed files with 1367914 additions and 206149 deletions

View file

@ -1,73 +1,73 @@
include $(MAKE_INCLUDE_GEN)
.PHONY: all clean
#*****************************************************************************#
# VARIABLES #
#*****************************************************************************#
MODULE_IFLAGS += -I../../include -fno-tree-switch-conversion
GLOBAL_CFLAGS += -DCONFIG_SSL_ROM
#*****************************************************************************#
# Object FILE LIST #
#*****************************************************************************#
OBJS =
ROM_CSRC = aes.o \
arc4.o \
asn1parse.o \
asn1write.o \
base64.o \
bignum.o \
ctr_drbg.o \
des.o \
dhm.o \
ecdh.o \
ecdsa.o \
ecp.o \
ecp_curves.o \
hmac_drbg.o \
md.o \
md_wrap.o \
md5.o \
oid.o \
pem.o \
pk.o \
pk_wrap.o \
pkwrite.o \
rsa.o \
sha1.o \
sha256.o \
sha512.o \
../../../ssl_ram_map/rom/rom_ssl_ram_map.o
OBJS = $(ROM_CSRC)
#*****************************************************************************#
# RULES TO GENERATE TARGETS #
#*****************************************************************************#
# Define the Rules to build the core targets
all: CORE_TARGETS RENAME_ROM_OBJS COPY_ROM_OBJS
#*****************************************************************************#
# GENERATE OBJECT FILE
#*****************************************************************************#
CORE_TARGETS: $(OBJS) $(ASM_OBJS)
#*****************************************************************************#
# RULES TO CLEAN TARGETS #
#*****************************************************************************#
clean:
$(REMOVE) *.o
$(REMOVE) *.i
$(REMOVE) *.s
$(REMOVE) *.d
-include $(DEPS)
include $(MAKE_INCLUDE_GEN)
.PHONY: all clean
#*****************************************************************************#
# VARIABLES #
#*****************************************************************************#
MODULE_IFLAGS += -I../../include -fno-tree-switch-conversion
GLOBAL_CFLAGS += -DCONFIG_SSL_ROM
#*****************************************************************************#
# Object FILE LIST #
#*****************************************************************************#
OBJS =
ROM_CSRC = aes.o \
arc4.o \
asn1parse.o \
asn1write.o \
base64.o \
bignum.o \
ctr_drbg.o \
des.o \
dhm.o \
ecdh.o \
ecdsa.o \
ecp.o \
ecp_curves.o \
hmac_drbg.o \
md.o \
md_wrap.o \
md5.o \
oid.o \
pem.o \
pk.o \
pk_wrap.o \
pkwrite.o \
rsa.o \
sha1.o \
sha256.o \
sha512.o \
../../../ssl_ram_map/rom/rom_ssl_ram_map.o
OBJS = $(ROM_CSRC)
#*****************************************************************************#
# RULES TO GENERATE TARGETS #
#*****************************************************************************#
# Define the Rules to build the core targets
all: CORE_TARGETS RENAME_ROM_OBJS COPY_ROM_OBJS
#*****************************************************************************#
# GENERATE OBJECT FILE
#*****************************************************************************#
CORE_TARGETS: $(OBJS) $(ASM_OBJS)
#*****************************************************************************#
# RULES TO CLEAN TARGETS #
#*****************************************************************************#
clean:
$(REMOVE) *.o
$(REMOVE) *.i
$(REMOVE) *.s
$(REMOVE) *.d
-include $(DEPS)

View file

@ -1,404 +1,404 @@
/*
* Generic ASN.1 parsing
*
* Copyright (C) 2006-2014, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; 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 program is distributed in the hope that it will be useful,
* but 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#if !defined(POLARSSL_CONFIG_FILE)
#include "polarssl/config.h"
#else
#include POLARSSL_CONFIG_FILE
#endif
#if defined(POLARSSL_ASN1_PARSE_C)
#include "polarssl/asn1.h"
#if defined(POLARSSL_BIGNUM_C)
#include "polarssl/bignum.h"
#endif
#if defined(POLARSSL_PLATFORM_C)
#include "polarssl/platform.h"
#else
#define polarssl_malloc malloc
#define polarssl_free free
#endif
#include <string.h>
#include <stdlib.h>
/*
* ASN.1 DER decoding routines
*/
SSL_ROM_TEXT_SECTION
int asn1_get_len( unsigned char **p,
const unsigned char *end,
size_t *len )
{
if( ( end - *p ) < 1 )
return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
if( ( **p & 0x80 ) == 0 )
*len = *(*p)++;
else
{
switch( **p & 0x7F )
{
case 1:
if( ( end - *p ) < 2 )
return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
*len = (*p)[1];
(*p) += 2;
break;
case 2:
if( ( end - *p ) < 3 )
return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
*len = ( (*p)[1] << 8 ) | (*p)[2];
(*p) += 3;
break;
case 3:
if( ( end - *p ) < 4 )
return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
*len = ( (*p)[1] << 16 ) | ( (*p)[2] << 8 ) | (*p)[3];
(*p) += 4;
break;
case 4:
if( ( end - *p ) < 5 )
return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
*len = ( (*p)[1] << 24 ) | ( (*p)[2] << 16 ) | ( (*p)[3] << 8 ) |
(*p)[4];
(*p) += 5;
break;
default:
return( POLARSSL_ERR_ASN1_INVALID_LENGTH );
}
}
if( *len > (size_t) ( end - *p ) )
return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
return( 0 );
}
SSL_ROM_TEXT_SECTION
int asn1_get_tag( unsigned char **p,
const unsigned char *end,
size_t *len, int tag )
{
if( ( end - *p ) < 1 )
return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
if( **p != tag )
return( POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
(*p)++;
return( asn1_get_len( p, end, len ) );
}
SSL_ROM_TEXT_SECTION
int asn1_get_bool( unsigned char **p,
const unsigned char *end,
int *val )
{
int ret;
size_t len;
if( ( ret = asn1_get_tag( p, end, &len, ASN1_BOOLEAN ) ) != 0 )
return( ret );
if( len != 1 )
return( POLARSSL_ERR_ASN1_INVALID_LENGTH );
*val = ( **p != 0 ) ? 1 : 0;
(*p)++;
return( 0 );
}
SSL_ROM_TEXT_SECTION
int asn1_get_int( unsigned char **p,
const unsigned char *end,
int *val )
{
int ret;
size_t len;
if( ( ret = asn1_get_tag( p, end, &len, ASN1_INTEGER ) ) != 0 )
return( ret );
if( len > sizeof( int ) || ( **p & 0x80 ) != 0 )
return( POLARSSL_ERR_ASN1_INVALID_LENGTH );
*val = 0;
while( len-- > 0 )
{
*val = ( *val << 8 ) | **p;
(*p)++;
}
return( 0 );
}
#if defined(POLARSSL_BIGNUM_C)
SSL_ROM_TEXT_SECTION
int asn1_get_mpi( unsigned char **p,
const unsigned char *end,
mpi *X )
{
int ret;
size_t len;
if( ( ret = asn1_get_tag( p, end, &len, ASN1_INTEGER ) ) != 0 )
return( ret );
ret = mpi_read_binary( X, *p, len );
*p += len;
return( ret );
}
#endif /* POLARSSL_BIGNUM_C */
SSL_ROM_TEXT_SECTION
int asn1_get_bitstring( unsigned char **p, const unsigned char *end,
asn1_bitstring *bs)
{
int ret;
/* Certificate type is a single byte bitstring */
if( ( ret = asn1_get_tag( p, end, &bs->len, ASN1_BIT_STRING ) ) != 0 )
return( ret );
/* Check length, subtract one for actual bit string length */
if( bs->len < 1 )
return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
bs->len -= 1;
/* Get number of unused bits, ensure unused bits <= 7 */
bs->unused_bits = **p;
if( bs->unused_bits > 7 )
return( POLARSSL_ERR_ASN1_INVALID_LENGTH );
(*p)++;
/* Get actual bitstring */
bs->p = *p;
*p += bs->len;
if( *p != end )
return( POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
return( 0 );
}
/*
* Get a bit string without unused bits
*/
SSL_ROM_TEXT_SECTION
int asn1_get_bitstring_null( unsigned char **p, const unsigned char *end,
size_t *len )
{
int ret;
if( ( ret = asn1_get_tag( p, end, len, ASN1_BIT_STRING ) ) != 0 )
return( ret );
if( (*len)-- < 2 || *(*p)++ != 0 )
return( POLARSSL_ERR_ASN1_INVALID_DATA );
return( 0 );
}
/*
* Parses and splits an ASN.1 "SEQUENCE OF <tag>"
*/
SSL_ROM_TEXT_SECTION
int asn1_get_sequence_of( unsigned char **p,
const unsigned char *end,
asn1_sequence *cur,
int tag)
{
int ret;
size_t len;
asn1_buf *buf;
/* Get main sequence tag */
if( ( ret = asn1_get_tag( p, end, &len,
ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
return( ret );
if( *p + len != end )
return( POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
while( *p < end )
{
buf = &(cur->buf);
buf->tag = **p;
if( ( ret = asn1_get_tag( p, end, &buf->len, tag ) ) != 0 )
return( ret );
buf->p = *p;
*p += buf->len;
/* Allocate and assign next pointer */
if( *p < end )
{
cur->next = (asn1_sequence *) polarssl_malloc(
sizeof( asn1_sequence ) );
if( cur->next == NULL )
return( POLARSSL_ERR_ASN1_MALLOC_FAILED );
cur = cur->next;
}
}
/* Set final sequence entry's next pointer to NULL */
cur->next = NULL;
if( *p != end )
return( POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
return( 0 );
}
SSL_ROM_TEXT_SECTION
int asn1_get_alg( unsigned char **p,
const unsigned char *end,
asn1_buf *alg, asn1_buf *params )
{
int ret;
size_t len;
if( ( ret = asn1_get_tag( p, end, &len,
ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
return( ret );
if( ( end - *p ) < 1 )
return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
alg->tag = **p;
end = *p + len;
if( ( ret = asn1_get_tag( p, end, &alg->len, ASN1_OID ) ) != 0 )
return( ret );
alg->p = *p;
*p += alg->len;
if( *p == end )
{
memset( params, 0, sizeof(asn1_buf) );
return( 0 );
}
params->tag = **p;
(*p)++;
if( ( ret = asn1_get_len( p, end, &params->len ) ) != 0 )
return( ret );
params->p = *p;
*p += params->len;
if( *p != end )
return( POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
return( 0 );
}
SSL_ROM_TEXT_SECTION
int asn1_get_alg_null( unsigned char **p,
const unsigned char *end,
asn1_buf *alg )
{
int ret;
asn1_buf params;
memset( &params, 0, sizeof(asn1_buf) );
if( ( ret = asn1_get_alg( p, end, alg, &params ) ) != 0 )
return( ret );
if( ( params.tag != ASN1_NULL && params.tag != 0 ) || params.len != 0 )
return( POLARSSL_ERR_ASN1_INVALID_DATA );
return( 0 );
}
SSL_ROM_TEXT_SECTION
void asn1_free_named_data( asn1_named_data *cur )
{
if( cur == NULL )
return;
polarssl_free( cur->oid.p );
polarssl_free( cur->val.p );
memset( cur, 0, sizeof( asn1_named_data ) );
}
SSL_ROM_TEXT_SECTION
void asn1_free_named_data_list( asn1_named_data **head )
{
asn1_named_data *cur;
while( ( cur = *head ) != NULL )
{
*head = cur->next;
asn1_free_named_data( cur );
polarssl_free( cur );
}
}
SSL_ROM_TEXT_SECTION
asn1_named_data *asn1_find_named_data( asn1_named_data *list,
const char *oid, size_t len )
{
while( list != NULL )
{
if( list->oid.len == len &&
memcmp( list->oid.p, oid, len ) == 0 )
{
break;
}
list = list->next;
}
return( list );
}
#endif /* POLARSSL_ASN1_PARSE_C */
/*
* Generic ASN.1 parsing
*
* Copyright (C) 2006-2014, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; 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 program is distributed in the hope that it will be useful,
* but 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#if !defined(POLARSSL_CONFIG_FILE)
#include "polarssl/config.h"
#else
#include POLARSSL_CONFIG_FILE
#endif
#if defined(POLARSSL_ASN1_PARSE_C)
#include "polarssl/asn1.h"
#if defined(POLARSSL_BIGNUM_C)
#include "polarssl/bignum.h"
#endif
#if defined(POLARSSL_PLATFORM_C)
#include "polarssl/platform.h"
#else
#define polarssl_malloc malloc
#define polarssl_free free
#endif
#include <string.h>
#include <stdlib.h>
/*
* ASN.1 DER decoding routines
*/
SSL_ROM_TEXT_SECTION
int asn1_get_len( unsigned char **p,
const unsigned char *end,
size_t *len )
{
if( ( end - *p ) < 1 )
return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
if( ( **p & 0x80 ) == 0 )
*len = *(*p)++;
else
{
switch( **p & 0x7F )
{
case 1:
if( ( end - *p ) < 2 )
return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
*len = (*p)[1];
(*p) += 2;
break;
case 2:
if( ( end - *p ) < 3 )
return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
*len = ( (*p)[1] << 8 ) | (*p)[2];
(*p) += 3;
break;
case 3:
if( ( end - *p ) < 4 )
return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
*len = ( (*p)[1] << 16 ) | ( (*p)[2] << 8 ) | (*p)[3];
(*p) += 4;
break;
case 4:
if( ( end - *p ) < 5 )
return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
*len = ( (*p)[1] << 24 ) | ( (*p)[2] << 16 ) | ( (*p)[3] << 8 ) |
(*p)[4];
(*p) += 5;
break;
default:
return( POLARSSL_ERR_ASN1_INVALID_LENGTH );
}
}
if( *len > (size_t) ( end - *p ) )
return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
return( 0 );
}
SSL_ROM_TEXT_SECTION
int asn1_get_tag( unsigned char **p,
const unsigned char *end,
size_t *len, int tag )
{
if( ( end - *p ) < 1 )
return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
if( **p != tag )
return( POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
(*p)++;
return( asn1_get_len( p, end, len ) );
}
SSL_ROM_TEXT_SECTION
int asn1_get_bool( unsigned char **p,
const unsigned char *end,
int *val )
{
int ret;
size_t len;
if( ( ret = asn1_get_tag( p, end, &len, ASN1_BOOLEAN ) ) != 0 )
return( ret );
if( len != 1 )
return( POLARSSL_ERR_ASN1_INVALID_LENGTH );
*val = ( **p != 0 ) ? 1 : 0;
(*p)++;
return( 0 );
}
SSL_ROM_TEXT_SECTION
int asn1_get_int( unsigned char **p,
const unsigned char *end,
int *val )
{
int ret;
size_t len;
if( ( ret = asn1_get_tag( p, end, &len, ASN1_INTEGER ) ) != 0 )
return( ret );
if( len > sizeof( int ) || ( **p & 0x80 ) != 0 )
return( POLARSSL_ERR_ASN1_INVALID_LENGTH );
*val = 0;
while( len-- > 0 )
{
*val = ( *val << 8 ) | **p;
(*p)++;
}
return( 0 );
}
#if defined(POLARSSL_BIGNUM_C)
SSL_ROM_TEXT_SECTION
int asn1_get_mpi( unsigned char **p,
const unsigned char *end,
mpi *X )
{
int ret;
size_t len;
if( ( ret = asn1_get_tag( p, end, &len, ASN1_INTEGER ) ) != 0 )
return( ret );
ret = mpi_read_binary( X, *p, len );
*p += len;
return( ret );
}
#endif /* POLARSSL_BIGNUM_C */
SSL_ROM_TEXT_SECTION
int asn1_get_bitstring( unsigned char **p, const unsigned char *end,
asn1_bitstring *bs)
{
int ret;
/* Certificate type is a single byte bitstring */
if( ( ret = asn1_get_tag( p, end, &bs->len, ASN1_BIT_STRING ) ) != 0 )
return( ret );
/* Check length, subtract one for actual bit string length */
if( bs->len < 1 )
return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
bs->len -= 1;
/* Get number of unused bits, ensure unused bits <= 7 */
bs->unused_bits = **p;
if( bs->unused_bits > 7 )
return( POLARSSL_ERR_ASN1_INVALID_LENGTH );
(*p)++;
/* Get actual bitstring */
bs->p = *p;
*p += bs->len;
if( *p != end )
return( POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
return( 0 );
}
/*
* Get a bit string without unused bits
*/
SSL_ROM_TEXT_SECTION
int asn1_get_bitstring_null( unsigned char **p, const unsigned char *end,
size_t *len )
{
int ret;
if( ( ret = asn1_get_tag( p, end, len, ASN1_BIT_STRING ) ) != 0 )
return( ret );
if( (*len)-- < 2 || *(*p)++ != 0 )
return( POLARSSL_ERR_ASN1_INVALID_DATA );
return( 0 );
}
/*
* Parses and splits an ASN.1 "SEQUENCE OF <tag>"
*/
SSL_ROM_TEXT_SECTION
int asn1_get_sequence_of( unsigned char **p,
const unsigned char *end,
asn1_sequence *cur,
int tag)
{
int ret;
size_t len;
asn1_buf *buf;
/* Get main sequence tag */
if( ( ret = asn1_get_tag( p, end, &len,
ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
return( ret );
if( *p + len != end )
return( POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
while( *p < end )
{
buf = &(cur->buf);
buf->tag = **p;
if( ( ret = asn1_get_tag( p, end, &buf->len, tag ) ) != 0 )
return( ret );
buf->p = *p;
*p += buf->len;
/* Allocate and assign next pointer */
if( *p < end )
{
cur->next = (asn1_sequence *) polarssl_malloc(
sizeof( asn1_sequence ) );
if( cur->next == NULL )
return( POLARSSL_ERR_ASN1_MALLOC_FAILED );
cur = cur->next;
}
}
/* Set final sequence entry's next pointer to NULL */
cur->next = NULL;
if( *p != end )
return( POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
return( 0 );
}
SSL_ROM_TEXT_SECTION
int asn1_get_alg( unsigned char **p,
const unsigned char *end,
asn1_buf *alg, asn1_buf *params )
{
int ret;
size_t len;
if( ( ret = asn1_get_tag( p, end, &len,
ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
return( ret );
if( ( end - *p ) < 1 )
return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
alg->tag = **p;
end = *p + len;
if( ( ret = asn1_get_tag( p, end, &alg->len, ASN1_OID ) ) != 0 )
return( ret );
alg->p = *p;
*p += alg->len;
if( *p == end )
{
memset( params, 0, sizeof(asn1_buf) );
return( 0 );
}
params->tag = **p;
(*p)++;
if( ( ret = asn1_get_len( p, end, &params->len ) ) != 0 )
return( ret );
params->p = *p;
*p += params->len;
if( *p != end )
return( POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
return( 0 );
}
SSL_ROM_TEXT_SECTION
int asn1_get_alg_null( unsigned char **p,
const unsigned char *end,
asn1_buf *alg )
{
int ret;
asn1_buf params;
memset( &params, 0, sizeof(asn1_buf) );
if( ( ret = asn1_get_alg( p, end, alg, &params ) ) != 0 )
return( ret );
if( ( params.tag != ASN1_NULL && params.tag != 0 ) || params.len != 0 )
return( POLARSSL_ERR_ASN1_INVALID_DATA );
return( 0 );
}
SSL_ROM_TEXT_SECTION
void asn1_free_named_data( asn1_named_data *cur )
{
if( cur == NULL )
return;
polarssl_free( cur->oid.p );
polarssl_free( cur->val.p );
memset( cur, 0, sizeof( asn1_named_data ) );
}
SSL_ROM_TEXT_SECTION
void asn1_free_named_data_list( asn1_named_data **head )
{
asn1_named_data *cur;
while( ( cur = *head ) != NULL )
{
*head = cur->next;
asn1_free_named_data( cur );
polarssl_free( cur );
}
}
SSL_ROM_TEXT_SECTION
asn1_named_data *asn1_find_named_data( asn1_named_data *list,
const char *oid, size_t len )
{
while( list != NULL )
{
if( list->oid.len == len &&
memcmp( list->oid.p, oid, len ) == 0 )
{
break;
}
list = list->next;
}
return( list );
}
#endif /* POLARSSL_ASN1_PARSE_C */

View file

@ -1,380 +1,380 @@
/*
* ASN.1 buffer writing functionality
*
* Copyright (C) 2006-2014, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; 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 program is distributed in the hope that it will be useful,
* but 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#if !defined(POLARSSL_CONFIG_FILE)
#include "polarssl/config.h"
#else
#include POLARSSL_CONFIG_FILE
#endif
#if defined(POLARSSL_ASN1_WRITE_C)
#include "polarssl/asn1write.h"
#if defined(POLARSSL_PLATFORM_C)
#include "polarssl/platform.h"
#else
#include <stdlib.h>
#define polarssl_malloc malloc
#define polarssl_free free
#endif
SSL_ROM_TEXT_SECTION
int asn1_write_len( unsigned char **p, unsigned char *start, size_t len )
{
if( len < 0x80 )
{
if( *p - start < 1 )
return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
*--(*p) = (unsigned char) len;
return( 1 );
}
if( len <= 0xFF )
{
if( *p - start < 2 )
return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
*--(*p) = (unsigned char) len;
*--(*p) = 0x81;
return( 2 );
}
if( *p - start < 3 )
return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
// We assume we never have lengths larger than 65535 bytes
//
*--(*p) = len % 256;
*--(*p) = ( len / 256 ) % 256;
*--(*p) = 0x82;
return( 3 );
}
SSL_ROM_TEXT_SECTION
int asn1_write_tag( unsigned char **p, unsigned char *start, unsigned char tag )
{
if( *p - start < 1 )
return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
*--(*p) = tag;
return( 1 );
}
SSL_ROM_TEXT_SECTION
int asn1_write_raw_buffer( unsigned char **p, unsigned char *start,
const unsigned char *buf, size_t size )
{
size_t len = 0;
if( *p - start < (int) size )
return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
len = size;
(*p) -= len;
memcpy( *p, buf, len );
return( (int) len );
}
#if defined(POLARSSL_BIGNUM_C)
SSL_ROM_TEXT_SECTION
int asn1_write_mpi( unsigned char **p, unsigned char *start, mpi *X )
{
int ret;
size_t len = 0;
// Write the MPI
//
len = mpi_size( X );
if( *p - start < (int) len )
return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
(*p) -= len;
MPI_CHK( mpi_write_binary( X, *p, len ) );
// DER format assumes 2s complement for numbers, so the leftmost bit
// should be 0 for positive numbers and 1 for negative numbers.
//
if( X->s ==1 && **p & 0x80 )
{
if( *p - start < 1 )
return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
*--(*p) = 0x00;
len += 1;
}
ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) );
ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_INTEGER ) );
ret = (int) len;
cleanup:
return( ret );
}
#endif /* POLARSSL_BIGNUM_C */
SSL_ROM_TEXT_SECTION
int asn1_write_null( unsigned char **p, unsigned char *start )
{
int ret;
size_t len = 0;
// Write NULL
//
ASN1_CHK_ADD( len, asn1_write_len( p, start, 0) );
ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_NULL ) );
return( (int) len );
}
SSL_ROM_TEXT_SECTION
int asn1_write_oid( unsigned char **p, unsigned char *start,
const char *oid, size_t oid_len )
{
int ret;
size_t len = 0;
ASN1_CHK_ADD( len, asn1_write_raw_buffer( p, start,
(const unsigned char *) oid, oid_len ) );
ASN1_CHK_ADD( len , asn1_write_len( p, start, len ) );
ASN1_CHK_ADD( len , asn1_write_tag( p, start, ASN1_OID ) );
return( (int) len );
}
SSL_ROM_TEXT_SECTION
int asn1_write_algorithm_identifier( unsigned char **p, unsigned char *start,
const char *oid, size_t oid_len,
size_t par_len )
{
int ret;
size_t len = 0;
if( par_len == 0 )
ASN1_CHK_ADD( len, asn1_write_null( p, start ) );
else
len += par_len;
ASN1_CHK_ADD( len, asn1_write_oid( p, start, oid, oid_len ) );
ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) );
ASN1_CHK_ADD( len, asn1_write_tag( p, start,
ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
return( (int) len );
}
SSL_ROM_TEXT_SECTION
int asn1_write_bool( unsigned char **p, unsigned char *start, int boolean )
{
int ret;
size_t len = 0;
if( *p - start < 1 )
return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
*--(*p) = (boolean) ? 1 : 0;
len++;
ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) );
ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_BOOLEAN ) );
return( (int) len );
}
SSL_ROM_TEXT_SECTION
int asn1_write_int( unsigned char **p, unsigned char *start, int val )
{
int ret;
size_t len = 0;
// TODO negative values and values larger than 128
// DER format assumes 2s complement for numbers, so the leftmost bit
// should be 0 for positive numbers and 1 for negative numbers.
//
if( *p - start < 1 )
return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
len += 1;
*--(*p) = val;
if( val > 0 && **p & 0x80 )
{
if( *p - start < 1 )
return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
*--(*p) = 0x00;
len += 1;
}
ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) );
ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_INTEGER ) );
return( (int) len );
}
SSL_ROM_TEXT_SECTION
int asn1_write_printable_string( unsigned char **p, unsigned char *start,
const char *text, size_t text_len )
{
int ret;
size_t len = 0;
ASN1_CHK_ADD( len, asn1_write_raw_buffer( p, start,
(const unsigned char *) text, text_len ) );
ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) );
ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_PRINTABLE_STRING ) );
return( (int) len );
}
SSL_ROM_TEXT_SECTION
int asn1_write_ia5_string( unsigned char **p, unsigned char *start,
const char *text, size_t text_len )
{
int ret;
size_t len = 0;
ASN1_CHK_ADD( len, asn1_write_raw_buffer( p, start,
(const unsigned char *) text, text_len ) );
ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) );
ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_IA5_STRING ) );
return( (int) len );
}
SSL_ROM_TEXT_SECTION
int asn1_write_bitstring( unsigned char **p, unsigned char *start,
const unsigned char *buf, size_t bits )
{
int ret;
size_t len = 0, size;
size = ( bits / 8 ) + ( ( bits % 8 ) ? 1 : 0 );
// Calculate byte length
//
if( *p - start < (int) size + 1 )
return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
len = size + 1;
(*p) -= size;
memcpy( *p, buf, size );
// Write unused bits
//
*--(*p) = (unsigned char) (size * 8 - bits);
ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) );
ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_BIT_STRING ) );
return( (int) len );
}
SSL_ROM_TEXT_SECTION
int asn1_write_octet_string( unsigned char **p, unsigned char *start,
const unsigned char *buf, size_t size )
{
int ret;
size_t len = 0;
ASN1_CHK_ADD( len, asn1_write_raw_buffer( p, start, buf, size ) );
ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) );
ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_OCTET_STRING ) );
return( (int) len );
}
SSL_ROM_TEXT_SECTION
asn1_named_data *asn1_store_named_data( asn1_named_data **head,
const char *oid, size_t oid_len,
const unsigned char *val,
size_t val_len )
{
asn1_named_data *cur;
if( ( cur = asn1_find_named_data( *head, oid, oid_len ) ) == NULL )
{
// Add new entry if not present yet based on OID
//
if( ( cur = polarssl_malloc( sizeof(asn1_named_data) ) ) == NULL )
return( NULL );
memset( cur, 0, sizeof(asn1_named_data) );
cur->oid.len = oid_len;
cur->oid.p = polarssl_malloc( oid_len );
if( cur->oid.p == NULL )
{
polarssl_free( cur );
return( NULL );
}
cur->val.len = val_len;
cur->val.p = polarssl_malloc( val_len );
if( cur->val.p == NULL )
{
polarssl_free( cur->oid.p );
polarssl_free( cur );
return( NULL );
}
memcpy( cur->oid.p, oid, oid_len );
cur->next = *head;
*head = cur;
}
else if( cur->val.len < val_len )
{
// Enlarge existing value buffer if needed
//
polarssl_free( cur->val.p );
cur->val.p = NULL;
cur->val.len = val_len;
cur->val.p = polarssl_malloc( val_len );
if( cur->val.p == NULL )
{
polarssl_free( cur->oid.p );
polarssl_free( cur );
return( NULL );
}
}
if( val != NULL )
memcpy( cur->val.p, val, val_len );
return( cur );
}
#endif /* POLARSSL_ASN1_WRITE_C */
/*
* ASN.1 buffer writing functionality
*
* Copyright (C) 2006-2014, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; 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 program is distributed in the hope that it will be useful,
* but 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#if !defined(POLARSSL_CONFIG_FILE)
#include "polarssl/config.h"
#else
#include POLARSSL_CONFIG_FILE
#endif
#if defined(POLARSSL_ASN1_WRITE_C)
#include "polarssl/asn1write.h"
#if defined(POLARSSL_PLATFORM_C)
#include "polarssl/platform.h"
#else
#include <stdlib.h>
#define polarssl_malloc malloc
#define polarssl_free free
#endif
SSL_ROM_TEXT_SECTION
int asn1_write_len( unsigned char **p, unsigned char *start, size_t len )
{
if( len < 0x80 )
{
if( *p - start < 1 )
return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
*--(*p) = (unsigned char) len;
return( 1 );
}
if( len <= 0xFF )
{
if( *p - start < 2 )
return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
*--(*p) = (unsigned char) len;
*--(*p) = 0x81;
return( 2 );
}
if( *p - start < 3 )
return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
// We assume we never have lengths larger than 65535 bytes
//
*--(*p) = len % 256;
*--(*p) = ( len / 256 ) % 256;
*--(*p) = 0x82;
return( 3 );
}
SSL_ROM_TEXT_SECTION
int asn1_write_tag( unsigned char **p, unsigned char *start, unsigned char tag )
{
if( *p - start < 1 )
return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
*--(*p) = tag;
return( 1 );
}
SSL_ROM_TEXT_SECTION
int asn1_write_raw_buffer( unsigned char **p, unsigned char *start,
const unsigned char *buf, size_t size )
{
size_t len = 0;
if( *p - start < (int) size )
return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
len = size;
(*p) -= len;
memcpy( *p, buf, len );
return( (int) len );
}
#if defined(POLARSSL_BIGNUM_C)
SSL_ROM_TEXT_SECTION
int asn1_write_mpi( unsigned char **p, unsigned char *start, mpi *X )
{
int ret;
size_t len = 0;
// Write the MPI
//
len = mpi_size( X );
if( *p - start < (int) len )
return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
(*p) -= len;
MPI_CHK( mpi_write_binary( X, *p, len ) );
// DER format assumes 2s complement for numbers, so the leftmost bit
// should be 0 for positive numbers and 1 for negative numbers.
//
if( X->s ==1 && **p & 0x80 )
{
if( *p - start < 1 )
return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
*--(*p) = 0x00;
len += 1;
}
ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) );
ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_INTEGER ) );
ret = (int) len;
cleanup:
return( ret );
}
#endif /* POLARSSL_BIGNUM_C */
SSL_ROM_TEXT_SECTION
int asn1_write_null( unsigned char **p, unsigned char *start )
{
int ret;
size_t len = 0;
// Write NULL
//
ASN1_CHK_ADD( len, asn1_write_len( p, start, 0) );
ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_NULL ) );
return( (int) len );
}
SSL_ROM_TEXT_SECTION
int asn1_write_oid( unsigned char **p, unsigned char *start,
const char *oid, size_t oid_len )
{
int ret;
size_t len = 0;
ASN1_CHK_ADD( len, asn1_write_raw_buffer( p, start,
(const unsigned char *) oid, oid_len ) );
ASN1_CHK_ADD( len , asn1_write_len( p, start, len ) );
ASN1_CHK_ADD( len , asn1_write_tag( p, start, ASN1_OID ) );
return( (int) len );
}
SSL_ROM_TEXT_SECTION
int asn1_write_algorithm_identifier( unsigned char **p, unsigned char *start,
const char *oid, size_t oid_len,
size_t par_len )
{
int ret;
size_t len = 0;
if( par_len == 0 )
ASN1_CHK_ADD( len, asn1_write_null( p, start ) );
else
len += par_len;
ASN1_CHK_ADD( len, asn1_write_oid( p, start, oid, oid_len ) );
ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) );
ASN1_CHK_ADD( len, asn1_write_tag( p, start,
ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
return( (int) len );
}
SSL_ROM_TEXT_SECTION
int asn1_write_bool( unsigned char **p, unsigned char *start, int boolean )
{
int ret;
size_t len = 0;
if( *p - start < 1 )
return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
*--(*p) = (boolean) ? 1 : 0;
len++;
ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) );
ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_BOOLEAN ) );
return( (int) len );
}
SSL_ROM_TEXT_SECTION
int asn1_write_int( unsigned char **p, unsigned char *start, int val )
{
int ret;
size_t len = 0;
// TODO negative values and values larger than 128
// DER format assumes 2s complement for numbers, so the leftmost bit
// should be 0 for positive numbers and 1 for negative numbers.
//
if( *p - start < 1 )
return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
len += 1;
*--(*p) = val;
if( val > 0 && **p & 0x80 )
{
if( *p - start < 1 )
return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
*--(*p) = 0x00;
len += 1;
}
ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) );
ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_INTEGER ) );
return( (int) len );
}
SSL_ROM_TEXT_SECTION
int asn1_write_printable_string( unsigned char **p, unsigned char *start,
const char *text, size_t text_len )
{
int ret;
size_t len = 0;
ASN1_CHK_ADD( len, asn1_write_raw_buffer( p, start,
(const unsigned char *) text, text_len ) );
ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) );
ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_PRINTABLE_STRING ) );
return( (int) len );
}
SSL_ROM_TEXT_SECTION
int asn1_write_ia5_string( unsigned char **p, unsigned char *start,
const char *text, size_t text_len )
{
int ret;
size_t len = 0;
ASN1_CHK_ADD( len, asn1_write_raw_buffer( p, start,
(const unsigned char *) text, text_len ) );
ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) );
ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_IA5_STRING ) );
return( (int) len );
}
SSL_ROM_TEXT_SECTION
int asn1_write_bitstring( unsigned char **p, unsigned char *start,
const unsigned char *buf, size_t bits )
{
int ret;
size_t len = 0, size;
size = ( bits / 8 ) + ( ( bits % 8 ) ? 1 : 0 );
// Calculate byte length
//
if( *p - start < (int) size + 1 )
return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
len = size + 1;
(*p) -= size;
memcpy( *p, buf, size );
// Write unused bits
//
*--(*p) = (unsigned char) (size * 8 - bits);
ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) );
ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_BIT_STRING ) );
return( (int) len );
}
SSL_ROM_TEXT_SECTION
int asn1_write_octet_string( unsigned char **p, unsigned char *start,
const unsigned char *buf, size_t size )
{
int ret;
size_t len = 0;
ASN1_CHK_ADD( len, asn1_write_raw_buffer( p, start, buf, size ) );
ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) );
ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_OCTET_STRING ) );
return( (int) len );
}
SSL_ROM_TEXT_SECTION
asn1_named_data *asn1_store_named_data( asn1_named_data **head,
const char *oid, size_t oid_len,
const unsigned char *val,
size_t val_len )
{
asn1_named_data *cur;
if( ( cur = asn1_find_named_data( *head, oid, oid_len ) ) == NULL )
{
// Add new entry if not present yet based on OID
//
if( ( cur = polarssl_malloc( sizeof(asn1_named_data) ) ) == NULL )
return( NULL );
memset( cur, 0, sizeof(asn1_named_data) );
cur->oid.len = oid_len;
cur->oid.p = polarssl_malloc( oid_len );
if( cur->oid.p == NULL )
{
polarssl_free( cur );
return( NULL );
}
cur->val.len = val_len;
cur->val.p = polarssl_malloc( val_len );
if( cur->val.p == NULL )
{
polarssl_free( cur->oid.p );
polarssl_free( cur );
return( NULL );
}
memcpy( cur->oid.p, oid, oid_len );
cur->next = *head;
*head = cur;
}
else if( cur->val.len < val_len )
{
// Enlarge existing value buffer if needed
//
polarssl_free( cur->val.p );
cur->val.p = NULL;
cur->val.len = val_len;
cur->val.p = polarssl_malloc( val_len );
if( cur->val.p == NULL )
{
polarssl_free( cur->oid.p );
polarssl_free( cur );
return( NULL );
}
}
if( val != NULL )
memcpy( cur->val.p, val, val_len );
return( cur );
}
#endif /* POLARSSL_ASN1_WRITE_C */

View file

@ -1,277 +1,277 @@
/*
* RFC 1521 base64 encoding/decoding
*
* Copyright (C) 2006-2014, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; 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 program is distributed in the hope that it will be useful,
* but 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#if !defined(POLARSSL_CONFIG_FILE)
#include "polarssl/config.h"
#else
#include POLARSSL_CONFIG_FILE
#endif
#if defined(POLARSSL_BASE64_C)
#include "polarssl/base64.h"
#if defined(_MSC_VER) && !defined(EFIX64) && !defined(EFI32)
#include <basetsd.h>
typedef UINT32 uint32_t;
#else
#include <inttypes.h>
#endif
#if defined(POLARSSL_PLATFORM_C)
#include "polarssl/platform.h"
#else
#define polarssl_printf printf
#endif
SSL_ROM_DATA_SECTION
static const unsigned char base64_enc_map[64] =
{
'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', '+', '/'
};
SSL_ROM_DATA_SECTION
static const unsigned char base64_dec_map[128] =
{
127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
127, 127, 127, 62, 127, 127, 127, 63, 52, 53,
54, 55, 56, 57, 58, 59, 60, 61, 127, 127,
127, 64, 127, 127, 127, 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, 127, 127, 127, 127, 127, 127, 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, 127, 127, 127, 127, 127
};
/*
* Encode a buffer into base64 format
*/
SSL_ROM_TEXT_SECTION
int base64_encode( unsigned char *dst, size_t *dlen,
const unsigned char *src, size_t slen )
{
size_t i, n;
int C1, C2, C3;
unsigned char *p;
if( slen == 0 )
return( 0 );
n = ( slen << 3 ) / 6;
switch( ( slen << 3 ) - ( n * 6 ) )
{
case 2: n += 3; break;
case 4: n += 2; break;
default: break;
}
if( *dlen < n + 1 )
{
*dlen = n + 1;
return( POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL );
}
n = ( slen / 3 ) * 3;
for( i = 0, p = dst; i < n; i += 3 )
{
C1 = *src++;
C2 = *src++;
C3 = *src++;
*p++ = base64_enc_map[(C1 >> 2) & 0x3F];
*p++ = base64_enc_map[(((C1 & 3) << 4) + (C2 >> 4)) & 0x3F];
*p++ = base64_enc_map[(((C2 & 15) << 2) + (C3 >> 6)) & 0x3F];
*p++ = base64_enc_map[C3 & 0x3F];
}
if( i < slen )
{
C1 = *src++;
C2 = ( ( i + 1 ) < slen ) ? *src++ : 0;
*p++ = base64_enc_map[(C1 >> 2) & 0x3F];
*p++ = base64_enc_map[(((C1 & 3) << 4) + (C2 >> 4)) & 0x3F];
if( ( i + 1 ) < slen )
*p++ = base64_enc_map[((C2 & 15) << 2) & 0x3F];
else *p++ = '=';
*p++ = '=';
}
*dlen = p - dst;
*p = 0;
return( 0 );
}
/*
* Decode a base64-formatted buffer
*/
SSL_ROM_TEXT_SECTION
int base64_decode( unsigned char *dst, size_t *dlen,
const unsigned char *src, size_t slen )
{
size_t i, n;
uint32_t j, x;
unsigned char *p;
for( i = n = j = 0; i < slen; i++ )
{
if( ( slen - i ) >= 2 &&
src[i] == '\r' && src[i + 1] == '\n' )
continue;
if( src[i] == '\n' )
continue;
if( src[i] == '=' && ++j > 2 )
return( POLARSSL_ERR_BASE64_INVALID_CHARACTER );
if( src[i] > 127 || base64_dec_map[src[i]] == 127 )
return( POLARSSL_ERR_BASE64_INVALID_CHARACTER );
if( base64_dec_map[src[i]] < 64 && j != 0 )
return( POLARSSL_ERR_BASE64_INVALID_CHARACTER );
n++;
}
if( n == 0 )
return( 0 );
n = ( ( n * 6 ) + 7 ) >> 3;
n -= j;
if( dst == NULL || *dlen < n )
{
*dlen = n;
return( POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL );
}
for( j = 3, n = x = 0, p = dst; i > 0; i--, src++ )
{
if( *src == '\r' || *src == '\n' )
continue;
j -= ( base64_dec_map[*src] == 64 );
x = ( x << 6 ) | ( base64_dec_map[*src] & 0x3F );
if( ++n == 4 )
{
n = 0;
if( j > 0 ) *p++ = (unsigned char)( x >> 16 );
if( j > 1 ) *p++ = (unsigned char)( x >> 8 );
if( j > 2 ) *p++ = (unsigned char)( x );
}
}
*dlen = p - dst;
return( 0 );
}
#if defined(POLARSSL_SELF_TEST)
#include <string.h>
#include <stdio.h>
static const unsigned char base64_test_dec[64] =
{
0x24, 0x48, 0x6E, 0x56, 0x87, 0x62, 0x5A, 0xBD,
0xBF, 0x17, 0xD9, 0xA2, 0xC4, 0x17, 0x1A, 0x01,
0x94, 0xED, 0x8F, 0x1E, 0x11, 0xB3, 0xD7, 0x09,
0x0C, 0xB6, 0xE9, 0x10, 0x6F, 0x22, 0xEE, 0x13,
0xCA, 0xB3, 0x07, 0x05, 0x76, 0xC9, 0xFA, 0x31,
0x6C, 0x08, 0x34, 0xFF, 0x8D, 0xC2, 0x6C, 0x38,
0x00, 0x43, 0xE9, 0x54, 0x97, 0xAF, 0x50, 0x4B,
0xD1, 0x41, 0xBA, 0x95, 0x31, 0x5A, 0x0B, 0x97
};
static const unsigned char base64_test_enc[] =
"JEhuVodiWr2/F9mixBcaAZTtjx4Rs9cJDLbpEG8i7hPK"
"swcFdsn6MWwINP+Nwmw4AEPpVJevUEvRQbqVMVoLlw==";
/*
* Checkup routine
*/
int base64_self_test( int verbose )
{
size_t len;
const unsigned char *src;
unsigned char buffer[128];
if( verbose != 0 )
polarssl_printf( " Base64 encoding test: " );
len = sizeof( buffer );
src = base64_test_dec;
if( base64_encode( buffer, &len, src, 64 ) != 0 ||
memcmp( base64_test_enc, buffer, 88 ) != 0 )
{
if( verbose != 0 )
polarssl_printf( "failed\n" );
return( 1 );
}
if( verbose != 0 )
polarssl_printf( "passed\n Base64 decoding test: " );
len = sizeof( buffer );
src = base64_test_enc;
if( base64_decode( buffer, &len, src, 88 ) != 0 ||
memcmp( base64_test_dec, buffer, 64 ) != 0 )
{
if( verbose != 0 )
polarssl_printf( "failed\n" );
return( 1 );
}
if( verbose != 0 )
polarssl_printf( "passed\n\n" );
return( 0 );
}
#endif /* POLARSSL_SELF_TEST */
#endif /* POLARSSL_BASE64_C */
/*
* RFC 1521 base64 encoding/decoding
*
* Copyright (C) 2006-2014, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; 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 program is distributed in the hope that it will be useful,
* but 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#if !defined(POLARSSL_CONFIG_FILE)
#include "polarssl/config.h"
#else
#include POLARSSL_CONFIG_FILE
#endif
#if defined(POLARSSL_BASE64_C)
#include "polarssl/base64.h"
#if defined(_MSC_VER) && !defined(EFIX64) && !defined(EFI32)
#include <basetsd.h>
typedef UINT32 uint32_t;
#else
#include <inttypes.h>
#endif
#if defined(POLARSSL_PLATFORM_C)
#include "polarssl/platform.h"
#else
#define polarssl_printf printf
#endif
SSL_ROM_DATA_SECTION
static const unsigned char base64_enc_map[64] =
{
'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', '+', '/'
};
SSL_ROM_DATA_SECTION
static const unsigned char base64_dec_map[128] =
{
127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
127, 127, 127, 62, 127, 127, 127, 63, 52, 53,
54, 55, 56, 57, 58, 59, 60, 61, 127, 127,
127, 64, 127, 127, 127, 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, 127, 127, 127, 127, 127, 127, 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, 127, 127, 127, 127, 127
};
/*
* Encode a buffer into base64 format
*/
SSL_ROM_TEXT_SECTION
int base64_encode( unsigned char *dst, size_t *dlen,
const unsigned char *src, size_t slen )
{
size_t i, n;
int C1, C2, C3;
unsigned char *p;
if( slen == 0 )
return( 0 );
n = ( slen << 3 ) / 6;
switch( ( slen << 3 ) - ( n * 6 ) )
{
case 2: n += 3; break;
case 4: n += 2; break;
default: break;
}
if( *dlen < n + 1 )
{
*dlen = n + 1;
return( POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL );
}
n = ( slen / 3 ) * 3;
for( i = 0, p = dst; i < n; i += 3 )
{
C1 = *src++;
C2 = *src++;
C3 = *src++;
*p++ = base64_enc_map[(C1 >> 2) & 0x3F];
*p++ = base64_enc_map[(((C1 & 3) << 4) + (C2 >> 4)) & 0x3F];
*p++ = base64_enc_map[(((C2 & 15) << 2) + (C3 >> 6)) & 0x3F];
*p++ = base64_enc_map[C3 & 0x3F];
}
if( i < slen )
{
C1 = *src++;
C2 = ( ( i + 1 ) < slen ) ? *src++ : 0;
*p++ = base64_enc_map[(C1 >> 2) & 0x3F];
*p++ = base64_enc_map[(((C1 & 3) << 4) + (C2 >> 4)) & 0x3F];
if( ( i + 1 ) < slen )
*p++ = base64_enc_map[((C2 & 15) << 2) & 0x3F];
else *p++ = '=';
*p++ = '=';
}
*dlen = p - dst;
*p = 0;
return( 0 );
}
/*
* Decode a base64-formatted buffer
*/
SSL_ROM_TEXT_SECTION
int base64_decode( unsigned char *dst, size_t *dlen,
const unsigned char *src, size_t slen )
{
size_t i, n;
uint32_t j, x;
unsigned char *p;
for( i = n = j = 0; i < slen; i++ )
{
if( ( slen - i ) >= 2 &&
src[i] == '\r' && src[i + 1] == '\n' )
continue;
if( src[i] == '\n' )
continue;
if( src[i] == '=' && ++j > 2 )
return( POLARSSL_ERR_BASE64_INVALID_CHARACTER );
if( src[i] > 127 || base64_dec_map[src[i]] == 127 )
return( POLARSSL_ERR_BASE64_INVALID_CHARACTER );
if( base64_dec_map[src[i]] < 64 && j != 0 )
return( POLARSSL_ERR_BASE64_INVALID_CHARACTER );
n++;
}
if( n == 0 )
return( 0 );
n = ( ( n * 6 ) + 7 ) >> 3;
n -= j;
if( dst == NULL || *dlen < n )
{
*dlen = n;
return( POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL );
}
for( j = 3, n = x = 0, p = dst; i > 0; i--, src++ )
{
if( *src == '\r' || *src == '\n' )
continue;
j -= ( base64_dec_map[*src] == 64 );
x = ( x << 6 ) | ( base64_dec_map[*src] & 0x3F );
if( ++n == 4 )
{
n = 0;
if( j > 0 ) *p++ = (unsigned char)( x >> 16 );
if( j > 1 ) *p++ = (unsigned char)( x >> 8 );
if( j > 2 ) *p++ = (unsigned char)( x );
}
}
*dlen = p - dst;
return( 0 );
}
#if defined(POLARSSL_SELF_TEST)
#include <string.h>
#include <stdio.h>
static const unsigned char base64_test_dec[64] =
{
0x24, 0x48, 0x6E, 0x56, 0x87, 0x62, 0x5A, 0xBD,
0xBF, 0x17, 0xD9, 0xA2, 0xC4, 0x17, 0x1A, 0x01,
0x94, 0xED, 0x8F, 0x1E, 0x11, 0xB3, 0xD7, 0x09,
0x0C, 0xB6, 0xE9, 0x10, 0x6F, 0x22, 0xEE, 0x13,
0xCA, 0xB3, 0x07, 0x05, 0x76, 0xC9, 0xFA, 0x31,
0x6C, 0x08, 0x34, 0xFF, 0x8D, 0xC2, 0x6C, 0x38,
0x00, 0x43, 0xE9, 0x54, 0x97, 0xAF, 0x50, 0x4B,
0xD1, 0x41, 0xBA, 0x95, 0x31, 0x5A, 0x0B, 0x97
};
static const unsigned char base64_test_enc[] =
"JEhuVodiWr2/F9mixBcaAZTtjx4Rs9cJDLbpEG8i7hPK"
"swcFdsn6MWwINP+Nwmw4AEPpVJevUEvRQbqVMVoLlw==";
/*
* Checkup routine
*/
int base64_self_test( int verbose )
{
size_t len;
const unsigned char *src;
unsigned char buffer[128];
if( verbose != 0 )
polarssl_printf( " Base64 encoding test: " );
len = sizeof( buffer );
src = base64_test_dec;
if( base64_encode( buffer, &len, src, 64 ) != 0 ||
memcmp( base64_test_enc, buffer, 88 ) != 0 )
{
if( verbose != 0 )
polarssl_printf( "failed\n" );
return( 1 );
}
if( verbose != 0 )
polarssl_printf( "passed\n Base64 decoding test: " );
len = sizeof( buffer );
src = base64_test_enc;
if( base64_decode( buffer, &len, src, 88 ) != 0 ||
memcmp( base64_test_dec, buffer, 64 ) != 0 )
{
if( verbose != 0 )
polarssl_printf( "failed\n" );
return( 1 );
}
if( verbose != 0 )
polarssl_printf( "passed\n\n" );
return( 0 );
}
#endif /* POLARSSL_SELF_TEST */
#endif /* POLARSSL_BASE64_C */

File diff suppressed because it is too large Load diff

View file

@ -1,290 +1,290 @@
/*
* Elliptic curve Diffie-Hellman
*
* Copyright (C) 2006-2014, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; 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 program is distributed in the hope that it will be useful,
* but 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/*
* References:
*
* SEC1 http://www.secg.org/index.php?action=secg,docs_secg
* RFC 4492
*/
#if !defined(POLARSSL_CONFIG_FILE)
#include "polarssl/config.h"
#else
#include POLARSSL_CONFIG_FILE
#endif
#if defined(POLARSSL_ECDH_C)
#include "polarssl/ecdh.h"
/*
* Generate public key: simple wrapper around ecp_gen_keypair
*/
SSL_ROM_TEXT_SECTION
int ecdh_gen_public( ecp_group *grp, mpi *d, ecp_point *Q,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng )
{
return ecp_gen_keypair( grp, d, Q, f_rng, p_rng );
}
/*
* Compute shared secret (SEC1 3.3.1)
*/
SSL_ROM_TEXT_SECTION
int ecdh_compute_shared( ecp_group *grp, mpi *z,
const ecp_point *Q, const mpi *d,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng )
{
int ret;
ecp_point P;
ecp_point_init( &P );
/*
* Make sure Q is a valid pubkey before using it
*/
MPI_CHK( ecp_check_pubkey( grp, Q ) );
MPI_CHK( ecp_mul( grp, &P, d, Q, f_rng, p_rng ) );
if( ecp_is_zero( &P ) )
{
ret = POLARSSL_ERR_ECP_BAD_INPUT_DATA;
goto cleanup;
}
MPI_CHK( mpi_copy( z, &P.X ) );
cleanup:
ecp_point_free( &P );
return( ret );
}
/*
* Initialize context
*/
SSL_ROM_TEXT_SECTION
void ecdh_init( ecdh_context *ctx )
{
memset( ctx, 0, sizeof( ecdh_context ) );
}
/*
* Free context
*/
SSL_ROM_TEXT_SECTION
void ecdh_free( ecdh_context *ctx )
{
if( ctx == NULL )
return;
ecp_group_free( &ctx->grp );
ecp_point_free( &ctx->Q );
ecp_point_free( &ctx->Qp );
ecp_point_free( &ctx->Vi );
ecp_point_free( &ctx->Vf );
mpi_free( &ctx->d );
mpi_free( &ctx->z );
mpi_free( &ctx->_d );
}
/*
* Setup and write the ServerKeyExhange parameters (RFC 4492)
* struct {
* ECParameters curve_params;
* ECPoint public;
* } ServerECDHParams;
*/
SSL_ROM_TEXT_SECTION
int ecdh_make_params( ecdh_context *ctx, size_t *olen,
unsigned char *buf, size_t blen,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng )
{
int ret;
size_t grp_len, pt_len;
if( ctx == NULL || ctx->grp.pbits == 0 )
return( POLARSSL_ERR_ECP_BAD_INPUT_DATA );
if( ( ret = ecdh_gen_public( &ctx->grp, &ctx->d, &ctx->Q, f_rng, p_rng ) )
!= 0 )
return( ret );
if( ( ret = ecp_tls_write_group( &ctx->grp, &grp_len, buf, blen ) )
!= 0 )
return( ret );
buf += grp_len;
blen -= grp_len;
if( ( ret = ecp_tls_write_point( &ctx->grp, &ctx->Q, ctx->point_format,
&pt_len, buf, blen ) ) != 0 )
return( ret );
*olen = grp_len + pt_len;
return( 0 );
}
/*
* Read the ServerKeyExhange parameters (RFC 4492)
* struct {
* ECParameters curve_params;
* ECPoint public;
* } ServerECDHParams;
*/
SSL_ROM_TEXT_SECTION
int ecdh_read_params( ecdh_context *ctx,
const unsigned char **buf, const unsigned char *end )
{
int ret;
if( ( ret = ecp_tls_read_group( &ctx->grp, buf, end - *buf ) ) != 0 )
return( ret );
if( ( ret = ecp_tls_read_point( &ctx->grp, &ctx->Qp, buf, end - *buf ) )
!= 0 )
return( ret );
return( 0 );
}
/*
* Get parameters from a keypair
*/
SSL_ROM_TEXT_SECTION
int ecdh_get_params( ecdh_context *ctx, const ecp_keypair *key,
ecdh_side side )
{
int ret;
if( ( ret = ecp_group_copy( &ctx->grp, &key->grp ) ) != 0 )
return( ret );
/* If it's not our key, just import the public part as Qp */
if( side == POLARSSL_ECDH_THEIRS )
return( ecp_copy( &ctx->Qp, &key->Q ) );
/* Our key: import public (as Q) and private parts */
if( side != POLARSSL_ECDH_OURS )
return( POLARSSL_ERR_ECP_BAD_INPUT_DATA );
if( ( ret = ecp_copy( &ctx->Q, &key->Q ) ) != 0 ||
( ret = mpi_copy( &ctx->d, &key->d ) ) != 0 )
return( ret );
return( 0 );
}
/*
* Setup and export the client public value
*/
SSL_ROM_TEXT_SECTION
int ecdh_make_public( ecdh_context *ctx, size_t *olen,
unsigned char *buf, size_t blen,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng )
{
int ret;
if( ctx == NULL || ctx->grp.pbits == 0 )
return( POLARSSL_ERR_ECP_BAD_INPUT_DATA );
if( ( ret = ecdh_gen_public( &ctx->grp, &ctx->d, &ctx->Q, f_rng, p_rng ) )
!= 0 )
return( ret );
return ecp_tls_write_point( &ctx->grp, &ctx->Q, ctx->point_format,
olen, buf, blen );
}
/*
* Parse and import the client's public value
*/
SSL_ROM_TEXT_SECTION
int ecdh_read_public( ecdh_context *ctx,
const unsigned char *buf, size_t blen )
{
int ret;
const unsigned char *p = buf;
if( ctx == NULL )
return( POLARSSL_ERR_ECP_BAD_INPUT_DATA );
if( ( ret = ecp_tls_read_point( &ctx->grp, &ctx->Qp, &p, blen ) ) != 0 )
return( ret );
if( (size_t)( p - buf ) != blen )
return( POLARSSL_ERR_ECP_BAD_INPUT_DATA );
return( 0 );
}
/*
* Derive and export the shared secret
*/
SSL_ROM_TEXT_SECTION
int ecdh_calc_secret( ecdh_context *ctx, size_t *olen,
unsigned char *buf, size_t blen,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng )
{
int ret;
if( ctx == NULL )
return( POLARSSL_ERR_ECP_BAD_INPUT_DATA );
if( ( ret = ecdh_compute_shared( &ctx->grp, &ctx->z, &ctx->Qp, &ctx->d,
f_rng, p_rng ) ) != 0 )
{
return( ret );
}
if( mpi_size( &ctx->z ) > blen )
return( POLARSSL_ERR_ECP_BAD_INPUT_DATA );
*olen = ctx->grp.pbits / 8 + ( ( ctx->grp.pbits % 8 ) != 0 );
return mpi_write_binary( &ctx->z, buf, *olen );
}
#if defined(POLARSSL_SELF_TEST)
/*
* Checkup routine
*/
int ecdh_self_test( int verbose )
{
((void) verbose );
return( 0 );
}
#endif /* POLARSSL_SELF_TEST */
#endif /* POLARSSL_ECDH_C */
/*
* Elliptic curve Diffie-Hellman
*
* Copyright (C) 2006-2014, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; 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 program is distributed in the hope that it will be useful,
* but 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/*
* References:
*
* SEC1 http://www.secg.org/index.php?action=secg,docs_secg
* RFC 4492
*/
#if !defined(POLARSSL_CONFIG_FILE)
#include "polarssl/config.h"
#else
#include POLARSSL_CONFIG_FILE
#endif
#if defined(POLARSSL_ECDH_C)
#include "polarssl/ecdh.h"
/*
* Generate public key: simple wrapper around ecp_gen_keypair
*/
SSL_ROM_TEXT_SECTION
int ecdh_gen_public( ecp_group *grp, mpi *d, ecp_point *Q,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng )
{
return ecp_gen_keypair( grp, d, Q, f_rng, p_rng );
}
/*
* Compute shared secret (SEC1 3.3.1)
*/
SSL_ROM_TEXT_SECTION
int ecdh_compute_shared( ecp_group *grp, mpi *z,
const ecp_point *Q, const mpi *d,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng )
{
int ret;
ecp_point P;
ecp_point_init( &P );
/*
* Make sure Q is a valid pubkey before using it
*/
MPI_CHK( ecp_check_pubkey( grp, Q ) );
MPI_CHK( ecp_mul( grp, &P, d, Q, f_rng, p_rng ) );
if( ecp_is_zero( &P ) )
{
ret = POLARSSL_ERR_ECP_BAD_INPUT_DATA;
goto cleanup;
}
MPI_CHK( mpi_copy( z, &P.X ) );
cleanup:
ecp_point_free( &P );
return( ret );
}
/*
* Initialize context
*/
SSL_ROM_TEXT_SECTION
void ecdh_init( ecdh_context *ctx )
{
memset( ctx, 0, sizeof( ecdh_context ) );
}
/*
* Free context
*/
SSL_ROM_TEXT_SECTION
void ecdh_free( ecdh_context *ctx )
{
if( ctx == NULL )
return;
ecp_group_free( &ctx->grp );
ecp_point_free( &ctx->Q );
ecp_point_free( &ctx->Qp );
ecp_point_free( &ctx->Vi );
ecp_point_free( &ctx->Vf );
mpi_free( &ctx->d );
mpi_free( &ctx->z );
mpi_free( &ctx->_d );
}
/*
* Setup and write the ServerKeyExhange parameters (RFC 4492)
* struct {
* ECParameters curve_params;
* ECPoint public;
* } ServerECDHParams;
*/
SSL_ROM_TEXT_SECTION
int ecdh_make_params( ecdh_context *ctx, size_t *olen,
unsigned char *buf, size_t blen,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng )
{
int ret;
size_t grp_len, pt_len;
if( ctx == NULL || ctx->grp.pbits == 0 )
return( POLARSSL_ERR_ECP_BAD_INPUT_DATA );
if( ( ret = ecdh_gen_public( &ctx->grp, &ctx->d, &ctx->Q, f_rng, p_rng ) )
!= 0 )
return( ret );
if( ( ret = ecp_tls_write_group( &ctx->grp, &grp_len, buf, blen ) )
!= 0 )
return( ret );
buf += grp_len;
blen -= grp_len;
if( ( ret = ecp_tls_write_point( &ctx->grp, &ctx->Q, ctx->point_format,
&pt_len, buf, blen ) ) != 0 )
return( ret );
*olen = grp_len + pt_len;
return( 0 );
}
/*
* Read the ServerKeyExhange parameters (RFC 4492)
* struct {
* ECParameters curve_params;
* ECPoint public;
* } ServerECDHParams;
*/
SSL_ROM_TEXT_SECTION
int ecdh_read_params( ecdh_context *ctx,
const unsigned char **buf, const unsigned char *end )
{
int ret;
if( ( ret = ecp_tls_read_group( &ctx->grp, buf, end - *buf ) ) != 0 )
return( ret );
if( ( ret = ecp_tls_read_point( &ctx->grp, &ctx->Qp, buf, end - *buf ) )
!= 0 )
return( ret );
return( 0 );
}
/*
* Get parameters from a keypair
*/
SSL_ROM_TEXT_SECTION
int ecdh_get_params( ecdh_context *ctx, const ecp_keypair *key,
ecdh_side side )
{
int ret;
if( ( ret = ecp_group_copy( &ctx->grp, &key->grp ) ) != 0 )
return( ret );
/* If it's not our key, just import the public part as Qp */
if( side == POLARSSL_ECDH_THEIRS )
return( ecp_copy( &ctx->Qp, &key->Q ) );
/* Our key: import public (as Q) and private parts */
if( side != POLARSSL_ECDH_OURS )
return( POLARSSL_ERR_ECP_BAD_INPUT_DATA );
if( ( ret = ecp_copy( &ctx->Q, &key->Q ) ) != 0 ||
( ret = mpi_copy( &ctx->d, &key->d ) ) != 0 )
return( ret );
return( 0 );
}
/*
* Setup and export the client public value
*/
SSL_ROM_TEXT_SECTION
int ecdh_make_public( ecdh_context *ctx, size_t *olen,
unsigned char *buf, size_t blen,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng )
{
int ret;
if( ctx == NULL || ctx->grp.pbits == 0 )
return( POLARSSL_ERR_ECP_BAD_INPUT_DATA );
if( ( ret = ecdh_gen_public( &ctx->grp, &ctx->d, &ctx->Q, f_rng, p_rng ) )
!= 0 )
return( ret );
return ecp_tls_write_point( &ctx->grp, &ctx->Q, ctx->point_format,
olen, buf, blen );
}
/*
* Parse and import the client's public value
*/
SSL_ROM_TEXT_SECTION
int ecdh_read_public( ecdh_context *ctx,
const unsigned char *buf, size_t blen )
{
int ret;
const unsigned char *p = buf;
if( ctx == NULL )
return( POLARSSL_ERR_ECP_BAD_INPUT_DATA );
if( ( ret = ecp_tls_read_point( &ctx->grp, &ctx->Qp, &p, blen ) ) != 0 )
return( ret );
if( (size_t)( p - buf ) != blen )
return( POLARSSL_ERR_ECP_BAD_INPUT_DATA );
return( 0 );
}
/*
* Derive and export the shared secret
*/
SSL_ROM_TEXT_SECTION
int ecdh_calc_secret( ecdh_context *ctx, size_t *olen,
unsigned char *buf, size_t blen,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng )
{
int ret;
if( ctx == NULL )
return( POLARSSL_ERR_ECP_BAD_INPUT_DATA );
if( ( ret = ecdh_compute_shared( &ctx->grp, &ctx->z, &ctx->Qp, &ctx->d,
f_rng, p_rng ) ) != 0 )
{
return( ret );
}
if( mpi_size( &ctx->z ) > blen )
return( POLARSSL_ERR_ECP_BAD_INPUT_DATA );
*olen = ctx->grp.pbits / 8 + ( ( ctx->grp.pbits % 8 ) != 0 );
return mpi_write_binary( &ctx->z, buf, *olen );
}
#if defined(POLARSSL_SELF_TEST)
/*
* Checkup routine
*/
int ecdh_self_test( int verbose )
{
((void) verbose );
return( 0 );
}
#endif /* POLARSSL_SELF_TEST */
#endif /* POLARSSL_ECDH_C */

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,361 +1,361 @@
/**
* \file md.c
*
* \brief Generic message digest wrapper for PolarSSL
*
* \author Adriaan de Jong <dejong@fox-it.com>
*
* Copyright (C) 2006-2014, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; 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 program is distributed in the hope that it will be useful,
* but 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#if !defined(POLARSSL_CONFIG_FILE)
#include "polarssl/config.h"
#else
#include POLARSSL_CONFIG_FILE
#endif
#if defined(POLARSSL_MD_C)
#include "polarssl/md.h"
#include "polarssl/md_wrap.h"
#include <stdlib.h>
#if defined(_MSC_VER) && !defined strcasecmp && !defined(EFIX64) && \
!defined(EFI32)
#define strcasecmp _stricmp
#endif
/* Implementation that should never be optimized out by the compiler */
SSL_ROM_TEXT_SECTION
static void polarssl_zeroize( void *v, size_t n ) {
volatile unsigned char *p = v; while( n-- ) *p++ = 0;
}
SSL_ROM_DATA_SECTION
static const int supported_digests[] = {
#if defined(POLARSSL_SHA512_C)
POLARSSL_MD_SHA384,
POLARSSL_MD_SHA512,
#endif
#if defined(POLARSSL_SHA256_C)
POLARSSL_MD_SHA224,
POLARSSL_MD_SHA256,
#endif
#if defined(POLARSSL_SHA1_C)
POLARSSL_MD_SHA1,
#endif
#if defined(POLARSSL_RIPEMD160_C)
POLARSSL_MD_RIPEMD160,
#endif
#if defined(POLARSSL_MD5_C)
POLARSSL_MD_MD5,
#endif
#if defined(POLARSSL_MD4_C)
POLARSSL_MD_MD4,
#endif
#if defined(POLARSSL_MD2_C)
POLARSSL_MD_MD2,
#endif
POLARSSL_MD_NONE
};
SSL_ROM_TEXT_SECTION
const int *md_list( void )
{
return( supported_digests );
}
SSL_ROM_TEXT_SECTION
const md_info_t *md_info_from_string( const char *md_name )
{
if( NULL == md_name )
return( NULL );
/* Get the appropriate digest information */
#if defined(POLARSSL_MD2_C)
if( !strcasecmp( "MD2", md_name ) )
return md_info_from_type( POLARSSL_MD_MD2 );
#endif
#if defined(POLARSSL_MD4_C)
if( !strcasecmp( "MD4", md_name ) )
return md_info_from_type( POLARSSL_MD_MD4 );
#endif
#if defined(POLARSSL_MD5_C)
if( !strcasecmp( "MD5", md_name ) )
return md_info_from_type( POLARSSL_MD_MD5 );
#endif
#if defined(POLARSSL_RIPEMD160_C)
if( !strcasecmp( "RIPEMD160", md_name ) )
return md_info_from_type( POLARSSL_MD_RIPEMD160 );
#endif
#if defined(POLARSSL_SHA1_C)
if( !strcasecmp( "SHA1", md_name ) || !strcasecmp( "SHA", md_name ) )
return md_info_from_type( POLARSSL_MD_SHA1 );
#endif
#if defined(POLARSSL_SHA256_C)
if( !strcasecmp( "SHA224", md_name ) )
return md_info_from_type( POLARSSL_MD_SHA224 );
if( !strcasecmp( "SHA256", md_name ) )
return md_info_from_type( POLARSSL_MD_SHA256 );
#endif
#if defined(POLARSSL_SHA512_C)
if( !strcasecmp( "SHA384", md_name ) )
return md_info_from_type( POLARSSL_MD_SHA384 );
if( !strcasecmp( "SHA512", md_name ) )
return md_info_from_type( POLARSSL_MD_SHA512 );
#endif
return( NULL );
}
SSL_ROM_TEXT_SECTION
const md_info_t *md_info_from_type( md_type_t md_type )
{
switch( md_type )
{
#if defined(POLARSSL_MD2_C)
case POLARSSL_MD_MD2:
return( &md2_info );
#endif
#if defined(POLARSSL_MD4_C)
case POLARSSL_MD_MD4:
return( &md4_info );
#endif
#if defined(POLARSSL_MD5_C)
case POLARSSL_MD_MD5:
return( &md5_info );
#endif
#if defined(POLARSSL_RIPEMD160_C)
case POLARSSL_MD_RIPEMD160:
return( &ripemd160_info );
#endif
#if defined(POLARSSL_SHA1_C)
case POLARSSL_MD_SHA1:
return( &sha1_info );
#endif
#if defined(POLARSSL_SHA256_C)
case POLARSSL_MD_SHA224:
return( &sha224_info );
case POLARSSL_MD_SHA256:
return( &sha256_info );
#endif
#if defined(POLARSSL_SHA512_C)
case POLARSSL_MD_SHA384:
return( &sha384_info );
case POLARSSL_MD_SHA512:
return( &sha512_info );
#endif
default:
return( NULL );
}
}
SSL_ROM_TEXT_SECTION
void md_init( md_context_t *ctx )
{
memset( ctx, 0, sizeof( md_context_t ) );
}
SSL_ROM_TEXT_SECTION
void md_free( md_context_t *ctx )
{
if( ctx == NULL )
return;
if( ctx->md_ctx )
ctx->md_info->ctx_free_func( ctx->md_ctx );
polarssl_zeroize( ctx, sizeof( md_context_t ) );
}
SSL_ROM_TEXT_SECTION
int md_init_ctx( md_context_t *ctx, const md_info_t *md_info )
{
if( md_info == NULL || ctx == NULL )
return( POLARSSL_ERR_MD_BAD_INPUT_DATA );
memset( ctx, 0, sizeof( md_context_t ) );
if( ( ctx->md_ctx = md_info->ctx_alloc_func() ) == NULL )
return( POLARSSL_ERR_MD_ALLOC_FAILED );
ctx->md_info = md_info;
md_info->starts_func( ctx->md_ctx );
return( 0 );
}
SSL_ROM_TEXT_SECTION
int md_free_ctx( md_context_t *ctx )
{
md_free( ctx );
return( 0 );
}
SSL_ROM_TEXT_SECTION
int md_starts( md_context_t *ctx )
{
if( ctx == NULL || ctx->md_info == NULL )
return( POLARSSL_ERR_MD_BAD_INPUT_DATA );
ctx->md_info->starts_func( ctx->md_ctx );
return( 0 );
}
SSL_ROM_TEXT_SECTION
int md_update( md_context_t *ctx, const unsigned char *input, size_t ilen )
{
if( ctx == NULL || ctx->md_info == NULL )
return( POLARSSL_ERR_MD_BAD_INPUT_DATA );
ctx->md_info->update_func( ctx->md_ctx, input, ilen );
return( 0 );
}
SSL_ROM_TEXT_SECTION
int md_finish( md_context_t *ctx, unsigned char *output )
{
if( ctx == NULL || ctx->md_info == NULL )
return( POLARSSL_ERR_MD_BAD_INPUT_DATA );
ctx->md_info->finish_func( ctx->md_ctx, output );
return( 0 );
}
SSL_ROM_TEXT_SECTION
int md( const md_info_t *md_info, const unsigned char *input, size_t ilen,
unsigned char *output )
{
if( md_info == NULL )
return( POLARSSL_ERR_MD_BAD_INPUT_DATA );
md_info->digest_func( input, ilen, output );
return( 0 );
}
SSL_ROM_TEXT_SECTION
int md_file( const md_info_t *md_info, const char *path, unsigned char *output )
{
#if defined(POLARSSL_FS_IO)
int ret;
#endif
if( md_info == NULL )
return( POLARSSL_ERR_MD_BAD_INPUT_DATA );
#if defined(POLARSSL_FS_IO)
ret = md_info->file_func( path, output );
if( ret != 0 )
return( POLARSSL_ERR_MD_FILE_IO_ERROR + ret );
return( ret );
#else
((void) path);
((void) output);
return( POLARSSL_ERR_MD_FEATURE_UNAVAILABLE );
#endif /* POLARSSL_FS_IO */
}
SSL_ROM_TEXT_SECTION
int md_hmac_starts( md_context_t *ctx, const unsigned char *key, size_t keylen )
{
if( ctx == NULL || ctx->md_info == NULL )
return( POLARSSL_ERR_MD_BAD_INPUT_DATA );
ctx->md_info->hmac_starts_func( ctx->md_ctx, key, keylen );
return( 0 );
}
SSL_ROM_TEXT_SECTION
int md_hmac_update( md_context_t *ctx, const unsigned char *input, size_t ilen )
{
if( ctx == NULL || ctx->md_info == NULL )
return( POLARSSL_ERR_MD_BAD_INPUT_DATA );
ctx->md_info->hmac_update_func( ctx->md_ctx, input, ilen );
return( 0 );
}
SSL_ROM_TEXT_SECTION
int md_hmac_finish( md_context_t *ctx, unsigned char *output )
{
if( ctx == NULL || ctx->md_info == NULL )
return( POLARSSL_ERR_MD_BAD_INPUT_DATA );
ctx->md_info->hmac_finish_func( ctx->md_ctx, output );
return( 0 );
}
SSL_ROM_TEXT_SECTION
int md_hmac_reset( md_context_t *ctx )
{
if( ctx == NULL || ctx->md_info == NULL )
return( POLARSSL_ERR_MD_BAD_INPUT_DATA );
ctx->md_info->hmac_reset_func( ctx->md_ctx );
return( 0 );
}
SSL_ROM_TEXT_SECTION
int md_hmac( const md_info_t *md_info, const unsigned char *key, size_t keylen,
const unsigned char *input, size_t ilen,
unsigned char *output )
{
if( md_info == NULL )
return( POLARSSL_ERR_MD_BAD_INPUT_DATA );
md_info->hmac_func( key, keylen, input, ilen, output );
return( 0 );
}
SSL_ROM_TEXT_SECTION
int md_process( md_context_t *ctx, const unsigned char *data )
{
if( ctx == NULL || ctx->md_info == NULL )
return( POLARSSL_ERR_MD_BAD_INPUT_DATA );
ctx->md_info->process_func( ctx->md_ctx, data );
return( 0 );
}
#endif /* POLARSSL_MD_C */
/**
* \file md.c
*
* \brief Generic message digest wrapper for PolarSSL
*
* \author Adriaan de Jong <dejong@fox-it.com>
*
* Copyright (C) 2006-2014, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; 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 program is distributed in the hope that it will be useful,
* but 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#if !defined(POLARSSL_CONFIG_FILE)
#include "polarssl/config.h"
#else
#include POLARSSL_CONFIG_FILE
#endif
#if defined(POLARSSL_MD_C)
#include "polarssl/md.h"
#include "polarssl/md_wrap.h"
#include <stdlib.h>
#if defined(_MSC_VER) && !defined strcasecmp && !defined(EFIX64) && \
!defined(EFI32)
#define strcasecmp _stricmp
#endif
/* Implementation that should never be optimized out by the compiler */
SSL_ROM_TEXT_SECTION
static void polarssl_zeroize( void *v, size_t n ) {
volatile unsigned char *p = v; while( n-- ) *p++ = 0;
}
SSL_ROM_DATA_SECTION
static const int supported_digests[] = {
#if defined(POLARSSL_SHA512_C)
POLARSSL_MD_SHA384,
POLARSSL_MD_SHA512,
#endif
#if defined(POLARSSL_SHA256_C)
POLARSSL_MD_SHA224,
POLARSSL_MD_SHA256,
#endif
#if defined(POLARSSL_SHA1_C)
POLARSSL_MD_SHA1,
#endif
#if defined(POLARSSL_RIPEMD160_C)
POLARSSL_MD_RIPEMD160,
#endif
#if defined(POLARSSL_MD5_C)
POLARSSL_MD_MD5,
#endif
#if defined(POLARSSL_MD4_C)
POLARSSL_MD_MD4,
#endif
#if defined(POLARSSL_MD2_C)
POLARSSL_MD_MD2,
#endif
POLARSSL_MD_NONE
};
SSL_ROM_TEXT_SECTION
const int *md_list( void )
{
return( supported_digests );
}
SSL_ROM_TEXT_SECTION
const md_info_t *md_info_from_string( const char *md_name )
{
if( NULL == md_name )
return( NULL );
/* Get the appropriate digest information */
#if defined(POLARSSL_MD2_C)
if( !strcasecmp( "MD2", md_name ) )
return md_info_from_type( POLARSSL_MD_MD2 );
#endif
#if defined(POLARSSL_MD4_C)
if( !strcasecmp( "MD4", md_name ) )
return md_info_from_type( POLARSSL_MD_MD4 );
#endif
#if defined(POLARSSL_MD5_C)
if( !strcasecmp( "MD5", md_name ) )
return md_info_from_type( POLARSSL_MD_MD5 );
#endif
#if defined(POLARSSL_RIPEMD160_C)
if( !strcasecmp( "RIPEMD160", md_name ) )
return md_info_from_type( POLARSSL_MD_RIPEMD160 );
#endif
#if defined(POLARSSL_SHA1_C)
if( !strcasecmp( "SHA1", md_name ) || !strcasecmp( "SHA", md_name ) )
return md_info_from_type( POLARSSL_MD_SHA1 );
#endif
#if defined(POLARSSL_SHA256_C)
if( !strcasecmp( "SHA224", md_name ) )
return md_info_from_type( POLARSSL_MD_SHA224 );
if( !strcasecmp( "SHA256", md_name ) )
return md_info_from_type( POLARSSL_MD_SHA256 );
#endif
#if defined(POLARSSL_SHA512_C)
if( !strcasecmp( "SHA384", md_name ) )
return md_info_from_type( POLARSSL_MD_SHA384 );
if( !strcasecmp( "SHA512", md_name ) )
return md_info_from_type( POLARSSL_MD_SHA512 );
#endif
return( NULL );
}
SSL_ROM_TEXT_SECTION
const md_info_t *md_info_from_type( md_type_t md_type )
{
switch( md_type )
{
#if defined(POLARSSL_MD2_C)
case POLARSSL_MD_MD2:
return( &md2_info );
#endif
#if defined(POLARSSL_MD4_C)
case POLARSSL_MD_MD4:
return( &md4_info );
#endif
#if defined(POLARSSL_MD5_C)
case POLARSSL_MD_MD5:
return( &md5_info );
#endif
#if defined(POLARSSL_RIPEMD160_C)
case POLARSSL_MD_RIPEMD160:
return( &ripemd160_info );
#endif
#if defined(POLARSSL_SHA1_C)
case POLARSSL_MD_SHA1:
return( &sha1_info );
#endif
#if defined(POLARSSL_SHA256_C)
case POLARSSL_MD_SHA224:
return( &sha224_info );
case POLARSSL_MD_SHA256:
return( &sha256_info );
#endif
#if defined(POLARSSL_SHA512_C)
case POLARSSL_MD_SHA384:
return( &sha384_info );
case POLARSSL_MD_SHA512:
return( &sha512_info );
#endif
default:
return( NULL );
}
}
SSL_ROM_TEXT_SECTION
void md_init( md_context_t *ctx )
{
memset( ctx, 0, sizeof( md_context_t ) );
}
SSL_ROM_TEXT_SECTION
void md_free( md_context_t *ctx )
{
if( ctx == NULL )
return;
if( ctx->md_ctx )
ctx->md_info->ctx_free_func( ctx->md_ctx );
polarssl_zeroize( ctx, sizeof( md_context_t ) );
}
SSL_ROM_TEXT_SECTION
int md_init_ctx( md_context_t *ctx, const md_info_t *md_info )
{
if( md_info == NULL || ctx == NULL )
return( POLARSSL_ERR_MD_BAD_INPUT_DATA );
memset( ctx, 0, sizeof( md_context_t ) );
if( ( ctx->md_ctx = md_info->ctx_alloc_func() ) == NULL )
return( POLARSSL_ERR_MD_ALLOC_FAILED );
ctx->md_info = md_info;
md_info->starts_func( ctx->md_ctx );
return( 0 );
}
SSL_ROM_TEXT_SECTION
int md_free_ctx( md_context_t *ctx )
{
md_free( ctx );
return( 0 );
}
SSL_ROM_TEXT_SECTION
int md_starts( md_context_t *ctx )
{
if( ctx == NULL || ctx->md_info == NULL )
return( POLARSSL_ERR_MD_BAD_INPUT_DATA );
ctx->md_info->starts_func( ctx->md_ctx );
return( 0 );
}
SSL_ROM_TEXT_SECTION
int md_update( md_context_t *ctx, const unsigned char *input, size_t ilen )
{
if( ctx == NULL || ctx->md_info == NULL )
return( POLARSSL_ERR_MD_BAD_INPUT_DATA );
ctx->md_info->update_func( ctx->md_ctx, input, ilen );
return( 0 );
}
SSL_ROM_TEXT_SECTION
int md_finish( md_context_t *ctx, unsigned char *output )
{
if( ctx == NULL || ctx->md_info == NULL )
return( POLARSSL_ERR_MD_BAD_INPUT_DATA );
ctx->md_info->finish_func( ctx->md_ctx, output );
return( 0 );
}
SSL_ROM_TEXT_SECTION
int md( const md_info_t *md_info, const unsigned char *input, size_t ilen,
unsigned char *output )
{
if( md_info == NULL )
return( POLARSSL_ERR_MD_BAD_INPUT_DATA );
md_info->digest_func( input, ilen, output );
return( 0 );
}
SSL_ROM_TEXT_SECTION
int md_file( const md_info_t *md_info, const char *path, unsigned char *output )
{
#if defined(POLARSSL_FS_IO)
int ret;
#endif
if( md_info == NULL )
return( POLARSSL_ERR_MD_BAD_INPUT_DATA );
#if defined(POLARSSL_FS_IO)
ret = md_info->file_func( path, output );
if( ret != 0 )
return( POLARSSL_ERR_MD_FILE_IO_ERROR + ret );
return( ret );
#else
((void) path);
((void) output);
return( POLARSSL_ERR_MD_FEATURE_UNAVAILABLE );
#endif /* POLARSSL_FS_IO */
}
SSL_ROM_TEXT_SECTION
int md_hmac_starts( md_context_t *ctx, const unsigned char *key, size_t keylen )
{
if( ctx == NULL || ctx->md_info == NULL )
return( POLARSSL_ERR_MD_BAD_INPUT_DATA );
ctx->md_info->hmac_starts_func( ctx->md_ctx, key, keylen );
return( 0 );
}
SSL_ROM_TEXT_SECTION
int md_hmac_update( md_context_t *ctx, const unsigned char *input, size_t ilen )
{
if( ctx == NULL || ctx->md_info == NULL )
return( POLARSSL_ERR_MD_BAD_INPUT_DATA );
ctx->md_info->hmac_update_func( ctx->md_ctx, input, ilen );
return( 0 );
}
SSL_ROM_TEXT_SECTION
int md_hmac_finish( md_context_t *ctx, unsigned char *output )
{
if( ctx == NULL || ctx->md_info == NULL )
return( POLARSSL_ERR_MD_BAD_INPUT_DATA );
ctx->md_info->hmac_finish_func( ctx->md_ctx, output );
return( 0 );
}
SSL_ROM_TEXT_SECTION
int md_hmac_reset( md_context_t *ctx )
{
if( ctx == NULL || ctx->md_info == NULL )
return( POLARSSL_ERR_MD_BAD_INPUT_DATA );
ctx->md_info->hmac_reset_func( ctx->md_ctx );
return( 0 );
}
SSL_ROM_TEXT_SECTION
int md_hmac( const md_info_t *md_info, const unsigned char *key, size_t keylen,
const unsigned char *input, size_t ilen,
unsigned char *output )
{
if( md_info == NULL )
return( POLARSSL_ERR_MD_BAD_INPUT_DATA );
md_info->hmac_func( key, keylen, input, ilen, output );
return( 0 );
}
SSL_ROM_TEXT_SECTION
int md_process( md_context_t *ctx, const unsigned char *data )
{
if( ctx == NULL || ctx->md_info == NULL )
return( POLARSSL_ERR_MD_BAD_INPUT_DATA );
ctx->md_info->process_func( ctx->md_ctx, data );
return( 0 );
}
#endif /* POLARSSL_MD_C */

View file

@ -1,368 +1,368 @@
/*
* Public Key abstraction layer
*
* Copyright (C) 2006-2014, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; 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 program is distributed in the hope that it will be useful,
* but 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#if !defined(POLARSSL_CONFIG_FILE)
#include "polarssl/config.h"
#else
#include POLARSSL_CONFIG_FILE
#endif
#if defined(POLARSSL_PK_C)
#include "polarssl/pk.h"
#include "polarssl/pk_wrap.h"
#if defined(POLARSSL_RSA_C)
#include "polarssl/rsa.h"
#endif
#if defined(POLARSSL_ECP_C)
#include "polarssl/ecp.h"
#endif
#if defined(POLARSSL_ECDSA_C)
#include "polarssl/ecdsa.h"
#endif
/* Implementation that should never be optimized out by the compiler */
SSL_ROM_TEXT_SECTION
static void polarssl_zeroize( void *v, size_t n ) {
volatile unsigned char *p = v; while( n-- ) *p++ = 0;
}
/*
* Initialise a pk_context
*/
SSL_ROM_TEXT_SECTION
void pk_init( pk_context *ctx )
{
if( ctx == NULL )
return;
ctx->pk_info = NULL;
ctx->pk_ctx = NULL;
}
/*
* Free (the components of) a pk_context
*/
SSL_ROM_TEXT_SECTION
void pk_free( pk_context *ctx )
{
if( ctx == NULL || ctx->pk_info == NULL )
return;
ctx->pk_info->ctx_free_func( ctx->pk_ctx );
polarssl_zeroize( ctx, sizeof( pk_context ) );
}
/*
* Get pk_info structure from type
*/
SSL_ROM_TEXT_SECTION
const pk_info_t * pk_info_from_type( pk_type_t pk_type )
{
switch( pk_type ) {
#if defined(POLARSSL_RSA_C)
case POLARSSL_PK_RSA:
return( &rsa_info );
#endif
#if defined(POLARSSL_ECP_C)
case POLARSSL_PK_ECKEY:
return( &eckey_info );
case POLARSSL_PK_ECKEY_DH:
return( &eckeydh_info );
#endif
#if defined(POLARSSL_ECDSA_C)
case POLARSSL_PK_ECDSA:
return( &ecdsa_info );
#endif
/* POLARSSL_PK_RSA_ALT omitted on purpose */
default:
return( NULL );
}
}
/*
* Initialise context
*/
SSL_ROM_TEXT_SECTION
int pk_init_ctx( pk_context *ctx, const pk_info_t *info )
{
if( ctx == NULL || info == NULL || ctx->pk_info != NULL )
return( POLARSSL_ERR_PK_BAD_INPUT_DATA );
if( ( ctx->pk_ctx = info->ctx_alloc_func() ) == NULL )
return( POLARSSL_ERR_PK_MALLOC_FAILED );
ctx->pk_info = info;
return( 0 );
}
/*
* Initialize an RSA-alt context
*/
SSL_ROM_TEXT_SECTION
int pk_init_ctx_rsa_alt( pk_context *ctx, void * key,
pk_rsa_alt_decrypt_func decrypt_func,
pk_rsa_alt_sign_func sign_func,
pk_rsa_alt_key_len_func key_len_func )
{
rsa_alt_context *rsa_alt;
const pk_info_t *info = &rsa_alt_info;
if( ctx == NULL || ctx->pk_info != NULL )
return( POLARSSL_ERR_PK_BAD_INPUT_DATA );
if( ( ctx->pk_ctx = info->ctx_alloc_func() ) == NULL )
return( POLARSSL_ERR_PK_MALLOC_FAILED );
ctx->pk_info = info;
rsa_alt = (rsa_alt_context *) ctx->pk_ctx;
rsa_alt->key = key;
rsa_alt->decrypt_func = decrypt_func;
rsa_alt->sign_func = sign_func;
rsa_alt->key_len_func = key_len_func;
return( 0 );
}
/*
* Tell if a PK can do the operations of the given type
*/
SSL_ROM_TEXT_SECTION
int pk_can_do( pk_context *ctx, pk_type_t type )
{
/* null or NONE context can't do anything */
if( ctx == NULL || ctx->pk_info == NULL )
return( 0 );
return( ctx->pk_info->can_do( type ) );
}
/*
* Helper for pk_sign and pk_verify
*/
SSL_ROM_TEXT_SECTION
static inline int pk_hashlen_helper( md_type_t md_alg, size_t *hash_len )
{
const md_info_t *md_info;
if( *hash_len != 0 )
return( 0 );
if( ( md_info = md_info_from_type( md_alg ) ) == NULL )
return( -1 );
*hash_len = md_info->size;
return( 0 );
}
/*
* Verify a signature
*/
SSL_ROM_TEXT_SECTION
int pk_verify( pk_context *ctx, md_type_t md_alg,
const unsigned char *hash, size_t hash_len,
const unsigned char *sig, size_t sig_len )
{
if( ctx == NULL || ctx->pk_info == NULL ||
pk_hashlen_helper( md_alg, &hash_len ) != 0 )
return( POLARSSL_ERR_PK_BAD_INPUT_DATA );
if( ctx->pk_info->verify_func == NULL )
return( POLARSSL_ERR_PK_TYPE_MISMATCH );
return( ctx->pk_info->verify_func( ctx->pk_ctx, md_alg, hash, hash_len,
sig, sig_len ) );
}
/*
* Verify a signature with options
*/
SSL_ROM_TEXT_SECTION
int pk_verify_ext( pk_type_t type, const void *options,
pk_context *ctx, md_type_t md_alg,
const unsigned char *hash, size_t hash_len,
const unsigned char *sig, size_t sig_len )
{
if( ctx == NULL || ctx->pk_info == NULL )
return( POLARSSL_ERR_PK_BAD_INPUT_DATA );
if( ! pk_can_do( ctx, type ) )
return( POLARSSL_ERR_PK_TYPE_MISMATCH );
if( type == POLARSSL_PK_RSASSA_PSS )
{
#if defined(POLARSSL_RSA_C) && defined(POLARSSL_PKCS1_V21)
int ret;
const pk_rsassa_pss_options *pss_opts;
if( options == NULL )
return( POLARSSL_ERR_PK_BAD_INPUT_DATA );
pss_opts = (const pk_rsassa_pss_options *) options;
if( sig_len < pk_get_len( ctx ) )
return( POLARSSL_ERR_RSA_VERIFY_FAILED );
ret = rsa_rsassa_pss_verify_ext( pk_rsa( *ctx ),
NULL, NULL, RSA_PUBLIC,
md_alg, hash_len, hash,
pss_opts->mgf1_hash_id,
pss_opts->expected_salt_len,
sig );
if( ret != 0 )
return( ret );
if( sig_len > pk_get_len( ctx ) )
return( POLARSSL_ERR_PK_SIG_LEN_MISMATCH );
return( 0 );
#else
return( POLARSSL_ERR_PK_FEATURE_UNAVAILABLE );
#endif
}
/* General case: no options */
if( options != NULL )
return( POLARSSL_ERR_PK_BAD_INPUT_DATA );
return( pk_verify( ctx, md_alg, hash, hash_len, sig, sig_len ) );
}
/*
* Make a signature
*/
SSL_ROM_TEXT_SECTION
int pk_sign( pk_context *ctx, md_type_t md_alg,
const unsigned char *hash, size_t hash_len,
unsigned char *sig, size_t *sig_len,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
{
if( ctx == NULL || ctx->pk_info == NULL ||
pk_hashlen_helper( md_alg, &hash_len ) != 0 )
return( POLARSSL_ERR_PK_BAD_INPUT_DATA );
if( ctx->pk_info->sign_func == NULL )
return( POLARSSL_ERR_PK_TYPE_MISMATCH );
return( ctx->pk_info->sign_func( ctx->pk_ctx, md_alg, hash, hash_len,
sig, sig_len, f_rng, p_rng ) );
}
/*
* Decrypt message
*/
SSL_ROM_TEXT_SECTION
int pk_decrypt( pk_context *ctx,
const unsigned char *input, size_t ilen,
unsigned char *output, size_t *olen, size_t osize,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
{
if( ctx == NULL || ctx->pk_info == NULL )
return( POLARSSL_ERR_PK_BAD_INPUT_DATA );
if( ctx->pk_info->decrypt_func == NULL )
return( POLARSSL_ERR_PK_TYPE_MISMATCH );
return( ctx->pk_info->decrypt_func( ctx->pk_ctx, input, ilen,
output, olen, osize, f_rng, p_rng ) );
}
/*
* Encrypt message
*/
SSL_ROM_TEXT_SECTION
int pk_encrypt( pk_context *ctx,
const unsigned char *input, size_t ilen,
unsigned char *output, size_t *olen, size_t osize,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
{
if( ctx == NULL || ctx->pk_info == NULL )
return( POLARSSL_ERR_PK_BAD_INPUT_DATA );
if( ctx->pk_info->encrypt_func == NULL )
return( POLARSSL_ERR_PK_TYPE_MISMATCH );
return( ctx->pk_info->encrypt_func( ctx->pk_ctx, input, ilen,
output, olen, osize, f_rng, p_rng ) );
}
/*
* Get key size in bits
*/
SSL_ROM_TEXT_SECTION
size_t pk_get_size( const pk_context *ctx )
{
if( ctx == NULL || ctx->pk_info == NULL )
return( 0 );
return( ctx->pk_info->get_size( ctx->pk_ctx ) );
}
/*
* Export debug information
*/
SSL_ROM_TEXT_SECTION
int pk_debug( const pk_context *ctx, pk_debug_item *items )
{
if( ctx == NULL || ctx->pk_info == NULL )
return( POLARSSL_ERR_PK_BAD_INPUT_DATA );
if( ctx->pk_info->debug_func == NULL )
return( POLARSSL_ERR_PK_TYPE_MISMATCH );
ctx->pk_info->debug_func( ctx->pk_ctx, items );
return( 0 );
}
/*
* Access the PK type name
*/
SSL_ROM_TEXT_SECTION
const char * pk_get_name( const pk_context *ctx )
{
if( ctx == NULL || ctx->pk_info == NULL )
return( "invalid PK" );
return( ctx->pk_info->name );
}
/*
* Access the PK type
*/
SSL_ROM_TEXT_SECTION
pk_type_t pk_get_type( const pk_context *ctx )
{
if( ctx == NULL || ctx->pk_info == NULL )
return( POLARSSL_PK_NONE );
return( ctx->pk_info->type );
}
#endif /* POLARSSL_PK_C */
/*
* Public Key abstraction layer
*
* Copyright (C) 2006-2014, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; 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 program is distributed in the hope that it will be useful,
* but 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#if !defined(POLARSSL_CONFIG_FILE)
#include "polarssl/config.h"
#else
#include POLARSSL_CONFIG_FILE
#endif
#if defined(POLARSSL_PK_C)
#include "polarssl/pk.h"
#include "polarssl/pk_wrap.h"
#if defined(POLARSSL_RSA_C)
#include "polarssl/rsa.h"
#endif
#if defined(POLARSSL_ECP_C)
#include "polarssl/ecp.h"
#endif
#if defined(POLARSSL_ECDSA_C)
#include "polarssl/ecdsa.h"
#endif
/* Implementation that should never be optimized out by the compiler */
SSL_ROM_TEXT_SECTION
static void polarssl_zeroize( void *v, size_t n ) {
volatile unsigned char *p = v; while( n-- ) *p++ = 0;
}
/*
* Initialise a pk_context
*/
SSL_ROM_TEXT_SECTION
void pk_init( pk_context *ctx )
{
if( ctx == NULL )
return;
ctx->pk_info = NULL;
ctx->pk_ctx = NULL;
}
/*
* Free (the components of) a pk_context
*/
SSL_ROM_TEXT_SECTION
void pk_free( pk_context *ctx )
{
if( ctx == NULL || ctx->pk_info == NULL )
return;
ctx->pk_info->ctx_free_func( ctx->pk_ctx );
polarssl_zeroize( ctx, sizeof( pk_context ) );
}
/*
* Get pk_info structure from type
*/
SSL_ROM_TEXT_SECTION
const pk_info_t * pk_info_from_type( pk_type_t pk_type )
{
switch( pk_type ) {
#if defined(POLARSSL_RSA_C)
case POLARSSL_PK_RSA:
return( &rsa_info );
#endif
#if defined(POLARSSL_ECP_C)
case POLARSSL_PK_ECKEY:
return( &eckey_info );
case POLARSSL_PK_ECKEY_DH:
return( &eckeydh_info );
#endif
#if defined(POLARSSL_ECDSA_C)
case POLARSSL_PK_ECDSA:
return( &ecdsa_info );
#endif
/* POLARSSL_PK_RSA_ALT omitted on purpose */
default:
return( NULL );
}
}
/*
* Initialise context
*/
SSL_ROM_TEXT_SECTION
int pk_init_ctx( pk_context *ctx, const pk_info_t *info )
{
if( ctx == NULL || info == NULL || ctx->pk_info != NULL )
return( POLARSSL_ERR_PK_BAD_INPUT_DATA );
if( ( ctx->pk_ctx = info->ctx_alloc_func() ) == NULL )
return( POLARSSL_ERR_PK_MALLOC_FAILED );
ctx->pk_info = info;
return( 0 );
}
/*
* Initialize an RSA-alt context
*/
SSL_ROM_TEXT_SECTION
int pk_init_ctx_rsa_alt( pk_context *ctx, void * key,
pk_rsa_alt_decrypt_func decrypt_func,
pk_rsa_alt_sign_func sign_func,
pk_rsa_alt_key_len_func key_len_func )
{
rsa_alt_context *rsa_alt;
const pk_info_t *info = &rsa_alt_info;
if( ctx == NULL || ctx->pk_info != NULL )
return( POLARSSL_ERR_PK_BAD_INPUT_DATA );
if( ( ctx->pk_ctx = info->ctx_alloc_func() ) == NULL )
return( POLARSSL_ERR_PK_MALLOC_FAILED );
ctx->pk_info = info;
rsa_alt = (rsa_alt_context *) ctx->pk_ctx;
rsa_alt->key = key;
rsa_alt->decrypt_func = decrypt_func;
rsa_alt->sign_func = sign_func;
rsa_alt->key_len_func = key_len_func;
return( 0 );
}
/*
* Tell if a PK can do the operations of the given type
*/
SSL_ROM_TEXT_SECTION
int pk_can_do( pk_context *ctx, pk_type_t type )
{
/* null or NONE context can't do anything */
if( ctx == NULL || ctx->pk_info == NULL )
return( 0 );
return( ctx->pk_info->can_do( type ) );
}
/*
* Helper for pk_sign and pk_verify
*/
SSL_ROM_TEXT_SECTION
static inline int pk_hashlen_helper( md_type_t md_alg, size_t *hash_len )
{
const md_info_t *md_info;
if( *hash_len != 0 )
return( 0 );
if( ( md_info = md_info_from_type( md_alg ) ) == NULL )
return( -1 );
*hash_len = md_info->size;
return( 0 );
}
/*
* Verify a signature
*/
SSL_ROM_TEXT_SECTION
int pk_verify( pk_context *ctx, md_type_t md_alg,
const unsigned char *hash, size_t hash_len,
const unsigned char *sig, size_t sig_len )
{
if( ctx == NULL || ctx->pk_info == NULL ||
pk_hashlen_helper( md_alg, &hash_len ) != 0 )
return( POLARSSL_ERR_PK_BAD_INPUT_DATA );
if( ctx->pk_info->verify_func == NULL )
return( POLARSSL_ERR_PK_TYPE_MISMATCH );
return( ctx->pk_info->verify_func( ctx->pk_ctx, md_alg, hash, hash_len,
sig, sig_len ) );
}
/*
* Verify a signature with options
*/
SSL_ROM_TEXT_SECTION
int pk_verify_ext( pk_type_t type, const void *options,
pk_context *ctx, md_type_t md_alg,
const unsigned char *hash, size_t hash_len,
const unsigned char *sig, size_t sig_len )
{
if( ctx == NULL || ctx->pk_info == NULL )
return( POLARSSL_ERR_PK_BAD_INPUT_DATA );
if( ! pk_can_do( ctx, type ) )
return( POLARSSL_ERR_PK_TYPE_MISMATCH );
if( type == POLARSSL_PK_RSASSA_PSS )
{
#if defined(POLARSSL_RSA_C) && defined(POLARSSL_PKCS1_V21)
int ret;
const pk_rsassa_pss_options *pss_opts;
if( options == NULL )
return( POLARSSL_ERR_PK_BAD_INPUT_DATA );
pss_opts = (const pk_rsassa_pss_options *) options;
if( sig_len < pk_get_len( ctx ) )
return( POLARSSL_ERR_RSA_VERIFY_FAILED );
ret = rsa_rsassa_pss_verify_ext( pk_rsa( *ctx ),
NULL, NULL, RSA_PUBLIC,
md_alg, hash_len, hash,
pss_opts->mgf1_hash_id,
pss_opts->expected_salt_len,
sig );
if( ret != 0 )
return( ret );
if( sig_len > pk_get_len( ctx ) )
return( POLARSSL_ERR_PK_SIG_LEN_MISMATCH );
return( 0 );
#else
return( POLARSSL_ERR_PK_FEATURE_UNAVAILABLE );
#endif
}
/* General case: no options */
if( options != NULL )
return( POLARSSL_ERR_PK_BAD_INPUT_DATA );
return( pk_verify( ctx, md_alg, hash, hash_len, sig, sig_len ) );
}
/*
* Make a signature
*/
SSL_ROM_TEXT_SECTION
int pk_sign( pk_context *ctx, md_type_t md_alg,
const unsigned char *hash, size_t hash_len,
unsigned char *sig, size_t *sig_len,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
{
if( ctx == NULL || ctx->pk_info == NULL ||
pk_hashlen_helper( md_alg, &hash_len ) != 0 )
return( POLARSSL_ERR_PK_BAD_INPUT_DATA );
if( ctx->pk_info->sign_func == NULL )
return( POLARSSL_ERR_PK_TYPE_MISMATCH );
return( ctx->pk_info->sign_func( ctx->pk_ctx, md_alg, hash, hash_len,
sig, sig_len, f_rng, p_rng ) );
}
/*
* Decrypt message
*/
SSL_ROM_TEXT_SECTION
int pk_decrypt( pk_context *ctx,
const unsigned char *input, size_t ilen,
unsigned char *output, size_t *olen, size_t osize,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
{
if( ctx == NULL || ctx->pk_info == NULL )
return( POLARSSL_ERR_PK_BAD_INPUT_DATA );
if( ctx->pk_info->decrypt_func == NULL )
return( POLARSSL_ERR_PK_TYPE_MISMATCH );
return( ctx->pk_info->decrypt_func( ctx->pk_ctx, input, ilen,
output, olen, osize, f_rng, p_rng ) );
}
/*
* Encrypt message
*/
SSL_ROM_TEXT_SECTION
int pk_encrypt( pk_context *ctx,
const unsigned char *input, size_t ilen,
unsigned char *output, size_t *olen, size_t osize,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
{
if( ctx == NULL || ctx->pk_info == NULL )
return( POLARSSL_ERR_PK_BAD_INPUT_DATA );
if( ctx->pk_info->encrypt_func == NULL )
return( POLARSSL_ERR_PK_TYPE_MISMATCH );
return( ctx->pk_info->encrypt_func( ctx->pk_ctx, input, ilen,
output, olen, osize, f_rng, p_rng ) );
}
/*
* Get key size in bits
*/
SSL_ROM_TEXT_SECTION
size_t pk_get_size( const pk_context *ctx )
{
if( ctx == NULL || ctx->pk_info == NULL )
return( 0 );
return( ctx->pk_info->get_size( ctx->pk_ctx ) );
}
/*
* Export debug information
*/
SSL_ROM_TEXT_SECTION
int pk_debug( const pk_context *ctx, pk_debug_item *items )
{
if( ctx == NULL || ctx->pk_info == NULL )
return( POLARSSL_ERR_PK_BAD_INPUT_DATA );
if( ctx->pk_info->debug_func == NULL )
return( POLARSSL_ERR_PK_TYPE_MISMATCH );
ctx->pk_info->debug_func( ctx->pk_ctx, items );
return( 0 );
}
/*
* Access the PK type name
*/
SSL_ROM_TEXT_SECTION
const char * pk_get_name( const pk_context *ctx )
{
if( ctx == NULL || ctx->pk_info == NULL )
return( "invalid PK" );
return( ctx->pk_info->name );
}
/*
* Access the PK type
*/
SSL_ROM_TEXT_SECTION
pk_type_t pk_get_type( const pk_context *ctx )
{
if( ctx == NULL || ctx->pk_info == NULL )
return( POLARSSL_PK_NONE );
return( ctx->pk_info->type );
}
#endif /* POLARSSL_PK_C */

View file

@ -1,366 +1,366 @@
/*
* Public Key layer for writing key files and structures
*
* Copyright (C) 2006-2014, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; 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 program is distributed in the hope that it will be useful,
* but 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#if !defined(POLARSSL_CONFIG_FILE)
#include "polarssl/config.h"
#else
#include POLARSSL_CONFIG_FILE
#endif
#if defined(POLARSSL_PK_WRITE_C)
#include "polarssl/pk.h"
#include "polarssl/asn1write.h"
#include "polarssl/oid.h"
#if defined(POLARSSL_RSA_C)
#include "polarssl/rsa.h"
#endif
#if defined(POLARSSL_ECP_C)
#include "polarssl/ecp.h"
#endif
#if defined(POLARSSL_ECDSA_C)
#include "polarssl/ecdsa.h"
#endif
#if defined(POLARSSL_PEM_WRITE_C)
#include "polarssl/pem.h"
#endif
#if defined(POLARSSL_PLATFORM_C)
#include "polarssl/platform.h"
#else
#include <stdlib.h>
#define polarssl_malloc malloc
#define polarssl_free free
#endif
#if defined(POLARSSL_RSA_C)
/*
* RSAPublicKey ::= SEQUENCE {
* modulus INTEGER, -- n
* publicExponent INTEGER -- e
* }
*/
SSL_ROM_TEXT_SECTION
static int pk_write_rsa_pubkey( unsigned char **p, unsigned char *start,
rsa_context *rsa )
{
int ret;
size_t len = 0;
ASN1_CHK_ADD( len, asn1_write_mpi( p, start, &rsa->E ) );
ASN1_CHK_ADD( len, asn1_write_mpi( p, start, &rsa->N ) );
ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) );
ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_CONSTRUCTED |
ASN1_SEQUENCE ) );
return( (int) len );
}
#endif /* POLARSSL_RSA_C */
#if defined(POLARSSL_ECP_C)
/*
* EC public key is an EC point
*/
SSL_ROM_TEXT_SECTION
static int pk_write_ec_pubkey( unsigned char **p, unsigned char *start,
ecp_keypair *ec )
{
int ret;
size_t len = 0;
unsigned char buf[POLARSSL_ECP_MAX_PT_LEN];
if( ( ret = ecp_point_write_binary( &ec->grp, &ec->Q,
POLARSSL_ECP_PF_UNCOMPRESSED,
&len, buf, sizeof( buf ) ) ) != 0 )
{
return( ret );
}
if( *p - start < (int) len )
return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
*p -= len;
memcpy( *p, buf, len );
return( (int) len );
}
/*
* ECParameters ::= CHOICE {
* namedCurve OBJECT IDENTIFIER
* }
*/
SSL_ROM_TEXT_SECTION
static int pk_write_ec_param( unsigned char **p, unsigned char *start,
ecp_keypair *ec )
{
int ret;
size_t len = 0;
const char *oid;
size_t oid_len;
if( ( ret = oid_get_oid_by_ec_grp( ec->grp.id, &oid, &oid_len ) ) != 0 )
return( ret );
ASN1_CHK_ADD( len, asn1_write_oid( p, start, oid, oid_len ) );
return( (int) len );
}
#endif /* POLARSSL_ECP_C */
SSL_ROM_TEXT_SECTION
int pk_write_pubkey( unsigned char **p, unsigned char *start,
const pk_context *key )
{
int ret;
size_t len = 0;
#if defined(POLARSSL_RSA_C)
if( pk_get_type( key ) == POLARSSL_PK_RSA )
ASN1_CHK_ADD( len, pk_write_rsa_pubkey( p, start, pk_rsa( *key ) ) );
else
#endif
#if defined(POLARSSL_ECP_C)
if( pk_get_type( key ) == POLARSSL_PK_ECKEY )
ASN1_CHK_ADD( len, pk_write_ec_pubkey( p, start, pk_ec( *key ) ) );
else
#endif
return( POLARSSL_ERR_PK_FEATURE_UNAVAILABLE );
return( (int) len );
}
SSL_ROM_TEXT_SECTION
int pk_write_pubkey_der( pk_context *key, unsigned char *buf, size_t size )
{
int ret;
unsigned char *c;
size_t len = 0, par_len = 0, oid_len;
const char *oid;
c = buf + size;
ASN1_CHK_ADD( len, pk_write_pubkey( &c, buf, key ) );
if( c - buf < 1 )
return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
/*
* SubjectPublicKeyInfo ::= SEQUENCE {
* algorithm AlgorithmIdentifier,
* subjectPublicKey BIT STRING }
*/
*--c = 0;
len += 1;
ASN1_CHK_ADD( len, asn1_write_len( &c, buf, len ) );
ASN1_CHK_ADD( len, asn1_write_tag( &c, buf, ASN1_BIT_STRING ) );
if( ( ret = oid_get_oid_by_pk_alg( pk_get_type( key ),
&oid, &oid_len ) ) != 0 )
{
return( ret );
}
#if defined(POLARSSL_ECP_C)
if( pk_get_type( key ) == POLARSSL_PK_ECKEY )
{
ASN1_CHK_ADD( par_len, pk_write_ec_param( &c, buf, pk_ec( *key ) ) );
}
#endif
ASN1_CHK_ADD( len, asn1_write_algorithm_identifier( &c, buf, oid, oid_len,
par_len ) );
ASN1_CHK_ADD( len, asn1_write_len( &c, buf, len ) );
ASN1_CHK_ADD( len, asn1_write_tag( &c, buf, ASN1_CONSTRUCTED |
ASN1_SEQUENCE ) );
return( (int) len );
}
SSL_ROM_TEXT_SECTION
int pk_write_key_der( pk_context *key, unsigned char *buf, size_t size )
{
int ret;
unsigned char *c = buf + size;
size_t len = 0;
#if defined(POLARSSL_RSA_C)
if( pk_get_type( key ) == POLARSSL_PK_RSA )
{
rsa_context *rsa = pk_rsa( *key );
ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->QP ) );
ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->DQ ) );
ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->DP ) );
ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->Q ) );
ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->P ) );
ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->D ) );
ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->E ) );
ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->N ) );
ASN1_CHK_ADD( len, asn1_write_int( &c, buf, 0 ) );
ASN1_CHK_ADD( len, asn1_write_len( &c, buf, len ) );
ASN1_CHK_ADD( len, asn1_write_tag( &c, buf, ASN1_CONSTRUCTED |
ASN1_SEQUENCE ) );
}
else
#endif /* POLARSSL_RSA_C */
#if defined(POLARSSL_ECP_C)
if( pk_get_type( key ) == POLARSSL_PK_ECKEY )
{
ecp_keypair *ec = pk_ec( *key );
size_t pub_len = 0, par_len = 0;
/*
* RFC 5915, or SEC1 Appendix C.4
*
* ECPrivateKey ::= SEQUENCE {
* version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1),
* privateKey OCTET STRING,
* parameters [0] ECParameters {{ NamedCurve }} OPTIONAL,
* publicKey [1] BIT STRING OPTIONAL
* }
*/
/* publicKey */
ASN1_CHK_ADD( pub_len, pk_write_ec_pubkey( &c, buf, ec ) );
if( c - buf < 1 )
return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
*--c = 0;
pub_len += 1;
ASN1_CHK_ADD( pub_len, asn1_write_len( &c, buf, pub_len ) );
ASN1_CHK_ADD( pub_len, asn1_write_tag( &c, buf, ASN1_BIT_STRING ) );
ASN1_CHK_ADD( pub_len, asn1_write_len( &c, buf, pub_len ) );
ASN1_CHK_ADD( pub_len, asn1_write_tag( &c, buf,
ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 1 ) );
len += pub_len;
/* parameters */
ASN1_CHK_ADD( par_len, pk_write_ec_param( &c, buf, ec ) );
ASN1_CHK_ADD( par_len, asn1_write_len( &c, buf, par_len ) );
ASN1_CHK_ADD( par_len, asn1_write_tag( &c, buf,
ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 0 ) );
len += par_len;
/* privateKey: write as MPI then fix tag */
ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &ec->d ) );
*c = ASN1_OCTET_STRING;
/* version */
ASN1_CHK_ADD( len, asn1_write_int( &c, buf, 1 ) );
ASN1_CHK_ADD( len, asn1_write_len( &c, buf, len ) );
ASN1_CHK_ADD( len, asn1_write_tag( &c, buf, ASN1_CONSTRUCTED |
ASN1_SEQUENCE ) );
}
else
#endif /* POLARSSL_ECP_C */
return( POLARSSL_ERR_PK_FEATURE_UNAVAILABLE );
return( (int) len );
}
#if defined(POLARSSL_PEM_WRITE_C)
#define PEM_BEGIN_PUBLIC_KEY "-----BEGIN PUBLIC KEY-----\n"
#define PEM_END_PUBLIC_KEY "-----END PUBLIC KEY-----\n"
#define PEM_BEGIN_PRIVATE_KEY_RSA "-----BEGIN RSA PRIVATE KEY-----\n"
#define PEM_END_PRIVATE_KEY_RSA "-----END RSA PRIVATE KEY-----\n"
#define PEM_BEGIN_PRIVATE_KEY_EC "-----BEGIN EC PRIVATE KEY-----\n"
#define PEM_END_PRIVATE_KEY_EC "-----END EC PRIVATE KEY-----\n"
SSL_ROM_TEXT_SECTION
int pk_write_pubkey_pem( pk_context *key, unsigned char *buf, size_t size )
{
int ret;
unsigned char output_buf[4096];
size_t olen = 0;
if( ( ret = pk_write_pubkey_der( key, output_buf,
sizeof(output_buf) ) ) < 0 )
{
return( ret );
}
if( ( ret = pem_write_buffer( PEM_BEGIN_PUBLIC_KEY, PEM_END_PUBLIC_KEY,
output_buf + sizeof(output_buf) - ret,
ret, buf, size, &olen ) ) != 0 )
{
return( ret );
}
return( 0 );
}
SSL_ROM_TEXT_SECTION
int pk_write_key_pem( pk_context *key, unsigned char *buf, size_t size )
{
int ret;
unsigned char output_buf[4096];
const char *begin, *end;
size_t olen = 0;
if( ( ret = pk_write_key_der( key, output_buf, sizeof(output_buf) ) ) < 0 )
return( ret );
#if defined(POLARSSL_RSA_C)
if( pk_get_type( key ) == POLARSSL_PK_RSA )
{
begin = PEM_BEGIN_PRIVATE_KEY_RSA;
end = PEM_END_PRIVATE_KEY_RSA;
}
else
#endif
#if defined(POLARSSL_ECP_C)
if( pk_get_type( key ) == POLARSSL_PK_ECKEY )
{
begin = PEM_BEGIN_PRIVATE_KEY_EC;
end = PEM_END_PRIVATE_KEY_EC;
}
else
#endif
return( POLARSSL_ERR_PK_FEATURE_UNAVAILABLE );
if( ( ret = pem_write_buffer( begin, end,
output_buf + sizeof(output_buf) - ret,
ret, buf, size, &olen ) ) != 0 )
{
return( ret );
}
return( 0 );
}
#endif /* POLARSSL_PEM_WRITE_C */
#endif /* POLARSSL_PK_WRITE_C */
/*
* Public Key layer for writing key files and structures
*
* Copyright (C) 2006-2014, Brainspark B.V.
*
* This file is part of PolarSSL (http://www.polarssl.org)
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
*
* All rights reserved.
*
* This program is free software; 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 program is distributed in the hope that it will be useful,
* but 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#if !defined(POLARSSL_CONFIG_FILE)
#include "polarssl/config.h"
#else
#include POLARSSL_CONFIG_FILE
#endif
#if defined(POLARSSL_PK_WRITE_C)
#include "polarssl/pk.h"
#include "polarssl/asn1write.h"
#include "polarssl/oid.h"
#if defined(POLARSSL_RSA_C)
#include "polarssl/rsa.h"
#endif
#if defined(POLARSSL_ECP_C)
#include "polarssl/ecp.h"
#endif
#if defined(POLARSSL_ECDSA_C)
#include "polarssl/ecdsa.h"
#endif
#if defined(POLARSSL_PEM_WRITE_C)
#include "polarssl/pem.h"
#endif
#if defined(POLARSSL_PLATFORM_C)
#include "polarssl/platform.h"
#else
#include <stdlib.h>
#define polarssl_malloc malloc
#define polarssl_free free
#endif
#if defined(POLARSSL_RSA_C)
/*
* RSAPublicKey ::= SEQUENCE {
* modulus INTEGER, -- n
* publicExponent INTEGER -- e
* }
*/
SSL_ROM_TEXT_SECTION
static int pk_write_rsa_pubkey( unsigned char **p, unsigned char *start,
rsa_context *rsa )
{
int ret;
size_t len = 0;
ASN1_CHK_ADD( len, asn1_write_mpi( p, start, &rsa->E ) );
ASN1_CHK_ADD( len, asn1_write_mpi( p, start, &rsa->N ) );
ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) );
ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_CONSTRUCTED |
ASN1_SEQUENCE ) );
return( (int) len );
}
#endif /* POLARSSL_RSA_C */
#if defined(POLARSSL_ECP_C)
/*
* EC public key is an EC point
*/
SSL_ROM_TEXT_SECTION
static int pk_write_ec_pubkey( unsigned char **p, unsigned char *start,
ecp_keypair *ec )
{
int ret;
size_t len = 0;
unsigned char buf[POLARSSL_ECP_MAX_PT_LEN];
if( ( ret = ecp_point_write_binary( &ec->grp, &ec->Q,
POLARSSL_ECP_PF_UNCOMPRESSED,
&len, buf, sizeof( buf ) ) ) != 0 )
{
return( ret );
}
if( *p - start < (int) len )
return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
*p -= len;
memcpy( *p, buf, len );
return( (int) len );
}
/*
* ECParameters ::= CHOICE {
* namedCurve OBJECT IDENTIFIER
* }
*/
SSL_ROM_TEXT_SECTION
static int pk_write_ec_param( unsigned char **p, unsigned char *start,
ecp_keypair *ec )
{
int ret;
size_t len = 0;
const char *oid;
size_t oid_len;
if( ( ret = oid_get_oid_by_ec_grp( ec->grp.id, &oid, &oid_len ) ) != 0 )
return( ret );
ASN1_CHK_ADD( len, asn1_write_oid( p, start, oid, oid_len ) );
return( (int) len );
}
#endif /* POLARSSL_ECP_C */
SSL_ROM_TEXT_SECTION
int pk_write_pubkey( unsigned char **p, unsigned char *start,
const pk_context *key )
{
int ret;
size_t len = 0;
#if defined(POLARSSL_RSA_C)
if( pk_get_type( key ) == POLARSSL_PK_RSA )
ASN1_CHK_ADD( len, pk_write_rsa_pubkey( p, start, pk_rsa( *key ) ) );
else
#endif
#if defined(POLARSSL_ECP_C)
if( pk_get_type( key ) == POLARSSL_PK_ECKEY )
ASN1_CHK_ADD( len, pk_write_ec_pubkey( p, start, pk_ec( *key ) ) );
else
#endif
return( POLARSSL_ERR_PK_FEATURE_UNAVAILABLE );
return( (int) len );
}
SSL_ROM_TEXT_SECTION
int pk_write_pubkey_der( pk_context *key, unsigned char *buf, size_t size )
{
int ret;
unsigned char *c;
size_t len = 0, par_len = 0, oid_len;
const char *oid;
c = buf + size;
ASN1_CHK_ADD( len, pk_write_pubkey( &c, buf, key ) );
if( c - buf < 1 )
return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
/*
* SubjectPublicKeyInfo ::= SEQUENCE {
* algorithm AlgorithmIdentifier,
* subjectPublicKey BIT STRING }
*/
*--c = 0;
len += 1;
ASN1_CHK_ADD( len, asn1_write_len( &c, buf, len ) );
ASN1_CHK_ADD( len, asn1_write_tag( &c, buf, ASN1_BIT_STRING ) );
if( ( ret = oid_get_oid_by_pk_alg( pk_get_type( key ),
&oid, &oid_len ) ) != 0 )
{
return( ret );
}
#if defined(POLARSSL_ECP_C)
if( pk_get_type( key ) == POLARSSL_PK_ECKEY )
{
ASN1_CHK_ADD( par_len, pk_write_ec_param( &c, buf, pk_ec( *key ) ) );
}
#endif
ASN1_CHK_ADD( len, asn1_write_algorithm_identifier( &c, buf, oid, oid_len,
par_len ) );
ASN1_CHK_ADD( len, asn1_write_len( &c, buf, len ) );
ASN1_CHK_ADD( len, asn1_write_tag( &c, buf, ASN1_CONSTRUCTED |
ASN1_SEQUENCE ) );
return( (int) len );
}
SSL_ROM_TEXT_SECTION
int pk_write_key_der( pk_context *key, unsigned char *buf, size_t size )
{
int ret;
unsigned char *c = buf + size;
size_t len = 0;
#if defined(POLARSSL_RSA_C)
if( pk_get_type( key ) == POLARSSL_PK_RSA )
{
rsa_context *rsa = pk_rsa( *key );
ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->QP ) );
ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->DQ ) );
ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->DP ) );
ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->Q ) );
ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->P ) );
ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->D ) );
ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->E ) );
ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->N ) );
ASN1_CHK_ADD( len, asn1_write_int( &c, buf, 0 ) );
ASN1_CHK_ADD( len, asn1_write_len( &c, buf, len ) );
ASN1_CHK_ADD( len, asn1_write_tag( &c, buf, ASN1_CONSTRUCTED |
ASN1_SEQUENCE ) );
}
else
#endif /* POLARSSL_RSA_C */
#if defined(POLARSSL_ECP_C)
if( pk_get_type( key ) == POLARSSL_PK_ECKEY )
{
ecp_keypair *ec = pk_ec( *key );
size_t pub_len = 0, par_len = 0;
/*
* RFC 5915, or SEC1 Appendix C.4
*
* ECPrivateKey ::= SEQUENCE {
* version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1),
* privateKey OCTET STRING,
* parameters [0] ECParameters {{ NamedCurve }} OPTIONAL,
* publicKey [1] BIT STRING OPTIONAL
* }
*/
/* publicKey */
ASN1_CHK_ADD( pub_len, pk_write_ec_pubkey( &c, buf, ec ) );
if( c - buf < 1 )
return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
*--c = 0;
pub_len += 1;
ASN1_CHK_ADD( pub_len, asn1_write_len( &c, buf, pub_len ) );
ASN1_CHK_ADD( pub_len, asn1_write_tag( &c, buf, ASN1_BIT_STRING ) );
ASN1_CHK_ADD( pub_len, asn1_write_len( &c, buf, pub_len ) );
ASN1_CHK_ADD( pub_len, asn1_write_tag( &c, buf,
ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 1 ) );
len += pub_len;
/* parameters */
ASN1_CHK_ADD( par_len, pk_write_ec_param( &c, buf, ec ) );
ASN1_CHK_ADD( par_len, asn1_write_len( &c, buf, par_len ) );
ASN1_CHK_ADD( par_len, asn1_write_tag( &c, buf,
ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 0 ) );
len += par_len;
/* privateKey: write as MPI then fix tag */
ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &ec->d ) );
*c = ASN1_OCTET_STRING;
/* version */
ASN1_CHK_ADD( len, asn1_write_int( &c, buf, 1 ) );
ASN1_CHK_ADD( len, asn1_write_len( &c, buf, len ) );
ASN1_CHK_ADD( len, asn1_write_tag( &c, buf, ASN1_CONSTRUCTED |
ASN1_SEQUENCE ) );
}
else
#endif /* POLARSSL_ECP_C */
return( POLARSSL_ERR_PK_FEATURE_UNAVAILABLE );
return( (int) len );
}
#if defined(POLARSSL_PEM_WRITE_C)
#define PEM_BEGIN_PUBLIC_KEY "-----BEGIN PUBLIC KEY-----\n"
#define PEM_END_PUBLIC_KEY "-----END PUBLIC KEY-----\n"
#define PEM_BEGIN_PRIVATE_KEY_RSA "-----BEGIN RSA PRIVATE KEY-----\n"
#define PEM_END_PRIVATE_KEY_RSA "-----END RSA PRIVATE KEY-----\n"
#define PEM_BEGIN_PRIVATE_KEY_EC "-----BEGIN EC PRIVATE KEY-----\n"
#define PEM_END_PRIVATE_KEY_EC "-----END EC PRIVATE KEY-----\n"
SSL_ROM_TEXT_SECTION
int pk_write_pubkey_pem( pk_context *key, unsigned char *buf, size_t size )
{
int ret;
unsigned char output_buf[4096];
size_t olen = 0;
if( ( ret = pk_write_pubkey_der( key, output_buf,
sizeof(output_buf) ) ) < 0 )
{
return( ret );
}
if( ( ret = pem_write_buffer( PEM_BEGIN_PUBLIC_KEY, PEM_END_PUBLIC_KEY,
output_buf + sizeof(output_buf) - ret,
ret, buf, size, &olen ) ) != 0 )
{
return( ret );
}
return( 0 );
}
SSL_ROM_TEXT_SECTION
int pk_write_key_pem( pk_context *key, unsigned char *buf, size_t size )
{
int ret;
unsigned char output_buf[4096];
const char *begin, *end;
size_t olen = 0;
if( ( ret = pk_write_key_der( key, output_buf, sizeof(output_buf) ) ) < 0 )
return( ret );
#if defined(POLARSSL_RSA_C)
if( pk_get_type( key ) == POLARSSL_PK_RSA )
{
begin = PEM_BEGIN_PRIVATE_KEY_RSA;
end = PEM_END_PRIVATE_KEY_RSA;
}
else
#endif
#if defined(POLARSSL_ECP_C)
if( pk_get_type( key ) == POLARSSL_PK_ECKEY )
{
begin = PEM_BEGIN_PRIVATE_KEY_EC;
end = PEM_END_PRIVATE_KEY_EC;
}
else
#endif
return( POLARSSL_ERR_PK_FEATURE_UNAVAILABLE );
if( ( ret = pem_write_buffer( begin, end,
output_buf + sizeof(output_buf) - ret,
ret, buf, size, &olen ) ) != 0 )
{
return( ret );
}
return( 0 );
}
#endif /* POLARSSL_PEM_WRITE_C */
#endif /* POLARSSL_PK_WRITE_C */