1 /*
2  * internal.c
3  *		Wrapper for builtin functions
4  *
5  * Copyright (c) 2001 Marko Kreen
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *	  notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *	  notice, this list of conditions and the following disclaimer in the
15  *	  documentation and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  *
29  * contrib/pgcrypto/internal-sha2.c
30  */
31 
32 #include "postgres.h"
33 
34 #include <time.h>
35 
36 #include "common/cryptohash.h"
37 #include "common/sha2.h"
38 #include "px.h"
39 
40 void		init_sha224(PX_MD *h);
41 void		init_sha256(PX_MD *h);
42 void		init_sha384(PX_MD *h);
43 void		init_sha512(PX_MD *h);
44 
45 /* SHA224 */
46 static unsigned
int_sha224_len(PX_MD * h)47 int_sha224_len(PX_MD *h)
48 {
49 	return PG_SHA224_DIGEST_LENGTH;
50 }
51 
52 static unsigned
int_sha224_block_len(PX_MD * h)53 int_sha224_block_len(PX_MD *h)
54 {
55 	return PG_SHA224_BLOCK_LENGTH;
56 }
57 
58 /* SHA256 */
59 static unsigned
int_sha256_len(PX_MD * h)60 int_sha256_len(PX_MD *h)
61 {
62 	return PG_SHA256_DIGEST_LENGTH;
63 }
64 
65 static unsigned
int_sha256_block_len(PX_MD * h)66 int_sha256_block_len(PX_MD *h)
67 {
68 	return PG_SHA256_BLOCK_LENGTH;
69 }
70 
71 /* SHA384 */
72 static unsigned
int_sha384_len(PX_MD * h)73 int_sha384_len(PX_MD *h)
74 {
75 	return PG_SHA384_DIGEST_LENGTH;
76 }
77 
78 static unsigned
int_sha384_block_len(PX_MD * h)79 int_sha384_block_len(PX_MD *h)
80 {
81 	return PG_SHA384_BLOCK_LENGTH;
82 }
83 
84 /* SHA512 */
85 static unsigned
int_sha512_len(PX_MD * h)86 int_sha512_len(PX_MD *h)
87 {
88 	return PG_SHA512_DIGEST_LENGTH;
89 }
90 
91 static unsigned
int_sha512_block_len(PX_MD * h)92 int_sha512_block_len(PX_MD *h)
93 {
94 	return PG_SHA512_BLOCK_LENGTH;
95 }
96 
97 /* Generic interface for all SHA2 methods */
98 static void
int_sha2_update(PX_MD * h,const uint8 * data,unsigned dlen)99 int_sha2_update(PX_MD *h, const uint8 *data, unsigned dlen)
100 {
101 	pg_cryptohash_ctx *ctx = (pg_cryptohash_ctx *) h->p.ptr;
102 
103 	if (pg_cryptohash_update(ctx, data, dlen) < 0)
104 		elog(ERROR, "could not update %s context", "SHA2");
105 }
106 
107 static void
int_sha2_reset(PX_MD * h)108 int_sha2_reset(PX_MD *h)
109 {
110 	pg_cryptohash_ctx *ctx = (pg_cryptohash_ctx *) h->p.ptr;
111 
112 	if (pg_cryptohash_init(ctx) < 0)
113 		elog(ERROR, "could not initialize %s context", "SHA2");
114 }
115 
116 static void
int_sha2_finish(PX_MD * h,uint8 * dst)117 int_sha2_finish(PX_MD *h, uint8 *dst)
118 {
119 	pg_cryptohash_ctx *ctx = (pg_cryptohash_ctx *) h->p.ptr;
120 
121 	if (pg_cryptohash_final(ctx, dst, h->result_size(h)) < 0)
122 		elog(ERROR, "could not finalize %s context", "SHA2");
123 }
124 
125 static void
int_sha2_free(PX_MD * h)126 int_sha2_free(PX_MD *h)
127 {
128 	pg_cryptohash_ctx *ctx = (pg_cryptohash_ctx *) h->p.ptr;
129 
130 	pg_cryptohash_free(ctx);
131 	pfree(h);
132 }
133 
134 /* init functions */
135 
136 void
init_sha224(PX_MD * md)137 init_sha224(PX_MD *md)
138 {
139 	pg_cryptohash_ctx *ctx;
140 
141 	ctx = pg_cryptohash_create(PG_SHA224);
142 	md->p.ptr = ctx;
143 
144 	md->result_size = int_sha224_len;
145 	md->block_size = int_sha224_block_len;
146 	md->reset = int_sha2_reset;
147 	md->update = int_sha2_update;
148 	md->finish = int_sha2_finish;
149 	md->free = int_sha2_free;
150 
151 	md->reset(md);
152 }
153 
154 void
init_sha256(PX_MD * md)155 init_sha256(PX_MD *md)
156 {
157 	pg_cryptohash_ctx *ctx;
158 
159 	ctx = pg_cryptohash_create(PG_SHA256);
160 	md->p.ptr = ctx;
161 
162 	md->result_size = int_sha256_len;
163 	md->block_size = int_sha256_block_len;
164 	md->reset = int_sha2_reset;
165 	md->update = int_sha2_update;
166 	md->finish = int_sha2_finish;
167 	md->free = int_sha2_free;
168 
169 	md->reset(md);
170 }
171 
172 void
init_sha384(PX_MD * md)173 init_sha384(PX_MD *md)
174 {
175 	pg_cryptohash_ctx *ctx;
176 
177 	ctx = pg_cryptohash_create(PG_SHA384);
178 	md->p.ptr = ctx;
179 
180 	md->result_size = int_sha384_len;
181 	md->block_size = int_sha384_block_len;
182 	md->reset = int_sha2_reset;
183 	md->update = int_sha2_update;
184 	md->finish = int_sha2_finish;
185 	md->free = int_sha2_free;
186 
187 	md->reset(md);
188 }
189 
190 void
init_sha512(PX_MD * md)191 init_sha512(PX_MD *md)
192 {
193 	pg_cryptohash_ctx *ctx;
194 
195 	ctx = pg_cryptohash_create(PG_SHA512);
196 	md->p.ptr = ctx;
197 
198 	md->result_size = int_sha512_len;
199 	md->block_size = int_sha512_block_len;
200 	md->reset = int_sha2_reset;
201 	md->update = int_sha2_update;
202 	md->finish = int_sha2_finish;
203 	md->free = int_sha2_free;
204 
205 	md->reset(md);
206 }
207