Line data Source code
1 : /*
2 : * gnome-keyring
3 : *
4 : * Copyright (C) 2008 Stefan Walter
5 : *
6 : * This program is free software; you can redistribute it and/or modify
7 : * it under the terms of the GNU Lesser General Public License as
8 : * published by the Free Software Foundation; either version 2.1 of
9 : * the License, or (at your option) any later version.
10 : *
11 : * This program is distributed in the hope that it will be useful, but
12 : * WITHOUT ANY WARRANTY; without even the implied warranty of
13 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 : * Lesser General Public License for more details.
15 : *
16 : * You should have received a copy of the GNU Lesser General Public
17 : * License along with this program; if not, see
18 : * <http://www.gnu.org/licenses/>.
19 : */
20 :
21 : #include "config.h"
22 :
23 : #include "gkm-crypto.h"
24 : #include "gkm-aes-mechanism.h"
25 : #include "gkm-dh-mechanism.h"
26 : #include "gkm-dsa-mechanism.h"
27 : #include "gkm-ecdsa-mechanism.h"
28 : #include "gkm-hkdf-mechanism.h"
29 : #include "gkm-null-mechanism.h"
30 : #include "gkm-rsa-mechanism.h"
31 : #include "gkm-session.h"
32 : #include "gkm-sexp.h"
33 : #include "gkm-sexp-key.h"
34 :
35 : #include "egg/egg-libgcrypt.h"
36 : #include "egg/egg-secure-memory.h"
37 :
38 : /* ----------------------------------------------------------------------------
39 : * PUBLIC
40 : */
41 :
42 : CK_RV
43 3 : gkm_crypto_data_to_sexp (const gchar *format, guint nbits, EggPadding padding,
44 : CK_BYTE_PTR data, CK_ULONG n_data, gcry_sexp_t *sexp)
45 : {
46 3 : gpointer padded = NULL;
47 : gcry_error_t gcry;
48 : gcry_mpi_t mpi;
49 : gsize n_padded;
50 : gsize block;
51 :
52 3 : g_assert (format);
53 3 : g_assert (sexp);
54 :
55 3 : g_return_val_if_fail (data, CKR_ARGUMENTS_BAD);
56 :
57 3 : block = (nbits + 7) / 8;
58 3 : if (n_data > block)
59 0 : return CKR_DATA_LEN_RANGE;
60 :
61 3 : if (padding) {
62 2 : if (!(padding) (g_realloc, block, data, n_data, &padded, &n_padded))
63 0 : return CKR_DATA_LEN_RANGE;
64 : }
65 :
66 : /* Prepare the input s expression */
67 6 : gcry = gcry_mpi_scan (&mpi, GCRYMPI_FMT_USG,
68 3 : padded ? padded : data,
69 3 : padded ? n_padded : n_data, NULL);
70 3 : g_free (padded);
71 :
72 3 : g_return_val_if_fail (gcry == 0, CKR_GENERAL_ERROR);
73 :
74 3 : gcry = gcry_sexp_build (sexp, NULL, format, mpi);
75 3 : gcry_mpi_release (mpi);
76 :
77 3 : g_return_val_if_fail (gcry == 0, CKR_GENERAL_ERROR);
78 :
79 3 : g_assert (*sexp);
80 3 : return CKR_OK;
81 : }
82 :
83 : CK_RV
84 5 : gkm_crypto_sexp_to_data (gcry_sexp_t sexp, guint bits, CK_BYTE_PTR data,
85 : CK_ULONG *n_data, EggPadding padding, ...)
86 : {
87 5 : gcry_sexp_t at = NULL;
88 : gsize n_block, offset, len;
89 5 : gcry_mpi_t mpi = NULL;
90 : gpointer padded;
91 : guchar *block;
92 : va_list va;
93 : gboolean ret;
94 : gcry_error_t gcry;
95 :
96 5 : g_assert (sexp);
97 5 : g_assert (data);
98 5 : g_assert (n_data);
99 5 : g_assert (bits);
100 :
101 : /* First try and dig out sexp child based on arguments */
102 5 : va_start (va, padding);
103 5 : at = gkm_sexp_get_childv (sexp, va);
104 5 : va_end (va);
105 :
106 : /* It's expected we would find it */
107 5 : g_return_val_if_fail (at != NULL, CKR_GENERAL_ERROR);
108 :
109 : /* Parse out the MPI */
110 5 : mpi = gcry_sexp_nth_mpi (at, 1, GCRYMPI_FMT_USG);
111 5 : g_return_val_if_fail (mpi != NULL, CKR_GENERAL_ERROR);
112 5 : gcry_sexp_release (at);
113 :
114 : /* Print out the MPI into the end of a temporary buffer */
115 5 : n_block = (bits + 7) / 8;
116 5 : gcry = gcry_mpi_print (GCRYMPI_FMT_USG, NULL, 0, &len, mpi);
117 5 : g_return_val_if_fail (gcry == 0, CKR_GENERAL_ERROR);
118 5 : g_return_val_if_fail (len <= n_block, CKR_GENERAL_ERROR);
119 5 : offset = n_block - len;
120 5 : block = g_malloc0 (n_block);
121 5 : memset (block, 0, offset);
122 5 : gcry = gcry_mpi_print (GCRYMPI_FMT_USG, block + offset, len, &len, mpi);
123 5 : g_return_val_if_fail (gcry == 0, CKR_GENERAL_ERROR);
124 5 : g_return_val_if_fail (len == n_block - offset, CKR_GENERAL_ERROR);
125 5 : gcry_mpi_release (mpi);
126 :
127 : /* Pad it properly if necessary */
128 5 : if (padding != NULL) {
129 0 : ret = (padding) (g_realloc, n_block, block, n_block, &padded, &n_block);
130 0 : g_free (block);
131 0 : if (ret == FALSE)
132 0 : return CKR_DATA_LEN_RANGE;
133 0 : block = padded;
134 : }
135 :
136 : /* Now stuff it into the output buffer */
137 5 : if (n_block > *n_data)
138 0 : return CKR_BUFFER_TOO_SMALL;
139 :
140 5 : memcpy (data, block, n_block);
141 5 : *n_data = n_block;
142 5 : g_free (block);
143 :
144 5 : return CKR_OK;
145 : }
146 :
147 :
148 : CK_RV
149 0 : gkm_crypto_encrypt (GkmSession *session, CK_MECHANISM_TYPE mech, CK_BYTE_PTR data,
150 : CK_ULONG n_data, CK_BYTE_PTR encrypted, CK_ULONG_PTR n_encrypted)
151 : {
152 : GkmSexp *sexp;
153 :
154 0 : switch (mech) {
155 0 : case CKM_RSA_PKCS:
156 : case CKM_RSA_X_509:
157 0 : sexp = gkm_session_get_crypto_state (session);
158 0 : g_return_val_if_fail (sexp, CKR_GENERAL_ERROR);
159 0 : return gkm_crypto_encrypt_xsa (gkm_sexp_get (sexp), mech, data, n_data, encrypted, n_encrypted);
160 0 : default:
161 0 : g_return_val_if_reached (CKR_GENERAL_ERROR);
162 : }
163 : }
164 :
165 : CK_RV
166 0 : gkm_crypto_encrypt_xsa (gcry_sexp_t sexp, CK_MECHANISM_TYPE mech, CK_BYTE_PTR data,
167 : CK_ULONG n_data, CK_BYTE_PTR encrypted, CK_ULONG_PTR n_encrypted)
168 : {
169 : int algorithm;
170 : CK_RV rv;
171 :
172 0 : g_return_val_if_fail (sexp, CKR_GENERAL_ERROR);
173 0 : g_return_val_if_fail (n_encrypted, CKR_ARGUMENTS_BAD);
174 0 : g_return_val_if_fail (data, CKR_ARGUMENTS_BAD);
175 :
176 0 : if (!gkm_sexp_parse_key (sexp, &algorithm, NULL, NULL))
177 0 : g_return_val_if_reached (CKR_GENERAL_ERROR);
178 :
179 : /*
180 : * The algorithm checks below are merely sanity checks.
181 : * Other code should have checed this at an earlier stage
182 : * and return the right error codes if invalid.
183 : */
184 :
185 0 : switch (mech) {
186 0 : case CKM_RSA_PKCS:
187 0 : g_return_val_if_fail (algorithm == GCRY_PK_RSA, CKR_GENERAL_ERROR);
188 0 : rv = gkm_rsa_mechanism_encrypt (sexp, egg_padding_pkcs1_pad_02, data, n_data, encrypted, n_encrypted);
189 0 : break;
190 0 : case CKM_RSA_X_509:
191 0 : g_return_val_if_fail (algorithm == GCRY_PK_RSA, CKR_GENERAL_ERROR);
192 0 : rv = gkm_rsa_mechanism_encrypt (sexp, egg_padding_zero_pad, data, n_data, encrypted, n_encrypted);
193 0 : break;
194 0 : default:
195 : /* Again shouldn't be reached */
196 0 : g_return_val_if_reached (CKR_GENERAL_ERROR);
197 : };
198 :
199 0 : return rv;
200 : }
201 :
202 : CK_RV
203 0 : gkm_crypto_decrypt (GkmSession *session, CK_MECHANISM_TYPE mech, CK_BYTE_PTR encrypted,
204 : CK_ULONG n_encrypted, CK_BYTE_PTR data, CK_ULONG_PTR n_data)
205 : {
206 : GkmSexp *sexp;
207 :
208 0 : switch (mech) {
209 0 : case CKM_RSA_PKCS:
210 : case CKM_RSA_X_509:
211 0 : sexp = gkm_session_get_crypto_state (session);
212 0 : g_return_val_if_fail (sexp, CKR_GENERAL_ERROR);
213 0 : return gkm_crypto_decrypt_xsa (gkm_sexp_get (sexp), mech, encrypted, n_encrypted, data, n_data);
214 0 : default:
215 0 : g_return_val_if_reached (CKR_GENERAL_ERROR);
216 : }
217 : }
218 :
219 : CK_RV
220 0 : gkm_crypto_decrypt_xsa (gcry_sexp_t sexp, CK_MECHANISM_TYPE mech, CK_BYTE_PTR encrypted,
221 : CK_ULONG n_encrypted, CK_BYTE_PTR data, CK_ULONG_PTR n_data)
222 : {
223 : int algorithm;
224 : CK_RV rv;
225 :
226 0 : g_return_val_if_fail (sexp, CKR_GENERAL_ERROR);
227 0 : g_return_val_if_fail (n_data, CKR_ARGUMENTS_BAD);
228 0 : g_return_val_if_fail (encrypted, CKR_ARGUMENTS_BAD);
229 :
230 0 : if (!gkm_sexp_parse_key (sexp, &algorithm, NULL, NULL))
231 0 : g_return_val_if_reached (CKR_GENERAL_ERROR);
232 :
233 : /*
234 : * The algorithm checks below are merely sanity checks.
235 : * Other code should have checed this at an earlier stage
236 : * and return the right error codes if invalid.
237 : */
238 :
239 0 : switch (mech) {
240 0 : case CKM_RSA_PKCS:
241 0 : g_return_val_if_fail (algorithm == GCRY_PK_RSA, CKR_GENERAL_ERROR);
242 0 : rv = gkm_rsa_mechanism_decrypt (sexp, egg_padding_pkcs1_unpad_02, encrypted, n_encrypted, data, n_data);
243 0 : break;
244 0 : case CKM_RSA_X_509:
245 0 : g_return_val_if_fail (algorithm == GCRY_PK_RSA, CKR_GENERAL_ERROR);
246 0 : rv = gkm_rsa_mechanism_decrypt (sexp, NULL, encrypted, n_encrypted, data, n_data);
247 0 : break;
248 0 : default:
249 : /* Again shouldn't be reached */
250 0 : g_return_val_if_reached (CKR_GENERAL_ERROR);
251 : };
252 :
253 0 : return rv;
254 : }
255 :
256 : CK_RV
257 0 : gkm_crypto_sign (GkmSession *session, CK_MECHANISM_TYPE mech, CK_BYTE_PTR data,
258 : CK_ULONG n_data, CK_BYTE_PTR signature, CK_ULONG_PTR n_signature)
259 : {
260 : GkmSexp *sexp;
261 :
262 0 : switch (mech) {
263 0 : case CKM_RSA_PKCS:
264 : case CKM_RSA_X_509:
265 : case CKM_DSA:
266 : case CKM_ECDSA:
267 0 : sexp = gkm_session_get_crypto_state (session);
268 0 : g_return_val_if_fail (sexp, CKR_GENERAL_ERROR);
269 0 : return gkm_crypto_sign_xsa (gkm_sexp_get (sexp), mech, data, n_data, signature, n_signature);
270 0 : default:
271 0 : g_return_val_if_reached (CKR_GENERAL_ERROR);
272 : }
273 : }
274 :
275 : CK_RV
276 3 : gkm_crypto_sign_xsa (gcry_sexp_t sexp, CK_MECHANISM_TYPE mech, CK_BYTE_PTR data,
277 : CK_ULONG n_data, CK_BYTE_PTR signature, CK_ULONG_PTR n_signature)
278 : {
279 : int algorithm;
280 : CK_RV rv;
281 :
282 3 : g_return_val_if_fail (sexp, CKR_GENERAL_ERROR);
283 3 : g_return_val_if_fail (n_signature, CKR_ARGUMENTS_BAD);
284 3 : g_return_val_if_fail (data, CKR_ARGUMENTS_BAD);
285 :
286 3 : if (!gkm_sexp_parse_key (sexp, &algorithm, NULL, NULL))
287 0 : g_return_val_if_reached (CKR_GENERAL_ERROR);
288 :
289 : /*
290 : * The algorithm checks below are merely sanity checks.
291 : * Other code should have checed this at an earlier stage
292 : * and return the right error codes if invalid.
293 : */
294 :
295 3 : switch (mech) {
296 1 : case CKM_RSA_PKCS:
297 1 : g_return_val_if_fail (algorithm == GCRY_PK_RSA, CKR_GENERAL_ERROR);
298 1 : rv = gkm_rsa_mechanism_sign (sexp, egg_padding_pkcs1_pad_01, data, n_data, signature, n_signature);
299 1 : break;
300 0 : case CKM_RSA_X_509:
301 0 : g_return_val_if_fail (algorithm == GCRY_PK_RSA, CKR_GENERAL_ERROR);
302 0 : rv = gkm_rsa_mechanism_sign (sexp, egg_padding_zero_pad, data, n_data, signature, n_signature);
303 0 : break;
304 1 : case CKM_DSA:
305 1 : g_return_val_if_fail (algorithm == GCRY_PK_DSA, CKR_GENERAL_ERROR);
306 1 : rv = gkm_dsa_mechanism_sign (sexp, data, n_data, signature, n_signature);
307 1 : break;
308 1 : case CKM_ECDSA:
309 1 : g_return_val_if_fail (algorithm == GCRY_PK_ECC, CKR_GENERAL_ERROR);
310 1 : rv = gkm_ecdsa_mechanism_sign (sexp, data, n_data, signature, n_signature);
311 1 : break;
312 0 : default:
313 : /* Again shouldn't be reached */
314 0 : g_return_val_if_reached (CKR_GENERAL_ERROR);
315 : };
316 :
317 3 : return rv;
318 : }
319 :
320 : CK_RV
321 0 : gkm_crypto_verify (GkmSession *session, CK_MECHANISM_TYPE mech, CK_BYTE_PTR data,
322 : CK_ULONG n_data, CK_BYTE_PTR signature, CK_ULONG n_signature)
323 : {
324 : GkmSexp *sexp;
325 :
326 0 : switch (mech) {
327 0 : case CKM_RSA_PKCS:
328 : case CKM_RSA_X_509:
329 : case CKM_DSA:
330 : case CKM_ECDSA:
331 0 : sexp = gkm_session_get_crypto_state (session);
332 0 : g_return_val_if_fail (sexp, CKR_GENERAL_ERROR);
333 0 : return gkm_crypto_verify_xsa (gkm_sexp_get (sexp), mech, data, n_data, signature, n_signature);
334 0 : default:
335 0 : g_return_val_if_reached (CKR_GENERAL_ERROR);
336 : }
337 : }
338 :
339 : CK_RV
340 3 : gkm_crypto_verify_xsa (gcry_sexp_t sexp, CK_MECHANISM_TYPE mech, CK_BYTE_PTR data,
341 : CK_ULONG n_data, CK_BYTE_PTR signature, CK_ULONG n_signature)
342 : {
343 : int algorithm;
344 : CK_RV rv;
345 :
346 3 : g_return_val_if_fail (sexp, CKR_GENERAL_ERROR);
347 3 : g_return_val_if_fail (signature, CKR_ARGUMENTS_BAD);
348 3 : g_return_val_if_fail (data, CKR_ARGUMENTS_BAD);
349 :
350 3 : if (!gkm_sexp_parse_key (sexp, &algorithm, NULL, NULL))
351 0 : g_return_val_if_reached (CKR_GENERAL_ERROR);
352 :
353 : /*
354 : * The algorithm checks below are merely sanity checks.
355 : * Other code should have checed this at an earlier stage
356 : * and return the right error codes if invalid.
357 : */
358 :
359 3 : switch (mech) {
360 1 : case CKM_RSA_PKCS:
361 1 : g_return_val_if_fail (algorithm == GCRY_PK_RSA, CKR_GENERAL_ERROR);
362 1 : rv = gkm_rsa_mechanism_verify (sexp, egg_padding_pkcs1_pad_01, data, n_data, signature, n_signature);
363 1 : break;
364 0 : case CKM_RSA_X_509:
365 0 : g_return_val_if_fail (algorithm == GCRY_PK_RSA, CKR_GENERAL_ERROR);
366 0 : rv = gkm_rsa_mechanism_verify (sexp, egg_padding_zero_pad, data, n_data, signature, n_signature);
367 0 : break;
368 1 : case CKM_DSA:
369 1 : g_return_val_if_fail (algorithm == GCRY_PK_DSA, CKR_GENERAL_ERROR);
370 1 : rv = gkm_dsa_mechanism_verify (sexp, data, n_data, signature, n_signature);
371 1 : break;
372 1 : case CKM_ECDSA:
373 1 : g_return_val_if_fail (algorithm == GCRY_PK_ECC, CKR_GENERAL_ERROR);
374 1 : rv = gkm_ecdsa_mechanism_verify (sexp, data, n_data, signature, n_signature);
375 1 : break;
376 0 : default:
377 : /* Again shouldn't be reached */
378 0 : g_return_val_if_reached (CKR_GENERAL_ERROR);
379 : };
380 :
381 3 : return rv;
382 : }
383 :
384 : CK_RV
385 0 : gkm_crypto_perform (GkmSession *session, CK_MECHANISM_TYPE mech, CK_ATTRIBUTE_TYPE method,
386 : CK_BYTE_PTR bufone, CK_ULONG n_bufone, CK_BYTE_PTR buftwo, CK_ULONG_PTR n_buftwo)
387 : {
388 0 : g_return_val_if_fail (GKM_IS_SESSION (session), CKR_GENERAL_ERROR);
389 0 : g_return_val_if_fail (method, CKR_GENERAL_ERROR);
390 0 : g_return_val_if_fail (n_buftwo, CKR_GENERAL_ERROR);
391 :
392 0 : switch (method) {
393 0 : case CKA_ENCRYPT:
394 0 : return gkm_crypto_encrypt (session, mech, bufone, n_bufone, buftwo, n_buftwo);
395 0 : case CKA_DECRYPT:
396 0 : return gkm_crypto_decrypt (session, mech, bufone, n_bufone, buftwo, n_buftwo);
397 0 : case CKA_SIGN:
398 0 : return gkm_crypto_sign (session, mech, bufone, n_bufone, buftwo, n_buftwo);
399 0 : case CKA_VERIFY:
400 0 : return gkm_crypto_verify (session, mech, bufone, n_bufone, buftwo, *n_buftwo);
401 0 : default:
402 0 : g_return_val_if_reached (CKR_GENERAL_ERROR);
403 : }
404 : }
405 :
406 : CK_RV
407 1 : gkm_crypto_generate_key_pair (GkmSession *session, CK_MECHANISM_TYPE mech,
408 : CK_ATTRIBUTE_PTR pub_atts, CK_ULONG n_pub_atts,
409 : CK_ATTRIBUTE_PTR priv_atts, CK_ULONG n_priv_atts,
410 : GkmObject **pub_key, GkmObject **priv_key)
411 : {
412 1 : g_return_val_if_fail (GKM_IS_SESSION (session), CKR_GENERAL_ERROR);
413 1 : g_return_val_if_fail (pub_key, CKR_GENERAL_ERROR);
414 1 : g_return_val_if_fail (priv_key, CKR_GENERAL_ERROR);
415 :
416 1 : switch (mech) {
417 1 : case CKM_DH_PKCS_KEY_PAIR_GEN:
418 1 : return gkm_dh_mechanism_generate (session, pub_atts, n_pub_atts,
419 : priv_atts, n_priv_atts,
420 : pub_key, priv_key);
421 0 : default:
422 0 : return CKR_MECHANISM_INVALID;
423 : }
424 : }
425 :
426 : CK_RV
427 2 : gkm_crypto_derive_key (GkmSession *session, CK_MECHANISM_PTR mech, GkmObject *base,
428 : CK_ATTRIBUTE_PTR attrs, CK_ULONG n_attrs, GkmObject **derived)
429 : {
430 2 : g_return_val_if_fail (GKM_IS_SESSION (session), CKR_GENERAL_ERROR);
431 2 : g_return_val_if_fail (GKM_IS_OBJECT (base), CKR_GENERAL_ERROR);
432 2 : g_return_val_if_fail (derived, CKR_GENERAL_ERROR);
433 :
434 2 : if (!gkm_object_has_attribute_ulong (base, session, CKA_ALLOWED_MECHANISMS, mech->mechanism))
435 0 : return CKR_KEY_TYPE_INCONSISTENT;
436 :
437 2 : if (!gkm_object_has_attribute_boolean (base, session, CKA_DERIVE, TRUE))
438 0 : return CKR_KEY_FUNCTION_NOT_PERMITTED;
439 :
440 2 : switch (mech->mechanism) {
441 1 : case CKM_DH_PKCS_DERIVE:
442 1 : return gkm_dh_mechanism_derive (session, mech, base, attrs,
443 : n_attrs, derived);
444 1 : case CKM_G_HKDF_SHA256_DERIVE:
445 1 : return gkm_hkdf_mechanism_derive (session, "sha256", mech, base,
446 : attrs, n_attrs, derived);
447 0 : default:
448 0 : return CKR_MECHANISM_INVALID;
449 : }
450 : }
451 :
452 : CK_RV
453 0 : gkm_crypto_wrap_key (GkmSession *session, CK_MECHANISM_PTR mech, GkmObject *wrapper,
454 : GkmObject *wrapped, CK_BYTE_PTR output, CK_ULONG_PTR n_output)
455 : {
456 0 : g_return_val_if_fail (GKM_IS_SESSION (session), CKR_GENERAL_ERROR);
457 0 : g_return_val_if_fail (GKM_IS_OBJECT (wrapper), CKR_GENERAL_ERROR);
458 0 : g_return_val_if_fail (GKM_IS_OBJECT (wrapped), CKR_GENERAL_ERROR);
459 0 : g_return_val_if_fail (mech, CKR_GENERAL_ERROR);
460 0 : g_return_val_if_fail (n_output, CKR_GENERAL_ERROR);
461 :
462 0 : if (!gkm_object_has_attribute_ulong (wrapper, session, CKA_ALLOWED_MECHANISMS, mech->mechanism))
463 0 : return CKR_KEY_TYPE_INCONSISTENT;
464 :
465 0 : if (!gkm_object_has_attribute_boolean (wrapper, session, CKA_WRAP, TRUE))
466 0 : return CKR_KEY_FUNCTION_NOT_PERMITTED;
467 :
468 0 : switch (mech->mechanism) {
469 0 : case CKM_AES_CBC_PAD:
470 0 : return gkm_aes_mechanism_wrap (session, mech, wrapper, wrapped,
471 : output, n_output);
472 0 : case CKM_G_NULL:
473 0 : return gkm_null_mechanism_wrap (session, mech, wrapper, wrapped,
474 : output, n_output);
475 0 : default:
476 0 : return CKR_MECHANISM_INVALID;
477 : }
478 : }
479 :
480 : CK_RV
481 19 : gkm_crypto_unwrap_key (GkmSession *session, CK_MECHANISM_PTR mech, GkmObject *wrapper,
482 : CK_VOID_PTR input, CK_ULONG n_input, CK_ATTRIBUTE_PTR attrs,
483 : CK_ULONG n_attrs, GkmObject **unwrapped)
484 : {
485 19 : g_return_val_if_fail (GKM_IS_SESSION (session), CKR_GENERAL_ERROR);
486 19 : g_return_val_if_fail (GKM_IS_OBJECT (wrapper), CKR_GENERAL_ERROR);
487 19 : g_return_val_if_fail (mech, CKR_GENERAL_ERROR);
488 19 : g_return_val_if_fail (unwrapped, CKR_GENERAL_ERROR);
489 :
490 19 : if (!gkm_object_has_attribute_ulong (wrapper, session, CKA_ALLOWED_MECHANISMS, mech->mechanism))
491 0 : return CKR_KEY_TYPE_INCONSISTENT;
492 :
493 19 : if (!gkm_object_has_attribute_boolean (wrapper, session, CKA_UNWRAP, TRUE))
494 0 : return CKR_KEY_FUNCTION_NOT_PERMITTED;
495 :
496 19 : switch (mech->mechanism) {
497 1 : case CKM_AES_CBC_PAD:
498 1 : return gkm_aes_mechanism_unwrap (session, mech, wrapper, input,
499 : n_input, attrs, n_attrs, unwrapped);
500 18 : case CKM_G_NULL:
501 18 : return gkm_null_mechanism_unwrap (session, mech, wrapper, input,
502 : n_input, attrs, n_attrs, unwrapped);
503 0 : default:
504 0 : return CKR_MECHANISM_INVALID;
505 : }
506 : }
507 :
508 : /* ----------------------------------------------------------------------------
509 : * PREPARE FUNCTIONS
510 : */
511 :
512 : CK_RV
513 0 : gkm_crypto_prepare (GkmSession *session, CK_MECHANISM_TYPE mech, GkmObject *key)
514 : {
515 0 : g_return_val_if_fail (GKM_IS_SESSION (session), CKR_GENERAL_ERROR);
516 :
517 0 : switch (mech) {
518 0 : case CKM_RSA_PKCS:
519 : case CKM_RSA_X_509:
520 : case CKM_ECDSA:
521 : case CKM_DSA:
522 0 : return gkm_crypto_prepare_xsa (session, mech, key);
523 0 : default:
524 0 : g_return_val_if_reached (CKR_GENERAL_ERROR);
525 : }
526 : }
527 :
528 : CK_RV
529 0 : gkm_crypto_prepare_xsa (GkmSession *session, CK_MECHANISM_TYPE mech, GkmObject *key)
530 : {
531 : GkmSexp *sexp;
532 :
533 0 : g_return_val_if_fail (GKM_IS_SESSION (session), CKR_GENERAL_ERROR);
534 0 : g_return_val_if_fail (GKM_IS_SEXP_KEY (key), CKR_GENERAL_ERROR);
535 :
536 : /* Load up the actual sexp we're going to use */
537 0 : sexp = gkm_sexp_key_acquire_crypto_sexp (GKM_SEXP_KEY (key), session);
538 0 : if (sexp == NULL)
539 0 : return CKR_USER_NOT_LOGGED_IN;
540 :
541 0 : gkm_session_set_crypto_state (session, sexp, gkm_sexp_unref);
542 0 : return CKR_OK;
543 : }
544 :
545 : /* --------------------------------------------------------------------------
546 : * UTILITY
547 : */
548 :
549 :
550 : void
551 705 : gkm_crypto_initialize (void)
552 : {
553 705 : egg_libgcrypt_initialize ();
554 705 : }
555 :
556 : gulong
557 1 : gkm_crypto_secret_key_length (CK_KEY_TYPE type)
558 : {
559 1 : switch (type) {
560 0 : case CKK_AES:
561 0 : return GKM_AES_MECHANISM_MIN_LENGTH;
562 1 : default:
563 1 : return 0;
564 : }
565 : }
|