39
39
#define FREE (ptr ) free(ptr)
40
40
#endif
41
41
42
+ /* Internal pg_cryptohash_ctx structure */
43
+ struct pg_cryptohash_ctx
44
+ {
45
+ pg_cryptohash_type type ;
46
+
47
+ union
48
+ {
49
+ pg_md5_ctx md5 ;
50
+ pg_sha224_ctx sha224 ;
51
+ pg_sha256_ctx sha256 ;
52
+ pg_sha384_ctx sha384 ;
53
+ pg_sha512_ctx sha512 ;
54
+ } data ;
55
+ };
56
+
42
57
/*
43
58
* pg_cryptohash_create
44
59
*
@@ -50,38 +65,18 @@ pg_cryptohash_create(pg_cryptohash_type type)
50
65
{
51
66
pg_cryptohash_ctx * ctx ;
52
67
68
+ /*
69
+ * Note that this always allocates enough space for the largest hash. A
70
+ * smaller allocation would be enough for md5, sha224 and sha256, but the
71
+ * small extra amount of memory does not make it worth complicating this
72
+ * code.
73
+ */
53
74
ctx = ALLOC (sizeof (pg_cryptohash_ctx ));
54
75
if (ctx == NULL )
55
76
return NULL ;
56
-
77
+ memset ( ctx , 0 , sizeof ( pg_cryptohash_ctx ));
57
78
ctx -> type = type ;
58
79
59
- switch (type )
60
- {
61
- case PG_MD5 :
62
- ctx -> data = ALLOC (sizeof (pg_md5_ctx ));
63
- break ;
64
- case PG_SHA224 :
65
- ctx -> data = ALLOC (sizeof (pg_sha224_ctx ));
66
- break ;
67
- case PG_SHA256 :
68
- ctx -> data = ALLOC (sizeof (pg_sha256_ctx ));
69
- break ;
70
- case PG_SHA384 :
71
- ctx -> data = ALLOC (sizeof (pg_sha384_ctx ));
72
- break ;
73
- case PG_SHA512 :
74
- ctx -> data = ALLOC (sizeof (pg_sha512_ctx ));
75
- break ;
76
- }
77
-
78
- if (ctx -> data == NULL )
79
- {
80
- explicit_bzero (ctx , sizeof (pg_cryptohash_ctx ));
81
- FREE (ctx );
82
- return NULL ;
83
- }
84
-
85
80
return ctx ;
86
81
}
87
82
95
90
pg_cryptohash_init (pg_cryptohash_ctx * ctx )
96
91
{
97
92
if (ctx == NULL )
98
- return 0 ;
93
+ return -1 ;
99
94
100
95
switch (ctx -> type )
101
96
{
102
97
case PG_MD5 :
103
- pg_md5_init (( pg_md5_ctx * ) ctx -> data );
98
+ pg_md5_init (& ctx -> data . md5 );
104
99
break ;
105
100
case PG_SHA224 :
106
- pg_sha224_init (( pg_sha224_ctx * ) ctx -> data );
101
+ pg_sha224_init (& ctx -> data . sha224 );
107
102
break ;
108
103
case PG_SHA256 :
109
- pg_sha256_init (( pg_sha256_ctx * ) ctx -> data );
104
+ pg_sha256_init (& ctx -> data . sha256 );
110
105
break ;
111
106
case PG_SHA384 :
112
- pg_sha384_init (( pg_sha384_ctx * ) ctx -> data );
107
+ pg_sha384_init (& ctx -> data . sha384 );
113
108
break ;
114
109
case PG_SHA512 :
115
- pg_sha512_init (( pg_sha512_ctx * ) ctx -> data );
110
+ pg_sha512_init (& ctx -> data . sha512 );
116
111
break ;
117
112
}
118
113
@@ -123,30 +118,31 @@ pg_cryptohash_init(pg_cryptohash_ctx *ctx)
123
118
* pg_cryptohash_update
124
119
*
125
120
* Update a hash context. Note that this implementation is designed
126
- * to never fail, so this always returns 0.
121
+ * to never fail, so this always returns 0 except if the caller has
122
+ * given a NULL context.
127
123
*/
128
124
int
129
125
pg_cryptohash_update (pg_cryptohash_ctx * ctx , const uint8 * data , size_t len )
130
126
{
131
127
if (ctx == NULL )
132
- return 0 ;
128
+ return -1 ;
133
129
134
130
switch (ctx -> type )
135
131
{
136
132
case PG_MD5 :
137
- pg_md5_update (( pg_md5_ctx * ) ctx -> data , data , len );
133
+ pg_md5_update (& ctx -> data . md5 , data , len );
138
134
break ;
139
135
case PG_SHA224 :
140
- pg_sha224_update (( pg_sha224_ctx * ) ctx -> data , data , len );
136
+ pg_sha224_update (& ctx -> data . sha224 , data , len );
141
137
break ;
142
138
case PG_SHA256 :
143
- pg_sha256_update (( pg_sha256_ctx * ) ctx -> data , data , len );
139
+ pg_sha256_update (& ctx -> data . sha256 , data , len );
144
140
break ;
145
141
case PG_SHA384 :
146
- pg_sha384_update (( pg_sha384_ctx * ) ctx -> data , data , len );
142
+ pg_sha384_update (& ctx -> data . sha384 , data , len );
147
143
break ;
148
144
case PG_SHA512 :
149
- pg_sha512_update (( pg_sha512_ctx * ) ctx -> data , data , len );
145
+ pg_sha512_update (& ctx -> data . sha512 , data , len );
150
146
break ;
151
147
}
152
148
@@ -157,30 +153,31 @@ pg_cryptohash_update(pg_cryptohash_ctx *ctx, const uint8 *data, size_t len)
157
153
* pg_cryptohash_final
158
154
*
159
155
* Finalize a hash context. Note that this implementation is designed
160
- * to never fail, so this always returns 0.
156
+ * to never fail, so this always returns 0 except if the caller has
157
+ * given a NULL context.
161
158
*/
162
159
int
163
160
pg_cryptohash_final (pg_cryptohash_ctx * ctx , uint8 * dest )
164
161
{
165
162
if (ctx == NULL )
166
- return 0 ;
163
+ return -1 ;
167
164
168
165
switch (ctx -> type )
169
166
{
170
167
case PG_MD5 :
171
- pg_md5_final (( pg_md5_ctx * ) ctx -> data , dest );
168
+ pg_md5_final (& ctx -> data . md5 , dest );
172
169
break ;
173
170
case PG_SHA224 :
174
- pg_sha224_final (( pg_sha224_ctx * ) ctx -> data , dest );
171
+ pg_sha224_final (& ctx -> data . sha224 , dest );
175
172
break ;
176
173
case PG_SHA256 :
177
- pg_sha256_final (( pg_sha256_ctx * ) ctx -> data , dest );
174
+ pg_sha256_final (& ctx -> data . sha256 , dest );
178
175
break ;
179
176
case PG_SHA384 :
180
- pg_sha384_final (( pg_sha384_ctx * ) ctx -> data , dest );
177
+ pg_sha384_final (& ctx -> data . sha384 , dest );
181
178
break ;
182
179
case PG_SHA512 :
183
- pg_sha512_final (( pg_sha512_ctx * ) ctx -> data , dest );
180
+ pg_sha512_final (& ctx -> data . sha512 , dest );
184
181
break ;
185
182
}
186
183
@@ -198,26 +195,6 @@ pg_cryptohash_free(pg_cryptohash_ctx *ctx)
198
195
if (ctx == NULL )
199
196
return ;
200
197
201
- switch (ctx -> type )
202
- {
203
- case PG_MD5 :
204
- explicit_bzero (ctx -> data , sizeof (pg_md5_ctx ));
205
- break ;
206
- case PG_SHA224 :
207
- explicit_bzero (ctx -> data , sizeof (pg_sha224_ctx ));
208
- break ;
209
- case PG_SHA256 :
210
- explicit_bzero (ctx -> data , sizeof (pg_sha256_ctx ));
211
- break ;
212
- case PG_SHA384 :
213
- explicit_bzero (ctx -> data , sizeof (pg_sha384_ctx ));
214
- break ;
215
- case PG_SHA512 :
216
- explicit_bzero (ctx -> data , sizeof (pg_sha512_ctx ));
217
- break ;
218
- }
219
-
220
- FREE (ctx -> data );
221
198
explicit_bzero (ctx , sizeof (pg_cryptohash_ctx ));
222
199
FREE (ctx );
223
200
}
0 commit comments