[tools] / trunk / publicdemo / sipp / milenage.c Repository:
ViewVC logotype

View of /trunk/publicdemo/sipp/milenage.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 70 - (download) (annotate)
Thu May 5 20:35:33 2011 UTC (2 years ago) by jhermanski
File size: 7261 byte(s)
Package all media, etc. needed for Public demo system into one tree
    1 /*-------------------------------------------------------------------
    2  *          Example algorithms f1, f1*, f2, f3, f4, f5, f5*
    3  *-------------------------------------------------------------------
    4  *
    5  *  A sample implementation of the example 3GPP authentication and
    6  *  key agreement functions f1, f1*, f2, f3, f4, f5 and f5*.  This is
    7  *  a byte-oriented implementation of the functions, and of the block
    8  *  cipher kernel function Rijndael.
    9  *
   10  *  This has been coded for clarity, not necessarily for efficiency.
   11  *
   12  *  The functions f2, f3, f4 and f5 share the same inputs and have
   13  *  been coded together as a single function.  f1, f1* and f5* are
   14  *  all coded separately.
   15  *
   16  *-----------------------------------------------------------------*/
   17 
   18 #include "milenage.h"
   19 #include "rijndael.h"
   20 
   21 /*--------------------------- prototypes --------------------------*/
   22 
   23 
   24 
   25 /*-------------------------------------------------------------------
   26  *                            Algorithm f1
   27  *-------------------------------------------------------------------
   28  *
   29  *  Computes network authentication code MAC-A from key K, random
   30  *  challenge RAND, sequence number SQN and authentication management
   31  *  field AMF.
   32  *
   33  *-----------------------------------------------------------------*/
   34 
   35 void f1    ( u8 k[16], u8 rand[16], u8 sqn[6], u8 amf[2],
   36              u8 mac_a[8], u8 op[16] )
   37 {
   38   u8 op_c[16];
   39   u8 temp[16];
   40   u8 in1[16];
   41   u8 out1[16];
   42   u8 rijndaelInput[16];
   43   u8 i;
   44 
   45   RijndaelKeySchedule( k );
   46 
   47   ComputeOPc( op_c, op );
   48 
   49   for (i=0; i<16; i++)
   50     rijndaelInput[i] = rand[i] ^ op_c[i];
   51   RijndaelEncrypt( rijndaelInput, temp );
   52 
   53   for (i=0; i<6; i++)
   54   {
   55     in1[i]    = sqn[i];
   56     in1[i+8]  = sqn[i];
   57   }
   58   for (i=0; i<2; i++)
   59   {
   60     in1[i+6]  = amf[i];
   61     in1[i+14] = amf[i];
   62   }
   63 
   64   /* XOR op_c and in1, rotate by r1=64, and XOR *
   65    * on the constant c1 (which is all zeroes)   */
   66 
   67   for (i=0; i<16; i++)
   68     rijndaelInput[(i+8) % 16] = in1[i] ^ op_c[i];
   69 
   70   /* XOR on the value temp computed before */
   71 
   72   for (i=0; i<16; i++)
   73     rijndaelInput[i] ^= temp[i];
   74 
   75   RijndaelEncrypt( rijndaelInput, out1 );
   76   for (i=0; i<16; i++)
   77     out1[i] ^= op_c[i];
   78 
   79   for (i=0; i<8; i++)
   80     mac_a[i] = out1[i];
   81 
   82   return;
   83 } /* end of function f1 */
   84 
   85 
   86 
   87 /*-------------------------------------------------------------------
   88  *                            Algorithms f2-f5
   89  *-------------------------------------------------------------------
   90  *
   91  *  Takes key K and random challenge RAND, and returns response RES,
   92  *  confidentiality key CK, integrity key IK and anonymity key AK.
   93  *
   94  *-----------------------------------------------------------------*/
   95 
   96 void f2345 ( u8 k[16], u8 rand[16],
   97              u8 res[8], u8 ck[16], u8 ik[16], u8 ak[6], u8 op[16] )
   98 {
   99   u8 op_c[16];
  100   u8 temp[16];
  101   u8 out[16];
  102   u8 rijndaelInput[16];
  103   u8 i;
  104 
  105   RijndaelKeySchedule( k );
  106 
  107   ComputeOPc( op_c, op );
  108 
  109   for (i=0; i<16; i++)
  110     rijndaelInput[i] = rand[i] ^ op_c[i];
  111   RijndaelEncrypt( rijndaelInput, temp );
  112 
  113   /* To obtain output block OUT2: XOR OPc and TEMP,    *
  114    * rotate by r2=0, and XOR on the constant c2 (which *
  115    * is all zeroes except that the last bit is 1).     */
  116 
  117   for (i=0; i<16; i++)
  118     rijndaelInput[i] = temp[i] ^ op_c[i];
  119   rijndaelInput[15] ^= 1;
  120 
  121   RijndaelEncrypt( rijndaelInput, out );
  122   for (i=0; i<16; i++)
  123     out[i] ^= op_c[i];
  124 
  125   for (i=0; i<8; i++)
  126     res[i] = out[i+8];
  127   for (i=0; i<6; i++)
  128     ak[i]  = out[i];
  129 
  130   /* To obtain output block OUT3: XOR OPc and TEMP,        *
  131    * rotate by r3=32, and XOR on the constant c3 (which    *
  132    * is all zeroes except that the next to last bit is 1). */
  133 
  134   for (i=0; i<16; i++)
  135     rijndaelInput[(i+12) % 16] = temp[i] ^ op_c[i];
  136   rijndaelInput[15] ^= 2;
  137 
  138   RijndaelEncrypt( rijndaelInput, out );
  139   for (i=0; i<16; i++)
  140     out[i] ^= op_c[i];
  141 
  142   for (i=0; i<16; i++)
  143     ck[i] = out[i];
  144 
  145   /* To obtain output block OUT4: XOR OPc and TEMP,         *
  146    * rotate by r4=64, and XOR on the constant c4 (which     *
  147    * is all zeroes except that the 2nd from last bit is 1). */
  148 
  149   for (i=0; i<16; i++)
  150     rijndaelInput[(i+8) % 16] = temp[i] ^ op_c[i];
  151   rijndaelInput[15] ^= 4;
  152 
  153   RijndaelEncrypt( rijndaelInput, out );
  154   for (i=0; i<16; i++)
  155     out[i] ^= op_c[i];
  156 
  157   for (i=0; i<16; i++)
  158     ik[i] = out[i];
  159 
  160   return;
  161 } /* end of function f2345 */
  162 
  163 
  164 /*-------------------------------------------------------------------
  165  *                            Algorithm f1*
  166  *-------------------------------------------------------------------
  167  *
  168  *  Computes resynch authentication code MAC-S from key K, random
  169  *  challenge RAND, sequence number SQN and authentication management
  170  *  field AMF.
  171  *
  172  *-----------------------------------------------------------------*/
  173 
  174 void f1star( u8 k[16], u8 rand[16], u8 sqn[6], u8 amf[2],
  175              u8 mac_s[8], u8 op[16] )
  176 {
  177   u8 op_c[16];
  178   u8 temp[16];
  179   u8 in1[16];
  180   u8 out1[16];
  181   u8 rijndaelInput[16];
  182   u8 i;
  183 
  184   RijndaelKeySchedule( k );
  185 
  186   ComputeOPc( op_c, op );
  187 
  188   for (i=0; i<16; i++)
  189     rijndaelInput[i] = rand[i] ^ op_c[i];
  190   RijndaelEncrypt( rijndaelInput, temp );
  191 
  192   for (i=0; i<6; i++)
  193   {
  194     in1[i]    = sqn[i];
  195     in1[i+8]  = sqn[i];
  196   }
  197   for (i=0; i<2; i++)
  198   {
  199     in1[i+6]  = amf[i];
  200     in1[i+14] = amf[i];
  201   }
  202 
  203   /* XOR op_c and in1, rotate by r1=64, and XOR *
  204    * on the constant c1 (which is all zeroes)   */
  205 
  206   for (i=0; i<16; i++)
  207     rijndaelInput[(i+8) % 16] = in1[i] ^ op_c[i];
  208 
  209   /* XOR on the value temp computed before */
  210 
  211   for (i=0; i<16; i++)
  212     rijndaelInput[i] ^= temp[i];
  213 
  214   RijndaelEncrypt( rijndaelInput, out1 );
  215   for (i=0; i<16; i++)
  216     out1[i] ^= op_c[i];
  217 
  218   for (i=0; i<8; i++)
  219     mac_s[i] = out1[i+8];
  220 
  221   return;
  222 } /* end of function f1star */
  223 
  224 
  225 /*-------------------------------------------------------------------
  226  *                            Algorithm f5*
  227  *-------------------------------------------------------------------
  228  *
  229  *  Takes key K and random challenge RAND, and returns resynch
  230  *  anonymity key AK.
  231  *
  232  *-----------------------------------------------------------------*/
  233 
  234 void f5star( u8 k[16], u8 rand[16],
  235              u8 ak[6], u8 op[16] )
  236 {
  237   u8 op_c[16];
  238   u8 temp[16];
  239   u8 out[16];
  240   u8 rijndaelInput[16];
  241   u8 i;
  242 
  243   RijndaelKeySchedule( k );
  244 
  245   ComputeOPc( op_c, op );
  246 
  247   for (i=0; i<16; i++)
  248     rijndaelInput[i] = rand[i] ^ op_c[i];
  249   RijndaelEncrypt( rijndaelInput, temp );
  250 
  251   /* To obtain output block OUT5: XOR OPc and TEMP,         *
  252    * rotate by r5=96, and XOR on the constant c5 (which     *
  253    * is all zeroes except that the 3rd from last bit is 1). */
  254 
  255   for (i=0; i<16; i++)
  256     rijndaelInput[(i+4) % 16] = temp[i] ^ op_c[i];
  257   rijndaelInput[15] ^= 8;
  258 
  259   RijndaelEncrypt( rijndaelInput, out );
  260   for (i=0; i<16; i++)
  261     out[i] ^= op_c[i];
  262 
  263   for (i=0; i<6; i++)
  264     ak[i] = out[i];
  265 
  266   return;
  267 } /* end of function f5star */
  268 
  269 
  270 /*-------------------------------------------------------------------
  271  *  Function to compute OPc from OP and K.  Assumes key schedule has
  272     already been performed.
  273  *-----------------------------------------------------------------*/
  274 
  275 void ComputeOPc( u8 op_c[16], u8 op[16] )
  276 {
  277   u8 i;
  278 
  279   RijndaelEncrypt( op, op_c );
  280   for (i=0; i<16; i++)
  281     op_c[i] ^= op[i];
  282 
  283   return;
  284 } /* end of function ComputeOPc */

No admin address has been configured
ViewVC Help
Powered by ViewVC 1.0.8