1238384Sjkim/* ==================================================================== 2238384Sjkim * Copyright (c) 2011 The OpenSSL Project. All rights reserved. 3238384Sjkim * 4238384Sjkim * Redistribution and use in source and binary forms, with or without 5238384Sjkim * modification, are permitted provided that the following conditions 6238384Sjkim * are met: 7238384Sjkim * 8238384Sjkim * 1. Redistributions of source code must retain the above copyright 9280297Sjkim * notice, this list of conditions and the following disclaimer. 10238384Sjkim * 11238384Sjkim * 2. Redistributions in binary form must reproduce the above copyright 12238384Sjkim * notice, this list of conditions and the following disclaimer in 13238384Sjkim * the documentation and/or other materials provided with the 14238384Sjkim * distribution. 15238384Sjkim * 16238384Sjkim * 3. All advertising materials mentioning features or use of this 17238384Sjkim * software must display the following acknowledgment: 18238384Sjkim * "This product includes software developed by the OpenSSL Project 19238384Sjkim * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 20238384Sjkim * 21238384Sjkim * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 22238384Sjkim * endorse or promote products derived from this software without 23238384Sjkim * prior written permission. For written permission, please contact 24238384Sjkim * openssl-core@openssl.org. 25238384Sjkim * 26238384Sjkim * 5. Products derived from this software may not be called "OpenSSL" 27238384Sjkim * nor may "OpenSSL" appear in their names without prior written 28238384Sjkim * permission of the OpenSSL Project. 29238384Sjkim * 30238384Sjkim * 6. Redistributions of any form whatsoever must retain the following 31238384Sjkim * acknowledgment: 32238384Sjkim * "This product includes software developed by the OpenSSL Project 33238384Sjkim * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 34238384Sjkim * 35238384Sjkim * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 36238384Sjkim * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 37238384Sjkim * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 38238384Sjkim * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 39238384Sjkim * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 40238384Sjkim * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 41238384Sjkim * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 42238384Sjkim * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 43238384Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 44238384Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 45238384Sjkim * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 46238384Sjkim * OF THE POSSIBILITY OF SUCH DAMAGE. 47238384Sjkim * ==================================================================== 48238384Sjkim */ 49238384Sjkim 50238384Sjkim#include <openssl/crypto.h> 51238384Sjkim#include "modes_lcl.h" 52238384Sjkim#include <string.h> 53238384Sjkim 54238384Sjkim#ifndef MODES_DEBUG 55238384Sjkim# ifndef NDEBUG 56238384Sjkim# define NDEBUG 57238384Sjkim# endif 58238384Sjkim#endif 59238384Sjkim#include <assert.h> 60238384Sjkim 61280297Sjkim/* 62280297Sjkim * First you setup M and L parameters and pass the key schedule. This is 63280297Sjkim * called once per session setup... 64280297Sjkim */ 65238384Sjkimvoid CRYPTO_ccm128_init(CCM128_CONTEXT *ctx, 66280297Sjkim unsigned int M, unsigned int L, void *key, 67280297Sjkim block128_f block) 68238384Sjkim{ 69280297Sjkim memset(ctx->nonce.c, 0, sizeof(ctx->nonce.c)); 70280297Sjkim ctx->nonce.c[0] = ((u8)(L - 1) & 7) | (u8)(((M - 2) / 2) & 7) << 3; 71280297Sjkim ctx->blocks = 0; 72280297Sjkim ctx->block = block; 73280297Sjkim ctx->key = key; 74238384Sjkim} 75238384Sjkim 76238384Sjkim/* !!! Following interfaces are to be called *once* per packet !!! */ 77238384Sjkim 78238384Sjkim/* Then you setup per-message nonce and pass the length of the message */ 79238384Sjkimint CRYPTO_ccm128_setiv(CCM128_CONTEXT *ctx, 80280297Sjkim const unsigned char *nonce, size_t nlen, size_t mlen) 81238384Sjkim{ 82280297Sjkim unsigned int L = ctx->nonce.c[0] & 7; /* the L parameter */ 83238384Sjkim 84280297Sjkim if (nlen < (14 - L)) 85280297Sjkim return -1; /* nonce is too short */ 86238384Sjkim 87280297Sjkim if (sizeof(mlen) == 8 && L >= 3) { 88280297Sjkim ctx->nonce.c[8] = (u8)(mlen >> (56 % (sizeof(mlen) * 8))); 89280297Sjkim ctx->nonce.c[9] = (u8)(mlen >> (48 % (sizeof(mlen) * 8))); 90280297Sjkim ctx->nonce.c[10] = (u8)(mlen >> (40 % (sizeof(mlen) * 8))); 91280297Sjkim ctx->nonce.c[11] = (u8)(mlen >> (32 % (sizeof(mlen) * 8))); 92280297Sjkim } else 93280297Sjkim ctx->nonce.u[1] = 0; 94238384Sjkim 95280297Sjkim ctx->nonce.c[12] = (u8)(mlen >> 24); 96280297Sjkim ctx->nonce.c[13] = (u8)(mlen >> 16); 97280297Sjkim ctx->nonce.c[14] = (u8)(mlen >> 8); 98280297Sjkim ctx->nonce.c[15] = (u8)mlen; 99238384Sjkim 100280297Sjkim ctx->nonce.c[0] &= ~0x40; /* clear Adata flag */ 101280297Sjkim memcpy(&ctx->nonce.c[1], nonce, 14 - L); 102238384Sjkim 103280297Sjkim return 0; 104238384Sjkim} 105238384Sjkim 106238384Sjkim/* Then you pass additional authentication data, this is optional */ 107238384Sjkimvoid CRYPTO_ccm128_aad(CCM128_CONTEXT *ctx, 108280297Sjkim const unsigned char *aad, size_t alen) 109280297Sjkim{ 110280297Sjkim unsigned int i; 111280297Sjkim block128_f block = ctx->block; 112238384Sjkim 113280297Sjkim if (alen == 0) 114280297Sjkim return; 115238384Sjkim 116280297Sjkim ctx->nonce.c[0] |= 0x40; /* set Adata flag */ 117280297Sjkim (*block) (ctx->nonce.c, ctx->cmac.c, ctx->key), ctx->blocks++; 118238384Sjkim 119280297Sjkim if (alen < (0x10000 - 0x100)) { 120280297Sjkim ctx->cmac.c[0] ^= (u8)(alen >> 8); 121280297Sjkim ctx->cmac.c[1] ^= (u8)alen; 122280297Sjkim i = 2; 123280297Sjkim } else if (sizeof(alen) == 8 124280297Sjkim && alen >= (size_t)1 << (32 % (sizeof(alen) * 8))) { 125280297Sjkim ctx->cmac.c[0] ^= 0xFF; 126280297Sjkim ctx->cmac.c[1] ^= 0xFF; 127280297Sjkim ctx->cmac.c[2] ^= (u8)(alen >> (56 % (sizeof(alen) * 8))); 128280297Sjkim ctx->cmac.c[3] ^= (u8)(alen >> (48 % (sizeof(alen) * 8))); 129280297Sjkim ctx->cmac.c[4] ^= (u8)(alen >> (40 % (sizeof(alen) * 8))); 130280297Sjkim ctx->cmac.c[5] ^= (u8)(alen >> (32 % (sizeof(alen) * 8))); 131280297Sjkim ctx->cmac.c[6] ^= (u8)(alen >> 24); 132280297Sjkim ctx->cmac.c[7] ^= (u8)(alen >> 16); 133280297Sjkim ctx->cmac.c[8] ^= (u8)(alen >> 8); 134280297Sjkim ctx->cmac.c[9] ^= (u8)alen; 135280297Sjkim i = 10; 136280297Sjkim } else { 137280297Sjkim ctx->cmac.c[0] ^= 0xFF; 138280297Sjkim ctx->cmac.c[1] ^= 0xFE; 139280297Sjkim ctx->cmac.c[2] ^= (u8)(alen >> 24); 140280297Sjkim ctx->cmac.c[3] ^= (u8)(alen >> 16); 141280297Sjkim ctx->cmac.c[4] ^= (u8)(alen >> 8); 142280297Sjkim ctx->cmac.c[5] ^= (u8)alen; 143280297Sjkim i = 6; 144280297Sjkim } 145238384Sjkim 146280297Sjkim do { 147280297Sjkim for (; i < 16 && alen; ++i, ++aad, --alen) 148280297Sjkim ctx->cmac.c[i] ^= *aad; 149280297Sjkim (*block) (ctx->cmac.c, ctx->cmac.c, ctx->key), ctx->blocks++; 150280297Sjkim i = 0; 151280297Sjkim } while (alen); 152238384Sjkim} 153238384Sjkim 154238384Sjkim/* Finally you encrypt or decrypt the message */ 155238384Sjkim 156280297Sjkim/* 157280297Sjkim * counter part of nonce may not be larger than L*8 bits, L is not larger 158280297Sjkim * than 8, therefore 64-bit counter... 159280297Sjkim */ 160280297Sjkimstatic void ctr64_inc(unsigned char *counter) 161280297Sjkim{ 162280297Sjkim unsigned int n = 8; 163280297Sjkim u8 c; 164238384Sjkim 165280297Sjkim counter += 8; 166280297Sjkim do { 167280297Sjkim --n; 168280297Sjkim c = counter[n]; 169280297Sjkim ++c; 170280297Sjkim counter[n] = c; 171280297Sjkim if (c) 172280297Sjkim return; 173280297Sjkim } while (n); 174238384Sjkim} 175238384Sjkim 176238384Sjkimint CRYPTO_ccm128_encrypt(CCM128_CONTEXT *ctx, 177280297Sjkim const unsigned char *inp, unsigned char *out, 178280297Sjkim size_t len) 179238384Sjkim{ 180280297Sjkim size_t n; 181280297Sjkim unsigned int i, L; 182280297Sjkim unsigned char flags0 = ctx->nonce.c[0]; 183280297Sjkim block128_f block = ctx->block; 184280297Sjkim void *key = ctx->key; 185280297Sjkim union { 186280297Sjkim u64 u[2]; 187280297Sjkim u8 c[16]; 188280297Sjkim } scratch; 189238384Sjkim 190280297Sjkim if (!(flags0 & 0x40)) 191280297Sjkim (*block) (ctx->nonce.c, ctx->cmac.c, key), ctx->blocks++; 192238384Sjkim 193280297Sjkim ctx->nonce.c[0] = L = flags0 & 7; 194280297Sjkim for (n = 0, i = 15 - L; i < 15; ++i) { 195280297Sjkim n |= ctx->nonce.c[i]; 196280297Sjkim ctx->nonce.c[i] = 0; 197280297Sjkim n <<= 8; 198280297Sjkim } 199280297Sjkim n |= ctx->nonce.c[15]; /* reconstructed length */ 200280297Sjkim ctx->nonce.c[15] = 1; 201238384Sjkim 202280297Sjkim if (n != len) 203280297Sjkim return -1; /* length mismatch */ 204238384Sjkim 205280297Sjkim ctx->blocks += ((len + 15) >> 3) | 1; 206280297Sjkim if (ctx->blocks > (U64(1) << 61)) 207280297Sjkim return -2; /* too much data */ 208238384Sjkim 209280297Sjkim while (len >= 16) { 210238384Sjkim#if defined(STRICT_ALIGNMENT) 211280297Sjkim union { 212280297Sjkim u64 u[2]; 213280297Sjkim u8 c[16]; 214280297Sjkim } temp; 215238384Sjkim 216280297Sjkim memcpy(temp.c, inp, 16); 217280297Sjkim ctx->cmac.u[0] ^= temp.u[0]; 218280297Sjkim ctx->cmac.u[1] ^= temp.u[1]; 219238384Sjkim#else 220280297Sjkim ctx->cmac.u[0] ^= ((u64 *)inp)[0]; 221280297Sjkim ctx->cmac.u[1] ^= ((u64 *)inp)[1]; 222238384Sjkim#endif 223280297Sjkim (*block) (ctx->cmac.c, ctx->cmac.c, key); 224280297Sjkim (*block) (ctx->nonce.c, scratch.c, key); 225280297Sjkim ctr64_inc(ctx->nonce.c); 226238384Sjkim#if defined(STRICT_ALIGNMENT) 227280297Sjkim temp.u[0] ^= scratch.u[0]; 228280297Sjkim temp.u[1] ^= scratch.u[1]; 229280297Sjkim memcpy(out, temp.c, 16); 230238384Sjkim#else 231280297Sjkim ((u64 *)out)[0] = scratch.u[0] ^ ((u64 *)inp)[0]; 232280297Sjkim ((u64 *)out)[1] = scratch.u[1] ^ ((u64 *)inp)[1]; 233238384Sjkim#endif 234280297Sjkim inp += 16; 235280297Sjkim out += 16; 236280297Sjkim len -= 16; 237280297Sjkim } 238238384Sjkim 239280297Sjkim if (len) { 240280297Sjkim for (i = 0; i < len; ++i) 241280297Sjkim ctx->cmac.c[i] ^= inp[i]; 242280297Sjkim (*block) (ctx->cmac.c, ctx->cmac.c, key); 243280297Sjkim (*block) (ctx->nonce.c, scratch.c, key); 244280297Sjkim for (i = 0; i < len; ++i) 245280297Sjkim out[i] = scratch.c[i] ^ inp[i]; 246280297Sjkim } 247238384Sjkim 248280297Sjkim for (i = 15 - L; i < 16; ++i) 249280297Sjkim ctx->nonce.c[i] = 0; 250238384Sjkim 251280297Sjkim (*block) (ctx->nonce.c, scratch.c, key); 252280297Sjkim ctx->cmac.u[0] ^= scratch.u[0]; 253280297Sjkim ctx->cmac.u[1] ^= scratch.u[1]; 254238384Sjkim 255280297Sjkim ctx->nonce.c[0] = flags0; 256238384Sjkim 257280297Sjkim return 0; 258238384Sjkim} 259238384Sjkim 260238384Sjkimint CRYPTO_ccm128_decrypt(CCM128_CONTEXT *ctx, 261280297Sjkim const unsigned char *inp, unsigned char *out, 262280297Sjkim size_t len) 263238384Sjkim{ 264280297Sjkim size_t n; 265280297Sjkim unsigned int i, L; 266280297Sjkim unsigned char flags0 = ctx->nonce.c[0]; 267280297Sjkim block128_f block = ctx->block; 268280297Sjkim void *key = ctx->key; 269280297Sjkim union { 270280297Sjkim u64 u[2]; 271280297Sjkim u8 c[16]; 272280297Sjkim } scratch; 273238384Sjkim 274280297Sjkim if (!(flags0 & 0x40)) 275280297Sjkim (*block) (ctx->nonce.c, ctx->cmac.c, key); 276238384Sjkim 277280297Sjkim ctx->nonce.c[0] = L = flags0 & 7; 278280297Sjkim for (n = 0, i = 15 - L; i < 15; ++i) { 279280297Sjkim n |= ctx->nonce.c[i]; 280280297Sjkim ctx->nonce.c[i] = 0; 281280297Sjkim n <<= 8; 282280297Sjkim } 283280297Sjkim n |= ctx->nonce.c[15]; /* reconstructed length */ 284280297Sjkim ctx->nonce.c[15] = 1; 285238384Sjkim 286280297Sjkim if (n != len) 287280297Sjkim return -1; 288238384Sjkim 289280297Sjkim while (len >= 16) { 290238384Sjkim#if defined(STRICT_ALIGNMENT) 291280297Sjkim union { 292280297Sjkim u64 u[2]; 293280297Sjkim u8 c[16]; 294280297Sjkim } temp; 295238384Sjkim#endif 296280297Sjkim (*block) (ctx->nonce.c, scratch.c, key); 297280297Sjkim ctr64_inc(ctx->nonce.c); 298238384Sjkim#if defined(STRICT_ALIGNMENT) 299280297Sjkim memcpy(temp.c, inp, 16); 300280297Sjkim ctx->cmac.u[0] ^= (scratch.u[0] ^= temp.u[0]); 301280297Sjkim ctx->cmac.u[1] ^= (scratch.u[1] ^= temp.u[1]); 302280297Sjkim memcpy(out, scratch.c, 16); 303238384Sjkim#else 304280297Sjkim ctx->cmac.u[0] ^= (((u64 *)out)[0] = scratch.u[0] ^ ((u64 *)inp)[0]); 305280297Sjkim ctx->cmac.u[1] ^= (((u64 *)out)[1] = scratch.u[1] ^ ((u64 *)inp)[1]); 306238384Sjkim#endif 307280297Sjkim (*block) (ctx->cmac.c, ctx->cmac.c, key); 308238384Sjkim 309280297Sjkim inp += 16; 310280297Sjkim out += 16; 311280297Sjkim len -= 16; 312280297Sjkim } 313238384Sjkim 314280297Sjkim if (len) { 315280297Sjkim (*block) (ctx->nonce.c, scratch.c, key); 316280297Sjkim for (i = 0; i < len; ++i) 317280297Sjkim ctx->cmac.c[i] ^= (out[i] = scratch.c[i] ^ inp[i]); 318280297Sjkim (*block) (ctx->cmac.c, ctx->cmac.c, key); 319280297Sjkim } 320238384Sjkim 321280297Sjkim for (i = 15 - L; i < 16; ++i) 322280297Sjkim ctx->nonce.c[i] = 0; 323238384Sjkim 324280297Sjkim (*block) (ctx->nonce.c, scratch.c, key); 325280297Sjkim ctx->cmac.u[0] ^= scratch.u[0]; 326280297Sjkim ctx->cmac.u[1] ^= scratch.u[1]; 327238384Sjkim 328280297Sjkim ctx->nonce.c[0] = flags0; 329238384Sjkim 330280297Sjkim return 0; 331238384Sjkim} 332238384Sjkim 333280297Sjkimstatic void ctr64_add(unsigned char *counter, size_t inc) 334280297Sjkim{ 335280297Sjkim size_t n = 8, val = 0; 336238384Sjkim 337280297Sjkim counter += 8; 338280297Sjkim do { 339280297Sjkim --n; 340280297Sjkim val += counter[n] + (inc & 0xff); 341280297Sjkim counter[n] = (unsigned char)val; 342280297Sjkim val >>= 8; /* carry bit */ 343280297Sjkim inc >>= 8; 344280297Sjkim } while (n && (inc || val)); 345238384Sjkim} 346238384Sjkim 347238384Sjkimint CRYPTO_ccm128_encrypt_ccm64(CCM128_CONTEXT *ctx, 348280297Sjkim const unsigned char *inp, unsigned char *out, 349280297Sjkim size_t len, ccm128_f stream) 350238384Sjkim{ 351280297Sjkim size_t n; 352280297Sjkim unsigned int i, L; 353280297Sjkim unsigned char flags0 = ctx->nonce.c[0]; 354280297Sjkim block128_f block = ctx->block; 355280297Sjkim void *key = ctx->key; 356280297Sjkim union { 357280297Sjkim u64 u[2]; 358280297Sjkim u8 c[16]; 359280297Sjkim } scratch; 360238384Sjkim 361280297Sjkim if (!(flags0 & 0x40)) 362280297Sjkim (*block) (ctx->nonce.c, ctx->cmac.c, key), ctx->blocks++; 363238384Sjkim 364280297Sjkim ctx->nonce.c[0] = L = flags0 & 7; 365280297Sjkim for (n = 0, i = 15 - L; i < 15; ++i) { 366280297Sjkim n |= ctx->nonce.c[i]; 367280297Sjkim ctx->nonce.c[i] = 0; 368280297Sjkim n <<= 8; 369280297Sjkim } 370280297Sjkim n |= ctx->nonce.c[15]; /* reconstructed length */ 371280297Sjkim ctx->nonce.c[15] = 1; 372238384Sjkim 373280297Sjkim if (n != len) 374280297Sjkim return -1; /* length mismatch */ 375238384Sjkim 376280297Sjkim ctx->blocks += ((len + 15) >> 3) | 1; 377280297Sjkim if (ctx->blocks > (U64(1) << 61)) 378280297Sjkim return -2; /* too much data */ 379238384Sjkim 380280297Sjkim if ((n = len / 16)) { 381280297Sjkim (*stream) (inp, out, n, key, ctx->nonce.c, ctx->cmac.c); 382280297Sjkim n *= 16; 383280297Sjkim inp += n; 384280297Sjkim out += n; 385280297Sjkim len -= n; 386280297Sjkim if (len) 387280297Sjkim ctr64_add(ctx->nonce.c, n / 16); 388280297Sjkim } 389238384Sjkim 390280297Sjkim if (len) { 391280297Sjkim for (i = 0; i < len; ++i) 392280297Sjkim ctx->cmac.c[i] ^= inp[i]; 393280297Sjkim (*block) (ctx->cmac.c, ctx->cmac.c, key); 394280297Sjkim (*block) (ctx->nonce.c, scratch.c, key); 395280297Sjkim for (i = 0; i < len; ++i) 396280297Sjkim out[i] = scratch.c[i] ^ inp[i]; 397280297Sjkim } 398238384Sjkim 399280297Sjkim for (i = 15 - L; i < 16; ++i) 400280297Sjkim ctx->nonce.c[i] = 0; 401238384Sjkim 402280297Sjkim (*block) (ctx->nonce.c, scratch.c, key); 403280297Sjkim ctx->cmac.u[0] ^= scratch.u[0]; 404280297Sjkim ctx->cmac.u[1] ^= scratch.u[1]; 405238384Sjkim 406280297Sjkim ctx->nonce.c[0] = flags0; 407238384Sjkim 408280297Sjkim return 0; 409238384Sjkim} 410238384Sjkim 411238384Sjkimint CRYPTO_ccm128_decrypt_ccm64(CCM128_CONTEXT *ctx, 412280297Sjkim const unsigned char *inp, unsigned char *out, 413280297Sjkim size_t len, ccm128_f stream) 414238384Sjkim{ 415280297Sjkim size_t n; 416280297Sjkim unsigned int i, L; 417280297Sjkim unsigned char flags0 = ctx->nonce.c[0]; 418280297Sjkim block128_f block = ctx->block; 419280297Sjkim void *key = ctx->key; 420280297Sjkim union { 421280297Sjkim u64 u[2]; 422280297Sjkim u8 c[16]; 423280297Sjkim } scratch; 424238384Sjkim 425280297Sjkim if (!(flags0 & 0x40)) 426280297Sjkim (*block) (ctx->nonce.c, ctx->cmac.c, key); 427238384Sjkim 428280297Sjkim ctx->nonce.c[0] = L = flags0 & 7; 429280297Sjkim for (n = 0, i = 15 - L; i < 15; ++i) { 430280297Sjkim n |= ctx->nonce.c[i]; 431280297Sjkim ctx->nonce.c[i] = 0; 432280297Sjkim n <<= 8; 433280297Sjkim } 434280297Sjkim n |= ctx->nonce.c[15]; /* reconstructed length */ 435280297Sjkim ctx->nonce.c[15] = 1; 436238384Sjkim 437280297Sjkim if (n != len) 438280297Sjkim return -1; 439238384Sjkim 440280297Sjkim if ((n = len / 16)) { 441280297Sjkim (*stream) (inp, out, n, key, ctx->nonce.c, ctx->cmac.c); 442280297Sjkim n *= 16; 443280297Sjkim inp += n; 444280297Sjkim out += n; 445280297Sjkim len -= n; 446280297Sjkim if (len) 447280297Sjkim ctr64_add(ctx->nonce.c, n / 16); 448280297Sjkim } 449238384Sjkim 450280297Sjkim if (len) { 451280297Sjkim (*block) (ctx->nonce.c, scratch.c, key); 452280297Sjkim for (i = 0; i < len; ++i) 453280297Sjkim ctx->cmac.c[i] ^= (out[i] = scratch.c[i] ^ inp[i]); 454280297Sjkim (*block) (ctx->cmac.c, ctx->cmac.c, key); 455280297Sjkim } 456238384Sjkim 457280297Sjkim for (i = 15 - L; i < 16; ++i) 458280297Sjkim ctx->nonce.c[i] = 0; 459238384Sjkim 460280297Sjkim (*block) (ctx->nonce.c, scratch.c, key); 461280297Sjkim ctx->cmac.u[0] ^= scratch.u[0]; 462280297Sjkim ctx->cmac.u[1] ^= scratch.u[1]; 463238384Sjkim 464280297Sjkim ctx->nonce.c[0] = flags0; 465238384Sjkim 466280297Sjkim return 0; 467238384Sjkim} 468238384Sjkim 469280297Sjkimsize_t CRYPTO_ccm128_tag(CCM128_CONTEXT *ctx, unsigned char *tag, size_t len) 470280297Sjkim{ 471280297Sjkim unsigned int M = (ctx->nonce.c[0] >> 3) & 7; /* the M parameter */ 472238384Sjkim 473280297Sjkim M *= 2; 474280297Sjkim M += 2; 475280297Sjkim if (len < M) 476280297Sjkim return 0; 477280297Sjkim memcpy(tag, ctx->cmac.c, M); 478280297Sjkim return M; 479238384Sjkim} 480