Hi All! I'm newbie in RADIUS and I have some problems with it. As I know, the "Attributes" field is not mandatory for Access-Reject and ResponseAuth = MD5(Code+ID+Length+RequestAuth+Attributes+Secret)where + denotes concatenation. I tried to build Access Reject responce which will fulfill theese conditions: ..... /* unsigned char* text; pointer to data stream int text_len; length of data stream unsigned char* key; pointer to authentication key int key_len; length of authentication key unsigned char* digest; caller digest to be filled in */ void MD5CalcDigest(const unsigned char *text, int text_len, const unsigned char *key, int key_len, unsigned char *digest) { MD5_CTX context; unsigned char k_ipad[65]; /* inner padding - * key XORd with ipad */ unsigned char k_opad[65]; /* outer padding - * key XORd with opad */ unsigned char tk[16]; int i; /* if key is longer than 64 bytes reset it to key=MD5(key) */ if (key_len > 64) { MD5_CTX tctx; MD5Init(&tctx); MD5Update(&tctx, key, key_len); MD5Final(tk, &tctx); key = tk; key_len = 16; } /* * the HMAC_MD5 transform looks like: * * MD5(K XOR opad, MD5(K XOR ipad, text)) * * where K is an n byte key * ipad is the byte 0x36 repeated 64 times * opad is the byte 0x5c repeated 64 times * and text is the data being protected */ /* start out by storing key in pads */ memset( k_ipad, 0, sizeof(k_ipad)); memset( k_opad, 0, sizeof(k_opad)); memcpy( k_ipad, key, key_len); memcpy( k_opad, key, key_len); /* XOR key with ipad and opad values */ for (i = 0; i < 64; i++) { k_ipad[i] ^= 0x36; k_opad[i] ^= 0x5c; } /* * perform inner MD5 */ MD5Init(&context); /* init context for 1st * pass */ MD5Update(&context, k_ipad, 64); /* start with inner pad */ MD5Update(&context, text, text_len); /* then text of datagram */ MD5Final(digest, &context); /* finish up 1st pass */ /* * perform outer MD5 */ MD5Init(&context); /* init context for 2nd * pass */ MD5Update(&context, k_opad, 64); /* start with outer pad */ MD5Update(&context, digest, 16); /* then results of 1st * hash */ MD5Final(digest, &context); /* finish up 2nd pass */ } ..... struct TRadiusPacket { byte code; byte identifier; unsigned short length; byte auth[AUTH_VECTOR_LEN]; byte *attribute; // 4096-20 max }; byte * prepare_access_responce( byte code, TRadiusPacket * access_request, const char * shared_secret, byte * output ) { /* Это уже проверялось - не работает unsigned short length = htons(4 + AUTH_VECTOR_LEN); output[0] = code; output[1] = access_request->identifier; memcpy( output + 2, (byte *)&length, 2 ); memset ( output + 4, 0, AUTH_VECTOR_LEN ); unsigned long secret_len = strlen( shared_secret ); byte digest[16]; MD5CalcDigest( output, length, shared_secret, secret_len, digest); memcpy( output + 4, digest, 16 ); return output; } This code doesn't works. What I did wrong? Thank you. -- Best Regards, Vyacheslav.