/* * Verify signature - finalize SHA1 operation and reapply SHA1, then * compare to the supplied digest. */ isc_boolean_t isc_hmacsha1_verify(isc_hmacsha1_t *ctx, unsigned char *digest, size_t len) { unsigned char newdigest[ISC_SHA1_DIGESTLENGTH]; REQUIRE(len <= ISC_SHA1_DIGESTLENGTH); isc_hmacsha1_sign(ctx, newdigest, ISC_SHA1_DIGESTLENGTH); return (ISC_TF(memcmp(digest, newdigest, len) == 0)); }
static isc_result_t sign(unsigned char *data, unsigned int length, unsigned char *hmac, isc_uint32_t algorithm, isccc_region_t *secret) { union { isc_hmacmd5_t hmd5; isc_hmacsha1_t hsha; isc_hmacsha224_t h224; isc_hmacsha256_t h256; isc_hmacsha384_t h384; isc_hmacsha512_t h512; } ctx; isc_result_t result; isccc_region_t source, target; unsigned char digest[ISC_SHA512_DIGESTLENGTH]; unsigned char digestb64[HSHA_LENGTH + 4]; source.rstart = digest; switch (algorithm) { case ISCCC_ALG_HMACMD5: isc_hmacmd5_init(&ctx.hmd5, secret->rstart, REGION_SIZE(*secret)); isc_hmacmd5_update(&ctx.hmd5, data, length); isc_hmacmd5_sign(&ctx.hmd5, digest); source.rend = digest + ISC_MD5_DIGESTLENGTH; break; case ISCCC_ALG_HMACSHA1: isc_hmacsha1_init(&ctx.hsha, secret->rstart, REGION_SIZE(*secret)); isc_hmacsha1_update(&ctx.hsha, data, length); isc_hmacsha1_sign(&ctx.hsha, digest, ISC_SHA1_DIGESTLENGTH); source.rend = digest + ISC_SHA1_DIGESTLENGTH; break; case ISCCC_ALG_HMACSHA224: isc_hmacsha224_init(&ctx.h224, secret->rstart, REGION_SIZE(*secret)); isc_hmacsha224_update(&ctx.h224, data, length); isc_hmacsha224_sign(&ctx.h224, digest, ISC_SHA224_DIGESTLENGTH); source.rend = digest + ISC_SHA224_DIGESTLENGTH; break; case ISCCC_ALG_HMACSHA256: isc_hmacsha256_init(&ctx.h256, secret->rstart, REGION_SIZE(*secret)); isc_hmacsha256_update(&ctx.h256, data, length); isc_hmacsha256_sign(&ctx.h256, digest, ISC_SHA256_DIGESTLENGTH); source.rend = digest + ISC_SHA256_DIGESTLENGTH; break; case ISCCC_ALG_HMACSHA384: isc_hmacsha384_init(&ctx.h384, secret->rstart, REGION_SIZE(*secret)); isc_hmacsha384_update(&ctx.h384, data, length); isc_hmacsha384_sign(&ctx.h384, digest, ISC_SHA384_DIGESTLENGTH); source.rend = digest + ISC_SHA384_DIGESTLENGTH; break; case ISCCC_ALG_HMACSHA512: isc_hmacsha512_init(&ctx.h512, secret->rstart, REGION_SIZE(*secret)); isc_hmacsha512_update(&ctx.h512, data, length); isc_hmacsha512_sign(&ctx.h512, digest, ISC_SHA512_DIGESTLENGTH); source.rend = digest + ISC_SHA512_DIGESTLENGTH; break; default: return (ISC_R_FAILURE); } memset(digestb64, 0, sizeof(digestb64)); target.rstart = digestb64; target.rend = digestb64 + sizeof(digestb64); result = isccc_base64_encode(&source, 64, "", &target); if (result != ISC_R_SUCCESS) return (result); if (algorithm == ISCCC_ALG_HMACMD5) PUT_MEM(digestb64, HMD5_LENGTH, hmac); else PUT_MEM(digestb64, HSHA_LENGTH, hmac); return (ISC_R_SUCCESS); }
static isc_result_t verify(isccc_sexpr_t *alist, unsigned char *data, unsigned int length, isc_uint32_t algorithm, isccc_region_t *secret) { union { isc_hmacmd5_t hmd5; isc_hmacsha1_t hsha; isc_hmacsha224_t h224; isc_hmacsha256_t h256; isc_hmacsha384_t h384; isc_hmacsha512_t h512; } ctx; isccc_region_t source; isccc_region_t target; isc_result_t result; isccc_sexpr_t *_auth, *hmac; unsigned char digest[ISC_SHA512_DIGESTLENGTH]; unsigned char digestb64[HSHA_LENGTH * 4]; /* * Extract digest. */ _auth = isccc_alist_lookup(alist, "_auth"); if (!isccc_alist_alistp(_auth)) return (ISC_R_FAILURE); if (algorithm == ISCCC_ALG_HMACMD5) hmac = isccc_alist_lookup(_auth, "hmd5"); else hmac = isccc_alist_lookup(_auth, "hsha"); if (!isccc_sexpr_binaryp(hmac)) return (ISC_R_FAILURE); /* * Compute digest. */ source.rstart = digest; target.rstart = digestb64; switch (algorithm) { case ISCCC_ALG_HMACMD5: isc_hmacmd5_init(&ctx.hmd5, secret->rstart, REGION_SIZE(*secret)); isc_hmacmd5_update(&ctx.hmd5, data, length); isc_hmacmd5_sign(&ctx.hmd5, digest); source.rend = digest + ISC_MD5_DIGESTLENGTH; break; case ISCCC_ALG_HMACSHA1: isc_hmacsha1_init(&ctx.hsha, secret->rstart, REGION_SIZE(*secret)); isc_hmacsha1_update(&ctx.hsha, data, length); isc_hmacsha1_sign(&ctx.hsha, digest, ISC_SHA1_DIGESTLENGTH); source.rend = digest + ISC_SHA1_DIGESTLENGTH; break; case ISCCC_ALG_HMACSHA224: isc_hmacsha224_init(&ctx.h224, secret->rstart, REGION_SIZE(*secret)); isc_hmacsha224_update(&ctx.h224, data, length); isc_hmacsha224_sign(&ctx.h224, digest, ISC_SHA224_DIGESTLENGTH); source.rend = digest + ISC_SHA224_DIGESTLENGTH; break; case ISCCC_ALG_HMACSHA256: isc_hmacsha256_init(&ctx.h256, secret->rstart, REGION_SIZE(*secret)); isc_hmacsha256_update(&ctx.h256, data, length); isc_hmacsha256_sign(&ctx.h256, digest, ISC_SHA256_DIGESTLENGTH); source.rend = digest + ISC_SHA256_DIGESTLENGTH; break; case ISCCC_ALG_HMACSHA384: isc_hmacsha384_init(&ctx.h384, secret->rstart, REGION_SIZE(*secret)); isc_hmacsha384_update(&ctx.h384, data, length); isc_hmacsha384_sign(&ctx.h384, digest, ISC_SHA384_DIGESTLENGTH); source.rend = digest + ISC_SHA384_DIGESTLENGTH; break; case ISCCC_ALG_HMACSHA512: isc_hmacsha512_init(&ctx.h512, secret->rstart, REGION_SIZE(*secret)); isc_hmacsha512_update(&ctx.h512, data, length); isc_hmacsha512_sign(&ctx.h512, digest, ISC_SHA512_DIGESTLENGTH); source.rend = digest + ISC_SHA512_DIGESTLENGTH; break; default: return (ISC_R_FAILURE); } target.rstart = digestb64; target.rend = digestb64 + sizeof(digestb64); memset(digestb64, 0, sizeof(digestb64)); result = isccc_base64_encode(&source, 64, "", &target); if (result != ISC_R_SUCCESS) return (result); /* * Verify. */ if (algorithm == ISCCC_ALG_HMACMD5) { unsigned char *value; value = (unsigned char *) isccc_sexpr_tostring(hmac); if (!isc_safe_memequal(value, digestb64, HMD5_LENGTH)) return (ISCCC_R_BADAUTH); } else { unsigned char *value; isc_uint32_t valalg; value = (unsigned char *) isccc_sexpr_tostring(hmac); GET8(valalg, value); if ((valalg != algorithm) || !isc_safe_memequal(value, digestb64, HSHA_LENGTH)) return (ISCCC_R_BADAUTH); } return (ISC_R_SUCCESS); }
int main(int argc, char **argv) { isc_sha1_t sha1; isc_sha224_t sha224; isc_md5_t md5; isc_hmacmd5_t hmacmd5; isc_hmacsha1_t hmacsha1; isc_hmacsha224_t hmacsha224; isc_hmacsha256_t hmacsha256; isc_hmacsha384_t hmacsha384; isc_hmacsha512_t hmacsha512; unsigned char digest[ISC_SHA512_DIGESTLENGTH]; unsigned char buffer[1024]; const char *s; unsigned char key[20]; UNUSED(argc); UNUSED(argv); s = "abc"; isc_sha1_init(&sha1); memcpy(buffer, s, strlen(s)); isc_sha1_update(&sha1, buffer, strlen(s)); isc_sha1_final(&sha1, digest); print_digest(s, "sha1", digest, ISC_SHA1_DIGESTLENGTH/4); s = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"; isc_sha1_init(&sha1); memcpy(buffer, s, strlen(s)); isc_sha1_update(&sha1, buffer, strlen(s)); isc_sha1_final(&sha1, digest); print_digest(s, "sha1", digest, ISC_SHA1_DIGESTLENGTH/4); s = "abc"; isc_sha224_init(&sha224); memcpy(buffer, s, strlen(s)); isc_sha224_update(&sha224, buffer, strlen(s)); isc_sha224_final(digest, &sha224); print_digest(s, "sha224", digest, ISC_SHA224_DIGESTLENGTH/4); s = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"; isc_sha224_init(&sha224); memcpy(buffer, s, strlen(s)); isc_sha224_update(&sha224, buffer, strlen(s)); isc_sha224_final(digest, &sha224); print_digest(s, "sha224", digest, ISC_SHA224_DIGESTLENGTH/4); s = "abc"; isc_md5_init(&md5); memcpy(buffer, s, strlen(s)); isc_md5_update(&md5, buffer, strlen(s)); isc_md5_final(&md5, digest); print_digest(s, "md5", digest, 4); /* * The 3 HMAC-MD5 examples from RFC2104 */ s = "Hi There"; memset(key, 0x0b, 16); isc_hmacmd5_init(&hmacmd5, key, 16); memcpy(buffer, s, strlen(s)); isc_hmacmd5_update(&hmacmd5, buffer, strlen(s)); isc_hmacmd5_sign(&hmacmd5, digest); print_digest(s, "hmacmd5", digest, 4); s = "what do ya want for nothing?"; strcpy((char *)key, "Jefe"); isc_hmacmd5_init(&hmacmd5, key, 4); memcpy(buffer, s, strlen(s)); isc_hmacmd5_update(&hmacmd5, buffer, strlen(s)); isc_hmacmd5_sign(&hmacmd5, digest); print_digest(s, "hmacmd5", digest, 4); s = "\335\335\335\335\335\335\335\335\335\335" "\335\335\335\335\335\335\335\335\335\335" "\335\335\335\335\335\335\335\335\335\335" "\335\335\335\335\335\335\335\335\335\335" "\335\335\335\335\335\335\335\335\335\335"; memset(key, 0xaa, 16); isc_hmacmd5_init(&hmacmd5, key, 16); memcpy(buffer, s, strlen(s)); isc_hmacmd5_update(&hmacmd5, buffer, strlen(s)); isc_hmacmd5_sign(&hmacmd5, digest); print_digest(s, "hmacmd5", digest, 4); /* * The 3 HMAC-SHA1 examples from RFC4634. */ s = "Hi There"; memset(key, 0x0b, 20); isc_hmacsha1_init(&hmacsha1, key, 20); memcpy(buffer, s, strlen(s)); isc_hmacsha1_update(&hmacsha1, buffer, strlen(s)); isc_hmacsha1_sign(&hmacsha1, digest, ISC_SHA1_DIGESTLENGTH); print_digest(s, "hmacsha1", digest, ISC_SHA1_DIGESTLENGTH/4); s = "what do ya want for nothing?"; strcpy((char *)key, "Jefe"); isc_hmacsha1_init(&hmacsha1, key, 4); memcpy(buffer, s, strlen(s)); isc_hmacsha1_update(&hmacsha1, buffer, strlen(s)); isc_hmacsha1_sign(&hmacsha1, digest, ISC_SHA1_DIGESTLENGTH); print_digest(s, "hmacsha1", digest, ISC_SHA1_DIGESTLENGTH/4); s = "\335\335\335\335\335\335\335\335\335\335" "\335\335\335\335\335\335\335\335\335\335" "\335\335\335\335\335\335\335\335\335\335" "\335\335\335\335\335\335\335\335\335\335" "\335\335\335\335\335\335\335\335\335\335"; memset(key, 0xaa, 20); isc_hmacsha1_init(&hmacsha1, key, 20); memcpy(buffer, s, strlen(s)); isc_hmacsha1_update(&hmacsha1, buffer, strlen(s)); isc_hmacsha1_sign(&hmacsha1, digest, ISC_SHA1_DIGESTLENGTH); print_digest(s, "hmacsha1", digest, ISC_SHA1_DIGESTLENGTH/4); /* * The 3 HMAC-SHA224 examples from RFC4634. */ s = "Hi There"; memset(key, 0x0b, 20); isc_hmacsha224_init(&hmacsha224, key, 20); memcpy(buffer, s, strlen(s)); isc_hmacsha224_update(&hmacsha224, buffer, strlen(s)); isc_hmacsha224_sign(&hmacsha224, digest, ISC_SHA224_DIGESTLENGTH); print_digest(s, "hmacsha224", digest, ISC_SHA224_DIGESTLENGTH/4); s = "what do ya want for nothing?"; strcpy((char *)key, "Jefe"); isc_hmacsha224_init(&hmacsha224, key, 4); memcpy(buffer, s, strlen(s)); isc_hmacsha224_update(&hmacsha224, buffer, strlen(s)); isc_hmacsha224_sign(&hmacsha224, digest, ISC_SHA224_DIGESTLENGTH); print_digest(s, "hmacsha224", digest, ISC_SHA224_DIGESTLENGTH/4); s = "\335\335\335\335\335\335\335\335\335\335" "\335\335\335\335\335\335\335\335\335\335" "\335\335\335\335\335\335\335\335\335\335" "\335\335\335\335\335\335\335\335\335\335" "\335\335\335\335\335\335\335\335\335\335"; memset(key, 0xaa, 20); isc_hmacsha224_init(&hmacsha224, key, 20); memcpy(buffer, s, strlen(s)); isc_hmacsha224_update(&hmacsha224, buffer, strlen(s)); isc_hmacsha224_sign(&hmacsha224, digest, ISC_SHA224_DIGESTLENGTH); print_digest(s, "hmacsha224", digest, ISC_SHA224_DIGESTLENGTH/4); /* * The 3 HMAC-SHA256 examples from RFC4634. */ s = "Hi There"; memset(key, 0x0b, 20); isc_hmacsha256_init(&hmacsha256, key, 20); memcpy(buffer, s, strlen(s)); isc_hmacsha256_update(&hmacsha256, buffer, strlen(s)); isc_hmacsha256_sign(&hmacsha256, digest, ISC_SHA256_DIGESTLENGTH); print_digest(s, "hmacsha256", digest, ISC_SHA256_DIGESTLENGTH/4); s = "what do ya want for nothing?"; strcpy((char *)key, "Jefe"); isc_hmacsha256_init(&hmacsha256, key, 4); memcpy(buffer, s, strlen(s)); isc_hmacsha256_update(&hmacsha256, buffer, strlen(s)); isc_hmacsha256_sign(&hmacsha256, digest, ISC_SHA256_DIGESTLENGTH); print_digest(s, "hmacsha256", digest, ISC_SHA256_DIGESTLENGTH/4); s = "\335\335\335\335\335\335\335\335\335\335" "\335\335\335\335\335\335\335\335\335\335" "\335\335\335\335\335\335\335\335\335\335" "\335\335\335\335\335\335\335\335\335\335" "\335\335\335\335\335\335\335\335\335\335"; memset(key, 0xaa, 20); isc_hmacsha256_init(&hmacsha256, key, 20); memcpy(buffer, s, strlen(s)); isc_hmacsha256_update(&hmacsha256, buffer, strlen(s)); isc_hmacsha256_sign(&hmacsha256, digest, ISC_SHA256_DIGESTLENGTH); print_digest(s, "hmacsha256", digest, ISC_SHA256_DIGESTLENGTH/4); /* * The 3 HMAC-SHA384 examples from RFC4634. */ s = "Hi There"; memset(key, 0x0b, 20); isc_hmacsha384_init(&hmacsha384, key, 20); memcpy(buffer, s, strlen(s)); isc_hmacsha384_update(&hmacsha384, buffer, strlen(s)); isc_hmacsha384_sign(&hmacsha384, digest, ISC_SHA384_DIGESTLENGTH); print_digest(s, "hmacsha384", digest, ISC_SHA384_DIGESTLENGTH/4); s = "what do ya want for nothing?"; strcpy((char *)key, "Jefe"); isc_hmacsha384_init(&hmacsha384, key, 4); memcpy(buffer, s, strlen(s)); isc_hmacsha384_update(&hmacsha384, buffer, strlen(s)); isc_hmacsha384_sign(&hmacsha384, digest, ISC_SHA384_DIGESTLENGTH); print_digest(s, "hmacsha384", digest, ISC_SHA384_DIGESTLENGTH/4); s = "\335\335\335\335\335\335\335\335\335\335" "\335\335\335\335\335\335\335\335\335\335" "\335\335\335\335\335\335\335\335\335\335" "\335\335\335\335\335\335\335\335\335\335" "\335\335\335\335\335\335\335\335\335\335"; memset(key, 0xaa, 20); isc_hmacsha384_init(&hmacsha384, key, 20); memcpy(buffer, s, strlen(s)); isc_hmacsha384_update(&hmacsha384, buffer, strlen(s)); isc_hmacsha384_sign(&hmacsha384, digest, ISC_SHA384_DIGESTLENGTH); print_digest(s, "hmacsha384", digest, ISC_SHA384_DIGESTLENGTH/4); /* * The 3 HMAC-SHA512 examples from RFC4634. */ s = "Hi There"; memset(key, 0x0b, 20); isc_hmacsha512_init(&hmacsha512, key, 20); memcpy(buffer, s, strlen(s)); isc_hmacsha512_update(&hmacsha512, buffer, strlen(s)); isc_hmacsha512_sign(&hmacsha512, digest, ISC_SHA512_DIGESTLENGTH); print_digest(s, "hmacsha512", digest, ISC_SHA512_DIGESTLENGTH/4); s = "what do ya want for nothing?"; strcpy((char *)key, "Jefe"); isc_hmacsha512_init(&hmacsha512, key, 4); memcpy(buffer, s, strlen(s)); isc_hmacsha512_update(&hmacsha512, buffer, strlen(s)); isc_hmacsha512_sign(&hmacsha512, digest, ISC_SHA512_DIGESTLENGTH); print_digest(s, "hmacsha512", digest, ISC_SHA512_DIGESTLENGTH/4); s = "\335\335\335\335\335\335\335\335\335\335" "\335\335\335\335\335\335\335\335\335\335" "\335\335\335\335\335\335\335\335\335\335" "\335\335\335\335\335\335\335\335\335\335" "\335\335\335\335\335\335\335\335\335\335"; memset(key, 0xaa, 20); isc_hmacsha512_init(&hmacsha512, key, 20); memcpy(buffer, s, strlen(s)); isc_hmacsha512_update(&hmacsha512, buffer, strlen(s)); isc_hmacsha512_sign(&hmacsha512, digest, ISC_SHA512_DIGESTLENGTH); print_digest(s, "hmacsha512", digest, ISC_SHA512_DIGESTLENGTH/4); return (0); }