summaryrefslogtreecommitdiffstats
path: root/src/util/crypto/nss/nss_obfuscate.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/util/crypto/nss/nss_obfuscate.c')
-rw-r--r--src/util/crypto/nss/nss_obfuscate.c214
1 files changed, 14 insertions, 200 deletions
diff --git a/src/util/crypto/nss/nss_obfuscate.c b/src/util/crypto/nss/nss_obfuscate.c
index 8c6bdc525..a55f22b6d 100644
--- a/src/util/crypto/nss/nss_obfuscate.c
+++ b/src/util/crypto/nss/nss_obfuscate.c
@@ -31,42 +31,17 @@
*/
#include "config.h"
-
#include <prerror.h>
-#include <nss.h>
#include <pk11func.h>
-#include <base64.h>
-#include <talloc.h>
#include "util/util.h"
#include "util/crypto/sss_crypto.h"
#include "util/crypto/nss/nss_util.h"
+#include "util/crypto/nss/nss_crypto.h"
#define OBF_BUFFER_SENTINEL "\0\1\2\3"
#define OBF_BUFFER_SENTINEL_SIZE 4
-#define MAKE_SECITEM(sdata, slen, sitem) do { \
- (sitem)->type = (siBuffer); \
- (sitem)->data = (sdata); \
- (sitem)->len = (slen); \
-} while(0)
-
-struct sss_nss_crypto_ctx {
- PK11SlotInfo *slot;
- PK11Context *ectx;
- PK11SymKey *keyobj;
- SECItem *sparam;
-
- SECItem *iv;
- SECItem *key;
-};
-
-struct crypto_mech_data {
- CK_MECHANISM_TYPE cipher;
- uint16_t keylen;
- uint16_t bsize;
-};
-
static struct crypto_mech_data cmdata[] = {
/* AES with automatic padding, 256b key, 128b block */
{ CKM_AES_CBC_PAD, 32, 16 },
@@ -83,147 +58,6 @@ static struct crypto_mech_data *get_crypto_mech_data(enum obfmethod meth)
return &cmdata[meth];
}
-static int generate_random_key(TALLOC_CTX *mem_ctx,
- PK11SlotInfo *slot,
- struct crypto_mech_data *mech_props,
- SECItem **_key)
-{
- SECStatus sret;
- SECItem *randkeydata;
- SECItem *key = NULL;
- PK11SymKey *randkey;
- int ret;
-
- randkey = PK11_KeyGen(slot, mech_props->cipher,
- NULL, mech_props->keylen, NULL);
- if (randkey == NULL) {
- DEBUG(SSSDBG_CRIT_FAILURE, "Failure to generate key (err %d)\n",
- PR_GetError());
- ret = EIO;
- goto done;
- }
-
- sret = PK11_ExtractKeyValue(randkey);
- if (sret != SECSuccess) {
- DEBUG(SSSDBG_CRIT_FAILURE, "Failure to extract key value (err %d)\n",
- PR_GetError());
- ret = EIO;
- goto done;
- }
-
- randkeydata = PK11_GetKeyData(randkey);
- if (randkeydata == NULL) {
- DEBUG(SSSDBG_CRIT_FAILURE, "Failure to get key data (err %d)\n",
- PR_GetError());
- ret = EIO;
- goto done;
- }
-
- /* randkeydata is valid until randkey is. Copy with talloc to
- * get a nice memory hierarchy symmetrical in encrypt
- * and decrypt case */
- key = talloc_zero(mem_ctx, SECItem);
- if (!key) {
- ret = ENOMEM;
- goto done;
- }
-
- key->data = talloc_memdup(key, randkeydata->data, randkeydata->len);
- if (!key->data) {
- ret = ENOMEM;
- goto done;
- }
- key->len = randkeydata->len;
-
- *_key = key;
- ret = EOK;
-done:
- if (ret != EOK) talloc_zfree(key);
- PK11_FreeSymKey(randkey);
- return ret;
-}
-
-static int sss_nss_crypto_ctx_destructor(struct sss_nss_crypto_ctx *cctx)
-{
- if (cctx->ectx) PK11_DestroyContext(cctx->ectx, PR_TRUE);
- if (cctx->sparam) SECITEM_FreeItem(cctx->sparam, PR_TRUE);
- if (cctx->slot) PK11_FreeSlot(cctx->slot);
- if (cctx->keyobj) PK11_FreeSymKey(cctx->keyobj);
-
- return EOK;
-}
-
-static int nss_ctx_init(TALLOC_CTX *mem_ctx,
- struct crypto_mech_data *mech_props,
- struct sss_nss_crypto_ctx **_cctx)
-{
- struct sss_nss_crypto_ctx *cctx;
- int ret;
-
- cctx = talloc_zero(mem_ctx, struct sss_nss_crypto_ctx);
- if (!cctx) {
- return ENOMEM;
- }
- talloc_set_destructor(cctx, sss_nss_crypto_ctx_destructor);
-
- cctx->slot = PK11_GetBestSlot(mech_props->cipher, NULL);
- if (cctx->slot == NULL) {
- DEBUG(SSSDBG_CRIT_FAILURE, "Unable to find security device (err %d)\n",
- PR_GetError());
- ret = EIO;
- goto done;
- }
-
- ret = EOK;
- *_cctx = cctx;
-done:
- if (ret) talloc_zfree(cctx);
- return ret;
-}
-
-static int nss_encrypt_decrypt_init(struct crypto_mech_data *mech_props,
- bool do_encrypt,
- struct sss_nss_crypto_ctx *cctx)
-{
- CK_ATTRIBUTE_TYPE op;
- int ret;
-
- op = do_encrypt ? CKA_ENCRYPT : CKA_DECRYPT;
-
- /* turn the raw key into a key object */
- cctx->keyobj = PK11_ImportSymKey(cctx->slot, mech_props->cipher,
- PK11_OriginUnwrap, op, cctx->key, NULL);
- if (cctx->keyobj == NULL) {
- DEBUG(SSSDBG_CRIT_FAILURE, "Failure to import key into NSS (err %d)\n",
- PR_GetError());
- ret = EIO;
- goto done;
- }
-
- /* turn the raw IV into a initialization vector object */
- cctx->sparam = PK11_ParamFromIV(mech_props->cipher, cctx->iv);
- if (cctx->sparam == NULL) {
- DEBUG(SSSDBG_CRIT_FAILURE, "Failure to set up PKCS11 param (err %d)\n",
- PR_GetError());
- ret = EIO;
- goto done;
- }
-
- /* Create cipher context */
- cctx->ectx = PK11_CreateContextBySymKey(mech_props->cipher, op,
- cctx->keyobj, cctx->sparam);
- if (cctx->ectx == NULL) {
- DEBUG(SSSDBG_CRIT_FAILURE, "Cannot create cipher context (err %d)\n",
- PORT_GetError());
- ret = EIO;
- goto done;
- }
-
- ret = EOK;
-done:
- return ret;
-}
-
int sss_password_encrypt(TALLOC_CTX *mem_ctx, const char *password, int plen,
enum obfmethod meth, char **obfpwd)
{
@@ -263,27 +97,14 @@ int sss_password_encrypt(TALLOC_CTX *mem_ctx, const char *password, int plen,
goto done;
}
- ret = nss_ctx_init(tmp_ctx, mech_props, &cctx);
+ /* Initiualize ctx and generate random encryption and IV key */
+ ret = nss_ctx_init(tmp_ctx, mech_props, NULL, 1, NULL, 1, &cctx);
if (ret) {
DEBUG(SSSDBG_CRIT_FAILURE, "Cannot initialize NSS context\n");
goto done;
}
- /* generate random encryption and IV key */
- ret = generate_random_key(cctx, cctx->slot, mech_props, &cctx->key);
- if (ret != EOK) {
- DEBUG(SSSDBG_CRIT_FAILURE, "Could not generate encryption key\n");
- goto done;
- }
-
- ret = generate_random_key(cctx, cctx->slot, mech_props, &cctx->iv);
- if (ret != EOK) {
- DEBUG(SSSDBG_CRIT_FAILURE,
- "Could not generate initialization vector\n");
- goto done;
- }
-
- ret = nss_encrypt_decrypt_init(mech_props, true, cctx);
+ ret = nss_crypto_init(mech_props, op_encrypt, cctx);
if (ret) {
DEBUG(SSSDBG_CRIT_FAILURE,
"Cannot initialize NSS context properties\n");
@@ -431,7 +252,8 @@ int sss_password_decrypt(TALLOC_CTX *mem_ctx, char *b64encoded,
memcpy(sentinel_check,
obfbuf + p + mech_props->keylen + mech_props->bsize + ctsize,
OBF_BUFFER_SENTINEL_SIZE);
- if (memcmp(sentinel_check, OBF_BUFFER_SENTINEL, OBF_BUFFER_SENTINEL_SIZE) != 0) {
+ if (memcmp(sentinel_check,
+ OBF_BUFFER_SENTINEL, OBF_BUFFER_SENTINEL_SIZE) != 0) {
DEBUG(SSSDBG_FATAL_FAILURE,
"Obfuscation buffer seems corrupt, aborting\n");
ret = EFAULT;
@@ -460,23 +282,15 @@ int sss_password_decrypt(TALLOC_CTX *mem_ctx, char *b64encoded,
}
safealign_memcpy(cryptotext, obfbuf+p, ctsize, &p);
- ret = nss_ctx_init(tmp_ctx, mech_props, &cctx);
+ ret = nss_ctx_init(tmp_ctx, mech_props,
+ keybuf, mech_props->keylen,
+ ivbuf, mech_props->bsize, &cctx);
if (ret) {
DEBUG(SSSDBG_CRIT_FAILURE, "Cannot initialize NSS context\n");
goto done;
}
- cctx->iv = talloc_zero(cctx, SECItem);
- cctx->key = talloc_zero(cctx, SECItem);
- if (!cctx->iv || !cctx->key) {
- ret = ENOMEM;
- goto done;
- }
-
- MAKE_SECITEM(ivbuf, mech_props->bsize, cctx->iv);
- MAKE_SECITEM(keybuf, mech_props->keylen, cctx->key);
-
- ret = nss_encrypt_decrypt_init(mech_props, false, cctx);
+ ret = nss_crypto_init(mech_props, op_decrypt, cctx);
if (ret) {
goto done;
}
@@ -487,8 +301,8 @@ int sss_password_decrypt(TALLOC_CTX *mem_ctx, char *b64encoded,
goto done;
}
- sret = PK11_CipherOp(cctx->ectx, (unsigned char *) pwdbuf, &plainlen, ctsize,
- cryptotext, ctsize);
+ sret = PK11_CipherOp(cctx->ectx, (unsigned char *) pwdbuf, &plainlen,
+ ctsize, cryptotext, ctsize);
if (sret != SECSuccess) {
DEBUG(SSSDBG_CRIT_FAILURE,
"Cannot execute the encryption operation (err %d)\n",
@@ -497,8 +311,8 @@ int sss_password_decrypt(TALLOC_CTX *mem_ctx, char *b64encoded,
goto done;
}
- sret = PK11_DigestFinal(cctx->ectx, (unsigned char *) pwdbuf+plainlen, &digestlen,
- ctsize - plainlen);
+ sret = PK11_DigestFinal(cctx->ectx, (unsigned char *) pwdbuf+plainlen,
+ &digestlen, ctsize - plainlen);
if (sret != SECSuccess) {
DEBUG(SSSDBG_CRIT_FAILURE,
"Cannot execute the encryption operation (err %d)\n",