예제 #1
0
static void mppe_GetMasterKey(uint8_t *nt_hashhash,uint8_t *nt_response,
			      uint8_t *masterkey)
{
       uint8_t digest[20];
       fr_SHA1_CTX Context;

       fr_SHA1Init(&Context);
       fr_SHA1Update(&Context,nt_hashhash,16);
       fr_SHA1Update(&Context,nt_response,24);
       fr_SHA1Update(&Context,magic1,27);
       fr_SHA1Final(digest,&Context);

       memcpy(masterkey,digest,16);
}
예제 #2
0
/*
 *	challenge_hash() is used by mschap2() and auth_response()
 *	implements RFC2759 ChallengeHash()
 *	generates 64 bit challenge
 */
void mschap_challenge_hash(uint8_t const *peer_challenge,
			    uint8_t const *auth_challenge,
			    char const *user_name, uint8_t *challenge )
{
	fr_SHA1_CTX Context;
	uint8_t hash[20];

	fr_SHA1Init(&Context);
	fr_SHA1Update(&Context, peer_challenge, 16);
	fr_SHA1Update(&Context, auth_challenge, 16);
	fr_SHA1Update(&Context, (uint8_t const *) user_name,
		      strlen(user_name));
	fr_SHA1Final(hash, &Context);
	memcpy(challenge, hash, 8);
}
예제 #3
0
/**
 * @brief Calculate the SHA1 hash of a string.
 *
 * Example: "%{sha1:foo}" == "0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33"
 */
static size_t sha1_xlat(UNUSED void *instance, REQUEST *request,
                       char *fmt, char *out, size_t outlen,
                       UNUSED RADIUS_ESCAPE_STRING func)
{
        char buffer[1024];
        uint8_t digest[20];
        int i;
        fr_SHA1_CTX ctx;

        if (!radius_xlat(buffer, sizeof(buffer), fmt, request, func)) {
                *out = '\0';
                return 0;
        }

        fr_SHA1Init(&ctx);
        fr_SHA1Update(&ctx, (void *) buffer, strlen(buffer));
        fr_SHA1Final(digest, &ctx);

        if (outlen < 41) {
                snprintf(out, outlen, "sha1_overflow");
                return strlen(out);
        }

        for (i = 0; i < 20; i++) {
                snprintf(out + i * 2, 3, "%02x", digest[i]);
        }

        return strlen(out);
}
예제 #4
0
/**
 * @brief Calculate the SHA1 hash of a string.
 *
 * Example: "%{sha1:foo}" == "0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33"
 */
static size_t sha1_xlat(UNUSED void *instance, UNUSED REQUEST *request,
                       char const *fmt, char *out, size_t outlen)
{
        uint8_t digest[16];
        int i, len;
        fr_SHA1_CTX ctx;

        /*
         *      We need room for at least one octet of output.
         */
        if (outlen < 3) {
                *out = '\0';
                return 0;
        }

        fr_SHA1Init(&ctx);
        fr_SHA1Update(&ctx, (const void *) fmt, strlen(fmt));
        fr_SHA1Final(digest, &ctx);

        /*
         *      Each digest octet takes two hex digits, plus one for
         *      the terminating NUL. SHA1 is 160 bits (20 bytes)
         */
        len = (outlen / 2) - 1;
        if (len > 20) len = 20;

        for (i = 0; i < len; i++) {
                snprintf(out + i * 2, 3, "%02x", digest[i]);
        }

        return strlen(out);
}
예제 #5
0
static void calc_sha1_digest(uint8_t *buffer, uint8_t const *challenge,
			     size_t challen, char const *password)
{
	uint8_t buf[1024];
	int i;
	fr_SHA1_CTX context;

	memset(buf, 0, 1024);
	memset(buf, 0x36, 64);
	for(i=0; i<64 && password[i]; i++) buf[i]^=password[i];
	memcpy(buf+64, challenge, challen);
	fr_SHA1Init(&context);
	fr_SHA1Update(&context,buf,64+challen);
	memset(buf, 0x5c, 64);
	for(i=0; i<64 && password[i]; i++) buf[i]^=password[i];
	fr_SHA1Final(buf+64,&context);
	fr_SHA1Init(&context);
	fr_SHA1Update(&context,buf,64+20);
	fr_SHA1Final(buffer,&context);
}
예제 #6
0
/*
 *	auth_response() generates MS-CHAP v2 SUCCESS response
 *	according to RFC 2759 GenerateAuthenticatorResponse()
 *	returns 42-octet response string
 */
void mschap_auth_response(char const *username,
                          uint8_t const *nt_hash_hash,
                          uint8_t const *ntresponse,
                          uint8_t const *peer_challenge, uint8_t const *auth_challenge,
                          char *response)
{
    fr_SHA1_CTX Context;
    static const uint8_t magic1[39] =
    {   0x4D, 0x61, 0x67, 0x69, 0x63, 0x20, 0x73, 0x65, 0x72, 0x76,
        0x65, 0x72, 0x20, 0x74, 0x6F, 0x20, 0x63, 0x6C, 0x69, 0x65,
        0x6E, 0x74, 0x20, 0x73, 0x69, 0x67, 0x6E, 0x69, 0x6E, 0x67,
        0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x74
    };

    static const uint8_t magic2[41] =
    {   0x50, 0x61, 0x64, 0x20, 0x74, 0x6F, 0x20, 0x6D, 0x61, 0x6B,
        0x65, 0x20, 0x69, 0x74, 0x20, 0x64, 0x6F, 0x20, 0x6D, 0x6F,
        0x72, 0x65, 0x20, 0x74, 0x68, 0x61, 0x6E, 0x20, 0x6F, 0x6E,
        0x65, 0x20, 0x69, 0x74, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6F,
        0x6E
    };

    static char const hex[16] = "0123456789ABCDEF";

    size_t i;
    uint8_t challenge[8];
    uint8_t digest[20];

    fr_SHA1Init(&Context);
    fr_SHA1Update(&Context, nt_hash_hash, 16);
    fr_SHA1Update(&Context, ntresponse, 24);
    fr_SHA1Update(&Context, magic1, 39);
    fr_SHA1Final(digest, &Context);
    mschap_challenge_hash(peer_challenge, auth_challenge, username, challenge);
    fr_SHA1Init(&Context);
    fr_SHA1Update(&Context, digest, 20);
    fr_SHA1Update(&Context, challenge, 8);
    fr_SHA1Update(&Context, magic2, 41);
    fr_SHA1Final(digest, &Context);

    /*
     *	Encode the value of 'Digest' as "S=" followed by
     *	40 ASCII hexadecimal digits and return it in
     *	AuthenticatorResponse.
     *	For example,
     *	"S=0123456789ABCDEF0123456789ABCDEF01234567"
     */
    response[0] = 'S';
    response[1] = '=';

    /*
     *	The hexadecimal digits [A-F] MUST be uppercase.
     */
    for (i = 0; i < sizeof(digest); i++) {
        response[2 + (i * 2)] = hex[(digest[i] >> 4) & 0x0f];
        response[3 + (i * 2)] = hex[digest[i] & 0x0f];
    }
}
예제 #7
0
static void mppe_GetAsymmetricStartKey(uint8_t *masterkey,uint8_t *sesskey,
				       int keylen,int issend)
{
       uint8_t digest[20];
       const uint8_t *s;
       fr_SHA1_CTX Context;

       memset(digest,0,20);

       if(issend) {
               s = magic3;
       } else {
               s = magic2;
       }

       fr_SHA1Init(&Context);
       fr_SHA1Update(&Context,masterkey,16);
       fr_SHA1Update(&Context,SHSpad1,40);
       fr_SHA1Update(&Context,s,84);
       fr_SHA1Update(&Context,SHSpad2,40);
       fr_SHA1Final(digest,&Context);

       memcpy(sesskey,digest,keylen);
}
예제 #8
0
void eapsim_calculate_keys(struct eapsim_keys *ek)
{
	fr_SHA1_CTX context;
	uint8_t fk[160];
	unsigned char buf[256];
	unsigned char *p;
	unsigned int  blen;

	p = buf;
	memcpy(p, ek->identity, ek->identitylen);   p = p+ek->identitylen;
	memcpy(p, ek->Kc[0], EAPSIM_Kc_SIZE);       p = p+EAPSIM_Kc_SIZE;
	memcpy(p, ek->Kc[1], EAPSIM_Kc_SIZE);       p = p+EAPSIM_Kc_SIZE;
	memcpy(p, ek->Kc[2], EAPSIM_Kc_SIZE);       p = p+EAPSIM_Kc_SIZE;
	memcpy(p, ek->nonce_mt, sizeof(ek->nonce_mt)); p=p+sizeof(ek->nonce_mt);
	memcpy(p, ek->versionlist, ek->versionlistlen);p=p+ek->versionlistlen;
	memcpy(p, ek->versionselect, sizeof(ek->versionselect)); p=p+sizeof(ek->versionselect);
	/* *p++ = ek->versionselect[1]; */

	blen = p - buf;

#if defined(TEST_CASE) || defined(DUMP_EAPSIM_KEYS)
	{
	  unsigned int i, j, k;

	  j=0; k=0;

	  printf("SHA1buffer was: ");
	  for (i = 0; i < blen; i++) {
	    if(j==4) {
	      printf("_");
	      j=0;
	    }
	    if(k==20) {
	      printf("\n		");
	      k=0;
	      j=0;
	    }
	    j++;
	    k++;

	    printf("%02x", buf[i]);
	  }
	  printf("\n");
	}
#endif


	/* do the master key first */
	fr_SHA1Init(&context);
	fr_SHA1Update(&context, buf, blen);
	fr_SHA1Final(ek->master_key, &context);

	/*
	 * now use the PRF to expand it, generated K_aut, K_encr,
	 * MSK and EMSK.
	 */
	fips186_2prf(ek->master_key, fk);

	/* split up the result */
	memcpy(ek->K_encr, fk +  0, 16);    /* 128 bits for encryption    */
	memcpy(ek->K_aut,  fk + 16, EAPSIM_AUTH_SIZE); /*128 bits for auth */
	memcpy(ek->msk,    fk + 32, 64);  /* 64 bytes for Master Session Key */
	memcpy(ek->emsk,   fk + 96, 64);  /* 64- extended Master Session Key */
}
예제 #9
0
void
fr_hmac_sha1(const uint8_t *text, int text_len,
	       const uint8_t *key, int key_len,
	       uint8_t *digest)
{
	fr_SHA1_CTX context;
	uint8_t k_ipad[65];    /* inner padding -
				      * key XORd with ipad
				      */
	uint8_t k_opad[65];    /* outer padding -
				      * key XORd with opad
				      */
	uint8_t tk[20];
	int i;
	/* if key is longer than 64 bytes reset it to key=SHA1(key) */
	if (key_len > 64) {

		fr_SHA1_CTX      tctx;

		fr_SHA1Init(&tctx);
		fr_SHA1Update(&tctx, key, key_len);
		fr_SHA1Final(tk, &tctx);

		key = tk;
		key_len = 20;
	}

#ifdef HMAC_SHA1_DATA_PROBLEMS
	if(sha1_data_problems)
	{
		int j,k;

		printf("\nhmac-sha1 key(%d): ", key_len);
		j=0; k=0;
		for (i = 0; i < key_len; i++) {
			if(j==4) {
				printf("_");
				j=0;
			}
			j++;

			printf("%02x", key[i]);
		}
		printf("\nDATA: (%d)    ",text_len);

		j=0; k=0;
		for (i = 0; i < text_len; i++) {
		  if(k==20) {
		    printf("\n	    ");
		    k=0;
		    j=0;
		  }
		  if(j==4) {
		    printf("_");
		    j=0;
		  }
		  k++;
		  j++;

		  printf("%02x", text[i]);
		}
		printf("\n");
	}
#endif


	/*
	 * the HMAC_SHA1 transform looks like:
	 *
	 * SHA1(K XOR opad, SHA1(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 SHA1
	 */
	fr_SHA1Init(&context);		   /* init context for 1st
					      * pass */
	fr_SHA1Update(&context, k_ipad, 64);      /* start with inner pad */
	fr_SHA1Update(&context, text, text_len); /* then text of datagram */
	fr_SHA1Final(digest, &context);	  /* finish up 1st pass */
	/*
	 * perform outer MD5
	 */
	fr_SHA1Init(&context);		   /* init context for 2nd
					      * pass */
	fr_SHA1Update(&context, k_opad, 64);     /* start with outer pad */
	fr_SHA1Update(&context, digest, 20);     /* then results of 1st
					      * hash */
	fr_SHA1Final(digest, &context);	  /* finish up 2nd pass */

#ifdef HMAC_SHA1_DATA_PROBLEMS
	if(sha1_data_problems)
	{
	  int j;

		printf("\nhmac-sha1 mac(20): ");
		j=0;
		for (i = 0; i < 20; i++) {
			if(j==4) {
				printf("_");
				j=0;
			}
			j++;

			printf("%02x", digest[i]);
		}
		printf("\n");
	}
#endif
}