diff options
Diffstat (limited to 'stack/obx/obx_md5.c')
-rw-r--r-- | stack/obx/obx_md5.c | 1050 |
1 files changed, 0 insertions, 1050 deletions
diff --git a/stack/obx/obx_md5.c b/stack/obx/obx_md5.c deleted file mode 100644 index 6e0d6ea..0000000 --- a/stack/obx/obx_md5.c +++ /dev/null @@ -1,1050 +0,0 @@ -/***************************************************************************** -** -** Name: obx_md5.c -** -** File: OBEX Authentication related functions -** -** Copyright (c) 2003-2011, Broadcom Corp., All Rights Reserved. -** Broadcom Bluetooth Core. Proprietary and confidential. -** -*****************************************************************************/ -#include <stdio.h> -#include <string.h> - -#include "bt_target.h" -#include "btu.h" -#include "obx_int.h" -#include "wcassert.h" - - - -/* -* This code implements the MD5 message-digest algorithm. -* The algorithm is due to Ron Rivest. This code was -* written by Colin Plumb in 1993, no copyright is claimed. -* This code is in the public domain; do with it what you wish. -* -* Equivalent code is available from RSA Data Security, Inc. -* This code has been tested against that, and is equivalent, -* except that you don't need to include two pages of legalese -* with every copy. -* -* To compute the message digest of a chunk of bytes, declare an -* MD5Context structure, pass it to MD5Init, call MD5Update as -* needed on buffers full of bytes, and then call MD5Final, which -* will fill a supplied 16-byte array with the digest. -*/ -typedef UINT32 word32; -typedef UINT8 byte; -struct xMD5Context { - word32 buf[4]; - word32 bytes[2]; - word32 in[16]; -}; - -static void obx_md5_transform(word32 buf[4], word32 const in[16]); - -/* -* Shuffle the bytes into little-endian order within words, as per the -* MD5 spec. Note: this code works regardless of the byte order. -*/ -static void obx_byte_swap(word32 *buf, unsigned words) -{ - byte *p = (byte *)buf; - do { - *buf++ = (word32)((unsigned)p[3] << 8 | p[2]) << 16 - | (word32)((unsigned)p[1] << 8 | p[0]); - p += 4; - } while (--words); -} - -/* -* Start MD5 accumulation. Set bit count to 0 and buffer to mysterious -* initialization constants. -*/ -static void obx_md5_init(struct xMD5Context *ctx) -{ - ctx->buf[0] = 0x67452301; - ctx->buf[1] = 0xefcdab89; - ctx->buf[2] = 0x98badcfe; - ctx->buf[3] = 0x10325476; - ctx->bytes[0] = 0; - ctx->bytes[1] = 0; -} - -/* -* Update context to reflect the concatenation of another buffer full -* of bytes. -*/ -static void obx_md5_update(struct xMD5Context *ctx, byte const *buf, int len) -{ - word32 t; - /* Update byte count */ - t = ctx->bytes[0]; - if ((ctx->bytes[0] = t + len) < t) - ctx->bytes[1]++; /* Carry from low to high */ - t = 64 - (t & 0x3f); /* Space avail in ctx->in (at least 1) */ - if ((unsigned)t > (unsigned)len) - { - memcpy ((byte *)ctx->in + 64 - (unsigned)t, buf, len); - return; - } - /* First chunk is an odd size */ - memcpy (ctx->in + (64 - (unsigned)t), buf, (unsigned)t); - obx_byte_swap(ctx->in, 16); - obx_md5_transform(ctx->buf, ctx->in); - buf += (unsigned)t; - len -= (unsigned)t; - /* Process data in 64-byte chunks */ - while (len >= 64) - { - /* coverity[access_dbuff_const] */ - memcpy (ctx->in, buf, 64); - obx_byte_swap(ctx->in, 16); - obx_md5_transform(ctx->buf, ctx->in); - buf += 64; - len -= 64; - } - /* Handle any remaining bytes of data. */ - memcpy (ctx->in, buf, len); -} - -/* -* Final wrapup - pad to 64-byte boundary with the bit pattern -* 1 0* (64-bit count of bits processed, MSB-first) -*/ -static void obx_md5_final(byte digest[16], struct xMD5Context *ctx) -{ - int count = (int)(ctx->bytes[0] & 0x3f); /* Bytes in ctx->in */ - byte *p = (byte *)ctx->in + count; /* First unused byte */ - /* Set the first char of padding to 0x80. There is always room.*/ - *p++ = 0x80; - /* Bytes of padding needed to make 56 bytes (-8..55) */ - count = 56 - 1 - count; - if (count < 0) /* Padding forces an extra block */ - { - memset (p, 0, count+8); - obx_byte_swap(ctx->in, 16); - obx_md5_transform(ctx->buf, ctx->in); - p = (byte *)ctx->in; - count = 56; - } - memset (p, 0, count+8); - obx_byte_swap(ctx->in, 14); - /* Append length in bits and transform */ - ctx->in[14] = ctx->bytes[0] << 3; - ctx->in[15] = ctx->bytes[1] << 3 | ctx->bytes[0] >> 29; - obx_md5_transform(ctx->buf, ctx->in); - obx_byte_swap(ctx->buf, 4); - memcpy (digest, ctx->buf, 16); - memset (ctx, 0, sizeof(ctx)); -} - -/* The four core functions - F1 is optimized somewhat */ -/* #define F1(x, y, z) (x & y | ~x & z) */ -#define F1(x, y, z) (z ^ (x & (y ^ z))) -#define F2(x, y, z) F1(z, x, y) -#define F3(x, y, z) (x ^ y ^ z) -#define F4(x, y, z) (y ^ (x | ~z)) - -/* This is the central step in the MD5 algorithm. */ -#define MD5STEP(f,w,x,y,z,in,s) \ -(w += f(x,y,z) + in, w = (w<<s | w>>(32-s)) + x) - -/* -* The core of the MD5 algorithm, this alters an existing MD5 hash to -* reflect the addition of 16 longwords of new data. MD5Update blocks -* the data and converts bytes into longwords for this routine. -*/ -static const word32 obx_md5_f1 [] = -{ - 0xd76aa478, - 0xe8c7b756, - 0x242070db, - 0xc1bdceee, - - 0xf57c0faf, - 0x4787c62a, - 0xa8304613, - 0xfd469501, - - 0x698098d8, - 0x8b44f7af, - 0xffff5bb1, - 0x895cd7be, - - 0x6b901122, - 0xfd987193, - 0xa679438e, - 0x49b40821 -}; - -static const word32 obx_md5_f2 [] = -{ - 0xf61e2562, - 0xc040b340, - 0x265e5a51, - 0xe9b6c7aa, - - 0xd62f105d, - 0x02441453, - 0xd8a1e681, - 0xe7d3fbc8, - - 0x21e1cde6, - 0xc33707d6, - 0xf4d50d87, - 0x455a14ed, - - 0xa9e3e905, - 0xfcefa3f8, - 0x676f02d9, - 0x8d2a4c8a -}; - -static const word32 obx_md5_f3 [] = -{ - 0xfffa3942, - 0x8771f681, - 0x6d9d6122, - 0xfde5380c, - - 0xa4beea44, - 0x4bdecfa9, - 0xf6bb4b60, - 0xbebfbc70, - - 0x289b7ec6, - 0xeaa127fa, - 0xd4ef3085, - 0x04881d05, - - 0xd9d4d039, - 0xe6db99e5, - 0x1fa27cf8, - 0xc4ac5665 -}; - -static const word32 obx_md5_f4 [] = -{ - 0xf4292244, - 0x432aff97, - 0xab9423a7, - 0xfc93a039, - - 0x655b59c3, - 0x8f0ccc92, - 0xffeff47d, - 0x85845dd1, - - 0x6fa87e4f, - 0xfe2ce6e0, - 0xa3014314, - 0x4e0811a1, - - 0xf7537e82, - 0xbd3af235, - 0x2ad7d2bb, - 0xeb86d391 -}; - -static const UINT8 obx_md5_a [] = -{ - 1, - 2, - 3, - 0, - 1, - 2, - 3 -}; - -static const word32 obx_md5_var1 [] = -{ - 7, - 12, - 17, - 22 -}; - -static const word32 obx_md5_var2 [] = -{ - 5, - 9, - 14, - 20 -}; - -static const word32 obx_md5_var3 [] = -{ - 4, - 11, - 16, - 23 -}; - -static const word32 obx_md5_var4 [] = -{ - 6, - 10, - 15, - 21 -}; - -static void obx_md5_transform(word32 buf[4], word32 const in[16]) -{ - int xx, yy, zz, i, j, k; - word32 a[4]; - - a[0] = buf[0]; - a[1] = buf[1]; - a[2] = buf[2]; - a[3] = buf[3]; - - yy = 0; - for(xx=0; xx<4; xx++) - { - j = 3; - for(i=0; i < 4; i++) - { - k = j--; - /* - OBX_TRACE_DEBUG4( "f1 a: %d, yy: %d, inc: 0x%x, var: %d", - obx_md5_a[k], yy, obx_md5_f1[yy], obx_md5_var1[i]); - */ - MD5STEP(F1, a[obx_md5_a[k]], a[obx_md5_a[k+1]], a[obx_md5_a[k+2]], a[obx_md5_a[k+3]], - in[yy] + obx_md5_f1[yy], obx_md5_var1[i]); - yy++; - } - } - - yy = 1; - zz = 0; - for(xx=0; xx<4; xx++) - { - j = 3; - for(i=0; i < 4; i++) - { - k = j--; - /* - OBX_TRACE_DEBUG4( "f2 a: %d, yy: %d, inc: 0x%x, var: %d", - obx_md5_a[k], yy, obx_md5_f2[zz], obx_md5_var2[i]); - */ - MD5STEP(F2, a[obx_md5_a[k]], a[obx_md5_a[k+1]], a[obx_md5_a[k+2]], a[obx_md5_a[k+3]], - in[yy] + obx_md5_f2[zz++], obx_md5_var2[i]); - yy += 5; - yy %= 16; - } - } - - yy = 5; - zz = 0; - for(xx=0; xx<4; xx++) - { - j = 3; - for(i=0; i < 4; i++) - { - k = j--; - /* - OBX_TRACE_DEBUG4( "f3 a: %d, yy: %d, inc: 0x%x, var: %d", - obx_md5_a[k], yy, obx_md5_f3[zz], obx_md5_var3[i]); - */ - MD5STEP(F3, a[obx_md5_a[k]], a[obx_md5_a[k+1]], a[obx_md5_a[k+2]], a[obx_md5_a[k+3]], - in[yy] + obx_md5_f3[zz++], obx_md5_var3[i]); - yy += 3; - yy %= 16; - } - } - - - yy = 0; - zz = 0; - for(xx=0; xx<4; xx++) - { - j = 3; - for(i=0; i < 4; i++) - { - k = j--; - /* - OBX_TRACE_DEBUG4( "f4 a: %d, yy: %d, inc: 0x%x, var: %d", - obx_md5_a[k], yy, obx_md5_f4[zz], obx_md5_var4[i]); - */ - MD5STEP(F4, a[obx_md5_a[k]], a[obx_md5_a[k+1]], a[obx_md5_a[k+2]], a[obx_md5_a[k+3]], - in[yy] + obx_md5_f4[zz++], obx_md5_var4[i]); - yy += 7; - yy %= 16; - } - } - - buf[0] += a[0]; - buf[1] += a[1]; - buf[2] += a[2]; - buf[3] += a[3]; -} - -/******************************************************************************* -** -** Function OBX_MD5 -** -** Description This function is called to run the MD5 algorithm. -** -** Returns void -** -*******************************************************************************/ -static void OBX_MD5(void *digest, UINT8 *nonce, UINT8 * password, int password_len) -{ - struct xMD5Context context; - UINT8 before[OBX_NONCE_SIZE + OBX_MAX_AUTH_KEY_SIZE + 4]; - - memcpy(before, nonce, OBX_NONCE_SIZE); - before[OBX_NONCE_SIZE] = ':'; - memcpy(before + OBX_NONCE_SIZE + 1, password, password_len); - /* - scru_dump_hex (before, "before", OBX_NONCE_SIZE + 1 + password_len, TRACE_LAYER_OBEX, TRACE_TYPE_GENERIC); - */ - - obx_md5_init(&context); -/* coverity[overrun-buffer-val] */ -/* -FALSE-POSITIVE: coverity says "Overrun of static array "before" of size 36 bytes by passing it as an argument to a function which indexes it at byte position 63" -obx_md5_update() only goes into that condition when (len >= 64). In this case, len is (OBX_NONCE_SIZE + 1 + password_len) which is less than or equal to 33. -password_len is less than or equal to OBX_MAX_AUTH_KEY_SIZE. The size of before[] is more than enough */ - obx_md5_update(&context, (byte const *)before, OBX_NONCE_SIZE + 1 + password_len); - obx_md5_final((byte *)digest, &context); - /* - scru_dump_hex (digest, "after", 16, TRACE_LAYER_OBEX, TRACE_TYPE_GENERIC); - */ -} - -/******************************************************************************* -** -** Function obx_session_id -** -** Description This function is called to run the MD5 algorithm to create a -** session id. -** -** Returns void -** -*******************************************************************************/ -void obx_session_id(UINT8 *p_sess_id, UINT8 *p_cl_addr, UINT8 * p_cl_nonce, int cl_nonce_len, - UINT8 *p_sr_addr, UINT8 * p_sr_nonce, int sr_nonce_len) -{ - struct xMD5Context context; - UINT8 before[(OBX_NONCE_SIZE + BD_ADDR_LEN) * 2 + 4]; - UINT8 *p = before; - UINT8 len; - - memcpy(p, p_cl_addr, BD_ADDR_LEN); - p += BD_ADDR_LEN; - memcpy(p, p_cl_nonce, cl_nonce_len); - p += cl_nonce_len; - memcpy(p, p_sr_addr, BD_ADDR_LEN); - p += BD_ADDR_LEN; - memcpy(p, p_sr_nonce, sr_nonce_len); - p += sr_nonce_len; - /* - scru_dump_hex (before, "before", OBX_NONCE_SIZE + 1 + password_len, TRACE_LAYER_OBEX, TRACE_TYPE_GENERIC); - */ - - len = BD_ADDR_LEN + cl_nonce_len + BD_ADDR_LEN + sr_nonce_len; - obx_md5_init(&context); -/* coverity [overrun-buffer-val] */ -/* Overrun of static array "before" of size 48 bytes by passing it as an argument to a function which indexes it at byte position 63*/ -/* FALSE-POSITIVE: obx_md5_update() only goes into that condition when (len >= 64). In this case, len is (OBX_NONCE_SIZE + 1 + password_len) which is less than or equal to 33. -password_len is less than or equal to OBX_MAX_AUTH_KEY_SIZE. The size of before[] is more than enough */ - obx_md5_update(&context, (byte const *)before, len); - obx_md5_final((byte *)p_sess_id, &context); - /* - scru_dump_hex (p_sess_id, "after", 16, TRACE_LAYER_OBEX, TRACE_TYPE_GENERIC); - */ -} - -#if (OBX_SERVER_INCLUDED == TRUE) -/******************************************************************************* -** -** Function obx_copy_and_rm_auth_hdrs -** -** Description This function is used to copy the given OBEX packet to a new packet -** with the authentication headers removed. -** -** Returns tOBX_STATUS -** -*******************************************************************************/ -tOBX_STATUS obx_copy_and_rm_auth_hdrs(BT_HDR *p_pkt, BT_HDR *p_new, UINT8 * p_hi) -{ - tOBX_STATUS status = OBX_SUCCESS; - UINT8 *pn, *po, *p_nlen = NULL; - int hsize, nsize; - UINT16 nlen, olen; - UINT8 size; - int xx; - - WC_ASSERT(p_new); - - - po = (UINT8 *)(p_pkt + 1) + p_pkt->offset + 1; - BE_STREAM_TO_UINT16(olen, po); - OBX_TRACE_DEBUG3( "obx_copy_and_rm_auth_hdrs event: %d, new len:%d, olen:%d", - p_pkt->event, p_new->len, olen); - - po = (UINT8 *)(p_pkt + 1) + p_pkt->offset; - if(p_new->len == 0) - { - p_new->offset = p_pkt->offset; - p_nlen = (UINT8 *)(p_new + 1) + p_new->offset + 1; - } - pn = (UINT8 *)(p_new + 1) + p_new->offset; - - /* Get the number of bytes before headers start */ - size = obx_hdr_start_offset[p_pkt->event - 1]; - if(p_new->len) - { - /* for OBX_AuthResponse - * - do not need to copy the stuff before headers - * there's already some header, skip them */ - pn += p_new->len; - nlen = p_new->len; - } - else - { - /* for obx_unauthorize_rsp - * - needs to copy the stuff before headers */ - memcpy(pn, po, size); - pn += size; - nlen = size; - } - po += size; - - olen -= size; - while(olen) - { - OBX_TRACE_DEBUG1( "olen:%d", olen); - hsize = (int)obx_read_header_len(po); - if(olen > hsize) - olen -= hsize; - else - olen = 0; - - xx = 0; - nsize = hsize; - while(p_hi[xx] != OBX_HI_NULL) - { - /* - OBX_TRACE_DEBUG2( "po:0x%x, hix:0x%x", *po, p_hi[xx]); - */ - if(*po == p_hi[xx++]) - { - nsize = 0; - break; - } - } - OBX_TRACE_DEBUG2( "hsize:%d, nsize:%d", hsize, nsize); - if(nsize) - { - /* skip auth challenge and auth response */ - if((nlen+hsize) < p_pkt->layer_specific) - { - /* copy other headers */ - memcpy(pn, po, hsize); - pn += hsize; - nlen += hsize; - } - else - { - OBX_TRACE_WARNING1( "obx_copy_and_rm_auth_hdrs Not enough room: %d", olen); - /* no more room in the new packet */ - status = OBX_NO_RESOURCES; - break; - } - } - po += hsize; - } - - if(status == OBX_SUCCESS) - { - if(p_nlen) - { - UINT16_TO_BE_STREAM(p_nlen, nlen); - } - p_new->len = nlen; - p_new->layer_specific = GKI_get_buf_size(p_new) - BT_HDR_SIZE - p_new->offset; - p_new->event = p_pkt->event; - } - - return status; -} - -/******************************************************************************* -** -** Function obx_unauthorize_rsp -** -** Description This function is used to add authentication challenge triplet -** -** Returns void. -** Note: this function assumes that all data can fit in the MTU -*******************************************************************************/ -BT_HDR * obx_unauthorize_rsp(tOBX_SR_CB *p_cb, tOBX_SR_SESS_CB *p_scb, BT_HDR *p_pkt) -{ - UINT8 *p; - UINT8 nonce[OBX_NONCE_SIZE+2]; - UINT8 option[2]; - UINT8 *p_target = NULL; - tOBX_TRIPLET triplet[OBX_MAX_NUM_AUTH_TRIPLET]; - UINT8 num_trip = 0; - BT_HDR *p_old; - UINT8 hi[] = {OBX_HI_CHALLENGE, OBX_HI_AUTH_RSP, OBX_HI_NULL}; - - OBX_TRACE_DEBUG1( "obx_unauthorize_rsp: %d", p_cb->target.len); - if(OBX_CheckHdr(p_pkt, OBX_HI_CHALLENGE) || OBX_CheckHdr(p_pkt, OBX_HI_AUTH_RSP)) - { - p_old = p_pkt; - p_pkt = OBX_HdrInit(p_scb->ll_cb.comm.handle, (UINT16)(p_old->len + BT_HDR_SIZE + p_old->offset)); - obx_copy_and_rm_auth_hdrs(p_old, p_pkt, hi); - GKI_freebuf(p_old); - } - - if(p_cb->target.len) - { - /* There must be the target header, change it to be WHO header */ - if( (p_target = OBX_CheckHdr(p_pkt, OBX_HI_TARGET)) != NULL) - { - *p_target = OBX_HI_WHO; - } - } - OBX_TRACE_DEBUG1( "p_target: %x", p_target); - - if(p_cb->p_auth) - { - /* server registers for authentication */ - /* prepare the triplet byte sequence */ - /* add nonce: tag, length, value */ - p_cb->p_auth->nonce = GKI_get_tick_count(); - sprintf ((char *)nonce, "%016lu", p_cb->p_auth->nonce); - - num_trip = 0; - triplet[num_trip].tag = OBX_NONCE_CHLNG_TAG; - triplet[num_trip].len = OBX_NONCE_SIZE; - triplet[num_trip].p_array = nonce; - num_trip++; - - if(p_cb->p_auth->auth_option) - { - /* add option */ - triplet[num_trip].tag = OBX_OPTIONS_CHLNG_TAG; - triplet[num_trip].len = 1; - option[0] = p_cb->p_auth->auth_option; - triplet[num_trip].p_array = option; - num_trip++; - } - if(p_cb->p_auth->realm_len) - { - /* add realm */ - triplet[num_trip].tag = OBX_REALM_CHLNG_TAG; - triplet[num_trip].len = p_cb->p_auth->realm_len+1; - triplet[num_trip].p_array = p_cb->p_auth->realm; - num_trip++; - } - - /* add the sequence to header */ - OBX_AddTriplet(p_pkt, OBX_HI_CHALLENGE, triplet, num_trip); - } - - p = (UINT8 *)(p_pkt + 1) + p_pkt->offset; - /* change the opcode to unauthorized response */ - *p++ = OBX_RSP_UNAUTHORIZED | OBX_FINAL; - /* adjust the packet len */ - UINT16_TO_BE_STREAM(p, p_pkt->len); - - /* add session sequence number, if session is active */ - if ((p_scb->sess_st == OBX_SESS_ACTIVE) && ((p_target = OBX_CheckHdr(p_pkt, OBX_HI_SESSION_SN)) != NULL)) - { - p_target++; - (*p_target)++; - } - - p_pkt->event = OBX_CONNECT_RSP_EVT; - - return p_pkt; -} - -/******************************************************************************* -** -** Function OBX_Password -** -** Description This function is called by the server to respond to an -** OBX_PASSWORD_EVT event. -** -** Returns OBX_SUCCESS, if successful. -** OBX_NO_RESOURCES, if OBX does not resources -** -*******************************************************************************/ -tOBX_STATUS OBX_Password(tOBX_HANDLE shandle, UINT8 *p_password, UINT8 password_len, - UINT8 *p_userid, UINT8 userid_len) -{ - tOBX_STATUS status = OBX_SUCCESS; - BT_HDR *p_pkt; - BT_HDR *p_rsp; - UINT8 temp_digest[OBX_DIGEST_SIZE]; - UINT8 nonce[OBX_NONCE_SIZE + 1]; - BOOLEAN pass = FALSE; - BOOLEAN digest_done = FALSE; - BOOLEAN option_userid = FALSE; - tOBX_TRIPLET triplet[OBX_MAX_NUM_AUTH_TRIPLET]; - UINT8 num_trip = OBX_MAX_NUM_AUTH_TRIPLET; - UINT8 xx; - UINT8 *p_target; - UINT16 tlen; - tOBX_SR_SESS_CB *p_scb = obx_sr_get_scb(shandle); - tOBX_SR_CB *p_cb = obx_sr_get_cb(shandle); - UINT8 *p; - tOBX_EVT_PARAM param; /* The event parameter. */ - - WC_ASSERT(password_len < OBX_MAX_AUTH_KEY_SIZE); - - if(p_scb == NULL || p_scb->p_saved_msg == NULL) - return OBX_NO_RESOURCES; - - /* The coverity complaints on this function is not correct. - * The value in triplet[] is set/initialized by OBX_ReadTriplet if num_trip returns TRUE. - * leave this unnecessary memset here */ - memset(triplet,0,sizeof(triplet)); - - p_pkt = p_scb->p_saved_msg; - - if(p_cb->p_auth == NULL) - { - pass = TRUE; - } - else if(OBX_ReadTriplet(p_pkt, OBX_HI_AUTH_RSP, triplet, &num_trip) == TRUE) - { - if(p_password && password_len ) - { - /* if given password, verify it */ - for(xx=0; xx<num_trip; xx++) - { - if(triplet[xx].tag == OBX_DIGEST_RSP_TAG) - { - sprintf((char *)nonce, "%016lu", p_cb->p_auth->nonce); - OBX_MD5 (temp_digest, nonce, p_password, password_len); - if (memcmp (temp_digest, triplet[xx].p_array, OBX_DIGEST_SIZE) == 0) - pass = TRUE; - break; - } - } - } - } - - /* check if challenged by client */ - num_trip = OBX_MAX_NUM_AUTH_TRIPLET; - if(pass == TRUE && OBX_ReadTriplet(p_pkt, OBX_HI_CHALLENGE, triplet, &num_trip) == TRUE) - { - /* Make sure password was passed in and not empty */ - if (p_password && password_len ) - { - for(xx=0; xx<num_trip; xx++) - { - if(triplet[xx].tag == OBX_NONCE_CHLNG_TAG) - { - /* nonce tag is mandatory */ - OBX_MD5 (temp_digest, triplet[xx].p_array, p_password, password_len); - digest_done = TRUE; - } - else if(triplet[xx].tag == OBX_OPTIONS_CHLNG_TAG) - { - /* user ID bit is set */ - if(OBX_AO_USR_ID & triplet[xx].p_array[0]) - option_userid = TRUE; - } - } - - if (option_userid && (userid_len == 0 || p_userid == NULL) ) - { - status = OBX_BAD_PARAMS; - } - } - } - - if(status == OBX_SUCCESS) - { - p_scb->p_saved_msg = NULL; - if(pass == TRUE) - { - p_rsp = OBX_HdrInit(shandle, OBX_MIN_MTU); - - /* add the authentication response if been challenged */ - if(digest_done) - { - num_trip = 1; - triplet[0].tag = OBX_DIGEST_RSP_TAG; - triplet[0].len = OBX_DIGEST_SIZE; - triplet[0].p_array = temp_digest; - if(option_userid) - { - num_trip++; - triplet[1].tag = OBX_USERID_RSP_TAG; - triplet[1].len = userid_len; - triplet[1].p_array = p_userid; - } - OBX_AddTriplet(p_rsp, OBX_HI_AUTH_RSP, triplet, num_trip); - } - - if( p_cb->target.len == OBX_DEFAULT_TARGET_LEN && - OBX_ReadTargetHdr(p_pkt, &p_target, &tlen, 0) == TRUE) - { - /* API user is supposed to handle WHO header - * for this special case, we add it for the API user */ - OBX_AddWhoHdr(p_rsp, p_target, tlen); - } - - /* use OBX_ConnectRsp to fill the common data */ - status = OBX_ConnectRsp(shandle, OBX_RSP_OK, p_rsp); - if(status == OBX_SUCCESS) - { - /* If authentication is successful, need to update session info */ - p = &p_scb->sess_info[OBX_SESSION_INFO_ID_IDX]; - UINT32_TO_BE_STREAM(p, p_scb->conn_id); - param.sess.p_sess_info = p_scb->sess_info; - param.sess.sess_op = OBX_SESS_OP_CREATE; - param.sess.sess_st = p_scb->sess_st; - param.sess.nssn = p_scb->param.ssn; - param.sess.ssn = p_scb->param.ssn; - param.sess.obj_offset = 0; - p = &p_scb->sess_info[OBX_SESSION_INFO_MTU_IDX]; - UINT16_TO_BE_STREAM(p, p_scb->param.conn.mtu); - memcpy(param.sess.peer_addr, p_scb->peer_addr, BD_ADDR_LEN); - (*p_cb->p_cback)(p_scb->ll_cb.comm.handle, OBX_SESSION_REQ_EVT, param, p_pkt); - (*p_cb->p_cback)(p_scb->ll_cb.comm.handle, OBX_CONNECT_REQ_EVT, p_scb->param, p_pkt); - } - else - GKI_freebuf(p_pkt); - } - else - { - /* server can not find the password, send unauthorized response */ - p_pkt = obx_unauthorize_rsp(p_cb, p_scb, p_pkt); - obx_ssm_event(p_scb, OBX_CONNECT_CFM_SEVT, p_pkt); - } - } - /* - else p_scb->p_saved_msg is still valid. - */ - - return status; -} -#endif - - -#if (OBX_CLIENT_INCLUDED == TRUE) -/******************************************************************************* -** -** Function OBX_AuthResponse -** -** Description This function is called by the client to respond to an -** OBX_PASSWORD_EVT event. -** -** Returns OBX_SUCCESS, if successful. -** OBX_NO_RESOURCES, if OBX does not resources -** -*******************************************************************************/ -tOBX_STATUS OBX_AuthResponse(tOBX_HANDLE handle, - UINT8 *p_password, UINT8 password_len, - UINT8 *p_userid, UINT8 userid_len, - BOOLEAN authenticate) -{ - tOBX_CL_CB *p_cb = obx_cl_get_cb(handle); - tOBX_STATUS status = OBX_NO_RESOURCES; - BT_HDR *p_pkt; - BT_HDR *p_saved_req; - UINT8 num_trip, flags = 0; - UINT16 nlen, xx; - UINT8 temp_digest[OBX_DIGEST_SIZE]; - UINT8 nonce[OBX_NONCE_SIZE + 1]; - BOOLEAN digest_done = FALSE; - BOOLEAN option_userid = FALSE; - UINT8 rsp_code; - BOOLEAN final; - UINT8 *p_target; - tOBX_TRIPLET triplet[OBX_MAX_NUM_AUTH_TRIPLET]; - UINT8 hi[] = {OBX_HI_CONN_ID, OBX_HI_TARGET, OBX_HI_CHALLENGE, OBX_HI_AUTH_RSP, - OBX_HI_SESSION_SN, /* prevent SSN from being copied */ - OBX_HI_NULL}; - WC_ASSERT(password_len < OBX_MAX_AUTH_KEY_SIZE); - WC_ASSERT(p_password); - - if(p_cb == NULL || p_cb->p_auth == NULL || p_cb->p_saved_req == NULL) - return OBX_NO_RESOURCES; - - p_saved_req = p_cb->p_saved_req; - p_pkt = OBX_HdrInit(handle, GKI_MAX_BUF_SIZE); /* make sure added length will fit */ - WC_ASSERT(p_pkt); - OBX_TRACE_DEBUG2("OBX_AuthResponse p_saved_req:%d, p_saved_req->len %d ", - p_saved_req->event, p_saved_req->len); - - /* if the save_req contains SSN, add it now */ - if ((p_target = OBX_CheckHdr(p_saved_req, OBX_HI_SESSION_SN)) != NULL) - { - p_target++; - OBX_Add1ByteHdr(p_pkt, OBX_HI_SESSION_SN, (UINT8)((*p_target) + 1)); - } - - /* The coverity complaints on this function is not correct. - * The value in triplet[] is set/initialized by OBX_ReadTriplet if num_trip returns TRUE. - * leave this unnecessary memset here */ - memset(triplet,0,sizeof(triplet)); - - /* if target header exists in the original request - * and the Connection ID has not been assigned yet, - * copy the target header over */ - if(OBX_ReadTargetHdr(p_saved_req, &p_target, &nlen, 0) == TRUE) - { - OBX_AddTargetHdr(p_pkt, p_target, nlen); - } - - /* read the challenge from received packet */ - num_trip = OBX_MAX_NUM_AUTH_TRIPLET; - if(OBX_ReadTriplet(p_cb->p_auth, OBX_HI_CHALLENGE, triplet, &num_trip) == TRUE) - { - status = OBX_SUCCESS; - for(xx=0; xx<num_trip; xx++) - { - if(triplet[xx].tag == OBX_NONCE_CHLNG_TAG) - { - /* nonce tag is mandatory */ - OBX_MD5 (temp_digest, triplet[xx].p_array, p_password, password_len); - digest_done = TRUE; - } - else if(triplet[xx].tag == OBX_OPTIONS_CHLNG_TAG) - { - /* user ID bit is set */ - if(OBX_AO_USR_ID & triplet[xx].p_array[0]) - option_userid = TRUE; - } - } - - if(option_userid && (userid_len == 0 || p_userid == NULL) ) - { - status = OBX_BAD_PARAMS; - } - OBX_TRACE_DEBUG2( "num_trip:%d, option_userid:%d", num_trip, option_userid); - - if(digest_done && status == OBX_SUCCESS) - { - /* Compose and add the authentication Response header */ - num_trip = 1; - triplet[0].tag = OBX_DIGEST_RSP_TAG; - triplet[0].len = OBX_DIGEST_SIZE; - triplet[0].p_array = temp_digest; - if(option_userid) - { - /* add user id */ - num_trip++; - triplet[1].tag = OBX_USERID_RSP_TAG; - triplet[1].len = userid_len; - triplet[1].p_array = p_userid; - } - OBX_AddTriplet(p_pkt, OBX_HI_AUTH_RSP, triplet, num_trip); - - /* if we want to authenticate the server, add the challenge header here */ - /* Note: we only do it for the CONNECT request */ - if(authenticate && p_saved_req->event == OBX_CONNECT_REQ_EVT) - { - /* Indicate in the control block to verify the response */ - p_cb->wait_auth = TRUE; - - /* add the challenge nonce */ - num_trip = 1; - triplet[0].tag = OBX_NONCE_CHLNG_TAG; - triplet[0].len = OBX_NONCE_SIZE; - triplet[0].p_array = nonce; - sprintf ((char *)nonce, "%016lu", GKI_get_tick_count()); - OBX_AddTriplet(p_pkt, OBX_HI_CHALLENGE, triplet, num_trip); - OBX_MD5 ((UINT8 *)(p_cb->p_auth), nonce, p_password, password_len); - } - - /* copy non-(target, conn_id, authentication) headers from p_saved_req. */ - status = obx_copy_and_rm_auth_hdrs(p_saved_req, p_pkt, hi); - OBX_TRACE_DEBUG4( "status:%d, save:%d, pkt:%d, off:%d", - status, p_saved_req->event, p_pkt->event, p_pkt->offset); - - if(status == OBX_SUCCESS) - { - /* get the final from the saved request */ - rsp_code = OBX_RSP_DEFAULT; - obx_access_rsp_code(p_saved_req, &rsp_code); - final = (rsp_code & OBX_FINAL) ? TRUE : FALSE; - OBX_TRACE_DEBUG1( "saved final:%d", final); - - /* call the associated API function to send the request again */ - switch(p_pkt->event) - { - case OBX_CONNECT_REQ_EVT: - status = OBX_ConnectReq((BD_ADDR_PTR)BT_BD_ANY, 0, 0, NULL, &p_cb->ll_cb.comm.handle, p_pkt); - break; - case OBX_PUT_REQ_EVT: - status = OBX_PutReq(handle, final, p_pkt); - break; - case OBX_GET_REQ_EVT: - status = OBX_GetReq(handle, final, p_pkt); - break; - case OBX_SETPATH_REQ_EVT: - /* get the flags from old request - if SetPath */ - flags = *((UINT8 *)(p_saved_req + 1) + p_saved_req->offset + 3); - status = OBX_SetPathReq(handle, flags, p_pkt); - break; - default: - /* it does not make sense to authenticate on Abort and Disconnect */ - OBX_TRACE_WARNING1( "Authenticate on bad request: %d", p_pkt->event); - status = OBX_NO_RESOURCES; - } /* switch (event) */ - } - } /* digest done */ - } /* challenge heaer exists */ - - if(status != OBX_SUCCESS) - { - GKI_freebuf(p_pkt); - } - - if(p_cb->wait_auth == FALSE) - { - GKI_freebuf(p_cb->p_auth); - p_cb->p_auth = NULL; - } - return status; -} - -#if (OBX_MD5_TEST_INCLUDED == TRUE) -/******************************************************************************* -** -** Function OBX_VerifyResponse -** -** Description This function is called by the client to verify the challenge -** response. -** -** Returns TRUE, if successful. -** FALSE, if authentication failed -** -*******************************************************************************/ -BOOLEAN OBX_VerifyResponse(UINT32 nonce_u32, UINT8 *p_password, UINT8 password_len, UINT8 *p_response) -{ - BOOLEAN status = FALSE; - UINT8 nonce[OBX_NONCE_SIZE + 1]; - UINT8 temp_digest[OBX_DIGEST_SIZE]; - - OBX_TRACE_API0( "OBX_VerifyResponse"); - if (p_password && password_len) - { - sprintf((char *)nonce, "%016lu", nonce_u32); - OBX_MD5 (temp_digest, nonce, p_password, password_len); - if (memcmp (temp_digest, p_response, OBX_DIGEST_SIZE) == 0) - status = TRUE; - } - return status; -} -#endif /* OBX_MD5_TEST_INCLUDED */ - - -#endif - - - |