Exemplo n.º 1
0
static void sha256_init(EVP_MD_CTX *ctx) {
  CHECK(SHA256_Init(ctx->md_data));
}
Exemplo n.º 2
0
static char *make_dirname(const char *pi_name, char **logtext)
{
    char *name, *parentdirname, *dirname, *err;

    /*
     * First, create the top-level directory for all shared PuTTY
     * connections owned by this user.
     */
    parentdirname = make_parentdir_name();
    if ((err = make_dir_and_check_ours(parentdirname)) != NULL) {
        *logtext = err;
        sfree(parentdirname);
        return NULL;
    }

    /*
     * Transform the platform-independent version of the connection
     * identifier into the name we'll actually use for the directory
     * containing the Unix socket.
     *
     * We do this by hashing the identifier with some user-specific
     * secret information, to avoid the privacy leak of having
     * "user@host" strings show up in 'netstat -x'. (Irritatingly, the
     * full pathname of a Unix-domain socket _does_ show up in the
     * 'netstat -x' output, at least on Linux, even if that socket is
     * in a directory not readable to the user running netstat. You'd
     * think putting things inside an 0700 directory would hide their
     * names from other users, but no.)
     *
     * The secret information we use to salt the hash lives in a file
     * inside the top-level directory we just created, so we must
     * first create that file (with some fresh random data in it) if
     * it's not already been done by a previous PuTTY.
     */
    {
        unsigned char saltbuf[SALT_SIZE];
        char *saltname;
        int saltfd, i, ret;

        saltname = dupprintf("%s/%s", parentdirname, SALT_FILENAME);
        saltfd = open(saltname, O_RDONLY);
        if (saltfd < 0) {
            char *tmpname;
            int pid;

            if (errno != ENOENT) {
                *logtext = dupprintf("%s: open: %s", saltname,
                                     strerror(errno));
                sfree(saltname);
                sfree(parentdirname);
                return NULL;
            }

            /*
             * The salt file doesn't already exist, so try to create
             * it. Another process may be attempting the same thing
             * simultaneously, so we must do this carefully: we write
             * a salt file under a different name, then hard-link it
             * into place, which guarantees that we won't change the
             * contents of an existing salt file.
             */
            pid = getpid();
            for (i = 0;; i++) {
                tmpname = dupprintf("%s/%s.tmp.%d.%d",
                                    parentdirname, SALT_FILENAME, pid, i);
                saltfd = open(tmpname, O_WRONLY | O_EXCL | O_CREAT, 0400);
                if (saltfd >= 0)
                    break;
                if (errno != EEXIST) {
                    *logtext = dupprintf("%s: open: %s", tmpname,
                                         strerror(errno));
                    sfree(tmpname);
                    sfree(saltname);
                    sfree(parentdirname);
                    return NULL;
                }
                sfree(tmpname);        /* go round and try again with i+1 */
            }
            /*
             * Invent some random data.
             */
            for (i = 0; i < SALT_SIZE; i++) {
                saltbuf[i] = random_byte();
            }
            ret = write(saltfd, saltbuf, SALT_SIZE);
            /* POSIX atomicity guarantee: because we wrote less than
             * PIPE_BUF bytes, the write either completed in full or
             * failed. */
            assert(SALT_SIZE < PIPE_BUF);
            assert(ret < 0 || ret == SALT_SIZE);
            if (ret < 0) {
                close(saltfd);
                *logtext = dupprintf("%s: write: %s", tmpname,
                                     strerror(errno));
                sfree(tmpname);
                sfree(saltname);
                sfree(parentdirname);
                return NULL;
            }
            if (close(saltfd) < 0) {
                *logtext = dupprintf("%s: close: %s", tmpname,
                                     strerror(errno));
                sfree(tmpname);
                sfree(saltname);
                sfree(parentdirname);
                return NULL;
            }

            /*
             * Now attempt to hard-link our temp file into place. We
             * tolerate EEXIST as an outcome, because that just means
             * another PuTTY got their attempt in before we did (and
             * we only care that there is a valid salt file we can
             * agree on, no matter who created it).
             */
            if (link(tmpname, saltname) < 0 && errno != EEXIST) {
                *logtext = dupprintf("%s: link: %s", saltname,
                                     strerror(errno));
                sfree(tmpname);
                sfree(saltname);
                sfree(parentdirname);
                return NULL;
            }

            /*
             * Whether that succeeded or not, get rid of our temp file.
             */
            if (unlink(tmpname) < 0) {
                *logtext = dupprintf("%s: unlink: %s", tmpname,
                                     strerror(errno));
                sfree(tmpname);
                sfree(saltname);
                sfree(parentdirname);
                return NULL;
            }

            /*
             * And now we've arranged for there to be a salt file, so
             * we can try to open it for reading again and this time
             * expect it to work.
             */
            sfree(tmpname);

            saltfd = open(saltname, O_RDONLY);
            if (saltfd < 0) {
                *logtext = dupprintf("%s: open: %s", saltname,
                                     strerror(errno));
                sfree(saltname);
                sfree(parentdirname);
                return NULL;
            }
        }

        for (i = 0; i < SALT_SIZE; i++) {
            ret = read(saltfd, saltbuf, SALT_SIZE);
            if (ret <= 0) {
                close(saltfd);
                *logtext = dupprintf("%s: read: %s", saltname,
                                     ret == 0 ? "unexpected EOF" :
                                     strerror(errno));
                sfree(saltname);
                sfree(parentdirname);
                return NULL;
            }
            assert(0 < ret && ret <= SALT_SIZE - i);
            i += ret;
        }

        close(saltfd);
        sfree(saltname);

        /*
         * Now we've got our salt, hash it with the connection
         * identifier to produce our actual socket name.
         */
        {
            SHA256_State sha;
            unsigned len;
            unsigned char lenbuf[4];
            unsigned char digest[32];
            char retbuf[65];

            SHA256_Init(&sha);
            PUT_32BIT(lenbuf, SALT_SIZE);
            SHA256_Bytes(&sha, lenbuf, 4);
            SHA256_Bytes(&sha, saltbuf, SALT_SIZE);
            len = strlen(pi_name);
            PUT_32BIT(lenbuf, len);
            SHA256_Bytes(&sha, lenbuf, 4);
            SHA256_Bytes(&sha, pi_name, len);
            SHA256_Final(&sha, digest);

            /*
             * And make it printable.
             */
            for (i = 0; i < 32; i++) {
                sprintf(retbuf + 2*i, "%02x", digest[i]);
                /* the last of those will also write the trailing NUL */
            }

            name = dupstr(retbuf);
        }

        smemclr(saltbuf, sizeof(saltbuf));
    }

    dirname = dupprintf("%s/%s", parentdirname, name);
    sfree(parentdirname);
    sfree(name);

    return dirname;
}
Exemplo n.º 3
0
static int
__archive_libmd_sha256init(archive_sha256_ctx *ctx)
{
  SHA256_Init(ctx);
  return (ARCHIVE_OK);
}
Exemplo n.º 4
0
int
main(void)
{
	SHA256_CTX ctx;
	uint8_t sum[32];
	int result = 0;
	int i, cnt;

	for (cnt = 0; cnt < (int)ntests; ++cnt) {
		SHA256_Init(&ctx);
		SHA256_Update(&ctx, tests[cnt].input, strlen(tests[cnt].input));
		SHA256_Final(sum, &ctx);
		if (memcmp(tests[cnt].result, sum, 32) != 0) {
			for (i = 0; i < 32; i++)
				printf("%02X", tests[cnt].result[i]);
			printf("\n");
			for (i = 0; i < 32; i++)
				printf("%02X", sum[i]);
			printf("\n");
			printf("test %d run %d failed\n", cnt, 1);
			result = 1;
		}

		SHA256_Init(&ctx);
		for (i = 0; tests[cnt].input[i] != '\0'; ++i)
			SHA256_Update(&ctx, &tests[cnt].input[i], 1);
		SHA256_Final(sum, &ctx);
		if (memcmp(tests[cnt].result, sum, 32) != 0) {
			for (i = 0; i < 32; i++)
				printf("%02X", tests[cnt].result[i]);
			printf("\n");
			for (i = 0; i < 32; i++)
				printf("%02X", sum[i]);
			printf("\n");
			printf("test %d run %d failed\n", cnt, 2);
			result = 1;
		}
	}

	/* Test vector from FIPS 180-2: appendix B.3. */
	char buf[1000];

	memset(buf, 'a', sizeof(buf));
	SHA256_Init(&ctx);
	for (i = 0; i < 1000; ++i)
		SHA256_Update(&ctx, buf, sizeof(buf));
	SHA256_Final(sum, &ctx);
	static const char expected[32] =
	"\xcd\xc7\x6e\x5c\x99\x14\xfb\x92\x81\xa1\xc7\xe2\x84\xd7\x3e\x67"
	"\xf1\x80\x9a\x48\xa4\x97\x20\x0e\x04\x6d\x39\xcc\xc7\x11\x2c\xd0";

	if (memcmp(expected, sum, 32) != 0) {
		printf("test %d failed\n", cnt);
		result = 1;
	}

	for (cnt = 0; cnt < ntests2; ++cnt) {
		char *cp = crypt_sha256(tests2[cnt].input, tests2[cnt].salt);

		if (strcmp(cp, tests2[cnt].expected) != 0) {
			printf("test %d: expected \"%s\", got \"%s\"\n",
			       cnt, tests2[cnt].expected, cp);
			result = 1;
		}
	}

	if (result == 0)
		puts("all tests OK");

	return result;
}
Exemplo n.º 5
0
static void md_init(mdCtx *ctx) { SHA256_Init(ctx); }
Exemplo n.º 6
0
static void
md_init(MD_CTX * ctx)
{
    SHA256_Init(ctx);
}
Exemplo n.º 7
0
static int
cnt_recv(const struct worker *wrk, struct req *req)
{
	unsigned recv_handling;
	struct SHA256Context sha256ctx;

	CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
	CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
	CHECK_OBJ_NOTNULL(req->vcl, VCL_CONF_MAGIC);
	AZ(req->obj);
	AZ(req->busyobj);

	VSLb(req->vsl, SLT_ReqStart, "%s %s", req->sp->addr, req->sp->port);

	if (req->err_code) {
		req->req_step = R_STP_ERROR;
		return (0);
	}

	/* By default we use the first backend */
	AZ(req->director);
	req->director = req->vcl->director[0];
	AN(req->director);

	EXP_Clr(&req->exp);

	req->disable_esi = 0;
	req->hash_always_miss = 0;
	req->hash_ignore_busy = 0;
	req->client_identity = NULL;

	http_CollectHdr(req->http, H_Cache_Control);

	VCL_recv_method(req);
	recv_handling = req->handling;

	if (cache_param->http_gzip_support &&
	     (recv_handling != VCL_RET_PIPE) &&
	     (recv_handling != VCL_RET_PASS)) {
		if (RFC2616_Req_Gzip(req->http)) {
			http_Unset(req->http, H_Accept_Encoding);
			http_SetHeader(req->http, "Accept-Encoding: gzip");
		} else {
			http_Unset(req->http, H_Accept_Encoding);
		}
	}

	req->sha256ctx = &sha256ctx;	/* so HSH_AddString() can find it */
	SHA256_Init(req->sha256ctx);
	VCL_hash_method(req);
	assert(req->handling == VCL_RET_HASH);
	SHA256_Final(req->digest, req->sha256ctx);
	req->sha256ctx = NULL;

	if (!strcmp(req->http->hd[HTTP_HDR_REQ].b, "HEAD"))
		req->wantbody = 0;
	else
		req->wantbody = 1;

	switch(recv_handling) {
	case VCL_RET_LOOKUP:
		req->req_step = R_STP_LOOKUP;
		return (0);
	case VCL_RET_PIPE:
		if (req->esi_level > 0) {
			/* XXX: VSL something */
			INCOMPL();
			return (1);
		}
		req->req_step = R_STP_PIPE;
		return (0);
	case VCL_RET_PASS:
		req->req_step = R_STP_PASS;
		return (0);
	case VCL_RET_ERROR:
		req->req_step = R_STP_ERROR;
		return (0);
	default:
		WRONG("Illegal action in vcl_recv{}");
	}
}
Exemplo n.º 8
0
void init_hashtable_values()
{
	printf("Pre-computing dcrypt internal hash values.\n");

	SHA256_CTX	hash;
	SHA256_Init(&hash);
	unsigned char md[32];

	if(tmp_array_1 && hash_1)
	{
		for(int x1 = 0; x1 < 16; x1++)
		{
			unsigned int offset_1 = x1;
			uint8_t * ta1 = &tmp_array_1[item_size*x1];
			memset(ta1, 0xff, SHA256_LEN); 
			ta1[SHA256_LEN] = hex_digits[x1];
			sha256_to_str(ta1, SHA256_LEN + 1, ta1,md);

			SHA256_CTX	*current_hash = &hash_1[x1];
			memcpy(current_hash,&hash,sizeof(SHA256_CTX));
			SHA256_Update(current_hash,ta1,SHA256_LEN);

			if(tmp_array_2 && hash_2)
			{
				for(int x2 = 0; x2 < 16; x2++)
				{
					unsigned int offset_2 = offset_1*16+x2;
					uint8_t * ta2 = &tmp_array_2[item_size*offset_2];
					memcpy(ta2,ta1,SHA256_LEN); 
					ta2[SHA256_LEN] = hex_digits[x2];
					sha256_to_str(ta2, SHA256_LEN + 1, ta2,md);

					memcpy(&hash_2[offset_2],&hash_1[offset_1],sizeof(SHA256_CTX));
					SHA256_Update(&hash_2[offset_2],ta2,SHA256_LEN);

					if(tmp_array_3 && hash_3)
					{
						for(int x3 = 0; x3 < 16; x3++)
						{
							unsigned int offset_3 = offset_2*16+x3;
							uint8_t * ta3 = &tmp_array_3[item_size*offset_3];
							memcpy(ta3,ta2,SHA256_LEN); 
							ta3[SHA256_LEN] = hex_digits[x3];
							sha256_to_str(ta3, SHA256_LEN + 1, ta3,md);

							memcpy(&hash_3[offset_3],&hash_2[offset_2],sizeof(SHA256_CTX));
							SHA256_Update(&hash_3[offset_3],ta3,SHA256_LEN);

							if(tmp_array_4 && hash_4)
							{
								for(int x4 = 0; x4 < 16; x4++)
								{
									unsigned int offset_4 = offset_3*16+x4;
									uint8_t * ta4 = &tmp_array_4[item_size*offset_4];
									memcpy(ta4,ta3,SHA256_LEN); 
									ta4[SHA256_LEN] = hex_digits[x4];
									sha256_to_str(ta4, SHA256_LEN + 1, ta4,md);

									memcpy(&hash_4[offset_4],&hash_3[offset_3],sizeof(SHA256_CTX));
									SHA256_Update(&hash_4[offset_4],ta4,SHA256_LEN);

									if(tmp_array_5 && hash_5)
									{
										for(int x5 = 0; x5 < 16; x5++)
										{
											unsigned int offset_5 = offset_4*16+x5;
											uint8_t * ta5 = &tmp_array_5[item_size*offset_5];
											memcpy(ta5,ta4,SHA256_LEN); 
											ta5[SHA256_LEN] = hex_digits[x5];
											sha256_to_str(ta5, SHA256_LEN + 1, ta5,md);

											memcpy(&hash_5[offset_5],&hash_4[offset_4],sizeof(SHA256_CTX));
											SHA256_Update(&hash_5[offset_5],ta5,SHA256_LEN);
										}
									}
								}
							}
						}
					}
				}
			}
		}
	}
	printf("Ready to rumble.\n");
}
Exemplo n.º 9
0
bool dcrypt_fast(u8int *data, size_t data_sz,uint32_t*md)
{
	#define MAX_INC 16

	unsigned char hash_buffer[SHA256_LEN*MAX_INC+SHA256_LEN*4+80+1];  

	unsigned char		index_buffer[SHA256_LEN+1]; 
	unsigned char 		*tmp_array = hash_buffer;     
	unsigned int	    index = 0;
	unsigned char		tmp_val;

	SHA256_CTX	hash;
	SHA256_Init(&hash);

	digest_to_skiplist((u8int *)md,index_buffer);   

	int steps = 0,index_test=index;
	while(1)
	{
		index_test += index_buffer[index_test]+1;

		if(index_test >= SHA256_LEN) return 0;
		if(index_test == SHA256_LEN - 1) break;
		steps++;
	}
	if(steps >= MAX_INC) return 0;/**/

	memset(tmp_array, 0xff, SHA256_LEN);      //set the first hash length in the temp array to all 0xff'
	memset(tmp_array + SHA256_LEN, 0x00, 2);  //set the last bytes to \000

	int count = 0; 

	if(tmp_array_1 && hash_1) // copy pre-calulated internal hashes
	{
		index += index_buffer[index]+1;
		unsigned int offset_1 = index_buffer[index];

		if(tmp_array_2 && hash_2) // depth 2
		{
			index += index_buffer[index]+1;
			unsigned int offset_2 = offset_1*16+index_buffer[index];

			if(tmp_array_3 && hash_3) // depth 3
			{
				index += index_buffer[index]+1;
				unsigned int offset_3 = offset_2*16+index_buffer[index];

				if(tmp_array_4 && hash_4) // depth 4
				{
					index += index_buffer[index]+1;
					unsigned int offset_4 = offset_3*16+index_buffer[index];

					if(tmp_array_5 && hash_5) // depth 5
					{
						index += index_buffer[index]+1;
						unsigned int offset_5 = offset_4*16+index_buffer[index];

						// depth 6?

						memcpy(tmp_array,&tmp_array_5[item_size*offset_5],SHA256_LEN); 
						memcpy(&hash,&hash_5[offset_5],sizeof(SHA256_CTX));
					}
					else
					{
						memcpy(tmp_array,&tmp_array_4[item_size*offset_4],SHA256_LEN); 
						memcpy(&hash,&hash_4[offset_4],sizeof(SHA256_CTX));
					}
				}
				else
				{
					memcpy(tmp_array,&tmp_array_3[item_size*offset_3],SHA256_LEN); 
					memcpy(&hash,&hash_3[offset_3],sizeof(SHA256_CTX));
				}
			}
			else
			{
				memcpy(tmp_array,&tmp_array_2[item_size*offset_2],SHA256_LEN); 
				memcpy(&hash,&hash_2[offset_2],sizeof(SHA256_CTX));
			}
		}
		else {
			memcpy(tmp_array,&tmp_array_1[item_size*offset_1],SHA256_LEN); 
			memcpy(&hash,&hash_1[offset_1],sizeof(SHA256_CTX));
		}
	}

 	do
	{
		index += index_buffer[index]+1;

		if(index >= SHA256_LEN) return 0;
	
		tmp_val = hex_digits[index_buffer[index]];

		tmp_array[SHA256_LEN] =  tmp_val; //set  end of tmp_array to tmp_val
		sha256_to_str(tmp_array, SHA256_LEN + 1, tmp_array+SHA256_LEN,(u8int *)md);

		count++;
		tmp_array += SHA256_LEN;

	}
	while ((index != SHA256_LEN - 1) || (tmp_val != tmp_array[SHA256_LEN - 1] ));

	SHA256_Update(&hash,hash_buffer+SHA256_LEN,SHA256_LEN*count);
	SHA256_Update(&hash,data,data_sz);
	SHA256_Final((u8int *)md, &hash);

	return 1;
}
Exemplo n.º 10
0
int
main(int argc, char **argv)
{
		char tarpath[PATH_MAX];
		char origtarpath[PATH_MAX];
		char selfpath[PATH_MAX];
		char *entrydata;
		struct archive *a;
		struct archive_entry *entry;
		int r;
		int64_t asize;
		//char *exclude_pattern = ".*/\\.svn/.*";
		//char buf[block];
		SHA256_CTX c;
		unsigned char md[SHA256_DIGEST_LENGTH];
		regex_t preg;
		int ch, i;
		verbosity verb; 
		char *modeline;
		int modelinesize;
		uint64_t (*modefunctions[11])( struct archive_entry *entry) = {
						archive_entry_mode,
						archive_entry_dev,
						archive_entry_devmajor,
						archive_entry_devminor,
						archive_entry_ino,
						archive_entry_nlink,
						archive_entry_rdevmajor,
						archive_entry_rdevminor,
						archive_entry_uid,
						archive_entry_gid,
						archive_entry_size
		};
		/*
		 * 16 characters should be enougth for all possible modefields
		 */
		char modes[(int)(sizeof(modefunctions)/sizeof(modefunctions[0]))][16];


		(void)realpath(argv[0], selfpath);
		// "$." -- empty match for any not-multiline input string
		if (regcomp(&preg, "$.", REG_EXTENDED) != 0)
		{
			fprintf(stderr, "Bad pattern\n");
			exit(1);
		}

		while ((ch = getopt(argc, argv, "r:")) != -1) {
						switch (ch) {
						case 'r':
								if (regcomp(&preg, optarg, REG_EXTENDED) != 0)
								{
									fprintf(stderr, "Bad pattern\n");
									exit(1);
								}; break;
						case '?':
						default:
										 usage(selfpath);
						 }
		}
		argc -= optind;
		argv += optind;

	a = archive_read_new();
	archive_read_support_compression_all(a);
	archive_read_support_format_all(a);

	if (argc == 0)
	{
			strncpy(tarpath, "stdin", sizeof("stdin"));
			r = archive_read_open_filename(a, NULL, ARCHIVE_DEFAULT_BYTES_PER_BLOCK);
			verb = Quiet;
	} else
	{
			(void)realpath(argv[0], tarpath);
			strcpy(origtarpath, argv[0]);
			if ((r = archive_read_open_filename(a, tarpath, ARCHIVE_DEFAULT_BYTES_PER_BLOCK)) == ARCHIVE_OK){
					verb = Noquiet;
			} else {
					printf("%s\n", archive_error_string(a));
					exit(1);
			}
	} 

		int counter=0;
		SHA256_Init(&c);
		while ((r = archive_read_next_header(a, &entry)) == ARCHIVE_OK)
		{
				modelinesize = 0;
				if ((++counter % 100) == 0) {
						printf ("%09d ", counter);
						printf("%s\n",archive_entry_pathname(entry));
						}
				if (regexec(&preg, archive_entry_pathname(entry), 0, NULL, 0) !=0)
				{
						SHA256_Update(&c, archive_entry_pathname(entry), sizeof(archive_entry_pathname(entry)));
						//printf("%s\n",archive_entry_pathname(entry));
						for (i=0; i  < sizeof(modefunctions)/sizeof(modefunctions[0]); i++){
								sprintf(modes[i], "%ld", modefunctions[i](entry));
								modelinesize += sizeof(modes[i]);
						}
						modeline = malloc(modelinesize);
						for (i=0; i  < sizeof(modefunctions)/sizeof(modefunctions[0]); i++){
								if (i == 0){
										strlcpy(modeline, modes[i], sizeof(modes[i]));
								} else {
										strlcat(modeline, modes[i], sizeof(modes[i]));
								}
								//free(modes[i]);
						}
						SHA256_Update(&c, modeline, modelinesize);
						free(modeline);
						if (archive_entry_filetype(entry) == AE_IFLNK){
								SHA256_Update(&c, archive_entry_symlink(entry), sizeof(archive_entry_symlink(entry)));
						}
						if (archive_entry_filetype(entry) == AE_IFREG
								)
						{
								asize = archive_entry_size(entry);
								entrydata = malloc(asize);
								archive_read_data(a, entrydata, asize);
								SHA256_Update(&c, entrydata, asize);
								//SHA256_Update(&lc, entrydata, asize);
								//SHA256_Final(&(md[0]),&lc);
								//pt(md);
								free(entrydata);
						}
				} else
				{
						archive_read_data_skip(a);
				}
		}
	if ( r == ARCHIVE_EOF )
	{
			if (verb != Quiet)
					printf("%s (%s) = ", toUpper(basename(selfpath)), origtarpath);
			SHA256_Final(&(md[0]),&c);
			pt(md);
	} else {
			//fprintf(stderr, "%s: %s\n", tarpath, "Can't operate with archive");
			fprintf(stderr, "%s: %s\n", tarpath, archive_error_string(a));
			exit(1);
	}
	archive_read_close(a);
	archive_read_free(a);
	regfree(&preg);
}
Exemplo n.º 11
0
static int
sign_with_p12_key(const struct http_io_conf *const config, char *key_file,
		  const char *pwd, char *plain_text, char *signed_buf, size_t buflen)
{
    unsigned char hash[SHA256_DIGEST_LENGTH];
    unsigned char sign[256];
    unsigned int sign_len = 0;
    FILE *fp = NULL;
    PKCS12 *p12 = NULL;
    EVP_PKEY *pkey = NULL;
    X509 *x509 = NULL;
    EVP_MD_CTX *ctx = NULL;
    RSA *prikey = NULL;
    SHA256_CTX sha256;
    const char *c;
    int ret;

    memset(hash, 0, SHA256_DIGEST_LENGTH);
    memset(sign, 0, 256);

    if (!(fp = fopen(key_file, "rb"))){        
        (*config->log)(LOG_ERR, "Error opening cert file %s: %s",
		       key_file, strerror(errno));
	return 1;
    }

    p12 = d2i_PKCS12_fp(fp, NULL);
    fclose(fp);

    if (!p12) {
        (*config->log)(LOG_ERR, "Error reading PKCS#12 file: %s",
		       strerror(errno));
	return 1;
    }

    STACK_OF(X509) *ca = NULL;
    ret = PKCS12_parse(p12, pwd, &pkey, &x509, &ca);
    PKCS12_free(p12);

    if (ret == 0) {
        (*config->log)(LOG_ERR, "Error parsing PKCS#12 file: %s",
		       strerror(errno));
	return 1;
    }

    sign_len = EVP_PKEY_size(pkey);
    ctx = EVP_MD_CTX_create();
    EVP_MD_CTX_init(ctx);

    prikey = EVP_PKEY_get1_RSA(pkey);

    SHA256_Init(&sha256);
    c = plain_text;
    SHA256_Update(&sha256, c, strlen(c));
    SHA256_Final(hash, &sha256);
      
    ret = RSA_sign(NID_sha256, hash, SHA256_DIGEST_LENGTH, sign,  &sign_len, prikey);
    EVP_MD_CTX_destroy(ctx);
    RSA_free(prikey);
    EVP_PKEY_free(pkey);
    X509_free(x509);

    if (ret == 0) {
        (*config->log)(LOG_ERR, "Signing p12 key with RSA Signature failed ");
	return 1;
    }
   
    memset(signed_buf, 0, buflen);
    http_io_base64_encode_safe(signed_buf, buflen, sign, sign_len);

    return 0;
}
Exemplo n.º 12
0
void HMAC_Init(HMAC_CTX *ctx, unsigned char *key, int len)
     //final parameter fixed to SHA256, so omitted EVP_MD *md;
{
     int i,j,reset=0;
     unsigned char pad[HMAC_MAX_MD_CBLOCK];

     unsigned char aux; //temporary, for the initialization loops

     //unsigned int ctx_key_length;
     unsigned char ctx_key[HMAC_MAX_MD_CBLOCK];


  /*
  if (md != NULL)
  {
  reset=1;
  ctx->md=md;
  }
  else
  md=ctx->md;
  */	

     if (key != NULL)
       {
         reset=1;
         //j=EVP_MD_block_size(md);
         j= HMAC_MAX_MD_CBLOCK;
      	 if (j < len)
	   { //apply sha to key get a 32byte-key, then pad to 64
	     //EVP_DigestInit(&ctx->md_ctx,md);
	     //EVP_DigestUpdate(&ctx->md_ctx,key,len);
	     //EVP_DigestFinal(&(ctx->md_ctx),ctx->key, &ctx->key_length);

	     SHA256_Init(&ctx->md_ctx);
	     SHA256_Update(&ctx->md_ctx,key,len);
	     SHA256_Final(ctx_key,&(ctx->md_ctx));
	     memset(&(ctx_key[32]),0,32);
	     //ctx_key_length=32; //in analogy to what's 6 lines below
	   }
	 else
	   {
	     memcpy(ctx_key,key,len);
	     memset(&(ctx_key[len]),0,sizeof(ctx_key)-len);
	     //ctx_key_length=len;
           }
       }

     if (reset)	
       {
	 for (i=0; i<HMAC_MAX_MD_CBLOCK; i++) {
           aux = ctx_key[i];
	   aux = 0x36^aux;
           pad[i]=aux;
         }

         //Initialize inner SHA structure, and hash ipad
	 //EVP_DigestInit(&ctx->i_ctx,md);
	 //EVP_DigestUpdate(&ctx->i_ctx,pad,EVP_MD_block_size(md));
	 SHA256_Init(&ctx->i_ctx);
	 SHA256_Update(&ctx->i_ctx,pad,HMAC_MAX_MD_CBLOCK);
	
	
	 for (i=0; i<HMAC_MAX_MD_CBLOCK; i++) {
           aux = ctx_key[i];
	   pad[i]=0x5c^aux;
         }

         //Initialize outer SHA structure, and hash opad
	 //EVP_DigestInit(&ctx->o_ctx,md);
	 //EVP_DigestUpdate(&ctx->o_ctx,pad,EVP_MD_block_size(md));
	 SHA256_Init(&ctx->o_ctx);
	 SHA256_Update(&ctx->o_ctx,pad,HMAC_MAX_MD_CBLOCK);
       }

     //copy inner sha structure to "current" sha structure
     memcpy(&ctx->md_ctx,&ctx->i_ctx,sizeof(ctx->i_ctx));
}
Exemplo n.º 13
0
 void sha256::encoder::reset() {
   SHA256_Init( &my->ctx);  
 }
Exemplo n.º 14
0
int main( int argc, char *argv[] )
{
    int     nRetVal     = EXIT_SUCCESS;
    DH     *pMine       = NULL,
           *pTheirs     = NULL;

    int     nSharedKey  = 0;
    char*   pSharedKey  = NULL;

    char    pFoldedKey[ SHA256_DIGEST_LENGTH ] = { 0 };

    ARGS    sArgs       = { 0 };
    int     fdSock      = 0;


    if( !parseArgs( &sArgs, argc, argv ) )
    {
            printf( "usage:\n%s\n"
                            "\t-client <ip>:<port>\n"
                            "\t-server <port>\n",
                            argv[0] );
            nRetVal = EXIT_FAILURE;
    }

    // bind/connect
    if( EXIT_SUCCESS == nRetVal )
    {
        fdSock = getNetworkConnection( &sArgs );

        if( -1 == fdSock )
        {
                nRetVal = EXIT_FAILURE;
        } else {
#ifdef DEBUG_OUTPUT
            printf( "[i]\tgot a connection\n" );
#endif
        }
    }

    // create diffie structures
    if( EXIT_SUCCESS == nRetVal )
    {
        pMine   = DH_new();
        pTheirs = DH_new();
        if( pMine && pTheirs )
        {
            BN_hex2bn( &(pMine->p),
                "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
                "29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
                "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
                "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"
                "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D"
                "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F"
                "83655D23DCA3AD961C62F356208552BB9ED529077096966D"
                "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B"
                "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9"
                "DE2BCBF6955817183995497CEA956AE515D2261898FA0510"
                "15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64"
                "ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7"
                "ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B"
                "F12FFA06D98A0864D87602733EC86A64521F2B18177B200C"
                "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31"
                "43DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7"
                "88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA"
                "2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6"
                "287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED"
                "1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9"
                "93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934028492"
                "36C3FAB4D27C7026C1D4DCB2602646DEC9751E763DBA37BD"
                "F8FF9406AD9E530EE5DB382F413001AEB06A53ED9027D831"
                "179727B0865A8918DA3EDBEBCF9B14ED44CE6CBACED4BB1B"
                "DB7F1447E6CC254B332051512BD7AF426FB8F401378CD2BF"
                "5983CA01C64B92ECF032EA15D1721D03F482D7CE6E74FEF6"
                "D55E702F46980C82B5A84031900B1C9E59E7C97FBEC7E8F3"
                "23A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AA"
                "CC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE328"
                "06A1D58BB7C5DA76F550AA3D8A1FBFF0EB19CCB1A313D55C"
                "DA56C9EC2EF29632387FE8D76E3C0468043E8F663F4860EE"
                "12BF2D5B0B7474D6E694F91E6DBE115974A3926F12FEE5E4"
                "38777CB6A932DF8CD8BEC4D073B931BA3BC832B68D9DD300"
                "741FA7BF8AFC47ED2576F6936BA424663AAB639C5AE4F568"
                "3423B4742BF1C978238F16CBE39D652DE3FDB8BEFC848AD9"
                "22222E04A4037C0713EB57A81A23F0C73473FC646CEA306B"
                "4BCBC8862F8385DDFA9D4B7FA2C087E879683303ED5BDD3A"
                "062B3CF5B3A278A66D2A13F83F44F82DDF310EE074AB6A36"
                "4597E899A0255DC164F31CC50846851DF9AB48195DED7EA1"
                "B1D510BD7EE74D73FAF36BC31ECFA268359046F4EB879F92"
                "4009438B481C6CD7889A002ED5EE382BC9190DA6FC026E47"
                "9558E4475677E9AA9E3050E2765694DFC81F56E880B96E71"
                "60C980DD98EDD3DFFFFFFFFFFFFFFFFF" );
            BN_hex2bn( &(pMine->g), "2" );
            // "they're" going to use the same
            pTheirs->p = BN_dup( pMine->p );
            pTheirs->g = BN_dup( pMine->g );
        }

        // check we have everything we should
        if( NULL == pMine       ||
            NULL == pMine->p    ||
            NULL == pMine->g    ||
            NULL == pTheirs     ||
            NULL == pTheirs->p  ||
            NULL == pTheirs->g     )
        {
            nRetVal = EXIT_FAILURE;
        }
    }
    // pMine has p & g

    if( EXIT_SUCCESS == nRetVal && pMine )
    {
#ifdef DEBUG_OUTPUT
        fprintf( stdout, "[i]\tgenerating key....." );
        fflush( stdout );
#endif
        if( DH_generate_key( pMine ) )
        {
#ifdef DEBUG_OUTPUT
            fprintf( stdout, "done.\n" );
#endif
        } else {
#ifdef DEBUG_OUTPUT
            fprintf( stdout, "failed.\n" );
#endif
            nRetVal = EXIT_FAILURE;
        }
    }

    //
    // we now have public and private keys
    //


    //
    // now push our public key
    //
    if( EXIT_SUCCESS == nRetVal )
    {
        pSharedKey = BN_bn2hex( pMine->pub_key ); // ( just reusing the var )
        if( pSharedKey )
        {
            nSharedKey = strlen( pSharedKey );
#ifdef DEBUG_OUTPUT
            printf( "[i]\tsending public key (%d)\n", nSharedKey );
#endif
            write( fdSock, pSharedKey, nSharedKey );
        } else {
            nRetVal = EXIT_FAILURE;
        }
    }

    //
    // read in pTheirs public key
    // (reusing pShareKey's buffer - its the same size after all)
    //
    if( EXIT_SUCCESS == nRetVal && pSharedKey )
    {
        bzero( pSharedKey, nSharedKey );
        if( nSharedKey == read( fdSock, pSharedKey, nSharedKey ) )
        {
            // looks good
        } else {
            // incompleate read - should really re-try
            nRetVal = EXIT_FAILURE;
        }
    }

    //
    // parse in the public key
    //
    if( EXIT_SUCCESS == nRetVal && pSharedKey )
    {
        BN_hex2bn( &(pTheirs->pub_key), pSharedKey );
    }

    //
    // free that temp buffer
    //
    if( pSharedKey )
    {
        OPENSSL_free( pSharedKey );
        pSharedKey = NULL;
        nSharedKey = 0;
    }

    //
    // calculate shared key
    //
    if( EXIT_SUCCESS == nRetVal )
    {
        nSharedKey = DH_size( pMine );
        pSharedKey = OPENSSL_malloc( nSharedKey );
        if( pSharedKey )
        {
            DH_compute_key( pSharedKey, pTheirs->pub_key, pMine );
        } else {
            // malloc failed
            nRetVal = EXIT_FAILURE;
        }
    }

    if( EXIT_SUCCESS == nRetVal && nSharedKey && pSharedKey )
    {
        // key is too big - needs folding
        SHA256_CTX      ctx                         =   { 0 };

        SHA256_Init( &ctx );
        SHA256_Update( &ctx, pSharedKey, nSharedKey );
        SHA256_Final( pFoldedKey, &ctx );

#ifdef DEBUG_OUTPUT
        fprintf( stdout, "[i]\tsuccesfully key-exchanged.\n" );
        {
            BIGNUM *pOutput = BN_bin2bn( pFoldedKey, sizeof( pFoldedKey ), NULL );
            char   *pTextOut= BN_bn2hex( pOutput );
            fprintf( stdout, "[i]\tshared key:\n%s\n", pTextOut );
            OPENSSL_free( pTextOut );
            BN_free( pOutput );
        }
#endif

        nRetVal = copyLoop( fdSock, pFoldedKey, sizeof( pFoldedKey ) );

        //
        // close the socket connection
        //
        close( fdSock );
    }

    if( pSharedKey )
    {
        OPENSSL_free( pSharedKey );
        pSharedKey = NULL;
        nSharedKey = 0;
    }


    if( pMine )
    {
        DH_free( pMine );
        pMine = NULL;
    }
    if( pTheirs )
    {
        DH_free( pTheirs );
        pTheirs = NULL;
    }


    return nRetVal;
}
Exemplo n.º 15
0
 error
 SHA256Strategy::init( boost::any& _context ) const {
     _context = SHA256_CTX();
     SHA256_Init( boost::any_cast<SHA256_CTX>( &_context ) );
     return SUCCESS();
 }
Exemplo n.º 16
0
int scanhash_dcrypt(int thr_id, uint32_t *pdata,
                    unsigned char *digest, const uint32_t *ptarget,
                    uint32_t max_nonce, unsigned long *hashes_done, int num_iter,unsigned long *hashes_skipped)
{
  uint32_t block[20], hash[8];
  uint32_t nNonce = pdata[19] - 1;
  const uint32_t Htarg = ptarget[7]; //the last element in the target is the first 32 bits of the target
  int i;
  bool completed;
  *hashes_skipped = 0;	
  //copy the block (first 80 bytes of pdata) into block
  memcpy(block, pdata, 80);

  SHA256_CTX	halfstate,fullstate;
  SHA256_Init(&halfstate);
  SHA256_Update(&halfstate,&block,sizeof(uint32_t)*19);
  
  do
  {
    //increment nNonce
    block[19] = ++nNonce;
		
    //completed = dcrypt((u8int*)block, 80, digest, hash, num_iter);

	memcpy(&fullstate,&halfstate,sizeof(SHA256_CTX)); 
	SHA256_Update(&fullstate,&block[19],sizeof(uint32_t));
	SHA256_Final((u8int *)hash, &fullstate);
	completed = dcrypt_fast((u8int*)block, 80,hash);/**/

    if (!completed)
    {
        *hashes_skipped += 1;
        continue;
    }

	/*
	// check optimized hash against previous hash function

	uint32_t hash2[8];

	int c2 = dcrypt((u8int*)block, 80, digest, hash2, num_iter);

	for(int i = 0; i < 8 ; i++)
	{
		if(hash[i] != hash2[i])
		{
			char s1[65],s2[65];
			digest_to_string((u8int*)hash, s1);
			digest_to_string((u8int*)hash2, s2);
			printf("Fail!!!\n%s %d\n%s %d\n",s1,completed,s2,c2);
			exit(0);
		}
	}/**/


    //hash[7] <= Htarg just compares the first 32 bits of the hash with the target
    // full_test fully compares the entire hash with the entire target

    if(hash[7] <= Htarg && fulltest(hash, ptarget)) 
    {
      *hashes_done = nNonce - pdata[19] + 1 - *hashes_skipped;
      pdata[19] = block[19];

		char s[65];
		digest_to_string((u8int*)hash, s);
	    applog(LOG_INFO, "hash found: %s", s);

		// check

		uint32_t hash2[8];

		int c2 = dcrypt((u8int*)block, 80, digest, hash2, num_iter);

		for(int i = 0; i < 8 ; i++)
		{
			if(hash[i] != hash2[i])
			{
				char s1[65],s2[65];
				digest_to_string((u8int*)hash, s1);
				digest_to_string((u8int*)hash2, s2);
				printf("Error invalid hash found.\n%s %d\n%s %d\n",s1,completed,s2,c2);
				exit(0);
			}
		}
		//printf("hash verified.\n");

      //found a hash!
      return 1;
    }

  }while(nNonce < max_nonce && !work_restart[thr_id].restart);
	
  *hashes_done = nNonce - pdata[19] + 1 - *hashes_skipped;
  pdata[19] = nNonce;

  //No luck yet
  return 0;
}
Exemplo n.º 17
0
int main(int argc, char **argv) {
	int		kl, l, fd, ac;
	int		quiet = 0, hash = 0;
	char		*av, *file = (char*)0;
	FILE		*IN = (FILE*)0;
	SHA256_CTX	ctx256;
	SHA384_CTX	ctx384;
	SHA512_CTX	ctx512;
	unsigned char	buf[BUFLEN];

	SHA256_Init(&ctx256);
	SHA384_Init(&ctx384);
	SHA512_Init(&ctx512);

	/* Read data from STDIN by default */
	fd = fileno(stdin);

	ac = 1;
	while (ac < argc) {
		if (*argv[ac] == '-') {
			av = argv[ac] + 1;
			if (!strcmp(av, "q")) {
				quiet = 1;
			} else if (!strcmp(av, "256")) {
				hash |= 1;
			} else if (!strcmp(av, "384")) {
				hash |= 2;
			} else if (!strcmp(av, "512")) {
				hash |= 4;
			} else if (!strcmp(av, "ALL")) {
				hash = 7;
			} else {
				usage(argv[0], "Invalid option.");
			}
			ac++;
		} else {
			file = argv[ac++];
			if (ac != argc) {
				usage(argv[0], "Too many arguments.");
			}
			if ((IN = fopen(file, "r")) == NULL) {
				perror(argv[0]);
				exit(-1);
			}
			fd = fileno(IN);
		}
	}
	if (hash == 0)
		hash = 7;	/* Default to ALL */

	kl = 0;
	while ((l = read(fd,buf,BUFLEN)) > 0) {
		kl += l;
		SHA256_Update(&ctx256, (unsigned char*)buf, l);
		SHA384_Update(&ctx384, (unsigned char*)buf, l);
		SHA512_Update(&ctx512, (unsigned char*)buf, l);
	}
	if (file) {
		fclose(IN);
	}

	if (hash & 1) {
		SHA256_End(&ctx256, buf);
		if (!quiet)
			printf("SHA-256 (%s) = ", file);
		printf("%s\n", buf);
	}
	if (hash & 2) {
		SHA384_End(&ctx384, buf);
		if (!quiet)
			printf("SHA-384 (%s) = ", file);
		printf("%s\n", buf);
	}
	if (hash & 4) {
		SHA512_End(&ctx512, buf);
		if (!quiet)
			printf("SHA-512 (%s) = ", file);
		printf("%s\n", buf);
	}

	return 1;
}
ULONG
AnscCryptoHmacSha256Digest
    (
        PVOID                       buffer,
        ULONG                       size,
        PANSC_CRYPTO_HASH           hash,
        PANSC_CRYPTO_KEY            key
    )
{
    ULONG                           i                                    = 0;
    UCHAR                           innerPadding[ANSC_SHA256_BLOCK_SIZE] = {0};
    UCHAR                           outerPadding[ANSC_SHA256_BLOCK_SIZE] = {0};
    UCHAR                           HMACKey[ANSC_SHA256_BLOCK_SIZE]      = {0};
    UCHAR                           tempBuffer[ANSC_SHA256_OUTPUT_SIZE]  = {0};
    SHA256_CTX                      context;

    AnscTraceFlow
        ((
            "%s -- size = %d, buffer = %s, key = %02X.%02X.%02X.%02X.%02X.%02X..., hash length = %d, key length = %d, block size %d, output size %d\n", 
            __FUNCTION__,
            size,
            (char*)buffer,
            key->Value[0][0], key->Value[0][1], key->Value[0][2],
            key->Value[0][3], key->Value[0][4], key->Value[0][5],
            hash->Length,
            key->Length,
            ANSC_SHA256_BLOCK_SIZE,
            ANSC_SHA256_OUTPUT_SIZE
        ));

    /*
     * if the key is longer than the block size of hash function, we have to reset it to the output size;
     * otherwise, we have to pad zeros to the end of the key
     */
    if ( key->Length > ANSC_SHA256_BLOCK_SIZE )
    {
        SHA256_Init  (&context);
        SHA256_Update(&context, key->Value[0], key->Length);
        SHA256_Final (HMACKey,  &context);
    }
    else
    {
        for ( i = 0; i < key->Length; i++ )
        {
            HMACKey[i] = key->Value[0][i];
        }
    }

    /*
     * perform the XOR operation between key and paddings
     */
    AnscCopyMemory(innerPadding, HMACKey, ANSC_SHA256_BLOCK_SIZE);
    AnscCopyMemory(outerPadding, HMACKey, ANSC_SHA256_BLOCK_SIZE);

    for ( i = 0; i < ANSC_SHA256_BLOCK_SIZE; i++ )
    {
        innerPadding[i] ^= ANSC_HMAC_INNER_PADDING_UNIT;
        outerPadding[i] ^= ANSC_HMAC_OUTER_PADDING_UNIT;
    }

    /*
     * perform inner SHA
     */
    SHA256_Init  (&context);
    SHA256_Update(&context,    innerPadding,   ANSC_SHA256_BLOCK_SIZE);
    SHA256_Update(&context,    (PUCHAR)buffer, size);
    SHA256_Final (tempBuffer, &context);

    /*
     * perform outer SHA
     */
    SHA256_Init  (&context);
    SHA256_Update(&context,    outerPadding, ANSC_SHA256_BLOCK_SIZE);
    SHA256_Update(&context,    tempBuffer,  ANSC_SHA256_OUTPUT_SIZE);
    SHA256_Final (hash->Value, &context);

    /*
     * let's make sure our output size is bigger than the requirement; otherwise, we should pad zeros to the end
     * of the hash result data
     */
    if ( ANSC_SHA256_OUTPUT_SIZE < hash->Length )
    {
        AnscZeroMemory(&hash->Value[ANSC_SHA256_OUTPUT_SIZE], hash->Length - ANSC_SHA256_OUTPUT_SIZE);
    }

    /*
     * return control to caller
     */
    return  hash->Length;
}
Exemplo n.º 19
0
TACK_RETVAL tackOpenSSLVerifyFunc(uint8_t publicKey[TACK_PUBKEY_LENGTH], 
						uint8_t signature[TACK_SIG_LENGTH],
						uint8_t* data, uint32_t dataLen)
{
    uint8_t pubKeyBuf[TACK_PUBKEY_LENGTH + 1];
    uint8_t hashBuf[TACK_HASH_LENGTH];
    EC_KEY* ec_key = 0;
    EC_GROUP* ec_group = 0;
    EC_POINT* ec_point = 0;
    ECDSA_SIG* ecdsa_sig = 0;
    SHA256_CTX sha256_ctx;	
    TACK_RETVAL retval = TACK_ERR_CRYPTO_FUNC;
    int ret = 0;
    
    /* Prepare the public key to be passed into OpenSSL */
    pubKeyBuf[0] = 0x04;
    memcpy(pubKeyBuf+1, publicKey, TACK_PUBKEY_LENGTH);
    
    /* Create EC_KEY from raw bytes */
    if ((ec_key = EC_KEY_new_by_curve_name(OBJ_txt2nid("prime256v1"))) == 0)
        goto end;
    if ((ec_group = EC_GROUP_new_by_curve_name(OBJ_txt2nid("prime256v1"))) == 0)
        goto end;
    if ((ec_point = EC_POINT_new(ec_group)) == 0)
        goto end;		
    if (EC_POINT_oct2point(ec_group, ec_point, pubKeyBuf, 65, 0) == 0) {
        retval = TACK_ERR_BAD_PUBKEY;
        goto end;
    }
    if (EC_KEY_set_public_key(ec_key, ec_point) == 0)
        goto end;
    
    /* Create ECDSA_SIG from raw bytes */
    if ((ecdsa_sig = ECDSA_SIG_new()) == 0)
        goto end;		
    if (BN_bin2bn(signature, TACK_SIG_LENGTH/2, ecdsa_sig->r) == 0)
        goto end;
    if (BN_bin2bn(signature + TACK_SIG_LENGTH/2, TACK_SIG_LENGTH/2, ecdsa_sig->s) == 0)
        goto end;
    
    /* Hash the input data */
    SHA256_Init(&sha256_ctx);  
    SHA256_Update(&sha256_ctx, data, dataLen);   
    SHA256_Final(hashBuf, &sha256_ctx);	
    
    /* Verify the signature */
    ret = ECDSA_do_verify(hashBuf, TACK_HASH_LENGTH, ecdsa_sig, ec_key);
    if (ret == 1)
        retval = TACK_OK;
    else if (ret == 0)
        retval = TACK_ERR_BAD_SIGNATURE;
    else if (ret == -1)
        retval = TACK_ERR_CRYPTO_FUNC;
    
end:
    if (ec_key)
        EC_KEY_free(ec_key);
    if (ec_group)
        EC_GROUP_free(ec_group);
    if (ec_point)
        EC_POINT_free(ec_point);
    if (ecdsa_sig)
        ECDSA_SIG_free(ecdsa_sig);
    
    return(retval);
}
Exemplo n.º 20
0
Arquivo: hash.c Projeto: MarginC/kame
/* initialise the hash */
void
yarrow_hash_init(struct yarrowhash *context)
{
	SHA256_Init(&context->sha);
}
Exemplo n.º 21
0
void* initializeSha256Context(void* ctx) 
{
    SHA256_CTX* hd = (SHA256_CTX*)ctx;
    SHA256_Init(hd);
    return (void*)hd;
}
Exemplo n.º 22
0
RTDECL(void) RTSha256Init(PRTSHA256CONTEXT pCtx)
{
    SHA256_Init(&pCtx->Private);
}
Exemplo n.º 23
0
static char *
crypt_sha256_r(const char *key, const char *salt, char *buffer, int buflen)
{
	u_long srounds;
	int n;
	uint8_t alt_result[32], temp_result[32];
	SHA256_CTX ctx, alt_ctx;
	size_t salt_len, key_len, cnt, rounds;
	char *cp, *copied_key, *copied_salt, *p_bytes, *s_bytes, *endp;
	const char *num;
	bool rounds_custom;

	copied_key = NULL;
	copied_salt = NULL;

	/* Default number of rounds. */
	rounds = ROUNDS_DEFAULT;
	rounds_custom = false;

	/* Find beginning of salt string. The prefix should normally always
	 * be present. Just in case it is not. */
	if (strncmp(sha256_salt_prefix, salt, sizeof(sha256_salt_prefix) - 1) == 0)
		/* Skip salt prefix. */
		salt += sizeof(sha256_salt_prefix) - 1;

	if (strncmp(salt, sha256_rounds_prefix, sizeof(sha256_rounds_prefix) - 1)
	    == 0) {
		num = salt + sizeof(sha256_rounds_prefix) - 1;
		srounds = strtoul(num, &endp, 10);

		if (*endp == '$') {
			salt = endp + 1;
			rounds = MAX(ROUNDS_MIN, MIN(srounds, ROUNDS_MAX));
			rounds_custom = true;
		}
	}

	salt_len = MIN(strcspn(salt, "$"), SALT_LEN_MAX);
	key_len = strlen(key);

	/* Prepare for the real work. */
	SHA256_Init(&ctx);

	/* Add the key string. */
	SHA256_Update(&ctx, key, key_len);

	/* The last part is the salt string. This must be at most 8
	 * characters and it ends at the first `$' character (for
	 * compatibility with existing implementations). */
	SHA256_Update(&ctx, salt, salt_len);

	/* Compute alternate SHA256 sum with input KEY, SALT, and KEY. The
	 * final result will be added to the first context. */
	SHA256_Init(&alt_ctx);

	/* Add key. */
	SHA256_Update(&alt_ctx, key, key_len);

	/* Add salt. */
	SHA256_Update(&alt_ctx, salt, salt_len);

	/* Add key again. */
	SHA256_Update(&alt_ctx, key, key_len);

	/* Now get result of this (32 bytes) and add it to the other context. */
	SHA256_Final(alt_result, &alt_ctx);

	/* Add for any character in the key one byte of the alternate sum. */
	for (cnt = key_len; cnt > 32; cnt -= 32)
		SHA256_Update(&ctx, alt_result, 32);
	SHA256_Update(&ctx, alt_result, cnt);

	/* Take the binary representation of the length of the key and for
	 * every 1 add the alternate sum, for every 0 the key. */
	for (cnt = key_len; cnt > 0; cnt >>= 1)
		if ((cnt & 1) != 0)
			SHA256_Update(&ctx, alt_result, 32);
		else
			SHA256_Update(&ctx, key, key_len);

	/* Create intermediate result. */
	SHA256_Final(alt_result, &ctx);

	/* Start computation of P byte sequence. */
	SHA256_Init(&alt_ctx);

	/* For every character in the password add the entire password. */
	for (cnt = 0; cnt < key_len; ++cnt)
		SHA256_Update(&alt_ctx, key, key_len);

	/* Finish the digest. */
	SHA256_Final(temp_result, &alt_ctx);

	/* Create byte sequence P. */
	cp = p_bytes = alloca(key_len);
	for (cnt = key_len; cnt >= 32; cnt -= 32) {
		memcpy(cp, temp_result, 32);
		cp += 32;
	}
	memcpy(cp, temp_result, cnt);

	/* Start computation of S byte sequence. */
	SHA256_Init(&alt_ctx);

	/* For every character in the password add the entire password. */
	for (cnt = 0; cnt < 16 + alt_result[0]; ++cnt)
		SHA256_Update(&alt_ctx, salt, salt_len);

	/* Finish the digest. */
	SHA256_Final(temp_result, &alt_ctx);

	/* Create byte sequence S. */
	cp = s_bytes = alloca(salt_len);
	for (cnt = salt_len; cnt >= 32; cnt -= 32) {
		memcpy(cp, temp_result, 32);
		cp += 32;
	}
	memcpy(cp, temp_result, cnt);

	/* Repeatedly run the collected hash value through SHA256 to burn CPU
	 * cycles. */
	for (cnt = 0; cnt < rounds; ++cnt) {
		/* New context. */
		SHA256_Init(&ctx);

		/* Add key or last result. */
		if ((cnt & 1) != 0)
			SHA256_Update(&ctx, p_bytes, key_len);
		else
			SHA256_Update(&ctx, alt_result, 32);

		/* Add salt for numbers not divisible by 3. */
		if (cnt % 3 != 0)
			SHA256_Update(&ctx, s_bytes, salt_len);

		/* Add key for numbers not divisible by 7. */
		if (cnt % 7 != 0)
			SHA256_Update(&ctx, p_bytes, key_len);

		/* Add key or last result. */
		if ((cnt & 1) != 0)
			SHA256_Update(&ctx, alt_result, 32);
		else
			SHA256_Update(&ctx, p_bytes, key_len);

		/* Create intermediate result. */
		SHA256_Final(alt_result, &ctx);
	}

	/* Now we can construct the result string. It consists of three
	 * parts. */
	cp = stpncpy(buffer, sha256_salt_prefix, MAX(0, buflen));
	buflen -= sizeof(sha256_salt_prefix) - 1;

	if (rounds_custom) {
		n = snprintf(cp, MAX(0, buflen), "%s%zu$",
			 sha256_rounds_prefix, rounds);

		cp += n;
		buflen -= n;
	}

	cp = stpncpy(cp, salt, MIN((size_t)MAX(0, buflen), salt_len));
	buflen -= MIN((size_t)MAX(0, buflen), salt_len);

	if (buflen > 0) {
		*cp++ = '$';
		--buflen;
	}

	b64_from_24bit(alt_result[0], alt_result[10], alt_result[20], 4, &buflen, &cp);
	b64_from_24bit(alt_result[21], alt_result[1], alt_result[11], 4, &buflen, &cp);
	b64_from_24bit(alt_result[12], alt_result[22], alt_result[2], 4, &buflen, &cp);
	b64_from_24bit(alt_result[3], alt_result[13], alt_result[23], 4, &buflen, &cp);
	b64_from_24bit(alt_result[24], alt_result[4], alt_result[14], 4, &buflen, &cp);
	b64_from_24bit(alt_result[15], alt_result[25], alt_result[5], 4, &buflen, &cp);
	b64_from_24bit(alt_result[6], alt_result[16], alt_result[26], 4, &buflen, &cp);
	b64_from_24bit(alt_result[27], alt_result[7], alt_result[17], 4, &buflen, &cp);
	b64_from_24bit(alt_result[18], alt_result[28], alt_result[8], 4, &buflen, &cp);
	b64_from_24bit(alt_result[9], alt_result[19], alt_result[29], 4, &buflen, &cp);
	b64_from_24bit(0, alt_result[31], alt_result[30], 3, &buflen, &cp);
	if (buflen <= 0) {
		errno = ERANGE;
		buffer = NULL;
	}
	else
		*cp = '\0';	/* Terminate the string. */

	/* Clear the buffer for the intermediate result so that people
	 * attaching to processes or reading core dumps cannot get any
	 * information. We do it in this way to clear correct_words[] inside
	 * the SHA256 implementation as well. */
	SHA256_Init(&ctx);
	SHA256_Final(alt_result, &ctx);
	memset(temp_result, '\0', sizeof(temp_result));
	memset(p_bytes, '\0', key_len);
	memset(s_bytes, '\0', salt_len);
	memset(&ctx, '\0', sizeof(ctx));
	memset(&alt_ctx, '\0', sizeof(alt_ctx));
	if (copied_key != NULL)
		memset(copied_key, '\0', key_len);
	if (copied_salt != NULL)
		memset(copied_salt, '\0', salt_len);

	return buffer;
}
Exemplo n.º 24
0
AnsiString HashCreator::_GetHashRaw(const unsigned char *input, int inputLength, HashCreator::RequestedEncoding encoding)
{
    int digestLength = 0;

    switch (_hashType)
    {
    case SHA1:
        digestLength = SHA_DIGEST_LENGTH;
        break;
    case SHA256:
        digestLength = SHA256_DIGEST_LENGTH;
        break;
    case MD5:
        digestLength = MD5_DIGEST_LENGTH;
        break;
    }

    unsigned char *results = new unsigned char[digestLength];

    switch (_hashType)
    {
    case SHA1:
    {
        SHA_CTX context;
        SHA1_Init(&context);
        SHA1_Update(&context, input, inputLength);
        SHA1_Final(results, &context);
        break;
    }
    case MD5:
    {
        MD5_CTX context;
        MD5_Init(&context);
        MD5_Update(&context, input, inputLength);
        MD5_Final(results, &context);
        break;
    }
    case SHA256:
    {
        SHA256_CTX context;
        SHA256_Init(&context);
        SHA256_Update(&context, input, inputLength);
        SHA256_Final(results, &context);
        break;
    }

    }


    HM::String retVal;
    if (encoding == hex)
    {
        char *s = new char[digestLength*2+1];

        for (int i=0; i<digestLength; i++)
            sprintf(s+i*2, "%02x", results[i]);

        s[digestLength*2]='\0';

        retVal = s;

        delete [] s;
    }
    else if (encoding == base64)
    {
        MimeCodeBase64 encoder;
        encoder.SetInput((const char*) results, digestLength, true);

        AnsiString sEncodedValue;
        encoder.GetOutput(sEncodedValue);

        retVal = sEncodedValue;
        retVal = retVal.Mid(0, retVal.GetLength()-2);
    }

    delete [] results;

    return retVal;
}
Exemplo n.º 25
0
	void HashSHA256::Begin()
	{
		SHA256_Init(m_state);
	}
Exemplo n.º 26
0
static enum req_fsm_nxt
cnt_recv(struct worker *wrk, struct req *req)
{
	unsigned recv_handling;
	struct SHA256Context sha256ctx;
	char *xff;

	CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
	CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
	CHECK_OBJ_NOTNULL(req->vcl, VCL_CONF_MAGIC);
	AZ(req->objcore);
	AZ(req->obj);
	AZ(req->objcore);

	AZ(isnan(req->t_first));
	AZ(isnan(req->t_prev));
	AZ(isnan(req->t_req));

	VSLb(req->vsl, SLT_ReqStart, "%s %s",
	    req->sp->client_addr_str, req->sp->client_port_str);

	http_VSL_log(req->http);

	if (req->err_code) {
		req->req_step = R_STP_SYNTH;
		return (REQ_FSM_MORE);
	}

	/* By default we use the first backend */
	AZ(req->director_hint);
	req->director_hint = req->vcl->director[0];
	AN(req->director_hint);

	req->d_ttl = -1;
	req->disable_esi = 0;
	req->hash_always_miss = 0;
	req->hash_ignore_busy = 0;
	req->client_identity = NULL;
	if (req->restarts == 0) {
		if (http_GetHdr(req->http, H_X_Forwarded_For, &xff)) {
			http_Unset(req->http, H_X_Forwarded_For);
			http_PrintfHeader(req->http, "X-Forwarded-For: %s, %s", xff,
					  req->sp->client_addr_str);
		} else {
			http_PrintfHeader(req->http, "X-Forwarded-For: %s",
					  req->sp->client_addr_str);
		}
	}

	http_CollectHdr(req->http, H_Cache_Control);

	VCL_recv_method(req->vcl, wrk, req, NULL, req->http->ws);

	/* Attempts to cache req.body may fail */
	if (req->req_body_status == REQ_BODY_FAIL) {
		return (REQ_FSM_DONE);
	}
	recv_handling = wrk->handling;

	/* We wash the A-E header here for the sake of VRY */
	if (cache_param->http_gzip_support &&
	     (recv_handling != VCL_RET_PIPE) &&
	     (recv_handling != VCL_RET_PASS)) {
		if (RFC2616_Req_Gzip(req->http)) {
			http_ForceHeader(req->http, H_Accept_Encoding, "gzip");
		} else {
			http_Unset(req->http, H_Accept_Encoding);
		}
	}

	req->sha256ctx = &sha256ctx;	/* so HSH_AddString() can find it */
	SHA256_Init(req->sha256ctx);
	VCL_hash_method(req->vcl, wrk, req, NULL, req->http->ws);
	assert(wrk->handling == VCL_RET_LOOKUP);
	SHA256_Final(req->digest, req->sha256ctx);
	req->sha256ctx = NULL;

	if (!strcmp(req->http->hd[HTTP_HDR_METHOD].b, "HEAD"))
		req->wantbody = 0;
	else
		req->wantbody = 1;

	switch(recv_handling) {
	case VCL_RET_PURGE:
		req->req_step = R_STP_PURGE;
		return (REQ_FSM_MORE);
	case VCL_RET_HASH:
		req->req_step = R_STP_LOOKUP;
		return (REQ_FSM_MORE);
	case VCL_RET_PIPE:
		if (req->esi_level == 0) {
			req->req_step = R_STP_PIPE;
			return (REQ_FSM_MORE);
		}
		VSLb(req->vsl, SLT_VCL_Error,
		    "vcl_recv{} returns pipe for ESI included object."
		    "  Doing pass.");
		req->req_step = R_STP_PASS;
		return (REQ_FSM_DONE);
	case VCL_RET_PASS:
		req->req_step = R_STP_PASS;
		return (REQ_FSM_MORE);
	case VCL_RET_SYNTH:
		req->req_step = R_STP_SYNTH;
		return (REQ_FSM_MORE);
	default:
		WRONG("Illegal return from vcl_recv{}");
	}
}
Exemplo n.º 27
0
//--------------------------------------------------
// Calculates files SHA1 digest
// szFileName - file name
// nDigestType - digest type. Supports only SHA1 (0)
// pDigestBuf - buffer to store the digest
// nDigestLen - buffer size, must be at least 20
//				will be updated by actual digest length
// lFileLen - pointer to a buffer where to store the file length
// returns error code or ERR_OK for success
//--------------------------------------------------
EXP_OPTION int calculateFileDigest(const char* szFileName, int nDigestType,
                                   byte* pDigestBuf, int* nDigestLen, long* lFileLen)
{
    int err = ERR_OK;
    byte buf[FILE_BUFSIZE];
    int i;
    FILE *f = NULL;

    RETURN_IF_NULL_PARAM(szFileName);
    RETURN_IF_NULL_PARAM(pDigestBuf);
    RETURN_IF_NULL_PARAM(nDigestLen);
    RETURN_IF_NULL_PARAM(lFileLen);

    memset(pDigestBuf, 0, *nDigestLen);
    if(nDigestType == DIGEST_SHA1) {
        if(*nDigestLen >= SHA_DIGEST_LENGTH) {
            SHA_CTX ctx;
            *nDigestLen = SHA_DIGEST_LENGTH;
            if((f = fopen(szFileName,"rb")) != NULL) {
                //byte *data,*temp_data;
                SHA1_Init(&ctx);
                *lFileLen = 0;
                for (;;) {
                    i = fread(buf, sizeof(char), FILE_BUFSIZE, f);
                    if (i <= 0) break;
                    *lFileLen += i;
                    SHA1_Update(&ctx, buf, (unsigned long)i);
                }
                SHA1_Final(pDigestBuf,&ctx);
                fclose(f);
            } // if - fopen
            else
                err = ERR_FILE_READ;
        }
        else
            err = ERR_DIGEST_LEN;
    } //AM 22.04.08
    else if(nDigestType == DIGEST_SHA256) {
        if(*nDigestLen >= SHA_DIGEST_LENGTH) {
            SHA256_CTX ctx;
            *nDigestLen = SHA256_DIGEST_LENGTH;
            if((f = fopen(szFileName,"rb")) != NULL) {
                //byte *data,*temp_data;
                SHA256_Init(&ctx);
                *lFileLen = 0;
                for (;;) {
                    i = fread(buf, sizeof(char), FILE_BUFSIZE, f);
                    if (i <= 0) break;
                    *lFileLen += i;
                    SHA256_Update(&ctx, buf, (unsigned long)i);
                }
                SHA256_Final(pDigestBuf,&ctx);
                fclose(f);
            } // if - fopen
            else
                err = ERR_FILE_READ;
        }
        else
            err = ERR_DIGEST_LEN;
    }
    else
        err = ERR_UNSUPPORTED_DIGEST;
    if (err != ERR_OK) SET_LAST_ERROR(err);
    return err;
}
Exemplo n.º 28
0
void init_skein_ctx()
{
        sph_skein512_init(&skein_ctx.skein);
        SHA256_Init(&skein_ctx.sha256);
}
Exemplo n.º 29
0
/* Initialise the hash */
void
randomdev_hash_init(struct randomdev_hash *context)
{

	SHA256_Init(&context->sha);
}
Exemplo n.º 30
0
int EVP_tls_cbc_digest_record(const EVP_MD *md, uint8_t *md_out,
                              size_t *md_out_size, const uint8_t header[13],
                              const uint8_t *data, size_t data_plus_mac_size,
                              size_t data_plus_mac_plus_padding_size,
                              const uint8_t *mac_secret,
                              unsigned mac_secret_length) {
  HASH_CTX md_state;
  void (*md_final_raw)(HASH_CTX *ctx, uint8_t *md_out);
  void (*md_transform)(HASH_CTX *ctx, const uint8_t *block);
  unsigned md_size, md_block_size = 64;
  // md_length_size is the number of bytes in the length field that terminates
  // the hash.
  unsigned md_length_size = 8;

  // Bound the acceptable input so we can forget about many possible overflows
  // later in this function. This is redundant with the record size limits in
  // TLS.
  if (data_plus_mac_plus_padding_size >= 1024 * 1024) {
    assert(0);
    return 0;
  }

  switch (EVP_MD_type(md)) {
    case NID_sha1:
      SHA1_Init(&md_state.sha1);
      md_final_raw = tls1_sha1_final_raw;
      md_transform = tls1_sha1_transform;
      md_size = SHA_DIGEST_LENGTH;
      break;

    case NID_sha256:
      SHA256_Init(&md_state.sha256);
      md_final_raw = tls1_sha256_final_raw;
      md_transform = tls1_sha256_transform;
      md_size = SHA256_DIGEST_LENGTH;
      break;

    case NID_sha384:
      SHA384_Init(&md_state.sha512);
      md_final_raw = tls1_sha512_final_raw;
      md_transform = tls1_sha512_transform;
      md_size = SHA384_DIGEST_LENGTH;
      md_block_size = 128;
      md_length_size = 16;
      break;

    default:
      // EVP_tls_cbc_record_digest_supported should have been called first to
      // check that the hash function is supported.
      assert(0);
      *md_out_size = 0;
      return 0;
  }

  assert(md_length_size <= MAX_HASH_BIT_COUNT_BYTES);
  assert(md_block_size <= MAX_HASH_BLOCK_SIZE);
  assert(md_size <= EVP_MAX_MD_SIZE);

  static const size_t kHeaderLength = 13;

  // kVarianceBlocks is the number of blocks of the hash that we have to
  // calculate in constant time because they could be altered by the
  // padding value.
  //
  // TLSv1 has MACs up to 48 bytes long (SHA-384) and the padding is not
  // required to be minimal. Therefore we say that the final six blocks
  // can vary based on the padding.
  static const size_t kVarianceBlocks = 6;

  // From now on we're dealing with the MAC, which conceptually has 13
  // bytes of `header' before the start of the data.
  size_t len = data_plus_mac_plus_padding_size + kHeaderLength;
  // max_mac_bytes contains the maximum bytes of bytes in the MAC, including
  // |header|, assuming that there's no padding.
  size_t max_mac_bytes = len - md_size - 1;
  // num_blocks is the maximum number of hash blocks.
  size_t num_blocks =
      (max_mac_bytes + 1 + md_length_size + md_block_size - 1) / md_block_size;
  // In order to calculate the MAC in constant time we have to handle
  // the final blocks specially because the padding value could cause the
  // end to appear somewhere in the final |kVarianceBlocks| blocks and we
  // can't leak where. However, |num_starting_blocks| worth of data can
  // be hashed right away because no padding value can affect whether
  // they are plaintext.
  size_t num_starting_blocks = 0;
  // k is the starting byte offset into the conceptual header||data where
  // we start processing.
  size_t k = 0;
  // mac_end_offset is the index just past the end of the data to be
  // MACed.
  size_t mac_end_offset = data_plus_mac_size + kHeaderLength - md_size;
  // c is the index of the 0x80 byte in the final hash block that
  // contains application data.
  size_t c = mac_end_offset % md_block_size;
  // index_a is the hash block number that contains the 0x80 terminating
  // value.
  size_t index_a = mac_end_offset / md_block_size;
  // index_b is the hash block number that contains the 64-bit hash
  // length, in bits.
  size_t index_b = (mac_end_offset + md_length_size) / md_block_size;

  if (num_blocks > kVarianceBlocks) {
    num_starting_blocks = num_blocks - kVarianceBlocks;
    k = md_block_size * num_starting_blocks;
  }

  // bits is the hash-length in bits. It includes the additional hash
  // block for the masked HMAC key.
  size_t bits = 8 * mac_end_offset;  // at most 18 bits to represent

  // Compute the initial HMAC block.
  bits += 8 * md_block_size;
  // hmac_pad is the masked HMAC key.
  uint8_t hmac_pad[MAX_HASH_BLOCK_SIZE];
  OPENSSL_memset(hmac_pad, 0, md_block_size);
  assert(mac_secret_length <= sizeof(hmac_pad));
  OPENSSL_memcpy(hmac_pad, mac_secret, mac_secret_length);
  for (size_t i = 0; i < md_block_size; i++) {
    hmac_pad[i] ^= 0x36;
  }

  md_transform(&md_state, hmac_pad);

  // The length check means |bits| fits in four bytes.
  uint8_t length_bytes[MAX_HASH_BIT_COUNT_BYTES];
  OPENSSL_memset(length_bytes, 0, md_length_size - 4);
  length_bytes[md_length_size - 4] = (uint8_t)(bits >> 24);
  length_bytes[md_length_size - 3] = (uint8_t)(bits >> 16);
  length_bytes[md_length_size - 2] = (uint8_t)(bits >> 8);
  length_bytes[md_length_size - 1] = (uint8_t)bits;

  if (k > 0) {
    // k is a multiple of md_block_size.
    uint8_t first_block[MAX_HASH_BLOCK_SIZE];
    OPENSSL_memcpy(first_block, header, 13);
    OPENSSL_memcpy(first_block + 13, data, md_block_size - 13);
    md_transform(&md_state, first_block);
    for (size_t i = 1; i < k / md_block_size; i++) {
      md_transform(&md_state, data + md_block_size * i - 13);
    }
  }

  uint8_t mac_out[EVP_MAX_MD_SIZE];
  OPENSSL_memset(mac_out, 0, sizeof(mac_out));

  // We now process the final hash blocks. For each block, we construct
  // it in constant time. If the |i==index_a| then we'll include the 0x80
  // bytes and zero pad etc. For each block we selectively copy it, in
  // constant time, to |mac_out|.
  for (size_t i = num_starting_blocks;
       i <= num_starting_blocks + kVarianceBlocks; i++) {
    uint8_t block[MAX_HASH_BLOCK_SIZE];
    uint8_t is_block_a = constant_time_eq_8(i, index_a);
    uint8_t is_block_b = constant_time_eq_8(i, index_b);
    for (size_t j = 0; j < md_block_size; j++) {
      uint8_t b = 0;
      if (k < kHeaderLength) {
        b = header[k];
      } else if (k < data_plus_mac_plus_padding_size + kHeaderLength) {
        b = data[k - kHeaderLength];
      }
      k++;

      uint8_t is_past_c = is_block_a & constant_time_ge_8(j, c);
      uint8_t is_past_cp1 = is_block_a & constant_time_ge_8(j, c + 1);
      // If this is the block containing the end of the
      // application data, and we are at the offset for the
      // 0x80 value, then overwrite b with 0x80.
      b = constant_time_select_8(is_past_c, 0x80, b);
      // If this the the block containing the end of the
      // application data and we're past the 0x80 value then
      // just write zero.
      b = b & ~is_past_cp1;
      // If this is index_b (the final block), but not
      // index_a (the end of the data), then the 64-bit
      // length didn't fit into index_a and we're having to
      // add an extra block of zeros.
      b &= ~is_block_b | is_block_a;

      // The final bytes of one of the blocks contains the
      // length.
      if (j >= md_block_size - md_length_size) {
        // If this is index_b, write a length byte.
        b = constant_time_select_8(
            is_block_b, length_bytes[j - (md_block_size - md_length_size)], b);
      }
      block[j] = b;
    }

    md_transform(&md_state, block);
    md_final_raw(&md_state, block);
    // If this is index_b, copy the hash value to |mac_out|.
    for (size_t j = 0; j < md_size; j++) {
      mac_out[j] |= block[j] & is_block_b;
    }
  }

  EVP_MD_CTX md_ctx;
  EVP_MD_CTX_init(&md_ctx);
  if (!EVP_DigestInit_ex(&md_ctx, md, NULL /* engine */)) {
    EVP_MD_CTX_cleanup(&md_ctx);
    return 0;
  }

  // Complete the HMAC in the standard manner.
  for (size_t i = 0; i < md_block_size; i++) {
    hmac_pad[i] ^= 0x6a;
  }

  EVP_DigestUpdate(&md_ctx, hmac_pad, md_block_size);
  EVP_DigestUpdate(&md_ctx, mac_out, md_size);
  unsigned md_out_size_u;
  EVP_DigestFinal(&md_ctx, md_out, &md_out_size_u);
  *md_out_size = md_out_size_u;
  EVP_MD_CTX_cleanup(&md_ctx);

  return 1;
}