1392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom/* ==================================================================== 2392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * Copyright (c) 2011 The OpenSSL Project. All rights reserved. 3392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * 4392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * Redistribution and use in source and binary forms, with or without 5392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * modification, are permitted provided that the following conditions 6392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * are met: 7392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * 8392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * 1. Redistributions of source code must retain the above copyright 9392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * notice, this list of conditions and the following disclaimer. 10392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * 11392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * 2. Redistributions in binary form must reproduce the above copyright 12392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * notice, this list of conditions and the following disclaimer in 13392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * the documentation and/or other materials provided with the 14392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * distribution. 15392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * 16392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * 3. All advertising materials mentioning features or use of this 17392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * software must display the following acknowledgment: 18392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * "This product includes software developed by the OpenSSL Project 19392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 20392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * 21392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 22392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * endorse or promote products derived from this software without 23392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * prior written permission. For written permission, please contact 24392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * openssl-core@openssl.org. 25392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * 26392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * 5. Products derived from this software may not be called "OpenSSL" 27392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * nor may "OpenSSL" appear in their names without prior written 28392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * permission of the OpenSSL Project. 29392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * 30392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * 6. Redistributions of any form whatsoever must retain the following 31392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * acknowledgment: 32392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * "This product includes software developed by the OpenSSL Project 33392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 34392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * 35392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 36392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 37392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 38392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 39392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 40392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 41392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 42392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 43392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 44392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 45392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 46392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * OF THE POSSIBILITY OF SUCH DAMAGE. 47392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * ==================================================================== 48392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom */ 49392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 50392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#include <openssl/crypto.h> 51392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#include "modes_lcl.h" 52392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#include <string.h> 53392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 54392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#ifndef MODES_DEBUG 55392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom# ifndef NDEBUG 56392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom# define NDEBUG 57392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom# endif 58392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif 59392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#include <assert.h> 60392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 61392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom/* First you setup M and L parameters and pass the key schedule. 62392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * This is called once per session setup... */ 63392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromvoid CRYPTO_ccm128_init(CCM128_CONTEXT *ctx, 64392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom unsigned int M,unsigned int L,void *key,block128_f block) 65392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom{ 66392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom memset(ctx->nonce.c,0,sizeof(ctx->nonce.c)); 67392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ctx->nonce.c[0] = ((u8)(L-1)&7) | (u8)(((M-2)/2)&7)<<3; 68392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ctx->blocks = 0; 69392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ctx->block = block; 70392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ctx->key = key; 71392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom} 72392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 73392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom/* !!! Following interfaces are to be called *once* per packet !!! */ 74392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 75392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom/* Then you setup per-message nonce and pass the length of the message */ 76392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromint CRYPTO_ccm128_setiv(CCM128_CONTEXT *ctx, 77392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom const unsigned char *nonce,size_t nlen,size_t mlen) 78392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom{ 79392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom unsigned int L = ctx->nonce.c[0]&7; /* the L parameter */ 80392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 81392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom if (nlen<(14-L)) return -1; /* nonce is too short */ 82392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 83392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom if (sizeof(mlen)==8 && L>=3) { 84392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ctx->nonce.c[8] = (u8)(mlen>>(56%(sizeof(mlen)*8))); 85392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ctx->nonce.c[9] = (u8)(mlen>>(48%(sizeof(mlen)*8))); 86392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ctx->nonce.c[10] = (u8)(mlen>>(40%(sizeof(mlen)*8))); 87392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ctx->nonce.c[11] = (u8)(mlen>>(32%(sizeof(mlen)*8))); 88392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom } 89392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom else 90ff41a4bc41ae1e1391f9b05117623ff70b985983Kenny Root ctx->nonce.u[1] = 0; 91392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 92392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ctx->nonce.c[12] = (u8)(mlen>>24); 93392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ctx->nonce.c[13] = (u8)(mlen>>16); 94392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ctx->nonce.c[14] = (u8)(mlen>>8); 95392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ctx->nonce.c[15] = (u8)mlen; 96392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 97392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ctx->nonce.c[0] &= ~0x40; /* clear Adata flag */ 98392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom memcpy(&ctx->nonce.c[1],nonce,14-L); 99392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 100392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom return 0; 101392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom} 102392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 103392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom/* Then you pass additional authentication data, this is optional */ 104392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromvoid CRYPTO_ccm128_aad(CCM128_CONTEXT *ctx, 105392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom const unsigned char *aad,size_t alen) 106392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom{ unsigned int i; 107392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom block128_f block = ctx->block; 108392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 109392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom if (alen==0) return; 110392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 111392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ctx->nonce.c[0] |= 0x40; /* set Adata flag */ 112392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom (*block)(ctx->nonce.c,ctx->cmac.c,ctx->key), 113392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ctx->blocks++; 114392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 115392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom if (alen<(0x10000-0x100)) { 116392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ctx->cmac.c[0] ^= (u8)(alen>>8); 117392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ctx->cmac.c[1] ^= (u8)alen; 118392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom i=2; 119392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom } 120392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom else if (sizeof(alen)==8 && alen>=(size_t)1<<(32%(sizeof(alen)*8))) { 121392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ctx->cmac.c[0] ^= 0xFF; 122392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ctx->cmac.c[1] ^= 0xFF; 123392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ctx->cmac.c[2] ^= (u8)(alen>>(56%(sizeof(alen)*8))); 124392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ctx->cmac.c[3] ^= (u8)(alen>>(48%(sizeof(alen)*8))); 125392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ctx->cmac.c[4] ^= (u8)(alen>>(40%(sizeof(alen)*8))); 126392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ctx->cmac.c[5] ^= (u8)(alen>>(32%(sizeof(alen)*8))); 127392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ctx->cmac.c[6] ^= (u8)(alen>>24); 128392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ctx->cmac.c[7] ^= (u8)(alen>>16); 129392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ctx->cmac.c[8] ^= (u8)(alen>>8); 130392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ctx->cmac.c[9] ^= (u8)alen; 131392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom i=10; 132392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom } 133392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom else { 134392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ctx->cmac.c[0] ^= 0xFF; 135392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ctx->cmac.c[1] ^= 0xFE; 136392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ctx->cmac.c[2] ^= (u8)(alen>>24); 137392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ctx->cmac.c[3] ^= (u8)(alen>>16); 138392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ctx->cmac.c[4] ^= (u8)(alen>>8); 139392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ctx->cmac.c[5] ^= (u8)alen; 140392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom i=6; 141392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom } 142392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 143392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom do { 144392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom for(;i<16 && alen;++i,++aad,--alen) 145392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ctx->cmac.c[i] ^= *aad; 146392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom (*block)(ctx->cmac.c,ctx->cmac.c,ctx->key), 147392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ctx->blocks++; 148392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom i=0; 149392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom } while (alen); 150392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom} 151392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 152392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom/* Finally you encrypt or decrypt the message */ 153392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 154392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom/* counter part of nonce may not be larger than L*8 bits, 155392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * L is not larger than 8, therefore 64-bit counter... */ 156392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromstatic void ctr64_inc(unsigned char *counter) { 157392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom unsigned int n=8; 158392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom u8 c; 159392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 160392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom counter += 8; 161392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom do { 162392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom --n; 163392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom c = counter[n]; 164392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ++c; 165392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom counter[n] = c; 166392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom if (c) return; 167392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom } while (n); 168392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom} 169392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 170392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromint CRYPTO_ccm128_encrypt(CCM128_CONTEXT *ctx, 171392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom const unsigned char *inp, unsigned char *out, 172392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom size_t len) 173392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom{ 174392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom size_t n; 175392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom unsigned int i,L; 176392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom unsigned char flags0 = ctx->nonce.c[0]; 177392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom block128_f block = ctx->block; 178392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom void * key = ctx->key; 179392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom union { u64 u[2]; u8 c[16]; } scratch; 180392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 181392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom if (!(flags0&0x40)) 182392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom (*block)(ctx->nonce.c,ctx->cmac.c,key), 183392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ctx->blocks++; 184392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 185392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ctx->nonce.c[0] = L = flags0&7; 186392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom for (n=0,i=15-L;i<15;++i) { 187392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom n |= ctx->nonce.c[i]; 188392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ctx->nonce.c[i]=0; 189392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom n <<= 8; 190392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom } 191392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom n |= ctx->nonce.c[15]; /* reconstructed length */ 192392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ctx->nonce.c[15]=1; 193392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 194392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom if (n!=len) return -1; /* length mismatch */ 195392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 196392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ctx->blocks += ((len+15)>>3)|1; 197392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom if (ctx->blocks > (U64(1)<<61)) return -2; /* too much data */ 198392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 199392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom while (len>=16) { 200392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#if defined(STRICT_ALIGNMENT) 201392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom union { u64 u[2]; u8 c[16]; } temp; 202392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 203392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom memcpy (temp.c,inp,16); 204392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ctx->cmac.u[0] ^= temp.u[0]; 205392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ctx->cmac.u[1] ^= temp.u[1]; 206392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#else 207392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ctx->cmac.u[0] ^= ((u64*)inp)[0]; 208392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ctx->cmac.u[1] ^= ((u64*)inp)[1]; 209392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif 210392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom (*block)(ctx->cmac.c,ctx->cmac.c,key); 211392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom (*block)(ctx->nonce.c,scratch.c,key); 212392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ctr64_inc(ctx->nonce.c); 213392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#if defined(STRICT_ALIGNMENT) 214392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom temp.u[0] ^= scratch.u[0]; 215392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom temp.u[1] ^= scratch.u[1]; 216392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom memcpy(out,temp.c,16); 217392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#else 218392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ((u64*)out)[0] = scratch.u[0]^((u64*)inp)[0]; 219392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ((u64*)out)[1] = scratch.u[1]^((u64*)inp)[1]; 220392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif 221392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom inp += 16; 222392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom out += 16; 223392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom len -= 16; 224392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom } 225392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 226392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom if (len) { 227392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom for (i=0; i<len; ++i) ctx->cmac.c[i] ^= inp[i]; 228392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom (*block)(ctx->cmac.c,ctx->cmac.c,key); 229392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom (*block)(ctx->nonce.c,scratch.c,key); 230392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom for (i=0; i<len; ++i) out[i] = scratch.c[i]^inp[i]; 231392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom } 232392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 233392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom for (i=15-L;i<16;++i) 234392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ctx->nonce.c[i]=0; 235392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 236392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom (*block)(ctx->nonce.c,scratch.c,key); 237392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ctx->cmac.u[0] ^= scratch.u[0]; 238392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ctx->cmac.u[1] ^= scratch.u[1]; 239392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 240392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ctx->nonce.c[0] = flags0; 241392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 242392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom return 0; 243392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom} 244392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 245392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromint CRYPTO_ccm128_decrypt(CCM128_CONTEXT *ctx, 246392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom const unsigned char *inp, unsigned char *out, 247392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom size_t len) 248392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom{ 249392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom size_t n; 250392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom unsigned int i,L; 251392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom unsigned char flags0 = ctx->nonce.c[0]; 252392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom block128_f block = ctx->block; 253392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom void * key = ctx->key; 254392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom union { u64 u[2]; u8 c[16]; } scratch; 255392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 256392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom if (!(flags0&0x40)) 257392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom (*block)(ctx->nonce.c,ctx->cmac.c,key); 258392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 259392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ctx->nonce.c[0] = L = flags0&7; 260392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom for (n=0,i=15-L;i<15;++i) { 261392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom n |= ctx->nonce.c[i]; 262392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ctx->nonce.c[i]=0; 263392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom n <<= 8; 264392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom } 265392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom n |= ctx->nonce.c[15]; /* reconstructed length */ 266392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ctx->nonce.c[15]=1; 267392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 268392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom if (n!=len) return -1; 269392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 270392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom while (len>=16) { 271392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#if defined(STRICT_ALIGNMENT) 272392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom union { u64 u[2]; u8 c[16]; } temp; 273392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif 274392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom (*block)(ctx->nonce.c,scratch.c,key); 275392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ctr64_inc(ctx->nonce.c); 276392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#if defined(STRICT_ALIGNMENT) 277392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom memcpy (temp.c,inp,16); 278392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ctx->cmac.u[0] ^= (scratch.u[0] ^= temp.u[0]); 279392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ctx->cmac.u[1] ^= (scratch.u[1] ^= temp.u[1]); 280392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom memcpy (out,scratch.c,16); 281392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#else 282392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ctx->cmac.u[0] ^= (((u64*)out)[0] = scratch.u[0]^((u64*)inp)[0]); 283392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ctx->cmac.u[1] ^= (((u64*)out)[1] = scratch.u[1]^((u64*)inp)[1]); 284392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif 285392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom (*block)(ctx->cmac.c,ctx->cmac.c,key); 286392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 287392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom inp += 16; 288392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom out += 16; 289392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom len -= 16; 290392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom } 291392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 292392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom if (len) { 293392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom (*block)(ctx->nonce.c,scratch.c,key); 294392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom for (i=0; i<len; ++i) 295392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ctx->cmac.c[i] ^= (out[i] = scratch.c[i]^inp[i]); 296392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom (*block)(ctx->cmac.c,ctx->cmac.c,key); 297392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom } 298392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 299392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom for (i=15-L;i<16;++i) 300392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ctx->nonce.c[i]=0; 301392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 302392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom (*block)(ctx->nonce.c,scratch.c,key); 303392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ctx->cmac.u[0] ^= scratch.u[0]; 304392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ctx->cmac.u[1] ^= scratch.u[1]; 305392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 306392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ctx->nonce.c[0] = flags0; 307392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 308392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom return 0; 309392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom} 310392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 311392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromstatic void ctr64_add (unsigned char *counter,size_t inc) 312392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom{ size_t n=8, val=0; 313392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 314392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom counter += 8; 315392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom do { 316392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom --n; 317392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom val += counter[n] + (inc&0xff); 318392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom counter[n] = (unsigned char)val; 319392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom val >>= 8; /* carry bit */ 320392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom inc >>= 8; 321392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom } while(n && (inc || val)); 322392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom} 323392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 324392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromint CRYPTO_ccm128_encrypt_ccm64(CCM128_CONTEXT *ctx, 325392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom const unsigned char *inp, unsigned char *out, 326392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom size_t len,ccm128_f stream) 327392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom{ 328392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom size_t n; 329392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom unsigned int i,L; 330392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom unsigned char flags0 = ctx->nonce.c[0]; 331392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom block128_f block = ctx->block; 332392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom void * key = ctx->key; 333392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom union { u64 u[2]; u8 c[16]; } scratch; 334392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 335392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom if (!(flags0&0x40)) 336392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom (*block)(ctx->nonce.c,ctx->cmac.c,key), 337392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ctx->blocks++; 338392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 339392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ctx->nonce.c[0] = L = flags0&7; 340392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom for (n=0,i=15-L;i<15;++i) { 341392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom n |= ctx->nonce.c[i]; 342392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ctx->nonce.c[i]=0; 343392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom n <<= 8; 344392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom } 345392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom n |= ctx->nonce.c[15]; /* reconstructed length */ 346392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ctx->nonce.c[15]=1; 347392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 348392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom if (n!=len) return -1; /* length mismatch */ 349392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 350392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ctx->blocks += ((len+15)>>3)|1; 351392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom if (ctx->blocks > (U64(1)<<61)) return -2; /* too much data */ 352392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 353392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom if ((n=len/16)) { 354392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom (*stream)(inp,out,n,key,ctx->nonce.c,ctx->cmac.c); 355392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom n *= 16; 356392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom inp += n; 357392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom out += n; 358392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom len -= n; 359392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom if (len) ctr64_add(ctx->nonce.c,n/16); 360392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom } 361392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 362392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom if (len) { 363392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom for (i=0; i<len; ++i) ctx->cmac.c[i] ^= inp[i]; 364392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom (*block)(ctx->cmac.c,ctx->cmac.c,key); 365392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom (*block)(ctx->nonce.c,scratch.c,key); 366392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom for (i=0; i<len; ++i) out[i] = scratch.c[i]^inp[i]; 367392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom } 368392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 369392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom for (i=15-L;i<16;++i) 370392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ctx->nonce.c[i]=0; 371392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 372392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom (*block)(ctx->nonce.c,scratch.c,key); 373392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ctx->cmac.u[0] ^= scratch.u[0]; 374392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ctx->cmac.u[1] ^= scratch.u[1]; 375392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 376392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ctx->nonce.c[0] = flags0; 377392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 378392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom return 0; 379392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom} 380392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 381392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromint CRYPTO_ccm128_decrypt_ccm64(CCM128_CONTEXT *ctx, 382392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom const unsigned char *inp, unsigned char *out, 383392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom size_t len,ccm128_f stream) 384392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom{ 385392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom size_t n; 386392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom unsigned int i,L; 387392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom unsigned char flags0 = ctx->nonce.c[0]; 388392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom block128_f block = ctx->block; 389392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom void * key = ctx->key; 390392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom union { u64 u[2]; u8 c[16]; } scratch; 391392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 392392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom if (!(flags0&0x40)) 393392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom (*block)(ctx->nonce.c,ctx->cmac.c,key); 394392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 395392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ctx->nonce.c[0] = L = flags0&7; 396392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom for (n=0,i=15-L;i<15;++i) { 397392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom n |= ctx->nonce.c[i]; 398392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ctx->nonce.c[i]=0; 399392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom n <<= 8; 400392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom } 401392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom n |= ctx->nonce.c[15]; /* reconstructed length */ 402392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ctx->nonce.c[15]=1; 403392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 404392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom if (n!=len) return -1; 405392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 406392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom if ((n=len/16)) { 407392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom (*stream)(inp,out,n,key,ctx->nonce.c,ctx->cmac.c); 408392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom n *= 16; 409392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom inp += n; 410392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom out += n; 411392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom len -= n; 412392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom if (len) ctr64_add(ctx->nonce.c,n/16); 413392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom } 414392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 415392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom if (len) { 416392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom (*block)(ctx->nonce.c,scratch.c,key); 417392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom for (i=0; i<len; ++i) 418392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ctx->cmac.c[i] ^= (out[i] = scratch.c[i]^inp[i]); 419392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom (*block)(ctx->cmac.c,ctx->cmac.c,key); 420392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom } 421392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 422392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom for (i=15-L;i<16;++i) 423392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ctx->nonce.c[i]=0; 424392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 425392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom (*block)(ctx->nonce.c,scratch.c,key); 426392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ctx->cmac.u[0] ^= scratch.u[0]; 427392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ctx->cmac.u[1] ^= scratch.u[1]; 428392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 429392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ctx->nonce.c[0] = flags0; 430392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 431392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom return 0; 432392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom} 433392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 434392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromsize_t CRYPTO_ccm128_tag(CCM128_CONTEXT *ctx,unsigned char *tag,size_t len) 435392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom{ unsigned int M = (ctx->nonce.c[0]>>3)&7; /* the M parameter */ 436392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 437392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom M *= 2; M += 2; 438392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom if (len<M) return 0; 439392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom memcpy(tag,ctx->cmac.c,M); 440392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom return M; 441392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom} 442