int NSSCryptoSymmetricKey::decryptCtxInit()

in xsec/enc/NSS/NSSCryptoSymmetricKey.cpp [171:288]


int NSSCryptoSymmetricKey::decryptCtxInit(const unsigned char * iv) {

	// Returns amount of IV data used (in bytes)
	// Sets m_initialised if the key is OK and the IV is OK.

	if (m_initialised)
		return 0;

	if (mp_k == 0) {
		throw XSECCryptoException(XSECCryptoException::SymmetricError,
			"NSS:SymmetricKey - Cannot initialise without key"); 
	}
    else if (m_keyMode == MODE_NONE) {
		throw XSECCryptoException(XSECCryptoException::SymmetricError,
			"NSS:SymmetricKey - Cannot initialise without mode"); 
    }

	// Set up the context according to the required cipher type

	switch (m_keyType) {

	case (XSECCryptoSymmetricKey::KEY_3DES_192) :

		// A 3DES key

		if (m_keyMode == MODE_CBC) {

			if (iv == NULL) {

				return 0;	// Cannot initialise without an IV

			}

            SECItem ivItem;
            ivItem.data = (unsigned char*)iv;
            ivItem.len = 8;
            int encryptAlg = (m_doPad == true ? CKM_DES3_CBC_PAD : CKM_DES3_CBC);

            SECItem * secParam = PK11_ParamFromIV(encryptAlg, &ivItem);
            mp_ctx = PK11_CreateContextBySymKey(encryptAlg, CKA_DECRYPT, mp_k, secParam);

            if (secParam)
                SECITEM_FreeItem(secParam, PR_TRUE);
			
            m_ivSize = 8;
        }
        else if (m_keyMode == MODE_ECB) {
	        SECItem * secParam = PK11_ParamFromIV(CKM_DES3_ECB, NULL);
            mp_ctx = PK11_CreateContextBySymKey(CKM_DES3_ECB, CKA_DECRYPT, mp_k, secParam);
            if (secParam)
                SECITEM_FreeItem(secParam, PR_TRUE);	
            m_ivSize = 0;
		}
        else {
		    throw XSECCryptoException(XSECCryptoException::SymmetricError,
			    "NSS:SymmetricKey - Unrecognized cipher mode");
        }

		break;

	case (XSECCryptoSymmetricKey::KEY_AES_128) :
    case (XSECCryptoSymmetricKey::KEY_AES_192) :
    case (XSECCryptoSymmetricKey::KEY_AES_256) :

		// An AES key

		if (m_keyMode == MODE_CBC) {

			if (iv == NULL) {

				return 0;	// Cannot initialise without an IV

			}

            SECItem ivItem;
            ivItem.data = (unsigned char*)iv;
            ivItem.len = 16;

            SECItem * secParam = PK11_ParamFromIV(CKM_AES_CBC_PAD, &ivItem);
            mp_ctx = PK11_CreateContextBySymKey(CKM_AES_CBC_PAD, CKA_DECRYPT, mp_k, secParam);

            if (secParam)
                SECITEM_FreeItem(secParam, PR_TRUE);

            m_ivSize = 16;

		}
		else if (m_keyMode == MODE_ECB) {

			SECItem * secParam = PK11_ParamFromIV(CKM_AES_ECB, NULL);
			mp_ctx = PK11_CreateContextBySymKey(CKM_AES_ECB, CKA_DECRYPT, mp_k, secParam);
            if (secParam)
                SECITEM_FreeItem(secParam, PR_TRUE);

            m_ivSize = 0;

		}
        else {
		    throw XSECCryptoException(XSECCryptoException::SymmetricError,
			    "NSS:SymmetricKey - Unrecognized cipher mode");
        }

		break;
	
	default :

		// Cannot do this without an IV
		throw XSECCryptoException(XSECCryptoException::SymmetricError,
			"NSS:SymmetricKey - Unknown key type"); 

	}

	// Reset some parameters
	m_initialised = true;

	// Return number of bytes chewed up by IV
	return m_ivSize;
}