int hmac (char* key, int keyLength, char* outFile, long fileLength, char** mac, int* macLength ){ DPRINT("\nin hmac.\n"); gcry_error_t err; gcry_md_hd_t shahd; DPRINT("opening hash\n"); err = gcry_md_open(&shahd, GCRY_MD_SHA256, GCRY_MD_FLAG_HMAC); if(err){ return MD_OPEN_ERROR;} DPRINT("setting key\n"); err = gcry_md_setkey(shahd, key, keyLength); if(err){ return MD_SETKEY_ERROR;} DPRINT("actually hashing\n"); DPRINT("%ld\n",fileLength); gcry_md_write(shahd, outFile, fileLength); DPRINT("done hashing\n"); *macLength = 32; char* temp; temp = gcry_md_read(shahd, GCRY_MD_SHA256); DPRINT("preparing to read hash\n"); /*copy it over since closing shahd would free the mac.*/ *mac = (char*)(malloc(*macLength * sizeof(char))); memcpy(*mac, temp, *macLength); gcry_md_close(shahd); return NONE; }
char * get_hmac(char * cipher, char * key, size_t length){ /* Generating hmac from the encrypted content GCRY_MD_SHA512 - Algo flags or of GCRY_MD_FLAG_SECURE | GCRY_MD_FLAG_HMAC indicating that its secure mode and we need HMAC */ gcry_error_t err; gcry_md_hd_t hm; err = gcry_md_open(&hm, GCRY_MD_SHA512, GCRY_MD_FLAG_SECURE | GCRY_MD_FLAG_HMAC); if(err != GPG_ERR_NO_ERROR){ printf ("Error at opening handle for hmac: %s\n",gcry_strerror(err)); exit(-1); } err = gcry_md_enable(hm,GCRY_MD_SHA512); err = gcry_md_setkey(hm, key,KEYLENGTH_SHA ); if(err != GPG_ERR_NO_ERROR){ printf ("Error at setting key: %s\n",gcry_strerror(err)); exit(-1); } // generating the HMAC using the cipher text gcry_md_write(hm,cipher,length); gcry_md_final(hm); // printf("\nlength: %lu\n",length); char * hmac; hmac = gcry_md_read(hm , GCRY_MD_SHA512 ); if(hmac == NULL ){ printf ("hmac null ?\n"); // exit(-1); } // print_buf(hmac,64); // debug // printf("hmac length : %lu\n",strlen(hmac)); // debug to check hmac length should be 64 return hmac; }
int crypt_hmac_init(struct crypt_hmac **ctx, const char *name, const void *buffer, size_t length) { struct crypt_hmac *h; unsigned int flags = GCRY_MD_FLAG_HMAC; assert(crypto_backend_initialised); h = malloc(sizeof(*h)); if (!h) return -ENOMEM; h->hash_id = gcry_md_map_name(crypt_hash_compat_name(name, &flags)); if (!h->hash_id) { free(h); return -EINVAL; } if (gcry_md_open(&h->hd, h->hash_id, flags)) { free(h); return -EINVAL; } if (gcry_md_setkey(h->hd, buffer, length)) { gcry_md_close(h->hd); free(h); return -EINVAL; } h->hash_len = gcry_md_get_algo_dlen(h->hash_id); *ctx = h; return 0; }
int init_decrypt_ctx(struct decrypt_ctx *ctx, struct psafe3_pro *pro, struct safe_sec *sec) { gcry_error_t gerr; assert(ctx != NULL); assert(pro != NULL); assert(sec != NULL); gerr = gcry_cipher_open(&ctx->cipher, GCRY_CIPHER_TWOFISH, GCRY_CIPHER_MODE_CBC, GCRY_CIPHER_SECURE); if (gerr != GPG_ERR_NO_ERROR) goto err_cipher; ctx->gerr = gcry_cipher_setkey(ctx->cipher, sec->rand_k, 32); if (gerr != GPG_ERR_NO_ERROR) goto err_cipher; ctx->gerr = gcry_cipher_setiv(ctx->cipher, pro->iv, 16); if (gerr != GPG_ERR_NO_ERROR) goto err_cipher; gerr = gcry_md_open(&ctx->hmac, GCRY_MD_SHA256, GCRY_MD_FLAG_SECURE|GCRY_MD_FLAG_HMAC); if (gerr != GPG_ERR_NO_ERROR) goto err_hmac; gerr = gcry_md_setkey(ctx->hmac, sec->rand_l, 32); if (gerr != GPG_ERR_NO_ERROR) goto err_hmac; return 0; err_hmac: gcry_cipher_close(ctx->cipher); err_cipher: ctx->gerr = gerr; return -1; }
HMACCTX hmac_init(const void *key, int len, enum ssh_hmac_e type) { HMACCTX c = NULL; switch(type) { case SSH_HMAC_SHA1: gcry_md_open(&c, GCRY_MD_SHA1, GCRY_MD_FLAG_HMAC); break; case SSH_HMAC_SHA256: gcry_md_open(&c, GCRY_MD_SHA256, GCRY_MD_FLAG_HMAC); break; case SSH_HMAC_SHA384: gcry_md_open(&c, GCRY_MD_SHA384, GCRY_MD_FLAG_HMAC); break; case SSH_HMAC_SHA512: gcry_md_open(&c, GCRY_MD_SHA512, GCRY_MD_FLAG_HMAC); break; case SSH_HMAC_MD5: gcry_md_open(&c, GCRY_MD_MD5, GCRY_MD_FLAG_HMAC); break; default: c = NULL; } gcry_md_setkey(c, key, len); return c; }
void gc_hash_hmac_setkey (gc_hash_handle handle, size_t len, const char *key) { _gc_hash_ctx *ctx = handle; #ifdef GNULIB_GC_MD2 if (ctx->alg != GC_MD2) #endif gcry_md_setkey (ctx->gch, key, len); }
int P_hash(const char *digest, unsigned char *dest, int dlen, unsigned char *secret, int sslen, unsigned char *seed, int slen) { unsigned char hmac[48]; uint32_t hlen; gcry_md_hd_t md; uint32_t tmpslen; unsigned char tmpseed[slen]; unsigned char *out = dest; int pending = dlen; int algo = gcry_md_map_name(digest); int algolen = gcry_md_get_algo_dlen(algo); // Copy initial seed memcpy(tmpseed, seed, slen); tmpslen = slen; // Calculate enough data to fill destination while (pending > 0) { gcry_md_open(&md, algo, GCRY_MD_FLAG_HMAC); gcry_md_setkey(md, secret, sslen); gcry_md_write(md, tmpseed, tmpslen); memcpy(tmpseed, gcry_md_read(md, algo), algolen); tmpslen = algolen; gcry_md_close(md); gcry_md_open(&md, algo, GCRY_MD_FLAG_HMAC); gcry_md_setkey(md, secret, sslen); gcry_md_write(md, tmpseed, tmpslen); gcry_md_write(md, seed, slen); memcpy(hmac, gcry_md_read(md, algo), algolen); hlen = algolen; hlen = (hlen > pending) ? pending : hlen; memcpy(out, hmac, hlen); out += hlen; pending -= hlen; } return hlen; }
gchar * xfce_mailwatch_cram_md5(const gchar *username, const gchar *password, const gchar *challenge_base64) { #ifdef HAVE_SSL_SUPPORT gchar challenge[2048]; gsize len, username_len; gcry_md_hd_t hmac_md5; gchar *response, *response_base64 = NULL; g_return_val_if_fail(username && *username && password && *password && challenge_base64 && *challenge_base64, NULL); len = xfce_mailwatch_base64_decode(challenge_base64, (guchar *)challenge, sizeof(challenge) - 1); if(len <= 0) return NULL; challenge[len] = 0; DBG("challenge is \"%s\"\n", challenge); if(gcry_md_open(&hmac_md5, GCRY_MD_MD5, GCRY_MD_FLAG_HMAC) != GPG_ERR_NO_ERROR) return NULL; gcry_md_setkey(hmac_md5, password, strlen(password)); gcry_md_write(hmac_md5, challenge, len); gcry_md_final(hmac_md5); username_len = strlen(username); /* username + a space + MD5 in hex + null */ response = g_malloc0(username_len + 1 + gcry_md_get_algo_dlen(GCRY_MD_MD5)*2 + 1); strcpy(response, username); response[username_len] = ' '; bin2hex(response + username_len + 1, gcry_md_read(hmac_md5, GCRY_MD_MD5), gcry_md_get_algo_dlen(GCRY_MD_MD5)); gcry_md_close(hmac_md5); DBG("response before base64: %s\n", response); if(xfce_mailwatch_base64_encode((guchar *)response, strlen(response), &response_base64) <= 0) { g_free(response_base64); response_base64 = NULL; } g_free(response); return response_base64; #else g_warning("CRAM-MD5 computation unavailable: libmailwatch was not compiled with gnutls support."); return NULL; #endif }
int hmacsha256_init(gcry_md_hd_t *mh, const char *key, int len) { gcry_error_t err; err = gcry_md_open(mh, GCRY_MD_SHA256, GCRY_MD_FLAG_HMAC | GCRY_MD_FLAG_SECURE); if (gcry_err_code(err)) return 0; err = gcry_md_setkey(*mh, key, len); return ! gcry_err_code(err); }
static void check_one_mac (int algo, const void *key, size_t keylen, const void *data, size_t datalen, const char *expect) { gcry_md_hd_t hd; unsigned char *p; int mdlen; int i; gcry_error_t err = 0; err = gcry_md_open (&hd, algo, GCRY_MD_FLAG_HMAC); if (err) { fail ("algo %d, grcy_md_open failed: %s\n", algo, gpg_strerror (err)); return; } mdlen = gcry_md_get_algo_dlen (algo); if (mdlen < 1 || mdlen > 500) { fail ("algo %d, grcy_md_get_algo_dlen failed: %d\n", algo, mdlen); return; } err = gcry_md_setkey (hd, key, keylen); if (err) { fail ("algo %d, grcy_md_setkey failed: %s\n", algo, gpg_strerror (err)); return; } gcry_md_write (hd, data, datalen); p = gcry_md_read (hd, 0); if (memcmp (p, expect, mdlen)) { printf ("computed: "); for (i = 0; i < mdlen; i++) printf ("%02x ", p[i] & 0xFF); printf ("\nexpected: "); for (i = 0; i < mdlen; i++) printf ("%02x ", expect[i] & 0xFF); printf ("\n"); fail ("algo %d, MAC does not match\n", algo); } gcry_md_close (hd); }
static int hmac_fdigest(lua_State *L) { HANDLER_HMAC c; size_t written = 0; const char *t = luaL_checkstring(L, 1); size_t s_len; const char *s = luaL_checklstring(L, 2, &s_len); size_t k_len; const char *k = luaL_checklstring(L, 3, &k_len); DIGEST_TYPE type = DIGEST_BY_NAME(t); #if CRYPTO_OPENSSL unsigned char digest[EVP_MAX_MD_SIZE]; #elif CRYPTO_GCRYPT unsigned char *digest; #endif if (IS_DIGEST_INVALID(type)) { luaL_argerror(L, 1, "invalid digest type"); return 0; } #if CRYPTO_OPENSSL HMAC_CTX_init(&c); HMAC_Init_ex(&c, k, k_len, type, NULL); HMAC_Update(&c, (unsigned char *)s, s_len); HMAC_Final(&c, digest, &written); #elif CRYPTO_GCRYPT gcry_md_open(&c, type, GCRY_MD_FLAG_HMAC); gcry_md_setkey(c, k, k_len); gcry_md_write(c, s, s_len); gcry_md_final(c); digest = gcry_md_read(c,type); written = gcry_md_get_algo_dlen(type); #endif if (lua_toboolean(L, 4)) lua_pushlstring(L, (char *)digest, written); else { char *hex = bin2hex(digest,written); lua_pushlstring(L, hex, written*2); free(hex); } #if CRYPTO_GCRYPT gcry_md_close(c); #endif return 1; }
/** * Calculate HMAC of a message (RFC 2104) * * @param key secret key * @param plaintext input plaintext * @param plaintext_len length of plaintext * @param hmac where to store the hmac */ void GNUNET_CRYPTO_hmac (const struct GNUNET_CRYPTO_AuthKey *key, const void *plaintext, size_t plaintext_len, struct GNUNET_HashCode * hmac) { gcry_md_hd_t md; const unsigned char *mc; GNUNET_assert (GPG_ERR_NO_ERROR == gcry_md_open (&md, GCRY_MD_SHA512, GCRY_MD_FLAG_HMAC)); gcry_md_setkey (md, key->key, sizeof (key->key)); gcry_md_write (md, plaintext, plaintext_len); mc = gcry_md_read (md, GCRY_MD_SHA512); if (mc != NULL) memcpy (hmac->bits, mc, sizeof (hmac->bits)); gcry_md_close (md); }
HMACCTX hmac_init(const void *key, int len, int type) { HMACCTX c = NULL; switch(type) { case HMAC_SHA1: gcry_md_open(&c, GCRY_MD_SHA1, GCRY_MD_FLAG_HMAC); break; case HMAC_MD5: gcry_md_open(&c, GCRY_MD_MD5, GCRY_MD_FLAG_HMAC); break; default: c = NULL; } gcry_md_setkey(c, key, len); return c; }
static int xmlSecGCryptHmacSetKey(xmlSecTransformPtr transform, xmlSecKeyPtr key) { xmlSecGCryptHmacCtxPtr ctx; xmlSecKeyDataPtr value; xmlSecBufferPtr buffer; gcry_error_t err; xmlSecAssert2(xmlSecGCryptHmacCheckId(transform), -1); xmlSecAssert2((transform->operation == xmlSecTransformOperationSign) || (transform->operation == xmlSecTransformOperationVerify), -1); xmlSecAssert2(xmlSecTransformCheckSize(transform, xmlSecGCryptHmacSize), -1); xmlSecAssert2(key != NULL, -1); ctx = xmlSecGCryptHmacGetCtx(transform); xmlSecAssert2(ctx != NULL, -1); xmlSecAssert2(ctx->digestCtx != NULL, -1); value = xmlSecKeyGetValue(key); xmlSecAssert2(xmlSecKeyDataCheckId(value, xmlSecGCryptKeyDataHmacId), -1); buffer = xmlSecKeyDataBinaryValueGetBuffer(value); xmlSecAssert2(buffer != NULL, -1); if(xmlSecBufferGetSize(buffer) == 0) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), NULL, XMLSEC_ERRORS_R_INVALID_KEY_DATA_SIZE, "key is empty"); return(-1); } err = gcry_md_setkey(ctx->digestCtx, xmlSecBufferGetData(buffer), xmlSecBufferGetSize(buffer)); if(err != GPG_ERR_NO_ERROR) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), "gcry_md_setkey", XMLSEC_ERRORS_R_CRYPTO_FAILED, XMLSEC_GCRYPT_REPORT_ERROR(err)); return(-1); } return(0); }
/*-------------------[ Std. HASH ]-------------------------------------*/ static tree_cell * nasl_gcrypt_hash (lex_ctxt * lexic, int algorithm, void *data, size_t datalen, void *key, size_t keylen) { gcry_md_hd_t hd; gcry_error_t err; tree_cell *retc; int dlen = gcry_md_get_algo_dlen (algorithm); if (data == NULL) return NULL; err = gcry_md_open (&hd, algorithm, key ? GCRY_MD_FLAG_HMAC : 0); if (err) { nasl_perror (lexic, "nasl_gcrypt_hash(): gcry_md_open failed: %s/%s\n", gcry_strsource (err), gcry_strerror (err)); return NULL; } if (key) { err = gcry_md_setkey (hd, key, keylen); if (err) { nasl_perror (lexic, "nasl_gcrypt_hash():" " gcry_md_setkey failed: %s/%s\n", gcry_strsource (err), gcry_strerror (err)); return NULL; } } gcry_md_write (hd, data, datalen); retc = alloc_tree_cell (0, NULL); retc->type = CONST_DATA; retc->x.str_val = g_memdup (gcry_md_read (hd, algorithm), dlen + 1); retc->size = dlen; gcry_md_close (hd); return retc; }
int journal_file_hmac_start(JournalFile *f) { uint8_t key[256 / 8]; /* Let's pass 256 bit from FSPRG to HMAC */ assert(f); if (!f->seal) return 0; if (f->hmac_running) return 0; /* Prepare HMAC for next cycle */ gcry_md_reset(f->hmac); FSPRG_GetKey(f->fsprg_state, key, sizeof(key), 0); gcry_md_setkey(f->hmac, key, sizeof(key)); f->hmac_running = true; return 0; }
/* calculate the HMAC of the message in data and store it in result * it is up to the caller to make sure that there's enough space * at result for the MAC */ int calc_hmac(const void *data, size_t datalen, int hid, unsigned char *result, char *key, unsigned int keylen) { static gcry_md_hd_t digest; gcry_error_t err; if (!digest) { err = gcry_md_open(&digest, hid, GCRY_MD_FLAG_HMAC); if (err) { log_error("gcry_md_open: %s", gcry_strerror(err)); return -1; } err = gcry_md_setkey(digest, key, keylen); if (err) { log_error("gcry_md_open: %s", gcry_strerror(err)); return -1; } } gcry_md_write(digest, data, datalen); memcpy(result, gcry_md_read(digest, 0), gcry_md_get_algo_dlen(hid)); gcry_md_reset(digest); return 0; }
static int hmac_fnew(lua_State *L) { HANDLER_HMAC *c = hmac_pnew(L); const char *s = luaL_checkstring(L, 1); size_t k_len; const char *k = luaL_checklstring(L, 2, &k_len); DIGEST_TYPE type = DIGEST_BY_NAME(s); if (IS_DIGEST_INVALID(type)) { luaL_argerror(L, 1, "invalid digest type"); return 0; } #if CRYPTO_OPENSSL HMAC_CTX_init(c); HMAC_Init_ex(c, k, k_len, type, NULL); #elif CRYPTO_GCRYPT gcry_md_open(c, type, GCRY_MD_FLAG_HMAC); gcry_md_setkey(*c, k, k_len); #endif return 1; }
Gc_rc gc_hmac_sha1 (const void *key, size_t keylen, const void *in, size_t inlen, char *resbuf) { size_t hlen = gcry_md_get_algo_dlen (GCRY_MD_SHA1); gcry_md_hd_t mdh; unsigned char *hash; gpg_error_t err; assert (hlen == GC_SHA1_DIGEST_SIZE); err = gcry_md_open (&mdh, GCRY_MD_SHA1, GCRY_MD_FLAG_HMAC); if (err != GPG_ERR_NO_ERROR) return GC_INVALID_HASH; err = gcry_md_setkey (mdh, key, keylen); if (err != GPG_ERR_NO_ERROR) { gcry_md_close (mdh); return GC_INVALID_HASH; } gcry_md_write (mdh, in, inlen); hash = gcry_md_read (mdh, GCRY_MD_SHA1); if (hash == NULL) { gcry_md_close (mdh); return GC_INVALID_HASH; } memcpy (resbuf, hash, hlen); gcry_md_close (mdh); return GC_OK; }
gboolean egg_hkdf_perform (const gchar *hash_algo, gconstpointer input, gsize n_input, gconstpointer salt, gsize n_salt, gconstpointer info, gsize n_info, gpointer output, gsize n_output) { gpointer alloc = NULL; gpointer buffer = NULL; gcry_md_hd_t md1, md2; guint hash_len; gint i; gint flags, algo; gsize step, n_buffer; guchar *at; gcry_error_t gcry; algo = gcry_md_map_name (hash_algo); g_return_val_if_fail (algo != 0, FALSE); hash_len = gcry_md_get_algo_dlen (algo); g_return_val_if_fail (hash_len != 0, FALSE); g_return_val_if_fail (n_output <= 255 * hash_len, FALSE); /* Buffer we need to for intermediate stuff */ if (gcry_is_secure (input)) { flags = GCRY_MD_FLAG_SECURE; buffer = gcry_malloc_secure (hash_len); } else { flags = 0; buffer = gcry_malloc (hash_len); } g_return_val_if_fail (buffer, FALSE); n_buffer = 0; /* Salt defaults to hash_len zeros */ if (!salt) { salt = alloc = g_malloc0 (hash_len); n_salt = hash_len; } /* Step 1: Extract */ gcry = gcry_md_open (&md1, algo, GCRY_MD_FLAG_HMAC | flags); g_return_val_if_fail (gcry == 0, FALSE); gcry = gcry_md_setkey (md1, salt, n_salt); g_return_val_if_fail (gcry == 0, FALSE); gcry_md_write (md1, input, n_input); /* Step 2: Expand */ gcry = gcry_md_open (&md2, algo, GCRY_MD_FLAG_HMAC | flags); g_return_val_if_fail (gcry == 0, FALSE); gcry = gcry_md_setkey (md2, gcry_md_read (md1, algo), hash_len); g_return_val_if_fail (gcry == 0, FALSE); gcry_md_close (md1); at = output; for (i = 1; i < 256; ++i) { gcry_md_reset (md2); gcry_md_write (md2, buffer, n_buffer); gcry_md_write (md2, info, n_info); gcry_md_putc (md2, i); n_buffer = hash_len; memcpy (buffer, gcry_md_read (md2, algo), n_buffer); step = MIN (n_buffer, n_output); memcpy (at, buffer, step); n_output -= step; at += step; if (!n_output) break; } g_free (alloc); gcry_free (buffer); return TRUE; }
static int wrap_gcry_md_setkey (void *ctx, const void *key, size_t keylen) { return gcry_md_setkey ((gcry_md_hd_t) ctx, key, keylen); }
gcry_error_t gcry_pbkdf2 (int PRF, const char *P, size_t Plen, const char *S, size_t Slen, unsigned int c, unsigned int dkLen, char *DK) { gcry_md_hd_t prf; gcry_error_t rc; char *U; unsigned int u; unsigned int hLen; unsigned int l; unsigned int r; unsigned char *p; unsigned int i; unsigned int k; hLen = gcry_md_get_algo_dlen (PRF); if (hLen == 0) return GPG_ERR_UNSUPPORTED_ALGORITHM; if (c == 0) return GPG_ERR_INV_ARG; if (dkLen == 0) return GPG_ERR_TOO_SHORT; /* * * Steps: * * 1. If dkLen > (2^32 - 1) * hLen, output "derived key too long" and * stop. */ if (dkLen > 4294967295U) return GPG_ERR_TOO_LARGE; /* * 2. Let l be the number of hLen-octet blocks in the derived key, * rounding up, and let r be the number of octets in the last * block: * * l = CEIL (dkLen / hLen) , * r = dkLen - (l - 1) * hLen . * * Here, CEIL (x) is the "ceiling" function, i.e. the smallest * integer greater than, or equal to, x. */ l = dkLen / hLen; if (dkLen % hLen) l++; r = dkLen - (l - 1) * hLen; /* * 3. For each block of the derived key apply the function F defined * below to the password P, the salt S, the iteration count c, and * the block index to compute the block: * * T_1 = F (P, S, c, 1) , * T_2 = F (P, S, c, 2) , * ... * T_l = F (P, S, c, l) , * * where the function F is defined as the exclusive-or sum of the * first c iterates of the underlying pseudorandom function PRF * applied to the password P and the concatenation of the salt S * and the block index i: * * F (P, S, c, i) = U_1 \xor U_2 \xor ... \xor U_c * * where * * U_1 = PRF (P, S || INT (i)) , * U_2 = PRF (P, U_1) , * ... * U_c = PRF (P, U_{c-1}) . * * Here, INT (i) is a four-octet encoding of the integer i, most * significant octet first. * * 4. Concatenate the blocks and extract the first dkLen octets to * produce a derived key DK: * * DK = T_1 || T_2 || ... || T_l<0..r-1> * * 5. Output the derived key DK. * * Note. The construction of the function F follows a "belt-and- * suspenders" approach. The iterates U_i are computed recursively to * remove a degree of parallelism from an opponent; they are exclusive- * ored together to reduce concerns about the recursion degenerating * into a small set of values. * */ rc = gcry_md_open (&prf, PRF, GCRY_MD_FLAG_HMAC | GCRY_MD_FLAG_SECURE); if (rc != GPG_ERR_NO_ERROR) return rc; U = (char*)gcry_malloc(hLen); if (!U) { rc = GPG_ERR_ENOMEM; goto done; } for (i = 1; i <= l; i++) { memset(DK + (i - 1) * hLen, 0, i == l ? r : hLen); for (u = 1; u <= c; u++) { gcry_md_reset (prf); rc = gcry_md_setkey (prf, P, Plen); if (rc != GPG_ERR_NO_ERROR) { goto done; } if (u == 1) { char tmp[4]; gcry_md_write (prf, S, Slen); tmp[0] = (i & 0xff000000) >> 24; tmp[1] = (i & 0x00ff0000) >> 16; tmp[2] = (i & 0x0000ff00) >> 8; tmp[3] = (i & 0x000000ff) >> 0; gcry_md_write (prf, tmp, 4); } else gcry_md_write (prf, U, hLen); p = gcry_md_read (prf, PRF); if (p == NULL) { rc = GPG_ERR_CONFIGURATION; goto done; } memcpy (U, p, hLen); for (k = 0; k < (i == l ? r : hLen); k++) DK[(i - 1) * hLen + k] ^= U[k]; }
int main(int argc, char *argv[]) { //initialization taken from the man pages /* Version check should be the very first call because it makes sure that important subsystems are intialized. */ if (!gcry_check_version (GCRYPT_VERSION)) { fputs ("libgcrypt version mismatch\n", stderr); exit (2); } /* Disable secure memory. */ gcry_control (GCRYCTL_DISABLE_SECMEM, 0); /* ... If required, other initialization goes here. */ /* Tell Libgcrypt that initialization has completed. */ gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); //variables and such char port[8]; char fileName[100]; char salt[17]; char password[33]; char key[33]; int fileSpecified = 0; struct addrinfo hints, *servinfo; int i; int s; //socket //parse input if(argc < 2 || argc > 3){ printf("Incorrect syntax, should be: ./uodec [<port>] [-l <file name>]"); exit(1); } if(strncmp(argv[1], "-l", 2) == 0){ fileSpecified = 1; strcpy(fileName, argv[2]); } else { memset(port, 0, 8); memcpy(port, argv[1], strlen(argv[1])); } FILE *srcFile; //followed beej's networking guide for this section: http://beej.us/guide/bgnet/output/html/singlepage/bgnet.html#syscalls if(!fileSpecified){ int fileSocket; struct sockaddr_storage fileAddr; memset(&hints, 0, sizeof hints); hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_PASSIVE; hints.ai_family = AF_INET; getaddrinfo(NULL, port, &hints, &servinfo); s = socket(servinfo->ai_family, servinfo->ai_socktype, servinfo->ai_protocol); bind(s, servinfo->ai_addr, servinfo->ai_addrlen); listen(s, 20); socklen_t addr_size = sizeof fileAddr; printf("Waiting for connection...\n"); fileSocket = accept(s, (struct sockaddr *) &fileAddr, &addr_size); printf("Inbound file."); shutdown(s, 2); char recvBuffer[512]; recv(fileSocket, fileName, 100, 0); printf("name = %s\n", fileName); srcFile = fopen(fileName, "w"); memset(recvBuffer, '\0', 512); int length; while(length = recv(fileSocket, recvBuffer, 512, 0)){ printf("writing files, length %d\n", length); fwrite(recvBuffer, 1, length, srcFile); } close(fileSocket); fclose(srcFile); } srcFile = fopen(fileName, "r"); char decFileName[100]; memset(decFileName, 0, 100); strcpy(decFileName, fileName); decFileName[strlen(decFileName) - 3] = '\0'; FILE * decFile = fopen(decFileName, "a+"); if(fgetc(decFile) != EOF){ printf("%s already exists, exitting.\n", decFileName); fclose(srcFile); fclose(decFile); exit(1); } //Get a password from the user printf("Password: "******"read %d bytes, wrote %d bytes,\n", readlen + 32 + padding + 1, readlen); readlen = fwrite(message, 1, readlen, decFile); } if(fileSpecified){ printf("Successfully decrypted %s to %s (%d bytes written).\n", fileName, decFileName, totalSize); } else { printf("Successfully recieved and decrypted %s to %s (%d bytes written).\n", fileName, decFileName, totalSize); } //house keeping fclose(srcFile); fclose(decFile); gcry_cipher_close(cipher); gcry_md_close(hash); return 0; }
void decrypt(char *outfile, char *inpfile) { gcry_err_code_t err = 0; gcry_cipher_hd_t gchandle; const int blks = gcry_cipher_get_algo_blklen(GCRY_CIPHER_AES256); const int keyl = gcry_cipher_get_algo_keylen(GCRY_CIPHER_AES256); long outfileSize = 0; char key[keyl]; const char* salt = "iuyjdbnbtaqonbgt"; //open output file FILE *fout = fopen(outfile, "r"); if (!fout) { printf("output file name : %s\n", outfile); fout = fopen(outfile, "w"); } else { printf("Output file already exist on disk.\n"); return;; } char password[100]; do { printf("Please enter password between 8-20 chars :"); scanf("%s", password); } while (strlen(password) > 20 || strlen(password) < 8); err = gcry_kdf_derive(password, strlen(password), GCRY_KDF_PBKDF2, GCRY_MD_SHA256, salt, strlen(salt), 937, keyl, key); if (err) { fprintf(stderr, "Failure: %s/%s\n", gcry_strsource(err), gcry_strerror(err)); exit(EXIT_FAILURE); } char ctext[blks]; char extractedIV[blks]; FILE *finp = fopen(inpfile, "r"); fseek(finp, 0, SEEK_SET); unsigned char extractedHMAC[keyl + 1]; fread(extractedHMAC, 1, keyl, finp); //extract HMAC from received file extractedHMAC[keyl] = '\0'; // Compare calculated HMAC with extracted HMAC ---> start long cipherSize = 0; fseek(finp, 0, SEEK_END); cipherSize = ftell(finp) - keyl; fseek(finp, keyl, SEEK_SET); unsigned char *hmacBuffer = malloc(cipherSize + 1); fread(hmacBuffer, 1, cipherSize, finp); gcry_md_hd_t hd; err = gcry_md_open(&hd, GCRY_MD_SHA256, GCRY_MD_FLAG_HMAC); if (err) { fprintf(stderr, "Failure: %s/%s\n", gcry_strsource(err), gcry_strerror(err)); fclose(finp); fclose(fout); exit(EXIT_FAILURE); } err = gcry_md_setkey(hd, key, keyl); if (err) { fprintf(stderr, "Failure: %s/%s\n", gcry_strsource(err), gcry_strerror(err)); fclose(finp); fclose(fout); exit(EXIT_FAILURE); } err = gcry_md_enable(hd, GCRY_MD_SHA256); if (err) { fprintf(stderr, "Failure: %s/%s\n", gcry_strsource(err), gcry_strerror(err)); fclose(finp); fclose(fout); exit(EXIT_FAILURE); } gcry_md_write(hd, hmacBuffer, cipherSize); char thmac[keyl]; unsigned char *hmac = thmac; hmac = gcry_md_read(hd, GCRY_MD_SHA256); int i = 0; int hflag = 1; for (; i < keyl; i++) { if (hmac[i] != extractedHMAC[i]) hflag = 0; } if (hflag) printf("HMAC successfully matched\n"); else printf("HMAC not matched\n"); fseek(finp, keyl, SEEK_SET); // Compare calculated HMAC with extracted HMAC ---> end //Decryption algo ------> start fread(extractedIV, 1, blks, finp); // read IV err = gcry_cipher_open(&gchandle, GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC, 0); if (err) { fprintf(stderr, "Failure: %s/%s\n", gcry_strsource(err), gcry_strerror(err)); exit(EXIT_FAILURE); } err = gcry_cipher_setkey(gchandle, key, keyl); if (err) { fprintf(stderr, "Failure: %s/%s\n", gcry_strsource(err), gcry_strerror(err)); exit(EXIT_FAILURE); } err = gcry_cipher_setiv(gchandle, extractedIV, blks); if (err) { fprintf(stderr, "Failure: %s/%s\n", gcry_strsource(err), gcry_strerror(err)); exit(EXIT_FAILURE); } if (!finp) { printf("Could not open input text file\n"); } else { int x = 0; char plaintext[blks]; while ((x = fread(plaintext, 1, blks, finp))) { if (x < blks) // add padding to last block outfileSize += x; err = gcry_cipher_decrypt(gchandle, ctext, blks, plaintext, x); if (err && x == blks) { fprintf(stderr, "Failure: %s/%s\n", gcry_strsource(err), gcry_strerror(err)); fclose(finp); fclose(fout); exit(EXIT_FAILURE); } fwrite(ctext, 1, blks, fout); } gcry_cipher_close(gchandle); gcry_md_close(hd); fclose(finp); fclose(fout); } free(hmacBuffer); //Decryption algo ------> end }
static int authenticate_md5(Pop3 pc, struct connection_state *scs, const char *capabilities) { char buf[BUF_SIZE]; char buf2[BUF_SIZE]; unsigned char *md5; gcry_md_hd_t gmh; gcry_error_t rc; if (!strstr(capabilities, "AUTH=CRAM-MD5")) { /* server doesn't support cram-md5. */ return 0; } tlscomm_printf(scs, "a007 AUTHENTICATE CRAM-MD5\r\n"); if (tlscomm_expect(scs, "+ ", buf, BUF_SIZE) == 0) goto expect_failure; Decode_Base64(buf + 2, buf2); IMAP_DM(pc, DEBUG_INFO, "CRAM-MD5 challenge: %s\n", buf2); strcpy(buf, PCU.userName); strcat(buf, " "); ask_user_for_password(pc, 0); rc = gcry_md_open(&gmh, GCRY_MD_MD5, GCRY_MD_FLAG_HMAC); if (rc != 0) { IMAP_DM(pc, DEBUG_INFO, "unable to initialize gcrypt md5\n"); return 0; } DEFROB(PCU.password); gcry_md_setkey(gmh, PCU.password, strlen(PCU.password)); ENFROB(PCU.password); gcry_md_write(gmh, (unsigned char *) buf2, strlen(buf2)); gcry_md_final(gmh); md5 = gcry_md_read(gmh, 0); Bin2Hex(md5, 16, buf2); gcry_md_close(gmh); strcat(buf, buf2); IMAP_DM(pc, DEBUG_INFO, "CRAM-MD5 response: %s\n", buf); Encode_Base64(buf, buf2); tlscomm_printf(scs, "%s\r\n", buf2); if (tlscomm_expect(scs, "a007 ", buf, BUF_SIZE) == 0) goto expect_failure; if (!strncmp(buf, "a007 OK", 7)) return 1; /* AUTH successful */ IMAP_DM(pc, DEBUG_ERROR, "CRAM-MD5 AUTH failed for user '%s@%s:%d'\n", PCU.userName, PCU.serverName, PCU.serverPort); IMAP_DM(pc, DEBUG_INFO, "It said %s", buf); return 0; expect_failure: IMAP_DM(pc, DEBUG_ERROR, "tlscomm_expect failed during cram-md5 auth: %s", buf); IMAP_DM(pc, DEBUG_ERROR, "failed to authenticate using cram-md5."); return 0; }
static int pkcs5_pbkdf2(const char *hash, const char *P, size_t Plen, const char *S, size_t Slen, unsigned int c, unsigned int dkLen, char *DK, int perfcheck) { gcry_md_hd_t prf; char U[MAX_PRF_BLOCK_LEN]; char T[MAX_PRF_BLOCK_LEN]; int PRF, i, k, rc = -EINVAL; unsigned int u, hLen, l, r; unsigned char *p; size_t tmplen = Slen + 4; char *tmp; tmp = alloca(tmplen); if (tmp == NULL) return -ENOMEM; if (init_crypto()) return -ENOSYS; PRF = gcry_md_map_name(hash); if (PRF == 0) return -EINVAL; hLen = gcry_md_get_algo_dlen(PRF); if (hLen == 0 || hLen > MAX_PRF_BLOCK_LEN) return -EINVAL; if (c == 0) return -EINVAL; if (dkLen == 0) return -EINVAL; /* * * Steps: * * 1. If dkLen > (2^32 - 1) * hLen, output "derived key too long" and * stop. */ if (dkLen > 4294967295U) return -EINVAL; /* * 2. Let l be the number of hLen-octet blocks in the derived key, * rounding up, and let r be the number of octets in the last * block: * * l = CEIL (dkLen / hLen) , * r = dkLen - (l - 1) * hLen . * * Here, CEIL (x) is the "ceiling" function, i.e. the smallest * integer greater than, or equal to, x. */ l = dkLen / hLen; if (dkLen % hLen) l++; r = dkLen - (l - 1) * hLen; /* * 3. For each block of the derived key apply the function F defined * below to the password P, the salt S, the iteration count c, and * the block index to compute the block: * * T_1 = F (P, S, c, 1) , * T_2 = F (P, S, c, 2) , * ... * T_l = F (P, S, c, l) , * * where the function F is defined as the exclusive-or sum of the * first c iterates of the underlying pseudorandom function PRF * applied to the password P and the concatenation of the salt S * and the block index i: * * F (P, S, c, i) = U_1 \xor U_2 \xor ... \xor U_c * * where * * U_1 = PRF (P, S || INT (i)) , * U_2 = PRF (P, U_1) , * ... * U_c = PRF (P, U_{c-1}) . * * Here, INT (i) is a four-octet encoding of the integer i, most * significant octet first. * * 4. Concatenate the blocks and extract the first dkLen octets to * produce a derived key DK: * * DK = T_1 || T_2 || ... || T_l<0..r-1> * * 5. Output the derived key DK. * * Note. The construction of the function F follows a "belt-and- * suspenders" approach. The iterates U_i are computed recursively to * remove a degree of parallelism from an opponent; they are exclusive- * ored together to reduce concerns about the recursion degenerating * into a small set of values. * */ if(gcry_md_open(&prf, PRF, GCRY_MD_FLAG_HMAC)) return -EINVAL; if (gcry_md_setkey(prf, P, Plen)) goto out; for (i = 1; (uint) i <= l; i++) { memset(T, 0, hLen); for (u = 1; u <= c ; u++) { gcry_md_reset(prf); if (u == 1) { memcpy(tmp, S, Slen); tmp[Slen + 0] = (i & 0xff000000) >> 24; tmp[Slen + 1] = (i & 0x00ff0000) >> 16; tmp[Slen + 2] = (i & 0x0000ff00) >> 8; tmp[Slen + 3] = (i & 0x000000ff) >> 0; gcry_md_write(prf, tmp, tmplen); } else { gcry_md_write(prf, U, hLen); } p = gcry_md_read(prf, PRF); if (p == NULL) goto out; memcpy(U, p, hLen); for (k = 0; (uint) k < hLen; k++) T[k] ^= U[k]; if (perfcheck && __PBKDF2_performance) { rc = 0; goto out; } if (perfcheck) __PBKDF2_global_j++; }
void hmac_MD5(char *fileName, int numOfIte) { //Code for HMAC_MD5 FILE *fin; // Names of the files used for HMAC_MD5 size_t hash_size = gcry_md_get_algo_dlen(GCRY_MD_MD5); size_t fl_rd_v; //FIle Reading variable double HMAC_MD5[100]; //Array stroing Time for each Encryption and Decryption clock_t start_HMD5, end_HMD5; //Defining Clock Functions variables to track time //gcrypt version check void grcrypt_init(){ if (!gcry_check_version (GCRYPT_VERSION)) { printf("LibGrycpt version doesn't match\n"); exit(-1); } } int j,k; //To run loop int bytes; //Scanning file BytebyByte char *key; char *buf_HMD5; gcry_md_hd_t handle_MD5; gcry_md_open(&handle_MD5,GCRY_MD_MD5,GCRY_MD_FLAG_HMAC|GCRY_MD_FLAG_SECURE); for(j=0; j<numOfIte;j++){ //Getting the value of key key = randomKey(32); printf("HMAC MD5 key for Iteration No %d is : %s ",j+1, key); //printf("The Key %s \n", key); printf("\n\n"); gcry_md_setkey(handle_MD5, key, strlen(key)); fin = fopen(fileName, "rb"); fseek(fin,0,SEEK_END); long int fileSize = ftell(fin); //fseek(fin,0,SEEK_SET); //printf("The file size is : %ld\n",fileSize); buf_HMD5 = malloc(sizeof(char) *fileSize); unsigned char *lenDig_HMD5 = NULL; start_HMD5 = clock(); //Clock for HMAC_MD5 Starts int bytes = fread(buf_HMD5, sizeof(char), fileSize-1, fin); gcry_md_write(handle_MD5, buf_HMD5, fl_rd_v);; gcry_md_final(handle_MD5); lenDig_HMD5 = gcry_md_read(handle_MD5, GCRY_MD_MD5); //message digest length, "int algo = 0" int i; printf("The Hash Generated using HMAC MD5 is: \n"); for(i=0;i<strlen(lenDig_HMD5);i++) { printf("%x",lenDig_HMD5[i]); } printf("\n"); /*while(fl_rd_v = fread(buf_HMD5, 1, fileSize-1, fin)) { gcry_md_write(handle_MD5, buf, fl_rd_v); if() }*/ end_HMD5 = clock(); //printf("End of Encrypption Iteration no %d using AES128 CBC Mode at: %ld \n ", j,end_EA128); double total_HMD5 = (double)(end_HMD5-start_HMD5)/CLOCKS_PER_SEC*1000000000; printf("\nTotal time taken for Hash Generation : %.2lf nano-seconds \n", total_HMD5); printf("--------------------------------------------------------------------------------\n"); HMAC_MD5[j] = total_HMD5; //} } gcry_md_close(handle_MD5); free(buf_HMD5); double Total_HMD5_Time=0.0; for(k=0;k<numOfIte;k++) { Total_HMD5_Time = Total_HMD5_Time + HMAC_MD5[k]; } printf("Total HASH Time (HMAC_MD5) for %d iterations is: %.2lf nano-seconds \n\n",k, Total_HMD5_Time); double meanHMD5_time = Total_HMD5_Time/numOfIte; printf("Mean Hash Time for (HMAC_MD5) %d iterations is: %.2lf nano-seconds \n\n",k, meanHMD5_time); double medianHMD5 = calculateMedian(HMAC_MD5, numOfIte); printf("The Median Hash Time for (HMAC_MD5) after %d Iterations is: %.2lf nano-seconds \n\n",numOfIte, medianHMD5); }
gsti_error_t kex_send_newkeys (gsti_ctx_t ctx) { gsti_error_t err; err = construct_keys (ctx); if (err) return err; ctx->pkt.type = SSH_MSG_NEWKEYS; ctx->pkt.payload_len = 1; err = _gsti_packet_write (ctx, &ctx->pkt); if (!err) err = _gsti_packet_flush (ctx); if (err) return err; /* Now we have to take the encryption keys into use. */ err = gcry_cipher_open (&ctx->encrypt_hd, ctx->ciph_algo, ctx->ciph_mode, 0); if (!ctx->ciph_blksize) ctx->ciph_blksize = gcry_cipher_get_algo_blklen (ctx->ciph_algo); if (err) ; else if (ctx->we_are_server) { if (!err) err = gcry_cipher_setkey (ctx->encrypt_hd, gsti_bstr_data (ctx->kex.key_d), gsti_bstr_length (ctx->kex.key_d)); if (!err) err = gcry_cipher_setiv (ctx->encrypt_hd, gsti_bstr_data (ctx->kex.iv_b), gsti_bstr_length (ctx->kex.iv_b)); if (!err) { err = gcry_md_open (&ctx->send_mac, ctx->mac_algo, GCRY_MD_FLAG_HMAC); if (!err) err = gcry_md_setkey (ctx->send_mac, gsti_bstr_data (ctx->kex.mac_f), gsti_bstr_length (ctx->kex.mac_f)); } } else { if (!err) err = gcry_cipher_setkey (ctx->encrypt_hd, gsti_bstr_data (ctx->kex.key_c), gsti_bstr_length (ctx->kex.key_c)); if (!err) err = gcry_cipher_setiv (ctx->encrypt_hd, gsti_bstr_data (ctx->kex.iv_a), gsti_bstr_length (ctx->kex.iv_a)); if (!err) { err = gcry_md_open (&ctx->send_mac, ctx->mac_algo, GCRY_MD_FLAG_HMAC); if (!err) err = gcry_md_setkey (ctx->send_mac, gsti_bstr_data (ctx->kex.mac_e), gsti_bstr_length (ctx->kex.mac_e)); } } if (err) _gsti_log_err (ctx, "setup encryption keys failed: %s\n", gsti_strerror (err)); return err; }
/* * Generate a deterministic secret exponent K less than DSA_Q. H1 is * the to be signed digest with a length of HLEN bytes. HALGO is the * algorithm used to create the hash. On success the value for K is * stored at R_K. */ gpg_err_code_t _gcry_dsa_gen_rfc6979_k (gcry_mpi_t *r_k, gcry_mpi_t dsa_q, gcry_mpi_t dsa_x, const unsigned char *h1, unsigned int hlen, int halgo, unsigned int extraloops) { gpg_err_code_t rc; unsigned char *V = NULL; unsigned char *K = NULL; unsigned char *x_buf = NULL; unsigned char *h1_buf = NULL; gcry_md_hd_t hd = NULL; unsigned char *t = NULL; gcry_mpi_t k = NULL; unsigned int tbits, qbits; int i; qbits = mpi_get_nbits (dsa_q); if (!qbits || !h1 || !hlen) return GPG_ERR_EINVAL; if (gcry_md_get_algo_dlen (halgo) != hlen) return GPG_ERR_DIGEST_ALGO; /* Step b: V = 0x01 0x01 0x01 ... 0x01 */ V = gcry_malloc (hlen); if (!V) { rc = gpg_err_code_from_syserror (); goto leave; } for (i=0; i < hlen; i++) V[i] = 1; /* Step c: K = 0x00 0x00 0x00 ... 0x00 */ K = gcry_calloc (1, hlen); if (!K) { rc = gpg_err_code_from_syserror (); goto leave; } rc = int2octets (&x_buf, dsa_x, (qbits+7)/8); if (rc) goto leave; rc = bits2octets (&h1_buf, h1, hlen*8, dsa_q, qbits); if (rc) goto leave; /* Create a handle to compute the HMACs. */ rc = gpg_err_code (gcry_md_open (&hd, halgo, (GCRY_MD_FLAG_SECURE | GCRY_MD_FLAG_HMAC))); if (rc) goto leave; /* Step d: K = HMAC_K(V || 0x00 || int2octets(x) || bits2octets(h1) */ rc = gpg_err_code (gcry_md_setkey (hd, K, hlen)); if (rc) goto leave; gcry_md_write (hd, V, hlen); gcry_md_write (hd, "", 1); gcry_md_write (hd, x_buf, (qbits+7)/8); gcry_md_write (hd, h1_buf, (qbits+7)/8); memcpy (K, gcry_md_read (hd, 0), hlen); /* Step e: V = HMAC_K(V) */ rc = gpg_err_code (gcry_md_setkey (hd, K, hlen)); if (rc) goto leave; gcry_md_write (hd, V, hlen); memcpy (V, gcry_md_read (hd, 0), hlen); /* Step f: K = HMAC_K(V || 0x01 || int2octets(x) || bits2octets(h1) */ rc = gpg_err_code (gcry_md_setkey (hd, K, hlen)); if (rc) goto leave; gcry_md_write (hd, V, hlen); gcry_md_write (hd, "\x01", 1); gcry_md_write (hd, x_buf, (qbits+7)/8); gcry_md_write (hd, h1_buf, (qbits+7)/8); memcpy (K, gcry_md_read (hd, 0), hlen); /* Step g: V = HMAC_K(V) */ rc = gpg_err_code (gcry_md_setkey (hd, K, hlen)); if (rc) goto leave; gcry_md_write (hd, V, hlen); memcpy (V, gcry_md_read (hd, 0), hlen); /* Step h. */ t = gcry_malloc ((qbits+7)/8+hlen); if (!t) { rc = gpg_err_code_from_syserror (); goto leave; } again: for (tbits = 0; tbits < qbits;) { /* V = HMAC_K(V) */ rc = gpg_err_code (gcry_md_setkey (hd, K, hlen)); if (rc) goto leave; gcry_md_write (hd, V, hlen); memcpy (V, gcry_md_read (hd, 0), hlen); /* T = T || V */ memcpy (t+(tbits+7)/8, V, hlen); tbits += 8*hlen; } /* k = bits2int (T) */ mpi_free (k); k = NULL; rc = gpg_err_code (gcry_mpi_scan (&k, GCRYMPI_FMT_USG, t, (tbits+7)/8, NULL)); if (rc) goto leave; if (tbits > qbits) gcry_mpi_rshift (k, k, tbits - qbits); /* Check: k < q and k > 1 */ if (!(mpi_cmp (k, dsa_q) < 0 && mpi_cmp_ui (k, 0) > 0)) { /* K = HMAC_K(V || 0x00) */ rc = gpg_err_code (gcry_md_setkey (hd, K, hlen)); if (rc) goto leave; gcry_md_write (hd, V, hlen); gcry_md_write (hd, "", 1); memcpy (K, gcry_md_read (hd, 0), hlen); /* V = HMAC_K(V) */ rc = gpg_err_code (gcry_md_setkey (hd, K, hlen)); if (rc) goto leave; gcry_md_write (hd, V, hlen); memcpy (V, gcry_md_read (hd, 0), hlen); goto again; } /* The caller may have requested that we introduce some extra loops. This is for example useful if the caller wants another value for K because the last returned one yielded an R of 0. Becuase this is very unlikely we implement it in a straightforward way. */ if (extraloops) { extraloops--; /* K = HMAC_K(V || 0x00) */ rc = gpg_err_code (gcry_md_setkey (hd, K, hlen)); if (rc) goto leave; gcry_md_write (hd, V, hlen); gcry_md_write (hd, "", 1); memcpy (K, gcry_md_read (hd, 0), hlen); /* V = HMAC_K(V) */ rc = gpg_err_code (gcry_md_setkey (hd, K, hlen)); if (rc) goto leave; gcry_md_write (hd, V, hlen); memcpy (V, gcry_md_read (hd, 0), hlen); goto again; } /* log_mpidump (" k", k); */ leave: gcry_free (t); gcry_md_close (hd); gcry_free (h1_buf); gcry_free (x_buf); gcry_free (K); gcry_free (V); if (rc) mpi_free (k); else *r_k = k; return rc; }
/* Process a received newkeys message and take the decryption keys in use. */ gsti_error_t kex_proc_newkeys (gsti_ctx_t ctx) { gsti_error_t err; if (ctx->pkt.type != SSH_MSG_NEWKEYS) return gsti_error (GPG_ERR_BUG); err = construct_keys (ctx); if (err) return err; err = gcry_cipher_open (&ctx->decrypt_hd, ctx->ciph_algo, ctx->ciph_mode, 0); if (!ctx->ciph_blksize) ctx->ciph_blksize = gcry_cipher_get_algo_blklen (ctx->ciph_algo); if (err) ; else if (ctx->we_are_server) { if (!err) err = gcry_cipher_setkey (ctx->decrypt_hd, gsti_bstr_data (ctx->kex.key_c), gsti_bstr_length (ctx->kex.key_c)); if (!err) err = gcry_cipher_setiv (ctx->decrypt_hd, gsti_bstr_data (ctx->kex.iv_a), gsti_bstr_length (ctx->kex.iv_a)); if (!err) { err = gcry_md_open (&ctx->recv_mac, ctx->mac_algo, GCRY_MD_FLAG_HMAC); if (!err) err = gcry_md_setkey (ctx->recv_mac, gsti_bstr_data (ctx->kex.mac_e), gsti_bstr_length (ctx->kex.mac_e)); } } else { if (!err) err = gcry_cipher_setkey (ctx->decrypt_hd, gsti_bstr_data (ctx->kex.key_d), gsti_bstr_length (ctx->kex.key_d)); if (!err) err = gcry_cipher_setiv (ctx->decrypt_hd, gsti_bstr_data (ctx->kex.iv_b), gsti_bstr_length (ctx->kex.iv_b)); if (!err) { err = gcry_md_open (&ctx->recv_mac, ctx->mac_algo, GCRY_MD_FLAG_HMAC); if (!err) err = gcry_md_setkey (ctx->recv_mac, gsti_bstr_data (ctx->kex.mac_f), gsti_bstr_length (ctx->kex.mac_f)); } } if (err) _gsti_log_err (ctx, "setup decryption keys failed: %s\n", gsti_strerror (err)); return err; }