/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* Copyright(c) 2013, Intel Corp. */
/* Wrapper functions for Intel optimized implementation of AES-GCM */
/* first prepare H and its derivatives for ghash */
intel_aes_gcmINIT(gcm->Htbl, (unsignedchar *)aes->k.expandedKey, aes->Nr);
gcm_InitIVContext(&gcm->gcm_iv);
/* if gcmParams is NULL, then we are creating an PKCS #11 MESSAGE * style context, in which we initialize the key once, then do separate * iv/aad's for each message. If we are doing that kind of operation, * we've finished with init here. We'll init the Counter in each AEAD
* call */ if (gcmParams == NULL) { return gcm;
}
/* reset the aad and message length counters */
gcm->Alen = 0;
gcm->Mlen = 0;
// Limit AADLen in accordance with SP800-38D if (sizeof(AAD_whole_len) >= 8 && AAD_whole_len > (1ULL << 61) - 1) {
PORT_SetError(SEC_ERROR_INPUT_LEN); return SECFailure;
} /* Initial TAG value is zero */
_mm_storeu_si128((__m128i *)gcm->T, _mm_setzero_si128());
_mm_storeu_si128((__m128i *)gcm->X0, _mm_setzero_si128());
/* Init the counter */ if (ivLen == 12) {
_mm_storeu_si128((__m128i *)gcm->CTR,
_mm_setr_epi32(((unsignedint *)iv)[0],
((unsignedint *)iv)[1],
((unsignedint *)iv)[2],
0x01000000));
} else { /* If IV size is not 96 bits, then the initial counter value is GHASH
* of the IV */
intel_aes_gcmAAD(gcm->Htbl, (unsignedchar *)iv, IV_whole_len, gcm->T);
/* Partial block */ if (IV_remainder_len) {
PORT_Memset(buff, 0, AES_BLOCK_SIZE);
PORT_Memcpy(buff, iv + IV_whole_len, IV_remainder_len);
intel_aes_gcmAAD(gcm->Htbl, buff, AES_BLOCK_SIZE, gcm->T);
}
/* TAG should be zero again */
_mm_storeu_si128((__m128i *)gcm->T, _mm_setzero_si128());
}
/* Encrypt the initial counter, will be used to encrypt the GHASH value,
* in the end */
rv = (*gcm->cipher)(gcm->aes_context, gcm->X0, &j, AES_BLOCK_SIZE, gcm->CTR,
AES_BLOCK_SIZE, AES_BLOCK_SIZE); if (rv != SECSuccess) { return SECFailure;
}
/* Promote the counter by 1 */
_mm_storeu_si128((__m128i *)gcm->CTR, _mm_shuffle_epi8(_mm_add_epi32(ONE, _mm_shuffle_epi8(_mm_loadu_si128((__m128i *)gcm->CTR), BSWAP_MASK)), BSWAP_MASK));
/* Now hash AAD - it would actually make sense to seperate the context * creation from the AAD, because that would allow to reuse the H, which * only changes when the AES key changes, and not every package, like the
* IV and AAD */
intel_aes_gcmAAD(gcm->Htbl, (unsignedchar *)aad, AAD_whole_len, gcm->T); if (AAD_remainder_len) {
PORT_Memset(buff, 0, AES_BLOCK_SIZE);
PORT_Memcpy(buff, aad + AAD_whole_len, AAD_remainder_len);
intel_aes_gcmAAD(gcm->Htbl, buff, AES_BLOCK_SIZE, gcm->T);
}
gcm->Alen += aadLen; return SECSuccess;
}
// GCM has a 16 octet block, with a 32-bit block counter // Limit in accordance with SP800-38D if (sizeof(inlen) > 4) { unsignedlonglong inlen_ull = inlen; if (inlen_ull >= ((1ULL << 32) - 2) * AES_BLOCK_SIZE) {
PORT_SetError(SEC_ERROR_INPUT_LEN); return SECFailure;
}
} /* paramLen comes all the way from the application layer, make sure
* it's correct */ if (paramLen != sizeof(CK_GCM_MESSAGE_PARAMS)) {
PORT_SetError(SEC_ERROR_INVALID_ARGS); return SECFailure;
}
/* if we were initialized with the C_EncryptInit, we shouldn't be in this
* function */ if (gcm->ctr_context_init) {
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); return SECFailure;
}
/* paramLen comes all the way from the application layer, make sure
* it's correct */ if (paramLen != sizeof(CK_GCM_MESSAGE_PARAMS)) {
PORT_SetError(SEC_ERROR_INVALID_ARGS); return SECFailure;
} /* if we were initialized with the C_DecryptInit, we shouldn't be in this
* function */ if (gcm->ctr_context_init) {
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); return SECFailure;
}
// GCM has a 16 octet block, with a 32-bit block counter // Limit in accordance with SP800-38D if (sizeof(inlen) > 4) { unsignedlonglong inlen_ull = inlen; if (inlen_ull >= ((1ULL << 32) - 2) * AES_BLOCK_SIZE) {
PORT_SetError(SEC_ERROR_INPUT_LEN); return SECFailure;
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.