diff options
Diffstat (limited to 'src/lib/libcrypto/evp/evp_aead.c')
-rw-r--r-- | src/lib/libcrypto/evp/evp_aead.c | 50 |
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 | ||
129 | ssize_t | 129 | int |
130 | EVP_AEAD_CTX_seal(const EVP_AEAD_CTX *ctx, unsigned char *out, | 130 | EVP_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 | ||
155 | error: | 153 | error: |
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 | ||
162 | ssize_t | 161 | int |
163 | EVP_AEAD_CTX_open(const EVP_AEAD_CTX *ctx, unsigned char *out, | 162 | EVP_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 | ||
186 | error: | 177 | error: |
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 | } |