예제 #1
0
static void
des3_set_key(struct krb5_key_state *ks, const void *in)
{
	void *kp = ks->ks_key;
	struct des3_state *ds = ks->ks_priv;
	struct cryptoini cri[2];

	if (kp != in)
		bcopy(in, kp, ks->ks_class->ec_keylen);

	if (ds->ds_session)
		crypto_freesession(ds->ds_session);

	bzero(cri, sizeof(cri));

	cri[0].cri_alg = CRYPTO_SHA1_HMAC;
	cri[0].cri_klen = 192;
	cri[0].cri_mlen = 0;
	cri[0].cri_key = ks->ks_key;
	cri[0].cri_next = &cri[1];

	cri[1].cri_alg = CRYPTO_3DES_CBC;
	cri[1].cri_klen = 192;
	cri[1].cri_mlen = 0;
	cri[1].cri_key = ks->ks_key;
	cri[1].cri_next = NULL;

	crypto_newsession(&ds->ds_session, cri,
	    CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE);
}
예제 #2
0
static void
aes_set_key(struct krb5_key_state *ks, const void *in)
{
	void *kp = ks->ks_key;
	struct aes_state *as = ks->ks_priv;
	struct cryptoini cri[2];

	if (kp != in)
		bcopy(in, kp, ks->ks_class->ec_keylen);

	if (as->as_session)
		crypto_freesession(as->as_session);

	bzero(cri, sizeof(cri));

	/*
	 * We only want the first 96 bits of the HMAC.
	 */
	cri[0].cri_alg = CRYPTO_SHA1_HMAC;
	cri[0].cri_klen = ks->ks_class->ec_keybits;
	cri[0].cri_mlen = 12;
	cri[0].cri_key = ks->ks_key;
	cri[0].cri_next = &cri[1];

	cri[1].cri_alg = CRYPTO_AES_CBC;
	cri[1].cri_klen = ks->ks_class->ec_keybits;
	cri[1].cri_mlen = 0;
	cri[1].cri_key = ks->ks_key;
	cri[1].cri_next = NULL;

	crypto_newsession(&as->as_session, cri,
	    CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE);
}
예제 #3
0
/* this function returns true if OCF can do the compression */
int ipsec_ocf_comp_sa_init(struct ipsec_sa *ipsp, int compalg)
{
	struct cryptoini cric;
	int error;

	KLIPS_PRINT(debug_pfkey,
		    "klips_debug:ipsec_ocf_comp_sa_init(c=0x%x)\n",
		    compalg);

	memset(&cric, 0, sizeof(cric));

	cric.cri_alg = ipsec_ocf_compalg(compalg);

	if (!cric.cri_alg) {
		KLIPS_PRINT(debug_pfkey, "klips_debug:ipsec_ocf_comp_sa_init: "
			    "invalid compalg=%d given\n", compalg);
		return 0;
	}

	error = crypto_newsession(&ipsp->ocf_cryptoid, &cric, ipsec_ocf_crid);
	if (error) {
		KLIPS_PRINT(debug_pfkey, "klips_debug:ipsec_ocf_comp_sa_init: "
			    "crypto_newsession failed 0x%x\n", error);
		return 0;
	}

	ipsp->ocf_in_use = 1;
	return 1;
}
예제 #4
0
static int
ocf_init(void)
{
	int error;
	struct cryptoini crie, cria;
	struct cryptodesc crda, crde;

	memset(&crie, 0, sizeof(crie));
	memset(&cria, 0, sizeof(cria));
	memset(&crde, 0, sizeof(crde));
	memset(&crda, 0, sizeof(crda));

	cria.cri_alg  = CRYPTO_SHA1_HMAC;
	cria.cri_klen = 20 * 8;
	cria.cri_key  = "0123456789abcdefghij";

	crie.cri_alg  = CRYPTO_3DES_CBC;
	crie.cri_klen = 24 * 8;
	crie.cri_key  = "0123456789abcdefghijklmn";

	crie.cri_next = &cria;

	error = crypto_newsession(&ocf_cryptoid, &crie, 0);
	if (error) {
		printk("crypto_newsession failed %d\n", error);
		return -1;
	}
	return 0;
}
예제 #5
0
static int
g_eli_crypto_cipher(u_int algo, int enc, u_char *data, size_t datasize,
    const u_char *key, size_t keysize)
{
	struct cryptoini cri;
	struct cryptop *crp;
	struct cryptodesc *crd;
	uint64_t sid;
	u_char *p;
	int error;

	KASSERT(algo != CRYPTO_AES_XTS,
	    ("%s: CRYPTO_AES_XTS unexpected here", __func__));

	bzero(&cri, sizeof(cri));
	cri.cri_alg = algo;
	cri.cri_key = __DECONST(void *, key);
	cri.cri_klen = keysize;
	error = crypto_newsession(&sid, &cri, CRYPTOCAP_F_SOFTWARE);
	if (error != 0)
		return (error);
	p = malloc(sizeof(*crp) + sizeof(*crd), M_ELI, M_NOWAIT | M_ZERO);
	if (p == NULL) {
		crypto_freesession(sid);
		return (ENOMEM);
	}
	crp = (struct cryptop *)p;	p += sizeof(*crp);
	crd = (struct cryptodesc *)p;	p += sizeof(*crd);

	crd->crd_skip = 0;
	crd->crd_len = datasize;
	crd->crd_flags = CRD_F_IV_EXPLICIT | CRD_F_IV_PRESENT;
	if (enc)
		crd->crd_flags |= CRD_F_ENCRYPT;
	crd->crd_alg = algo;
	crd->crd_key = __DECONST(void *, key);
	crd->crd_klen = keysize;
	bzero(crd->crd_iv, sizeof(crd->crd_iv));
	crd->crd_next = NULL;

	crp->crp_sid = sid;
	crp->crp_ilen = datasize;
	crp->crp_olen = datasize;
	crp->crp_opaque = NULL;
	crp->crp_callback = g_eli_crypto_done;
	crp->crp_buf = (void *)data;
	crp->crp_flags = CRYPTO_F_CBIFSYNC;
	crp->crp_desc = crd;

	error = crypto_dispatch(crp);
	if (error == 0) {
		while (crp->crp_opaque == NULL)
			tsleep(crp, PRIBIO, "geli", hz / 5);
		error = crp->crp_etype;
	}

	free(crp, M_ELI);
	crypto_freesession(sid);
	return (error);
}
예제 #6
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);
}
예제 #7
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;
}
예제 #8
0
/*
 * ah_init() is called when an SPI is being set up.
 */
int
ah_init(struct tdb *tdbp, struct xformsw *xsp, struct ipsecinit *ii)
{
	struct auth_hash *thash = NULL;
	struct cryptoini cria, crin;

	/* Authentication operation. */
	switch (ii->ii_authalg) {
	case SADB_AALG_MD5HMAC:
		thash = &auth_hash_hmac_md5_96;
		break;

	case SADB_AALG_SHA1HMAC:
		thash = &auth_hash_hmac_sha1_96;
		break;

	case SADB_X_AALG_RIPEMD160HMAC:
		thash = &auth_hash_hmac_ripemd_160_96;
		break;

	case SADB_X_AALG_SHA2_256:
		thash = &auth_hash_hmac_sha2_256_128;
		break;

	case SADB_X_AALG_SHA2_384:
		thash = &auth_hash_hmac_sha2_384_192;
		break;

	case SADB_X_AALG_SHA2_512:
		thash = &auth_hash_hmac_sha2_512_256;
		break;

	case SADB_X_AALG_MD5:
		thash = &auth_hash_key_md5;
		break;

	case SADB_X_AALG_SHA1:
		thash = &auth_hash_key_sha1;
		break;

	default:
		DPRINTF(("ah_init(): unsupported authentication algorithm %d specified\n", ii->ii_authalg));
		return EINVAL;
	}

	if (ii->ii_authkeylen != thash->keysize && thash->keysize != 0) {
		DPRINTF(("ah_init(): keylength %d doesn't match algorithm "
		    "%s keysize (%d)\n", ii->ii_authkeylen, thash->name,
		    thash->keysize));
		return EINVAL;
	}

	tdbp->tdb_xform = xsp;
	tdbp->tdb_authalgxform = thash;
	tdbp->tdb_rpl = AH_HMAC_INITIAL_RPL;

	DPRINTF(("ah_init(): initialized TDB with hash algorithm %s\n",
	    thash->name));

	tdbp->tdb_amxkeylen = ii->ii_authkeylen;
	tdbp->tdb_amxkey = malloc(tdbp->tdb_amxkeylen, M_XDATA, M_WAITOK);

	bcopy(ii->ii_authkey, tdbp->tdb_amxkey, tdbp->tdb_amxkeylen);

	/* Initialize crypto session. */
	bzero(&cria, sizeof(cria));
	cria.cri_alg = tdbp->tdb_authalgxform->type;
	cria.cri_klen = ii->ii_authkeylen * 8;
	cria.cri_key = ii->ii_authkey;

	if ((tdbp->tdb_wnd > 0) && (tdbp->tdb_flags & TDBF_ESN)) {
		bzero(&crin, sizeof(crin));
		crin.cri_alg = CRYPTO_ESN;
		cria.cri_next = &crin;
	}

	return crypto_newsession(&tdbp->tdb_cryptoid, &cria, 0);
}
예제 #9
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;
}
예제 #10
0
int ipsec_ocf_sa_init(struct ipsec_sa *ipsp, int authalg, int encalg)
{
	struct cryptoini crie, cria;
	int error;

	KLIPS_PRINT(debug_pfkey,
		    "klips_debug:ipsec_ocf_sa_init(a=0x%x,e=0x%x)\n",
		    authalg, encalg);

	if (authalg && ipsp->ips_key_bits_a == 0) {
		KLIPS_PRINT(debug_pfkey,
			    "klips_debug:ipsec_ocf_sa_init(a=0x%x,e=0x%x) a-key-bits=0\n",
			    authalg, encalg);
		/* pretend we are happy with this */
		return 1;
	}

	if (encalg && ipsp->ips_key_bits_e == 0) {
		KLIPS_PRINT(debug_pfkey,
			    "klips_debug:ipsec_ocf_sa_init(a=0x%x,e=0x%x) e-key-bits=0\n",
			    authalg, encalg);
		/* pretend we are happy with this */
		return 1;
	}

	if (ipsp->ocf_in_use)
		printk(
			"KLIPS: ipsec_ocf_sa_init received SA is already initted?\n");


	memset(&crie, 0, sizeof(crie));
	memset(&cria, 0, sizeof(cria));

	cria.cri_alg = ipsec_ocf_authalg(authalg);
	cria.cri_klen = ipsp->ips_key_bits_a;
	cria.cri_key  = ipsp->ips_key_a;
	cria.cri_mlen = 12;

	crie.cri_alg = ipsec_ocf_encalg(encalg);
	crie.cri_klen = ipsp->ips_key_bits_e;
	crie.cri_key  = ipsp->ips_key_e;
	switch (crie.cri_alg) {
	case CRYPTO_AES_CBC:
		ipsp->ips_iv_size = 16;
		break;
	case CRYPTO_DES_CBC:
	case CRYPTO_3DES_CBC:
		ipsp->ips_iv_size = 8;
		break;
	default:
		ipsp->ips_iv_size = 0;
		break;
	}
	ipsp->ips_iv_bits = ipsp->ips_iv_size * 8;
	ipsp->ips_auth_bits = ipsp->ips_key_bits_a;

	if (authalg && encalg) {
		crie.cri_next = &cria;
		error = crypto_newsession(&ipsp->ocf_cryptoid, &crie,
					  ipsec_ocf_crid);
	} else if (encalg) {
		error = crypto_newsession(&ipsp->ocf_cryptoid, &crie,
					  ipsec_ocf_crid);
	} else if (authalg) {
		error = crypto_newsession(&ipsp->ocf_cryptoid, &cria,
					  ipsec_ocf_crid);
	} else {
		KLIPS_PRINT(debug_pfkey, "klips_debug:ipsec_ocf_sa_init: "
			    "no authalg or encalg\n");
		return 0;
	}

	if (error) {
		KLIPS_PRINT(debug_pfkey, "klips_debug:ipsec_ocf_sa_init: "
			    "crypto_newsession failed 0x%x\n", error);
		return 0;
	}

	/* make sure no ALG stuff bites us */
	if (ipsp->ips_alg_enc)
		printk("We received an ALG initted SA\n");
	ipsp->ips_alg_enc = NULL;

	ipsp->ocf_in_use = 1;
	return 1;
}
예제 #11
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;
}
예제 #12
0
/*
 * esp_init() is called when an SPI is being set up.
 */
int
esp_init(struct tdb *tdbp, struct xformsw *xsp, struct ipsecinit *ii)
{
	const struct enc_xform *txform = NULL;
	const struct auth_hash *thash = NULL;
	struct cryptoini cria, crie;

	if (!ii->ii_encalg && !ii->ii_authalg) {
		DPRINTF(("esp_init(): neither authentication nor encryption "
		    "algorithm given"));
		return EINVAL;
	}

	if (ii->ii_encalg) {
		switch (ii->ii_encalg) {
		case SADB_EALG_NULL:
			txform = &enc_xform_null;
			break;

		case SADB_EALG_DESCBC:
			txform = &enc_xform_des;
			break;

		case SADB_EALG_3DESCBC:
			txform = &enc_xform_3des;
			break;

		case SADB_X_EALG_AES:
			txform = &enc_xform_rijndael128;
			break;

		case SADB_X_EALG_AESCTR:
			txform = &enc_xform_aes_ctr;
			break;

		case SADB_X_EALG_BLF:
			txform = &enc_xform_blf;
			break;

		case SADB_X_EALG_CAST:
			txform = &enc_xform_cast5;
			break;

		case SADB_X_EALG_SKIPJACK:
			txform = &enc_xform_skipjack;
			break;

		default:
			DPRINTF(("esp_init(): unsupported encryption algorithm %d specified\n", ii->ii_encalg));
			return EINVAL;
		}

		if (ii->ii_enckeylen < txform->minkey) {
			DPRINTF(("esp_init(): keylength %d too small (min length is %d) for algorithm %s\n", ii->ii_enckeylen, txform->minkey, txform->name));
			return EINVAL;
		}

		if (ii->ii_enckeylen > txform->maxkey) {
			DPRINTF(("esp_init(): keylength %d too large (max length is %d) for algorithm %s\n", ii->ii_enckeylen, txform->maxkey, txform->name));
			return EINVAL;
		}

		tdbp->tdb_encalgxform = txform;

		DPRINTF(("esp_init(): initialized TDB with enc algorithm %s\n",
		    txform->name));

		tdbp->tdb_ivlen = txform->ivsize;
		if (tdbp->tdb_flags & TDBF_HALFIV)
			tdbp->tdb_ivlen /= 2;
	}

	if (ii->ii_authalg) {
		switch (ii->ii_authalg) {
		case SADB_AALG_MD5HMAC:
			thash = &auth_hash_hmac_md5_96;
			break;

		case SADB_AALG_SHA1HMAC:
			thash = &auth_hash_hmac_sha1_96;
			break;

		case SADB_X_AALG_RIPEMD160HMAC:
			thash = &auth_hash_hmac_ripemd_160_96;
			break;

		case SADB_X_AALG_SHA2_256:
			thash = &auth_hash_hmac_sha2_256_96;
			break;

		case SADB_X_AALG_SHA2_384:
			thash = &auth_hash_hmac_sha2_384_96;
			break;

		case SADB_X_AALG_SHA2_512:
			thash = &auth_hash_hmac_sha2_512_96;
			break;

		default:
			DPRINTF(("esp_init(): unsupported authentication algorithm %d specified\n", ii->ii_authalg));
			return EINVAL;
		}

		if (ii->ii_authkeylen != thash->keysize) {
			DPRINTF(("esp_init(): keylength %d doesn't match algorithm %s keysize (%d)\n", ii->ii_authkeylen, thash->name, thash->keysize));
			return EINVAL;
		}

		tdbp->tdb_authalgxform = thash;

		DPRINTF(("esp_init(): initialized TDB with hash algorithm %s\n",
		    thash->name));
	}

	tdbp->tdb_xform = xsp;
	tdbp->tdb_bitmap = 0;
	tdbp->tdb_rpl = AH_HMAC_INITIAL_RPL;

	/* Initialize crypto session */
	if (tdbp->tdb_encalgxform) {
		/* Save the raw keys */
		tdbp->tdb_emxkeylen = ii->ii_enckeylen;
		tdbp->tdb_emxkey = malloc(tdbp->tdb_emxkeylen, M_XDATA,
		    M_WAITOK);
		bcopy(ii->ii_enckey, tdbp->tdb_emxkey, tdbp->tdb_emxkeylen);

		bzero(&crie, sizeof(crie));

		crie.cri_alg = tdbp->tdb_encalgxform->type;

		if (tdbp->tdb_authalgxform)
			crie.cri_next = &cria;
		else
			crie.cri_next = NULL;

		crie.cri_klen = ii->ii_enckeylen * 8;
		crie.cri_key = ii->ii_enckey;
		/* XXX Rounds ? */
	}

	if (tdbp->tdb_authalgxform) {
		/* Save the raw keys */
		tdbp->tdb_amxkeylen = ii->ii_authkeylen;
		tdbp->tdb_amxkey = malloc(tdbp->tdb_amxkeylen, M_XDATA,
		    M_WAITOK);
		bcopy(ii->ii_authkey, tdbp->tdb_amxkey, tdbp->tdb_amxkeylen);

		bzero(&cria, sizeof(cria));

		cria.cri_alg = tdbp->tdb_authalgxform->type;
		cria.cri_next = NULL;
		cria.cri_klen = ii->ii_authkeylen * 8;
		cria.cri_key = ii->ii_authkey;
	}

	return crypto_newsession(&tdbp->tdb_cryptoid,
	    (tdbp->tdb_encalgxform ? &crie : &cria), 0);
}
예제 #13
0
/*
 * 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;
}
예제 #14
0
static int
g_eli_crypto_cipher(u_int algo, int enc, u_char *data, size_t datasize,
                    const u_char *key, size_t keysize)
{
    struct cryptoini cri;
    struct cryptop *crp;
    struct cryptodesc *crd;
    struct uio *uio;
    struct iovec *iov;
    uint64_t sid;
    u_char *p;
    int error;

    bzero(&cri, sizeof(cri));
    cri.cri_alg = algo;
    cri.cri_key = __DECONST(void *, key);
    cri.cri_klen = keysize;
    error = crypto_newsession(&sid, &cri, CRYPTOCAP_F_SOFTWARE);
    if (error != 0)
        return (error);
    p = malloc(sizeof(*crp) + sizeof(*crd) + sizeof(*uio) + sizeof(*iov),
               M_ELI, M_NOWAIT | M_ZERO);
    if (p == NULL) {
        crypto_freesession(sid);
        return (ENOMEM);
    }
    crp = (struct cryptop *)p;
    p += sizeof(*crp);
    crd = (struct cryptodesc *)p;
    p += sizeof(*crd);
    uio = (struct uio *)p;
    p += sizeof(*uio);
    iov = (struct iovec *)p;
    p += sizeof(*iov);

    iov->iov_len = datasize;
    iov->iov_base = data;

    uio->uio_iov = iov;
    uio->uio_iovcnt = 1;
    uio->uio_segflg = UIO_SYSSPACE;
    uio->uio_resid = datasize;

    crd->crd_skip = 0;
    crd->crd_len = datasize;
    crd->crd_flags = CRD_F_IV_EXPLICIT | CRD_F_IV_PRESENT;
    if (enc)
        crd->crd_flags |= CRD_F_ENCRYPT;
    crd->crd_alg = algo;
    crd->crd_key = __DECONST(void *, key);
    crd->crd_klen = keysize;
    bzero(crd->crd_iv, sizeof(crd->crd_iv));
    crd->crd_next = NULL;

    crp->crp_sid = sid;
    crp->crp_ilen = datasize;
    crp->crp_olen = datasize;
    crp->crp_opaque = NULL;
    crp->crp_callback = g_eli_crypto_done;
    crp->crp_buf = (void *)uio;
    crp->crp_flags = CRYPTO_F_IOV | CRYPTO_F_CBIFSYNC | CRYPTO_F_REL;
    crp->crp_desc = crd;

    error = crypto_dispatch(crp);
    if (error == 0) {
        while (crp->crp_opaque == NULL)
            tsleep(crp, PRIBIO, "geli", hz / 5);
        error = crp->crp_etype;
    }

    free(crp, M_ELI);
    crypto_freesession(sid);
    return (error);
}