-
Notifications
You must be signed in to change notification settings - Fork 48
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Pin mbed TLS branch and add mbed TLS utils folder (#7)
* Pin mbed TLS branch. * Add mbedtls utils folder. * Uncrustify and point to correct folder.
- Loading branch information
Showing
5 changed files
with
273 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,267 @@ | ||
/* | ||
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved | ||
* SPDX-License-Identifier: Apache-2.0 | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); you may | ||
* not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
* | ||
* This file is part of mbed TLS (https://tls.mbed.org) | ||
*/ | ||
|
||
/** | ||
* @file mbedtls_utils.c | ||
* @brief Helper functions originating from mbedTLS. | ||
*/ | ||
|
||
/* Standard includes. */ | ||
#include <string.h> | ||
|
||
/* mbedTLS includes. */ | ||
#include "mbedtls/base64.h" | ||
#include "mbedtls/rsa.h" | ||
#include "mbedtls/asn1.h" | ||
#include "mbedtls/platform_util.h" | ||
#include "mbedtls/oid.h" | ||
/*-----------------------------------------------------------*/ | ||
|
||
/* @brief Converts PEM documents into DER formatted byte arrays. | ||
* This is a helper function from mbedTLS util pem2der.c | ||
* (https://github.com/ARMmbed/mbedtls/blob/development/programs/util/pem2der.c#L75) | ||
* | ||
* \param pucInput[in] Pointer to PEM object | ||
* \param xLen[in] Length of PEM object | ||
* \param pucOutput[out] Pointer to buffer where DER oboject will be placed | ||
* \param pxOlen[in/out] Pointer to length of DER buffer. This value is updated | ||
* to contain the actual length of the converted DER object. | ||
* | ||
* \return 0 if successful. Negative if conversion failed. If buffer is not | ||
* large enough to hold converted object, pxOlen is still updated but -1 is returned. | ||
* | ||
*/ | ||
int convert_pem_to_der( const unsigned char * pucInput, | ||
size_t xLen, | ||
unsigned char * pucOutput, | ||
size_t * pxOlen ) | ||
{ | ||
int lRet; | ||
const unsigned char * pucS1; | ||
const unsigned char * pucS2; | ||
const unsigned char * pucEnd = pucInput + xLen; | ||
size_t xOtherLen = 0; | ||
|
||
pucS1 = ( unsigned char * ) strstr( ( const char * ) pucInput, "-----BEGIN" ); | ||
|
||
if( pucS1 == NULL ) | ||
{ | ||
return( -1 ); | ||
} | ||
|
||
pucS2 = ( unsigned char * ) strstr( ( const char * ) pucInput, "-----END" ); | ||
|
||
if( pucS2 == NULL ) | ||
{ | ||
return( -1 ); | ||
} | ||
|
||
pucS1 += 10; | ||
|
||
while( pucS1 < pucEnd && *pucS1 != '-' ) | ||
{ | ||
pucS1++; | ||
} | ||
|
||
while( pucS1 < pucEnd && *pucS1 == '-' ) | ||
{ | ||
pucS1++; | ||
} | ||
|
||
if( *pucS1 == '\r' ) | ||
{ | ||
pucS1++; | ||
} | ||
|
||
if( *pucS1 == '\n' ) | ||
{ | ||
pucS1++; | ||
} | ||
|
||
if( ( pucS2 <= pucS1 ) || ( pucS2 > pucEnd ) ) | ||
{ | ||
return( -1 ); | ||
} | ||
|
||
lRet = mbedtls_base64_decode( NULL, 0, &xOtherLen, ( const unsigned char * ) pucS1, pucS2 - pucS1 ); | ||
|
||
if( lRet == MBEDTLS_ERR_BASE64_INVALID_CHARACTER ) | ||
{ | ||
return( lRet ); | ||
} | ||
|
||
if( xOtherLen > *pxOlen ) | ||
{ | ||
return( -1 ); | ||
} | ||
|
||
if( ( lRet = mbedtls_base64_decode( pucOutput, xOtherLen, &xOtherLen, ( const unsigned char * ) pucS1, | ||
pucS2 - pucS1 ) ) != 0 ) | ||
{ | ||
return( lRet ); | ||
} | ||
|
||
*pxOlen = xOtherLen; | ||
|
||
return( 0 ); | ||
} | ||
/*-----------------------------------------------------------*/ | ||
|
||
|
||
/* This function is a modified version of the static function | ||
* rsa_rsassa_pkcs1_v15_encode() inside of rsa.c in mbedTLS. It has been extracted | ||
* so that FreeRTOS PKCS #11 libraries and testing may use it. */ | ||
|
||
/* Construct a PKCS v1.5 encoding of a hashed message | ||
* | ||
* This is used both for signature generation and verification. | ||
* | ||
* Parameters: | ||
* - md_alg: Identifies the hash algorithm used to generate the given hash; | ||
* MBEDTLS_MD_NONE if raw data is signed. | ||
* - hashlen: Length of hash in case hashlen is MBEDTLS_MD_NONE. | ||
* - hash: Buffer containing the hashed message or the raw data. | ||
* - dst_len: Length of the encoded message. | ||
* - dst: Buffer to hold the encoded message. | ||
* | ||
* Assumptions: | ||
* - hash has size hashlen if md_alg == MBEDTLS_MD_NONE. | ||
* - hash has size corresponding to md_alg if md_alg != MBEDTLS_MD_NONE. | ||
* - dst points to a buffer of size at least dst_len. | ||
* | ||
*/ | ||
|
||
/* \brief Formats cryptographically hashed data for RSA signing in accordance | ||
* with PKCS #1 version 1.5. | ||
* | ||
* Currently assumes SHA-256. | ||
*/ | ||
int PKI_RSA_RSASSA_PKCS1_v15_Encode( const unsigned char * hash, | ||
size_t dst_len, | ||
unsigned char * dst ) | ||
{ | ||
size_t oid_size = 0; | ||
size_t nb_pad = dst_len; | ||
unsigned char * p = dst; | ||
const char * oid = NULL; | ||
mbedtls_md_type_t md_alg = MBEDTLS_MD_SHA256; | ||
unsigned int hashlen = 0; | ||
|
||
const mbedtls_md_info_t * md_info = mbedtls_md_info_from_type( md_alg ); | ||
|
||
if( md_info == NULL ) | ||
{ | ||
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); | ||
} | ||
|
||
if( mbedtls_oid_get_oid_by_md( md_alg, &oid, &oid_size ) != 0 ) | ||
{ | ||
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); | ||
} | ||
|
||
hashlen = mbedtls_md_get_size( md_info ); | ||
|
||
/* Double-check that 8 + hashlen + oid_size can be used as a | ||
* 1-byte ASN.1 length encoding and that there's no overflow. */ | ||
if( ( 8 + hashlen + oid_size >= 0x80 ) || | ||
( 10 + hashlen < hashlen ) || | ||
( 10 + hashlen + oid_size < 10 + hashlen ) ) | ||
{ | ||
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); | ||
} | ||
|
||
/* | ||
* Static bounds check: | ||
* - Need 10 bytes for five tag-length pairs. | ||
* (Insist on 1-byte length encodings to protect against variants of | ||
* Bleichenbacher's forgery attack against lax PKCS#1v1.5 verification) | ||
* - Need hashlen bytes for hash | ||
* - Need oid_size bytes for hash alg OID. | ||
*/ | ||
if( nb_pad < 10 + hashlen + oid_size ) | ||
{ | ||
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); | ||
} | ||
|
||
nb_pad -= 10 + hashlen + oid_size; | ||
|
||
/* Need space for signature header and padding delimiter (3 bytes), | ||
* and 8 bytes for the minimal padding */ | ||
if( nb_pad < 3 + 8 ) | ||
{ | ||
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); | ||
} | ||
|
||
nb_pad -= 3; | ||
|
||
/* Now nb_pad is the amount of memory to be filled | ||
* with padding, and at least 8 bytes long. */ | ||
|
||
/* Write signature header and padding */ | ||
*p++ = 0; | ||
*p++ = MBEDTLS_RSA_SIGN; | ||
memset( p, 0xFF, nb_pad ); | ||
p += nb_pad; | ||
*p++ = 0; | ||
|
||
/* Are we signing raw data? */ | ||
if( md_alg == MBEDTLS_MD_NONE ) | ||
{ | ||
memcpy( p, hash, hashlen ); | ||
return( 0 ); | ||
} | ||
|
||
/* Signing hashed data, add corresponding ASN.1 structure | ||
* | ||
* DigestInfo ::= SEQUENCE { | ||
* digestAlgorithm DigestAlgorithmIdentifier, | ||
* digest Digest } | ||
* DigestAlgorithmIdentifier ::= AlgorithmIdentifier | ||
* Digest ::= OCTET STRING | ||
* | ||
* Schematic: | ||
* TAG-SEQ + LEN [ TAG-SEQ + LEN [ TAG-OID + LEN [ OID ] | ||
* TAG-NULL + LEN [ NULL ] ] | ||
* TAG-OCTET + LEN [ HASH ] ] | ||
*/ | ||
*p++ = MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED; | ||
*p++ = ( unsigned char ) ( 0x08 + oid_size + hashlen ); | ||
*p++ = MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED; | ||
*p++ = ( unsigned char ) ( 0x04 + oid_size ); | ||
*p++ = MBEDTLS_ASN1_OID; | ||
*p++ = ( unsigned char ) oid_size; | ||
memcpy( p, oid, oid_size ); | ||
p += oid_size; | ||
*p++ = MBEDTLS_ASN1_NULL; | ||
*p++ = 0x00; | ||
*p++ = MBEDTLS_ASN1_OCTET_STRING; | ||
*p++ = ( unsigned char ) hashlen; | ||
memcpy( p, hash, hashlen ); | ||
p += hashlen; | ||
|
||
/* Just a sanity-check, should be automatic | ||
* after the initial bounds check. */ | ||
if( p != dst + dst_len ) | ||
{ | ||
mbedtls_platform_zeroize( dst, dst_len ); | ||
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); | ||
} | ||
|
||
return( 0 ); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters