void meteor_user_generate_x(SRPUser *usr, char const *identity, char const *salt, char const *password, unsigned char *buff, BIGNUM **x) { const static char *static_delim = ":"; BIGNUM *x_inner; char *catString_i_p = malloc(strlen(identity)+1 + strlen(static_delim)+ 1 + strlen(password)+1 + 1); strcpy(catString_i_p, identity); strcat(catString_i_p, static_delim); strcat(catString_i_p, password); catString_i_p[strlen(catString_i_p)] = '\0'; unsigned char lbuff[SHA256_DIGEST_LENGTH] = ""; hash(usr->hash_alg, (const unsigned char *)catString_i_p, strlen(catString_i_p), lbuff); x_inner = BN_bin2bn(lbuff, hash_length(usr->hash_alg), NULL); char *x_inner_str_lower = convert_to_lower(BN_bn2hex(x_inner)); char *catString_s_i_p = malloc(strlen(salt)+1 + strlen(x_inner_str_lower)+1 + 1); strcpy(catString_s_i_p, salt); strcat(catString_s_i_p, x_inner_str_lower); catString_s_i_p[strlen(catString_s_i_p)] = '\0'; unsigned char xbuff[SHA256_DIGEST_LENGTH] = ""; hash(usr->hash_alg, (const unsigned char *)catString_s_i_p, strlen((char *)catString_s_i_p), xbuff); *x = BN_bin2bn(xbuff, hash_length(usr->hash_alg), NULL); BN_free(x_inner); free(catString_i_p); free(catString_s_i_p); }
struct ibuf * ikev2_msg_auth(struct iked *env, struct iked_sa *sa, int response) { struct ibuf *authmsg = NULL, *nonce, *prfkey, *buf; uint8_t *ptr; struct iked_id *id; size_t tmplen; /* * Create the payload to be signed/MAC'ed for AUTH */ if (!response) { if ((nonce = sa->sa_rnonce) == NULL || (sa->sa_iid.id_type == 0) || (prfkey = sa->sa_key_iprf) == NULL || (buf = sa->sa_1stmsg) == NULL) return (NULL); id = &sa->sa_iid; } else { if ((nonce = sa->sa_inonce) == NULL || (sa->sa_rid.id_type == 0) || (prfkey = sa->sa_key_rprf) == NULL || (buf = sa->sa_2ndmsg) == NULL) return (NULL); id = &sa->sa_rid; } if ((authmsg = ibuf_dup(buf)) == NULL) return (NULL); if (ibuf_cat(authmsg, nonce) != 0) goto fail; if ((hash_setkey(sa->sa_prf, ibuf_data(prfkey), ibuf_size(prfkey))) == NULL) goto fail; if ((ptr = ibuf_advance(authmsg, hash_length(sa->sa_prf))) == NULL) goto fail; hash_init(sa->sa_prf); hash_update(sa->sa_prf, ibuf_data(id->id_buf), ibuf_size(id->id_buf)); hash_final(sa->sa_prf, ptr, &tmplen); if (tmplen != hash_length(sa->sa_prf)) goto fail; log_debug("%s: %s auth data length %zu", __func__, response ? "responder" : "initiator", ibuf_size(authmsg)); print_hex(ibuf_data(authmsg), 0, ibuf_size(authmsg)); return (authmsg); fail: ibuf_release(authmsg); return (NULL); }
static void calculate_H_AMK( SRP_HashAlgorithm alg, unsigned char *dest, const BIGNUM * A, const unsigned char * M, const unsigned char * K ) { HashCTX ctx; hash_init( alg, &ctx ); update_hash_n( alg, &ctx, A ); hash_update( alg, &ctx, M, hash_length(alg) ); hash_update( alg, &ctx, K, hash_length(alg) ); hash_final( alg, &ctx, dest ); }
static SRP_Result calculate_H_AMK(SRP_HashAlgorithm alg, unsigned char *dest, const mpz_t A, const unsigned char *M, const unsigned char *K) { HashCTX ctx; hash_init(alg, &ctx); if (!update_hash_n(alg, &ctx, A)) return SRP_ERR; hash_update(alg, &ctx, M, hash_length(alg)); hash_update(alg, &ctx, K, hash_length(alg)); hash_final(alg, &ctx, dest); return SRP_OK; }
/* * returns the length of the variable */ int v_length(var_t *var) { char tmpsb[64]; switch (var->type) { case V_STR: return strlen((char *) var->v.p.ptr); case V_UDS: return uds_length(var); case V_HASH: return hash_length(var); case V_PTR: ltostr(var->v.ap.p, tmpsb); return strlen(tmpsb); case V_INT: ltostr(var->v.i, tmpsb); return strlen(tmpsb); case V_NUM: ftostr(var->v.n, tmpsb); return strlen(tmpsb); case V_ARRAY: return var->v.a.size; } return 1; }
static void calculate_M( SRP_HashAlgorithm alg, NGConstant *ng, unsigned char * dest, const char * I, const BIGNUM * s, const BIGNUM * A, const BIGNUM * B, const unsigned char * K ) { unsigned char H_N[ SHA256_DIGEST_LENGTH ]; unsigned char H_g[ SHA256_DIGEST_LENGTH ]; unsigned char H_I[ SHA256_DIGEST_LENGTH ]; unsigned char H_xor[ SHA256_DIGEST_LENGTH ]; HashCTX ctx; int i = 0; int hash_len = hash_length(alg); hash_num( alg, ng->N, H_N ); hash_num( alg, ng->g, H_g ); hash(alg, (const unsigned char *)I, strlen(I), H_I); for (i=0; i < hash_len; i++ ) H_xor[i] = H_N[i] ^ H_g[i]; hash_init( alg, &ctx ); hash_update( alg, &ctx, H_xor, hash_len ); hash_update( alg, &ctx, H_I, hash_len ); update_hash_n( alg, &ctx, s ); update_hash_n( alg, &ctx, A ); update_hash_n( alg, &ctx, B ); hash_update( alg, &ctx, K, hash_len ); hash_final( alg, &ctx, dest ); }
void meteor_user_generate_M_string( struct SRPUser *usr, const char * S_str, unsigned char *buff, const char * B_str, char ** M_str ) { BIGNUM *M = BN_new(); char *ABS = malloc( strlen(usr->Astr) + strlen(B_str) + strlen(S_str) + 1 ); strcpy(ABS, usr->Astr); strcat(ABS, B_str); strcat(ABS, S_str); hash( usr->hash_alg, (const unsigned char *)ABS, strlen(ABS), buff ); M = BN_bin2bn( buff, hash_length(usr->hash_alg), NULL ); if ( !M ) goto cleanup_and_exit; *M_str = convert_to_lower( BN_bn2hex(M) ); cleanup_and_exit: BN_free(M); }
int ikev2_msg_integr(struct iked *env, struct iked_sa *sa, struct ibuf *src) { int ret = -1; size_t integrlen, tmplen; struct ibuf *integr, *prf, *tmp = NULL; u_int8_t *ptr; log_debug("%s: message length %d", __func__, ibuf_size(src)); print_hex(ibuf_data(src), 0, ibuf_size(src)); if (sa == NULL || sa->sa_integr == NULL) { log_debug("%s: invalid SA", __func__); return (-1); } if (sa->sa_hdr.sh_initiator) { integr = sa->sa_key_iauth; prf = sa->sa_key_iprf; } else { integr = sa->sa_key_rauth; prf = sa->sa_key_rprf; } integrlen = hash_length(sa->sa_integr); log_debug("%s: integrity checksum length %d", __func__, integrlen); /* * Validate packet checksum */ if ((tmp = ibuf_new(NULL, hash_keylength(sa->sa_integr))) == NULL) goto done; hash_setkey(sa->sa_integr, ibuf_data(integr), ibuf_size(integr)); hash_init(sa->sa_integr); hash_update(sa->sa_integr, ibuf_data(src), ibuf_size(src) - integrlen); hash_final(sa->sa_integr, ibuf_data(tmp), &tmplen); if (tmplen != integrlen) { log_debug("%s: hash failure", __func__); goto done; } if ((ptr = ibuf_seek(src, ibuf_size(src) - integrlen, integrlen)) == NULL) goto done; memcpy(ptr, ibuf_data(tmp), tmplen); print_hex(ibuf_data(tmp), 0, ibuf_size(tmp)); ret = 0; done: ibuf_release(tmp); return (ret); }
static SRP_Result calculate_M(SRP_HashAlgorithm alg, NGConstant *ng, unsigned char *dest, const char *I, const unsigned char *s_bytes, size_t s_len, const mpz_t A, const mpz_t B, const unsigned char *K) { unsigned char H_N[SHA512_DIGEST_LENGTH]; unsigned char H_g[SHA512_DIGEST_LENGTH]; unsigned char H_I[SHA512_DIGEST_LENGTH]; unsigned char H_xor[SHA512_DIGEST_LENGTH]; HashCTX ctx; size_t i = 0; size_t hash_len = hash_length(alg); if (!hash_num(alg, ng->N, H_N)) return SRP_ERR; if (!hash_num(alg, ng->g, H_g)) return SRP_ERR; hash(alg, (const unsigned char *)I, strlen(I), H_I); for (i = 0; i < hash_len; i++) H_xor[i] = H_N[i] ^ H_g[i]; hash_init(alg, &ctx); hash_update(alg, &ctx, H_xor, hash_len); hash_update(alg, &ctx, H_I, hash_len); hash_update(alg, &ctx, s_bytes, s_len); if (!update_hash_n(alg, &ctx, A)) return SRP_ERR; if (!update_hash_n(alg, &ctx, B)) return SRP_ERR; hash_update(alg, &ctx, K, hash_len); hash_final(alg, &ctx, dest); return SRP_OK; }
/* user_M must be exactly SHA512_DIGEST_LENGTH bytes in size */ void srp_verifier_verify_session( struct SRPVerifier *ver, const unsigned char *user_M, unsigned char **bytes_HAMK) { if (memcmp(ver->M, user_M, hash_length(ver->hash_alg)) == 0) { ver->authenticated = 1; *bytes_HAMK = ver->H_AMK; } else *bytes_HAMK = NULL; }
int kerfs_icache_report(int direction, void *param, size_t size, size_t offset, size_t length, unsigned char *buf) { size_t current = 0; KERFS_PRINTF(offset, length, buf, current, "icache load: %d%%\n", (100 * hash_count(icache)) / hash_length(icache)); KERFS_PRINTF(offset, length, buf, current, "IN USE %d, DIRTY %d, LRU LEN %d, TOTAL CACHED %d\n", ic_inuse->count, ic_dirty->count, ic_lru->count, icache->count); return current; }
static BIGNUM * H_ns( SRP_HashAlgorithm alg, const BIGNUM * n, const unsigned char * bytes, int len_bytes ) { unsigned char buff[ SHA512_DIGEST_LENGTH ]; int len_n = BN_num_bytes(n); int nbytes = len_n + len_bytes; unsigned char * bin = (unsigned char *) malloc( nbytes ); BN_bn2bin(n, bin); memcpy( bin + len_n, bytes, len_bytes ); hash( alg, bin, nbytes, buff ); free(bin); return BN_bin2bn(buff, hash_length(alg), NULL); }
void meteor_user_generate_u( struct SRPUser *usr, char const *Bstr, unsigned char *buff, BIGNUM **u ) { unsigned char *catString_u = malloc( strlen(usr->Astr)+strlen(Bstr)+1 ); strcpy((char *)catString_u, usr->Astr); strcat( (char *)catString_u, Bstr); hash( usr->hash_alg, catString_u, strlen((char *)catString_u), buff ); *u = BN_bin2bn(buff, hash_length(usr->hash_alg), NULL); }
static BIGNUM * H_nn( SRP_HashAlgorithm alg, const BIGNUM * n1, const BIGNUM * n2 ) { unsigned char buff[ SHA512_DIGEST_LENGTH ]; int len_n1 = BN_num_bytes(n1); int len_n2 = BN_num_bytes(n2); int nbytes = len_n1 + len_n2; unsigned char * bin = (unsigned char *) malloc( nbytes ); BN_bn2bin(n1, bin); BN_bn2bin(n2, bin + len_n1); hash( alg, bin, nbytes, buff ); free(bin); return BN_bin2bn(buff, hash_length(alg), NULL); }
void meteor_user_generate_HAMK( struct SRPUser *usr, unsigned char *buff, const char * M_str, const char * S_str ) { char * AMS = malloc( strlen(usr->Astr) + strlen(M_str) + strlen(S_str) + 1 ); strcpy( AMS, usr->Astr ); strcat( AMS, M_str ); strcat( AMS, S_str ); hash( usr->hash_alg, (const unsigned char *)AMS, strlen(AMS), buff ); usr->HAMK = convert_to_lower( BN_bn2hex(BN_bin2bn(buff, hash_length(usr->hash_alg), NULL)) ); }
static SRP_Result H_ns(mpz_t result, SRP_HashAlgorithm alg, const unsigned char *n, size_t len_n, const unsigned char *bytes, size_t len_bytes) { unsigned char buff[SHA512_DIGEST_LENGTH]; size_t nbytes = len_n + len_bytes; unsigned char *bin = (unsigned char *)srp_alloc(nbytes); if (!bin) return SRP_ERR; memcpy(bin, n, len_n); memcpy(bin + len_n, bytes, len_bytes); hash(alg, bin, nbytes, buff); srp_free(bin); mpz_from_bin(buff, hash_length(alg), result); return SRP_OK; }
static BIGNUM * calculate_x( SRP_HashAlgorithm alg, const BIGNUM * salt, const char * username, const unsigned char * password, int password_len ) { unsigned char ucp_hash[SHA512_DIGEST_LENGTH]; HashCTX ctx; hash_init( alg, &ctx ); hash_update( alg, &ctx, username, strlen(username) ); hash_update( alg, &ctx, ":", 1 ); hash_update( alg, &ctx, password, password_len ); hash_final( alg, &ctx, ucp_hash ); return H_ns( alg, salt, ucp_hash, hash_length(alg) ); }
void meteor_user_generate_u(SRPUser *usr, char const *Bstr, unsigned char *buff, BIGNUM **u) { char *catString_u = malloc(strlen(usr->Astr)+1 + strlen(Bstr)+1); strcpy(catString_u, usr->Astr); strcat(catString_u, Bstr); unsigned char lbuff[SHA256_DIGEST_LENGTH] = ""; hash(usr->hash_alg, (const unsigned char *)catString_u, strlen(catString_u), lbuff); *u = BN_bin2bn(lbuff, hash_length(usr->hash_alg), NULL); free(catString_u); }
static BIGNUM * H_nn( SRP_HashAlgorithm alg, const BIGNUM * n1, const BIGNUM * n2, int N_len) { unsigned char buff[ SHA512_DIGEST_LENGTH ]; int len_n1 = BN_num_bytes(n1); int len_n2 = BN_num_bytes(n2); int N_len2 = N_len * 2; unsigned char * bin = (unsigned char *) malloc( N_len2 ); for (int i = 0; i < N_len2; i++) bin[i] = 0; BN_bn2bin(n1, bin + N_len - len_n1); BN_bn2bin(n2, bin + N_len2 - len_n2); hash( alg, bin, N_len2, buff ); free(bin); return BN_bin2bn(buff, hash_length(alg), NULL); }
void meteor_user_generate_x( struct SRPUser *usr, char const *identity, char const *salt, char const *password, unsigned char *buff, BIGNUM **x ) { const char * static_delim = ":"; BIGNUM * x_inner = 0; const unsigned char * catString_i_p = malloc(strlen(identity) + strlen(password) + 1); strcpy((char *)catString_i_p, identity); strcat((char *)catString_i_p, static_delim); strcat((char *)catString_i_p, password); hash( usr->hash_alg, catString_i_p, strlen((char *)catString_i_p), buff ); x_inner = BN_bin2bn(buff, hash_length(usr->hash_alg), NULL); if ( !x_inner ) goto cleanup_and_exit; // x_innerStr should now equal salt value const char * x_inner_str = BN_bn2hex(x_inner); char * x_inner_str_lower = convert_to_lower(x_inner_str); const unsigned char * catString_s_i_p = malloc(strlen(salt) + strlen(x_inner_str_lower) + 1); strcpy((char *)catString_s_i_p, salt); strcat((char *)catString_s_i_p, x_inner_str_lower); hash( usr->hash_alg, catString_s_i_p, strlen((char *)catString_s_i_p), buff ); *x = BN_bin2bn(buff, hash_length(usr->hash_alg), NULL); cleanup_and_exit: BN_free( x_inner ); }
static int calculate_x(mpz_t result, SRP_HashAlgorithm alg, const unsigned char *salt, size_t salt_len, const char *username, const unsigned char *password, size_t password_len) { unsigned char ucp_hash[SHA512_DIGEST_LENGTH]; HashCTX ctx; hash_init(alg, &ctx); srp_dbg_data((char*) username, strlen(username), "Username for x: "); srp_dbg_data((char*) password, password_len, "Password for x: "); hash_update(alg, &ctx, username, strlen(username)); hash_update(alg, &ctx, ":", 1); hash_update(alg, &ctx, password, password_len); hash_final(alg, &ctx, ucp_hash); return H_ns(result, alg, salt, salt_len, ucp_hash, hash_length(alg)); }
void meteor_user_generate_HAMK(SRPUser *usr, unsigned char *buff, const char *M_str, const char *S_str) { char *AMS = malloc(strlen(usr->Astr)+1 + strlen(M_str)+1 + strlen(S_str)+1 + 1); strcpy(AMS, usr->Astr); strcat(AMS, M_str); strcat(AMS, S_str); AMS[strlen(AMS)] = '\0'; unsigned char lbuff[SHA256_DIGEST_LENGTH] = ""; hash(usr->hash_alg, (const unsigned char *)AMS, strlen(AMS), lbuff); usr->HAMK = BN_bn2hex(BN_bin2bn(lbuff, hash_length(usr->hash_alg), NULL)); free(AMS); }
static BIGNUM * H_nn_rfc5054( SRP_HashAlgorithm alg, const BIGNUM * N, const BIGNUM * n1, const BIGNUM * n2 ) { unsigned char buff[ SHA512_DIGEST_LENGTH ]; int len_N = BN_num_bytes(N); int len_n1 = BN_num_bytes(n1); int len_n2 = BN_num_bytes(n2); int nbytes = len_N * 2; unsigned char * bin = (unsigned char *) malloc( nbytes ); if (!bin) return 0; memset(bin, 0, nbytes); BN_bn2bin(n1, bin + (len_N - len_n1)); BN_bn2bin(n2, bin + (len_N + len_N - len_n2)); hash( alg, bin, nbytes, buff ); free(bin); return BN_bin2bn(buff, hash_length(alg), NULL); }
void meteor_user_generate_k( struct SRPUser *usr, unsigned char *buff, BIGNUM **k ) { char * N_str = BN_bn2hex( usr->ng->N ); // generator (g) is always 0x02 but bn2hex represents string as 02 and meteor (javascript) lib represents as 2 // so hard coding this value to 2 to be able to generate what meteor expects us to const char * g_str = "2"; char * cat_string_n_g = malloc( strlen(N_str) + strlen(g_str) + 1 ); strcpy( cat_string_n_g, N_str ); strcat( cat_string_n_g, g_str ); const char * ng = convert_to_lower( cat_string_n_g ); hash( usr->hash_alg, (const unsigned char *)ng, strlen(ng), buff ); *k = BN_bin2bn( buff, hash_length(usr->hash_alg), NULL ); }
const char * meteor_user_generate_M_string(SRPUser *usr, const char *S_str, unsigned char *buff, const char *B_str) { BIGNUM *M = BN_new(); char *ABS = malloc(strlen(usr->Astr)+1 + strlen(B_str)+1 + strlen(S_str)+1 + 1); strcpy(ABS, usr->Astr); strcat(ABS, B_str); strcat(ABS, usr->Sstr); ABS[strlen(ABS)] = '\0'; unsigned char lbuff[SHA256_DIGEST_LENGTH] = ""; hash(usr->hash_alg, (const unsigned char *)ABS, strlen(ABS), lbuff); M = BN_bin2bn(lbuff, hash_length(usr->hash_alg), NULL); free(ABS); return convert_to_lower(BN_bn2hex(M)); }
static SRP_Result H_nn( mpz_t result, SRP_HashAlgorithm alg, const mpz_t N, const mpz_t n1, const mpz_t n2) { unsigned char buff[SHA512_DIGEST_LENGTH]; size_t len_N = mpz_num_bytes(N); size_t len_n1 = mpz_num_bytes(n1); size_t len_n2 = mpz_num_bytes(n2); size_t nbytes = len_N + len_N; unsigned char *bin = (unsigned char *)srp_alloc(nbytes); if (!bin) return SRP_ERR; if (len_n1 > len_N || len_n2 > len_N) { srp_free(bin); return SRP_ERR; } memset(bin, 0, nbytes); mpz_to_bin(n1, bin + (len_N - len_n1)); mpz_to_bin(n2, bin + (len_N + len_N - len_n2)); hash(alg, bin, nbytes, buff); srp_free(bin); mpz_from_bin(buff, hash_length(alg), result); return SRP_OK; }
void meteor_user_generate_k( SRPUser *usr, unsigned char *buff, BIGNUM **k ) { char *N_str = BN_bn2hex(usr->ng->N); // generator (g) is always 0x02 but bn2hex represents // string as 02 and meteor (javascript) lib represents as 2 // so hard coding this value to 2 to be able to generate // what meteor expects static const char *g_str = "2"; char *cat_string_n_g = malloc(strlen(N_str)+1 + strlen(g_str)+1 + 1); strcpy(cat_string_n_g, N_str); strcat(cat_string_n_g, g_str); cat_string_n_g[strlen(cat_string_n_g)] = '\0'; char *ng = convert_to_lower(cat_string_n_g); unsigned char lbuff[SHA256_DIGEST_LENGTH] = ""; hash(usr->hash_alg, (const unsigned char *)ng, strlen(ng), lbuff); *k = BN_bin2bn(lbuff, hash_length(usr->hash_alg), NULL); free(cat_string_n_g); }
int srp_user_get_session_key_length( struct SRPUser * usr ) { return hash_length( usr->hash_alg ); }
const unsigned char * srp_user_get_session_key( struct SRPUser * usr, int * key_length ) { if (key_length) *key_length = hash_length( usr->hash_alg ); return usr->session_key; }
int srp_verifier_get_session_key_length( struct SRPVerifier * ver ) { return hash_length( ver->hash_alg ); }