[BACK]Return to umac.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / ssh

Diff for /src/usr.bin/ssh/umac.c between version 1.13 and 1.14

version 1.13, 2017/10/27 01:01:17 version 1.14, 2017/11/28 06:04:51
Line 1 
Line 1 
 /* $OpenBSD$ */  /* $OpenBSD$ */
 /* -----------------------------------------------------------------------  /* -----------------------------------------------------------------------
  *   *
  * umac.c -- C Implementation UMAC Message Authentication   * umac.c -- C Implementation UMAC Message Authentication
  *   *
  * Version 0.93b of rfc4418.txt -- 2006 July 18   * Version 0.93b of rfc4418.txt -- 2006 July 18
Line 10 
Line 10 
  * Please report bugs and suggestions to the UMAC webpage.   * Please report bugs and suggestions to the UMAC webpage.
  *   *
  * Copyright (c) 1999-2006 Ted Krovetz   * Copyright (c) 1999-2006 Ted Krovetz
  *   *
  * Permission to use, copy, modify, and distribute this software and   * Permission to use, copy, modify, and distribute this software and
  * its documentation for any purpose and with or without fee, is hereby   * its documentation for any purpose and with or without fee, is hereby
  * granted provided that the above copyright notice appears in all copies   * granted provided that the above copyright notice appears in all copies
Line 18 
Line 18 
  * holder not be used in advertising or publicity pertaining to   * holder not be used in advertising or publicity pertaining to
  * distribution of the software without specific, written prior permission.   * distribution of the software without specific, written prior permission.
  *   *
  * Comments should be directed to Ted Krovetz (tdk@acm.org)   * Comments should be directed to Ted Krovetz (tdk@acm.org)
  *   *
  * ---------------------------------------------------------------------- */   * ---------------------------------------------------------------------- */
   
  /* ////////////////////// IMPORTANT NOTES /////////////////////////////////   /* ////////////////////// IMPORTANT NOTES /////////////////////////////////
Line 202 
Line 202 
 }  }
   
 /* The final UHASH result is XOR'd with the output of a pseudorandom  /* The final UHASH result is XOR'd with the output of a pseudorandom
  * function. Here, we use AES to generate random output and   * function. Here, we use AES to generate random output and
  * xor the appropriate bytes depending on the last bits of nonce.   * xor the appropriate bytes depending on the last bits of nonce.
  * This scheme is optimized for sequential, increasing big-endian nonces.   * This scheme is optimized for sequential, increasing big-endian nonces.
  */   */
Line 278 
Line 278 
 /* ---------------------------------------------------------------------- */  /* ---------------------------------------------------------------------- */
   
 /* The NH-based hash functions used in UMAC are described in the UMAC paper  /* The NH-based hash functions used in UMAC are described in the UMAC paper
  * and specification, both of which can be found at the UMAC website.   * and specification, both of which can be found at the UMAC website.
  * The interface to this implementation has two   * The interface to this implementation has two
  * versions, one expects the entire message being hashed to be passed   * versions, one expects the entire message being hashed to be passed
  * in a single buffer and returns the hash result immediately. The second   * in a single buffer and returns the hash result immediately. The second
  * allows the message to be passed in a sequence of buffers. In the   * allows the message to be passed in a sequence of buffers. In the
  * muliple-buffer interface, the client calls the routine nh_update() as   * muliple-buffer interface, the client calls the routine nh_update() as
  * many times as necessary. When there is no more data to be fed to the   * many times as necessary. When there is no more data to be fed to the
  * hash, the client calls nh_final() which calculates the hash output.   * hash, the client calls nh_final() which calculates the hash output.
  * Before beginning another hash calculation the nh_reset() routine   * Before beginning another hash calculation the nh_reset() routine
  * must be called. The single-buffer routine, nh(), is equivalent to   * must be called. The single-buffer routine, nh(), is equivalent to
  * the sequence of calls nh_update() and nh_final(); however it is   * the sequence of calls nh_update() and nh_final(); however it is
  * optimized and should be prefered whenever the multiple-buffer interface   * optimized and should be prefered whenever the multiple-buffer interface
  * is not necessary. When using either interface, it is the client's   * is not necessary. When using either interface, it is the client's
  * responsability to pass no more than L1_KEY_LEN bytes per hash result.   * responsability to pass no more than L1_KEY_LEN bytes per hash result.
  *   *
  * The routine nh_init() initializes the nh_ctx data structure and   * The routine nh_init() initializes the nh_ctx data structure and
  * must be called once, before any other PDF routine.   * must be called once, before any other PDF routine.
  */   */
   
  /* The "nh_aux" routines do the actual NH hashing work. They   /* The "nh_aux" routines do the actual NH hashing work. They
   * expect buffers to be multiples of L1_PAD_BOUNDARY. These routines    * expect buffers to be multiples of L1_PAD_BOUNDARY. These routines
   * produce output for all STREAMS NH iterations in one call,    * produce output for all STREAMS NH iterations in one call,
   * allowing the parallel implementation of the streams.    * allowing the parallel implementation of the streams.
   */    */
   
Line 322 
Line 322 
 #if (UMAC_OUTPUT_LEN == 4)  #if (UMAC_OUTPUT_LEN == 4)
   
 static void nh_aux(void *kp, const void *dp, void *hp, UINT32 dlen)  static void nh_aux(void *kp, const void *dp, void *hp, UINT32 dlen)
 /* NH hashing primitive. Previous (partial) hash result is loaded and  /* NH hashing primitive. Previous (partial) hash result is loaded and
 * then stored via hp pointer. The length of the data pointed at by "dp",  * then stored via hp pointer. The length of the data pointed at by "dp",
 * "dlen", is guaranteed to be divisible by L1_PAD_BOUNDARY (32).  Key  * "dlen", is guaranteed to be divisible by L1_PAD_BOUNDARY (32).  Key
 * is expected to be endian compensated in memory at key setup.  * is expected to be endian compensated in memory at key setup.
 */  */
 {  {
     UINT64 h;      UINT64 h;
Line 671 
Line 671 
     if (hc->next_data_empty != 0) {      if (hc->next_data_empty != 0) {
         nh_len = ((hc->next_data_empty + (L1_PAD_BOUNDARY - 1)) &          nh_len = ((hc->next_data_empty + (L1_PAD_BOUNDARY - 1)) &
                                                 ~(L1_PAD_BOUNDARY - 1));                                                  ~(L1_PAD_BOUNDARY - 1));
         zero_pad(hc->data + hc->next_data_empty,          zero_pad(hc->data + hc->next_data_empty,
                                           nh_len - hc->next_data_empty);                                            nh_len - hc->next_data_empty);
         nh_transform(hc, hc->data, nh_len);          nh_transform(hc, hc->data, nh_len);
         hc->bytes_hashed += hc->next_data_empty;          hc->bytes_hashed += hc->next_data_empty;
Line 738 
Line 738 
  * buffers are presented sequentially. In the sequential interface, the   * buffers are presented sequentially. In the sequential interface, the
  * UHASH client calls the routine uhash_update() as many times as necessary.   * UHASH client calls the routine uhash_update() as many times as necessary.
  * When there is no more data to be fed to UHASH, the client calls   * When there is no more data to be fed to UHASH, the client calls
  * uhash_final() which   * uhash_final() which
  * calculates the UHASH output. Before beginning another UHASH calculation   * calculates the UHASH output. Before beginning another UHASH calculation
  * the uhash_reset() routine must be called. The all-at-once UHASH routine,   * the uhash_reset() routine must be called. The all-at-once UHASH routine,
  * uhash(), is equivalent to the sequence of calls uhash_update() and   * uhash(), is equivalent to the sequence of calls uhash_update() and
  * uhash_final(); however it is optimized and should be   * uhash_final(); however it is optimized and should be
  * used whenever the sequential interface is not necessary.   * used whenever the sequential interface is not necessary.
  *   *
  * The routine uhash_init() initializes the uhash_ctx data structure and   * The routine uhash_init() initializes the uhash_ctx data structure and
  * must be called once, before any other UHASH routine.   * must be called once, before any other UHASH routine.
  */   */
   
 /* ---------------------------------------------------------------------- */  /* ---------------------------------------------------------------------- */
 /* ----- Constants and uhash_ctx ---------------------------------------- */  /* ----- Constants and uhash_ctx ---------------------------------------- */
Line 829 
Line 829 
   
     for (i = 0; i < STREAMS; i++) {      for (i = 0; i < STREAMS; i++) {
         if ((UINT32)(data[i] >> 32) == 0xfffffffful) {          if ((UINT32)(data[i] >> 32) == 0xfffffffful) {
             hc->poly_accum[i] = poly64(hc->poly_accum[i],              hc->poly_accum[i] = poly64(hc->poly_accum[i],
                                        hc->poly_key_8[i], p64 - 1);                                         hc->poly_key_8[i], p64 - 1);
             hc->poly_accum[i] = poly64(hc->poly_accum[i],              hc->poly_accum[i] = poly64(hc->poly_accum[i],
                                        hc->poly_key_8[i], (data[i] - 59));                                         hc->poly_key_8[i], (data[i] - 59));
Line 913 
Line 913 
         if (ahc->poly_accum[i] >= p64)          if (ahc->poly_accum[i] >= p64)
             ahc->poly_accum[i] -= p64;              ahc->poly_accum[i] -= p64;
         t  = ip_aux(0,ahc->ip_keys+(i*4), ahc->poly_accum[i]);          t  = ip_aux(0,ahc->ip_keys+(i*4), ahc->poly_accum[i]);
         STORE_UINT32_BIG((UINT32 *)res+i,          STORE_UINT32_BIG((UINT32 *)res+i,
                          ip_reduce_p36(t) ^ ahc->ip_trans[i]);                           ip_reduce_p36(t) ^ ahc->ip_trans[i]);
     }      }
 }  }
Line 978 
Line 978 
     for (i = 0; i < STREAMS; i++)      for (i = 0; i < STREAMS; i++)
           memcpy(ahc->ip_keys+4*i, buf+(8*i+4)*sizeof(UINT64),            memcpy(ahc->ip_keys+4*i, buf+(8*i+4)*sizeof(UINT64),
                                                  4*sizeof(UINT64));                                                   4*sizeof(UINT64));
     endian_convert_if_le(ahc->ip_keys, sizeof(UINT64),      endian_convert_if_le(ahc->ip_keys, sizeof(UINT64),
                                                   sizeof(ahc->ip_keys));                                                    sizeof(ahc->ip_keys));
     for (i = 0; i < STREAMS*4; i++)      for (i = 0; i < STREAMS*4; i++)
         ahc->ip_keys[i] %= p36;  /* Bring into Z_p36 */          ahc->ip_keys[i] %= p36;  /* Bring into Z_p36 */
Line 1128 
Line 1128 
      */       */
     if (len <= L1_KEY_LEN) {      if (len <= L1_KEY_LEN) {
         if (len == 0)                  /* If zero length messages will not */          if (len == 0)                  /* If zero length messages will not */
                 nh_len = L1_PAD_BOUNDARY;  /* be seen, comment out this case   */                  nh_len = L1_PAD_BOUNDARY;  /* be seen, comment out this case   */
         else          else
                 nh_len = ((len + (L1_PAD_BOUNDARY - 1)) & ~(L1_PAD_BOUNDARY - 1));                  nh_len = ((len + (L1_PAD_BOUNDARY - 1)) & ~(L1_PAD_BOUNDARY - 1));
         extra_zeroes_needed = nh_len - len;          extra_zeroes_needed = nh_len - len;
Line 1169 
Line 1169 
   
 /* The UMAC interface has two interfaces, an all-at-once interface where  /* The UMAC interface has two interfaces, an all-at-once interface where
  * the entire message to be authenticated is passed to UMAC in one buffer,   * the entire message to be authenticated is passed to UMAC in one buffer,
  * and a sequential interface where the message is presented a little at a   * and a sequential interface where the message is presented a little at a
  * time. The all-at-once is more optimaized than the sequential version and   * time. The all-at-once is more optimaized than the sequential version and
  * should be preferred when the sequential interface is not required.   * should be preferred when the sequential interface is not required.
  */   */
 struct umac_ctx {  struct umac_ctx {
     uhash_ctx hash;          /* Hash function for message compression    */      uhash_ctx hash;          /* Hash function for message compression    */
Line 1207 
Line 1207 
 /* ---------------------------------------------------------------------- */  /* ---------------------------------------------------------------------- */
   
 struct umac_ctx *umac_new(const u_char key[])  struct umac_ctx *umac_new(const u_char key[])
 /* Dynamically allocate a umac_ctx struct, initialize variables,  /* Dynamically allocate a umac_ctx struct, initialize variables,
  * generate subkeys from key. Align to 16-byte boundary.   * generate subkeys from key. Align to 16-byte boundary.
  */   */
 {  {
Line 1257 
Line 1257 
 /* ---------------------------------------------------------------------- */  /* ---------------------------------------------------------------------- */
   
 #if 0  #if 0
 int umac(struct umac_ctx *ctx, u_char *input,  int umac(struct umac_ctx *ctx, u_char *input,
          long len, u_char tag[],           long len, u_char tag[],
          u_char nonce[8])           u_char nonce[8])
 /* All-in-one version simply calls umac_update() and umac_final().        */  /* All-in-one version simply calls umac_update() and umac_final().        */

Legend:
Removed from v.1.13  
changed lines
  Added in v.1.14