source: svn/trunk/newcon3bcm2_21bu/dta/src/bootloader/aes/aes-cmac.c @ 2

Last change on this file since 2 was 2, checked in by phkim, 11 years ago

1.phkim

  1. revision copy newcon3sk r27
  • Property svn:executable set to *
File size: 3.9 KB
Line 
1/***************************************************************
2*
3* Broadcom Corp. Confidential
4* Copyright 2011 Broadcom Corp. All Rights Reserved.
5*
6* THIS SOFTWARE MAY ONLY BE USED SUBJECT TO AN EXECUTED
7* SOFTWARE LICENSE AGREEMENT BETWEEN THE USER AND BROADCOM.
8* YOU HAVE NO RIGHT TO USE OR EXPLOIT THIS MATERIAL EXCEPT
9* SUBJECT TO THE TERMS OF SUCH AN AGREEMENT.
10*
11* File:         aes-cmac.c
12* Description: aes-cmac reference implementation. this implementation
13* is lifted from RFC-4493 and modified to work with particular aes
14* implementation that I had. This used only for testing of signatures
15* and not intended for production since it is very slow.
16*
17* Created: Mon November 15 2010.
18*
19*
20*
21****************************************************************/
22
23#include "ministd.h"
24#include "aes.h"
25
26/* constants */
27
28unsigned char const_Zero[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
29unsigned char const_Rb[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0x87};
30
31void xor_128(unsigned char *a, unsigned char *b, unsigned char *out)
32{
33        int i;
34        for (i=0;i<16; i++)
35        {
36                out[i] = a[i] ^ b[i];
37        }
38}
39
40void leftshift_onebit(unsigned char *input,unsigned char *output)
41{
42        int         i;
43        unsigned char overflow = 0;
44
45        for ( i=15; i>=0; i-- ) {
46                output[i] = input[i] << 1;
47                output[i] |= overflow;
48                overflow = (input[i] & 0x80)?1:0;
49        }
50        return;
51}
52
53void generate_subkey(aes_ctx_t *ctx, unsigned char *K1, unsigned char *K2)
54{
55        unsigned char L[16];
56        unsigned char tmp[16];
57
58        aes_encrypt(ctx,const_Zero,L);
59
60        if ( (L[0] & 0x80) == 0 ) { /* If MSB(L) = 0, then K1 = L << 1 */
61                leftshift_onebit(L,K1);
62        } else {    /* Else K1 = ( L << 1 ) (+) Rb */
63
64                leftshift_onebit(L,tmp);
65                xor_128(tmp,const_Rb,K1);
66        }
67
68        if ( (K1[0] & 0x80) == 0 ) {
69                leftshift_onebit(K1,K2);
70        } else {
71                leftshift_onebit(K1,tmp);
72                xor_128(tmp,const_Rb,K2);
73        }
74        return;
75}
76
77void padding ( unsigned char *lastb, unsigned char *pad, int length )
78{
79        int         j;
80
81        /* original last block */
82        for ( j=0; j<16; j++ ) {
83                if ( j < length ) {
84                        pad[j] = lastb[j];
85                } else if ( j == length ) {
86                        pad[j] = 0x80;
87                } else {
88                        pad[j] = 0x00;
89                }
90        }
91}
92
93void aes_cmac ( aes_ctx_t *ctx, unsigned char *input, int length, unsigned char *mac )
94{
95        unsigned char       X[16],Y[16], M_last[16], padded[16];
96        unsigned char       K1[16], K2[16];
97        int         n, i, flag;
98        generate_subkey(ctx, K1,K2);
99
100        n = (length+15) / 16;       /* n is number of rounds */
101
102        if ( n == 0 ) {
103                n = 1;
104                flag = 0;
105        } else {
106                if ( (length%16) == 0 ) { /* last block is a complete block */
107                        flag = 1;
108                } else { /* last block is not complete block */
109                        flag = 0;
110                }
111
112
113        }
114
115        if ( flag ) { /* last block is complete block */
116                xor_128(&input[16*(n-1)],K1,M_last);
117        } else {
118                padding(&input[16*(n-1)],padded,length%16);
119                xor_128(padded,K2,M_last);
120        }
121
122        for ( i=0; i<16; i++ ) X[i] = 0;
123        for ( i=0; i<n-1; i++ ) {
124                xor_128(X,&input[16*i],Y); /* Y := Mi (+) X  */
125                aes_encrypt(ctx,Y,X);      /* X := AES-128(KEY, Y); */
126        }
127
128        xor_128(X,M_last,Y);
129        aes_encrypt(ctx,Y,X);
130
131        for ( i=0; i<16; i++ ) {
132                mac[i] = X[i];
133        }
134}
135
136int test_aes_cmac()
137{
138        unsigned char L[16], K1[16], K2[16], T[16];
139        unsigned char M[64] = {
140                0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
141                0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
142                0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
143                0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
144                0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11,
145                0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef,
146                0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17,
147                0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10
148        };
149        unsigned char key[16] = {
150                0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
151                0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c
152        };
153
154        aes_ctx_t *ctx;
155
156        ctx = aes_alloc_ctx(key, sizeof(key));
157
158        printf("\nSubkey Generation\n");
159        aes_encrypt(ctx,const_Zero,L);
160
161        generate_subkey(ctx,K1,K2);
162
163
164        aes_cmac(ctx,M,0,T);
165        aes_cmac(ctx,M,16,T);
166        aes_cmac(ctx,M,40,T);
167        aes_cmac(ctx,M,64,T);
168        printf("--------------------------------------------------\n");
169        aes_free_ctx(ctx);
170
171        return 0;
172}
173
174
Note: See TracBrowser for help on using the repository browser.