-
+ 0BD7662525269421638C3CF0B5013C4E89B3181BE9D081FD6CE4CAC5AFD731AE831EEAE39F854BCBD5D31A134C47D1083F3C92A44F6DDF64D6160DE04E4D561C
smg_comms/c_wrappers/c_wrappers.c
(0 . 0)(1 . 222)
18 //Wrapper methods for C implementations of RSA and MPI.
19 //To be used / called from Ada so that the C part remains well separated.
20 //S.MG, 2018
21
22 #include "c_wrappers.h"
23 #include "mpi.h"
24 #include "smg_rsa.h"
25 #include <assert.h>
26 #include <string.h> //for memmove...
27
28 //Wrapper for comparing the given arrays of octets as MPIs
29 //Steps:
30 //1. allocate space for 2 MPIs u and v
31 //2. set buffer of u to content of a, buffer of v to content of b
32 //3. call mpi_cmp(u,v) and store result
33 //4. de-allocate u and v
34 //5. return result
35 int mpi_cmp_octets(char *a, unsigned int len_a, char *b, unsigned int len_b) {
36 //variable to hold the final result of comparing a to b as MPIs
37 int result;
38
39 //calculate how much space is needed for each MPI
40 unsigned int nlimbs_a = mpi_nlimb_hint_from_nbytes( len_a );
41 unsigned int nlimbs_b = mpi_nlimb_hint_from_nbytes( len_b );
42
43 //allocate space for the 2 MPIs
44 MPI u = mpi_alloc(nlimbs_a);
45 MPI v = mpi_alloc(nlimbs_b);
46
47 //set the given octets as the values of the 2 MPIs
48 //the sign is set to 0 (last parameter).
49 mpi_set_buffer(u, a, len_a, 0);
50 mpi_set_buffer(v, b, len_b, 0);
51
52 //compare the MPIs as numbers and store the result
53 result = mpi_cmp(u, v);
54
55 //tidy up: free the memory allocated for the 2 MPIs
56 mpi_free(u);
57 mpi_free(v);
58
59 //return the result comparing a to b as MPIs
60 return result;
61 }
62
63 //Encryption of given input with a public RSA key: n and e given as octets too.
64 //Steps:
65 //1. create (allocate memory for) MPIs for out and input;
66 //2. set the input as buffer for the corresponding MPI;
67 //3. create and set the public key structure with n,e as contents;
68 //4. call rsa/public_rsa and retrieve the result storing it in out;
69 //5. free allocated memory for all the MPIs.
70 //6. return the actual length of the encrypted result
71 int public_rsa_octets( char *out , unsigned int len_out,
72 char *input, unsigned int len_input,
73 char *n , unsigned int len_n,
74 char *e , unsigned int len_e) {
75
76 // precondition: output has enough memory allocated
77 assert( len_out >= KEY_LENGTH_OCTETS );
78
79 //allocate memory for input and output MPIs
80 unsigned int nlimbs_in = mpi_nlimb_hint_from_nbytes( len_input );
81 unsigned int nlimbs_out = mpi_nlimb_hint_from_nbytes( len_out );
82 MPI in_mpi = mpi_alloc(nlimbs_in);
83 MPI out_mpi = mpi_alloc(nlimbs_out);
84
85 //set input as buffer for in_mpi
86 mpi_set_buffer(in_mpi, input, len_input, 0);
87
88 //create public key structure and set its contents to given n, e
89 RSA_public_key pk;
90 unsigned int nlimbs_n = mpi_nlimb_hint_from_nbytes( len_n );
91 unsigned int nlimbs_e = mpi_nlimb_hint_from_nbytes( len_e );
92 pk.n = mpi_alloc(nlimbs_n);
93 pk.e = mpi_alloc(nlimbs_e);
94 mpi_set_buffer(pk.n, n, len_n, 0);
95 mpi_set_buffer(pk.e, e, len_e, 0);
96
97 //call rsa public_key encryption and retrieve the result, storing it in out
98 public_rsa( out_mpi, in_mpi, &pk);
99 int len = len_out;
100 mpi_to_octets( out, &len, out_mpi );
101
102 //tidy up: free allocated memory for ALL MPIs.
103 mpi_free(in_mpi);
104 mpi_free(out_mpi);
105 mpi_free(pk.n);
106 mpi_free(pk.e);
107
108 //return actual length
109 return len;
110 }
111
112 //Decryption of given input with the private key given through its components.
113 //Steps:
114 //1. create (allocate memory for) MPIs for out and input;
115 //2. set the input as buffer for the corresponding MPI;
116 //3. create and set the private key structure with n,e,d,p,q,u as contents;
117 //4. call rsa/private_rsa and retrieve the result storing it in out;
118 //5. free allocated memory for all the MPIs.
119 //6. return the actual length of the result
120 int private_rsa_octets( char *out, unsigned int len_out,
121 char *input, unsigned int len_input,
122 char *n , unsigned int len_n,
123 char *e , unsigned int len_e,
124 char *d , unsigned int len_d,
125 char *p , unsigned int len_p,
126 char *q , unsigned int len_q,
127 char *u , unsigned int len_u) {
128 // precondition: output has enough memory allocated
129 assert( len_out >= KEY_LENGTH_OCTETS );
130
131 //allocate memory for input and output MPIs
132 unsigned int nlimbs_in = mpi_nlimb_hint_from_nbytes( len_input );
133 unsigned int nlimbs_out = mpi_nlimb_hint_from_nbytes( len_out );
134 MPI in_mpi = mpi_alloc(nlimbs_in);
135 MPI out_mpi = mpi_alloc(nlimbs_out);
136
137 //set input as buffer for in_mpi
138 mpi_set_buffer(in_mpi, input, len_input, 0);
139
140 //create private key structure and set its contents to given n,e,d,p,q,u
141 RSA_secret_key sk;
142 unsigned int nlimbs_n = mpi_nlimb_hint_from_nbytes( len_n );
143 unsigned int nlimbs_e = mpi_nlimb_hint_from_nbytes( len_e );
144 unsigned int nlimbs_d = mpi_nlimb_hint_from_nbytes( len_d );
145 unsigned int nlimbs_p = mpi_nlimb_hint_from_nbytes( len_p );
146 unsigned int nlimbs_q = mpi_nlimb_hint_from_nbytes( len_q );
147 unsigned int nlimbs_u = mpi_nlimb_hint_from_nbytes( len_u );
148 sk.n = mpi_alloc(nlimbs_n);
149 sk.e = mpi_alloc(nlimbs_e);
150 sk.d = mpi_alloc(nlimbs_d);
151 sk.p = mpi_alloc(nlimbs_p);
152 sk.q = mpi_alloc(nlimbs_q);
153 sk.u = mpi_alloc(nlimbs_u);
154 mpi_set_buffer(sk.n, n, len_n, 0);
155 mpi_set_buffer(sk.e, e, len_e, 0);
156 mpi_set_buffer(sk.d, d, len_d, 0);
157 mpi_set_buffer(sk.p, p, len_p, 0);
158 mpi_set_buffer(sk.q, q, len_q, 0);
159 mpi_set_buffer(sk.u, u, len_u, 0);
160
161 //call rsa secret_key encryption and retrieve the result, storing it in out
162 secret_rsa( out_mpi, in_mpi, &sk );
163 int len = len_out;
164 mpi_to_octets( out, &len, out_mpi );
165
166 //tidy up: free memory previously allocated for MPIs
167 mpi_free(in_mpi);
168 mpi_free(out_mpi);
169 mpi_free(sk.n);
170 mpi_free(sk.e);
171 mpi_free(sk.d);
172 mpi_free(sk.p);
173 mpi_free(sk.q);
174 mpi_free(sk.u);
175
176 //return number of octets copied in out - real length of result
177 return len;
178 }
179
180 //Generates a new RSA key and stores its components at the specified locations.
181 void gen_rsa_octets( char *n, unsigned int *len_n,
182 char *e, unsigned int *len_e,
183 char *d, unsigned int *len_d,
184 char *p, unsigned int *len_p,
185 char *q, unsigned int *len_q,
186 char *u, unsigned int *len_u) {
187 // precondition: all pointers have enough memory allocated
188 assert( *len_n >= KEY_LENGTH_OCTETS );
189 assert( *len_e >= KEY_LENGTH_OCTETS );
190 assert( *len_d >= KEY_LENGTH_OCTETS );
191 assert( *len_p >= KEY_LENGTH_OCTETS / 2);
192 assert( *len_q >= KEY_LENGTH_OCTETS / 2);
193 assert( *len_u >= KEY_LENGTH_OCTETS / 2);
194
195 //the secret key structure that will hold generated key components
196 RSA_secret_key sk;
197 int nlimbs = mpi_nlimb_hint_from_nbytes( KEY_LENGTH_OCTETS );
198 int nlimbs_pq = mpi_nlimb_hint_from_nbytes( KEY_LENGTH_OCTETS / 2 );
199
200 sk.n = mpi_alloc(nlimbs);
201 sk.e = mpi_alloc(nlimbs);
202 sk.d = mpi_alloc(nlimbs);
203 sk.p = mpi_alloc(nlimbs_pq);
204 sk.q = mpi_alloc(nlimbs_pq);
205 sk.u = mpi_alloc(nlimbs_pq);
206
207 //generate the rsa key pair - this may take a while!
208 gen_keypair(&sk);
209
210 //copy components to their place
211 mpi_to_octets( n, len_n, sk.n );
212 mpi_to_octets( e, len_e, sk.e );
213 mpi_to_octets( d, len_d, sk.d );
214 mpi_to_octets( p, len_p, sk.p );
215 mpi_to_octets( q, len_q, sk.q );
216 mpi_to_octets( u, len_u, sk.u );
217
218 //tidy up: free ALL MPIs
219 mpi_free(sk.n);
220 mpi_free(sk.e);
221 mpi_free(sk.d);
222 mpi_free(sk.p);
223 mpi_free(sk.q);
224 mpi_free(sk.u);
225 }
226
227 void mpi_to_octets( char *out, unsigned int *len_out, MPI m) {
228 //copy the components as raw octets to the given pointers
229 int len = 0;
230 int sign;
231 unsigned char * buffer = mpi_get_buffer( m, &len, &sign );
232
233 //check and don't copy MORE than there is allocated space in out!
234 assert( len <= *len_out );
235 memmove( out, buffer, len );
236 *len_out = len; //save actual length of the component
237
238 xfree( buffer ); //free the buffer that was allocated by mpi_get_buffer
239 }