Example program to test AES-GCM functionality. Used for a workshop

Dependencies:   mbed

Committer:
HannesTschofenig
Date:
Thu Sep 27 06:34:22 2018 +0000
Revision:
0:796d0f61a05b
Example AES-GCM test program

Who changed what in which revision?

UserRevisionLine numberNew contents of line
HannesTschofenig 0:796d0f61a05b 1 /**
HannesTschofenig 0:796d0f61a05b 2 * \file pkcs11.c
HannesTschofenig 0:796d0f61a05b 3 *
HannesTschofenig 0:796d0f61a05b 4 * \brief Wrapper for PKCS#11 library libpkcs11-helper
HannesTschofenig 0:796d0f61a05b 5 *
HannesTschofenig 0:796d0f61a05b 6 * \author Adriaan de Jong <dejong@fox-it.com>
HannesTschofenig 0:796d0f61a05b 7 *
HannesTschofenig 0:796d0f61a05b 8 * Copyright (C) 2006-2014, Brainspark B.V.
HannesTschofenig 0:796d0f61a05b 9 *
HannesTschofenig 0:796d0f61a05b 10 * This file is part of PolarSSL (http://www.polarssl.org)
HannesTschofenig 0:796d0f61a05b 11 * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
HannesTschofenig 0:796d0f61a05b 12 *
HannesTschofenig 0:796d0f61a05b 13 * All rights reserved.
HannesTschofenig 0:796d0f61a05b 14 *
HannesTschofenig 0:796d0f61a05b 15 * This program is free software; you can redistribute it and/or modify
HannesTschofenig 0:796d0f61a05b 16 * it under the terms of the GNU General Public License as published by
HannesTschofenig 0:796d0f61a05b 17 * the Free Software Foundation; either version 2 of the License, or
HannesTschofenig 0:796d0f61a05b 18 * (at your option) any later version.
HannesTschofenig 0:796d0f61a05b 19 *
HannesTschofenig 0:796d0f61a05b 20 * This program is distributed in the hope that it will be useful,
HannesTschofenig 0:796d0f61a05b 21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
HannesTschofenig 0:796d0f61a05b 22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
HannesTschofenig 0:796d0f61a05b 23 * GNU General Public License for more details.
HannesTschofenig 0:796d0f61a05b 24 *
HannesTschofenig 0:796d0f61a05b 25 * You should have received a copy of the GNU General Public License along
HannesTschofenig 0:796d0f61a05b 26 * with this program; if not, write to the Free Software Foundation, Inc.,
HannesTschofenig 0:796d0f61a05b 27 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
HannesTschofenig 0:796d0f61a05b 28 */
HannesTschofenig 0:796d0f61a05b 29
HannesTschofenig 0:796d0f61a05b 30 #include "polarssl/pkcs11.h"
HannesTschofenig 0:796d0f61a05b 31
HannesTschofenig 0:796d0f61a05b 32 #if defined(POLARSSL_PKCS11_C)
HannesTschofenig 0:796d0f61a05b 33 #include "polarssl/md.h"
HannesTschofenig 0:796d0f61a05b 34 #include "polarssl/oid.h"
HannesTschofenig 0:796d0f61a05b 35 #include "polarssl/x509_crt.h"
HannesTschofenig 0:796d0f61a05b 36
HannesTschofenig 0:796d0f61a05b 37 #if defined(POLARSSL_PLATFORM_C)
HannesTschofenig 0:796d0f61a05b 38 #include "polarssl/platform.h"
HannesTschofenig 0:796d0f61a05b 39 #else
HannesTschofenig 0:796d0f61a05b 40 #include <stdlib.h>
HannesTschofenig 0:796d0f61a05b 41 #define polarssl_malloc malloc
HannesTschofenig 0:796d0f61a05b 42 #define polarssl_free free
HannesTschofenig 0:796d0f61a05b 43 #endif
HannesTschofenig 0:796d0f61a05b 44
HannesTschofenig 0:796d0f61a05b 45 int pkcs11_x509_cert_init( x509_crt *cert, pkcs11h_certificate_t pkcs11_cert )
HannesTschofenig 0:796d0f61a05b 46 {
HannesTschofenig 0:796d0f61a05b 47 int ret = 1;
HannesTschofenig 0:796d0f61a05b 48 unsigned char *cert_blob = NULL;
HannesTschofenig 0:796d0f61a05b 49 size_t cert_blob_size = 0;
HannesTschofenig 0:796d0f61a05b 50
HannesTschofenig 0:796d0f61a05b 51 if( cert == NULL )
HannesTschofenig 0:796d0f61a05b 52 {
HannesTschofenig 0:796d0f61a05b 53 ret = 2;
HannesTschofenig 0:796d0f61a05b 54 goto cleanup;
HannesTschofenig 0:796d0f61a05b 55 }
HannesTschofenig 0:796d0f61a05b 56
HannesTschofenig 0:796d0f61a05b 57 if( pkcs11h_certificate_getCertificateBlob( pkcs11_cert, NULL,
HannesTschofenig 0:796d0f61a05b 58 &cert_blob_size ) != CKR_OK )
HannesTschofenig 0:796d0f61a05b 59 {
HannesTschofenig 0:796d0f61a05b 60 ret = 3;
HannesTschofenig 0:796d0f61a05b 61 goto cleanup;
HannesTschofenig 0:796d0f61a05b 62 }
HannesTschofenig 0:796d0f61a05b 63
HannesTschofenig 0:796d0f61a05b 64 cert_blob = polarssl_malloc( cert_blob_size );
HannesTschofenig 0:796d0f61a05b 65 if( NULL == cert_blob )
HannesTschofenig 0:796d0f61a05b 66 {
HannesTschofenig 0:796d0f61a05b 67 ret = 4;
HannesTschofenig 0:796d0f61a05b 68 goto cleanup;
HannesTschofenig 0:796d0f61a05b 69 }
HannesTschofenig 0:796d0f61a05b 70
HannesTschofenig 0:796d0f61a05b 71 if( pkcs11h_certificate_getCertificateBlob( pkcs11_cert, cert_blob,
HannesTschofenig 0:796d0f61a05b 72 &cert_blob_size ) != CKR_OK )
HannesTschofenig 0:796d0f61a05b 73 {
HannesTschofenig 0:796d0f61a05b 74 ret = 5;
HannesTschofenig 0:796d0f61a05b 75 goto cleanup;
HannesTschofenig 0:796d0f61a05b 76 }
HannesTschofenig 0:796d0f61a05b 77
HannesTschofenig 0:796d0f61a05b 78 if( 0 != x509_crt_parse(cert, cert_blob, cert_blob_size ) )
HannesTschofenig 0:796d0f61a05b 79 {
HannesTschofenig 0:796d0f61a05b 80 ret = 6;
HannesTschofenig 0:796d0f61a05b 81 goto cleanup;
HannesTschofenig 0:796d0f61a05b 82 }
HannesTschofenig 0:796d0f61a05b 83
HannesTschofenig 0:796d0f61a05b 84 ret = 0;
HannesTschofenig 0:796d0f61a05b 85
HannesTschofenig 0:796d0f61a05b 86 cleanup:
HannesTschofenig 0:796d0f61a05b 87 if( NULL != cert_blob )
HannesTschofenig 0:796d0f61a05b 88 polarssl_free( cert_blob );
HannesTschofenig 0:796d0f61a05b 89
HannesTschofenig 0:796d0f61a05b 90 return ret;
HannesTschofenig 0:796d0f61a05b 91 }
HannesTschofenig 0:796d0f61a05b 92
HannesTschofenig 0:796d0f61a05b 93
HannesTschofenig 0:796d0f61a05b 94 int pkcs11_priv_key_init( pkcs11_context *priv_key,
HannesTschofenig 0:796d0f61a05b 95 pkcs11h_certificate_t pkcs11_cert )
HannesTschofenig 0:796d0f61a05b 96 {
HannesTschofenig 0:796d0f61a05b 97 int ret = 1;
HannesTschofenig 0:796d0f61a05b 98 x509_crt cert;
HannesTschofenig 0:796d0f61a05b 99
HannesTschofenig 0:796d0f61a05b 100 x509_crt_init( &cert );
HannesTschofenig 0:796d0f61a05b 101
HannesTschofenig 0:796d0f61a05b 102 if( priv_key == NULL )
HannesTschofenig 0:796d0f61a05b 103 goto cleanup;
HannesTschofenig 0:796d0f61a05b 104
HannesTschofenig 0:796d0f61a05b 105 if( 0 != pkcs11_x509_cert_init( &cert, pkcs11_cert ) )
HannesTschofenig 0:796d0f61a05b 106 goto cleanup;
HannesTschofenig 0:796d0f61a05b 107
HannesTschofenig 0:796d0f61a05b 108 priv_key->len = pk_get_len(&cert.pk);
HannesTschofenig 0:796d0f61a05b 109 priv_key->pkcs11h_cert = pkcs11_cert;
HannesTschofenig 0:796d0f61a05b 110
HannesTschofenig 0:796d0f61a05b 111 ret = 0;
HannesTschofenig 0:796d0f61a05b 112
HannesTschofenig 0:796d0f61a05b 113 cleanup:
HannesTschofenig 0:796d0f61a05b 114 x509_crt_free( &cert );
HannesTschofenig 0:796d0f61a05b 115
HannesTschofenig 0:796d0f61a05b 116 return ret;
HannesTschofenig 0:796d0f61a05b 117 }
HannesTschofenig 0:796d0f61a05b 118
HannesTschofenig 0:796d0f61a05b 119 void pkcs11_priv_key_free( pkcs11_context *priv_key )
HannesTschofenig 0:796d0f61a05b 120 {
HannesTschofenig 0:796d0f61a05b 121 if( NULL != priv_key )
HannesTschofenig 0:796d0f61a05b 122 pkcs11h_certificate_freeCertificate( priv_key->pkcs11h_cert );
HannesTschofenig 0:796d0f61a05b 123 }
HannesTschofenig 0:796d0f61a05b 124
HannesTschofenig 0:796d0f61a05b 125 int pkcs11_decrypt( pkcs11_context *ctx,
HannesTschofenig 0:796d0f61a05b 126 int mode, size_t *olen,
HannesTschofenig 0:796d0f61a05b 127 const unsigned char *input,
HannesTschofenig 0:796d0f61a05b 128 unsigned char *output,
HannesTschofenig 0:796d0f61a05b 129 size_t output_max_len )
HannesTschofenig 0:796d0f61a05b 130 {
HannesTschofenig 0:796d0f61a05b 131 size_t input_len, output_len;
HannesTschofenig 0:796d0f61a05b 132
HannesTschofenig 0:796d0f61a05b 133 if( NULL == ctx )
HannesTschofenig 0:796d0f61a05b 134 return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
HannesTschofenig 0:796d0f61a05b 135
HannesTschofenig 0:796d0f61a05b 136 if( RSA_PRIVATE != mode )
HannesTschofenig 0:796d0f61a05b 137 return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
HannesTschofenig 0:796d0f61a05b 138
HannesTschofenig 0:796d0f61a05b 139 output_len = input_len = ctx->len;
HannesTschofenig 0:796d0f61a05b 140
HannesTschofenig 0:796d0f61a05b 141 if( input_len < 16 || input_len > output_max_len )
HannesTschofenig 0:796d0f61a05b 142 return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
HannesTschofenig 0:796d0f61a05b 143
HannesTschofenig 0:796d0f61a05b 144 /* Determine size of output buffer */
HannesTschofenig 0:796d0f61a05b 145 if( pkcs11h_certificate_decryptAny( ctx->pkcs11h_cert, CKM_RSA_PKCS, input,
HannesTschofenig 0:796d0f61a05b 146 input_len, NULL, &output_len ) != CKR_OK )
HannesTschofenig 0:796d0f61a05b 147 {
HannesTschofenig 0:796d0f61a05b 148 return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
HannesTschofenig 0:796d0f61a05b 149 }
HannesTschofenig 0:796d0f61a05b 150
HannesTschofenig 0:796d0f61a05b 151 if( output_len > output_max_len )
HannesTschofenig 0:796d0f61a05b 152 return( POLARSSL_ERR_RSA_OUTPUT_TOO_LARGE );
HannesTschofenig 0:796d0f61a05b 153
HannesTschofenig 0:796d0f61a05b 154 if( pkcs11h_certificate_decryptAny( ctx->pkcs11h_cert, CKM_RSA_PKCS, input,
HannesTschofenig 0:796d0f61a05b 155 input_len, output, &output_len ) != CKR_OK )
HannesTschofenig 0:796d0f61a05b 156 {
HannesTschofenig 0:796d0f61a05b 157 return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
HannesTschofenig 0:796d0f61a05b 158 }
HannesTschofenig 0:796d0f61a05b 159 *olen = output_len;
HannesTschofenig 0:796d0f61a05b 160 return( 0 );
HannesTschofenig 0:796d0f61a05b 161 }
HannesTschofenig 0:796d0f61a05b 162
HannesTschofenig 0:796d0f61a05b 163 int pkcs11_sign( pkcs11_context *ctx,
HannesTschofenig 0:796d0f61a05b 164 int mode,
HannesTschofenig 0:796d0f61a05b 165 md_type_t md_alg,
HannesTschofenig 0:796d0f61a05b 166 unsigned int hashlen,
HannesTschofenig 0:796d0f61a05b 167 const unsigned char *hash,
HannesTschofenig 0:796d0f61a05b 168 unsigned char *sig )
HannesTschofenig 0:796d0f61a05b 169 {
HannesTschofenig 0:796d0f61a05b 170 size_t sig_len = 0, asn_len = 0, oid_size = 0;
HannesTschofenig 0:796d0f61a05b 171 unsigned char *p = sig;
HannesTschofenig 0:796d0f61a05b 172 const char *oid;
HannesTschofenig 0:796d0f61a05b 173
HannesTschofenig 0:796d0f61a05b 174 if( NULL == ctx )
HannesTschofenig 0:796d0f61a05b 175 return POLARSSL_ERR_RSA_BAD_INPUT_DATA;
HannesTschofenig 0:796d0f61a05b 176
HannesTschofenig 0:796d0f61a05b 177 if( RSA_PRIVATE != mode )
HannesTschofenig 0:796d0f61a05b 178 return POLARSSL_ERR_RSA_BAD_INPUT_DATA;
HannesTschofenig 0:796d0f61a05b 179
HannesTschofenig 0:796d0f61a05b 180 if( md_alg != POLARSSL_MD_NONE )
HannesTschofenig 0:796d0f61a05b 181 {
HannesTschofenig 0:796d0f61a05b 182 const md_info_t *md_info = md_info_from_type( md_alg );
HannesTschofenig 0:796d0f61a05b 183 if( md_info == NULL )
HannesTschofenig 0:796d0f61a05b 184 return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
HannesTschofenig 0:796d0f61a05b 185
HannesTschofenig 0:796d0f61a05b 186 if( oid_get_oid_by_md( md_alg, &oid, &oid_size ) != 0 )
HannesTschofenig 0:796d0f61a05b 187 return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
HannesTschofenig 0:796d0f61a05b 188
HannesTschofenig 0:796d0f61a05b 189 hashlen = md_get_size( md_info );
HannesTschofenig 0:796d0f61a05b 190 asn_len = 10 + oid_size;
HannesTschofenig 0:796d0f61a05b 191 }
HannesTschofenig 0:796d0f61a05b 192
HannesTschofenig 0:796d0f61a05b 193 sig_len = ctx->len;
HannesTschofenig 0:796d0f61a05b 194 if ( hashlen > sig_len || asn_len > sig_len ||
HannesTschofenig 0:796d0f61a05b 195 hashlen + asn_len > sig_len )
HannesTschofenig 0:796d0f61a05b 196 {
HannesTschofenig 0:796d0f61a05b 197 return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
HannesTschofenig 0:796d0f61a05b 198 }
HannesTschofenig 0:796d0f61a05b 199
HannesTschofenig 0:796d0f61a05b 200 if( md_alg != POLARSSL_MD_NONE)
HannesTschofenig 0:796d0f61a05b 201 {
HannesTschofenig 0:796d0f61a05b 202 /*
HannesTschofenig 0:796d0f61a05b 203 * DigestInfo ::= SEQUENCE {
HannesTschofenig 0:796d0f61a05b 204 * digestAlgorithm DigestAlgorithmIdentifier,
HannesTschofenig 0:796d0f61a05b 205 * digest Digest }
HannesTschofenig 0:796d0f61a05b 206 *
HannesTschofenig 0:796d0f61a05b 207 * DigestAlgorithmIdentifier ::= AlgorithmIdentifier
HannesTschofenig 0:796d0f61a05b 208 *
HannesTschofenig 0:796d0f61a05b 209 * Digest ::= OCTET STRING
HannesTschofenig 0:796d0f61a05b 210 */
HannesTschofenig 0:796d0f61a05b 211 *p++ = ASN1_SEQUENCE | ASN1_CONSTRUCTED;
HannesTschofenig 0:796d0f61a05b 212 *p++ = (unsigned char) ( 0x08 + oid_size + hashlen );
HannesTschofenig 0:796d0f61a05b 213 *p++ = ASN1_SEQUENCE | ASN1_CONSTRUCTED;
HannesTschofenig 0:796d0f61a05b 214 *p++ = (unsigned char) ( 0x04 + oid_size );
HannesTschofenig 0:796d0f61a05b 215 *p++ = ASN1_OID;
HannesTschofenig 0:796d0f61a05b 216 *p++ = oid_size & 0xFF;
HannesTschofenig 0:796d0f61a05b 217 memcpy( p, oid, oid_size );
HannesTschofenig 0:796d0f61a05b 218 p += oid_size;
HannesTschofenig 0:796d0f61a05b 219 *p++ = ASN1_NULL;
HannesTschofenig 0:796d0f61a05b 220 *p++ = 0x00;
HannesTschofenig 0:796d0f61a05b 221 *p++ = ASN1_OCTET_STRING;
HannesTschofenig 0:796d0f61a05b 222 *p++ = hashlen;
HannesTschofenig 0:796d0f61a05b 223 }
HannesTschofenig 0:796d0f61a05b 224
HannesTschofenig 0:796d0f61a05b 225 memcpy( p, hash, hashlen );
HannesTschofenig 0:796d0f61a05b 226
HannesTschofenig 0:796d0f61a05b 227 if( pkcs11h_certificate_signAny( ctx->pkcs11h_cert, CKM_RSA_PKCS, sig,
HannesTschofenig 0:796d0f61a05b 228 asn_len + hashlen, sig, &sig_len ) != CKR_OK )
HannesTschofenig 0:796d0f61a05b 229 {
HannesTschofenig 0:796d0f61a05b 230 return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
HannesTschofenig 0:796d0f61a05b 231 }
HannesTschofenig 0:796d0f61a05b 232
HannesTschofenig 0:796d0f61a05b 233 return( 0 );
HannesTschofenig 0:796d0f61a05b 234 }
HannesTschofenig 0:796d0f61a05b 235
HannesTschofenig 0:796d0f61a05b 236 #endif /* defined(POLARSSL_PKCS11_C) */
HannesTschofenig 0:796d0f61a05b 237
HannesTschofenig 0:796d0f61a05b 238