LCOV - code coverage report
Current view: top level - pkcs11/gkm - gkm-crypto.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 45.6 % 274 125
Test Date: 2024-04-08 13:24:42 Functions: 47.4 % 19 9

            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              : }
        

Generated by: LCOV version 2.0-1