I am creating a demo program to explain how to import OpenSSL generated Private key, Signing message, extracting public part and Independently Verifying a messege digest using RSA.N, RSA.E, Signature, Digest.
While am trying to pass public parameters as char, I am getting following error.
failed! mbedtls_rsa_complete: -4080
WHile passing mbedtls_mpi* the same program is working fine. Any help would be appreciated. [snippet given below]
Thanks,
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <mbedtls/md.h>
#include <mbedtls/pk.h>
#include <mbedtls/rsa.h>
typedef struct RsaPublic
{
mbedtls_mpi N;
mbedtls_mpi E;
}RsaPublic_t;
typedef struct Signature
{
uint8_t Signature[MBEDTLS_MPI_MAX_SIZE];
size_t SignatureLength;
uint8_t Digest[MBEDTLS_MD_MAX_SIZE];
size_t DigestLength;
mbedtls_pk_context PK;
RsaPublic_t Public;
}Signature_t;
void SignatureInit( Signature_t *CTX )
{
if( NULL == CTX )
{
return;
}
memset( CTX, 0x00, sizeof(Signature_t) );
mbedtls_pk_init( &CTX->PK );
mbedtls_mpi_init( &CTX->Public.N );
mbedtls_mpi_init( &CTX->Public.E );
}
int HexDump( uint8_t *Stream, size_t StreamLength )
{
int i;
for( i=0; i < StreamLength; i++ )
{
printf("%02X", 0xff & Stream[i]);
}
printf("\r\n");
return i;
}
int ReadKeyFile( Signature_t *CTX, uint8_t *FileName, uint8_t *Password )
{
return ( mbedtls_pk_parse_keyfile( &CTX->PK, FileName, Password ) );
}
int GetFileDigest( Signature_t *CTX, uint8_t *FileName )
{
CTX->DigestLength = 32;
return( mbedtls_md_file( mbedtls_md_info_from_type( MBEDTLS_MD_SHA256 ),
FileName, CTX->Digest ) );
}
int SignDigest( Signature_t *CTX )
{
mbedtls_rsa_context *rsa = mbedtls_pk_rsa(CTX->PK);
CTX->SignatureLength = rsa->len;
return( mbedtls_rsa_pkcs1_sign( rsa, NULL, NULL, MBEDTLS_RSA_PRIVATE, MBEDTLS_MD_SHA256,
MBEDTLS_MD_MAX_SIZE, CTX->Digest, CTX->Signature ) );
}
int ExportPublic( Signature_t *CTX )
{
mbedtls_rsa_context *rsa = mbedtls_pk_rsa(CTX->PK);
return( mbedtls_rsa_export( rsa, &CTX->Public.N, NULL, NULL, NULL, &CTX->Public.E ) );
}
int VerifyOnly( uint8_t *Digest, size_t DigestLength,
uint8_t *Signature, size_t SignatureLength,
// uint8_t *N, size_t N_len, uint8_t *E, size_t E_len )
// Problem while using above line
mbedtls_mpi *N, mbedtls_mpi *E )
{
int ret = EXIT_SUCCESS;
/* Verify uses it's RSA Context */
mbedtls_rsa_context rsa;
/* Initialize RSA Context */
mbedtls_rsa_init( &rsa, MBEDTLS_RSA_PKCS_V15, 0 );
/* Import RSA Publc Parameters */
//if( ret = mbedtls_rsa_import_raw( &rsa, N, N_len, NULL, 0, NULL, 0, NULL, 0, E, E_len ) )
// Problem while using above line
if( ret = mbedtls_rsa_import( &rsa, N, NULL, NULL, NULL, E ) )
{
printf( "failed! mbedtls_rsa_import_raw: -%04x", -ret );
return (ret);
}
if( ret = mbedtls_rsa_complete( &rsa ) )
{
printf( "failed! mbedtls_rsa_complete: -%04x", -ret );
return (ret);
}
return( mbedtls_rsa_pkcs1_verify( &rsa, NULL, NULL, MBEDTLS_RSA_PUBLIC, MBEDTLS_MD_SHA256,
32, Digest, Signature ) );
}
int main()
{
int ret = EXIT_SUCCESS;
Signature_t S1;
SignatureInit( &S1 );
// Can ready any PEM formatted RSA Key file here
//if( ret = ReadKeyFile( &S1, "private.key", NULL ) )
if( ret = ReadKeyFile( &S1, "p.k", NULL ) )
{
printf("... failed! ReadKeyFile -%04x", -ret);
return ret;
}
if( ret = GetFileDigest( &S1, "Message.txt" ) )
{
printf("... failed! DigestFile -%04x", -ret);
return ret;
}
printf("Message Digest:\r\n");
HexDump( S1.Digest, MBEDTLS_MD_MAX_SIZE/2 );
if( ret = SignDigest( &S1 ) )
{
printf("... failed! ReadMsgFile -%04x", -ret);
return ret;
}
printf("Signature:\r\n");
HexDump( S1.Signature, S1.SignatureLength );
if( ret = ExportPublic( &S1 ) )
{
printf("... failed! ExportPublic -%04x", -ret);
return ret;
}
mbedtls_mpi_write_file( "N:", &S1.Public.N, 16, NULL );
mbedtls_mpi_write_file( "E:", &S1.Public.E, 16, NULL );
uint8_t _N[1024]; size_t _N_len;
uint8_t _E[1024]; size_t _E_len;
mbedtls_mpi_write_string( &S1.Public.N, 16, _N, 1024, &_N_len );
mbedtls_mpi_write_string( &S1.Public.E, 16, _E, 1024, &_E_len );
printf("Independent Verification Begin ");
if( ret = VerifyOnly( S1.Digest, S1.DigestLength,
S1.Signature, S1.SignatureLength,
&S1.Public.N, &S1.Public.E ) )
// _N, _N_len, _E, _E_len ) )
{
printf("... failed! VerifyOnly -%04x", -ret);
return ret;
}
printf("Done!\r\n");
return(ret);
}