summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/evp/evp_aead.c
diff options
context:
space:
mode:
authorjsing <>2014-05-26 13:01:58 +0000
committerjsing <>2014-05-26 13:01:58 +0000
commit1e04f96479c885fa94175f42f348872cbdd3c9d4 (patch)
tree2d8c2f3b74e112db8f84b41231b2cde79d0be571 /src/lib/libcrypto/evp/evp_aead.c
parent3ebf48c494177b3b775febf8302322375c80fe3b (diff)
downloadopenbsd-1e04f96479c885fa94175f42f348872cbdd3c9d4.tar.gz
openbsd-1e04f96479c885fa94175f42f348872cbdd3c9d4.tar.bz2
openbsd-1e04f96479c885fa94175f42f348872cbdd3c9d4.zip
Implement an improved version of the EVP AEAD API. The
EVP_AEAD_CTX_{open,seal} functions previously returned an ssize_t that was overloaded to indicate success/failure, along with the number of bytes written as output. This change adds an explicit *out_len argument which is used to return the number of output bytes and the return value is now an int that is purely used to identify success or failure. This change effectively rides the last libcrypto crank (although I do not expect there to be many users of the EVP AEAD API currently). Thanks to Adam Langley for providing the improved code that this diff is based on. ok miod@
Diffstat (limited to 'src/lib/libcrypto/evp/evp_aead.c')
-rw-r--r--src/lib/libcrypto/evp/evp_aead.c50
1 files changed, 21 insertions, 29 deletions
diff --git a/src/lib/libcrypto/evp/evp_aead.c b/src/lib/libcrypto/evp/evp_aead.c
index c8ba1df54a..427bf05467 100644
--- a/src/lib/libcrypto/evp/evp_aead.c
+++ b/src/lib/libcrypto/evp/evp_aead.c
@@ -126,67 +126,59 @@ check_alias(const unsigned char *in, size_t in_len, const unsigned char *out)
126 return 0; 126 return 0;
127} 127}
128 128
129ssize_t 129int
130EVP_AEAD_CTX_seal(const EVP_AEAD_CTX *ctx, unsigned char *out, 130EVP_AEAD_CTX_seal(const EVP_AEAD_CTX *ctx, unsigned char *out, size_t *out_len,
131 size_t max_out_len, const unsigned char *nonce, size_t nonce_len, 131 size_t max_out_len, const unsigned char *nonce, size_t nonce_len,
132 const unsigned char *in, size_t in_len, const unsigned char *ad, 132 const unsigned char *in, size_t in_len, const unsigned char *ad,
133 size_t ad_len) 133 size_t ad_len)
134{ 134{
135 size_t possible_out_len = in_len + ctx->aead->overhead; 135 size_t possible_out_len = in_len + ctx->aead->overhead;
136 ssize_t r;
137 136
138 if (possible_out_len < in_len /* overflow */ || 137 /* Overflow. */
139 possible_out_len > SSIZE_MAX /* return value cannot be 138 if (possible_out_len < in_len) {
140 represented */) { 139 EVPerr(EVP_F_AEAD_CTX_SEAL, EVP_R_TOO_LARGE);
141 EVPerr(EVP_F_EVP_AEAD_CTX_SEAL, EVP_R_TOO_LARGE);
142 goto error; 140 goto error;
143 } 141 }
144 142
145 if (!check_alias(in, in_len, out)) { 143 if (!check_alias(in, in_len, out)) {
146 EVPerr(EVP_F_EVP_AEAD_CTX_SEAL, EVP_R_OUTPUT_ALIASES_INPUT); 144 EVPerr(EVP_F_AEAD_CTX_SEAL, EVP_R_OUTPUT_ALIASES_INPUT);
147 goto error; 145 goto error;
148 } 146 }
149 147
150 r = ctx->aead->seal(ctx, out, max_out_len, nonce, nonce_len, 148 if (ctx->aead->seal(ctx, out, out_len, max_out_len, nonce, nonce_len,
151 in, in_len, ad, ad_len); 149 in, in_len, ad, ad_len)) {
152 if (r >= 0) 150 return 1;
153 return r; 151 }
154 152
155error: 153error:
156 /* In the event of an error, clear the output buffer so that a caller 154 /* In the event of an error, clear the output buffer so that a caller
157 * that doesn't check the return value doesn't send raw data. */ 155 * that doesn't check the return value doesn't send raw data. */
158 memset(out, 0, max_out_len); 156 memset(out, 0, max_out_len);
159 return -1; 157 *out_len = 0;
158 return 0;
160} 159}
161 160
162ssize_t 161int
163EVP_AEAD_CTX_open(const EVP_AEAD_CTX *ctx, unsigned char *out, 162EVP_AEAD_CTX_open(const EVP_AEAD_CTX *ctx, unsigned char *out, size_t *out_len,
164 size_t max_out_len, const unsigned char *nonce, size_t nonce_len, 163 size_t max_out_len, const unsigned char *nonce, size_t nonce_len,
165 const unsigned char *in, size_t in_len, const unsigned char *ad, 164 const unsigned char *in, size_t in_len, const unsigned char *ad,
166 size_t ad_len) 165 size_t ad_len)
167{ 166{
168 ssize_t r;
169
170 if (in_len > SSIZE_MAX) {
171 EVPerr(EVP_F_EVP_AEAD_CTX_OPEN, EVP_R_TOO_LARGE);
172 goto error; /* may not be able to represent return value. */
173 }
174
175 if (!check_alias(in, in_len, out)) { 167 if (!check_alias(in, in_len, out)) {
176 EVPerr(EVP_F_EVP_AEAD_CTX_OPEN, EVP_R_OUTPUT_ALIASES_INPUT); 168 EVPerr(EVP_F_AEAD_CTX_OPEN, EVP_R_OUTPUT_ALIASES_INPUT);
177 goto error; 169 goto error;
178 } 170 }
179 171
180 r = ctx->aead->open(ctx, out, max_out_len, nonce, nonce_len, 172 if (ctx->aead->open(ctx, out, out_len, max_out_len, nonce, nonce_len,
181 in, in_len, ad, ad_len); 173 in, in_len, ad, ad_len)) {
182 174 return 1;
183 if (r >= 0) 175 }
184 return r;
185 176
186error: 177error:
187 /* In the event of an error, clear the output buffer so that a caller 178 /* In the event of an error, clear the output buffer so that a caller
188 * that doesn't check the return value doesn't try and process bad 179 * that doesn't check the return value doesn't try and process bad
189 * data. */ 180 * data. */
190 memset(out, 0, max_out_len); 181 memset(out, 0, max_out_len);
191 return -1; 182 *out_len = 0;
183 return 0;
192} 184}