1.\" $OpenBSD: EVP_aes_128_ccm.3,v 1.5 2024/12/29 12:27:28 schwarze Exp $ 2.\" full merge up to: 3.\" OpenSSL EVP_EncryptInit.pod 0874d7f2 Oct 11 13:13:47 2022 +0100 4.\" OpenSSL EVP_aes.pod a1ec85c1 Apr 21 10:49:12 2020 +0100 5.\" 6.\" Copyright (c) 2024 Ingo Schwarze <schwarze@openbsd.org> 7.\" 8.\" Permission to use, copy, modify, and distribute this software for any 9.\" purpose with or without fee is hereby granted, provided that the above 10.\" copyright notice and this permission notice appear in all copies. 11.\" 12.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 13.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 14.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 15.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 16.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 17.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 18.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 19.\" 20.\" This file is a derived work containing a few sentences 21.\" written by Dr. Stephen Henson <steve@openssl.org> 22.\" covered by the following license: 23.\" 24.\" Copyright (c) 2012 The OpenSSL Project. All rights reserved. 25.\" 26.\" Redistribution and use in source and binary forms, with or without 27.\" modification, are permitted provided that the following conditions 28.\" are met: 29.\" 30.\" 1. Redistributions of source code must retain the above copyright 31.\" notice, this list of conditions and the following disclaimer. 32.\" 33.\" 2. Redistributions in binary form must reproduce the above copyright 34.\" notice, this list of conditions and the following disclaimer in 35.\" the documentation and/or other materials provided with the 36.\" distribution. 37.\" 38.\" 3. All advertising materials mentioning features or use of this 39.\" software must display the following acknowledgment: 40.\" "This product includes software developed by the OpenSSL Project 41.\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 42.\" 43.\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 44.\" endorse or promote products derived from this software without 45.\" prior written permission. For written permission, please contact 46.\" openssl-core@openssl.org. 47.\" 48.\" 5. Products derived from this software may not be called "OpenSSL" 49.\" nor may "OpenSSL" appear in their names without prior written 50.\" permission of the OpenSSL Project. 51.\" 52.\" 6. Redistributions of any form whatsoever must retain the following 53.\" acknowledgment: 54.\" "This product includes software developed by the OpenSSL Project 55.\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" 56.\" 57.\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 58.\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 59.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 60.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 61.\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 62.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 63.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 64.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 65.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 66.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 67.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 68.\" OF THE POSSIBILITY OF SUCH DAMAGE. 69.\" 70.Dd $Mdocdate: December 29 2024 $ 71.Dt EVP_AES_128_CCM 3 72.Os 73.Sh NAME 74.Nm EVP_aes_128_ccm , 75.Nm EVP_aes_192_ccm , 76.Nm EVP_aes_256_ccm 77.Nd EVP AES cipher in Counter with CBC-MAC mode 78.Sh SYNOPSIS 79.In openssl/evp.h 80.Ft const EVP_CIPHER * 81.Fn EVP_aes_128_ccm void 82.Ft const EVP_CIPHER * 83.Fn EVP_aes_192_ccm void 84.Ft const EVP_CIPHER * 85.Fn EVP_aes_256_ccm void 86.\" The following #define'd constants are intentionally undocumented: 87.\" Completely unused by anything: 88.\" EVP_CTRL_CCM_SET_MSGLEN, EVP_CCM_TLS_FIXED_IV_LEN, EVP_CCM_TLS_IV_LEN 89.\" Very rarely used and unused in LibreSSL: 90.\" EVP_CCM_TLS_EXPLICIT_IV_LEN, EVP_CCM_TLS_TAG_LEN, EVP_CCM8_TLS_TAG_LEN 91.Sh DESCRIPTION 92.Fn EVP_aes_128_ccm , 93.Fn EVP_aes_192_ccm , 94and 95.Fn EVP_aes_256_ccm 96provide the Advanced Encryption Standard algorithm for 128, 192 and 256-bit 97keys in Counter with CBC-MAC (CCM) mode in the 98.Xr evp 3 99framework. 100This mode supports Authenticated Encryption with Additional Data (AEAD) 101and can be used in a number of communication protocols. 102Longer keys make precomputation attacks harder at a cost in performance. 103.Pp 104For CCM mode ciphers, the behaviour of the EVP interface is subtly 105altered and several additional 106.Xr EVP_CIPHER_CTX_ctrl 3 107operations are required to function correctly. 108Some of the 109.Dv EVP_CTRL_CCM_* 110control commands are older aliases for corresponding 111.Dv EVP_CTRL_AEAD_* 112constants as indicated below. 113.Pp 114The less cumbersome and less error-prone 115.Xr EVP_AEAD_CTX_new 3 116API does not provide CCM modes. 117Some communication protocols support alternatives to CCM, which may 118sometimes allow choosing the better API by avoiding CCM. 119.Ss Configuration controls 120The following two control commands can be issued as soon as 121.Xr EVP_EncryptInit 3 122has been called with a CCM 123.Fa type 124and 125.Dv NULL 126pointers for 127.Fa key 128and 129.Fa iv . 130Both commands are optional and override each other. 131If issued when a nonce is already set, they silently cause data corruption. 132The 133.Fa ptr 134argument is ignored by both; passing 135.Dv NULL 136is recommended. 137.Bl -tag -width Ds 138.It Dv EVP_CTRL_CCM_SET_L 139Set the size 140.Ms L 141of the length field to 142.Fa arg 143bytes and the size of the nonce to 144.No 15 \- Fa arg 145bytes. 146By default, 8 bytes are used for the length field and 7 for the nonce. 147Selecting a smaller size 148.Ms L 149for the length field reduces des maximum size of messages that can be sent, 150but in return allows transmitting more messages with the same key. 151It is an error to pass less than 2 or more than the default value of 8 for 152.Fa arg . 153.It Dv EVP_CTRL_AEAD_SET_IVLEN Pq == Dv EVP_CTRL_CCM_SET_IVLEN 154Set the size of the nonce to 155.Fa arg 156bytes and the size 157.Ms L 158of the length field to 159.No 15 \- Fa arg 160bytes. 161By default, 7 bytes are used for the nonce and 8 for the length field. 162Selecting a larger size of the nonce allows transmitting more messages with 163the same key at the expense of reducing the maximum size for each message. 164It is an error to pass more than 13 or less than the default value of 7 for 165.Fa arg . 166.El 167.Pp 168After optionally issuing one of the above control commands, 169.Xr EVP_EncryptInit 3 170can be called a second time, this time passing 171.Dv NULL 172for the 173.Fa type 174argument, with the other two arguments pointing to the desired AES key 175and to the desired nonce. 176.Ss Encryption controls 177.Bl -tag -width Ds 178.It Dv EVP_CTRL_AEAD_SET_TAG Pq == Dv EVP_CTRL_CCM_SET_TAG 179If the 180.Fa ptr 181argument is 182.Dv NULL , 183set the tag length 184.Ms M 185to 186.Fa arg 187bytes. 188The default value is 12. 189Selecting a larger value makes tampering harder for an attacker, 190at a small expense of making the messages slightly longer. 191Selecting a smaller value is not recommended. 192It is an error to pass an odd number for 193.Fa arg , 194or a number that is less than 4 or greater than 16, or to pass 195.Dv NULL 196to 197.Fa ptr 198when 199.Fa ctx 200is not configured for encrypting. 201Issuing this control command when an encryption key is already configured 202silently causes data corruption. 203.It Dv EVP_CTRL_AEAD_GET_TAG Pq == Dv EVP_CTRL_CCM_GET_TAG 204Store the 205.Fa arg 206bytes of the tag in the memory provided by the caller starting at 207.Fa ptr . 208It is an error to issue this control command when 209.Fa ctx 210is not configured for encrypting, when no data was encrypted yet, with an 211.Fa arg 212that does not match the configured tag length 213.Ms M , 214or when the tag has already been retrieved earlier. 215.El 216.Pp 217Before passing any plaintext data to 218.Xr EVP_EncryptUpdate 3 , 219call 220.Xr EVP_EncryptUpdate 3 221with both 222.Fa in 223and 224.Fa out 225set to 226.Dv NULL , 227passing the total plaintext length in bytes as 228.Fa in_len . 229This constructs the first block to be digested with CBC-MAC 230and copies the text length to 231.Pf * Fa out_len . 232It does not check whether 233.Fa in_len 234exceeds the limit of 235.Pf 256\(ha Ms L ; 236the most significant bytes of excessive values are silently discarded. 237.Pp 238It is an error if the 239.Fa in_len 240argument of the 241.Xr EVP_EncryptUpdate 3 242call passing the plaintext data does not match the total length 243specified earlier. 244Splitting the text into more than one chunks to be passed in multiple calls of 245.Xr EVP_EncryptUpdate 3 246is not supported for CCM. 247.Pp 248To specify any additional authenticated data (AAD), call 249.Xr EVP_EncryptUpdate 3 250with the 251.Fa out 252argument set to 253.Dv NULL . 254.Ss Decryption controls 255.Bl -tag -width Ds 256.It Dv EVP_CTRL_AEAD_SET_TAG Pq == Dv EVP_CTRL_CCM_SET_TAG 257If the 258.Fa ptr 259argument is not 260.Dv NULL , 261copy 262.Fa arg 263bytes starting at 264.Fa ptr 265to the expected CCM tag value. 266It is an error to pass an odd number for 267.Fa arg , 268or a number that is less than 4 or greater than 16. 269Passing a number that does not correspond to the tag length 270.Ms M 271that was used for encryption does not raise an error right away, 272but results in undefined behaviour 273and typically causes subsequent authentication failure. 274It is also an error to pass a 275.Pf non- Dv NULL 276.Fa ptr 277when 278.Fa ctx 279is configured for encryption. 280.El 281.Pp 282Before passing any ciphertext data to 283.Xr EVP_DecryptUpdate 3 , 284call 285.Xr EVP_DecryptUpdate 3 286with both 287.Fa in 288and 289.Fa out 290set to 291.Dv NULL , 292passing the total ciphertext length in bytes as 293.Fa in_len . 294This constructs the first block to be digested with CBC-MAC 295and copies the text length to 296.Pf * Fa out_len . 297It does not check whether 298.Fa in_len 299exceeds the limit of 300.Pf 256\(ha Ms L ; 301the most significant bytes of excessive values are silently discarded. 302.Pp 303It is an error if the 304.Fa in_len 305argument of the 306.Xr EVP_DecryptUpdate 3 307call passing the ciphertext data does not match the total length 308specified earlier. 309Splitting the text into more than one chunks to be passed in multiple calls of 310.Xr EVP_DecryptUpdate 3 311is not supported for CCM. 312.Pp 313To specify any additional authenticated data (AAD), call 314.Xr EVP_DecryptUpdate 3 315with the 316.Fa out 317argument set to 318.Dv NULL . 319.Pp 320If the return value of 321.Xr EVP_DecryptUpdate 3 322does not indicate success, the authentication operation may have failed. 323In that case, regard any output data as corrupted. 324.Pp 325Do not call 326.Xr EVP_DecryptFinal 3 327when using CCM. 328Such a call would not do anything useful, and it would fail 329because the tag that was set with 330.Dv EVP_CTRL_CCM_SET_TAG 331was already consumed by 332.Xr EVP_DecryptUpdate 3 . 333.Sh RETURN VALUES 334These functions return a static constant 335.Vt EVP_CIPHER 336structure that provides the implementation of the respective AEAD cipher mode. 337.Sh EXAMPLES 338The following code encrypts and digests some secret text 339and some additional, public data with AES-CCM. 340Specifically, it implements the Test Vector #1 341given in section 8 of RFC 3610. 342.Bd -literal -offset indent 343/* input data */ 344const unsigned char key[] = { 345 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 346 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF 347}; 348const unsigned char nonce[] = { 349 0x00, 0x00, 0x00, 0x03, 0x02, 0x01, 0x00, 0xA0, 350 0xA1, 0xA2, 0xA3, 0xA4, 0xA5 351}; 352const int nonce_len = sizeof(nonce); 353const int size_len = 15 - nonce_len; 354 355const unsigned char aad[] = { 356 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 357}; 358const int aad_len = sizeof(aad); 359 360const unsigned char plaintext[] = { 361 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 362 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 363 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E 364}; 365const int text_len = sizeof(plaintext); 366 367/* expected output data */ 368const unsigned char ciphertext[] = { 369 0x58, 0x8C, 0x97, 0x9A, 0x61, 0xC6, 0x63, 0xD2, 370 0xF0, 0x66, 0xD0, 0xC2, 0xC0, 0xF9, 0x89, 0x80, 371 0x6D, 0x5F, 0x6B, 0x61, 0xDA, 0xC3, 0x84 372}; 373 374const unsigned char wanted_tag[] = { 375 0x17, 0xE8, 0xD1, 0x2C, 0xFD, 0xF9, 0x26, 0xE0 376}; 377const int tag_len = sizeof(wanted_tag); 378 379const int out_len = aad_len + text_len + tag_len; 380unsigned char out_buf[out_len]; 381unsigned char *out_p = out_buf; 382unsigned char *out_end = out_buf + out_len; 383 384/* auxiliary variables */ 385EVP_CIPHER_CTX *ctx; 386int irv, i; 387 388/* configuration */ 389ctx = EVP_CIPHER_CTX_new(); 390if (ctx == NULL) 391 err(1, "EVP_CIPHER_CTX_new"); 392 393if (EVP_EncryptInit(ctx, EVP_aes_128_ccm(), NULL, NULL) != 1) 394 err(1, "EVP_EncryptInit(NULL)"); 395 396if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_L, 397 size_len, NULL) <= 0) 398 err(1, "EVP_CTRL_CCM_SET_L(%d)", size_len); 399 400if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_TAG, 401 tag_len, NULL) <= 0) 402 err(1, "EVP_CTRL_CCM_SET_TAG(%d)", tag_len); 403 404/* process input data */ 405if (EVP_EncryptInit(ctx, NULL, key, nonce) != 1) 406 err(1, "EVP_EncryptInit(key, nonce)"); 407 408if (EVP_EncryptUpdate(ctx, NULL, &irv, NULL, text_len) != 1) 409 err(1, "EVP_EncryptUpdate(len = %d)", text_len); 410if (irv != text_len) 411 errx(1, "text length: want %d, got %d", text_len, irv); 412 413irv = -1; 414if (EVP_EncryptUpdate(ctx, NULL, &irv, aad, aad_len) != 1) 415 err(1, "EVP_EncryptUpdate(AAD)"); 416memcpy(out_p, aad, aad_len); 417out_p += aad_len; 418 419irv = -1; 420if (EVP_EncryptUpdate(ctx, out_p, &irv, plaintext, text_len) != 1) 421 err(1, "EVP_EncryptUpdate(plaintext)"); 422if (irv != text_len) 423 errx(1, "text_len: want %d, got %d", text_len, irv); 424out_p += irv; 425 426/* 427 * EVP_EncryptFinal(3) doesn't really do anything for CCM. 428 * Call it anyway to stay closer to normal EVP_Encrypt*(3) idioms, 429 * to match what the OpenSSL Wiki suggests since 2013, and to ease 430 * later migration of the code to a different AEAD algorithm. 431 */ 432irv = -1; 433if (EVP_EncryptFinal(ctx, out_p, &irv) != 1) 434 err(1, "EVP_EncryptFinal"); 435if (irv != 0) 436 errx(1, "final_len: want 0, got %d", irv); 437 438/* check output data */ 439if (memcmp(out_buf + aad_len, ciphertext, text_len) != 0) 440 errx(1, "ciphertext mismatch"); 441 442if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_GET_TAG, 443 tag_len, out_p) <= 0) 444 err(1, "EVP_CTRL_CCM_GET_TAG"); 445if (memcmp(out_p, wanted_tag, tag_len) != 0) 446 errx(1, "tag mismatch"); 447out_p += tag_len; 448if (out_p != out_end) 449 errx(1, "end of output: want %p, got %p", out_end, out_p); 450 451printf("Total packet length = %d.", out_len); 452printf(" [Authenticated and Encrypted Output]"); 453for (i = 0; i < out_len; i++) { 454 if (i % 16 == 0) 455 printf("\en "); 456 if (i % 4 == 0) 457 putchar(' '); 458 printf(" %02X", out_buf[i]); 459} 460putchar('\en'); 461 462EVP_CIPHER_CTX_free(ctx); 463.Ed 464.Pp 465The reverse operation for the same test vector, 466i.e. decrypting and comparing the digest, 467is implemented by the following code. 468.Pp 469The variable declarations and definitions up to the call of 470.Xr EVP_CIPHER_CTX_new 3 471are the same as above. 472The chief differences are: 473.Bl -dash -width 1n -compact 474.It 475The tag is not part of the output, 476so the total output length is shorter. 477.It 478No 479.Xr memcmp 3 480of the tag takes place. 481Instead, the control command 482.Dv EVP_CTRL_CCM_SET_TAG 483requires the tag that is going to be verified as an additional argument. 484.It 485While 486.Xr EVP_EncryptFinal 3 487is an optional no-op, 488.Xr EVP_DecryptFinal 3 489is not called and would fail. 490.El 491.Bd -literal -offset indent 492const int out_len = aad_len + text_len; 493 494/* configuration */ 495ctx = EVP_CIPHER_CTX_new(); 496if (ctx == NULL) 497 err(1, "EVP_CIPHER_CTX_new"); 498 499if (EVP_DecryptInit(ctx, EVP_aes_128_ccm(), NULL, NULL) != 1) 500 err(1, "EVP_DecryptInit(NULL)"); 501 502if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_L, size_len, NULL) <= 0) 503 err(1, "EVP_CTRL_CCM_SET_L(%d)", size_len); 504 505if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_TAG, 506 tag_len, (void *)wanted_tag) <= 0) 507 err(1, "EVP_CTRL_CCM_SET_TAG(%d)", tag_len); 508 509/* process input data */ 510if (EVP_DecryptInit(ctx, NULL, key, nonce) != 1) 511 err(1, "EVP_DecryptInit(key, nonce)"); 512 513if (EVP_DecryptUpdate(ctx, NULL, &irv, NULL, text_len) != 1) 514 err(1, "EVP_DecryptUpdate(len = %d)", text_len); 515if (irv != text_len) 516 errx(1, "text length: want %d, got %d", text_len, irv); 517 518irv = -1; 519if (EVP_DecryptUpdate(ctx, NULL, &irv, aad, aad_len) != 1) 520 err(1, "EVP_DecryptUpdate(AAD)"); 521memcpy(out_p, aad, aad_len); 522out_p += aad_len; 523 524irv = -1; 525if (EVP_DecryptUpdate(ctx, out_p, &irv, ciphertext, text_len) != 1) 526 err(1, "EVP_DecryptUpdate(ciphertext)"); 527if (irv != text_len) 528 errx(1, "text_len: want %d, got %d", text_len, irv); 529out_p += irv; 530 531/* Do not call EVP_DecryptFinal(3); it would fail and do nothing. */ 532 533/* check output data */ 534if (memcmp(out_buf + aad_len, plaintext, text_len) != 0) 535 errx(1, "plaintext mismatch"); 536if (out_p != out_end) 537 errx(1, "end of output: want %p, got %p", out_end, out_p); 538 539printf("Total packet length = %d.", out_len); 540printf(" [Decrypted and Authenticated Input]"); 541for (i = 0; i < out_len; i++) { 542 if (i % 16 == 0) 543 printf("\n "); 544 if (i % 4 == 0) 545 putchar(' '); 546 printf(" %02X", out_buf[i]); 547} 548putchar('\n'); 549 550EVP_CIPHER_CTX_free(ctx); 551.Ed 552.Sh SEE ALSO 553.Xr AES_encrypt 3 , 554.Xr evp 3 , 555.Xr EVP_aes_128_cbc 3 , 556.Xr EVP_aes_128_gcm 3 , 557.Xr EVP_EncryptInit 3 558.Sh STANDARDS 559.Rs 560.%A Doug Whiting 561.%A Russ Housley 562.%A Niels Ferguson 563.%T Counter with CBC-MAC (CCM) 564.%R RFC 3610 565.%D September 2003 566.Re 567.Sh HISTORY 568.Fn EVP_aes_128_ccm , 569.Fn EVP_aes_192_ccm , 570and 571.Fn EVP_aes_256_ccm 572first appeared in OpenSSL 1.0.1 and have been available since 573.Ox 5.3 . 574