57#if !defined(MBEDTLS_CONFIG_FILE)
60#include MBEDTLS_CONFIG_FILE
63#if defined(MBEDTLS_NIST_KW_C)
71#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
72#if defined(MBEDTLS_PLATFORM_C)
76#define mbedtls_printf printf
80#if !defined(MBEDTLS_NIST_KW_ALT)
82#define KW_SEMIBLOCK_LENGTH 8
83#define MIN_SEMIBLOCKS_COUNT 3
86static inline unsigned char mbedtls_nist_kw_safer_memcmp(
const void *
a,
const void *
b,
size_t n )
89 volatile const unsigned char *
A = (
volatile const unsigned char *)
a;
90 volatile const unsigned char *
B = (
volatile const unsigned char *)
b;
91 volatile unsigned char diff = 0;
93 for(
i = 0;
i <
n;
i++ )
98 unsigned char x =
A[
i],
y =
B[
i];
106static const unsigned char NIST_KW_ICV1[] = {0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6};
108static const unsigned char NIST_KW_ICV2[] = {0xA6, 0x59, 0x59, 0xA6};
111#define GET_UINT32_BE(n,b,i) \
113 (n) = ( (uint32_t) (b)[(i) ] << 24 ) \
114 | ( (uint32_t) (b)[(i) + 1] << 16 ) \
115 | ( (uint32_t) (b)[(i) + 2] << 8 ) \
116 | ( (uint32_t) (b)[(i) + 3] ); \
121#define PUT_UINT32_BE(n,b,i) \
123 (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
124 (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
125 (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
126 (b)[(i) + 3] = (unsigned char) ( (n) ); \
140 const unsigned char *
key,
141 unsigned int keybits,
150 if( cipher_info ==
NULL )
197static void calc_a_xor_t(
unsigned char A[KW_SEMIBLOCK_LENGTH],
uint64_t t )
200 for(
i = 0;
i <
sizeof(
t );
i++ )
202 A[
i] ^= (
t >> ( (
sizeof(
t ) - 1 -
i ) * 8 ) ) & 0xff;
212 const unsigned char *
input,
size_t in_len,
213 unsigned char *output,
size_t *out_len,
size_t out_size )
216 size_t semiblocks = 0;
218 size_t olen, padlen = 0;
220 unsigned char outbuff[KW_SEMIBLOCK_LENGTH * 2];
221 unsigned char inbuff[KW_SEMIBLOCK_LENGTH * 2];
229 if(
out_size < in_len + KW_SEMIBLOCK_LENGTH )
240 in_len > 0x1FFFFFFFFFFFFF8 ||
242 in_len % KW_SEMIBLOCK_LENGTH != 0 )
247 memcpy( output, NIST_KW_ICV1, KW_SEMIBLOCK_LENGTH );
252 if( in_len % 8 != 0 )
254 padlen = ( 8 - ( in_len % 8 ) );
257 if(
out_size < in_len + KW_SEMIBLOCK_LENGTH + padlen )
268 || in_len > 0xFFFFFFFF
275 memcpy( output, NIST_KW_ICV2, KW_SEMIBLOCK_LENGTH / 2 );
276 PUT_UINT32_BE( ( in_len & 0xffffffff ), output,
277 KW_SEMIBLOCK_LENGTH / 2 );
279 memcpy( output + KW_SEMIBLOCK_LENGTH,
input, in_len );
280 memset( output + KW_SEMIBLOCK_LENGTH + in_len, 0, padlen );
282 semiblocks = ( ( in_len + padlen ) / KW_SEMIBLOCK_LENGTH ) + 1;
284 s = 6 * ( semiblocks - 1 );
287 && in_len <= KW_SEMIBLOCK_LENGTH )
289 memcpy( inbuff, output, 16 );
291 inbuff, 16, output, &olen );
297 unsigned char *
R2 = output + KW_SEMIBLOCK_LENGTH;
298 unsigned char *
A = output;
303 if( semiblocks < MIN_SEMIBLOCKS_COUNT )
310 for(
t = 1;
t <=
s;
t++ )
312 memcpy( inbuff,
A, KW_SEMIBLOCK_LENGTH );
313 memcpy( inbuff + KW_SEMIBLOCK_LENGTH,
R2, KW_SEMIBLOCK_LENGTH );
316 inbuff, 16, outbuff, &olen );
320 memcpy(
A, outbuff, KW_SEMIBLOCK_LENGTH );
321 calc_a_xor_t(
A,
t );
323 memcpy(
R2, outbuff + KW_SEMIBLOCK_LENGTH, KW_SEMIBLOCK_LENGTH );
324 R2 += KW_SEMIBLOCK_LENGTH;
325 if(
R2 >= output + ( semiblocks * KW_SEMIBLOCK_LENGTH ) )
326 R2 = output + KW_SEMIBLOCK_LENGTH;
330 *out_len = semiblocks * KW_SEMIBLOCK_LENGTH;
336 memset( output, 0, semiblocks * KW_SEMIBLOCK_LENGTH );
353 const unsigned char *
input,
size_t semiblocks,
354 unsigned char A[KW_SEMIBLOCK_LENGTH],
355 unsigned char *output,
size_t* out_len )
358 const size_t s = 6 * ( semiblocks - 1 );
361 unsigned char outbuff[KW_SEMIBLOCK_LENGTH * 2];
362 unsigned char inbuff[KW_SEMIBLOCK_LENGTH * 2];
363 unsigned char *
R =
NULL;
366 if( semiblocks < MIN_SEMIBLOCKS_COUNT )
372 memmove( output,
input + KW_SEMIBLOCK_LENGTH, ( semiblocks - 1 ) * KW_SEMIBLOCK_LENGTH );
373 R = output + ( semiblocks - 2 ) * KW_SEMIBLOCK_LENGTH;
376 for(
t =
s;
t >= 1;
t-- )
378 calc_a_xor_t(
A,
t );
380 memcpy( inbuff,
A, KW_SEMIBLOCK_LENGTH );
381 memcpy( inbuff + KW_SEMIBLOCK_LENGTH,
R, KW_SEMIBLOCK_LENGTH );
384 inbuff, 16, outbuff, &olen );
388 memcpy(
A, outbuff, KW_SEMIBLOCK_LENGTH );
391 memcpy(
R, outbuff + KW_SEMIBLOCK_LENGTH, KW_SEMIBLOCK_LENGTH );
394 R = output + ( semiblocks - 2 ) * KW_SEMIBLOCK_LENGTH;
396 R -= KW_SEMIBLOCK_LENGTH;
399 *out_len = ( semiblocks - 1 ) * KW_SEMIBLOCK_LENGTH;
403 memset( output, 0, ( semiblocks - 1 ) * KW_SEMIBLOCK_LENGTH );
416 const unsigned char *
input,
size_t in_len,
417 unsigned char *output,
size_t *out_len,
size_t out_size )
421 unsigned char A[KW_SEMIBLOCK_LENGTH];
422 unsigned char diff, bad_padding = 0;
425 if(
out_size < in_len - KW_SEMIBLOCK_LENGTH )
438 in_len > 0x200000000000000 ||
440 in_len % KW_SEMIBLOCK_LENGTH != 0 )
446 A, output, out_len );
451 diff = mbedtls_nist_kw_safer_memcmp( NIST_KW_ICV1,
A, KW_SEMIBLOCK_LENGTH );
468 if( in_len < KW_SEMIBLOCK_LENGTH * 2 ||
470 in_len > 0x100000000 ||
472 in_len % KW_SEMIBLOCK_LENGTH != 0 )
477 if( in_len == KW_SEMIBLOCK_LENGTH * 2 )
479 unsigned char outbuff[KW_SEMIBLOCK_LENGTH * 2];
481 input, 16, outbuff, &olen );
485 memcpy(
A, outbuff, KW_SEMIBLOCK_LENGTH );
486 memcpy( output, outbuff + KW_SEMIBLOCK_LENGTH, KW_SEMIBLOCK_LENGTH );
488 *out_len = KW_SEMIBLOCK_LENGTH;
494 A, output, out_len );
500 diff = mbedtls_nist_kw_safer_memcmp( NIST_KW_ICV2,
A, KW_SEMIBLOCK_LENGTH / 2 );
507 GET_UINT32_BE( Plen,
A, KW_SEMIBLOCK_LENGTH / 2 );
514 padlen = in_len - KW_SEMIBLOCK_LENGTH - Plen;
522 for( diff = 0,
i = 0;
i < KW_SEMIBLOCK_LENGTH;
i++ )
524 if(
i >= KW_SEMIBLOCK_LENGTH - padlen )
525 diff |= output[*out_len - KW_SEMIBLOCK_LENGTH +
i];
527 bad_padding |= output[*out_len - KW_SEMIBLOCK_LENGTH +
i];
539 memset( output + Plen, 0, padlen );
551 memset( output, 0, *out_len );
564#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
572static const unsigned int key_len[KW_TESTS] = { 16, 24, 32 };
574static const unsigned char kw_key[KW_TESTS][32] = {
575 { 0x75, 0x75, 0xda, 0x3a, 0x93, 0x60, 0x7c, 0xc2,
576 0xbf, 0xd8, 0xce, 0xc7, 0xaa, 0xdf, 0xd9, 0xa6 },
577 { 0x2d, 0x85, 0x26, 0x08, 0x1d, 0x02, 0xfb, 0x5b,
578 0x85, 0xf6, 0x9a, 0xc2, 0x86, 0xec, 0xd5, 0x7d,
579 0x40, 0xdf, 0x5d, 0xf3, 0x49, 0x47, 0x44, 0xd3 },
580 { 0x11, 0x2a, 0xd4, 0x1b, 0x48, 0x56, 0xc7, 0x25,
581 0x4a, 0x98, 0x48, 0xd3, 0x0f, 0xdd, 0x78, 0x33,
582 0x5b, 0x03, 0x9a, 0x48, 0xa8, 0x96, 0x2c, 0x4d,
583 0x1c, 0xb7, 0x8e, 0xab, 0xd5, 0xda, 0xd7, 0x88 }
586static const unsigned char kw_msg[KW_TESTS][40] = {
587 { 0x42, 0x13, 0x6d, 0x3c, 0x38, 0x4a, 0x3e, 0xea,
588 0xc9, 0x5a, 0x06, 0x6f, 0xd2, 0x8f, 0xed, 0x3f },
589 { 0x95, 0xc1, 0x1b, 0xf5, 0x35, 0x3a, 0xfe, 0xdb,
590 0x98, 0xfd, 0xd6, 0xc8, 0xca, 0x6f, 0xdb, 0x6d,
591 0xa5, 0x4b, 0x74, 0xb4, 0x99, 0x0f, 0xdc, 0x45,
592 0xc0, 0x9d, 0x15, 0x8f, 0x51, 0xce, 0x62, 0x9d,
593 0xe2, 0xaf, 0x26, 0xe3, 0x25, 0x0e, 0x6b, 0x4c },
594 { 0x1b, 0x20, 0xbf, 0x19, 0x90, 0xb0, 0x65, 0xd7,
595 0x98, 0xe1, 0xb3, 0x22, 0x64, 0xad, 0x50, 0xa8,
596 0x74, 0x74, 0x92, 0xba, 0x09, 0xa0, 0x4d, 0xd1 }
599static const size_t kw_msg_len[KW_TESTS] = { 16, 40, 24 };
600static const size_t kw_out_len[KW_TESTS] = { 24, 48, 32 };
601static const unsigned char kw_res[KW_TESTS][48] = {
602 { 0x03, 0x1f, 0x6b, 0xd7, 0xe6, 0x1e, 0x64, 0x3d,
603 0xf6, 0x85, 0x94, 0x81, 0x6f, 0x64, 0xca, 0xa3,
604 0xf5, 0x6f, 0xab, 0xea, 0x25, 0x48, 0xf5, 0xfb },
605 { 0x44, 0x3c, 0x6f, 0x15, 0x09, 0x83, 0x71, 0x91,
606 0x3e, 0x5c, 0x81, 0x4c, 0xa1, 0xa0, 0x42, 0xec,
607 0x68, 0x2f, 0x7b, 0x13, 0x6d, 0x24, 0x3a, 0x4d,
608 0x6c, 0x42, 0x6f, 0xc6, 0x97, 0x15, 0x63, 0xe8,
609 0xa1, 0x4a, 0x55, 0x8e, 0x09, 0x64, 0x16, 0x19,
610 0xbf, 0x03, 0xfc, 0xaf, 0x90, 0xb1, 0xfc, 0x2d },
611 { 0xba, 0x8a, 0x25, 0x9a, 0x47, 0x1b, 0x78, 0x7d,
612 0xd5, 0xd5, 0x40, 0xec, 0x25, 0xd4, 0x3d, 0x87,
613 0x20, 0x0f, 0xda, 0xdc, 0x6d, 0x1f, 0x05, 0xd9,
614 0x16, 0x58, 0x4f, 0xa9, 0xf6, 0xcb, 0xf5, 0x12 }
617static const unsigned char kwp_key[KW_TESTS][32] = {
618 { 0x78, 0x65, 0xe2, 0x0f, 0x3c, 0x21, 0x65, 0x9a,
619 0xb4, 0x69, 0x0b, 0x62, 0x9c, 0xdf, 0x3c, 0xc4 },
620 { 0xf5, 0xf8, 0x96, 0xa3, 0xbd, 0x2f, 0x4a, 0x98,
621 0x23, 0xef, 0x16, 0x2b, 0x00, 0xb8, 0x05, 0xd7,
622 0xde, 0x1e, 0xa4, 0x66, 0x26, 0x96, 0xa2, 0x58 },
623 { 0x95, 0xda, 0x27, 0x00, 0xca, 0x6f, 0xd9, 0xa5,
624 0x25, 0x54, 0xee, 0x2a, 0x8d, 0xf1, 0x38, 0x6f,
625 0x5b, 0x94, 0xa1, 0xa6, 0x0e, 0xd8, 0xa4, 0xae,
626 0xf6, 0x0a, 0x8d, 0x61, 0xab, 0x5f, 0x22, 0x5a }
629static const unsigned char kwp_msg[KW_TESTS][31] = {
630 { 0xbd, 0x68, 0x43, 0xd4, 0x20, 0x37, 0x8d, 0xc8,
632 { 0x6c, 0xcd, 0xd5, 0x85, 0x18, 0x40, 0x97, 0xeb,
633 0xd5, 0xc3, 0xaf, 0x3e, 0x47, 0xd0, 0x2c, 0x19,
634 0x14, 0x7b, 0x4d, 0x99, 0x5f, 0x96, 0x43, 0x66,
635 0x91, 0x56, 0x75, 0x8c, 0x13, 0x16, 0x8f },
638static const size_t kwp_msg_len[KW_TESTS] = { 9, 31, 1 };
640static const unsigned char kwp_res[KW_TESTS][48] = {
641 { 0x41, 0xec, 0xa9, 0x56, 0xd4, 0xaa, 0x04, 0x7e,
642 0xb5, 0xcf, 0x4e, 0xfe, 0x65, 0x96, 0x61, 0xe7,
643 0x4d, 0xb6, 0xf8, 0xc5, 0x64, 0xe2, 0x35, 0x00 },
644 { 0x4e, 0x9b, 0xc2, 0xbc, 0xbc, 0x6c, 0x1e, 0x13,
645 0xd3, 0x35, 0xbc, 0xc0, 0xf7, 0x73, 0x6a, 0x88,
646 0xfa, 0x87, 0x53, 0x66, 0x15, 0xbb, 0x8e, 0x63,
647 0x8b, 0xcc, 0x81, 0x66, 0x84, 0x68, 0x17, 0x90,
648 0x67, 0xcf, 0xa9, 0x8a, 0x9d, 0x0e, 0x33, 0x26 },
649 { 0x06, 0xba, 0x7a, 0xe6, 0xf3, 0x24, 0x8c, 0xfd,
650 0xcf, 0x26, 0x75, 0x07, 0xfa, 0x00, 0x1b, 0xc4 }
652static const size_t kwp_out_len[KW_TESTS] = { 24, 40, 16 };
654int mbedtls_nist_kw_self_test(
int verbose )
657 unsigned char out[48];
663 for(
i = 0;
i < KW_TESTS;
i++ )
669 kw_key[
i], key_len[
i] * 8, 1 );
679 kw_msg_len[
i],
out, &olen,
sizeof(
out ) );
680 if(
ret != 0 || kw_out_len[
i] != olen ||
691 kw_key[
i], key_len[
i] * 8, 0 ) )
703 if(
ret != 0 || olen != kw_msg_len[
i] ||
717 for(
i = 0;
i < KW_TESTS;
i++ )
719 olen =
sizeof(
out );
733 kwp_msg_len[
i],
out, &olen,
sizeof(
out ) );
735 if(
ret != 0 || kwp_out_len[
i] != olen ||
746 kwp_key[
i], key_len[
i] * 8, 0 ) )
756 olen,
out, &olen,
sizeof(
out ) );
758 if(
ret != 0 || olen != kwp_msg_len[
i] ||
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
int mbedtls_cipher_setup(mbedtls_cipher_context_t *ctx, const mbedtls_cipher_info_t *cipher_info)
This function initializes and fills the cipher-context structure with the appropriate values....
int mbedtls_cipher_setkey(mbedtls_cipher_context_t *ctx, const unsigned char *key, int key_bitlen, const mbedtls_operation_t operation)
This function sets the key to use with the given context.
#define MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE
#define MBEDTLS_ERR_CIPHER_AUTH_FAILED
#define MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA
const mbedtls_cipher_info_t * mbedtls_cipher_info_from_values(const mbedtls_cipher_id_t cipher_id, int key_bitlen, const mbedtls_cipher_mode_t mode)
This function retrieves the cipher-information structure associated with the given cipher ID,...
void mbedtls_cipher_free(mbedtls_cipher_context_t *ctx)
This function frees and clears the cipher-specific context of ctx. Freeing ctx itself remains the res...
int mbedtls_cipher_update(mbedtls_cipher_context_t *ctx, const unsigned char *input, size_t ilen, unsigned char *output, size_t *olen)
The generic cipher update function. It encrypts or decrypts using the given cipher context....
mbedtls_cipher_id_t
Supported cipher types.
static void cleanup(void)
GLint GLint GLint GLint GLint x
GLint GLint GLint GLint GLint GLint y
GLboolean GLboolean GLboolean b
GLboolean GLboolean GLboolean GLboolean a
GLenum GLenum GLenum input
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
#define memcpy(s1, s2, n)
#define memmove(s1, s2, n)
static HANDLE PIO_APC_ROUTINE PVOID PIO_STATUS_BLOCK ULONG PVOID ULONG PVOID ULONG out_size
This file provides an API for key wrapping (KW) and key wrapping with padding (KWP) as defined in NIS...
int mbedtls_nist_kw_setkey(mbedtls_nist_kw_context *ctx, mbedtls_cipher_id_t cipher, const unsigned char *key, unsigned int keybits, const int is_wrap)
This function initializes the key wrapping context set in the ctx parameter and sets the encryption k...
int mbedtls_nist_kw_wrap(mbedtls_nist_kw_context *ctx, mbedtls_nist_kw_mode_t mode, const unsigned char *input, size_t in_len, unsigned char *output, size_t *out_len, size_t out_size)
This function encrypts a buffer using key wrapping.
int mbedtls_nist_kw_unwrap(mbedtls_nist_kw_context *ctx, mbedtls_nist_kw_mode_t mode, const unsigned char *input, size_t in_len, unsigned char *output, size_t *out_len, size_t out_size)
This function decrypts a buffer using key wrapping.
void mbedtls_nist_kw_free(mbedtls_nist_kw_context *ctx)
This function releases and clears the specified key wrapping context and underlying cipher sub-contex...
void mbedtls_nist_kw_init(mbedtls_nist_kw_context *ctx)
This function initializes the specified key wrapping context to make references valid and prepare the...
Configuration options (set of defines)
#define R2(v, w, x, y, z, i)
The key wrapping context-type definition. The key wrapping context is passed to the APIs called.
wchar_t tm const _CrtWcstime_Writes_and_advances_ptr_ count wchar_t ** out