kern/66029: MD5 alignment problem on a TriMedia processor

Charles Hardin chardin at 2wire.com
Tue Apr 27 09:30:25 PDT 2004


>Number:         66029
>Category:       kern
>Synopsis:       MD5 alignment problem on a TriMedia processor
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Tue Apr 27 09:30:24 PDT 2004
>Closed-Date:
>Last-Modified:
>Originator:     Charles Hardin
>Release:        5.2.1
>Organization:
2Wire
>Environment:
>Description:
      Have been porting a crypto subsystem over to BSD on an alignment senstive processor and stumbled across sporadic hmac_md5 failures that i tracked down to the md5 crypto core alignment access...
>How-To-Repeat:
The following EAP packets were generated using the existing code and on the bad one you'll notice the alignment on the pad is off while the good one is half word aligned...

This code was run a Linux box linked against the sasl library using their hmac_md5 to verify...

#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <md5global.h>
#include <md5.h>
#include <hmac-md5.h>


#if 0
/* bad */
static unsigned char eapmic[] = {
    0x1f, 0x8c, 0x4d, 0xd7, 0x4e, 0x0a, 0x05, 0xff,
    0x22, 0x0e, 0x00, 0x73, 0x80, 0x09, 0xb6, 0xf2 
};

static unsigned char eapol[] = {
 0x00, 0x60, 0xb3, 0x1b, 0x45, 0x56, 0x00, 0x11, 0x22, 0x33, 0x44, 0x01, 0x88, 0x8e, 0x01, 0x03
, 0x00, 0x7f, 0xfe, 0x03, 0xa1, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xb3
, 0xc6, 0x4f, 0x40, 0x5d, 0x9a, 0x4c, 0x7b, 0x05, 0x6c, 0x52, 0x57, 0x8f, 0x8b, 0x41, 0xd4, 0x91
, 0xb1, 0x75, 0xa6, 0xad, 0x5f, 0xd6, 0x49, 0x1e, 0xa9, 0xbd, 0xd1, 0x3b, 0xf3, 0x84, 0xd4, 0x91
, 0xb1, 0x75, 0xa6, 0xad, 0x5f, 0xd6, 0x49, 0x1e, 0xa9, 0xbd, 0xd1, 0x3b, 0xf3, 0x84, 0xd6, 0x00
, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a
, 0xcc, 0xd0, 0xde, 0xc0, 0x85, 0x77, 0x0e, 0x05, 0x5a, 0x4e, 0x59, 0xcf, 0x43, 0xaf, 0x43, 0x00
, 0x20, 0xcb, 0x7a, 0x8c, 0x8c, 0x91, 0x22, 0x21, 0x1b, 0x2e, 0x4d, 0x13, 0x7f, 0xe8, 0xd2, 0x20
, 0x8f, 0x55, 0x2f, 0xf3, 0xfc, 0x3d, 0xea, 0x14, 0xff, 0xdc, 0x29, 0x2c, 0xfe, 0xdf, 0xc0, 0x7e
, 0x7a
};

#endif

#if 1
/* good */
static unsigned char eapmic[] = {
    0xc8, 0xc5, 0x6f, 0x81, 0x9c, 0xb0, 0x37, 0xc5,
    0x95, 0x68, 0xd2, 0xa9, 0xaf, 0x9e, 0x97, 0x52
};

static unsigned char eapol[] = {
 0x00, 0x60, 0xb3, 0x1b, 0x45, 0x56, 0x00, 0x11, 0x22, 0x33, 0x44, 0x01, 0x88, 0x8e, 0x01, 0x03
, 0x00, 0x6c, 0xfe, 0x03, 0x91, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xe3
, 0x55, 0xcb, 0x0e, 0x7e, 0xb4, 0xa9, 0xce, 0xfc, 0x1d, 0xa2, 0x76, 0x74, 0xeb, 0x9e, 0xab, 0xf7
, 0xec, 0xc4, 0x1d, 0x36, 0xaf, 0xa3, 0x83, 0xe4, 0x3f, 0x2a, 0x4d, 0xa7, 0xf7, 0x41, 0x2f, 0xf7
, 0xec, 0xc4, 0x1d, 0x36, 0xaf, 0xa3, 0x83, 0xe4, 0x3f, 0x2a, 0x4d, 0xa7, 0xf7, 0x41, 0x31, 0x00
, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42
, 0x33, 0x88, 0x60, 0xeb, 0xe3, 0x70, 0xf6, 0x8c, 0x2f, 0xa0, 0x09, 0xdb, 0xfe, 0xfd, 0x08, 0x00
, 0x0d, 0xda, 0x29, 0xba, 0xc8, 0x18, 0x20, 0xac, 0x40, 0x50, 0xe0, 0x23, 0xf7, 0xa1
};
#endif

#define IV_FIELD_LEN  16
#define ID_FIELD_LEN  8

#define MIC_OFFSET  (sizeof(u_int8_t) + 2*sizeof(u_int16_t) + \
                     2*sizeof(u_int64_t) + 32 + IV_FIELD_LEN + ID_FIELD_LEN)

int
main(int argc, char **argv)
{
    unsigned char mic[HMAC_MD5_SIZE], oldmic[HMAC_MD5_SIZE];
    unsigned char *cp, *keydesc;
    int i, len;

    cp = eapol;
    cp += 14; /* ethernet hdr */
    keydesc = cp;
    keydesc += 4; /* eap hdr */
    memcpy(oldmic, &keydesc[MIC_OFFSET], HMAC_MD5_SIZE);
    memset(&keydesc[MIC_OFFSET], 0, HMAC_MD5_SIZE);
    len = sizeof(eapol) - (cp - eapol);
    hmac_md5(cp, len, eapmic, sizeof(eapmic), mic);
    printf("HMAC_MD5_SIZE %u %u\n", HMAC_MD5_SIZE, len);
    printf("mic    ");
    for (i = 0; i < HMAC_MD5_SIZE; i++) {
        printf("%02x ", mic[i]);
    }
    printf("\n");
    printf("oldmic ");
    for (i = 0; i < HMAC_MD5_SIZE; i++) {
        printf("%02x ", oldmic[i]);
    }
    printf("\n");
    printf("result %d\n", memcmp(mic, oldmic, HMAC_MD5_SIZE));
}

>Fix:
--- src/sys/crypto/md5.c       2004-04-27 09:17:39.000000000 -0700
+++ src/sys/crypto/md5-patched.c       2004-04-27 09:17:19.000000000 -0700
@@ -228,20 +228,17 @@
 #endif
 }
  
-#if BYTE_ORDER == BIG_ENDIAN
-u_int32_t X[16];
-#endif
-
 static void md5_calc(b64, ctxt)
        u_int8_t *b64;
        md5_ctxt *ctxt;
 {
+       u_int32_t X[16];
        u_int32_t A = ctxt->md5_sta;
        u_int32_t B = ctxt->md5_stb;
        u_int32_t C = ctxt->md5_stc;
        u_int32_t D = ctxt->md5_std;
 #if BYTE_ORDER == LITTLE_ENDIAN
-       u_int32_t *X = (u_int32_t *)b64;
+       bcopy(b64, X, sizeof(X));
 #endif
 #if BYTE_ORDER == BIG_ENDIAN
        /* 4 byte words */

>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list