/*
- * Copyright (c) 2008 Apple Inc. All rights reserved.
+ * Copyright (c) 2008-2016 Apple Inc. All rights reserved.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- *
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* unlawful or unlicensed copies of an Apple operating system, or to
* circumvent, violate, or enable the circumvention or violation of, any
* terms of an Apple operating system software license agreement.
- *
+ *
* Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this file.
- *
+ *
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
- *
+ *
* @APPLE_OSREFERENCE_LICENSE_HEADER_END@
*/
int
-esp_cbc_decrypt_aes(m, off, sav, algo, ivlen)
- struct mbuf *m;
- size_t off;
- struct secasvar *sav;
- const struct esp_algorithm *algo;
- int ivlen;
+esp_cbc_decrypt_aes(
+ struct mbuf *m,
+ size_t off,
+ struct secasvar *sav,
+ const struct esp_algorithm *algo,
+ int ivlen)
{
struct mbuf *s;
struct mbuf *d, *d0, *dp;
{
lck_mtx_assert(sadb_mutex, LCK_MTX_ASSERT_OWNED);
aes_gcm_ctx *ctx = (aes_gcm_ctx*)P2ROUNDUP(sav->sched, ESP_GCM_ALIGN);
+ u_int ivlen = sav->ivlen;
+ unsigned char nonce[ESP_GCM_SALT_LEN+ivlen];
int rc;
ctx->decrypt = &ctx->ctxt[0];
return (rc);
}
- rc = aes_encrypt_key_gcm((const unsigned char *) _KEYBUF(sav->key_enc), _KEYLEN(sav->key_enc)-ESP_GCM_SALT_LEN, ctx->encrypt);
+ bzero(nonce, ESP_GCM_SALT_LEN + ivlen);
+ memcpy(nonce, _KEYBUF(sav->key_enc)+_KEYLEN(sav->key_enc)-ESP_GCM_SALT_LEN, ESP_GCM_SALT_LEN);
+ memcpy(nonce+ESP_GCM_SALT_LEN, sav->iv, ivlen);
+
+ rc = aes_encrypt_key_with_iv_gcm((const unsigned char *) _KEYBUF(sav->key_enc), _KEYLEN(sav->key_enc)-ESP_GCM_SALT_LEN, nonce, ctx->encrypt);
if (rc) {
return (rc);
}
+
+ rc = aes_encrypt_reset_gcm(ctx->encrypt);
+ if (rc) {
+ return (rc);
+ }
+
return (rc);
}
int scutoff;
int i, len;
unsigned char nonce[ESP_GCM_SALT_LEN+ivlen];
-
+
if (ivlen != ESP_GCM_IVLEN) {
ipseclog((LOG_ERR, "%s: unsupported ivlen %d\n", __FUNCTION__, ivlen));
m_freem(m);
bodyoff = off + sizeof(struct newesp) + ivlen;
}
- m_copyback(m, ivoff, ivlen, sav->iv);
+ bzero(nonce, ESP_GCM_SALT_LEN+ivlen);
+ /* generate new iv */
+ ctx = (aes_gcm_ctx *)P2ROUNDUP(sav->sched, ESP_GCM_ALIGN);
- if (m->m_pkthdr.len < bodyoff) {
- ipseclog((LOG_ERR, "%s: bad len %d/%lu\n", __FUNCTION__,
- m->m_pkthdr.len, (u_int32_t)bodyoff));
+ if (aes_encrypt_reset_gcm(ctx->encrypt)) {
+ ipseclog((LOG_ERR, "%s: gcm reset failure\n", __FUNCTION__));
m_freem(m);
return EINVAL;
}
- /* Set IV */
- memcpy(nonce, _KEYBUF(sav->key_enc)+_KEYLEN(sav->key_enc)-ESP_GCM_SALT_LEN, ESP_GCM_SALT_LEN);
- memcpy(nonce+ESP_GCM_SALT_LEN, sav->iv, ivlen);
+ if (aes_encrypt_inc_iv_gcm((unsigned char *)nonce, ctx->encrypt)) {
+ ipseclog((LOG_ERR, "%s: iv generation failure\n", __FUNCTION__));
+ m_freem(m);
+ return EINVAL;
+ }
- ctx = (aes_gcm_ctx *)P2ROUNDUP(sav->sched, ESP_GCM_ALIGN);
- if (aes_encrypt_set_iv_gcm(nonce, sizeof(nonce), ctx->encrypt)) {
- ipseclog((LOG_ERR, "%s: failed to set IV\n", __FUNCTION__));
+ /*
+ * The IV is now generated within corecrypto and
+ * is provided to ESP using aes_encrypt_inc_iv_gcm().
+ * This makes the sav->iv redundant and is no longer
+ * used in GCM operations. But we still copy the IV
+ * back to sav->iv to ensure that any future code reading
+ * this value will get the latest IV.
+ */
+ memcpy(sav->iv, (nonce + ESP_GCM_SALT_LEN), ivlen);
+ m_copyback(m, ivoff, ivlen, sav->iv);
+ bzero(nonce, ESP_GCM_SALT_LEN+ivlen);
+
+ if (m->m_pkthdr.len < bodyoff) {
+ ipseclog((LOG_ERR, "%s: bad len %d/%lu\n", __FUNCTION__,
+ m->m_pkthdr.len, (u_int32_t)bodyoff));
m_freem(m);
- bzero(nonce, sizeof(nonce));
return EINVAL;
}
- bzero(nonce, sizeof(nonce));
/* Set Additional Authentication Data */
if (!(sav->flags & SADB_X_EXT_OLD)) {
sp_aligned = NULL;
}
- /* generate new iv */
- key_sa_stir_iv(sav);
-
return 0;
}
int
-esp_gcm_decrypt_aes(m, off, sav, algo, ivlen)
- struct mbuf *m;
- size_t off;
- struct secasvar *sav;
- const struct esp_algorithm *algo __unused;
- int ivlen;
+esp_gcm_decrypt_aes(
+ struct mbuf *m,
+ size_t off,
+ struct secasvar *sav,
+ const struct esp_algorithm *algo __unused,
+ int ivlen)
{
struct mbuf *s;
struct mbuf *d, *d0, *dp;