Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 27 Apr 2004 09:24:02 -0700 (PDT)
From:      Charles Hardin <chardin@2wire.com>
To:        freebsd-gnats-submit@FreeBSD.org
Subject:   kern/66029: MD5 alignment problem on a TriMedia processor
Message-ID:  <200404271624.i3RGO2Om056751@www.freebsd.org>
Resent-Message-ID: <200404271630.i3RGUOaD023830@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>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:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200404271624.i3RGO2Om056751>