3b08dec5ee634f83ee18e1753d5ffe0ac5e3c458Jakub Hrozek/*
3b08dec5ee634f83ee18e1753d5ffe0ac5e3c458Jakub Hrozek SSSD
3b08dec5ee634f83ee18e1753d5ffe0ac5e3c458Jakub Hrozek
3b08dec5ee634f83ee18e1753d5ffe0ac5e3c458Jakub Hrozek NSS crypto wrappers
3b08dec5ee634f83ee18e1753d5ffe0ac5e3c458Jakub Hrozek
3b08dec5ee634f83ee18e1753d5ffe0ac5e3c458Jakub Hrozek Authors:
3b08dec5ee634f83ee18e1753d5ffe0ac5e3c458Jakub Hrozek Sumit Bose <sbose@redhat.com>
3b08dec5ee634f83ee18e1753d5ffe0ac5e3c458Jakub Hrozek Jakub Hrozek <jhrozek@redhat.com>
3b08dec5ee634f83ee18e1753d5ffe0ac5e3c458Jakub Hrozek
3b08dec5ee634f83ee18e1753d5ffe0ac5e3c458Jakub Hrozek Copyright (C) Red Hat, Inc 2010
3b08dec5ee634f83ee18e1753d5ffe0ac5e3c458Jakub Hrozek
3b08dec5ee634f83ee18e1753d5ffe0ac5e3c458Jakub Hrozek This program is free software; you can redistribute it and/or modify
3b08dec5ee634f83ee18e1753d5ffe0ac5e3c458Jakub Hrozek it under the terms of the GNU General Public License as published by
3b08dec5ee634f83ee18e1753d5ffe0ac5e3c458Jakub Hrozek the Free Software Foundation; either version 3 of the License, or
3b08dec5ee634f83ee18e1753d5ffe0ac5e3c458Jakub Hrozek (at your option) any later version.
3b08dec5ee634f83ee18e1753d5ffe0ac5e3c458Jakub Hrozek
3b08dec5ee634f83ee18e1753d5ffe0ac5e3c458Jakub Hrozek This program is distributed in the hope that it will be useful,
3b08dec5ee634f83ee18e1753d5ffe0ac5e3c458Jakub Hrozek but WITHOUT ANY WARRANTY; without even the implied warranty of
3b08dec5ee634f83ee18e1753d5ffe0ac5e3c458Jakub Hrozek MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3b08dec5ee634f83ee18e1753d5ffe0ac5e3c458Jakub Hrozek GNU General Public License for more details.
3b08dec5ee634f83ee18e1753d5ffe0ac5e3c458Jakub Hrozek
3b08dec5ee634f83ee18e1753d5ffe0ac5e3c458Jakub Hrozek You should have received a copy of the GNU General Public License
3b08dec5ee634f83ee18e1753d5ffe0ac5e3c458Jakub Hrozek along with this program. If not, see <http://www.gnu.org/licenses/>.
3b08dec5ee634f83ee18e1753d5ffe0ac5e3c458Jakub Hrozek*/
3b08dec5ee634f83ee18e1753d5ffe0ac5e3c458Jakub Hrozek
3b08dec5ee634f83ee18e1753d5ffe0ac5e3c458Jakub Hrozek#include "config.h"
3b08dec5ee634f83ee18e1753d5ffe0ac5e3c458Jakub Hrozek
3b08dec5ee634f83ee18e1753d5ffe0ac5e3c458Jakub Hrozek#include <prinit.h>
3b08dec5ee634f83ee18e1753d5ffe0ac5e3c458Jakub Hrozek#include <nss.h>
3b08dec5ee634f83ee18e1753d5ffe0ac5e3c458Jakub Hrozek
3b08dec5ee634f83ee18e1753d5ffe0ac5e3c458Jakub Hrozek#include "util/util.h"
5cd4414fce1e0eb4133dfc6fc828bf25c8a959f9Lukas Slebodnik#include "util/crypto/nss/nss_util.h"
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce#include "util/crypto/nss/nss_crypto.h"
3b08dec5ee634f83ee18e1753d5ffe0ac5e3c458Jakub Hrozek
3b08dec5ee634f83ee18e1753d5ffe0ac5e3c458Jakub Hrozekstatic int nspr_nss_init_done = 0;
3b08dec5ee634f83ee18e1753d5ffe0ac5e3c458Jakub Hrozek
3b08dec5ee634f83ee18e1753d5ffe0ac5e3c458Jakub Hrozekint nspr_nss_init(void)
3b08dec5ee634f83ee18e1753d5ffe0ac5e3c458Jakub Hrozek{
3b08dec5ee634f83ee18e1753d5ffe0ac5e3c458Jakub Hrozek SECStatus sret;
3b08dec5ee634f83ee18e1753d5ffe0ac5e3c458Jakub Hrozek
3b08dec5ee634f83ee18e1753d5ffe0ac5e3c458Jakub Hrozek /* nothing to do */
3b08dec5ee634f83ee18e1753d5ffe0ac5e3c458Jakub Hrozek if (nspr_nss_init_done == 1) return SECSuccess;
3b08dec5ee634f83ee18e1753d5ffe0ac5e3c458Jakub Hrozek
3b08dec5ee634f83ee18e1753d5ffe0ac5e3c458Jakub Hrozek PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
3b08dec5ee634f83ee18e1753d5ffe0ac5e3c458Jakub Hrozek
3b08dec5ee634f83ee18e1753d5ffe0ac5e3c458Jakub Hrozek sret = NSS_NoDB_Init(NULL);
3b08dec5ee634f83ee18e1753d5ffe0ac5e3c458Jakub Hrozek if (sret != SECSuccess) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE,
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov "Error initializing connection to NSS [%d]\n",
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov PR_GetError());
3b08dec5ee634f83ee18e1753d5ffe0ac5e3c458Jakub Hrozek return EIO;
3b08dec5ee634f83ee18e1753d5ffe0ac5e3c458Jakub Hrozek }
3b08dec5ee634f83ee18e1753d5ffe0ac5e3c458Jakub Hrozek
3b08dec5ee634f83ee18e1753d5ffe0ac5e3c458Jakub Hrozek nspr_nss_init_done = 1;
3b08dec5ee634f83ee18e1753d5ffe0ac5e3c458Jakub Hrozek return EOK;
3b08dec5ee634f83ee18e1753d5ffe0ac5e3c458Jakub Hrozek}
3b08dec5ee634f83ee18e1753d5ffe0ac5e3c458Jakub Hrozek
3b08dec5ee634f83ee18e1753d5ffe0ac5e3c458Jakub Hrozekint nspr_nss_cleanup(void)
3b08dec5ee634f83ee18e1753d5ffe0ac5e3c458Jakub Hrozek{
3b08dec5ee634f83ee18e1753d5ffe0ac5e3c458Jakub Hrozek SECStatus sret;
3b08dec5ee634f83ee18e1753d5ffe0ac5e3c458Jakub Hrozek
3b08dec5ee634f83ee18e1753d5ffe0ac5e3c458Jakub Hrozek /* nothing to do */
3b08dec5ee634f83ee18e1753d5ffe0ac5e3c458Jakub Hrozek if (nspr_nss_init_done == 0) return SECSuccess;
3b08dec5ee634f83ee18e1753d5ffe0ac5e3c458Jakub Hrozek
3b08dec5ee634f83ee18e1753d5ffe0ac5e3c458Jakub Hrozek sret = NSS_Shutdown();
3b08dec5ee634f83ee18e1753d5ffe0ac5e3c458Jakub Hrozek if (sret != SECSuccess) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE,
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov "Error shutting down connection to NSS [%d]\n",
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov PR_GetError());
3b08dec5ee634f83ee18e1753d5ffe0ac5e3c458Jakub Hrozek return EIO;
3b08dec5ee634f83ee18e1753d5ffe0ac5e3c458Jakub Hrozek }
3b08dec5ee634f83ee18e1753d5ffe0ac5e3c458Jakub Hrozek
3b08dec5ee634f83ee18e1753d5ffe0ac5e3c458Jakub Hrozek PR_Cleanup();
3b08dec5ee634f83ee18e1753d5ffe0ac5e3c458Jakub Hrozek nspr_nss_init_done = 0;
3b08dec5ee634f83ee18e1753d5ffe0ac5e3c458Jakub Hrozek return EOK;
3b08dec5ee634f83ee18e1753d5ffe0ac5e3c458Jakub Hrozek}
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorcestatic int sss_nss_crypto_ctx_destructor(struct sss_nss_crypto_ctx *cctx)
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce{
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce if (cctx->ectx) PK11_DestroyContext(cctx->ectx, PR_TRUE);
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce if (cctx->sparam) SECITEM_FreeItem(cctx->sparam, PR_TRUE);
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce if (cctx->slot) PK11_FreeSlot(cctx->slot);
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce if (cctx->keyobj) PK11_FreeSymKey(cctx->keyobj);
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce return EOK;
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce}
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorcestatic int generate_random_key(TALLOC_CTX *mem_ctx,
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce PK11SlotInfo *slot,
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce struct crypto_mech_data *mech_props,
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce SECItem **_key)
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce{
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce SECStatus sret;
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce SECItem *randkeydata;
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce SECItem *key = NULL;
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce PK11SymKey *randkey;
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce int ret;
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce randkey = PK11_KeyGen(slot, mech_props->cipher,
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce NULL, mech_props->keylen, NULL);
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce if (randkey == NULL) {
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce DEBUG(SSSDBG_CRIT_FAILURE, "Failure to generate key (err %d)\n",
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce PR_GetError());
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce ret = EIO;
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce goto done;
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce }
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce sret = PK11_ExtractKeyValue(randkey);
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce if (sret != SECSuccess) {
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce DEBUG(SSSDBG_CRIT_FAILURE, "Failure to extract key value (err %d)\n",
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce PR_GetError());
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce ret = EIO;
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce goto done;
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce }
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce randkeydata = PK11_GetKeyData(randkey);
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce if (randkeydata == NULL) {
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce DEBUG(SSSDBG_CRIT_FAILURE, "Failure to get key data (err %d)\n",
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce PR_GetError());
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce ret = EIO;
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce goto done;
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce }
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce /* randkeydata is valid until randkey is. Copy with talloc to
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce * get a nice memory hierarchy symmetrical in encrypt
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce * and decrypt case */
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce key = talloc_zero(mem_ctx, SECItem);
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce if (!key) {
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce ret = ENOMEM;
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce goto done;
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce }
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce key->data = talloc_memdup(key, randkeydata->data, randkeydata->len);
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce if (!key->data) {
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce ret = ENOMEM;
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce goto done;
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce }
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce key->len = randkeydata->len;
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce *_key = key;
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce ret = EOK;
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorcedone:
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce if (ret != EOK) talloc_zfree(key);
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce PK11_FreeSymKey(randkey);
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce return ret;
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce}
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorceint nss_ctx_init(TALLOC_CTX *mem_ctx,
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce struct crypto_mech_data *mech_props,
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce uint8_t *key, int keylen,
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce uint8_t *iv, int ivlen,
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce struct sss_nss_crypto_ctx **_cctx)
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce{
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce struct sss_nss_crypto_ctx *cctx;
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce int ret;
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce cctx = talloc_zero(mem_ctx, struct sss_nss_crypto_ctx);
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce if (!cctx) {
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce return ENOMEM;
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce }
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce talloc_set_destructor(cctx, sss_nss_crypto_ctx_destructor);
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce cctx->slot = PK11_GetBestSlot(mech_props->cipher, NULL);
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce if (cctx->slot == NULL) {
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce DEBUG(SSSDBG_CRIT_FAILURE, "Unable to find security device (err %d)\n",
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce PR_GetError());
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce ret = EIO;
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce goto done;
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce }
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce if (keylen > 0) {
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce cctx->key = talloc(cctx, SECItem);
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce if (cctx->key == NULL) {
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce DEBUG(SSSDBG_CRIT_FAILURE,
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce "Failed to allocate Key buffer\n");
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce ret = ENOMEM;
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce goto done;
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce }
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce if (key) {
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce MAKE_SECITEM(key, keylen, cctx->key);
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce } else {
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce ret = generate_random_key(cctx, cctx->slot,
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce mech_props, &cctx->key);
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce if (ret != EOK) {
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce DEBUG(SSSDBG_CRIT_FAILURE,
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce "Could not generate encryption key\n");
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce goto done;
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce }
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce }
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce }
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce if (ivlen > 0) {
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce cctx->iv = talloc(cctx, SECItem);
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce if (cctx->iv == NULL) {
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce DEBUG(SSSDBG_CRIT_FAILURE, "Failed to allocate IV buffer\n");
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce ret = ENOMEM;
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce goto done;
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce }
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce if (iv) {
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce MAKE_SECITEM(iv, ivlen, cctx->iv);
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce } else {
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce ret = generate_random_key(cctx, cctx->slot,
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce mech_props, &cctx->iv);
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce if (ret != EOK) {
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce DEBUG(SSSDBG_CRIT_FAILURE,
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce "Could not generate initialization vector\n");
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce goto done;
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce }
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce }
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce }
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce ret = EOK;
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce *_cctx = cctx;
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorcedone:
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce if (ret) talloc_zfree(cctx);
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce return ret;
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce}
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorceint nss_crypto_init(struct crypto_mech_data *mech_props,
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce enum crypto_mech_op crypto_op,
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce struct sss_nss_crypto_ctx *cctx)
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce{
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce CK_ATTRIBUTE_TYPE op;
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce int ret;
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce switch (crypto_op) {
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce case op_encrypt:
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce op = CKA_ENCRYPT;
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce break;
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce case op_decrypt:
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce op = CKA_DECRYPT;
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce break;
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce case op_sign:
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce op = CKA_SIGN;
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce break;
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce default:
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce return EFAULT;
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce }
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce /* turn the raw key into a key object */
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce cctx->keyobj = PK11_ImportSymKey(cctx->slot, mech_props->cipher,
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce PK11_OriginUnwrap, op, cctx->key, NULL);
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce if (cctx->keyobj == NULL) {
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce DEBUG(SSSDBG_CRIT_FAILURE, "Failure to import key into NSS (err %d)\n",
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce PR_GetError());
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce ret = EIO;
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce goto done;
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce }
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce if (crypto_op == op_encrypt || crypto_op == op_decrypt) {
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce /* turn the raw IV into a initialization vector object */
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce cctx->sparam = PK11_ParamFromIV(mech_props->cipher, cctx->iv);
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce if (cctx->sparam == NULL) {
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce DEBUG(SSSDBG_CRIT_FAILURE,
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce "Failure to set up PKCS11 param (err %d)\n",
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce PR_GetError());
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce ret = EIO;
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce goto done;
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce }
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce } else {
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce cctx->sparam = SECITEM_AllocItem(NULL, NULL, 0);
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce if (cctx->sparam == NULL) {
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce DEBUG(SSSDBG_CRIT_FAILURE, "Failure to allocate SECItem\n");
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce ret = EIO;
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce goto done;
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce }
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce MAKE_SECITEM(NULL, 0, cctx->sparam);
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce }
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce /* Create cipher context */
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce cctx->ectx = PK11_CreateContextBySymKey(mech_props->cipher, op,
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce cctx->keyobj, cctx->sparam);
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce if (cctx->ectx == NULL) {
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce DEBUG(SSSDBG_CRIT_FAILURE, "Cannot create cipher context (err %d)\n",
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce PORT_GetError());
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce ret = EIO;
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce goto done;
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce }
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce ret = EOK;
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorcedone:
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce return ret;
625bb2ddf15e8f305a53afa44e87f2146fa930afSimo Sorce}