1 /*
2  *  RSA simple data encryption 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 #include "mbedtls/platform.h"
23 
24 #if defined(MBEDTLS_BIGNUM_C) && defined(MBEDTLS_RSA_C) && \
25     defined(MBEDTLS_ENTROPY_C) && defined(MBEDTLS_FS_IO) && \
26     defined(MBEDTLS_CTR_DRBG_C)
27 #include "mbedtls/rsa.h"
28 #include "mbedtls/entropy.h"
29 #include "mbedtls/ctr_drbg.h"
30 
31 #include <string.h>
32 #endif
33 
34 #if !defined(MBEDTLS_BIGNUM_C) || !defined(MBEDTLS_RSA_C) ||  \
35     !defined(MBEDTLS_ENTROPY_C) || !defined(MBEDTLS_FS_IO) || \
36     !defined(MBEDTLS_CTR_DRBG_C)
main(void)37 int main( void )
38 {
39     mbedtls_printf("MBEDTLS_BIGNUM_C and/or MBEDTLS_RSA_C and/or "
40            "MBEDTLS_ENTROPY_C and/or MBEDTLS_FS_IO and/or "
41            "MBEDTLS_CTR_DRBG_C not defined.\n");
42     mbedtls_exit( 0 );
43 }
44 #else
45 
46 
main(int argc,char * argv[])47 int main( int argc, char *argv[] )
48 {
49     FILE *f;
50     int ret = 1;
51     int exit_code = MBEDTLS_EXIT_FAILURE;
52     size_t i;
53     mbedtls_rsa_context rsa;
54     mbedtls_entropy_context entropy;
55     mbedtls_ctr_drbg_context ctr_drbg;
56     unsigned char input[1024];
57     unsigned char buf[512];
58     const char *pers = "rsa_encrypt";
59     mbedtls_mpi N, E;
60 
61     if( argc != 2 )
62     {
63         mbedtls_printf( "usage: rsa_encrypt <string of max 100 characters>\n" );
64 
65 #if defined(_WIN32)
66         mbedtls_printf( "\n" );
67 #endif
68 
69         mbedtls_exit( exit_code );
70     }
71 
72     mbedtls_printf( "\n  . Seeding the random number generator..." );
73     fflush( stdout );
74 
75     mbedtls_mpi_init( &N ); mbedtls_mpi_init( &E );
76     mbedtls_rsa_init( &rsa );
77     mbedtls_ctr_drbg_init( &ctr_drbg );
78     mbedtls_entropy_init( &entropy );
79 
80     ret = mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func,
81                                  &entropy, (const unsigned char *) pers,
82                                  strlen( pers ) );
83     if( ret != 0 )
84     {
85         mbedtls_printf( " failed\n  ! mbedtls_ctr_drbg_seed returned %d\n",
86                         ret );
87         goto exit;
88     }
89 
90     mbedtls_printf( "\n  . Reading public key from rsa_pub.txt" );
91     fflush( stdout );
92 
93     if( ( f = fopen( "rsa_pub.txt", "rb" ) ) == NULL )
94     {
95         mbedtls_printf( " failed\n  ! Could not open rsa_pub.txt\n" \
96                 "  ! Please run rsa_genkey first\n\n" );
97         goto exit;
98     }
99 
100     if( ( ret = mbedtls_mpi_read_file( &N, 16, f ) ) != 0 ||
101         ( ret = mbedtls_mpi_read_file( &E, 16, f ) ) != 0 )
102     {
103         mbedtls_printf( " failed\n  ! mbedtls_mpi_read_file returned %d\n\n",
104                         ret );
105         fclose( f );
106         goto exit;
107     }
108     fclose( f );
109 
110     if( ( ret = mbedtls_rsa_import( &rsa, &N, NULL, NULL, NULL, &E ) ) != 0 )
111     {
112         mbedtls_printf( " failed\n  ! mbedtls_rsa_import returned %d\n\n",
113                         ret );
114         goto exit;
115     }
116 
117     if( strlen( argv[1] ) > 100 )
118     {
119         mbedtls_printf( " Input data larger than 100 characters.\n\n" );
120         goto exit;
121     }
122 
123     memcpy( input, argv[1], strlen( argv[1] ) );
124 
125     /*
126      * Calculate the RSA encryption of the hash.
127      */
128     mbedtls_printf( "\n  . Generating the RSA encrypted value" );
129     fflush( stdout );
130 
131     ret = mbedtls_rsa_pkcs1_encrypt( &rsa, mbedtls_ctr_drbg_random,
132                                      &ctr_drbg, strlen( argv[1] ), input, buf );
133     if( ret != 0 )
134     {
135         mbedtls_printf( " failed\n  ! mbedtls_rsa_pkcs1_encrypt returned %d\n\n",
136                         ret );
137         goto exit;
138     }
139 
140     /*
141      * Write the signature into result-enc.txt
142      */
143     if( ( f = fopen( "result-enc.txt", "wb+" ) ) == NULL )
144     {
145         mbedtls_printf( " failed\n  ! Could not create %s\n\n", "result-enc.txt" );
146         goto exit;
147     }
148 
149     for( i = 0; i < rsa.MBEDTLS_PRIVATE(len); i++ )
150         mbedtls_fprintf( f, "%02X%s", buf[i],
151                  ( i + 1 ) % 16 == 0 ? "\r\n" : " " );
152 
153     fclose( f );
154 
155     mbedtls_printf( "\n  . Done (created \"%s\")\n\n", "result-enc.txt" );
156 
157     exit_code = MBEDTLS_EXIT_SUCCESS;
158 
159 exit:
160     mbedtls_mpi_free( &N ); mbedtls_mpi_free( &E );
161     mbedtls_ctr_drbg_free( &ctr_drbg );
162     mbedtls_entropy_free( &entropy );
163     mbedtls_rsa_free( &rsa );
164 
165     mbedtls_exit( exit_code );
166 }
167 #endif /* MBEDTLS_BIGNUM_C && MBEDTLS_RSA_C && MBEDTLS_ENTROPY_C &&
168           MBEDTLS_FS_IO && MBEDTLS_CTR_DRBG_C */
169