1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193
|
/* Copyright 2014 The ChromiumOS Authors
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*
* Utility functions for message digest functions.
*/
#include "2common.h"
#include "2sha.h"
#include "2sysincludes.h"
size_t vb2_digest_size(enum vb2_hash_algorithm hash_alg)
{
switch (hash_alg) {
#if VB2_SUPPORT_SHA1
case VB2_HASH_SHA1:
return VB2_SHA1_DIGEST_SIZE;
#endif
#if VB2_SUPPORT_SHA256
case VB2_HASH_SHA224:
return VB2_SHA224_DIGEST_SIZE;
case VB2_HASH_SHA256:
return VB2_SHA256_DIGEST_SIZE;
#endif
#if VB2_SUPPORT_SHA512
case VB2_HASH_SHA384:
return VB2_SHA384_DIGEST_SIZE;
case VB2_HASH_SHA512:
return VB2_SHA512_DIGEST_SIZE;
#endif
default:
return 0;
}
}
size_t vb2_hash_block_size(enum vb2_hash_algorithm alg)
{
switch (alg) {
#if VB2_SUPPORT_SHA1
case VB2_HASH_SHA1:
return VB2_SHA1_BLOCK_SIZE;
#endif
#if VB2_SUPPORT_SHA256
case VB2_HASH_SHA224: /* SHA224 reuses SHA256 internal structures */
case VB2_HASH_SHA256:
return VB2_SHA256_BLOCK_SIZE;
#endif
#if VB2_SUPPORT_SHA512
case VB2_HASH_SHA384: /* SHA384 reuses SHA512 internal structures */
case VB2_HASH_SHA512:
return VB2_SHA512_BLOCK_SIZE;
#endif
default:
return 0;
}
}
test_mockable
vb2_error_t vb2_digest_init(struct vb2_digest_context *dc, bool allow_hwcrypto,
enum vb2_hash_algorithm algo, uint32_t data_size)
{
const char msg[] = "%u bytes, hash algo %d, HW acceleration %s";
dc->hash_alg = algo;
dc->using_hwcrypto = 0;
if (allow_hwcrypto) {
vb2_error_t rv = vb2ex_hwcrypto_digest_init(algo, data_size);
if (rv == VB2_SUCCESS) {
VB2_DEBUG(msg, data_size, algo, "enabled\n");
dc->using_hwcrypto = 1;
return VB2_SUCCESS;
}
if (rv != VB2_ERROR_EX_HWCRYPTO_UNSUPPORTED) {
VB2_DEBUG(msg, data_size, algo, "initialization error");
VB2_DEBUG_RAW(": %#x\n", rv);
return rv;
}
VB2_DEBUG(msg, data_size, algo, "unsupported\n");
} else {
VB2_DEBUG(msg, data_size, algo, "forbidden\n");
}
switch (algo) {
#if VB2_SUPPORT_SHA1
case VB2_HASH_SHA1:
vb2_sha1_init(&dc->sha1);
return VB2_SUCCESS;
#endif
#if VB2_SUPPORT_SHA256
case VB2_HASH_SHA224:
case VB2_HASH_SHA256:
vb2_sha256_init(&dc->sha256, algo);
return VB2_SUCCESS;
#endif
#if VB2_SUPPORT_SHA512
case VB2_HASH_SHA384:
case VB2_HASH_SHA512:
vb2_sha512_init(&dc->sha512, algo);
return VB2_SUCCESS;
#endif
default:
return VB2_ERROR_SHA_INIT_ALGORITHM;
}
}
test_mockable
vb2_error_t vb2_digest_extend(struct vb2_digest_context *dc, const uint8_t *buf,
uint32_t size)
{
if (dc->using_hwcrypto)
return vb2ex_hwcrypto_digest_extend(buf, size);
switch (dc->hash_alg) {
#if VB2_SUPPORT_SHA1
case VB2_HASH_SHA1:
vb2_sha1_update(&dc->sha1, buf, size);
return VB2_SUCCESS;
#endif
#if VB2_SUPPORT_SHA256
case VB2_HASH_SHA224:
case VB2_HASH_SHA256:
vb2_sha256_update(&dc->sha256, buf, size);
return VB2_SUCCESS;
#endif
#if VB2_SUPPORT_SHA512
case VB2_HASH_SHA384:
case VB2_HASH_SHA512:
vb2_sha512_update(&dc->sha512, buf, size);
return VB2_SUCCESS;
#endif
default:
return VB2_ERROR_SHA_EXTEND_ALGORITHM;
}
}
test_mockable
vb2_error_t vb2_digest_finalize(struct vb2_digest_context *dc, uint8_t *digest,
uint32_t digest_size)
{
if (dc->using_hwcrypto)
return vb2ex_hwcrypto_digest_finalize(digest, digest_size);
if (digest_size < vb2_digest_size(dc->hash_alg))
return VB2_ERROR_SHA_FINALIZE_DIGEST_SIZE;
switch (dc->hash_alg) {
#if VB2_SUPPORT_SHA1
case VB2_HASH_SHA1:
vb2_sha1_finalize(&dc->sha1, digest);
return VB2_SUCCESS;
#endif
#if VB2_SUPPORT_SHA256
case VB2_HASH_SHA224:
case VB2_HASH_SHA256:
vb2_sha256_finalize(&dc->sha256, digest, dc->hash_alg);
return VB2_SUCCESS;
#endif
#if VB2_SUPPORT_SHA512
case VB2_HASH_SHA384:
case VB2_HASH_SHA512:
vb2_sha512_finalize(&dc->sha512, digest, dc->hash_alg);
return VB2_SUCCESS;
#endif
default:
return VB2_ERROR_SHA_FINALIZE_ALGORITHM;
}
}
vb2_error_t vb2_hash_calculate(bool allow_hwcrypto, const void *buf,
uint32_t size, enum vb2_hash_algorithm algo,
struct vb2_hash *hash)
{
struct vb2_digest_context dc;
hash->algo = algo;
VB2_TRY(vb2_digest_init(&dc, allow_hwcrypto, algo, size));
VB2_TRY(vb2_digest_extend(&dc, buf, size));
return vb2_digest_finalize(&dc, hash->raw, vb2_digest_size(algo));
}
vb2_error_t vb2_hash_verify(bool allow_hwcrypto, const void *buf, uint32_t size,
const struct vb2_hash *hash)
{
struct vb2_hash tmp;
VB2_TRY(vb2_hash_calculate(allow_hwcrypto, buf, size, hash->algo, &tmp));
if (memcmp(tmp.raw, hash->raw, vb2_digest_size(hash->algo)))
return VB2_ERROR_SHA_MISMATCH;
else
return VB2_SUCCESS;
}
|