-
Notifications
You must be signed in to change notification settings - Fork 4.6k
/
pal_hmac.c
163 lines (136 loc) · 4.01 KB
/
pal_hmac.c
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
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
#include "pal_hmac.h"
struct hmac_ctx_st
{
CCHmacAlgorithm appleAlgId;
CCHmacContext hmac;
};
void AppleCryptoNative_HmacFree(HmacCtx* pHmac)
{
if (pHmac != NULL)
{
free(pHmac);
}
}
static CCHmacAlgorithm PalAlgorithmToAppleAlgorithm(PAL_HashAlgorithm algorithm)
{
switch (algorithm)
{
case PAL_MD5:
return kCCHmacAlgMD5;
case PAL_SHA1:
return kCCHmacAlgSHA1;
case PAL_SHA256:
return kCCHmacAlgSHA256;
case PAL_SHA384:
return kCCHmacAlgSHA384;
case PAL_SHA512:
return kCCHmacAlgSHA512;
default:
// 0 is a defined value (SHA1) so "unknown" has to be something else
return UINT_MAX;
}
}
static int32_t GetHmacOutputSize(PAL_HashAlgorithm algorithm)
{
switch (algorithm)
{
case PAL_MD5:
return CC_MD5_DIGEST_LENGTH;
case PAL_SHA1:
return CC_SHA1_DIGEST_LENGTH;
case PAL_SHA256:
return CC_SHA256_DIGEST_LENGTH;
case PAL_SHA384:
return CC_SHA384_DIGEST_LENGTH;
case PAL_SHA512:
return CC_SHA512_DIGEST_LENGTH;
default:
return -1;
}
}
HmacCtx* AppleCryptoNative_HmacCreate(PAL_HashAlgorithm algorithm, int32_t* pcbHmac)
{
if (pcbHmac == NULL)
return NULL;
CCHmacAlgorithm appleAlgId = PalAlgorithmToAppleAlgorithm(algorithm);
if (appleAlgId == UINT_MAX)
{
*pcbHmac = -1;
return NULL;
}
HmacCtx* hmacCtx = (HmacCtx*)malloc(sizeof(HmacCtx));
if (hmacCtx == NULL)
return hmacCtx;
hmacCtx->appleAlgId = appleAlgId;
*pcbHmac = GetHmacOutputSize(algorithm);
return hmacCtx;
}
int32_t AppleCryptoNative_HmacInit(HmacCtx* ctx, uint8_t* pbKey, int32_t cbKey)
{
if (ctx == NULL || cbKey < 0)
return 0;
if (cbKey != 0 && pbKey == NULL)
return 0;
// No return value
CCHmacInit(&ctx->hmac, ctx->appleAlgId, pbKey, (size_t)cbKey);
return 1;
}
int32_t AppleCryptoNative_HmacUpdate(HmacCtx* ctx, uint8_t* pbData, int32_t cbData)
{
if (cbData == 0)
return 1;
if (ctx == NULL || pbData == NULL)
return 0;
// No return value
CCHmacUpdate(&ctx->hmac, pbData, (size_t)cbData);
return 1;
}
int32_t AppleCryptoNative_HmacFinal(HmacCtx* ctx, uint8_t* pbOutput)
{
if (ctx == NULL || pbOutput == NULL)
return 0;
// No return value
CCHmacFinal(&ctx->hmac, pbOutput);
return 1;
}
int32_t AppleCryptoNative_HmacCurrent(const HmacCtx* ctx, uint8_t* pbOutput)
{
if (ctx == NULL || pbOutput == NULL)
return 0;
HmacCtx dup = *ctx;
return AppleCryptoNative_HmacFinal(&dup, pbOutput);
}
int32_t AppleCryptoNative_HmacOneShot(PAL_HashAlgorithm algorithm,
const uint8_t* pKey,
int32_t cbKey,
const uint8_t* pBuf,
int32_t cbBuf,
uint8_t* pOutput,
int32_t cbOutput,
int32_t* pcbDigest)
{
if (pOutput == NULL || cbOutput <= 0 || pcbDigest == NULL)
return -1;
CCHmacAlgorithm ccAlgorithm = PalAlgorithmToAppleAlgorithm(algorithm);
*pcbDigest = GetHmacOutputSize(algorithm);
if (ccAlgorithm == UINT_MAX)
return -1;
if (cbOutput < *pcbDigest)
return -1;
CCHmac(ccAlgorithm, pKey, (size_t)cbKey, pBuf, (size_t)cbBuf, pOutput);
return 1;
}
HmacCtx* AppleCryptoNative_HmacClone(const HmacCtx* ctx)
{
if (ctx == NULL)
return NULL;
HmacCtx* cloneCtx = (HmacCtx*)malloc(sizeof(HmacCtx)); // Must use same allocator as AppleCryptoNative_HmacCreate
if (cloneCtx == NULL)
{
return NULL;
}
memcpy(cloneCtx, ctx, sizeof(HmacCtx));
return cloneCtx;
}