BA / SerialCom

Fork of OmniWheels by Gustav Atmel

Committer:
gustavatmel
Date:
Tue May 01 15:55:34 2018 +0000
Revision:
2:798925c9e4a8
Parent:
1:9c5af431a1f1
bluetooth

Who changed what in which revision?

UserRevisionLine numberNew contents of line
gustavatmel 1:9c5af431a1f1 1 /*
gustavatmel 1:9c5af431a1f1 2 * Public Key layer for writing key files and structures
gustavatmel 1:9c5af431a1f1 3 *
gustavatmel 1:9c5af431a1f1 4 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
gustavatmel 1:9c5af431a1f1 5 * SPDX-License-Identifier: Apache-2.0
gustavatmel 1:9c5af431a1f1 6 *
gustavatmel 1:9c5af431a1f1 7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
gustavatmel 1:9c5af431a1f1 8 * not use this file except in compliance with the License.
gustavatmel 1:9c5af431a1f1 9 * You may obtain a copy of the License at
gustavatmel 1:9c5af431a1f1 10 *
gustavatmel 1:9c5af431a1f1 11 * http://www.apache.org/licenses/LICENSE-2.0
gustavatmel 1:9c5af431a1f1 12 *
gustavatmel 1:9c5af431a1f1 13 * Unless required by applicable law or agreed to in writing, software
gustavatmel 1:9c5af431a1f1 14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
gustavatmel 1:9c5af431a1f1 15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
gustavatmel 1:9c5af431a1f1 16 * See the License for the specific language governing permissions and
gustavatmel 1:9c5af431a1f1 17 * limitations under the License.
gustavatmel 1:9c5af431a1f1 18 *
gustavatmel 1:9c5af431a1f1 19 * This file is part of mbed TLS (https://tls.mbed.org)
gustavatmel 1:9c5af431a1f1 20 */
gustavatmel 1:9c5af431a1f1 21
gustavatmel 1:9c5af431a1f1 22 #if !defined(MBEDTLS_CONFIG_FILE)
gustavatmel 1:9c5af431a1f1 23 #include "mbedtls/config.h"
gustavatmel 1:9c5af431a1f1 24 #else
gustavatmel 1:9c5af431a1f1 25 #include MBEDTLS_CONFIG_FILE
gustavatmel 1:9c5af431a1f1 26 #endif
gustavatmel 1:9c5af431a1f1 27
gustavatmel 1:9c5af431a1f1 28 #if defined(MBEDTLS_PK_WRITE_C)
gustavatmel 1:9c5af431a1f1 29
gustavatmel 1:9c5af431a1f1 30 #include "mbedtls/pk.h"
gustavatmel 1:9c5af431a1f1 31 #include "mbedtls/asn1write.h"
gustavatmel 1:9c5af431a1f1 32 #include "mbedtls/oid.h"
gustavatmel 1:9c5af431a1f1 33
gustavatmel 1:9c5af431a1f1 34 #include <string.h>
gustavatmel 1:9c5af431a1f1 35
gustavatmel 1:9c5af431a1f1 36 #if defined(MBEDTLS_RSA_C)
gustavatmel 1:9c5af431a1f1 37 #include "mbedtls/rsa.h"
gustavatmel 1:9c5af431a1f1 38 #endif
gustavatmel 1:9c5af431a1f1 39 #if defined(MBEDTLS_ECP_C)
gustavatmel 1:9c5af431a1f1 40 #include "mbedtls/ecp.h"
gustavatmel 1:9c5af431a1f1 41 #endif
gustavatmel 1:9c5af431a1f1 42 #if defined(MBEDTLS_ECDSA_C)
gustavatmel 1:9c5af431a1f1 43 #include "mbedtls/ecdsa.h"
gustavatmel 1:9c5af431a1f1 44 #endif
gustavatmel 1:9c5af431a1f1 45 #if defined(MBEDTLS_PEM_WRITE_C)
gustavatmel 1:9c5af431a1f1 46 #include "mbedtls/pem.h"
gustavatmel 1:9c5af431a1f1 47 #endif
gustavatmel 1:9c5af431a1f1 48
gustavatmel 1:9c5af431a1f1 49 #if defined(MBEDTLS_PLATFORM_C)
gustavatmel 1:9c5af431a1f1 50 #include "mbedtls/platform.h"
gustavatmel 1:9c5af431a1f1 51 #else
gustavatmel 1:9c5af431a1f1 52 #include <stdlib.h>
gustavatmel 1:9c5af431a1f1 53 #define mbedtls_calloc calloc
gustavatmel 1:9c5af431a1f1 54 #define mbedtls_free free
gustavatmel 1:9c5af431a1f1 55 #endif
gustavatmel 1:9c5af431a1f1 56
gustavatmel 1:9c5af431a1f1 57 #if defined(MBEDTLS_RSA_C)
gustavatmel 1:9c5af431a1f1 58 /*
gustavatmel 1:9c5af431a1f1 59 * RSAPublicKey ::= SEQUENCE {
gustavatmel 1:9c5af431a1f1 60 * modulus INTEGER, -- n
gustavatmel 1:9c5af431a1f1 61 * publicExponent INTEGER -- e
gustavatmel 1:9c5af431a1f1 62 * }
gustavatmel 1:9c5af431a1f1 63 */
gustavatmel 1:9c5af431a1f1 64 static int pk_write_rsa_pubkey( unsigned char **p, unsigned char *start,
gustavatmel 1:9c5af431a1f1 65 mbedtls_rsa_context *rsa )
gustavatmel 1:9c5af431a1f1 66 {
gustavatmel 1:9c5af431a1f1 67 int ret;
gustavatmel 1:9c5af431a1f1 68 size_t len = 0;
gustavatmel 1:9c5af431a1f1 69 mbedtls_mpi T;
gustavatmel 1:9c5af431a1f1 70
gustavatmel 1:9c5af431a1f1 71 mbedtls_mpi_init( &T );
gustavatmel 1:9c5af431a1f1 72
gustavatmel 1:9c5af431a1f1 73 /* Export E */
gustavatmel 1:9c5af431a1f1 74 if ( ( ret = mbedtls_rsa_export( rsa, NULL, NULL, NULL, NULL, &T ) ) != 0 ||
gustavatmel 1:9c5af431a1f1 75 ( ret = mbedtls_asn1_write_mpi( p, start, &T ) ) < 0 )
gustavatmel 1:9c5af431a1f1 76 goto end_of_export;
gustavatmel 1:9c5af431a1f1 77 len += ret;
gustavatmel 1:9c5af431a1f1 78
gustavatmel 1:9c5af431a1f1 79 /* Export N */
gustavatmel 1:9c5af431a1f1 80 if ( ( ret = mbedtls_rsa_export( rsa, &T, NULL, NULL, NULL, NULL ) ) != 0 ||
gustavatmel 1:9c5af431a1f1 81 ( ret = mbedtls_asn1_write_mpi( p, start, &T ) ) < 0 )
gustavatmel 1:9c5af431a1f1 82 goto end_of_export;
gustavatmel 1:9c5af431a1f1 83 len += ret;
gustavatmel 1:9c5af431a1f1 84
gustavatmel 1:9c5af431a1f1 85 end_of_export:
gustavatmel 1:9c5af431a1f1 86
gustavatmel 1:9c5af431a1f1 87 mbedtls_mpi_free( &T );
gustavatmel 1:9c5af431a1f1 88 if( ret < 0 )
gustavatmel 1:9c5af431a1f1 89 return( ret );
gustavatmel 1:9c5af431a1f1 90
gustavatmel 1:9c5af431a1f1 91 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
gustavatmel 1:9c5af431a1f1 92 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_CONSTRUCTED |
gustavatmel 1:9c5af431a1f1 93 MBEDTLS_ASN1_SEQUENCE ) );
gustavatmel 1:9c5af431a1f1 94
gustavatmel 1:9c5af431a1f1 95 return( (int) len );
gustavatmel 1:9c5af431a1f1 96 }
gustavatmel 1:9c5af431a1f1 97 #endif /* MBEDTLS_RSA_C */
gustavatmel 1:9c5af431a1f1 98
gustavatmel 1:9c5af431a1f1 99 #if defined(MBEDTLS_ECP_C)
gustavatmel 1:9c5af431a1f1 100 /*
gustavatmel 1:9c5af431a1f1 101 * EC public key is an EC point
gustavatmel 1:9c5af431a1f1 102 */
gustavatmel 1:9c5af431a1f1 103 static int pk_write_ec_pubkey( unsigned char **p, unsigned char *start,
gustavatmel 1:9c5af431a1f1 104 mbedtls_ecp_keypair *ec )
gustavatmel 1:9c5af431a1f1 105 {
gustavatmel 1:9c5af431a1f1 106 int ret;
gustavatmel 1:9c5af431a1f1 107 size_t len = 0;
gustavatmel 1:9c5af431a1f1 108 unsigned char buf[MBEDTLS_ECP_MAX_PT_LEN];
gustavatmel 1:9c5af431a1f1 109
gustavatmel 1:9c5af431a1f1 110 if( ( ret = mbedtls_ecp_point_write_binary( &ec->grp, &ec->Q,
gustavatmel 1:9c5af431a1f1 111 MBEDTLS_ECP_PF_UNCOMPRESSED,
gustavatmel 1:9c5af431a1f1 112 &len, buf, sizeof( buf ) ) ) != 0 )
gustavatmel 1:9c5af431a1f1 113 {
gustavatmel 1:9c5af431a1f1 114 return( ret );
gustavatmel 1:9c5af431a1f1 115 }
gustavatmel 1:9c5af431a1f1 116
gustavatmel 1:9c5af431a1f1 117 if( *p < start || (size_t)( *p - start ) < len )
gustavatmel 1:9c5af431a1f1 118 return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
gustavatmel 1:9c5af431a1f1 119
gustavatmel 1:9c5af431a1f1 120 *p -= len;
gustavatmel 1:9c5af431a1f1 121 memcpy( *p, buf, len );
gustavatmel 1:9c5af431a1f1 122
gustavatmel 1:9c5af431a1f1 123 return( (int) len );
gustavatmel 1:9c5af431a1f1 124 }
gustavatmel 1:9c5af431a1f1 125
gustavatmel 1:9c5af431a1f1 126 /*
gustavatmel 1:9c5af431a1f1 127 * ECParameters ::= CHOICE {
gustavatmel 1:9c5af431a1f1 128 * namedCurve OBJECT IDENTIFIER
gustavatmel 1:9c5af431a1f1 129 * }
gustavatmel 1:9c5af431a1f1 130 */
gustavatmel 1:9c5af431a1f1 131 static int pk_write_ec_param( unsigned char **p, unsigned char *start,
gustavatmel 1:9c5af431a1f1 132 mbedtls_ecp_keypair *ec )
gustavatmel 1:9c5af431a1f1 133 {
gustavatmel 1:9c5af431a1f1 134 int ret;
gustavatmel 1:9c5af431a1f1 135 size_t len = 0;
gustavatmel 1:9c5af431a1f1 136 const char *oid;
gustavatmel 1:9c5af431a1f1 137 size_t oid_len;
gustavatmel 1:9c5af431a1f1 138
gustavatmel 1:9c5af431a1f1 139 if( ( ret = mbedtls_oid_get_oid_by_ec_grp( ec->grp.id, &oid, &oid_len ) ) != 0 )
gustavatmel 1:9c5af431a1f1 140 return( ret );
gustavatmel 1:9c5af431a1f1 141
gustavatmel 1:9c5af431a1f1 142 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_oid( p, start, oid, oid_len ) );
gustavatmel 1:9c5af431a1f1 143
gustavatmel 1:9c5af431a1f1 144 return( (int) len );
gustavatmel 1:9c5af431a1f1 145 }
gustavatmel 1:9c5af431a1f1 146 #endif /* MBEDTLS_ECP_C */
gustavatmel 1:9c5af431a1f1 147
gustavatmel 1:9c5af431a1f1 148 int mbedtls_pk_write_pubkey( unsigned char **p, unsigned char *start,
gustavatmel 1:9c5af431a1f1 149 const mbedtls_pk_context *key )
gustavatmel 1:9c5af431a1f1 150 {
gustavatmel 1:9c5af431a1f1 151 int ret;
gustavatmel 1:9c5af431a1f1 152 size_t len = 0;
gustavatmel 1:9c5af431a1f1 153
gustavatmel 1:9c5af431a1f1 154 #if defined(MBEDTLS_RSA_C)
gustavatmel 1:9c5af431a1f1 155 if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_RSA )
gustavatmel 1:9c5af431a1f1 156 MBEDTLS_ASN1_CHK_ADD( len, pk_write_rsa_pubkey( p, start, mbedtls_pk_rsa( *key ) ) );
gustavatmel 1:9c5af431a1f1 157 else
gustavatmel 1:9c5af431a1f1 158 #endif
gustavatmel 1:9c5af431a1f1 159 #if defined(MBEDTLS_ECP_C)
gustavatmel 1:9c5af431a1f1 160 if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_ECKEY )
gustavatmel 1:9c5af431a1f1 161 MBEDTLS_ASN1_CHK_ADD( len, pk_write_ec_pubkey( p, start, mbedtls_pk_ec( *key ) ) );
gustavatmel 1:9c5af431a1f1 162 else
gustavatmel 1:9c5af431a1f1 163 #endif
gustavatmel 1:9c5af431a1f1 164 return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE );
gustavatmel 1:9c5af431a1f1 165
gustavatmel 1:9c5af431a1f1 166 return( (int) len );
gustavatmel 1:9c5af431a1f1 167 }
gustavatmel 1:9c5af431a1f1 168
gustavatmel 1:9c5af431a1f1 169 int mbedtls_pk_write_pubkey_der( mbedtls_pk_context *key, unsigned char *buf, size_t size )
gustavatmel 1:9c5af431a1f1 170 {
gustavatmel 1:9c5af431a1f1 171 int ret;
gustavatmel 1:9c5af431a1f1 172 unsigned char *c;
gustavatmel 1:9c5af431a1f1 173 size_t len = 0, par_len = 0, oid_len;
gustavatmel 1:9c5af431a1f1 174 const char *oid;
gustavatmel 1:9c5af431a1f1 175
gustavatmel 1:9c5af431a1f1 176 c = buf + size;
gustavatmel 1:9c5af431a1f1 177
gustavatmel 1:9c5af431a1f1 178 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_pk_write_pubkey( &c, buf, key ) );
gustavatmel 1:9c5af431a1f1 179
gustavatmel 1:9c5af431a1f1 180 if( c - buf < 1 )
gustavatmel 1:9c5af431a1f1 181 return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
gustavatmel 1:9c5af431a1f1 182
gustavatmel 1:9c5af431a1f1 183 /*
gustavatmel 1:9c5af431a1f1 184 * SubjectPublicKeyInfo ::= SEQUENCE {
gustavatmel 1:9c5af431a1f1 185 * algorithm AlgorithmIdentifier,
gustavatmel 1:9c5af431a1f1 186 * subjectPublicKey BIT STRING }
gustavatmel 1:9c5af431a1f1 187 */
gustavatmel 1:9c5af431a1f1 188 *--c = 0;
gustavatmel 1:9c5af431a1f1 189 len += 1;
gustavatmel 1:9c5af431a1f1 190
gustavatmel 1:9c5af431a1f1 191 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) );
gustavatmel 1:9c5af431a1f1 192 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_BIT_STRING ) );
gustavatmel 1:9c5af431a1f1 193
gustavatmel 1:9c5af431a1f1 194 if( ( ret = mbedtls_oid_get_oid_by_pk_alg( mbedtls_pk_get_type( key ),
gustavatmel 1:9c5af431a1f1 195 &oid, &oid_len ) ) != 0 )
gustavatmel 1:9c5af431a1f1 196 {
gustavatmel 1:9c5af431a1f1 197 return( ret );
gustavatmel 1:9c5af431a1f1 198 }
gustavatmel 1:9c5af431a1f1 199
gustavatmel 1:9c5af431a1f1 200 #if defined(MBEDTLS_ECP_C)
gustavatmel 1:9c5af431a1f1 201 if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_ECKEY )
gustavatmel 1:9c5af431a1f1 202 {
gustavatmel 1:9c5af431a1f1 203 MBEDTLS_ASN1_CHK_ADD( par_len, pk_write_ec_param( &c, buf, mbedtls_pk_ec( *key ) ) );
gustavatmel 1:9c5af431a1f1 204 }
gustavatmel 1:9c5af431a1f1 205 #endif
gustavatmel 1:9c5af431a1f1 206
gustavatmel 1:9c5af431a1f1 207 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_algorithm_identifier( &c, buf, oid, oid_len,
gustavatmel 1:9c5af431a1f1 208 par_len ) );
gustavatmel 1:9c5af431a1f1 209
gustavatmel 1:9c5af431a1f1 210 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) );
gustavatmel 1:9c5af431a1f1 211 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_CONSTRUCTED |
gustavatmel 1:9c5af431a1f1 212 MBEDTLS_ASN1_SEQUENCE ) );
gustavatmel 1:9c5af431a1f1 213
gustavatmel 1:9c5af431a1f1 214 return( (int) len );
gustavatmel 1:9c5af431a1f1 215 }
gustavatmel 1:9c5af431a1f1 216
gustavatmel 1:9c5af431a1f1 217 int mbedtls_pk_write_key_der( mbedtls_pk_context *key, unsigned char *buf, size_t size )
gustavatmel 1:9c5af431a1f1 218 {
gustavatmel 1:9c5af431a1f1 219 int ret;
gustavatmel 1:9c5af431a1f1 220 unsigned char *c = buf + size;
gustavatmel 1:9c5af431a1f1 221 size_t len = 0;
gustavatmel 1:9c5af431a1f1 222
gustavatmel 1:9c5af431a1f1 223 #if defined(MBEDTLS_RSA_C)
gustavatmel 1:9c5af431a1f1 224 if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_RSA )
gustavatmel 1:9c5af431a1f1 225 {
gustavatmel 1:9c5af431a1f1 226 mbedtls_mpi T; /* Temporary holding the exported parameters */
gustavatmel 1:9c5af431a1f1 227 mbedtls_rsa_context *rsa = mbedtls_pk_rsa( *key );
gustavatmel 1:9c5af431a1f1 228
gustavatmel 1:9c5af431a1f1 229 /*
gustavatmel 1:9c5af431a1f1 230 * Export the parameters one after another to avoid simultaneous copies.
gustavatmel 1:9c5af431a1f1 231 */
gustavatmel 1:9c5af431a1f1 232
gustavatmel 1:9c5af431a1f1 233 mbedtls_mpi_init( &T );
gustavatmel 1:9c5af431a1f1 234
gustavatmel 1:9c5af431a1f1 235 /* Export QP */
gustavatmel 1:9c5af431a1f1 236 if( ( ret = mbedtls_rsa_export_crt( rsa, NULL, NULL, &T ) ) != 0 ||
gustavatmel 1:9c5af431a1f1 237 ( ret = mbedtls_asn1_write_mpi( &c, buf, &T ) ) < 0 )
gustavatmel 1:9c5af431a1f1 238 goto end_of_export;
gustavatmel 1:9c5af431a1f1 239 len += ret;
gustavatmel 1:9c5af431a1f1 240
gustavatmel 1:9c5af431a1f1 241 /* Export DQ */
gustavatmel 1:9c5af431a1f1 242 if( ( ret = mbedtls_rsa_export_crt( rsa, NULL, &T, NULL ) ) != 0 ||
gustavatmel 1:9c5af431a1f1 243 ( ret = mbedtls_asn1_write_mpi( &c, buf, &T ) ) < 0 )
gustavatmel 1:9c5af431a1f1 244 goto end_of_export;
gustavatmel 1:9c5af431a1f1 245 len += ret;
gustavatmel 1:9c5af431a1f1 246
gustavatmel 1:9c5af431a1f1 247 /* Export DP */
gustavatmel 1:9c5af431a1f1 248 if( ( ret = mbedtls_rsa_export_crt( rsa, &T, NULL, NULL ) ) != 0 ||
gustavatmel 1:9c5af431a1f1 249 ( ret = mbedtls_asn1_write_mpi( &c, buf, &T ) ) < 0 )
gustavatmel 1:9c5af431a1f1 250 goto end_of_export;
gustavatmel 1:9c5af431a1f1 251 len += ret;
gustavatmel 1:9c5af431a1f1 252
gustavatmel 1:9c5af431a1f1 253 /* Export Q */
gustavatmel 1:9c5af431a1f1 254 if ( ( ret = mbedtls_rsa_export( rsa, NULL, NULL,
gustavatmel 1:9c5af431a1f1 255 &T, NULL, NULL ) ) != 0 ||
gustavatmel 1:9c5af431a1f1 256 ( ret = mbedtls_asn1_write_mpi( &c, buf, &T ) ) < 0 )
gustavatmel 1:9c5af431a1f1 257 goto end_of_export;
gustavatmel 1:9c5af431a1f1 258 len += ret;
gustavatmel 1:9c5af431a1f1 259
gustavatmel 1:9c5af431a1f1 260 /* Export P */
gustavatmel 1:9c5af431a1f1 261 if ( ( ret = mbedtls_rsa_export( rsa, NULL, &T,
gustavatmel 1:9c5af431a1f1 262 NULL, NULL, NULL ) ) != 0 ||
gustavatmel 1:9c5af431a1f1 263 ( ret = mbedtls_asn1_write_mpi( &c, buf, &T ) ) < 0 )
gustavatmel 1:9c5af431a1f1 264 goto end_of_export;
gustavatmel 1:9c5af431a1f1 265 len += ret;
gustavatmel 1:9c5af431a1f1 266
gustavatmel 1:9c5af431a1f1 267 /* Export D */
gustavatmel 1:9c5af431a1f1 268 if ( ( ret = mbedtls_rsa_export( rsa, NULL, NULL,
gustavatmel 1:9c5af431a1f1 269 NULL, &T, NULL ) ) != 0 ||
gustavatmel 1:9c5af431a1f1 270 ( ret = mbedtls_asn1_write_mpi( &c, buf, &T ) ) < 0 )
gustavatmel 1:9c5af431a1f1 271 goto end_of_export;
gustavatmel 1:9c5af431a1f1 272 len += ret;
gustavatmel 1:9c5af431a1f1 273
gustavatmel 1:9c5af431a1f1 274 /* Export E */
gustavatmel 1:9c5af431a1f1 275 if ( ( ret = mbedtls_rsa_export( rsa, NULL, NULL,
gustavatmel 1:9c5af431a1f1 276 NULL, NULL, &T ) ) != 0 ||
gustavatmel 1:9c5af431a1f1 277 ( ret = mbedtls_asn1_write_mpi( &c, buf, &T ) ) < 0 )
gustavatmel 1:9c5af431a1f1 278 goto end_of_export;
gustavatmel 1:9c5af431a1f1 279 len += ret;
gustavatmel 1:9c5af431a1f1 280
gustavatmel 1:9c5af431a1f1 281 /* Export N */
gustavatmel 1:9c5af431a1f1 282 if ( ( ret = mbedtls_rsa_export( rsa, &T, NULL,
gustavatmel 1:9c5af431a1f1 283 NULL, NULL, NULL ) ) != 0 ||
gustavatmel 1:9c5af431a1f1 284 ( ret = mbedtls_asn1_write_mpi( &c, buf, &T ) ) < 0 )
gustavatmel 1:9c5af431a1f1 285 goto end_of_export;
gustavatmel 1:9c5af431a1f1 286 len += ret;
gustavatmel 1:9c5af431a1f1 287
gustavatmel 1:9c5af431a1f1 288 end_of_export:
gustavatmel 1:9c5af431a1f1 289
gustavatmel 1:9c5af431a1f1 290 mbedtls_mpi_free( &T );
gustavatmel 1:9c5af431a1f1 291 if( ret < 0 )
gustavatmel 1:9c5af431a1f1 292 return( ret );
gustavatmel 1:9c5af431a1f1 293
gustavatmel 1:9c5af431a1f1 294 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_int( &c, buf, 0 ) );
gustavatmel 1:9c5af431a1f1 295 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) );
gustavatmel 1:9c5af431a1f1 296 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c,
gustavatmel 1:9c5af431a1f1 297 buf, MBEDTLS_ASN1_CONSTRUCTED |
gustavatmel 1:9c5af431a1f1 298 MBEDTLS_ASN1_SEQUENCE ) );
gustavatmel 1:9c5af431a1f1 299 }
gustavatmel 1:9c5af431a1f1 300 else
gustavatmel 1:9c5af431a1f1 301 #endif /* MBEDTLS_RSA_C */
gustavatmel 1:9c5af431a1f1 302 #if defined(MBEDTLS_ECP_C)
gustavatmel 1:9c5af431a1f1 303 if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_ECKEY )
gustavatmel 1:9c5af431a1f1 304 {
gustavatmel 1:9c5af431a1f1 305 mbedtls_ecp_keypair *ec = mbedtls_pk_ec( *key );
gustavatmel 1:9c5af431a1f1 306 size_t pub_len = 0, par_len = 0;
gustavatmel 1:9c5af431a1f1 307
gustavatmel 1:9c5af431a1f1 308 /*
gustavatmel 1:9c5af431a1f1 309 * RFC 5915, or SEC1 Appendix C.4
gustavatmel 1:9c5af431a1f1 310 *
gustavatmel 1:9c5af431a1f1 311 * ECPrivateKey ::= SEQUENCE {
gustavatmel 1:9c5af431a1f1 312 * version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1),
gustavatmel 1:9c5af431a1f1 313 * privateKey OCTET STRING,
gustavatmel 1:9c5af431a1f1 314 * parameters [0] ECParameters {{ NamedCurve }} OPTIONAL,
gustavatmel 1:9c5af431a1f1 315 * publicKey [1] BIT STRING OPTIONAL
gustavatmel 1:9c5af431a1f1 316 * }
gustavatmel 1:9c5af431a1f1 317 */
gustavatmel 1:9c5af431a1f1 318
gustavatmel 1:9c5af431a1f1 319 /* publicKey */
gustavatmel 1:9c5af431a1f1 320 MBEDTLS_ASN1_CHK_ADD( pub_len, pk_write_ec_pubkey( &c, buf, ec ) );
gustavatmel 1:9c5af431a1f1 321
gustavatmel 1:9c5af431a1f1 322 if( c - buf < 1 )
gustavatmel 1:9c5af431a1f1 323 return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
gustavatmel 1:9c5af431a1f1 324 *--c = 0;
gustavatmel 1:9c5af431a1f1 325 pub_len += 1;
gustavatmel 1:9c5af431a1f1 326
gustavatmel 1:9c5af431a1f1 327 MBEDTLS_ASN1_CHK_ADD( pub_len, mbedtls_asn1_write_len( &c, buf, pub_len ) );
gustavatmel 1:9c5af431a1f1 328 MBEDTLS_ASN1_CHK_ADD( pub_len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_BIT_STRING ) );
gustavatmel 1:9c5af431a1f1 329
gustavatmel 1:9c5af431a1f1 330 MBEDTLS_ASN1_CHK_ADD( pub_len, mbedtls_asn1_write_len( &c, buf, pub_len ) );
gustavatmel 1:9c5af431a1f1 331 MBEDTLS_ASN1_CHK_ADD( pub_len, mbedtls_asn1_write_tag( &c, buf,
gustavatmel 1:9c5af431a1f1 332 MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 1 ) );
gustavatmel 1:9c5af431a1f1 333 len += pub_len;
gustavatmel 1:9c5af431a1f1 334
gustavatmel 1:9c5af431a1f1 335 /* parameters */
gustavatmel 1:9c5af431a1f1 336 MBEDTLS_ASN1_CHK_ADD( par_len, pk_write_ec_param( &c, buf, ec ) );
gustavatmel 1:9c5af431a1f1 337
gustavatmel 1:9c5af431a1f1 338 MBEDTLS_ASN1_CHK_ADD( par_len, mbedtls_asn1_write_len( &c, buf, par_len ) );
gustavatmel 1:9c5af431a1f1 339 MBEDTLS_ASN1_CHK_ADD( par_len, mbedtls_asn1_write_tag( &c, buf,
gustavatmel 1:9c5af431a1f1 340 MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 0 ) );
gustavatmel 1:9c5af431a1f1 341 len += par_len;
gustavatmel 1:9c5af431a1f1 342
gustavatmel 1:9c5af431a1f1 343 /* privateKey: write as MPI then fix tag */
gustavatmel 1:9c5af431a1f1 344 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, buf, &ec->d ) );
gustavatmel 1:9c5af431a1f1 345 *c = MBEDTLS_ASN1_OCTET_STRING;
gustavatmel 1:9c5af431a1f1 346
gustavatmel 1:9c5af431a1f1 347 /* version */
gustavatmel 1:9c5af431a1f1 348 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_int( &c, buf, 1 ) );
gustavatmel 1:9c5af431a1f1 349
gustavatmel 1:9c5af431a1f1 350 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) );
gustavatmel 1:9c5af431a1f1 351 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_CONSTRUCTED |
gustavatmel 1:9c5af431a1f1 352 MBEDTLS_ASN1_SEQUENCE ) );
gustavatmel 1:9c5af431a1f1 353 }
gustavatmel 1:9c5af431a1f1 354 else
gustavatmel 1:9c5af431a1f1 355 #endif /* MBEDTLS_ECP_C */
gustavatmel 1:9c5af431a1f1 356 return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE );
gustavatmel 1:9c5af431a1f1 357
gustavatmel 1:9c5af431a1f1 358 return( (int) len );
gustavatmel 1:9c5af431a1f1 359 }
gustavatmel 1:9c5af431a1f1 360
gustavatmel 1:9c5af431a1f1 361 #if defined(MBEDTLS_PEM_WRITE_C)
gustavatmel 1:9c5af431a1f1 362
gustavatmel 1:9c5af431a1f1 363 #define PEM_BEGIN_PUBLIC_KEY "-----BEGIN PUBLIC KEY-----\n"
gustavatmel 1:9c5af431a1f1 364 #define PEM_END_PUBLIC_KEY "-----END PUBLIC KEY-----\n"
gustavatmel 1:9c5af431a1f1 365
gustavatmel 1:9c5af431a1f1 366 #define PEM_BEGIN_PRIVATE_KEY_RSA "-----BEGIN RSA PRIVATE KEY-----\n"
gustavatmel 1:9c5af431a1f1 367 #define PEM_END_PRIVATE_KEY_RSA "-----END RSA PRIVATE KEY-----\n"
gustavatmel 1:9c5af431a1f1 368 #define PEM_BEGIN_PRIVATE_KEY_EC "-----BEGIN EC PRIVATE KEY-----\n"
gustavatmel 1:9c5af431a1f1 369 #define PEM_END_PRIVATE_KEY_EC "-----END EC PRIVATE KEY-----\n"
gustavatmel 1:9c5af431a1f1 370
gustavatmel 1:9c5af431a1f1 371 /*
gustavatmel 1:9c5af431a1f1 372 * Max sizes of key per types. Shown as tag + len (+ content).
gustavatmel 1:9c5af431a1f1 373 */
gustavatmel 1:9c5af431a1f1 374
gustavatmel 1:9c5af431a1f1 375 #if defined(MBEDTLS_RSA_C)
gustavatmel 1:9c5af431a1f1 376 /*
gustavatmel 1:9c5af431a1f1 377 * RSA public keys:
gustavatmel 1:9c5af431a1f1 378 * SubjectPublicKeyInfo ::= SEQUENCE { 1 + 3
gustavatmel 1:9c5af431a1f1 379 * algorithm AlgorithmIdentifier, 1 + 1 (sequence)
gustavatmel 1:9c5af431a1f1 380 * + 1 + 1 + 9 (rsa oid)
gustavatmel 1:9c5af431a1f1 381 * + 1 + 1 (params null)
gustavatmel 1:9c5af431a1f1 382 * subjectPublicKey BIT STRING } 1 + 3 + (1 + below)
gustavatmel 1:9c5af431a1f1 383 * RSAPublicKey ::= SEQUENCE { 1 + 3
gustavatmel 1:9c5af431a1f1 384 * modulus INTEGER, -- n 1 + 3 + MPI_MAX + 1
gustavatmel 1:9c5af431a1f1 385 * publicExponent INTEGER -- e 1 + 3 + MPI_MAX + 1
gustavatmel 1:9c5af431a1f1 386 * }
gustavatmel 1:9c5af431a1f1 387 */
gustavatmel 1:9c5af431a1f1 388 #define RSA_PUB_DER_MAX_BYTES 38 + 2 * MBEDTLS_MPI_MAX_SIZE
gustavatmel 1:9c5af431a1f1 389
gustavatmel 1:9c5af431a1f1 390 /*
gustavatmel 1:9c5af431a1f1 391 * RSA private keys:
gustavatmel 1:9c5af431a1f1 392 * RSAPrivateKey ::= SEQUENCE { 1 + 3
gustavatmel 1:9c5af431a1f1 393 * version Version, 1 + 1 + 1
gustavatmel 1:9c5af431a1f1 394 * modulus INTEGER, 1 + 3 + MPI_MAX + 1
gustavatmel 1:9c5af431a1f1 395 * publicExponent INTEGER, 1 + 3 + MPI_MAX + 1
gustavatmel 1:9c5af431a1f1 396 * privateExponent INTEGER, 1 + 3 + MPI_MAX + 1
gustavatmel 1:9c5af431a1f1 397 * prime1 INTEGER, 1 + 3 + MPI_MAX / 2 + 1
gustavatmel 1:9c5af431a1f1 398 * prime2 INTEGER, 1 + 3 + MPI_MAX / 2 + 1
gustavatmel 1:9c5af431a1f1 399 * exponent1 INTEGER, 1 + 3 + MPI_MAX / 2 + 1
gustavatmel 1:9c5af431a1f1 400 * exponent2 INTEGER, 1 + 3 + MPI_MAX / 2 + 1
gustavatmel 1:9c5af431a1f1 401 * coefficient INTEGER, 1 + 3 + MPI_MAX / 2 + 1
gustavatmel 1:9c5af431a1f1 402 * otherPrimeInfos OtherPrimeInfos OPTIONAL 0 (not supported)
gustavatmel 1:9c5af431a1f1 403 * }
gustavatmel 1:9c5af431a1f1 404 */
gustavatmel 1:9c5af431a1f1 405 #define MPI_MAX_SIZE_2 MBEDTLS_MPI_MAX_SIZE / 2 + \
gustavatmel 1:9c5af431a1f1 406 MBEDTLS_MPI_MAX_SIZE % 2
gustavatmel 1:9c5af431a1f1 407 #define RSA_PRV_DER_MAX_BYTES 47 + 3 * MBEDTLS_MPI_MAX_SIZE \
gustavatmel 1:9c5af431a1f1 408 + 5 * MPI_MAX_SIZE_2
gustavatmel 1:9c5af431a1f1 409
gustavatmel 1:9c5af431a1f1 410 #else /* MBEDTLS_RSA_C */
gustavatmel 1:9c5af431a1f1 411
gustavatmel 1:9c5af431a1f1 412 #define RSA_PUB_DER_MAX_BYTES 0
gustavatmel 1:9c5af431a1f1 413 #define RSA_PRV_DER_MAX_BYTES 0
gustavatmel 1:9c5af431a1f1 414
gustavatmel 1:9c5af431a1f1 415 #endif /* MBEDTLS_RSA_C */
gustavatmel 1:9c5af431a1f1 416
gustavatmel 1:9c5af431a1f1 417 #if defined(MBEDTLS_ECP_C)
gustavatmel 1:9c5af431a1f1 418 /*
gustavatmel 1:9c5af431a1f1 419 * EC public keys:
gustavatmel 1:9c5af431a1f1 420 * SubjectPublicKeyInfo ::= SEQUENCE { 1 + 2
gustavatmel 1:9c5af431a1f1 421 * algorithm AlgorithmIdentifier, 1 + 1 (sequence)
gustavatmel 1:9c5af431a1f1 422 * + 1 + 1 + 7 (ec oid)
gustavatmel 1:9c5af431a1f1 423 * + 1 + 1 + 9 (namedCurve oid)
gustavatmel 1:9c5af431a1f1 424 * subjectPublicKey BIT STRING 1 + 2 + 1 [1]
gustavatmel 1:9c5af431a1f1 425 * + 1 (point format) [1]
gustavatmel 1:9c5af431a1f1 426 * + 2 * ECP_MAX (coords) [1]
gustavatmel 1:9c5af431a1f1 427 * }
gustavatmel 1:9c5af431a1f1 428 */
gustavatmel 1:9c5af431a1f1 429 #define ECP_PUB_DER_MAX_BYTES 30 + 2 * MBEDTLS_ECP_MAX_BYTES
gustavatmel 1:9c5af431a1f1 430
gustavatmel 1:9c5af431a1f1 431 /*
gustavatmel 1:9c5af431a1f1 432 * EC private keys:
gustavatmel 1:9c5af431a1f1 433 * ECPrivateKey ::= SEQUENCE { 1 + 2
gustavatmel 1:9c5af431a1f1 434 * version INTEGER , 1 + 1 + 1
gustavatmel 1:9c5af431a1f1 435 * privateKey OCTET STRING, 1 + 1 + ECP_MAX
gustavatmel 1:9c5af431a1f1 436 * parameters [0] ECParameters OPTIONAL, 1 + 1 + (1 + 1 + 9)
gustavatmel 1:9c5af431a1f1 437 * publicKey [1] BIT STRING OPTIONAL 1 + 2 + [1] above
gustavatmel 1:9c5af431a1f1 438 * }
gustavatmel 1:9c5af431a1f1 439 */
gustavatmel 1:9c5af431a1f1 440 #define ECP_PRV_DER_MAX_BYTES 29 + 3 * MBEDTLS_ECP_MAX_BYTES
gustavatmel 1:9c5af431a1f1 441
gustavatmel 1:9c5af431a1f1 442 #else /* MBEDTLS_ECP_C */
gustavatmel 1:9c5af431a1f1 443
gustavatmel 1:9c5af431a1f1 444 #define ECP_PUB_DER_MAX_BYTES 0
gustavatmel 1:9c5af431a1f1 445 #define ECP_PRV_DER_MAX_BYTES 0
gustavatmel 1:9c5af431a1f1 446
gustavatmel 1:9c5af431a1f1 447 #endif /* MBEDTLS_ECP_C */
gustavatmel 1:9c5af431a1f1 448
gustavatmel 1:9c5af431a1f1 449 #define PUB_DER_MAX_BYTES RSA_PUB_DER_MAX_BYTES > ECP_PUB_DER_MAX_BYTES ? \
gustavatmel 1:9c5af431a1f1 450 RSA_PUB_DER_MAX_BYTES : ECP_PUB_DER_MAX_BYTES
gustavatmel 1:9c5af431a1f1 451 #define PRV_DER_MAX_BYTES RSA_PRV_DER_MAX_BYTES > ECP_PRV_DER_MAX_BYTES ? \
gustavatmel 1:9c5af431a1f1 452 RSA_PRV_DER_MAX_BYTES : ECP_PRV_DER_MAX_BYTES
gustavatmel 1:9c5af431a1f1 453
gustavatmel 1:9c5af431a1f1 454 int mbedtls_pk_write_pubkey_pem( mbedtls_pk_context *key, unsigned char *buf, size_t size )
gustavatmel 1:9c5af431a1f1 455 {
gustavatmel 1:9c5af431a1f1 456 int ret;
gustavatmel 1:9c5af431a1f1 457 unsigned char output_buf[PUB_DER_MAX_BYTES];
gustavatmel 1:9c5af431a1f1 458 size_t olen = 0;
gustavatmel 1:9c5af431a1f1 459
gustavatmel 1:9c5af431a1f1 460 if( ( ret = mbedtls_pk_write_pubkey_der( key, output_buf,
gustavatmel 1:9c5af431a1f1 461 sizeof(output_buf) ) ) < 0 )
gustavatmel 1:9c5af431a1f1 462 {
gustavatmel 1:9c5af431a1f1 463 return( ret );
gustavatmel 1:9c5af431a1f1 464 }
gustavatmel 1:9c5af431a1f1 465
gustavatmel 1:9c5af431a1f1 466 if( ( ret = mbedtls_pem_write_buffer( PEM_BEGIN_PUBLIC_KEY, PEM_END_PUBLIC_KEY,
gustavatmel 1:9c5af431a1f1 467 output_buf + sizeof(output_buf) - ret,
gustavatmel 1:9c5af431a1f1 468 ret, buf, size, &olen ) ) != 0 )
gustavatmel 1:9c5af431a1f1 469 {
gustavatmel 1:9c5af431a1f1 470 return( ret );
gustavatmel 1:9c5af431a1f1 471 }
gustavatmel 1:9c5af431a1f1 472
gustavatmel 1:9c5af431a1f1 473 return( 0 );
gustavatmel 1:9c5af431a1f1 474 }
gustavatmel 1:9c5af431a1f1 475
gustavatmel 1:9c5af431a1f1 476 int mbedtls_pk_write_key_pem( mbedtls_pk_context *key, unsigned char *buf, size_t size )
gustavatmel 1:9c5af431a1f1 477 {
gustavatmel 1:9c5af431a1f1 478 int ret;
gustavatmel 1:9c5af431a1f1 479 unsigned char output_buf[PRV_DER_MAX_BYTES];
gustavatmel 1:9c5af431a1f1 480 const char *begin, *end;
gustavatmel 1:9c5af431a1f1 481 size_t olen = 0;
gustavatmel 1:9c5af431a1f1 482
gustavatmel 1:9c5af431a1f1 483 if( ( ret = mbedtls_pk_write_key_der( key, output_buf, sizeof(output_buf) ) ) < 0 )
gustavatmel 1:9c5af431a1f1 484 return( ret );
gustavatmel 1:9c5af431a1f1 485
gustavatmel 1:9c5af431a1f1 486 #if defined(MBEDTLS_RSA_C)
gustavatmel 1:9c5af431a1f1 487 if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_RSA )
gustavatmel 1:9c5af431a1f1 488 {
gustavatmel 1:9c5af431a1f1 489 begin = PEM_BEGIN_PRIVATE_KEY_RSA;
gustavatmel 1:9c5af431a1f1 490 end = PEM_END_PRIVATE_KEY_RSA;
gustavatmel 1:9c5af431a1f1 491 }
gustavatmel 1:9c5af431a1f1 492 else
gustavatmel 1:9c5af431a1f1 493 #endif
gustavatmel 1:9c5af431a1f1 494 #if defined(MBEDTLS_ECP_C)
gustavatmel 1:9c5af431a1f1 495 if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_ECKEY )
gustavatmel 1:9c5af431a1f1 496 {
gustavatmel 1:9c5af431a1f1 497 begin = PEM_BEGIN_PRIVATE_KEY_EC;
gustavatmel 1:9c5af431a1f1 498 end = PEM_END_PRIVATE_KEY_EC;
gustavatmel 1:9c5af431a1f1 499 }
gustavatmel 1:9c5af431a1f1 500 else
gustavatmel 1:9c5af431a1f1 501 #endif
gustavatmel 1:9c5af431a1f1 502 return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE );
gustavatmel 1:9c5af431a1f1 503
gustavatmel 1:9c5af431a1f1 504 if( ( ret = mbedtls_pem_write_buffer( begin, end,
gustavatmel 1:9c5af431a1f1 505 output_buf + sizeof(output_buf) - ret,
gustavatmel 1:9c5af431a1f1 506 ret, buf, size, &olen ) ) != 0 )
gustavatmel 1:9c5af431a1f1 507 {
gustavatmel 1:9c5af431a1f1 508 return( ret );
gustavatmel 1:9c5af431a1f1 509 }
gustavatmel 1:9c5af431a1f1 510
gustavatmel 1:9c5af431a1f1 511 return( 0 );
gustavatmel 1:9c5af431a1f1 512 }
gustavatmel 1:9c5af431a1f1 513 #endif /* MBEDTLS_PEM_WRITE_C */
gustavatmel 1:9c5af431a1f1 514
gustavatmel 1:9c5af431a1f1 515 #endif /* MBEDTLS_PK_WRITE_C */