Return to cmac.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / strongswan / src / libstrongswan / plugins / cmac |
1.1 misho 1: /* 2: * Copyright (C) 2012 Tobias Brunner 3: * HSR Hochschule fuer Technik Rapperswil 4: * 5: * This program is free software; you can redistribute it and/or modify it 6: * under the terms of the GNU General Public License as published by the 7: * Free Software Foundation; either version 2 of the License, or (at your 8: * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. 9: * 10: * This program is distributed in the hope that it will be useful, but 11: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 12: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13: * for more details. 14: */ 15: 16: #include <string.h> 17: 18: #include "cmac.h" 19: 20: #include <utils/debug.h> 21: #include <crypto/mac.h> 22: #include <crypto/prfs/mac_prf.h> 23: #include <crypto/signers/mac_signer.h> 24: 25: typedef struct private_mac_t private_mac_t; 26: 27: /** 28: * Private data of a mac_t object. 29: * 30: * The variable names are the same as in the RFC. 31: */ 32: struct private_mac_t { 33: 34: /** 35: * Public interface. 36: */ 37: mac_t public; 38: 39: /** 40: * Block size, in bytes 41: */ 42: uint8_t b; 43: 44: /** 45: * Crypter with key K 46: */ 47: crypter_t *k; 48: 49: /** 50: * K1 51: */ 52: uint8_t *k1; 53: 54: /** 55: * K2 56: */ 57: uint8_t *k2; 58: 59: /** 60: * T 61: */ 62: uint8_t *t; 63: 64: /** 65: * remaining, unprocessed bytes in append mode 66: */ 67: uint8_t *remaining; 68: 69: /** 70: * number of bytes in remaining 71: */ 72: int remaining_bytes; 73: }; 74: 75: /** 76: * process supplied data, but do not run final operation 77: */ 78: static bool update(private_mac_t *this, chunk_t data) 79: { 80: chunk_t iv; 81: 82: if (this->remaining_bytes + data.len <= this->b) 83: { /* no complete block (or last block), just copy into remaining */ 84: memcpy(this->remaining + this->remaining_bytes, data.ptr, data.len); 85: this->remaining_bytes += data.len; 86: return TRUE; 87: } 88: 89: iv = chunk_alloca(this->b); 90: memset(iv.ptr, 0, iv.len); 91: 92: /* T := 0x00000000000000000000000000000000 (initially) 93: * for each block M_i (except the last) 94: * X := T XOR M_i; 95: * T := AES-128(K, X); 96: */ 97: 98: /* append data to remaining bytes, process block M_1 */ 99: memcpy(this->remaining + this->remaining_bytes, data.ptr, 100: this->b - this->remaining_bytes); 101: data = chunk_skip(data, this->b - this->remaining_bytes); 102: memxor(this->t, this->remaining, this->b); 103: if (!this->k->encrypt(this->k, chunk_create(this->t, this->b), iv, NULL)) 104: { 105: return FALSE; 106: } 107: 108: /* process blocks M_2 ... M_n-1 */ 109: while (data.len > this->b) 110: { 111: memcpy(this->remaining, data.ptr, this->b); 112: data = chunk_skip(data, this->b); 113: memxor(this->t, this->remaining, this->b); 114: if (!this->k->encrypt(this->k, chunk_create(this->t, this->b), iv, NULL)) 115: { 116: return FALSE; 117: } 118: } 119: 120: /* store remaining bytes of block M_n */ 121: memcpy(this->remaining, data.ptr, data.len); 122: this->remaining_bytes = data.len; 123: 124: return TRUE; 125: } 126: 127: /** 128: * process last block M_last 129: */ 130: static bool final(private_mac_t *this, uint8_t *out) 131: { 132: chunk_t iv; 133: 134: iv = chunk_alloca(this->b); 135: memset(iv.ptr, 0, iv.len); 136: 137: /* if last block is complete 138: * M_last := M_n XOR K1; 139: * else 140: * M_last := padding(M_n) XOR K2; 141: */ 142: if (this->remaining_bytes == this->b) 143: { 144: memxor(this->remaining, this->k1, this->b); 145: } 146: else 147: { 148: /* padding(x) = x || 10^i where i is 128-8*r-1 149: * That is, padding(x) is the concatenation of x and a single '1', 150: * followed by the minimum number of '0's, so that the total length is 151: * equal to 128 bits. 152: */ 153: if (this->remaining_bytes < this->b) 154: { 155: this->remaining[this->remaining_bytes] = 0x80; 156: while (++this->remaining_bytes < this->b) 157: { 158: this->remaining[this->remaining_bytes] = 0x00; 159: } 160: } 161: memxor(this->remaining, this->k2, this->b); 162: } 163: /* T := M_last XOR T; 164: * T := AES-128(K,T); 165: */ 166: memxor(this->t, this->remaining, this->b); 167: if (!this->k->encrypt(this->k, chunk_create(this->t, this->b), iv, NULL)) 168: { 169: return FALSE; 170: } 171: 172: memcpy(out, this->t, this->b); 173: 174: /* reset state */ 175: memset(this->t, 0, this->b); 176: this->remaining_bytes = 0; 177: 178: return TRUE; 179: } 180: 181: METHOD(mac_t, get_mac, bool, 182: private_mac_t *this, chunk_t data, uint8_t *out) 183: { 184: /* update T, do not process last block */ 185: if (!update(this, data)) 186: { 187: return FALSE; 188: } 189: 190: if (out) 191: { /* if not in append mode, process last block and output result */ 192: return final(this, out); 193: } 194: return TRUE; 195: } 196: 197: METHOD(mac_t, get_mac_size, size_t, 198: private_mac_t *this) 199: { 200: return this->b; 201: } 202: 203: /** 204: * Left-shift the given chunk by one bit. 205: */ 206: static void bit_shift(chunk_t chunk) 207: { 208: size_t i; 209: 210: for (i = 0; i < chunk.len; i++) 211: { 212: chunk.ptr[i] <<= 1; 213: if (i < chunk.len - 1 && chunk.ptr[i + 1] & 0x80) 214: { 215: chunk.ptr[i] |= 0x01; 216: } 217: } 218: } 219: 220: /** 221: * Apply the following key derivation (in-place): 222: * if MSB(C) == 0 223: * C := C << 1 224: * else 225: * C := (C << 1) XOR 0x00000000000000000000000000000087 226: */ 227: static void derive_key(chunk_t chunk) 228: { 229: if (chunk.ptr[0] & 0x80) 230: { 231: chunk_t rb; 232: 233: rb = chunk_alloca(chunk.len); 234: memset(rb.ptr, 0, rb.len); 235: rb.ptr[rb.len - 1] = 0x87; 236: bit_shift(chunk); 237: memxor(chunk.ptr, rb.ptr, chunk.len); 238: } 239: else 240: { 241: bit_shift(chunk); 242: } 243: } 244: 245: METHOD(mac_t, set_key, bool, 246: private_mac_t *this, chunk_t key) 247: { 248: chunk_t resized, iv, l; 249: 250: memset(this->t, 0, this->b); 251: this->remaining_bytes = 0; 252: 253: /* we support variable keys as defined in RFC 4615 */ 254: if (key.len == this->b) 255: { 256: resized = key; 257: } 258: else 259: { /* use cmac recursively to resize longer or shorter keys */ 260: resized = chunk_alloca(this->b); 261: memset(resized.ptr, 0, resized.len); 262: if (!set_key(this, resized) || 263: !get_mac(this, key, resized.ptr)) 264: { 265: return FALSE; 266: } 267: } 268: 269: /* 270: * Rb = 0x00000000000000000000000000000087 271: * L = 0x00000000000000000000000000000000 encrypted with K 272: * if MSB(L) == 0 273: * K1 = L << 1 274: * else 275: * K1 = (L << 1) XOR Rb 276: * if MSB(K1) == 0 277: * K2 = K1 << 1 278: * else 279: * K2 = (K1 << 1) XOR Rb 280: */ 281: iv = chunk_alloca(this->b); 282: memset(iv.ptr, 0, iv.len); 283: l = chunk_alloca(this->b); 284: memset(l.ptr, 0, l.len); 285: if (!this->k->set_key(this->k, resized) || 286: !this->k->encrypt(this->k, l, iv, NULL)) 287: { 288: return FALSE; 289: } 290: derive_key(l); 291: memcpy(this->k1, l.ptr, l.len); 292: derive_key(l); 293: memcpy(this->k2, l.ptr, l.len); 294: memwipe(l.ptr, l.len); 295: 296: return TRUE; 297: } 298: 299: METHOD(mac_t, destroy, void, 300: private_mac_t *this) 301: { 302: this->k->destroy(this->k); 303: memwipe(this->k1, this->b); 304: free(this->k1); 305: memwipe(this->k2, this->b); 306: free(this->k2); 307: free(this->t); 308: free(this->remaining); 309: free(this); 310: } 311: 312: /* 313: * Described in header 314: */ 315: mac_t *cmac_create(encryption_algorithm_t algo, size_t key_size) 316: { 317: private_mac_t *this; 318: crypter_t *crypter; 319: uint8_t b; 320: 321: crypter = lib->crypto->create_crypter(lib->crypto, algo, key_size); 322: if (!crypter) 323: { 324: return NULL; 325: } 326: b = crypter->get_block_size(crypter); 327: /* input and output of crypter must be equal for cmac */ 328: if (b != key_size) 329: { 330: crypter->destroy(crypter); 331: return NULL; 332: } 333: 334: INIT(this, 335: .public = { 336: .get_mac = _get_mac, 337: .get_mac_size = _get_mac_size, 338: .set_key = _set_key, 339: .destroy = _destroy, 340: }, 341: .b = b, 342: .k = crypter, 343: .k1 = malloc(b), 344: .k2 = malloc(b), 345: .t = malloc(b), 346: .remaining = malloc(b), 347: ); 348: memset(this->t, 0, b); 349: 350: return &this->public; 351: } 352: 353: /* 354: * Described in header. 355: */ 356: prf_t *cmac_prf_create(pseudo_random_function_t algo) 357: { 358: mac_t *cmac; 359: 360: switch (algo) 361: { 362: case PRF_AES128_CMAC: 363: cmac = cmac_create(ENCR_AES_CBC, 16); 364: break; 365: default: 366: return NULL; 367: } 368: if (cmac) 369: { 370: return mac_prf_create(cmac); 371: } 372: return NULL; 373: } 374: 375: /* 376: * Described in header 377: */ 378: signer_t *cmac_signer_create(integrity_algorithm_t algo) 379: { 380: size_t truncation; 381: mac_t *cmac; 382: 383: switch (algo) 384: { 385: case AUTH_AES_CMAC_96: 386: cmac = cmac_create(ENCR_AES_CBC, 16); 387: truncation = 12; 388: break; 389: default: 390: return NULL; 391: } 392: if (cmac) 393: { 394: return mac_signer_create(cmac, truncation); 395: } 396: return NULL; 397: }