Esempio n. 1
0
/*
 * ah_init() is called when an SPI is being set up.
 */
static int
ah_init(struct secasvar *sav, struct xformsw *xsp)
{
	struct cryptoini cria;
	int error;

	error = ah_init0(sav, xsp, &cria);
	return error ? error :
		 crypto_newsession(&sav->tdb_cryptoid, &cria, V_crypto_support);
}
Esempio n. 2
0
/*
 * ah_init() is called when an SPI is being set up.
 */
static int
ah_init(struct secasvar *sav, const struct xformsw *xsp)
{
	struct cryptoini cria;
	int error;

	error = ah_init0(sav, xsp, &cria);
	if (!error)
		error = crypto_newsession(&sav->tdb_cryptoid,
					   &cria, crypto_support);
	return error;
}
Esempio n. 3
0
/*
 * esp_init() is called when an SPI is being set up.
 */
static int
esp_init(struct secasvar *sav, struct xformsw *xsp)
{
	struct enc_xform *txform;
	struct cryptoini cria, crie;
	int keylen;
	int error;

	txform = esp_algorithm_lookup(sav->alg_enc);
	if (txform == NULL) {
		DPRINTF(("%s: unsupported encryption algorithm %d\n",
			__func__, sav->alg_enc));
		return EINVAL;
	}
	if (sav->key_enc == NULL) {
		DPRINTF(("%s: no encoding key for %s algorithm\n",
			 __func__, txform->name));
		return EINVAL;
	}
	if ((sav->flags & (SADB_X_EXT_OLD | SADB_X_EXT_IV4B)) ==
	    SADB_X_EXT_IV4B) {
		DPRINTF(("%s: 4-byte IV not supported with protocol\n",
			__func__));
		return EINVAL;
	}
	/* subtract off the salt, RFC4106, 8.1 and RFC3686, 5.1 */
	keylen = _KEYLEN(sav->key_enc) - SAV_ISCTRORGCM(sav) * 4;
	if (txform->minkey > keylen || keylen > txform->maxkey) {
		DPRINTF(("%s: invalid key length %u, must be in the range "
			"[%u..%u] for algorithm %s\n", __func__,
			keylen, txform->minkey, txform->maxkey,
			txform->name));
		return EINVAL;
	}

	/*
	 * NB: The null xform needs a non-zero blocksize to keep the
	 *      crypto code happy but if we use it to set ivlen then
	 *      the ESP header will be processed incorrectly.  The
	 *      compromise is to force it to zero here.
	 */
	if (SAV_ISCTRORGCM(sav))
		sav->ivlen = 8;	/* RFC4106 3.1 and RFC3686 3.1 */
	else
		sav->ivlen = (txform == &enc_xform_null ? 0 : txform->ivsize);

	/*
	 * Setup AH-related state.
	 */
	if (sav->alg_auth != 0) {
		error = ah_init0(sav, xsp, &cria);
		if (error)
			return error;
	}

	/* NB: override anything set in ah_init0 */
	sav->tdb_xform = xsp;
	sav->tdb_encalgxform = txform;

	/*
	 * Whenever AES-GCM is used for encryption, one
	 * of the AES authentication algorithms is chosen
	 * as well, based on the key size.
	 */
	if (sav->alg_enc == SADB_X_EALG_AESGCM16) {
		switch (keylen) {
		case AES_128_GMAC_KEY_LEN:
			sav->alg_auth = SADB_X_AALG_AES128GMAC;
			sav->tdb_authalgxform = &auth_hash_nist_gmac_aes_128;
			break;
		case AES_192_GMAC_KEY_LEN:
			sav->alg_auth = SADB_X_AALG_AES192GMAC;
			sav->tdb_authalgxform = &auth_hash_nist_gmac_aes_192;
			break;
		case AES_256_GMAC_KEY_LEN:
			sav->alg_auth = SADB_X_AALG_AES256GMAC;
			sav->tdb_authalgxform = &auth_hash_nist_gmac_aes_256;
			break;
		default:
			DPRINTF(("%s: invalid key length %u"
				 "for algorithm %s\n", __func__,
				 keylen, txform->name));
			return EINVAL;
		}
		bzero(&cria, sizeof(cria));
		cria.cri_alg = sav->tdb_authalgxform->type;
		cria.cri_key = sav->key_enc->key_data;
		cria.cri_klen = _KEYBITS(sav->key_enc) - SAV_ISGCM(sav) * 32;
	}

	/* Initialize crypto session. */
	bzero(&crie, sizeof(crie));
	crie.cri_alg = sav->tdb_encalgxform->type;
	crie.cri_key = sav->key_enc->key_data;
	crie.cri_klen = _KEYBITS(sav->key_enc) - SAV_ISCTRORGCM(sav) * 32;

	if (sav->tdb_authalgxform && sav->tdb_encalgxform) {
		/* init both auth & enc */
		crie.cri_next = &cria;
		error = crypto_newsession(&sav->tdb_cryptoid,
					  &crie, V_crypto_support);
	} else if (sav->tdb_encalgxform) {
		error = crypto_newsession(&sav->tdb_cryptoid,
					  &crie, V_crypto_support);
	} else if (sav->tdb_authalgxform) {
		error = crypto_newsession(&sav->tdb_cryptoid,
					  &cria, V_crypto_support);
	} else {
		/* XXX cannot happen? */
		DPRINTF(("%s: no encoding OR authentication xform!\n",
			__func__));
		error = EINVAL;
	}
	return error;
}
Esempio n. 4
0
/*
 * esp_init() is called when an SPI is being set up.
 */
static int
esp_init(struct secasvar *sav, struct xformsw *xsp)
{
	struct enc_xform *txform;
	struct cryptoini cria, crie;
	int keylen;
	int error;

	txform = esp_algorithm_lookup(sav->alg_enc);
	if (txform == NULL) {
		DPRINTF(("%s: unsupported encryption algorithm %d\n",
			__func__, sav->alg_enc));
		return EINVAL;
	}
	if (sav->key_enc == NULL) {
		DPRINTF(("%s: no encoding key for %s algorithm\n",
			 __func__, txform->name));
		return EINVAL;
	}
	if ((sav->flags&(SADB_X_EXT_OLD|SADB_X_EXT_IV4B)) == SADB_X_EXT_IV4B) {
		DPRINTF(("%s: 4-byte IV not supported with protocol\n",
			__func__));
		return EINVAL;
	}
	keylen = _KEYLEN(sav->key_enc);
	if (txform->minkey > keylen || keylen > txform->maxkey) {
		DPRINTF(("%s: invalid key length %u, must be in the range "
			"[%u..%u] for algorithm %s\n", __func__,
			keylen, txform->minkey, txform->maxkey,
			txform->name));
		return EINVAL;
	}

	/*
	 * NB: The null xform needs a non-zero blocksize to keep the
	 *      crypto code happy but if we use it to set ivlen then
	 *      the ESP header will be processed incorrectly.  The
	 *      compromise is to force it to zero here.
	 */
	sav->ivlen = (txform == &enc_xform_null ? 0 : txform->blocksize);
	sav->iv = (caddr_t) malloc(sav->ivlen, M_XDATA, M_WAITOK);
	if (sav->iv == NULL) {
		DPRINTF(("%s: no memory for IV\n", __func__));
		return EINVAL;
	}
	key_randomfill(sav->iv, sav->ivlen);	/*XXX*/

	/*
	 * Setup AH-related state.
	 */
	if (sav->alg_auth != 0) {
		error = ah_init0(sav, xsp, &cria);
		if (error)
			return error;
	}

	/* NB: override anything set in ah_init0 */
	sav->tdb_xform = xsp;
	sav->tdb_encalgxform = txform;

	/* Initialize crypto session. */
	bzero(&crie, sizeof (crie));
	crie.cri_alg = sav->tdb_encalgxform->type;
	crie.cri_klen = _KEYBITS(sav->key_enc);
	crie.cri_key = sav->key_enc->key_data;
	/* XXX Rounds ? */

	if (sav->tdb_authalgxform && sav->tdb_encalgxform) {
		/* init both auth & enc */
		crie.cri_next = &cria;
		error = crypto_newsession(&sav->tdb_cryptoid,
					  &crie, V_crypto_support);
	} else if (sav->tdb_encalgxform) {
		error = crypto_newsession(&sav->tdb_cryptoid,
					  &crie, V_crypto_support);
	} else if (sav->tdb_authalgxform) {
		error = crypto_newsession(&sav->tdb_cryptoid,
					  &cria, V_crypto_support);
	} else {
		/* XXX cannot happen? */
		DPRINTF(("%s: no encoding OR authentication xform!\n",
			__func__));
		error = EINVAL;
	}
	return error;
}
/*
 * esp_init() is called when an SPI is being set up.
 */
static int
esp_init(struct secasvar *sav, const struct xformsw *xsp)
{
    const struct enc_xform *txform;
    struct cryptoini cria, crie;
    int keylen;
    int error;

    txform = esp_algorithm_lookup(sav->alg_enc);
    if (txform == NULL) {
        DPRINTF(("esp_init: unsupported encryption algorithm %d\n",
                 sav->alg_enc));
        return EINVAL;
    }
    if (sav->key_enc == NULL) {
        DPRINTF(("esp_init: no encoding key for %s algorithm\n",
                 txform->name));
        return EINVAL;
    }
    if ((sav->flags&(SADB_X_EXT_OLD|SADB_X_EXT_IV4B)) == SADB_X_EXT_IV4B) {
        DPRINTF(("esp_init: 4-byte IV not supported with protocol\n"));
        return EINVAL;
    }
    keylen = _KEYLEN(sav->key_enc);
    if (txform->minkey > keylen || keylen > txform->maxkey) {
        DPRINTF(("esp_init: invalid key length %u, must be in "
                 "the range [%u..%u] for algorithm %s\n",
                 keylen, txform->minkey, txform->maxkey,
                 txform->name));
        return EINVAL;
    }

    sav->ivlen = txform->ivsize;

    /*
     * Setup AH-related state.
     */
    if (sav->alg_auth != 0) {
        error = ah_init0(sav, xsp, &cria);
        if (error)
            return error;
    }

    /* NB: override anything set in ah_init0 */
    sav->tdb_xform = xsp;
    sav->tdb_encalgxform = txform;

    if (sav->alg_enc == SADB_X_EALG_AESGCM16 ||
            sav->alg_enc == SADB_X_EALG_AESGMAC) {
        switch (keylen) {
        case 20:
            sav->alg_auth = SADB_X_AALG_AES128GMAC;
            sav->tdb_authalgxform = &auth_hash_gmac_aes_128;
            break;
        case 28:
            sav->alg_auth = SADB_X_AALG_AES192GMAC;
            sav->tdb_authalgxform = &auth_hash_gmac_aes_192;
            break;
        case 36:
            sav->alg_auth = SADB_X_AALG_AES256GMAC;
            sav->tdb_authalgxform = &auth_hash_gmac_aes_256;
            break;
        }
        memset(&cria, 0, sizeof(cria));
        cria.cri_alg = sav->tdb_authalgxform->type;
        cria.cri_klen = _KEYBITS(sav->key_enc);
        cria.cri_key = _KEYBUF(sav->key_enc);
    }

    /* Initialize crypto session. */
    memset(&crie, 0, sizeof (crie));
    crie.cri_alg = sav->tdb_encalgxform->type;
    crie.cri_klen = _KEYBITS(sav->key_enc);
    crie.cri_key = _KEYBUF(sav->key_enc);
    /* XXX Rounds ? */

    if (sav->tdb_authalgxform && sav->tdb_encalgxform) {
        /* init both auth & enc */
        crie.cri_next = &cria;
        error = crypto_newsession(&sav->tdb_cryptoid,
                                  &crie, crypto_support);
    } else if (sav->tdb_encalgxform) {
        error = crypto_newsession(&sav->tdb_cryptoid,
                                  &crie, crypto_support);
    } else if (sav->tdb_authalgxform) {
        error = crypto_newsession(&sav->tdb_cryptoid,
                                  &cria, crypto_support);
    } else {
        /* XXX cannot happen? */
        DPRINTF(("esp_init: no encoding OR authentication xform!\n"));
        error = EINVAL;
    }
    return error;
}