1  /*
2   *  RSASSA-PSS/SHA-256 signature creation program
3   *
4   *  Copyright The Mbed TLS Contributors
5   *  SPDX-License-Identifier: Apache-2.0
6   *
7   *  Licensed under the Apache License, Version 2.0 (the "License"); you may
8   *  not use this file except in compliance with the License.
9   *  You may obtain a copy of the License at
10   *
11   *  http://www.apache.org/licenses/LICENSE-2.0
12   *
13   *  Unless required by applicable law or agreed to in writing, software
14   *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15   *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   *  See the License for the specific language governing permissions and
17   *  limitations under the License.
18   */
19  
20  #include "mbedtls/build_info.h"
21  
22  #if defined(MBEDTLS_PLATFORM_C)
23  #include "mbedtls/platform.h"
24  #else
25  #include <stdio.h>
26  #include <stdlib.h>
27  #define mbedtls_snprintf        snprintf
28  #define mbedtls_printf          printf
29  #define mbedtls_exit            exit
30  #define MBEDTLS_EXIT_SUCCESS    EXIT_SUCCESS
31  #define MBEDTLS_EXIT_FAILURE    EXIT_FAILURE
32  #endif /* MBEDTLS_PLATFORM_C */
33  
34  #if !defined(MBEDTLS_MD_C) || !defined(MBEDTLS_ENTROPY_C) ||  \
35      !defined(MBEDTLS_RSA_C) || !defined(MBEDTLS_SHA256_C) ||        \
36      !defined(MBEDTLS_PK_PARSE_C) || !defined(MBEDTLS_FS_IO) ||    \
37      !defined(MBEDTLS_CTR_DRBG_C)
main(void)38  int main( void )
39  {
40      mbedtls_printf("MBEDTLS_MD_C and/or MBEDTLS_ENTROPY_C and/or "
41             "MBEDTLS_RSA_C and/or MBEDTLS_SHA256_C and/or "
42             "MBEDTLS_PK_PARSE_C and/or MBEDTLS_FS_IO and/or "
43             "MBEDTLS_CTR_DRBG_C not defined.\n");
44      mbedtls_exit( 0 );
45  }
46  #else
47  
48  #include "mbedtls/entropy.h"
49  #include "mbedtls/ctr_drbg.h"
50  #include "mbedtls/md.h"
51  #include "mbedtls/rsa.h"
52  #include "mbedtls/pk.h"
53  
54  #include <stdio.h>
55  #include <string.h>
56  
57  
main(int argc,char * argv[])58  int main( int argc, char *argv[] )
59  {
60      FILE *f;
61      int ret = 1;
62      int exit_code = MBEDTLS_EXIT_FAILURE;
63      mbedtls_pk_context pk;
64      mbedtls_entropy_context entropy;
65      mbedtls_ctr_drbg_context ctr_drbg;
66      unsigned char hash[32];
67      unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
68      char filename[512];
69      const char *pers = "rsa_sign_pss";
70      size_t olen = 0;
71  
72      mbedtls_entropy_init( &entropy );
73      mbedtls_pk_init( &pk );
74      mbedtls_ctr_drbg_init( &ctr_drbg );
75  
76      if( argc != 3 )
77      {
78          mbedtls_printf( "usage: rsa_sign_pss <key_file> <filename>\n" );
79  
80  #if defined(_WIN32)
81          mbedtls_printf( "\n" );
82  #endif
83  
84          goto exit;
85      }
86  
87      mbedtls_printf( "\n  . Seeding the random number generator..." );
88      fflush( stdout );
89  
90      if( ( ret = mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func, &entropy,
91                                 (const unsigned char *) pers,
92                                 strlen( pers ) ) ) != 0 )
93      {
94          mbedtls_printf( " failed\n  ! mbedtls_ctr_drbg_seed returned %d\n", ret );
95          goto exit;
96      }
97  
98      mbedtls_printf( "\n  . Reading private key from '%s'", argv[1] );
99      fflush( stdout );
100  
101      if( ( ret = mbedtls_pk_parse_keyfile( &pk, argv[1], "",
102                      mbedtls_ctr_drbg_random, &ctr_drbg ) ) != 0 )
103      {
104          mbedtls_printf( " failed\n  ! Could not read key from '%s'\n", argv[1] );
105          mbedtls_printf( "  ! mbedtls_pk_parse_public_keyfile returned %d\n\n", ret );
106          goto exit;
107      }
108  
109      if( !mbedtls_pk_can_do( &pk, MBEDTLS_PK_RSA ) )
110      {
111          mbedtls_printf( " failed\n  ! Key is not an RSA key\n" );
112          goto exit;
113      }
114  
115      if( ( ret = mbedtls_rsa_set_padding( mbedtls_pk_rsa( pk ),
116                                           MBEDTLS_RSA_PKCS_V21,
117                                           MBEDTLS_MD_SHA256 ) ) != 0 )
118      {
119          mbedtls_printf( " failed\n  ! Padding not supported\n" );
120          goto exit;
121      }
122  
123      /*
124       * Compute the SHA-256 hash of the input file,
125       * then calculate the RSA signature of the hash.
126       */
127      mbedtls_printf( "\n  . Generating the RSA/SHA-256 signature" );
128      fflush( stdout );
129  
130      if( ( ret = mbedtls_md_file(
131                      mbedtls_md_info_from_type( MBEDTLS_MD_SHA256 ),
132                      argv[2], hash ) ) != 0 )
133      {
134          mbedtls_printf( " failed\n  ! Could not open or read %s\n\n", argv[2] );
135          goto exit;
136      }
137  
138      if( ( ret = mbedtls_pk_sign( &pk, MBEDTLS_MD_SHA256, hash, 0,
139                                   buf, sizeof( buf ), &olen,
140                                   mbedtls_ctr_drbg_random, &ctr_drbg ) ) != 0 )
141      {
142          mbedtls_printf( " failed\n  ! mbedtls_pk_sign returned %d\n\n", ret );
143          goto exit;
144      }
145  
146      /*
147       * Write the signature into <filename>.sig
148       */
149      mbedtls_snprintf( filename, 512, "%s.sig", argv[2] );
150  
151      if( ( f = fopen( filename, "wb+" ) ) == NULL )
152      {
153          mbedtls_printf( " failed\n  ! Could not create %s\n\n", filename );
154          goto exit;
155      }
156  
157      if( fwrite( buf, 1, olen, f ) != olen )
158      {
159          mbedtls_printf( "failed\n  ! fwrite failed\n\n" );
160          fclose( f );
161          goto exit;
162      }
163  
164      fclose( f );
165  
166      mbedtls_printf( "\n  . Done (created \"%s\")\n\n", filename );
167  
168      exit_code = MBEDTLS_EXIT_SUCCESS;
169  
170  exit:
171      mbedtls_pk_free( &pk );
172      mbedtls_ctr_drbg_free( &ctr_drbg );
173      mbedtls_entropy_free( &entropy );
174  
175  #if defined(_WIN32)
176      mbedtls_printf( "  + Press Enter to exit this program.\n" );
177      fflush( stdout ); getchar();
178  #endif
179  
180      mbedtls_exit( exit_code );
181  }
182  #endif /* MBEDTLS_BIGNUM_C && MBEDTLS_ENTROPY_C && MBEDTLS_RSA_C &&
183            MBEDTLS_SHA256_C && MBEDTLS_PK_PARSE_C && MBEDTLS_FS_IO &&
184            MBEDTLS_CTR_DRBG_C */
185