hmac_link.c revision 431a83fb29482c5170b3e4026e59bb14849a6707
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff/*
b7b6b01a0d0622181a4c28dd60401f0ab2480d00Mark Andrews * Portions Copyright (C) 2004-2014 Internet Systems Consortium, Inc. ("ISC")
fcb54ce0a4f7377486df5bec83b3aa4711bf4131Mark Andrews * Portions Copyright (C) 1999-2002 Internet Software Consortium.
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence *
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff * Permission to use, copy, modify, and/or distribute this software for any
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff * purpose with or without fee is hereby granted, provided that the above
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff * copyright notice and this permission notice appear in all copies.
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence *
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NETWORK ASSOCIATES DISCLAIMS
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff *
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff * Portions Copyright (C) 1995-2000 by Network Associates, Inc.
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein *
9c3531d72aeaad6c5f01efe6a1c82023e1379e4dDavid Lawrence * Permission to use, copy, modify, and/or distribute this software for any
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein * purpose with or without fee is hereby granted, provided that the above
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff * copyright notice and this permission notice appear in all copies.
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein *
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NETWORK ASSOCIATES DISCLAIMS
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
8cdfd17426179ae6f629a9b7475d46a22f535047Bob Halley * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff */
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff
9282e3c21a20f354e22ad3f092aea4956abaea5cMichael Graff/*
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff * Principal Author: Brian Wellington
9282e3c21a20f354e22ad3f092aea4956abaea5cMichael Graff * $Id: hmac_link.c,v 1.19 2011/01/11 23:47:13 tbox Exp $
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff */
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff#include <config.h>
058eeac2105c39e7cb31fb75ee0b473717ec3bbcMark Andrews
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence#include <isc/buffer.h>
3024dbecbac365171bc6de0f3fa04951d6558be3Michael Graff#include <isc/hmacmd5.h>
5fca48054b5e791a2fa0c5015bc3b6fef4fcdce1Andreas Gustafsson#include <isc/hmacsha.h>
f181f94ec8da8b1dbcc6353e8be965ea4a5ea282Michael Graff#include <isc/md5.h>
6028d1ce0380d0ba7f6c6ecd1ad20b31ddd1becbDavid Lawrence#include <isc/sha1.h>
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence#include <isc/mem.h>
3ac63b472022ff92691d1fe69ac715a729671965Michael Graff#include <isc/safe.h>
440be4c866f6935ac069db79a414304507a664c2Michael Graff#include <isc/string.h>
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff#include <isc/util.h>
e45d323a2a0f4ca08d4b139546e60a5fa7bd3f0cMichael Graff
29f28fe573d4b3b318b3b026d567c1eb86738015Michael Graff#include <dst/result.h>
86944a4c8002e80ae9b6eb5a5e29b797879be45fMichael Graff
21e7034ec046105c00a0dab86c83732e2e77ad99Michael Graff#include "dst_internal.h"
e51511aa3281f8dc384eb1283115c7f8d5c402aeMichael Graff#include "dst_parse.h"
e51511aa3281f8dc384eb1283115c7f8d5c402aeMichael Graff
d1cbf714097e900ed1703529584d3e1a50e8a4a8Brian Wellingtonstatic isc_result_t hmacmd5_fromdns(dst_key_t *key, isc_buffer_t *data);
11efdeb076d65fa9f0c5fc067dc040e7c99dfba6Michael Graff
09f22ac5b09e70bc526015f37168ba33e21ea91fDavid Lawrencestruct dst_hmacmd5_key {
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff unsigned char key[ISC_MD5_BLOCK_LENGTH];
92ef1a9b9dbd48ecb507b42ac62c15afefdaf838David Lawrence};
31fab17bcdbe302592a6c0dc5374ef56333ee879Michael Graff
92ef1a9b9dbd48ecb507b42ac62c15afefdaf838David Lawrencestatic isc_result_t
31fab17bcdbe302592a6c0dc5374ef56333ee879Michael Graffgetkeybits(dst_key_t *key, struct dst_private_element *element) {
92ef1a9b9dbd48ecb507b42ac62c15afefdaf838David Lawrence
31fab17bcdbe302592a6c0dc5374ef56333ee879Michael Graff if (element->length != 2)
92ef1a9b9dbd48ecb507b42ac62c15afefdaf838David Lawrence return (DST_R_INVALIDPRIVATEKEY);
31fab17bcdbe302592a6c0dc5374ef56333ee879Michael Graff
92ef1a9b9dbd48ecb507b42ac62c15afefdaf838David Lawrence key->key_bits = (element->data[0] << 8) + element->data[1];
31fab17bcdbe302592a6c0dc5374ef56333ee879Michael Graff
92ef1a9b9dbd48ecb507b42ac62c15afefdaf838David Lawrence return (ISC_R_SUCCESS);
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff}
92ef1a9b9dbd48ecb507b42ac62c15afefdaf838David Lawrence
fe14eafefa91fada7cea0a55b09196c01477406cBob Halleystatic isc_result_t
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graffhmacmd5_createctx(dst_key_t *key, dst_context_t *dctx) {
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein isc_hmacmd5_t *hmacmd5ctx;
8cdfd17426179ae6f629a9b7475d46a22f535047Bob Halley dst_hmacmd5_key_t *hkey = key->keydata.hmacmd5;
8cdfd17426179ae6f629a9b7475d46a22f535047Bob Halley
8cdfd17426179ae6f629a9b7475d46a22f535047Bob Halley hmacmd5ctx = isc_mem_get(dctx->mctx, sizeof(isc_hmacmd5_t));
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff if (hmacmd5ctx == NULL)
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein return (ISC_R_NOMEMORY);
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff isc_hmacmd5_init(hmacmd5ctx, hkey->key, ISC_SHA1_BLOCK_LENGTH);
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein dctx->ctxdata.hmacmd5ctx = hmacmd5ctx;
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff return (ISC_R_SUCCESS);
d947011dc393d9f9988d1349d585b246d19cc3c7Michael Graff}
49a940dc68b30d9e4f9e1bd3c0503d8b90bb1726Mark Andrews
d947011dc393d9f9988d1349d585b246d19cc3c7Michael Graffstatic void
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graffhmacmd5_destroyctx(dst_context_t *dctx) {
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein isc_hmacmd5_t *hmacmd5ctx = dctx->ctxdata.hmacmd5ctx;
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein if (hmacmd5ctx != NULL) {
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff isc_hmacmd5_invalidate(hmacmd5ctx);
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein isc_mem_put(dctx->mctx, hmacmd5ctx, sizeof(isc_hmacmd5_t));
7b5172166d816efabcdb22519b136ba124bb2619Brian Wellington dctx->ctxdata.hmacmd5ctx = NULL;
7b5172166d816efabcdb22519b136ba124bb2619Brian Wellington }
8cdfd17426179ae6f629a9b7475d46a22f535047Bob Halley}
7b5172166d816efabcdb22519b136ba124bb2619Brian Wellington
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austeinstatic isc_result_t
7b5172166d816efabcdb22519b136ba124bb2619Brian Wellingtonhmacmd5_adddata(dst_context_t *dctx, const isc_region_t *data) {
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein isc_hmacmd5_t *hmacmd5ctx = dctx->ctxdata.hmacmd5ctx;
7b5172166d816efabcdb22519b136ba124bb2619Brian Wellington
3ac63b472022ff92691d1fe69ac715a729671965Michael Graff isc_hmacmd5_update(hmacmd5ctx, data->base, data->length);
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein return (ISC_R_SUCCESS);
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein}
213973a334f92d4aef4ef62b4538fc2e4d0e8082Michael Graff
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austeinstatic isc_result_t
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graffhmacmd5_sign(dst_context_t *dctx, isc_buffer_t *sig) {
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein isc_hmacmd5_t *hmacmd5ctx = dctx->ctxdata.hmacmd5ctx;
081cff0c33514a5dc63ab794fc199c07377ab756Mark Andrews unsigned char *digest;
213973a334f92d4aef4ef62b4538fc2e4d0e8082Michael Graff
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff if (isc_buffer_availablelength(sig) < ISC_MD5_DIGESTLENGTH)
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff return (ISC_R_NOSPACE);
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff digest = isc_buffer_used(sig);
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff isc_hmacmd5_sign(hmacmd5ctx, digest);
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff isc_buffer_add(sig, ISC_MD5_DIGESTLENGTH);
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff return (ISC_R_SUCCESS);
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein}
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graffstatic isc_result_t
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graffhmacmd5_verify(dst_context_t *dctx, const isc_region_t *sig) {
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff isc_hmacmd5_t *hmacmd5ctx = dctx->ctxdata.hmacmd5ctx;
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff if (sig->length > ISC_MD5_DIGESTLENGTH)
439c0011e642fb1d26011116144af698125262dbMichael Graff return (DST_R_VERIFYFAILURE);
11efdeb076d65fa9f0c5fc067dc040e7c99dfba6Michael Graff
3ac63b472022ff92691d1fe69ac715a729671965Michael Graff if (isc_hmacmd5_verify2(hmacmd5ctx, sig->base, sig->length))
11efdeb076d65fa9f0c5fc067dc040e7c99dfba6Michael Graff return (ISC_R_SUCCESS);
3ac63b472022ff92691d1fe69ac715a729671965Michael Graff else
081cff0c33514a5dc63ab794fc199c07377ab756Mark Andrews return (DST_R_VERIFYFAILURE);
84c46a7acb961cac19c0d857bfdd00f3383a9bc6Michael Graff}
3ac63b472022ff92691d1fe69ac715a729671965Michael Graff
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halleystatic isc_boolean_t
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graffhmacmd5_compare(const dst_key_t *key1, const dst_key_t *key2) {
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff dst_hmacmd5_key_t *hkey1, *hkey2;
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff
e51511aa3281f8dc384eb1283115c7f8d5c402aeMichael Graff hkey1 = key1->keydata.hmacmd5;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff hkey2 = key2->keydata.hmacmd5;
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein if (hkey1 == NULL && hkey2 == NULL)
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein return (ISC_TRUE);
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein else if (hkey1 == NULL || hkey2 == NULL)
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein return (ISC_FALSE);
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein if (isc_safe_memcmp(hkey1->key, hkey2->key, ISC_SHA1_BLOCK_LENGTH))
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein return (ISC_TRUE);
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein else
213973a334f92d4aef4ef62b4538fc2e4d0e8082Michael Graff return (ISC_FALSE);
8cdfd17426179ae6f629a9b7475d46a22f535047Bob Halley}
8cdfd17426179ae6f629a9b7475d46a22f535047Bob Halley
213973a334f92d4aef4ef62b4538fc2e4d0e8082Michael Graffstatic isc_result_t
6dde125c2f47617ceef1518cf9e5588e8f366b71Michael Graffhmacmd5_generate(dst_key_t *key, int pseudorandom_ok, void (*callback)(int)) {
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein isc_buffer_t b;
6dde125c2f47617ceef1518cf9e5588e8f366b71Michael Graff isc_result_t ret;
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein unsigned int bytes;
6dde125c2f47617ceef1518cf9e5588e8f366b71Michael Graff unsigned char data[ISC_SHA1_BLOCK_LENGTH];
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein
6dde125c2f47617ceef1518cf9e5588e8f366b71Michael Graff UNUSED(callback);
213973a334f92d4aef4ef62b4538fc2e4d0e8082Michael Graff
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein bytes = (key->key_size + 7) / 8;
213973a334f92d4aef4ef62b4538fc2e4d0e8082Michael Graff if (bytes > ISC_SHA1_BLOCK_LENGTH) {
8cdfd17426179ae6f629a9b7475d46a22f535047Bob Halley bytes = ISC_SHA1_BLOCK_LENGTH;
8cdfd17426179ae6f629a9b7475d46a22f535047Bob Halley key->key_size = ISC_SHA1_BLOCK_LENGTH * 8;
213973a334f92d4aef4ef62b4538fc2e4d0e8082Michael Graff }
6dde125c2f47617ceef1518cf9e5588e8f366b71Michael Graff
6dde125c2f47617ceef1518cf9e5588e8f366b71Michael Graff memset(data, 0, ISC_SHA1_BLOCK_LENGTH);
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein ret = dst__entropy_getdata(data, bytes, ISC_TF(pseudorandom_ok != 0));
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley
59c049874bbef182857c57bd9cca292898921c69Bob Halley if (ret != ISC_R_SUCCESS)
59c049874bbef182857c57bd9cca292898921c69Bob Halley return (ret);
59c049874bbef182857c57bd9cca292898921c69Bob Halley
59c049874bbef182857c57bd9cca292898921c69Bob Halley isc_buffer_init(&b, data, bytes);
59c049874bbef182857c57bd9cca292898921c69Bob Halley isc_buffer_add(&b, bytes);
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff ret = hmacmd5_fromdns(key, &b);
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff memset(data, 0, ISC_SHA1_BLOCK_LENGTH);
8cdfd17426179ae6f629a9b7475d46a22f535047Bob Halley
8cdfd17426179ae6f629a9b7475d46a22f535047Bob Halley return (ret);
8cdfd17426179ae6f629a9b7475d46a22f535047Bob Halley}
8cdfd17426179ae6f629a9b7475d46a22f535047Bob Halley
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austeinstatic isc_boolean_t
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graffhmacmd5_isprivate(const dst_key_t *key) {
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff UNUSED(key);
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff return (ISC_TRUE);
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graff}
1f90c108282533a23b8362c34bcde4267c1eb4b1Michael Graff
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graffstatic void
ebdd11e84734e28ddd64562e82a7c646a58a04f4Michael Graffhmacmd5_destroy(dst_key_t *key) {
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley dst_hmacmd5_key_t *hkey = key->keydata.hmacmd5;
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff memset(hkey, 0, sizeof(dst_hmacmd5_key_t));
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff isc_mem_put(key->mctx, hkey, sizeof(dst_hmacmd5_key_t));
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley key->keydata.hmacmd5 = NULL;
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff}
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff
59e22acc4f79ff481f7bfa46ef0558957ae53cfcMichael Graffstatic isc_result_t
59e22acc4f79ff481f7bfa46ef0558957ae53cfcMichael Graffhmacmd5_todns(const dst_key_t *key, isc_buffer_t *data) {
306a93530536f05edfb477cac1c2667d90129a8fMichael Graff dst_hmacmd5_key_t *hkey;
306a93530536f05edfb477cac1c2667d90129a8fMichael Graff unsigned int bytes;
28ab8277a068f273f0a805a83b4811446cb78a5bBob Halley
d43c2cc7bc4022701f141e299ea8f3fb1d0640c2Michael Graff REQUIRE(key->keydata.hmacmd5 != NULL);
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff hkey = key->keydata.hmacmd5;
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff bytes = (key->key_size + 7) / 8;
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff if (isc_buffer_availablelength(data) < bytes)
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff return (ISC_R_NOSPACE);
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff isc_buffer_putmem(data, hkey->key, bytes);
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff return (ISC_R_SUCCESS);
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff}
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austeinstatic isc_result_t
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graffhmacmd5_fromdns(dst_key_t *key, isc_buffer_t *data) {
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff dst_hmacmd5_key_t *hkey;
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff int keylen;
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff isc_region_t r;
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff isc_md5_t md5ctx;
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff isc_buffer_remainingregion(data, &r);
d43c2cc7bc4022701f141e299ea8f3fb1d0640c2Michael Graff if (r.length == 0)
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff return (ISC_R_SUCCESS);
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein hkey = isc_mem_get(key->mctx, sizeof(dst_hmacmd5_key_t));
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff if (hkey == NULL)
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff return (ISC_R_NOMEMORY);
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff memset(hkey->key, 0, sizeof(hkey->key));
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff if (r.length > ISC_SHA1_BLOCK_LENGTH) {
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff isc_md5_init(&md5ctx);
439c0011e642fb1d26011116144af698125262dbMichael Graff isc_md5_update(&md5ctx, r.base, r.length);
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff isc_md5_final(&md5ctx, hkey->key);
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff keylen = ISC_MD5_DIGESTLENGTH;
d43c2cc7bc4022701f141e299ea8f3fb1d0640c2Michael Graff } else {
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff memmove(hkey->key, r.base, r.length);
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff keylen = r.length;
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein }
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff
57ecc983c0b37ce7dbccf28f44c6bffdfd6491f7Andreas Gustafsson key->key_size = keylen * 8;
57ecc983c0b37ce7dbccf28f44c6bffdfd6491f7Andreas Gustafsson key->keydata.hmacmd5 = hkey;
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff return (ISC_R_SUCCESS);
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff}
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graffstatic isc_result_t
439c0011e642fb1d26011116144af698125262dbMichael Graffhmacmd5_tofile(const dst_key_t *key, const char *directory) {
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff int cnt = 0;
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff dst_hmacmd5_key_t *hkey;
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff dst_private_t priv;
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff int bytes = (key->key_size + 7) / 8;
5f1f24822fabe7b78af5f81553bfc11a170326c3Mark Andrews unsigned char buf[2];
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein if (key->keydata.hmacmd5 == NULL)
784d78b831830bf7b53507e742254f9c49295752Andreas Gustafsson return (DST_R_NULLKEY);
784d78b831830bf7b53507e742254f9c49295752Andreas Gustafsson
784d78b831830bf7b53507e742254f9c49295752Andreas Gustafsson hkey = key->keydata.hmacmd5;
784d78b831830bf7b53507e742254f9c49295752Andreas Gustafsson
784d78b831830bf7b53507e742254f9c49295752Andreas Gustafsson priv.elements[cnt].tag = TAG_HMACMD5_KEY;
784d78b831830bf7b53507e742254f9c49295752Andreas Gustafsson priv.elements[cnt].length = bytes;
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff priv.elements[cnt++].data = hkey->key;
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff
d43c2cc7bc4022701f141e299ea8f3fb1d0640c2Michael Graff buf[0] = (key->key_bits >> 8) & 0xffU;
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff buf[1] = key->key_bits & 0xffU;
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff priv.elements[cnt].tag = TAG_HMACMD5_BITS;
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff priv.elements[cnt].data = buf;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff priv.elements[cnt++].length = 2;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff priv.nelements = cnt;
439c0011e642fb1d26011116144af698125262dbMichael Graff return (dst__privstruct_writefile(key, &priv, directory));
439c0011e642fb1d26011116144af698125262dbMichael Graff}
439c0011e642fb1d26011116144af698125262dbMichael Graff
439c0011e642fb1d26011116144af698125262dbMichael Graffstatic isc_result_t
f36a81c88493985ee2d1c53cc6fe88f4b00dbbc8Michael Graffhmacmd5_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
439c0011e642fb1d26011116144af698125262dbMichael Graff dst_private_t priv;
439c0011e642fb1d26011116144af698125262dbMichael Graff isc_result_t result, tresult;
439c0011e642fb1d26011116144af698125262dbMichael Graff isc_buffer_t b;
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff isc_mem_t *mctx = key->mctx;
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graff unsigned int i;
d98c74e2ec5b96bd22aa4ed6d893e8993787493bMichael Graff
d98c74e2ec5b96bd22aa4ed6d893e8993787493bMichael Graff UNUSED(pub);
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff /* read private key file */
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff result = dst__privstruct_parse(key, DST_ALG_HMACMD5, lexer, mctx,
439c0011e642fb1d26011116144af698125262dbMichael Graff &priv);
1a0e33bc2044e1902493111db14cbf793083ac47Michael Graff if (result != ISC_R_SUCCESS)
439c0011e642fb1d26011116144af698125262dbMichael Graff return (result);
439c0011e642fb1d26011116144af698125262dbMichael Graff
dd95acdbce0e2a2775391709cdfca0a9eda7e8f7Mark Andrews key->key_bits = 0;
439c0011e642fb1d26011116144af698125262dbMichael Graff for (i = 0; i < priv.nelements && result == ISC_R_SUCCESS; i++) {
5fca48054b5e791a2fa0c5015bc3b6fef4fcdce1Andreas Gustafsson switch (priv.elements[i].tag) {
5fca48054b5e791a2fa0c5015bc3b6fef4fcdce1Andreas Gustafsson case TAG_HMACMD5_KEY:
550085fed1d0af54ba5b2f588898afec158195deMark Andrews isc_buffer_init(&b, priv.elements[i].data,
550085fed1d0af54ba5b2f588898afec158195deMark Andrews priv.elements[i].length);
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff isc_buffer_add(&b, priv.elements[i].length);
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graff tresult = hmacmd5_fromdns(key, &b);
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graff if (tresult != ISC_R_SUCCESS)
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graff result = tresult;
78bf1ca89505820ed7b03be4bf0c0b53b557f3cdAndreas Gustafsson break;
439c0011e642fb1d26011116144af698125262dbMichael Graff case TAG_HMACMD5_BITS:
439c0011e642fb1d26011116144af698125262dbMichael Graff tresult = getkeybits(key, &priv.elements[i]);
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graff if (tresult != ISC_R_SUCCESS)
5f1f24822fabe7b78af5f81553bfc11a170326c3Mark Andrews result = tresult;
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff break;
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graff default:
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley result = DST_R_INVALIDPRIVATEKEY;
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff break;
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff }
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graff }
5f1f24822fabe7b78af5f81553bfc11a170326c3Mark Andrews dst__privstruct_free(&priv, mctx);
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley memset(&priv, 0, sizeof(priv));
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graff return (result);
1a0e33bc2044e1902493111db14cbf793083ac47Michael Graff}
49a940dc68b30d9e4f9e1bd3c0503d8b90bb1726Mark Andrews
49a940dc68b30d9e4f9e1bd3c0503d8b90bb1726Mark Andrewsstatic dst_func_t hmacmd5_functions = {
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff hmacmd5_createctx,
3ac63b472022ff92691d1fe69ac715a729671965Michael Graff hmacmd5_destroyctx,
651228967966ba4fb2e52f92d1207c790af4b130Michael Graff hmacmd5_adddata,
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graff hmacmd5_sign,
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graff hmacmd5_verify,
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff NULL, /*%< verify2 */
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graff NULL, /*%< computesecret */
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley hmacmd5_compare,
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graff NULL, /*%< paramcompare */
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graff hmacmd5_generate,
dd95acdbce0e2a2775391709cdfca0a9eda7e8f7Mark Andrews hmacmd5_isprivate,
dd95acdbce0e2a2775391709cdfca0a9eda7e8f7Mark Andrews hmacmd5_destroy,
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff hmacmd5_todns,
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff hmacmd5_fromdns,
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff hmacmd5_tofile,
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff hmacmd5_parse,
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff NULL, /*%< cleanup */
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff NULL, /*%< fromlabel */
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff NULL, /*%< dump */
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff NULL, /*%< restore */
897c9ddb4d745b2bfecf98b17e5487bb6656299aMichael Graff};
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graffisc_result_t
1a0e33bc2044e1902493111db14cbf793083ac47Michael Graffdst__hmacmd5_init(dst_func_t **funcp) {
1a0e33bc2044e1902493111db14cbf793083ac47Michael Graff REQUIRE(funcp != NULL);
53cf67186506f9557aaf2149898dd76715803db2Mark Andrews if (*funcp == NULL)
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff *funcp = &hmacmd5_functions;
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff return (ISC_R_SUCCESS);
1a0e33bc2044e1902493111db14cbf793083ac47Michael Graff}
c6715d23151ab9948c7191b1ed1b99a14e6def7dDavid Lawrence
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graffstatic isc_result_t hmacsha1_fromdns(dst_key_t *key, isc_buffer_t *data);
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graffstruct dst_hmacsha1_key {
49a940dc68b30d9e4f9e1bd3c0503d8b90bb1726Mark Andrews unsigned char key[ISC_SHA1_BLOCK_LENGTH];
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff};
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graffstatic isc_result_t
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graffhmacsha1_createctx(dst_key_t *key, dst_context_t *dctx) {
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff isc_hmacsha1_t *hmacsha1ctx;
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff dst_hmacsha1_key_t *hkey = key->keydata.hmacsha1;
49a940dc68b30d9e4f9e1bd3c0503d8b90bb1726Mark Andrews
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff hmacsha1ctx = isc_mem_get(dctx->mctx, sizeof(isc_hmacsha1_t));
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff if (hmacsha1ctx == NULL)
49a940dc68b30d9e4f9e1bd3c0503d8b90bb1726Mark Andrews return (ISC_R_NOMEMORY);
49a940dc68b30d9e4f9e1bd3c0503d8b90bb1726Mark Andrews isc_hmacsha1_init(hmacsha1ctx, hkey->key, ISC_SHA1_BLOCK_LENGTH);
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff dctx->ctxdata.hmacsha1ctx = hmacsha1ctx;
517274e709a3c730cd42f37dc1260dde95d1ea38Michael Graff return (ISC_R_SUCCESS);
517274e709a3c730cd42f37dc1260dde95d1ea38Michael Graff}
517274e709a3c730cd42f37dc1260dde95d1ea38Michael Graff
49a940dc68b30d9e4f9e1bd3c0503d8b90bb1726Mark Andrewsstatic void
517274e709a3c730cd42f37dc1260dde95d1ea38Michael Graffhmacsha1_destroyctx(dst_context_t *dctx) {
59e22acc4f79ff481f7bfa46ef0558957ae53cfcMichael Graff isc_hmacsha1_t *hmacsha1ctx = dctx->ctxdata.hmacsha1ctx;
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff if (hmacsha1ctx != NULL) {
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff isc_hmacsha1_invalidate(hmacsha1ctx);
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff isc_mem_put(dctx->mctx, hmacsha1ctx, sizeof(isc_hmacsha1_t));
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff dctx->ctxdata.hmacsha1ctx = NULL;
4a3ad0da975d7115d401700f955814a0dff1adb0Bob Halley }
4a3ad0da975d7115d401700f955814a0dff1adb0Bob Halley}
53cf67186506f9557aaf2149898dd76715803db2Mark Andrews
24a2d84aedbad12fba2ca319c98745e62ef0bc16Bob Halleystatic isc_result_t
1a0e33bc2044e1902493111db14cbf793083ac47Michael Graffhmacsha1_adddata(dst_context_t *dctx, const isc_region_t *data) {
1a0e33bc2044e1902493111db14cbf793083ac47Michael Graff isc_hmacsha1_t *hmacsha1ctx = dctx->ctxdata.hmacsha1ctx;
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff
ffd9f879709c5fb35f25368e74e2e12eb6881d9bMichael Graff isc_hmacsha1_update(hmacsha1ctx, data->base, data->length);
4a3ad0da975d7115d401700f955814a0dff1adb0Bob Halley return (ISC_R_SUCCESS);
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff}
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graffstatic isc_result_t
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graffhmacsha1_sign(dst_context_t *dctx, isc_buffer_t *sig) {
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff isc_hmacsha1_t *hmacsha1ctx = dctx->ctxdata.hmacsha1ctx;
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff unsigned char *digest;
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff
3d12fa7e76c02d06e1adeaa7846b60378a3cd204Michael Graff if (isc_buffer_availablelength(sig) < ISC_SHA1_DIGESTLENGTH)
3d12fa7e76c02d06e1adeaa7846b60378a3cd204Michael Graff return (ISC_R_NOSPACE);
1a0e33bc2044e1902493111db14cbf793083ac47Michael Graff digest = isc_buffer_used(sig);
1a0e33bc2044e1902493111db14cbf793083ac47Michael Graff isc_hmacsha1_sign(hmacsha1ctx, digest, ISC_SHA1_DIGESTLENGTH);
1a0e33bc2044e1902493111db14cbf793083ac47Michael Graff isc_buffer_add(sig, ISC_SHA1_DIGESTLENGTH);
1a0e33bc2044e1902493111db14cbf793083ac47Michael Graff
1a0e33bc2044e1902493111db14cbf793083ac47Michael Graff return (ISC_R_SUCCESS);
1a0e33bc2044e1902493111db14cbf793083ac47Michael Graff}
1a0e33bc2044e1902493111db14cbf793083ac47Michael Graff
1a0e33bc2044e1902493111db14cbf793083ac47Michael Graffstatic isc_result_t
53cf67186506f9557aaf2149898dd76715803db2Mark Andrewshmacsha1_verify(dst_context_t *dctx, const isc_region_t *sig) {
53cf67186506f9557aaf2149898dd76715803db2Mark Andrews isc_hmacsha1_t *hmacsha1ctx = dctx->ctxdata.hmacsha1ctx;
1a0e33bc2044e1902493111db14cbf793083ac47Michael Graff
550085fed1d0af54ba5b2f588898afec158195deMark Andrews if (sig->length > ISC_SHA1_DIGESTLENGTH || sig->length == 0)
78854e02c127f31ab90f56da0531542004b45377Michael Graff return (DST_R_VERIFYFAILURE);
550085fed1d0af54ba5b2f588898afec158195deMark Andrews
550085fed1d0af54ba5b2f588898afec158195deMark Andrews if (isc_hmacsha1_verify(hmacsha1ctx, sig->base, sig->length))
550085fed1d0af54ba5b2f588898afec158195deMark Andrews return (ISC_R_SUCCESS);
78854e02c127f31ab90f56da0531542004b45377Michael Graff else
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff return (DST_R_VERIFYFAILURE);
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff}
daf83a29374c487a2800333d371e98e77e5a0d64Bob Halley
daf83a29374c487a2800333d371e98e77e5a0d64Bob Halleystatic isc_boolean_t
306a93530536f05edfb477cac1c2667d90129a8fMichael Graffhmacsha1_compare(const dst_key_t *key1, const dst_key_t *key2) {
306a93530536f05edfb477cac1c2667d90129a8fMichael Graff dst_hmacsha1_key_t *hkey1, *hkey2;
e1db5e817f89b1b9ec7dab366f1bfe1c7b299438Michael Graff
58cbc05eb0b80510182496ad905cd407f3624dbeBrian Wellington hkey1 = key1->keydata.hmacsha1;
58cbc05eb0b80510182496ad905cd407f3624dbeBrian Wellington hkey2 = key2->keydata.hmacsha1;
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff
306a93530536f05edfb477cac1c2667d90129a8fMichael Graff if (hkey1 == NULL && hkey2 == NULL)
306a93530536f05edfb477cac1c2667d90129a8fMichael Graff return (ISC_TRUE);
306a93530536f05edfb477cac1c2667d90129a8fMichael Graff else if (hkey1 == NULL || hkey2 == NULL)
306a93530536f05edfb477cac1c2667d90129a8fMichael Graff return (ISC_FALSE);
306a93530536f05edfb477cac1c2667d90129a8fMichael Graff
306a93530536f05edfb477cac1c2667d90129a8fMichael Graff if (isc_safe_memcmp(hkey1->key, hkey2->key, ISC_SHA1_BLOCK_LENGTH))
306a93530536f05edfb477cac1c2667d90129a8fMichael Graff return (ISC_TRUE);
306a93530536f05edfb477cac1c2667d90129a8fMichael Graff else
306a93530536f05edfb477cac1c2667d90129a8fMichael Graff return (ISC_FALSE);
306a93530536f05edfb477cac1c2667d90129a8fMichael Graff}
306a93530536f05edfb477cac1c2667d90129a8fMichael Graff
306a93530536f05edfb477cac1c2667d90129a8fMichael Graffstatic isc_result_t
306a93530536f05edfb477cac1c2667d90129a8fMichael Graffhmacsha1_generate(dst_key_t *key, int pseudorandom_ok, void (*callback)(int)) {
9e992ecf375cd1eaa5351d06eca8cf7f543d5938Andreas Gustafsson isc_buffer_t b;
9e992ecf375cd1eaa5351d06eca8cf7f543d5938Andreas Gustafsson isc_result_t ret;
9e992ecf375cd1eaa5351d06eca8cf7f543d5938Andreas Gustafsson unsigned int bytes;
9e992ecf375cd1eaa5351d06eca8cf7f543d5938Andreas Gustafsson unsigned char data[ISC_SHA1_BLOCK_LENGTH];
9e992ecf375cd1eaa5351d06eca8cf7f543d5938Andreas Gustafsson
9e992ecf375cd1eaa5351d06eca8cf7f543d5938Andreas Gustafsson UNUSED(callback);
9e992ecf375cd1eaa5351d06eca8cf7f543d5938Andreas Gustafsson
9e992ecf375cd1eaa5351d06eca8cf7f543d5938Andreas Gustafsson bytes = (key->key_size + 7) / 8;
9e992ecf375cd1eaa5351d06eca8cf7f543d5938Andreas Gustafsson if (bytes > ISC_SHA1_BLOCK_LENGTH) {
9e992ecf375cd1eaa5351d06eca8cf7f543d5938Andreas Gustafsson bytes = ISC_SHA1_BLOCK_LENGTH;
306a93530536f05edfb477cac1c2667d90129a8fMichael Graff key->key_size = ISC_SHA1_BLOCK_LENGTH * 8;
306a93530536f05edfb477cac1c2667d90129a8fMichael Graff }
306a93530536f05edfb477cac1c2667d90129a8fMichael Graff
306a93530536f05edfb477cac1c2667d90129a8fMichael Graff memset(data, 0, ISC_SHA1_BLOCK_LENGTH);
306a93530536f05edfb477cac1c2667d90129a8fMichael Graff ret = dst__entropy_getdata(data, bytes, ISC_TF(pseudorandom_ok != 0));
306a93530536f05edfb477cac1c2667d90129a8fMichael Graff
306a93530536f05edfb477cac1c2667d90129a8fMichael Graff if (ret != ISC_R_SUCCESS)
306a93530536f05edfb477cac1c2667d90129a8fMichael Graff return (ret);
306a93530536f05edfb477cac1c2667d90129a8fMichael Graff
306a93530536f05edfb477cac1c2667d90129a8fMichael Graff isc_buffer_init(&b, data, bytes);
306a93530536f05edfb477cac1c2667d90129a8fMichael Graff isc_buffer_add(&b, bytes);
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff ret = hmacsha1_fromdns(key, &b);
76c8294c81fb48b1da6e1fc5b83322a4cedb8e58Andreas Gustafsson memset(data, 0, ISC_SHA1_BLOCK_LENGTH);
76c8294c81fb48b1da6e1fc5b83322a4cedb8e58Andreas Gustafsson
76c8294c81fb48b1da6e1fc5b83322a4cedb8e58Andreas Gustafsson return (ret);
21e7034ec046105c00a0dab86c83732e2e77ad99Michael Graff}
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence
21e7034ec046105c00a0dab86c83732e2e77ad99Michael Graffstatic isc_boolean_t
21e7034ec046105c00a0dab86c83732e2e77ad99Michael Graffhmacsha1_isprivate(const dst_key_t *key) {
21e7034ec046105c00a0dab86c83732e2e77ad99Michael Graff UNUSED(key);
21e7034ec046105c00a0dab86c83732e2e77ad99Michael Graff return (ISC_TRUE);
21e7034ec046105c00a0dab86c83732e2e77ad99Michael Graff}
550085fed1d0af54ba5b2f588898afec158195deMark Andrews
21e7034ec046105c00a0dab86c83732e2e77ad99Michael Graffstatic void
21e7034ec046105c00a0dab86c83732e2e77ad99Michael Graffhmacsha1_destroy(dst_key_t *key) {
21e7034ec046105c00a0dab86c83732e2e77ad99Michael Graff dst_hmacsha1_key_t *hkey = key->keydata.hmacsha1;
a14eb88840e06b8d458c1556e5452b6d2a50012eMichael Graff
a14eb88840e06b8d458c1556e5452b6d2a50012eMichael Graff memset(hkey, 0, sizeof(dst_hmacsha1_key_t));
a14eb88840e06b8d458c1556e5452b6d2a50012eMichael Graff isc_mem_put(key->mctx, hkey, sizeof(dst_hmacsha1_key_t));
a14eb88840e06b8d458c1556e5452b6d2a50012eMichael Graff key->keydata.hmacsha1 = NULL;
a14eb88840e06b8d458c1556e5452b6d2a50012eMichael Graff}
a14eb88840e06b8d458c1556e5452b6d2a50012eMichael Graff
a14eb88840e06b8d458c1556e5452b6d2a50012eMichael Graffstatic isc_result_t
a14eb88840e06b8d458c1556e5452b6d2a50012eMichael Graffhmacsha1_todns(const dst_key_t *key, isc_buffer_t *data) {
a14eb88840e06b8d458c1556e5452b6d2a50012eMichael Graff dst_hmacsha1_key_t *hkey;
a14eb88840e06b8d458c1556e5452b6d2a50012eMichael Graff unsigned int bytes;
2bcb48cfcae36398454c98e40c563e2cde748e07Michael Graff
2bcb48cfcae36398454c98e40c563e2cde748e07Michael Graff REQUIRE(key->keydata.hmacsha1 != NULL);
d1fb73ada84ee15ea078c80b1cd0ca8ddc6aa856Michael Graff
d1fb73ada84ee15ea078c80b1cd0ca8ddc6aa856Michael Graff hkey = key->keydata.hmacsha1;
2bcb48cfcae36398454c98e40c563e2cde748e07Michael Graff
2bcb48cfcae36398454c98e40c563e2cde748e07Michael Graff bytes = (key->key_size + 7) / 8;
d1fb73ada84ee15ea078c80b1cd0ca8ddc6aa856Michael Graff if (isc_buffer_availablelength(data) < bytes)
d1fb73ada84ee15ea078c80b1cd0ca8ddc6aa856Michael Graff return (ISC_R_NOSPACE);
2bcb48cfcae36398454c98e40c563e2cde748e07Michael Graff isc_buffer_putmem(data, hkey->key, bytes);
2bcb48cfcae36398454c98e40c563e2cde748e07Michael Graff
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff return (ISC_R_SUCCESS);
2bcb48cfcae36398454c98e40c563e2cde748e07Michael Graff}
6bd8cee98332533a4fa705b82ca9ec1606738ba9Mark Andrews
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrewsstatic isc_result_t
2bcb48cfcae36398454c98e40c563e2cde748e07Michael Graffhmacsha1_fromdns(dst_key_t *key, isc_buffer_t *data) {
d1fb73ada84ee15ea078c80b1cd0ca8ddc6aa856Michael Graff dst_hmacsha1_key_t *hkey;
2bcb48cfcae36398454c98e40c563e2cde748e07Michael Graff int keylen;
2bcb48cfcae36398454c98e40c563e2cde748e07Michael Graff isc_region_t r;
2bcb48cfcae36398454c98e40c563e2cde748e07Michael Graff isc_sha1_t sha1ctx;
2bcb48cfcae36398454c98e40c563e2cde748e07Michael Graff
d1fb73ada84ee15ea078c80b1cd0ca8ddc6aa856Michael Graff isc_buffer_remainingregion(data, &r);
59e22acc4f79ff481f7bfa46ef0558957ae53cfcMichael Graff if (r.length == 0)
2bcb48cfcae36398454c98e40c563e2cde748e07Michael Graff return (ISC_R_SUCCESS);
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff hkey = isc_mem_get(key->mctx, sizeof(dst_hmacsha1_key_t));
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff if (hkey == NULL)
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff return (ISC_R_NOMEMORY);
d1fb73ada84ee15ea078c80b1cd0ca8ddc6aa856Michael Graff
d1fb73ada84ee15ea078c80b1cd0ca8ddc6aa856Michael Graff memset(hkey->key, 0, sizeof(hkey->key));
59e22acc4f79ff481f7bfa46ef0558957ae53cfcMichael Graff
59e22acc4f79ff481f7bfa46ef0558957ae53cfcMichael Graff if (r.length > ISC_SHA1_BLOCK_LENGTH) {
f6f4ceece41f040cc43722afa9a5cd1f54a576b6Michael Graff isc_sha1_init(&sha1ctx);
59e22acc4f79ff481f7bfa46ef0558957ae53cfcMichael Graff isc_sha1_update(&sha1ctx, r.base, r.length);
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff isc_sha1_final(&sha1ctx, hkey->key);
2bcb48cfcae36398454c98e40c563e2cde748e07Michael Graff keylen = ISC_SHA1_DIGESTLENGTH;
2bcb48cfcae36398454c98e40c563e2cde748e07Michael Graff } else {
59e22acc4f79ff481f7bfa46ef0558957ae53cfcMichael Graff memmove(hkey->key, r.base, r.length);
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff keylen = r.length;
2bcb48cfcae36398454c98e40c563e2cde748e07Michael Graff }
2bcb48cfcae36398454c98e40c563e2cde748e07Michael Graff
368b37b616234fce3d23099eb180f1dd38e1fb62Mark Andrews key->key_size = keylen * 8;
2bcb48cfcae36398454c98e40c563e2cde748e07Michael Graff key->keydata.hmacsha1 = hkey;
d1fb73ada84ee15ea078c80b1cd0ca8ddc6aa856Michael Graff
d1fb73ada84ee15ea078c80b1cd0ca8ddc6aa856Michael Graff return (ISC_R_SUCCESS);
d1fb73ada84ee15ea078c80b1cd0ca8ddc6aa856Michael Graff}
d98c74e2ec5b96bd22aa4ed6d893e8993787493bMichael Graff
2bcb48cfcae36398454c98e40c563e2cde748e07Michael Graffstatic isc_result_t
d1fb73ada84ee15ea078c80b1cd0ca8ddc6aa856Michael Graffhmacsha1_tofile(const dst_key_t *key, const char *directory) {
01883602b1e9c0a91f1c3526d80d8ef9db747e92Mark Andrews int cnt = 0;
d98c74e2ec5b96bd22aa4ed6d893e8993787493bMichael Graff dst_hmacsha1_key_t *hkey;
2bcb48cfcae36398454c98e40c563e2cde748e07Michael Graff dst_private_t priv;
2bcb48cfcae36398454c98e40c563e2cde748e07Michael Graff int bytes = (key->key_size + 7) / 8;
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff unsigned char buf[2];
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff if (key->keydata.hmacsha1 == NULL)
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff return (DST_R_NULLKEY);
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff hkey = key->keydata.hmacsha1;
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff priv.elements[cnt].tag = TAG_HMACSHA1_KEY;
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff priv.elements[cnt].length = bytes;
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff priv.elements[cnt++].data = hkey->key;
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff buf[0] = (key->key_bits >> 8) & 0xffU;
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff buf[1] = key->key_bits & 0xffU;
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff priv.elements[cnt].tag = TAG_HMACSHA1_BITS;
59e22acc4f79ff481f7bfa46ef0558957ae53cfcMichael Graff priv.elements[cnt].data = buf;
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff priv.elements[cnt++].length = 2;
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff priv.nelements = cnt;
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff return (dst__privstruct_writefile(key, &priv, directory));
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff}
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff
528829aa8ad69238e674cd81078bc14d4199691bMichael Graffstatic isc_result_t
528829aa8ad69238e674cd81078bc14d4199691bMichael Graffhmacsha1_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff dst_private_t priv;
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley isc_result_t result, tresult;
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff isc_buffer_t b;
6bd8cee98332533a4fa705b82ca9ec1606738ba9Mark Andrews isc_mem_t *mctx = key->mctx;
6bd8cee98332533a4fa705b82ca9ec1606738ba9Mark Andrews unsigned int i;
6bd8cee98332533a4fa705b82ca9ec1606738ba9Mark Andrews
6bd8cee98332533a4fa705b82ca9ec1606738ba9Mark Andrews UNUSED(pub);
6bd8cee98332533a4fa705b82ca9ec1606738ba9Mark Andrews /* read private key file */
6bd8cee98332533a4fa705b82ca9ec1606738ba9Mark Andrews result = dst__privstruct_parse(key, DST_ALG_HMACSHA1, lexer, mctx,
6bd8cee98332533a4fa705b82ca9ec1606738ba9Mark Andrews &priv);
6bd8cee98332533a4fa705b82ca9ec1606738ba9Mark Andrews if (result != ISC_R_SUCCESS)
6bd8cee98332533a4fa705b82ca9ec1606738ba9Mark Andrews return (result);
6bd8cee98332533a4fa705b82ca9ec1606738ba9Mark Andrews
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff key->key_bits = 0;
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff for (i = 0; i < priv.nelements; i++) {
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff switch (priv.elements[i].tag) {
6bd8cee98332533a4fa705b82ca9ec1606738ba9Mark Andrews case TAG_HMACSHA1_KEY:
6bd8cee98332533a4fa705b82ca9ec1606738ba9Mark Andrews isc_buffer_init(&b, priv.elements[i].data,
6bd8cee98332533a4fa705b82ca9ec1606738ba9Mark Andrews priv.elements[i].length);
6bd8cee98332533a4fa705b82ca9ec1606738ba9Mark Andrews isc_buffer_add(&b, priv.elements[i].length);
6bd8cee98332533a4fa705b82ca9ec1606738ba9Mark Andrews tresult = hmacsha1_fromdns(key, &b);
6bd8cee98332533a4fa705b82ca9ec1606738ba9Mark Andrews if (tresult != ISC_R_SUCCESS)
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff result = tresult;
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff break;
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff case TAG_HMACSHA1_BITS:
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff tresult = getkeybits(key, &priv.elements[i]);
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff if (tresult != ISC_R_SUCCESS)
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff result = tresult;
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff break;
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff default:
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff result = DST_R_INVALIDPRIVATEKEY;
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff break;
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff }
4bb16c5856e5c6b05ac43c60f9f9376641bdcccfMark Andrews }
4bb16c5856e5c6b05ac43c60f9f9376641bdcccfMark Andrews dst__privstruct_free(&priv, mctx);
4bb16c5856e5c6b05ac43c60f9f9376641bdcccfMark Andrews memset(&priv, 0, sizeof(priv));
4bb16c5856e5c6b05ac43c60f9f9376641bdcccfMark Andrews return (result);
4bb16c5856e5c6b05ac43c60f9f9376641bdcccfMark Andrews}
d947011dc393d9f9988d1349d585b246d19cc3c7Michael Graff
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graffstatic dst_func_t hmacsha1_functions = {
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff hmacsha1_createctx,
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff hmacsha1_destroyctx,
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff hmacsha1_adddata,
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff hmacsha1_sign,
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff hmacsha1_verify,
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff NULL, /* verify2 */
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff NULL, /* computesecret */
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff hmacsha1_compare,
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff NULL, /* paramcompare */
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff hmacsha1_generate,
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff hmacsha1_isprivate,
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff hmacsha1_destroy,
6dde125c2f47617ceef1518cf9e5588e8f366b71Michael Graff hmacsha1_todns,
6dde125c2f47617ceef1518cf9e5588e8f366b71Michael Graff hmacsha1_fromdns,
6dde125c2f47617ceef1518cf9e5588e8f366b71Michael Graff hmacsha1_tofile,
6dde125c2f47617ceef1518cf9e5588e8f366b71Michael Graff hmacsha1_parse,
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff NULL, /* cleanup */
6dde125c2f47617ceef1518cf9e5588e8f366b71Michael Graff NULL, /* fromlabel */
2bcb48cfcae36398454c98e40c563e2cde748e07Michael Graff NULL, /* dump */
2bcb48cfcae36398454c98e40c563e2cde748e07Michael Graff NULL, /* restore */
2bcb48cfcae36398454c98e40c563e2cde748e07Michael Graff};
2bcb48cfcae36398454c98e40c563e2cde748e07Michael Graff
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graffisc_result_t
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graffdst__hmacsha1_init(dst_func_t **funcp) {
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff REQUIRE(funcp != NULL);
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graff if (*funcp == NULL)
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence *funcp = &hmacsha1_functions;
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff return (ISC_R_SUCCESS);
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graff}
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graff
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graffstatic isc_result_t hmacsha224_fromdns(dst_key_t *key, isc_buffer_t *data);
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graffstruct dst_hmacsha224_key {
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff unsigned char key[ISC_SHA224_BLOCK_LENGTH];
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff};
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graffstatic isc_result_t
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graffhmacsha224_createctx(dst_key_t *key, dst_context_t *dctx) {
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff isc_hmacsha224_t *hmacsha224ctx;
78854e02c127f31ab90f56da0531542004b45377Michael Graff dst_hmacsha224_key_t *hkey = key->keydata.hmacsha224;
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graff
7ec42e4be45c0486ce80461293f377fb4b904dc0Michael Graff hmacsha224ctx = isc_mem_get(dctx->mctx, sizeof(isc_hmacsha224_t));
7ec42e4be45c0486ce80461293f377fb4b904dc0Michael Graff if (hmacsha224ctx == NULL)
7ec42e4be45c0486ce80461293f377fb4b904dc0Michael Graff return (ISC_R_NOMEMORY);
7ec42e4be45c0486ce80461293f377fb4b904dc0Michael Graff isc_hmacsha224_init(hmacsha224ctx, hkey->key, ISC_SHA224_BLOCK_LENGTH);
517274e709a3c730cd42f37dc1260dde95d1ea38Michael Graff dctx->ctxdata.hmacsha224ctx = hmacsha224ctx;
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graff return (ISC_R_SUCCESS);
7ec42e4be45c0486ce80461293f377fb4b904dc0Michael Graff}
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graff
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graffstatic void
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graffhmacsha224_destroyctx(dst_context_t *dctx) {
7ec42e4be45c0486ce80461293f377fb4b904dc0Michael Graff isc_hmacsha224_t *hmacsha224ctx = dctx->ctxdata.hmacsha224ctx;
7ec42e4be45c0486ce80461293f377fb4b904dc0Michael Graff
7ec42e4be45c0486ce80461293f377fb4b904dc0Michael Graff if (hmacsha224ctx != NULL) {
7ec42e4be45c0486ce80461293f377fb4b904dc0Michael Graff isc_hmacsha224_invalidate(hmacsha224ctx);
7ec42e4be45c0486ce80461293f377fb4b904dc0Michael Graff isc_mem_put(dctx->mctx, hmacsha224ctx, sizeof(isc_hmacsha224_t));
7ec42e4be45c0486ce80461293f377fb4b904dc0Michael Graff dctx->ctxdata.hmacsha224ctx = NULL;
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff }
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graff}
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graff
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halleystatic isc_result_t
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graffhmacsha224_adddata(dst_context_t *dctx, const isc_region_t *data) {
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff isc_hmacsha224_t *hmacsha224ctx = dctx->ctxdata.hmacsha224ctx;
7ec42e4be45c0486ce80461293f377fb4b904dc0Michael Graff
7ec42e4be45c0486ce80461293f377fb4b904dc0Michael Graff isc_hmacsha224_update(hmacsha224ctx, data->base, data->length);
7ec42e4be45c0486ce80461293f377fb4b904dc0Michael Graff return (ISC_R_SUCCESS);
7ec42e4be45c0486ce80461293f377fb4b904dc0Michael Graff}
517274e709a3c730cd42f37dc1260dde95d1ea38Michael Graff
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graffstatic isc_result_t
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graffhmacsha224_sign(dst_context_t *dctx, isc_buffer_t *sig) {
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff isc_hmacsha224_t *hmacsha224ctx = dctx->ctxdata.hmacsha224ctx;
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graff unsigned char *digest;
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graff
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff if (isc_buffer_availablelength(sig) < ISC_SHA224_DIGESTLENGTH)
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff return (ISC_R_NOSPACE);
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley digest = isc_buffer_used(sig);
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff isc_hmacsha224_sign(hmacsha224ctx, digest, ISC_SHA224_DIGESTLENGTH);
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graff isc_buffer_add(sig, ISC_SHA224_DIGESTLENGTH);
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff return (ISC_R_SUCCESS);
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff}
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graffstatic isc_result_t
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graffhmacsha224_verify(dst_context_t *dctx, const isc_region_t *sig) {
081cff0c33514a5dc63ab794fc199c07377ab756Mark Andrews isc_hmacsha224_t *hmacsha224ctx = dctx->ctxdata.hmacsha224ctx;
081cff0c33514a5dc63ab794fc199c07377ab756Mark Andrews
081cff0c33514a5dc63ab794fc199c07377ab756Mark Andrews if (sig->length > ISC_SHA224_DIGESTLENGTH || sig->length == 0)
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff return (DST_R_VERIFYFAILURE);
081cff0c33514a5dc63ab794fc199c07377ab756Mark Andrews
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graff if (isc_hmacsha224_verify(hmacsha224ctx, sig->base, sig->length))
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graff return (ISC_R_SUCCESS);
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff else
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff return (DST_R_VERIFYFAILURE);
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff}
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff
5f1f24822fabe7b78af5f81553bfc11a170326c3Mark Andrewsstatic isc_boolean_t
081cff0c33514a5dc63ab794fc199c07377ab756Mark Andrewshmacsha224_compare(const dst_key_t *key1, const dst_key_t *key2) {
081cff0c33514a5dc63ab794fc199c07377ab756Mark Andrews dst_hmacsha224_key_t *hkey1, *hkey2;
5f1f24822fabe7b78af5f81553bfc11a170326c3Mark Andrews
5f1f24822fabe7b78af5f81553bfc11a170326c3Mark Andrews hkey1 = key1->keydata.hmacsha224;
081cff0c33514a5dc63ab794fc199c07377ab756Mark Andrews hkey2 = key2->keydata.hmacsha224;
081cff0c33514a5dc63ab794fc199c07377ab756Mark Andrews
081cff0c33514a5dc63ab794fc199c07377ab756Mark Andrews if (hkey1 == NULL && hkey2 == NULL)
081cff0c33514a5dc63ab794fc199c07377ab756Mark Andrews return (ISC_TRUE);
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff else if (hkey1 == NULL || hkey2 == NULL)
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff return (ISC_FALSE);
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff if (isc_safe_memcmp(hkey1->key, hkey2->key, ISC_SHA224_BLOCK_LENGTH))
081cff0c33514a5dc63ab794fc199c07377ab756Mark Andrews return (ISC_TRUE);
081cff0c33514a5dc63ab794fc199c07377ab756Mark Andrews else
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff return (ISC_FALSE);
93d3a6fd20aceb9998eca4723bba8810243e7689Michael Graff}
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graff
f788a5704623c1d686b770a0f014fd52834d4a67Michael Graffstatic isc_result_t
93d3a6fd20aceb9998eca4723bba8810243e7689Michael Graffhmacsha224_generate(dst_key_t *key, int pseudorandom_ok,
3d12fa7e76c02d06e1adeaa7846b60378a3cd204Michael Graff void (*callback)(int))
d92770e851ebbc1005b3bf121e3c9f13b67a3f42Mark Andrews{
59e22acc4f79ff481f7bfa46ef0558957ae53cfcMichael Graff isc_buffer_t b;
59e22acc4f79ff481f7bfa46ef0558957ae53cfcMichael Graff isc_result_t ret;
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff unsigned int bytes;
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff unsigned char data[ISC_SHA224_BLOCK_LENGTH];
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff
081cff0c33514a5dc63ab794fc199c07377ab756Mark Andrews UNUSED(callback);
081cff0c33514a5dc63ab794fc199c07377ab756Mark Andrews
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff bytes = (key->key_size + 7) / 8;
93d3a6fd20aceb9998eca4723bba8810243e7689Michael Graff if (bytes > ISC_SHA224_BLOCK_LENGTH) {
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graff bytes = ISC_SHA224_BLOCK_LENGTH;
f788a5704623c1d686b770a0f014fd52834d4a67Michael Graff key->key_size = ISC_SHA224_BLOCK_LENGTH * 8;
93d3a6fd20aceb9998eca4723bba8810243e7689Michael Graff }
3d12fa7e76c02d06e1adeaa7846b60378a3cd204Michael Graff
d92770e851ebbc1005b3bf121e3c9f13b67a3f42Mark Andrews memset(data, 0, ISC_SHA224_BLOCK_LENGTH);
59e22acc4f79ff481f7bfa46ef0558957ae53cfcMichael Graff ret = dst__entropy_getdata(data, bytes, ISC_TF(pseudorandom_ok != 0));
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley if (ret != ISC_R_SUCCESS)
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley return (ret);
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley
081cff0c33514a5dc63ab794fc199c07377ab756Mark Andrews isc_buffer_init(&b, data, bytes);
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley isc_buffer_add(&b, bytes);
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley ret = hmacsha224_fromdns(key, &b);
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley memset(data, 0, ISC_SHA224_BLOCK_LENGTH);
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graff
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff return (ret);
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff}
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graffstatic isc_boolean_t
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graffhmacsha224_isprivate(const dst_key_t *key) {
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff UNUSED(key);
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence return (ISC_TRUE);
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff}
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff
d43c2cc7bc4022701f141e299ea8f3fb1d0640c2Michael Graffstatic void
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graffhmacsha224_destroy(dst_key_t *key) {
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff dst_hmacsha224_key_t *hkey = key->keydata.hmacsha224;
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff memset(hkey, 0, sizeof(dst_hmacsha224_key_t));
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff isc_mem_put(key->mctx, hkey, sizeof(dst_hmacsha224_key_t));
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff key->keydata.hmacsha224 = NULL;
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff}
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graff
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencestatic isc_result_t
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graffhmacsha224_todns(const dst_key_t *key, isc_buffer_t *data) {
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graff dst_hmacsha224_key_t *hkey;
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff unsigned int bytes;
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff REQUIRE(key->keydata.hmacsha224 != NULL);
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff
d43c2cc7bc4022701f141e299ea8f3fb1d0640c2Michael Graff hkey = key->keydata.hmacsha224;
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff bytes = (key->key_size + 7) / 8;
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff if (isc_buffer_availablelength(data) < bytes)
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley return (ISC_R_NOSPACE);
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graff isc_buffer_putmem(data, hkey->key, bytes);
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graff
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff return (ISC_R_SUCCESS);
a385f150bb21b8b81f70ed7df545357a83f1da82Michael Graff}
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halleystatic isc_result_t
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halleyhmacsha224_fromdns(dst_key_t *key, isc_buffer_t *data) {
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley dst_hmacsha224_key_t *hkey;
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence int keylen;
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley isc_region_t r;
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley isc_sha224_t sha224ctx;
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley isc_buffer_remainingregion(data, &r);
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley if (r.length == 0)
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley return (ISC_R_SUCCESS);
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley hkey = isc_mem_get(key->mctx, sizeof(dst_hmacsha224_key_t));
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graff if (hkey == NULL)
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence return (ISC_R_NOMEMORY);
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graff memset(hkey->key, 0, sizeof(hkey->key));
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley if (r.length > ISC_SHA224_BLOCK_LENGTH) {
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley isc_sha224_init(&sha224ctx);
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley isc_sha224_update(&sha224ctx, r.base, r.length);
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley isc_sha224_final(hkey->key, &sha224ctx);
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley keylen = ISC_SHA224_DIGESTLENGTH;
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley } else {
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley memmove(hkey->key, r.base, r.length);
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley keylen = r.length;
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graff }
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graff
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley key->key_size = keylen * 8;
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley key->keydata.hmacsha224 = hkey;
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence return (ISC_R_SUCCESS);
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff}
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graffstatic isc_result_t
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graffhmacsha224_tofile(const dst_key_t *key, const char *directory) {
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff int cnt = 0;
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff dst_hmacsha224_key_t *hkey;
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff dst_private_t priv;
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff int bytes = (key->key_size + 7) / 8;
a385f150bb21b8b81f70ed7df545357a83f1da82Michael Graff unsigned char buf[2];
a385f150bb21b8b81f70ed7df545357a83f1da82Michael Graff
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff if (key->keydata.hmacsha224 == NULL)
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graff return (DST_R_NULLKEY);
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff hkey = key->keydata.hmacsha224;
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graff
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff priv.elements[cnt].tag = TAG_HMACSHA224_KEY;
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff priv.elements[cnt].length = bytes;
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff priv.elements[cnt++].data = hkey->key;
0e27dac042d622ff9cde568a90347e1d53b9d784Andreas Gustafsson
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff buf[0] = (key->key_bits >> 8) & 0xffU;
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff buf[1] = key->key_bits & 0xffU;
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff priv.elements[cnt].tag = TAG_HMACSHA224_BITS;
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff priv.elements[cnt].data = buf;
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley priv.elements[cnt++].length = 2;
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley priv.nelements = cnt;
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley return (dst__privstruct_writefile(key, &priv, directory));
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley}
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graffstatic isc_result_t
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graffhmacsha224_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley dst_private_t priv;
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley isc_result_t result, tresult;
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley isc_buffer_t b;
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley isc_mem_t *mctx = key->mctx;
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley unsigned int i;
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley UNUSED(pub);
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley /* read private key file */
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley result = dst__privstruct_parse(key, DST_ALG_HMACSHA224, lexer, mctx,
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graff &priv);
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graff if (result != ISC_R_SUCCESS)
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graff return (result);
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley key->key_bits = 0;
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff for (i = 0; i < priv.nelements; i++) {
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff switch (priv.elements[i].tag) {
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff case TAG_HMACSHA224_KEY:
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff isc_buffer_init(&b, priv.elements[i].data,
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graff priv.elements[i].length);
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff isc_buffer_add(&b, priv.elements[i].length);
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff tresult = hmacsha224_fromdns(key, &b);
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley if (tresult != ISC_R_SUCCESS)
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley result = tresult;
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley break;
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley case TAG_HMACSHA224_BITS:
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graff tresult = getkeybits(key, &priv.elements[i]);
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence if (tresult != ISC_R_SUCCESS)
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley result = tresult;
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graff break;
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley default:
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley result = DST_R_INVALIDPRIVATEKEY;
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley break;
0e27dac042d622ff9cde568a90347e1d53b9d784Andreas Gustafsson }
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley }
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley dst__privstruct_free(&priv, mctx);
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley memset(&priv, 0, sizeof(priv));
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley return (result);
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley}
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halleystatic dst_func_t hmacsha224_functions = {
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley hmacsha224_createctx,
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley hmacsha224_destroyctx,
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley hmacsha224_adddata,
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graff hmacsha224_sign,
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley hmacsha224_verify,
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley NULL, /* verify2 */
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley NULL, /* computesecret */
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley hmacsha224_compare,
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley NULL, /* paramcompare */
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley hmacsha224_generate,
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley hmacsha224_isprivate,
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley hmacsha224_destroy,
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley hmacsha224_todns,
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graff hmacsha224_fromdns,
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley hmacsha224_tofile,
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graff hmacsha224_parse,
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graff NULL, /* cleanup */
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley NULL, /* fromlabel */
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley NULL, /* dump */
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley NULL, /* restore */
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley};
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley
fbc09123cd0cac8d513165c441ef2b2ed9b3445cBob Halleyisc_result_t
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halleydst__hmacsha224_init(dst_func_t **funcp) {
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graff REQUIRE(funcp != NULL);
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley if (*funcp == NULL)
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley *funcp = &hmacsha224_functions;
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff return (ISC_R_SUCCESS);
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff}
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graffstatic isc_result_t hmacsha256_fromdns(dst_key_t *key, isc_buffer_t *data);
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence
517274e709a3c730cd42f37dc1260dde95d1ea38Michael Graffstruct dst_hmacsha256_key {
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley unsigned char key[ISC_SHA256_BLOCK_LENGTH];
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence};
517274e709a3c730cd42f37dc1260dde95d1ea38Michael Graff
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halleystatic isc_result_t
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graffhmacsha256_createctx(dst_key_t *key, dst_context_t *dctx) {
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff isc_hmacsha256_t *hmacsha256ctx;
f181f94ec8da8b1dbcc6353e8be965ea4a5ea282Michael Graff dst_hmacsha256_key_t *hkey = key->keydata.hmacsha256;
f181f94ec8da8b1dbcc6353e8be965ea4a5ea282Michael Graff
f181f94ec8da8b1dbcc6353e8be965ea4a5ea282Michael Graff hmacsha256ctx = isc_mem_get(dctx->mctx, sizeof(isc_hmacsha256_t));
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graff if (hmacsha256ctx == NULL)
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence return (ISC_R_NOMEMORY);
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff isc_hmacsha256_init(hmacsha256ctx, hkey->key, ISC_SHA256_BLOCK_LENGTH);
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff dctx->ctxdata.hmacsha256ctx = hmacsha256ctx;
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff return (ISC_R_SUCCESS);
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graff}
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graffstatic void
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graffhmacsha256_destroyctx(dst_context_t *dctx) {
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff isc_hmacsha256_t *hmacsha256ctx = dctx->ctxdata.hmacsha256ctx;
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff if (hmacsha256ctx != NULL) {
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff isc_hmacsha256_invalidate(hmacsha256ctx);
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff isc_mem_put(dctx->mctx, hmacsha256ctx, sizeof(isc_hmacsha256_t));
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff dctx->ctxdata.hmacsha256ctx = NULL;
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff }
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff}
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graffstatic isc_result_t
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graffhmacsha256_adddata(dst_context_t *dctx, const isc_region_t *data) {
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff isc_hmacsha256_t *hmacsha256ctx = dctx->ctxdata.hmacsha256ctx;
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff isc_hmacsha256_update(hmacsha256ctx, data->base, data->length);
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff return (ISC_R_SUCCESS);
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff}
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graffstatic isc_result_t
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graffhmacsha256_sign(dst_context_t *dctx, isc_buffer_t *sig) {
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff isc_hmacsha256_t *hmacsha256ctx = dctx->ctxdata.hmacsha256ctx;
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff unsigned char *digest;
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff if (isc_buffer_availablelength(sig) < ISC_SHA256_DIGESTLENGTH)
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff return (ISC_R_NOSPACE);
d43c2cc7bc4022701f141e299ea8f3fb1d0640c2Michael Graff digest = isc_buffer_used(sig);
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff isc_hmacsha256_sign(hmacsha256ctx, digest, ISC_SHA256_DIGESTLENGTH);
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff isc_buffer_add(sig, ISC_SHA256_DIGESTLENGTH);
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff return (ISC_R_SUCCESS);
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff}
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graffstatic isc_result_t
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graffhmacsha256_verify(dst_context_t *dctx, const isc_region_t *sig) {
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff isc_hmacsha256_t *hmacsha256ctx = dctx->ctxdata.hmacsha256ctx;
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley if (sig->length > ISC_SHA256_DIGESTLENGTH || sig->length == 0)
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley return (DST_R_VERIFYFAILURE);
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley if (isc_hmacsha256_verify(hmacsha256ctx, sig->base, sig->length))
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley return (ISC_R_SUCCESS);
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley else
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley return (DST_R_VERIFYFAILURE);
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley}
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halleystatic isc_boolean_t
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halleyhmacsha256_compare(const dst_key_t *key1, const dst_key_t *key2) {
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley dst_hmacsha256_key_t *hkey1, *hkey2;
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley hkey1 = key1->keydata.hmacsha256;
e407562a75eb93073bb72089cced150d7ffe4d4fTatuya JINMEI 神明達哉 hkey2 = key2->keydata.hmacsha256;
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews if (hkey1 == NULL && hkey2 == NULL)
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley return (ISC_TRUE);
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley else if (hkey1 == NULL || hkey2 == NULL)
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley return (ISC_FALSE);
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley if (isc_safe_memcmp(hkey1->key, hkey2->key, ISC_SHA256_BLOCK_LENGTH))
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley return (ISC_TRUE);
d1cbf714097e900ed1703529584d3e1a50e8a4a8Brian Wellington else
d1cbf714097e900ed1703529584d3e1a50e8a4a8Brian Wellington return (ISC_FALSE);
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley}
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halleystatic isc_result_t
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halleyhmacsha256_generate(dst_key_t *key, int pseudorandom_ok,
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley void (*callback)(int))
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley{
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley isc_buffer_t b;
d1cbf714097e900ed1703529584d3e1a50e8a4a8Brian Wellington isc_result_t ret;
d1cbf714097e900ed1703529584d3e1a50e8a4a8Brian Wellington unsigned int bytes;
d1cbf714097e900ed1703529584d3e1a50e8a4a8Brian Wellington unsigned char data[ISC_SHA256_BLOCK_LENGTH];
d1cbf714097e900ed1703529584d3e1a50e8a4a8Brian Wellington
d1cbf714097e900ed1703529584d3e1a50e8a4a8Brian Wellington UNUSED(callback);
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley bytes = (key->key_size + 7) / 8;
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley if (bytes > ISC_SHA256_BLOCK_LENGTH) {
d1cbf714097e900ed1703529584d3e1a50e8a4a8Brian Wellington bytes = ISC_SHA256_BLOCK_LENGTH;
d1cbf714097e900ed1703529584d3e1a50e8a4a8Brian Wellington key->key_size = ISC_SHA256_BLOCK_LENGTH * 8;
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley }
e407562a75eb93073bb72089cced150d7ffe4d4fTatuya JINMEI 神明達哉
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley memset(data, 0, ISC_SHA256_BLOCK_LENGTH);
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley ret = dst__entropy_getdata(data, bytes, ISC_TF(pseudorandom_ok != 0));
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley if (ret != ISC_R_SUCCESS)
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley return (ret);
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley isc_buffer_init(&b, data, bytes);
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley isc_buffer_add(&b, bytes);
d1cbf714097e900ed1703529584d3e1a50e8a4a8Brian Wellington ret = hmacsha256_fromdns(key, &b);
d1cbf714097e900ed1703529584d3e1a50e8a4a8Brian Wellington memset(data, 0, ISC_SHA256_BLOCK_LENGTH);
d1cbf714097e900ed1703529584d3e1a50e8a4a8Brian Wellington
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley return (ret);
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley}
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halleystatic isc_boolean_t
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halleyhmacsha256_isprivate(const dst_key_t *key) {
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley UNUSED(key);
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley return (ISC_TRUE);
e407562a75eb93073bb72089cced150d7ffe4d4fTatuya JINMEI 神明達哉}
e180037bc15a98cac0b91ffcf464e9c96918294bMark Andrews
e180037bc15a98cac0b91ffcf464e9c96918294bMark Andrewsstatic void
d1cbf714097e900ed1703529584d3e1a50e8a4a8Brian Wellingtonhmacsha256_destroy(dst_key_t *key) {
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley dst_hmacsha256_key_t *hkey = key->keydata.hmacsha256;
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley memset(hkey, 0, sizeof(dst_hmacsha256_key_t));
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley isc_mem_put(key->mctx, hkey, sizeof(dst_hmacsha256_key_t));
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley key->keydata.hmacsha256 = NULL;
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley}
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halleystatic isc_result_t
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halleyhmacsha256_todns(const dst_key_t *key, isc_buffer_t *data) {
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley dst_hmacsha256_key_t *hkey;
897c9ddb4d745b2bfecf98b17e5487bb6656299aMichael Graff unsigned int bytes;
897c9ddb4d745b2bfecf98b17e5487bb6656299aMichael Graff
897c9ddb4d745b2bfecf98b17e5487bb6656299aMichael Graff REQUIRE(key->keydata.hmacsha256 != NULL);
897c9ddb4d745b2bfecf98b17e5487bb6656299aMichael Graff
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence hkey = key->keydata.hmacsha256;
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff
897c9ddb4d745b2bfecf98b17e5487bb6656299aMichael Graff bytes = (key->key_size + 7) / 8;
897c9ddb4d745b2bfecf98b17e5487bb6656299aMichael Graff if (isc_buffer_availablelength(data) < bytes)
e44487bfc23599b6b240e09d83d1c862fecfcc82Michael Graff return (ISC_R_NOSPACE);
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff isc_buffer_putmem(data, hkey->key, bytes);
897c9ddb4d745b2bfecf98b17e5487bb6656299aMichael Graff
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff return (ISC_R_SUCCESS);
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff}
e44487bfc23599b6b240e09d83d1c862fecfcc82Michael Graff
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graffstatic isc_result_t
897c9ddb4d745b2bfecf98b17e5487bb6656299aMichael Graffhmacsha256_fromdns(dst_key_t *key, isc_buffer_t *data) {
897c9ddb4d745b2bfecf98b17e5487bb6656299aMichael Graff dst_hmacsha256_key_t *hkey;
f181f94ec8da8b1dbcc6353e8be965ea4a5ea282Michael Graff int keylen;
f181f94ec8da8b1dbcc6353e8be965ea4a5ea282Michael Graff isc_region_t r;
f181f94ec8da8b1dbcc6353e8be965ea4a5ea282Michael Graff isc_sha256_t sha256ctx;
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff isc_buffer_remainingregion(data, &r);
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff if (r.length == 0)
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff return (ISC_R_SUCCESS);
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff hkey = isc_mem_get(key->mctx, sizeof(dst_hmacsha256_key_t));
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff if (hkey == NULL)
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff return (ISC_R_NOMEMORY);
78854e02c127f31ab90f56da0531542004b45377Michael Graff
306a93530536f05edfb477cac1c2667d90129a8fMichael Graff memset(hkey->key, 0, sizeof(hkey->key));
78854e02c127f31ab90f56da0531542004b45377Michael Graff
78854e02c127f31ab90f56da0531542004b45377Michael Graff if (r.length > ISC_SHA256_BLOCK_LENGTH) {
78854e02c127f31ab90f56da0531542004b45377Michael Graff isc_sha256_init(&sha256ctx);
78854e02c127f31ab90f56da0531542004b45377Michael Graff isc_sha256_update(&sha256ctx, r.base, r.length);
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff isc_sha256_final(hkey->key, &sha256ctx);
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff keylen = ISC_SHA256_DIGESTLENGTH;
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff } else {
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff memmove(hkey->key, r.base, r.length);
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff keylen = r.length;
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff }
78854e02c127f31ab90f56da0531542004b45377Michael Graff
78854e02c127f31ab90f56da0531542004b45377Michael Graff key->key_size = keylen * 8;
306a93530536f05edfb477cac1c2667d90129a8fMichael Graff key->keydata.hmacsha256 = hkey;
78854e02c127f31ab90f56da0531542004b45377Michael Graff
78854e02c127f31ab90f56da0531542004b45377Michael Graff return (ISC_R_SUCCESS);
78854e02c127f31ab90f56da0531542004b45377Michael Graff}
550085fed1d0af54ba5b2f588898afec158195deMark Andrews
306a93530536f05edfb477cac1c2667d90129a8fMichael Graffstatic isc_result_t
78854e02c127f31ab90f56da0531542004b45377Michael Graffhmacsha256_tofile(const dst_key_t *key, const char *directory) {
78854e02c127f31ab90f56da0531542004b45377Michael Graff int cnt = 0;
78854e02c127f31ab90f56da0531542004b45377Michael Graff dst_hmacsha256_key_t *hkey;
78854e02c127f31ab90f56da0531542004b45377Michael Graff dst_private_t priv;
78854e02c127f31ab90f56da0531542004b45377Michael Graff int bytes = (key->key_size + 7) / 8;
550085fed1d0af54ba5b2f588898afec158195deMark Andrews unsigned char buf[2];
78854e02c127f31ab90f56da0531542004b45377Michael Graff
78854e02c127f31ab90f56da0531542004b45377Michael Graff if (key->keydata.hmacsha256 == NULL)
306a93530536f05edfb477cac1c2667d90129a8fMichael Graff return (DST_R_NULLKEY);
78854e02c127f31ab90f56da0531542004b45377Michael Graff
78854e02c127f31ab90f56da0531542004b45377Michael Graff hkey = key->keydata.hmacsha256;
78854e02c127f31ab90f56da0531542004b45377Michael Graff
78854e02c127f31ab90f56da0531542004b45377Michael Graff priv.elements[cnt].tag = TAG_HMACSHA256_KEY;
78854e02c127f31ab90f56da0531542004b45377Michael Graff priv.elements[cnt].length = bytes;
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff priv.elements[cnt++].data = hkey->key;
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff
78854e02c127f31ab90f56da0531542004b45377Michael Graff buf[0] = (key->key_bits >> 8) & 0xffU;
78854e02c127f31ab90f56da0531542004b45377Michael Graff buf[1] = key->key_bits & 0xffU;
78854e02c127f31ab90f56da0531542004b45377Michael Graff priv.elements[cnt].tag = TAG_HMACSHA256_BITS;
78854e02c127f31ab90f56da0531542004b45377Michael Graff priv.elements[cnt].data = buf;
78854e02c127f31ab90f56da0531542004b45377Michael Graff priv.elements[cnt++].length = 2;
78854e02c127f31ab90f56da0531542004b45377Michael Graff
78854e02c127f31ab90f56da0531542004b45377Michael Graff priv.nelements = cnt;
78854e02c127f31ab90f56da0531542004b45377Michael Graff return (dst__privstruct_writefile(key, &priv, directory));
78854e02c127f31ab90f56da0531542004b45377Michael Graff}
78854e02c127f31ab90f56da0531542004b45377Michael Graff
897c9ddb4d745b2bfecf98b17e5487bb6656299aMichael Graffstatic isc_result_t
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graffhmacsha256_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
2a0b8796d46265c078ba7f4dea2979c62ebf5badBob Halley dst_private_t priv;
78854e02c127f31ab90f56da0531542004b45377Michael Graff isc_result_t result, tresult;
e44487bfc23599b6b240e09d83d1c862fecfcc82Michael Graff isc_buffer_t b;
e44487bfc23599b6b240e09d83d1c862fecfcc82Michael Graff isc_mem_t *mctx = key->mctx;
306a93530536f05edfb477cac1c2667d90129a8fMichael Graff unsigned int i;
306a93530536f05edfb477cac1c2667d90129a8fMichael Graff
e44487bfc23599b6b240e09d83d1c862fecfcc82Michael Graff UNUSED(pub);
e44487bfc23599b6b240e09d83d1c862fecfcc82Michael Graff /* read private key file */
e44487bfc23599b6b240e09d83d1c862fecfcc82Michael Graff result = dst__privstruct_parse(key, DST_ALG_HMACSHA256, lexer, mctx,
2a0b8796d46265c078ba7f4dea2979c62ebf5badBob Halley &priv);
78854e02c127f31ab90f56da0531542004b45377Michael Graff if (result != ISC_R_SUCCESS)
7923de0ddd65218a78785a951df5db8b46c0fce3Andreas Gustafsson return (result);
78854e02c127f31ab90f56da0531542004b45377Michael Graff
78854e02c127f31ab90f56da0531542004b45377Michael Graff key->key_bits = 0;
306a93530536f05edfb477cac1c2667d90129a8fMichael Graff for (i = 0; i < priv.nelements; i++) {
78854e02c127f31ab90f56da0531542004b45377Michael Graff switch (priv.elements[i].tag) {
78854e02c127f31ab90f56da0531542004b45377Michael Graff case TAG_HMACSHA256_KEY:
78854e02c127f31ab90f56da0531542004b45377Michael Graff isc_buffer_init(&b, priv.elements[i].data,
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graff priv.elements[i].length);
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff isc_buffer_add(&b, priv.elements[i].length);
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff tresult = hmacsha256_fromdns(key, &b);
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff if (tresult != ISC_R_SUCCESS)
78854e02c127f31ab90f56da0531542004b45377Michael Graff result = tresult;
78854e02c127f31ab90f56da0531542004b45377Michael Graff break;
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff case TAG_HMACSHA256_BITS:
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff tresult = getkeybits(key, &priv.elements[i]);
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff if (tresult != ISC_R_SUCCESS)
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence result = tresult;
e44487bfc23599b6b240e09d83d1c862fecfcc82Michael Graff break;
59c049874bbef182857c57bd9cca292898921c69Bob Halley default:
59c049874bbef182857c57bd9cca292898921c69Bob Halley result = DST_R_INVALIDPRIVATEKEY;
59c049874bbef182857c57bd9cca292898921c69Bob Halley break;
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graff }
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graff }
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graff dst__privstruct_free(&priv, mctx);
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graff memset(&priv, 0, sizeof(priv));
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graff return (result);
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graff}
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graff
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graffstatic dst_func_t hmacsha256_functions = {
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graff hmacsha256_createctx,
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graff hmacsha256_destroyctx,
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graff hmacsha256_adddata,
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graff hmacsha256_sign,
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graff hmacsha256_verify,
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graff NULL, /* verify2 */
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graff NULL, /* computesecret */
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graff hmacsha256_compare,
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graff NULL, /* paramcompare */
59c049874bbef182857c57bd9cca292898921c69Bob Halley hmacsha256_generate,
78bf1ca89505820ed7b03be4bf0c0b53b557f3cdAndreas Gustafsson hmacsha256_isprivate,
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley hmacsha256_destroy,
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graff hmacsha256_todns,
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graff hmacsha256_fromdns,
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graff hmacsha256_tofile,
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graff hmacsha256_parse,
e44487bfc23599b6b240e09d83d1c862fecfcc82Michael Graff NULL, /* cleanup */
e44487bfc23599b6b240e09d83d1c862fecfcc82Michael Graff NULL, /* fromlabel */
e44487bfc23599b6b240e09d83d1c862fecfcc82Michael Graff NULL, /* dump */
e44487bfc23599b6b240e09d83d1c862fecfcc82Michael Graff NULL, /* restore */
e44487bfc23599b6b240e09d83d1c862fecfcc82Michael Graff};
59c049874bbef182857c57bd9cca292898921c69Bob Halley
e44487bfc23599b6b240e09d83d1c862fecfcc82Michael Graffisc_result_t
59c049874bbef182857c57bd9cca292898921c69Bob Halleydst__hmacsha256_init(dst_func_t **funcp) {
59c049874bbef182857c57bd9cca292898921c69Bob Halley REQUIRE(funcp != NULL);
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graff if (*funcp == NULL)
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graff *funcp = &hmacsha256_functions;
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graff return (ISC_R_SUCCESS);
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graff}
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graff
a385f150bb21b8b81f70ed7df545357a83f1da82Michael Graffstatic isc_result_t hmacsha384_fromdns(dst_key_t *key, isc_buffer_t *data);
a385f150bb21b8b81f70ed7df545357a83f1da82Michael Graff
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graffstruct dst_hmacsha384_key {
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graff unsigned char key[ISC_SHA384_BLOCK_LENGTH];
78bf1ca89505820ed7b03be4bf0c0b53b557f3cdAndreas Gustafsson};
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graff
78bf1ca89505820ed7b03be4bf0c0b53b557f3cdAndreas Gustafssonstatic isc_result_t
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graffhmacsha384_createctx(dst_key_t *key, dst_context_t *dctx) {
e51511aa3281f8dc384eb1283115c7f8d5c402aeMichael Graff isc_hmacsha384_t *hmacsha384ctx;
e51511aa3281f8dc384eb1283115c7f8d5c402aeMichael Graff dst_hmacsha384_key_t *hkey = key->keydata.hmacsha384;
78bf1ca89505820ed7b03be4bf0c0b53b557f3cdAndreas Gustafsson
78bf1ca89505820ed7b03be4bf0c0b53b557f3cdAndreas Gustafsson hmacsha384ctx = isc_mem_get(dctx->mctx, sizeof(isc_hmacsha384_t));
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff if (hmacsha384ctx == NULL)
78bf1ca89505820ed7b03be4bf0c0b53b557f3cdAndreas Gustafsson return (ISC_R_NOMEMORY);
e51511aa3281f8dc384eb1283115c7f8d5c402aeMichael Graff isc_hmacsha384_init(hmacsha384ctx, hkey->key, ISC_SHA384_BLOCK_LENGTH);
e51511aa3281f8dc384eb1283115c7f8d5c402aeMichael Graff dctx->ctxdata.hmacsha384ctx = hmacsha384ctx;
439c0011e642fb1d26011116144af698125262dbMichael Graff return (ISC_R_SUCCESS);
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence}
439c0011e642fb1d26011116144af698125262dbMichael Graff
439c0011e642fb1d26011116144af698125262dbMichael Graffstatic void
439c0011e642fb1d26011116144af698125262dbMichael Graffhmacsha384_destroyctx(dst_context_t *dctx) {
439c0011e642fb1d26011116144af698125262dbMichael Graff isc_hmacsha384_t *hmacsha384ctx = dctx->ctxdata.hmacsha384ctx;
439c0011e642fb1d26011116144af698125262dbMichael Graff
439c0011e642fb1d26011116144af698125262dbMichael Graff if (hmacsha384ctx != NULL) {
439c0011e642fb1d26011116144af698125262dbMichael Graff isc_hmacsha384_invalidate(hmacsha384ctx);
439c0011e642fb1d26011116144af698125262dbMichael Graff isc_mem_put(dctx->mctx, hmacsha384ctx, sizeof(isc_hmacsha384_t));
439c0011e642fb1d26011116144af698125262dbMichael Graff dctx->ctxdata.hmacsha384ctx = NULL;
439c0011e642fb1d26011116144af698125262dbMichael Graff }
439c0011e642fb1d26011116144af698125262dbMichael Graff}
439c0011e642fb1d26011116144af698125262dbMichael Graff
439c0011e642fb1d26011116144af698125262dbMichael Graffstatic isc_result_t
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graffhmacsha384_adddata(dst_context_t *dctx, const isc_region_t *data) {
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence isc_hmacsha384_t *hmacsha384ctx = dctx->ctxdata.hmacsha384ctx;
439c0011e642fb1d26011116144af698125262dbMichael Graff
439c0011e642fb1d26011116144af698125262dbMichael Graff isc_hmacsha384_update(hmacsha384ctx, data->base, data->length);
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graff return (ISC_R_SUCCESS);
439c0011e642fb1d26011116144af698125262dbMichael Graff}
439c0011e642fb1d26011116144af698125262dbMichael Graff
439c0011e642fb1d26011116144af698125262dbMichael Graffstatic isc_result_t
439c0011e642fb1d26011116144af698125262dbMichael Graffhmacsha384_sign(dst_context_t *dctx, isc_buffer_t *sig) {
439c0011e642fb1d26011116144af698125262dbMichael Graff isc_hmacsha384_t *hmacsha384ctx = dctx->ctxdata.hmacsha384ctx;
439c0011e642fb1d26011116144af698125262dbMichael Graff unsigned char *digest;
439c0011e642fb1d26011116144af698125262dbMichael Graff
439c0011e642fb1d26011116144af698125262dbMichael Graff if (isc_buffer_availablelength(sig) < ISC_SHA384_DIGESTLENGTH)
439c0011e642fb1d26011116144af698125262dbMichael Graff return (ISC_R_NOSPACE);
439c0011e642fb1d26011116144af698125262dbMichael Graff digest = isc_buffer_used(sig);
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley isc_hmacsha384_sign(hmacsha384ctx, digest, ISC_SHA384_DIGESTLENGTH);
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley isc_buffer_add(sig, ISC_SHA384_DIGESTLENGTH);
439c0011e642fb1d26011116144af698125262dbMichael Graff
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graff return (ISC_R_SUCCESS);
439c0011e642fb1d26011116144af698125262dbMichael Graff}
439c0011e642fb1d26011116144af698125262dbMichael Graff
439c0011e642fb1d26011116144af698125262dbMichael Graffstatic isc_result_t
439c0011e642fb1d26011116144af698125262dbMichael Graffhmacsha384_verify(dst_context_t *dctx, const isc_region_t *sig) {
439c0011e642fb1d26011116144af698125262dbMichael Graff isc_hmacsha384_t *hmacsha384ctx = dctx->ctxdata.hmacsha384ctx;
439c0011e642fb1d26011116144af698125262dbMichael Graff
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graff if (sig->length > ISC_SHA384_DIGESTLENGTH || sig->length == 0)
439c0011e642fb1d26011116144af698125262dbMichael Graff return (DST_R_VERIFYFAILURE);
439c0011e642fb1d26011116144af698125262dbMichael Graff
439c0011e642fb1d26011116144af698125262dbMichael Graff if (isc_hmacsha384_verify(hmacsha384ctx, sig->base, sig->length))
439c0011e642fb1d26011116144af698125262dbMichael Graff return (ISC_R_SUCCESS);
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graff else
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graff return (DST_R_VERIFYFAILURE);
5f1f24822fabe7b78af5f81553bfc11a170326c3Mark Andrews}
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graff
439c0011e642fb1d26011116144af698125262dbMichael Graffstatic isc_boolean_t
439c0011e642fb1d26011116144af698125262dbMichael Graffhmacsha384_compare(const dst_key_t *key1, const dst_key_t *key2) {
e51511aa3281f8dc384eb1283115c7f8d5c402aeMichael Graff dst_hmacsha384_key_t *hkey1, *hkey2;
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff hkey1 = key1->keydata.hmacsha384;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff hkey2 = key2->keydata.hmacsha384;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff if (hkey1 == NULL && hkey2 == NULL)
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff return (ISC_TRUE);
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff else if (hkey1 == NULL || hkey2 == NULL)
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff return (ISC_FALSE);
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff if (isc_safe_memcmp(hkey1->key, hkey2->key, ISC_SHA384_BLOCK_LENGTH))
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff return (ISC_TRUE);
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff else
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley return (ISC_FALSE);
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff}
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graff
1f90c108282533a23b8362c34bcde4267c1eb4b1Michael Graffstatic isc_result_t
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graffhmacsha384_generate(dst_key_t *key, int pseudorandom_ok,
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff void (*callback)(int))
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff{
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley isc_buffer_t b;
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley isc_result_t ret;
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff unsigned int bytes;
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff unsigned char data[ISC_SHA384_BLOCK_LENGTH];
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff
59e22acc4f79ff481f7bfa46ef0558957ae53cfcMichael Graff UNUSED(callback);
59e22acc4f79ff481f7bfa46ef0558957ae53cfcMichael Graff
306a93530536f05edfb477cac1c2667d90129a8fMichael Graff bytes = (key->key_size + 7) / 8;
306a93530536f05edfb477cac1c2667d90129a8fMichael Graff if (bytes > ISC_SHA384_BLOCK_LENGTH) {
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff bytes = ISC_SHA384_BLOCK_LENGTH;
d43c2cc7bc4022701f141e299ea8f3fb1d0640c2Michael Graff key->key_size = ISC_SHA384_BLOCK_LENGTH * 8;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff }
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff memset(data, 0, ISC_SHA384_BLOCK_LENGTH);
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff ret = dst__entropy_getdata(data, bytes, ISC_TF(pseudorandom_ok != 0));
e51511aa3281f8dc384eb1283115c7f8d5c402aeMichael Graff
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence if (ret != ISC_R_SUCCESS)
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff return (ret);
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff isc_buffer_init(&b, data, bytes);
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff isc_buffer_add(&b, bytes);
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff ret = hmacsha384_fromdns(key, &b);
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff memset(data, 0, ISC_SHA384_BLOCK_LENGTH);
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff return (ret);
517274e709a3c730cd42f37dc1260dde95d1ea38Michael Graff}
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff
d43c2cc7bc4022701f141e299ea8f3fb1d0640c2Michael Graffstatic isc_boolean_t
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graffhmacsha384_isprivate(const dst_key_t *key) {
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graff UNUSED(key);
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff return (ISC_TRUE);
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff}
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graffstatic void
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graffhmacsha384_destroy(dst_key_t *key) {
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff dst_hmacsha384_key_t *hkey = key->keydata.hmacsha384;
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff
e51511aa3281f8dc384eb1283115c7f8d5c402aeMichael Graff memset(hkey, 0, sizeof(dst_hmacsha384_key_t));
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence isc_mem_put(key->mctx, hkey, sizeof(dst_hmacsha384_key_t));
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff key->keydata.hmacsha384 = NULL;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff}
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graffstatic isc_result_t
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graffhmacsha384_todns(const dst_key_t *key, isc_buffer_t *data) {
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff dst_hmacsha384_key_t *hkey;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff unsigned int bytes;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff
d43c2cc7bc4022701f141e299ea8f3fb1d0640c2Michael Graff REQUIRE(key->keydata.hmacsha384 != NULL);
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff hkey = key->keydata.hmacsha384;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff bytes = (key->key_size + 7) / 8;
e51511aa3281f8dc384eb1283115c7f8d5c402aeMichael Graff if (isc_buffer_availablelength(data) < bytes)
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence return (ISC_R_NOSPACE);
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff isc_buffer_putmem(data, hkey->key, bytes);
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff return (ISC_R_SUCCESS);
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff}
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graffstatic isc_result_t
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graffhmacsha384_fromdns(dst_key_t *key, isc_buffer_t *data) {
d43c2cc7bc4022701f141e299ea8f3fb1d0640c2Michael Graff dst_hmacsha384_key_t *hkey;
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff int keylen;
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff isc_region_t r;
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff isc_sha384_t sha384ctx;
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff isc_buffer_remainingregion(data, &r);
e51511aa3281f8dc384eb1283115c7f8d5c402aeMichael Graff if (r.length == 0)
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence return (ISC_R_SUCCESS);
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff hkey = isc_mem_get(key->mctx, sizeof(dst_hmacsha384_key_t));
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff if (hkey == NULL)
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff return (ISC_R_NOMEMORY);
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff memset(hkey->key, 0, sizeof(hkey->key));
439c0011e642fb1d26011116144af698125262dbMichael Graff
f36a81c88493985ee2d1c53cc6fe88f4b00dbbc8Michael Graff if (r.length > ISC_SHA384_BLOCK_LENGTH) {
f36a81c88493985ee2d1c53cc6fe88f4b00dbbc8Michael Graff isc_sha384_init(&sha384ctx);
f36a81c88493985ee2d1c53cc6fe88f4b00dbbc8Michael Graff isc_sha384_update(&sha384ctx, r.base, r.length);
f36a81c88493985ee2d1c53cc6fe88f4b00dbbc8Michael Graff isc_sha384_final(hkey->key, &sha384ctx);
f36a81c88493985ee2d1c53cc6fe88f4b00dbbc8Michael Graff keylen = ISC_SHA384_DIGESTLENGTH;
f36a81c88493985ee2d1c53cc6fe88f4b00dbbc8Michael Graff } else {
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff memmove(hkey->key, r.base, r.length);
d43c2cc7bc4022701f141e299ea8f3fb1d0640c2Michael Graff keylen = r.length;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff }
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff key->key_size = keylen * 8;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff key->keydata.hmacsha384 = hkey;
439c0011e642fb1d26011116144af698125262dbMichael Graff
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence return (ISC_R_SUCCESS);
439c0011e642fb1d26011116144af698125262dbMichael Graff}
439c0011e642fb1d26011116144af698125262dbMichael Graff
6d14fe95e9ea5bbc5e863e5aab4618f7b3dbcc0fMichael Graffstatic isc_result_t
439c0011e642fb1d26011116144af698125262dbMichael Graffhmacsha384_tofile(const dst_key_t *key, const char *directory) {
439c0011e642fb1d26011116144af698125262dbMichael Graff int cnt = 0;
439c0011e642fb1d26011116144af698125262dbMichael Graff dst_hmacsha384_key_t *hkey;
d43c2cc7bc4022701f141e299ea8f3fb1d0640c2Michael Graff dst_private_t priv;
439c0011e642fb1d26011116144af698125262dbMichael Graff int bytes = (key->key_size + 7) / 8;
439c0011e642fb1d26011116144af698125262dbMichael Graff unsigned char buf[2];
439c0011e642fb1d26011116144af698125262dbMichael Graff
439c0011e642fb1d26011116144af698125262dbMichael Graff if (key->keydata.hmacsha384 == NULL)
439c0011e642fb1d26011116144af698125262dbMichael Graff return (DST_R_NULLKEY);
439c0011e642fb1d26011116144af698125262dbMichael Graff
439c0011e642fb1d26011116144af698125262dbMichael Graff hkey = key->keydata.hmacsha384;
439c0011e642fb1d26011116144af698125262dbMichael Graff
e51511aa3281f8dc384eb1283115c7f8d5c402aeMichael Graff priv.elements[cnt].tag = TAG_HMACSHA384_KEY;
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence priv.elements[cnt].length = bytes;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff priv.elements[cnt++].data = hkey->key;
f181f94ec8da8b1dbcc6353e8be965ea4a5ea282Michael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff buf[0] = (key->key_bits >> 8) & 0xffU;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff buf[1] = key->key_bits & 0xffU;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff priv.elements[cnt].tag = TAG_HMACSHA384_BITS;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff priv.elements[cnt].data = buf;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff priv.elements[cnt++].length = 2;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff priv.nelements = cnt;
439c0011e642fb1d26011116144af698125262dbMichael Graff return (dst__privstruct_writefile(key, &priv, directory));
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff}
7da0286b540515c82ea83163d6cba59a64fa3eddMichael Graff
f181f94ec8da8b1dbcc6353e8be965ea4a5ea282Michael Graffstatic isc_result_t
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halleyhmacsha384_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff dst_private_t priv;
d43c2cc7bc4022701f141e299ea8f3fb1d0640c2Michael Graff isc_result_t result, tresult;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff isc_buffer_t b;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff isc_mem_t *mctx = key->mctx;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff unsigned int i;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff
e51511aa3281f8dc384eb1283115c7f8d5c402aeMichael Graff UNUSED(pub);
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence /* read private key file */
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff result = dst__privstruct_parse(key, DST_ALG_HMACSHA384, lexer, mctx,
3f6a66689410910ef601a4d26f10a24f331ef83cMichael Graff &priv);
6d14fe95e9ea5bbc5e863e5aab4618f7b3dbcc0fMichael Graff if (result != ISC_R_SUCCESS)
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff return (result);
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff key->key_bits = 0;
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff for (i = 0; i < priv.nelements; i++) {
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff switch (priv.elements[i].tag) {
439c0011e642fb1d26011116144af698125262dbMichael Graff case TAG_HMACSHA384_KEY:
d43c2cc7bc4022701f141e299ea8f3fb1d0640c2Michael Graff isc_buffer_init(&b, priv.elements[i].data,
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff priv.elements[i].length);
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff isc_buffer_add(&b, priv.elements[i].length);
3f6a66689410910ef601a4d26f10a24f331ef83cMichael Graff tresult = hmacsha384_fromdns(key, &b);
3f6a66689410910ef601a4d26f10a24f331ef83cMichael Graff if (tresult != ISC_R_SUCCESS)
3f6a66689410910ef601a4d26f10a24f331ef83cMichael Graff result = tresult;
d43c2cc7bc4022701f141e299ea8f3fb1d0640c2Michael Graff break;
3f6a66689410910ef601a4d26f10a24f331ef83cMichael Graff case TAG_HMACSHA384_BITS:
3f6a66689410910ef601a4d26f10a24f331ef83cMichael Graff tresult = getkeybits(key, &priv.elements[i]);
3f6a66689410910ef601a4d26f10a24f331ef83cMichael Graff if (tresult != ISC_R_SUCCESS)
3f6a66689410910ef601a4d26f10a24f331ef83cMichael Graff result = tresult;
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff break;
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff default:
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff result = DST_R_INVALIDPRIVATEKEY;
2992344aacdb08e4af936c176d49ef789f5673ddMichael Graff break;
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence }
2992344aacdb08e4af936c176d49ef789f5673ddMichael Graff }
519b4a1a27c8b767a57a981dda69a3c6394bd49dMichael Graff dst__privstruct_free(&priv, mctx);
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff memset(&priv, 0, sizeof(priv));
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff return (result);
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff}
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graffstatic dst_func_t hmacsha384_functions = {
519b4a1a27c8b767a57a981dda69a3c6394bd49dMichael Graff hmacsha384_createctx,
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence hmacsha384_destroyctx,
519b4a1a27c8b767a57a981dda69a3c6394bd49dMichael Graff hmacsha384_adddata,
519b4a1a27c8b767a57a981dda69a3c6394bd49dMichael Graff hmacsha384_sign,
a385f150bb21b8b81f70ed7df545357a83f1da82Michael Graff hmacsha384_verify,
1f90c108282533a23b8362c34bcde4267c1eb4b1Michael Graff NULL, /* verify2 */
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff NULL, /* computesecret */
78854e02c127f31ab90f56da0531542004b45377Michael Graff hmacsha384_compare,
306a93530536f05edfb477cac1c2667d90129a8fMichael Graff NULL, /* paramcompare */
306a93530536f05edfb477cac1c2667d90129a8fMichael Graff hmacsha384_generate,
d43c2cc7bc4022701f141e299ea8f3fb1d0640c2Michael Graff hmacsha384_isprivate,
d4d2a13916a114879763562db6a19b70b1444ec1Michael Graff hmacsha384_destroy,
519b4a1a27c8b767a57a981dda69a3c6394bd49dMichael Graff hmacsha384_todns,
6d14fe95e9ea5bbc5e863e5aab4618f7b3dbcc0fMichael Graff hmacsha384_fromdns,
897c9ddb4d745b2bfecf98b17e5487bb6656299aMichael Graff hmacsha384_tofile,
519b4a1a27c8b767a57a981dda69a3c6394bd49dMichael Graff hmacsha384_parse,
519b4a1a27c8b767a57a981dda69a3c6394bd49dMichael Graff NULL, /* cleanup */
519b4a1a27c8b767a57a981dda69a3c6394bd49dMichael Graff NULL, /* fromlabel */
519b4a1a27c8b767a57a981dda69a3c6394bd49dMichael Graff NULL, /* dump */
519b4a1a27c8b767a57a981dda69a3c6394bd49dMichael Graff NULL, /* restore */
519b4a1a27c8b767a57a981dda69a3c6394bd49dMichael Graff};
519b4a1a27c8b767a57a981dda69a3c6394bd49dMichael Graff
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graffisc_result_t
519b4a1a27c8b767a57a981dda69a3c6394bd49dMichael Graffdst__hmacsha384_init(dst_func_t **funcp) {
519b4a1a27c8b767a57a981dda69a3c6394bd49dMichael Graff REQUIRE(funcp != NULL);
519b4a1a27c8b767a57a981dda69a3c6394bd49dMichael Graff if (*funcp == NULL)
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff *funcp = &hmacsha384_functions;
f3ca27e9fe307b55e35ea8d7b37351650630e5a3Andreas Gustafsson return (ISC_R_SUCCESS);
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff}
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graffstatic isc_result_t hmacsha512_fromdns(dst_key_t *key, isc_buffer_t *data);
2992344aacdb08e4af936c176d49ef789f5673ddMichael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graffstruct dst_hmacsha512_key {
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff unsigned char key[ISC_SHA512_BLOCK_LENGTH];
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff};
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencestatic isc_result_t
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graffhmacsha512_createctx(dst_key_t *key, dst_context_t *dctx) {
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff isc_hmacsha512_t *hmacsha512ctx;
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff dst_hmacsha512_key_t *hkey = key->keydata.hmacsha512;
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff hmacsha512ctx = isc_mem_get(dctx->mctx, sizeof(isc_hmacsha512_t));
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff if (hmacsha512ctx == NULL)
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff return (ISC_R_NOMEMORY);
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff isc_hmacsha512_init(hmacsha512ctx, hkey->key, ISC_SHA512_BLOCK_LENGTH);
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff dctx->ctxdata.hmacsha512ctx = hmacsha512ctx;
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff return (ISC_R_SUCCESS);
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff}
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graffstatic void
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graffhmacsha512_destroyctx(dst_context_t *dctx) {
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff isc_hmacsha512_t *hmacsha512ctx = dctx->ctxdata.hmacsha512ctx;
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff if (hmacsha512ctx != NULL) {
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff isc_hmacsha512_invalidate(hmacsha512ctx);
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff isc_mem_put(dctx->mctx, hmacsha512ctx, sizeof(isc_hmacsha512_t));
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff dctx->ctxdata.hmacsha512ctx = NULL;
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff }
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff}
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graffstatic isc_result_t
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graffhmacsha512_adddata(dst_context_t *dctx, const isc_region_t *data) {
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff isc_hmacsha512_t *hmacsha512ctx = dctx->ctxdata.hmacsha512ctx;
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff isc_hmacsha512_update(hmacsha512ctx, data->base, data->length);
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff return (ISC_R_SUCCESS);
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff}
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graffstatic isc_result_t
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graffhmacsha512_sign(dst_context_t *dctx, isc_buffer_t *sig) {
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff isc_hmacsha512_t *hmacsha512ctx = dctx->ctxdata.hmacsha512ctx;
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff unsigned char *digest;
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff if (isc_buffer_availablelength(sig) < ISC_SHA512_DIGESTLENGTH)
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff return (ISC_R_NOSPACE);
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff digest = isc_buffer_used(sig);
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff isc_hmacsha512_sign(hmacsha512ctx, digest, ISC_SHA512_DIGESTLENGTH);
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff isc_buffer_add(sig, ISC_SHA512_DIGESTLENGTH);
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff return (ISC_R_SUCCESS);
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff}
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graffstatic isc_result_t
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graffhmacsha512_verify(dst_context_t *dctx, const isc_region_t *sig) {
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff isc_hmacsha512_t *hmacsha512ctx = dctx->ctxdata.hmacsha512ctx;
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff
5a5b79c5ab0ccdc821dd5498935e5cc7b96d2499Michael Graff if (sig->length > ISC_SHA512_DIGESTLENGTH || sig->length == 0)
5a5b79c5ab0ccdc821dd5498935e5cc7b96d2499Michael Graff return (DST_R_VERIFYFAILURE);
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff if (isc_hmacsha512_verify(hmacsha512ctx, sig->base, sig->length))
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff return (ISC_R_SUCCESS);
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff else
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graff return (DST_R_VERIFYFAILURE);
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence}
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff
439c0011e642fb1d26011116144af698125262dbMichael Graffstatic isc_boolean_t
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graffhmacsha512_compare(const dst_key_t *key1, const dst_key_t *key2) {
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff dst_hmacsha512_key_t *hkey1, *hkey2;
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff
439c0011e642fb1d26011116144af698125262dbMichael Graff hkey1 = key1->keydata.hmacsha512;
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff hkey2 = key2->keydata.hmacsha512;
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff if (hkey1 == NULL && hkey2 == NULL)
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff return (ISC_TRUE);
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff else if (hkey1 == NULL || hkey2 == NULL)
6d14fe95e9ea5bbc5e863e5aab4618f7b3dbcc0fMichael Graff return (ISC_FALSE);
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff
439c0011e642fb1d26011116144af698125262dbMichael Graff if (isc_safe_memcmp(hkey1->key, hkey2->key, ISC_SHA512_BLOCK_LENGTH))
5e387b9ce6bafdfadedb5b34e4c33a4404e5d589Brian Wellington return (ISC_TRUE);
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff else
e34efaccfaab4dbbe45edd0a58e2b6e930e5784bMichael Graff return (ISC_FALSE);
439c0011e642fb1d26011116144af698125262dbMichael Graff}
439c0011e642fb1d26011116144af698125262dbMichael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graffstatic isc_result_t
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graffhmacsha512_generate(dst_key_t *key, int pseudorandom_ok,
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff void (*callback)(int))
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff{
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff isc_buffer_t b;
e51511aa3281f8dc384eb1283115c7f8d5c402aeMichael Graff isc_result_t ret;
d98c74e2ec5b96bd22aa4ed6d893e8993787493bMichael Graff unsigned int bytes;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff unsigned char data[ISC_SHA512_BLOCK_LENGTH];
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff UNUSED(callback);
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff bytes = (key->key_size + 7) / 8;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff if (bytes > ISC_SHA512_BLOCK_LENGTH) {
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff bytes = ISC_SHA512_BLOCK_LENGTH;
d98c74e2ec5b96bd22aa4ed6d893e8993787493bMichael Graff key->key_size = ISC_SHA512_BLOCK_LENGTH * 8;
d98c74e2ec5b96bd22aa4ed6d893e8993787493bMichael Graff }
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff memset(data, 0, ISC_SHA512_BLOCK_LENGTH);
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff ret = dst__entropy_getdata(data, bytes, ISC_TF(pseudorandom_ok != 0));
d43c2cc7bc4022701f141e299ea8f3fb1d0640c2Michael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff if (ret != ISC_R_SUCCESS)
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff return (ret);
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff isc_buffer_init(&b, data, bytes);
6d14fe95e9ea5bbc5e863e5aab4618f7b3dbcc0fMichael Graff isc_buffer_add(&b, bytes);
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence ret = hmacsha512_fromdns(key, &b);
6d14fe95e9ea5bbc5e863e5aab4618f7b3dbcc0fMichael Graff memset(data, 0, ISC_SHA512_BLOCK_LENGTH);
6d14fe95e9ea5bbc5e863e5aab4618f7b3dbcc0fMichael Graff
6d14fe95e9ea5bbc5e863e5aab4618f7b3dbcc0fMichael Graff return (ret);
6d14fe95e9ea5bbc5e863e5aab4618f7b3dbcc0fMichael Graff}
6d14fe95e9ea5bbc5e863e5aab4618f7b3dbcc0fMichael Graff
6d14fe95e9ea5bbc5e863e5aab4618f7b3dbcc0fMichael Graffstatic isc_boolean_t
6d14fe95e9ea5bbc5e863e5aab4618f7b3dbcc0fMichael Graffhmacsha512_isprivate(const dst_key_t *key) {
d43c2cc7bc4022701f141e299ea8f3fb1d0640c2Michael Graff UNUSED(key);
6d14fe95e9ea5bbc5e863e5aab4618f7b3dbcc0fMichael Graff return (ISC_TRUE);
6d14fe95e9ea5bbc5e863e5aab4618f7b3dbcc0fMichael Graff}
6d14fe95e9ea5bbc5e863e5aab4618f7b3dbcc0fMichael Graff
6d14fe95e9ea5bbc5e863e5aab4618f7b3dbcc0fMichael Graffstatic void
6d14fe95e9ea5bbc5e863e5aab4618f7b3dbcc0fMichael Graffhmacsha512_destroy(dst_key_t *key) {
6d14fe95e9ea5bbc5e863e5aab4618f7b3dbcc0fMichael Graff dst_hmacsha512_key_t *hkey = key->keydata.hmacsha512;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff memset(hkey, 0, sizeof(dst_hmacsha512_key_t));
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff isc_mem_put(key->mctx, hkey, sizeof(dst_hmacsha512_key_t));
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff key->keydata.hmacsha512 = NULL;
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff}
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graffstatic isc_result_t
e51511aa3281f8dc384eb1283115c7f8d5c402aeMichael Graffhmacsha512_todns(const dst_key_t *key, isc_buffer_t *data) {
1a0e33bc2044e1902493111db14cbf793083ac47Michael Graff dst_hmacsha512_key_t *hkey;
1a0e33bc2044e1902493111db14cbf793083ac47Michael Graff unsigned int bytes;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff REQUIRE(key->keydata.hmacsha512 != NULL);
e51511aa3281f8dc384eb1283115c7f8d5c402aeMichael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff hkey = key->keydata.hmacsha512;
d6fe7ba94969ee51a3f4298a735fbc6e11691ad8Mark Andrews
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff bytes = (key->key_size + 7) / 8;
e51511aa3281f8dc384eb1283115c7f8d5c402aeMichael Graff if (isc_buffer_availablelength(data) < bytes)
e51511aa3281f8dc384eb1283115c7f8d5c402aeMichael Graff return (ISC_R_NOSPACE);
e51511aa3281f8dc384eb1283115c7f8d5c402aeMichael Graff isc_buffer_putmem(data, hkey->key, bytes);
e51511aa3281f8dc384eb1283115c7f8d5c402aeMichael Graff
e51511aa3281f8dc384eb1283115c7f8d5c402aeMichael Graff return (ISC_R_SUCCESS);
e51511aa3281f8dc384eb1283115c7f8d5c402aeMichael Graff}
e51511aa3281f8dc384eb1283115c7f8d5c402aeMichael Graff
e51511aa3281f8dc384eb1283115c7f8d5c402aeMichael Graffstatic isc_result_t
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graffhmacsha512_fromdns(dst_key_t *key, isc_buffer_t *data) {
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff dst_hmacsha512_key_t *hkey;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff int keylen;
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff isc_region_t r;
1a0e33bc2044e1902493111db14cbf793083ac47Michael Graff isc_sha512_t sha512ctx;
1a286a6613d385b443030a8c932e40ac9e9c301fBob Halley
53cf67186506f9557aaf2149898dd76715803db2Mark Andrews isc_buffer_remainingregion(data, &r);
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff if (r.length == 0)
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff return (ISC_R_SUCCESS);
d43c2cc7bc4022701f141e299ea8f3fb1d0640c2Michael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff hkey = isc_mem_get(key->mctx, sizeof(dst_hmacsha512_key_t));
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff if (hkey == NULL)
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff return (ISC_R_NOMEMORY);
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff memset(hkey->key, 0, sizeof(hkey->key));
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff if (r.length > ISC_SHA512_BLOCK_LENGTH) {
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff isc_sha512_init(&sha512ctx);
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff isc_sha512_update(&sha512ctx, r.base, r.length);
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff isc_sha512_final(hkey->key, &sha512ctx);
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff keylen = ISC_SHA512_DIGESTLENGTH;
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff } else {
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff memmove(hkey->key, r.base, r.length);
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff keylen = r.length;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff }
e51511aa3281f8dc384eb1283115c7f8d5c402aeMichael Graff
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence key->key_size = keylen * 8;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff key->keydata.hmacsha512 = hkey;
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff return (ISC_R_SUCCESS);
6dde125c2f47617ceef1518cf9e5588e8f366b71Michael Graff}
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graffstatic isc_result_t
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graffhmacsha512_tofile(const dst_key_t *key, const char *directory) {
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff int cnt = 0;
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff dst_hmacsha512_key_t *hkey;
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff dst_private_t priv;
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff int bytes = (key->key_size + 7) / 8;
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff unsigned char buf[2];
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff if (key->keydata.hmacsha512 == NULL)
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff return (DST_R_NULLKEY);
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff hkey = key->keydata.hmacsha512;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff
d43c2cc7bc4022701f141e299ea8f3fb1d0640c2Michael Graff priv.elements[cnt].tag = TAG_HMACSHA512_KEY;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff priv.elements[cnt].length = bytes;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff priv.elements[cnt++].data = hkey->key;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff buf[0] = (key->key_bits >> 8) & 0xffU;
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff buf[1] = key->key_bits & 0xffU;
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff priv.elements[cnt].tag = TAG_HMACSHA512_BITS;
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff priv.elements[cnt].data = buf;
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff priv.elements[cnt++].length = 2;
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff
f181f94ec8da8b1dbcc6353e8be965ea4a5ea282Michael Graff priv.nelements = cnt;
f181f94ec8da8b1dbcc6353e8be965ea4a5ea282Michael Graff return (dst__privstruct_writefile(key, &priv, directory));
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff}
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graffstatic isc_result_t
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graffhmacsha512_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff dst_private_t priv;
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff isc_result_t result, tresult;
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff isc_buffer_t b;
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff isc_mem_t *mctx = key->mctx;
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff unsigned int i;
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff
d43c2cc7bc4022701f141e299ea8f3fb1d0640c2Michael Graff UNUSED(pub);
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff /* read private key file */
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff result = dst__privstruct_parse(key, DST_ALG_HMACSHA512, lexer, mctx,
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff &priv);
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff if (result != ISC_R_SUCCESS)
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff return (result);
d43c2cc7bc4022701f141e299ea8f3fb1d0640c2Michael Graff
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff key->key_bits = 0;
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff for (i = 0; i < priv.nelements; i++) {
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff switch (priv.elements[i].tag) {
f181f94ec8da8b1dbcc6353e8be965ea4a5ea282Michael Graff case TAG_HMACSHA512_KEY:
f181f94ec8da8b1dbcc6353e8be965ea4a5ea282Michael Graff isc_buffer_init(&b, priv.elements[i].data,
f181f94ec8da8b1dbcc6353e8be965ea4a5ea282Michael Graff priv.elements[i].length);
f181f94ec8da8b1dbcc6353e8be965ea4a5ea282Michael Graff isc_buffer_add(&b, priv.elements[i].length);
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff tresult = hmacsha512_fromdns(key, &b);
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff if (tresult != ISC_R_SUCCESS)
f181f94ec8da8b1dbcc6353e8be965ea4a5ea282Michael Graff result = tresult;
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff break;
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff case TAG_HMACSHA512_BITS:
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff tresult = getkeybits(key, &priv.elements[i]);
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence if (tresult != ISC_R_SUCCESS)
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff result = tresult;
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff break;
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff default:
439c0011e642fb1d26011116144af698125262dbMichael Graff result = DST_R_INVALIDPRIVATEKEY;
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graff break;
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graff }
439c0011e642fb1d26011116144af698125262dbMichael Graff }
439c0011e642fb1d26011116144af698125262dbMichael Graff dst__privstruct_free(&priv, mctx);
439c0011e642fb1d26011116144af698125262dbMichael Graff memset(&priv, 0, sizeof(priv));
69a7905cf392ce5ddb6a9c0b090262598cf02294Michael Graff return (result);
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff}
439c0011e642fb1d26011116144af698125262dbMichael Graff
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graffstatic dst_func_t hmacsha512_functions = {
439c0011e642fb1d26011116144af698125262dbMichael Graff hmacsha512_createctx,
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff hmacsha512_destroyctx,
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff hmacsha512_adddata,
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff hmacsha512_sign,
69a7905cf392ce5ddb6a9c0b090262598cf02294Michael Graff hmacsha512_verify,
69a7905cf392ce5ddb6a9c0b090262598cf02294Michael Graff NULL, /* verify2 */
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff NULL, /* computesecret */
69a7905cf392ce5ddb6a9c0b090262598cf02294Michael Graff hmacsha512_compare,
ffd9f879709c5fb35f25368e74e2e12eb6881d9bMichael Graff NULL, /* paramcompare */
69a7905cf392ce5ddb6a9c0b090262598cf02294Michael Graff hmacsha512_generate,
1a0e33bc2044e1902493111db14cbf793083ac47Michael Graff hmacsha512_isprivate,
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff hmacsha512_destroy,
1a0e33bc2044e1902493111db14cbf793083ac47Michael Graff hmacsha512_todns,
d98c74e2ec5b96bd22aa4ed6d893e8993787493bMichael Graff hmacsha512_fromdns,
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff hmacsha512_tofile,
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff hmacsha512_parse,
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff NULL, /* cleanup */
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff NULL, /* fromlabel */
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff NULL, /* dump */
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff NULL, /* restore */
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff};
69a7905cf392ce5ddb6a9c0b090262598cf02294Michael Graff
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graffisc_result_t
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graffdst__hmacsha512_init(dst_func_t **funcp) {
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff REQUIRE(funcp != NULL);
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff if (*funcp == NULL)
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff *funcp = &hmacsha512_functions;
d43c2cc7bc4022701f141e299ea8f3fb1d0640c2Michael Graff return (ISC_R_SUCCESS);
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff}
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff/*! \file */
59e22acc4f79ff481f7bfa46ef0558957ae53cfcMichael Graff