Esempio n. 1
0
File: Util.cpp Progetto: encukou/pki
/*
 * for Secure Messaging in Secure Channel
 */
TPS_PUBLIC PRStatus Util::EncryptData(PK11SymKey *encSessionKey,
			   Buffer &input, Buffer &output)
{
    PRStatus rv = PR_FAILURE;
    SECStatus s = SECFailure;
    //static SECItem noParams = { siBuffer, 0, 0 };
    static unsigned char d[8] = { 0,0,0,0,0,0,0,0 };
    static SECItem ivParams = { siBuffer, d, 8 };
    PK11Context *context = NULL;
    unsigned char result[8];
    int len;
    int i;

    /* this is ECB mode
    context = PK11_CreateContextBySymKey(CKM_DES3_ECB, CKA_ENCRYPT, encSessionKey,
                    &noParams);
    */
    // use CBC mode
    context = PK11_CreateContextBySymKey(CKM_DES3_CBC, CKA_ENCRYPT, encSessionKey,
                    &ivParams);
    if (!context) {
        goto done;
    }

    for(i = 0;i < (int)input.size();i += 8) {
        s = PK11_CipherOp(context, result, &len, 8,
                (unsigned char *)(((BYTE*)input)+i), 8);

        if (s != SECSuccess) {
            goto done;
        }
	output.replace(i, result, 8);
    }

    rv = PR_SUCCESS;
//    RA::Debug("Util::EncryptData", "success");
done:

    //#define VRFY_ENC_SESSION_KEY
    // fix this to use CBC mode later
#ifdef VRFY_ENC_SESSION_KEY
    Buffer enc_key_buffer = Buffer((BYTE *) PK11_GetKeyData(encSessionKey)->data, PK11_GetKeyData(encSessionKey)->len);
        RA::DebugBuffer("Util::EncryptData", "Verifying Encrypted Data",
		&output);
        Buffer out1 = Buffer(16, (BYTE)0);
	PRStatus status = Util::DecryptData(enc_key_buffer, output, out1);
        RA::DebugBuffer("Util::EncryptData", "Decrypted Data",
		&out1);
#endif


    if( context != NULL ) {
        PK11_DestroyContext( context, PR_TRUE );
        context = NULL;
    }

    return rv;
}
Esempio n. 2
0
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;
}
Esempio n. 3
0
void
ssl_PrintKey(sslSocket *ss, const char *msg, PK11SymKey *key)
{
    SECStatus rv;
    SECItem *rawkey;

    rv = PK11_ExtractKeyValue(key);
    if (rv != SECSuccess) {
        ssl_Trace("Could not extract key for %s", msg);
        return;
    }
    rawkey = PK11_GetKeyData(key);
    if (!rawkey) {
        ssl_Trace("Could not extract key for %s", msg);
        return;
    }
    ssl_PrintBuf(ss, msg, rawkey->data, rawkey->len);
}
Esempio n. 4
0
SECStatus
tls13_HkdfExpandLabelRaw(PK11SymKey *prk, SSLHashType baseHash,
                         const PRUint8 *handshakeHash, unsigned int handshakeHashLen,
                         const char *label, unsigned int labelLen,
                         unsigned char *output, unsigned int outputLen)
{
    PK11SymKey *derived = NULL;
    SECItem *rawkey;
    SECStatus rv;

    rv = tls13_HkdfExpandLabel(prk, baseHash, handshakeHash, handshakeHashLen,
                               label, labelLen,
                               kTlsHkdfInfo[baseHash].pkcs11Mech, outputLen,
                               &derived);
    if (rv != SECSuccess || !derived) {
        goto abort;
    }

    rv = PK11_ExtractKeyValue(derived);
    if (rv != SECSuccess) {
        goto abort;
    }

    rawkey = PK11_GetKeyData(derived);
    if (!rawkey) {
        goto abort;
    }

    PORT_Assert(rawkey->len == outputLen);
    memcpy(output, rawkey->data, outputLen);
    PK11_FreeSymKey(derived);

    return SECSuccess;

abort:
    if (derived) {
        PK11_FreeSymKey(derived);
    }
    PORT_SetError(SSL_ERROR_SYM_KEY_CONTEXT_FAILURE);
    return SECFailure;
}
Esempio n. 5
0
void
PrintKey(PK11SymKey *symKey)
{
    char *name = PK11_GetSymKeyNickname(symKey);
    int len = PK11_GetKeyLength(symKey);
    int strength = PK11_GetKeyStrength(symKey, NULL);
    SECItem *value = NULL;
    CK_KEY_TYPE type = PK11_GetSymKeyType(symKey);
    (void) PK11_ExtractKeyValue(symKey);

    value = PK11_GetKeyData(symKey);

    printf("%-20s %3d   %4d   %10s  ", name ? name: " ", len, strength, 
				GetStringFromKeyType(type));
    if (value && value->data) {
	printBuf(value->data, value->len);
    } else {
	printf("<restricted>");
    }
    printf("\n");
}
Esempio n. 6
0
void nss_symkey_log(PK11SymKey *key, const char *msg)
{
	if (key != NULL) {
		DBG(DBG_CRYPT, DBG_log("computed key %s with length =%d", msg,
				       PK11_GetKeyLength(key)));
	} else {
		DBG_log("NULL key %s", msg);
	}

	if (!PK11_IsFIPS()) {
		if (key != NULL) {
			SECStatus status = PK11_ExtractKeyValue(key);
			PR_ASSERT(status == SECSuccess);
			SECItem *keydata = PK11_GetKeyData(key);

			DBG(DBG_CRYPT, DBG_dump("value: ", keydata->data,
						keydata->len));

			/* SECITEM_FreeItem(keydata, PR_TRUE); */
		}
	}
}
Esempio n. 7
0
static void do_serpent(u_int8_t *buf, size_t buf_size, PK11SymKey *key,
		       u_int8_t *iv, bool enc)
{
	serpent_context serpent_ctx;
	u_int8_t iv_bak[SERPENT_CBC_BLOCK_SIZE];
	u_int8_t *new_iv = buf + buf_size - SERPENT_CBC_BLOCK_SIZE;
	u_int8_t *bare_key_ptr;
	size_t bare_key_len;

	/* unpack key from PK11SymKey (or crash!) */
	{
		SECStatus status = PK11_ExtractKeyValue(key);
		SECItem *keydata;

		passert(status == SECSuccess);
		keydata = PK11_GetKeyData(key);
		bare_key_ptr = keydata->data;
		bare_key_len = keydata->len;
		// SECITEM_FreeItem(keydata, PR_TRUE);
	}

	serpent_set_key(&serpent_ctx, bare_key_ptr, bare_key_len);
	/*
	 *	my SERPENT cbc does not touch passed IV (optimization for
	 *	ESP handling), so I must "emulate" des-like IV
	 *	crunching
	 */
	if (!enc) {
		memcpy(iv_bak, new_iv, SERPENT_CBC_BLOCK_SIZE);
		new_iv = iv_bak;
	}

	serpent_cbc_encrypt(&serpent_ctx, buf, buf, buf_size, iv, enc);

	memcpy(iv, new_iv, SERPENT_CBC_BLOCK_SIZE);
}
Esempio n. 8
0
SECStatus
tls13_HkdfExtract(PK11SymKey *ikm1, PK11SymKey *ikm2in, SSLHashType baseHash,
                  PK11SymKey **prkp)
{
    CK_NSS_HKDFParams params;
    SECItem paramsi;
    SECStatus rv;
    SECItem *salt;
    PK11SymKey *prk;
    static const PRUint8 zeroKeyBuf[HASH_LENGTH_MAX];
    PK11SymKey *zeroKey = NULL;
    PK11SlotInfo *slot = NULL;
    PK11SymKey *ikm2;

    params.bExtract = CK_TRUE;
    params.bExpand = CK_FALSE;
    params.pInfo = NULL;
    params.ulInfoLen = 0UL;

    if (ikm1) {
        /* TODO([email protected]): This violates the PKCS#11 key boundary
         * but is imposed on us by the present HKDF interface. */
        rv = PK11_ExtractKeyValue(ikm1);
        if (rv != SECSuccess)
            return rv;

        salt = PK11_GetKeyData(ikm1);
        if (!salt)
            return SECFailure;

        params.pSalt = salt->data;
        params.ulSaltLen = salt->len;
        PORT_Assert(salt->len > 0);
    } else {
        /* Per documentation for CKM_NSS_HKDF_*:
         *
         *  If the optional salt is given, it is used; otherwise, the salt is
         *  set to a sequence of zeros equal in length to the HMAC output.
         */
        params.pSalt = NULL;
        params.ulSaltLen = 0UL;
    }
    paramsi.data = (unsigned char *)&params;
    paramsi.len = sizeof(params);

    PORT_Assert(kTlsHkdfInfo[baseHash].pkcs11Mech);
    PORT_Assert(kTlsHkdfInfo[baseHash].hashSize);
    PORT_Assert(kTlsHkdfInfo[baseHash].hash == baseHash);

    /* A zero ikm2 is a key of hash-length 0s. */
    if (!ikm2in) {
        SECItem zeroItem = {
            siBuffer,
            (unsigned char *)zeroKeyBuf,
            kTlsHkdfInfo[baseHash].hashSize
        };
        slot = PK11_GetInternalSlot();
        if (!slot) {
            return SECFailure;
        }
        zeroKey = PK11_ImportSymKey(slot,
                                    kTlsHkdfInfo[baseHash].pkcs11Mech,
                                    PK11_OriginUnwrap,
                                    CKA_DERIVE, &zeroItem, NULL);
        if (!zeroKey)
            return SECFailure;
        ikm2 = zeroKey;
    } else {
        ikm2 = ikm2in;
    }
    PORT_Assert(ikm2);

    PRINT_BUF(50, (NULL, "HKDF Extract: IKM1/Salt", params.pSalt, params.ulSaltLen));
    PRINT_KEY(50, (NULL, "HKDF Extract: IKM2", ikm2));

    prk = PK11_Derive(ikm2, kTlsHkdfInfo[baseHash].pkcs11Mech,
                      &paramsi, kTlsHkdfInfo[baseHash].pkcs11Mech,
                      CKA_DERIVE, kTlsHkdfInfo[baseHash].hashSize);
    if (zeroKey)
        PK11_FreeSymKey(zeroKey);
    if (slot)
        PK11_FreeSlot(slot);
    if (!prk)
        return SECFailure;

    PRINT_KEY(50, (NULL, "HKDF Extract", prk));
    *prkp = prk;

    return SECSuccess;
}
Esempio n. 9
0
static gchar*
cipher_pbkdf2_nss_sha1(const gchar *passphrase, const gchar *salt,
	guint iter_count, guint out_len)
{
	PK11SlotInfo *slot;
	SECAlgorithmID *algorithm = NULL;
	PK11SymKey *symkey = NULL;
	const SECItem *symkey_data = NULL;
	SECItem salt_item, passphrase_item;
	guchar *passphrase_buff, *salt_buff;
	gchar *ret;

	g_return_val_if_fail(passphrase != NULL, NULL);
	g_return_val_if_fail(iter_count > 0, NULL);
	g_return_val_if_fail(out_len > 0, NULL);

	NSS_NoDB_Init(NULL);

	slot = PK11_GetBestSlot(PK11_AlgtagToMechanism(SEC_OID_PKCS5_PBKDF2),
		NULL);
	if (slot == NULL) {
		purple_debug_error("cipher-test", "NSS: couldn't get slot: "
			"%d\n", PR_GetError());
		return NULL;
	}

	salt_buff = (guchar*)g_strdup(salt ? salt : "");
	salt_item.type = siBuffer;
	salt_item.data = salt_buff;
	salt_item.len = salt ? strlen(salt) : 0;

	algorithm = PK11_CreatePBEV2AlgorithmID(SEC_OID_PKCS5_PBKDF2,
		SEC_OID_AES_256_CBC, SEC_OID_HMAC_SHA1, out_len, iter_count,
		&salt_item);
	if (algorithm == NULL) {
		purple_debug_error("cipher-test", "NSS: couldn't create "
			"algorithm ID: %d\n", PR_GetError());
		PK11_FreeSlot(slot);
		g_free(salt_buff);
		return NULL;
	}

	passphrase_buff = (guchar*)g_strdup(passphrase);
	passphrase_item.type = siBuffer;
	passphrase_item.data = passphrase_buff;
	passphrase_item.len = strlen(passphrase);

	symkey = PK11_PBEKeyGen(slot, algorithm, &passphrase_item, PR_FALSE,
		NULL);
	if (symkey == NULL) {
		purple_debug_error("cipher-test", "NSS: Couldn't generate key: "
			"%d\n", PR_GetError());
		SECOID_DestroyAlgorithmID(algorithm, PR_TRUE);
		PK11_FreeSlot(slot);
		g_free(passphrase_buff);
		g_free(salt_buff);
		return NULL;
	}

	if (PK11_ExtractKeyValue(symkey) == SECSuccess)
		symkey_data = PK11_GetKeyData(symkey);

	if (symkey_data == NULL || symkey_data->data == NULL) {
		purple_debug_error("cipher-test", "NSS: Couldn't extract key "
			"value: %d\n", PR_GetError());
		PK11_FreeSymKey(symkey);
		SECOID_DestroyAlgorithmID(algorithm, PR_TRUE);
		PK11_FreeSlot(slot);
		g_free(passphrase_buff);
		g_free(salt_buff);
		return NULL;
	}

	if (symkey_data->len != out_len) {
		purple_debug_error("cipher-test", "NSS: Invalid key length: %d "
			"(should be %d)\n", symkey_data->len, out_len);
		PK11_FreeSymKey(symkey);
		SECOID_DestroyAlgorithmID(algorithm, PR_TRUE);
		PK11_FreeSlot(slot);
		g_free(passphrase_buff);
		g_free(salt_buff);
		return NULL;
	}

	ret = purple_base16_encode(symkey_data->data, symkey_data->len);

	PK11_FreeSymKey(symkey);
	SECOID_DestroyAlgorithmID(algorithm, PR_TRUE);
	PK11_FreeSlot(slot);
	g_free(passphrase_buff);
	g_free(salt_buff);
	return ret;
}