LCOV - code coverage report
Current view: top level - src/crypto - md5.c (source / functions) Hit Total Coverage
Test: wpa_supplicant/hostapd combined for hwsim test run 1401264779 Lines: 24 30 80.0 %
Date: 2014-05-28 Functions: 2 2 100.0 %

          Line data    Source code
       1             : /*
       2             :  * MD5 hash implementation and interface functions
       3             :  * Copyright (c) 2003-2005, Jouni Malinen <j@w1.fi>
       4             :  *
       5             :  * This software may be distributed under the terms of the BSD license.
       6             :  * See README for more details.
       7             :  */
       8             : 
       9             : #include "includes.h"
      10             : 
      11             : #include "common.h"
      12             : #include "md5.h"
      13             : #include "crypto.h"
      14             : 
      15             : 
      16             : /**
      17             :  * hmac_md5_vector - HMAC-MD5 over data vector (RFC 2104)
      18             :  * @key: Key for HMAC operations
      19             :  * @key_len: Length of the key in bytes
      20             :  * @num_elem: Number of elements in the data vector
      21             :  * @addr: Pointers to the data areas
      22             :  * @len: Lengths of the data blocks
      23             :  * @mac: Buffer for the hash (16 bytes)
      24             :  * Returns: 0 on success, -1 on failure
      25             :  */
      26        7305 : int hmac_md5_vector(const u8 *key, size_t key_len, size_t num_elem,
      27             :                     const u8 *addr[], const size_t *len, u8 *mac)
      28             : {
      29             :         u8 k_pad[64]; /* padding - key XORd with ipad/opad */
      30             :         u8 tk[16];
      31             :         const u8 *_addr[6];
      32             :         size_t i, _len[6];
      33             : 
      34        7305 :         if (num_elem > 5) {
      35             :                 /*
      36             :                  * Fixed limit on the number of fragments to avoid having to
      37             :                  * allocate memory (which could fail).
      38             :                  */
      39           0 :                 return -1;
      40             :         }
      41             : 
      42             :         /* if key is longer than 64 bytes reset it to key = MD5(key) */
      43        7305 :         if (key_len > 64) {
      44           0 :                 if (md5_vector(1, &key, &key_len, tk))
      45           0 :                         return -1;
      46           0 :                 key = tk;
      47           0 :                 key_len = 16;
      48             :         }
      49             : 
      50             :         /* the HMAC_MD5 transform looks like:
      51             :          *
      52             :          * MD5(K XOR opad, MD5(K XOR ipad, text))
      53             :          *
      54             :          * where K is an n byte key
      55             :          * ipad is the byte 0x36 repeated 64 times
      56             :          * opad is the byte 0x5c repeated 64 times
      57             :          * and text is the data being protected */
      58             : 
      59             :         /* start out by storing key in ipad */
      60        7305 :         os_memset(k_pad, 0, sizeof(k_pad));
      61        7305 :         os_memcpy(k_pad, key, key_len);
      62             : 
      63             :         /* XOR key with ipad values */
      64      474825 :         for (i = 0; i < 64; i++)
      65      467520 :                 k_pad[i] ^= 0x36;
      66             : 
      67             :         /* perform inner MD5 */
      68        7305 :         _addr[0] = k_pad;
      69        7305 :         _len[0] = 64;
      70       15326 :         for (i = 0; i < num_elem; i++) {
      71        8021 :                 _addr[i + 1] = addr[i];
      72        8021 :                 _len[i + 1] = len[i];
      73             :         }
      74        7305 :         if (md5_vector(1 + num_elem, _addr, _len, mac))
      75           0 :                 return -1;
      76             : 
      77        7305 :         os_memset(k_pad, 0, sizeof(k_pad));
      78        7305 :         os_memcpy(k_pad, key, key_len);
      79             :         /* XOR key with opad values */
      80      474825 :         for (i = 0; i < 64; i++)
      81      467520 :                 k_pad[i] ^= 0x5c;
      82             : 
      83             :         /* perform outer MD5 */
      84        7305 :         _addr[0] = k_pad;
      85        7305 :         _len[0] = 64;
      86        7305 :         _addr[1] = mac;
      87        7305 :         _len[1] = MD5_MAC_LEN;
      88        7305 :         return md5_vector(2, _addr, _len, mac);
      89             : }
      90             : 
      91             : 
      92             : /**
      93             :  * hmac_md5 - HMAC-MD5 over data buffer (RFC 2104)
      94             :  * @key: Key for HMAC operations
      95             :  * @key_len: Length of the key in bytes
      96             :  * @data: Pointers to the data area
      97             :  * @data_len: Length of the data area
      98             :  * @mac: Buffer for the hash (16 bytes)
      99             :  * Returns: 0 on success, -1 on failure
     100             :  */
     101        6929 : int hmac_md5(const u8 *key, size_t key_len, const u8 *data, size_t data_len,
     102             :               u8 *mac)
     103             : {
     104        6929 :         return hmac_md5_vector(key, key_len, 1, &data, &data_len, mac);
     105             : }

Generated by: LCOV version 1.10