]>
Commit | Line | Data |
---|---|---|
a672a02a SL |
1 | /* |
2 | * Copyright 2001-2019 The OpenSSL Project Authors. All Rights Reserved. | |
3 | * | |
4 | * Licensed under the Apache License 2.0 (the "License"). You may not use | |
5 | * this file except in compliance with the License. You can obtain a copy | |
6 | * in the file LICENSE in the source distribution or at | |
7 | * https://www.openssl.org/source/license.html | |
8 | */ | |
9 | ||
e1178600 | 10 | #include "cipher_locl.h" |
4a42e264 | 11 | #include "internal/ciphers/cipher_gcm.h" |
a672a02a | 12 | |
a672a02a | 13 | |
4a42e264 | 14 | int gcm_setiv(PROV_GCM_CTX *ctx, const unsigned char *iv, size_t ivlen) |
a672a02a SL |
15 | { |
16 | CRYPTO_gcm128_setiv(&ctx->gcm, iv, ivlen); | |
17 | return 1; | |
18 | } | |
19 | ||
4a42e264 | 20 | int gcm_aad_update(PROV_GCM_CTX *ctx, const unsigned char *aad, size_t aad_len) |
a672a02a SL |
21 | { |
22 | return CRYPTO_gcm128_aad(&ctx->gcm, aad, aad_len) == 0; | |
23 | } | |
24 | ||
4a42e264 SL |
25 | int gcm_cipher_update(PROV_GCM_CTX *ctx, const unsigned char *in, |
26 | size_t len, unsigned char *out) | |
a672a02a SL |
27 | { |
28 | if (ctx->enc) { | |
29 | if (ctx->ctr != NULL) { | |
30 | #if defined(AES_GCM_ASM) | |
31 | size_t bulk = 0; | |
32 | ||
33 | if (len >= 32 && AES_GCM_ASM(ctx)) { | |
34 | size_t res = (16 - ctx->gcm.mres) % 16; | |
35 | ||
36 | if (CRYPTO_gcm128_encrypt(&ctx->gcm, in, out, res)) | |
37 | return 0; | |
38 | bulk = aesni_gcm_encrypt(in + res, out + res, len - res, | |
39 | ctx->gcm.key, | |
40 | ctx->gcm.Yi.c, ctx->gcm.Xi.u); | |
41 | ctx->gcm.len.u[1] += bulk; | |
42 | bulk += res; | |
43 | } | |
44 | if (CRYPTO_gcm128_encrypt_ctr32(&ctx->gcm, in + bulk, out + bulk, | |
45 | len - bulk, ctx->ctr)) | |
46 | return 0; | |
47 | #else | |
48 | if (CRYPTO_gcm128_encrypt_ctr32(&ctx->gcm, in, out, len, ctx->ctr)) | |
49 | return 0; | |
50 | #endif /* AES_GCM_ASM */ | |
51 | } else { | |
52 | if (CRYPTO_gcm128_encrypt(&ctx->gcm, in, out, len)) | |
53 | return 0; | |
54 | } | |
55 | } else { | |
56 | if (ctx->ctr != NULL) { | |
57 | #if defined(AES_GCM_ASM) | |
58 | size_t bulk = 0; | |
59 | ||
60 | if (len >= 16 && AES_GCM_ASM(ctx)) { | |
61 | size_t res = (16 - ctx->gcm.mres) % 16; | |
62 | ||
63 | if (CRYPTO_gcm128_decrypt(&ctx->gcm, in, out, res)) | |
64 | return -1; | |
65 | ||
66 | bulk = aesni_gcm_decrypt(in + res, out + res, len - res, | |
67 | ctx->gcm.key, | |
68 | ctx->gcm.Yi.c, ctx->gcm.Xi.u); | |
69 | ctx->gcm.len.u[1] += bulk; | |
70 | bulk += res; | |
71 | } | |
72 | if (CRYPTO_gcm128_decrypt_ctr32(&ctx->gcm, in + bulk, out + bulk, | |
73 | len - bulk, ctx->ctr)) | |
74 | return 0; | |
75 | #else | |
76 | if (CRYPTO_gcm128_decrypt_ctr32(&ctx->gcm, in, out, len, ctx->ctr)) | |
77 | return 0; | |
78 | #endif /* AES_GCM_ASM */ | |
79 | } else { | |
80 | if (CRYPTO_gcm128_decrypt(&ctx->gcm, in, out, len)) | |
81 | return 0; | |
82 | } | |
83 | } | |
84 | return 1; | |
85 | } | |
86 | ||
4a42e264 | 87 | int gcm_cipher_final(PROV_GCM_CTX *ctx, unsigned char *tag) |
a672a02a SL |
88 | { |
89 | if (ctx->enc) { | |
90 | CRYPTO_gcm128_tag(&ctx->gcm, tag, GCM_TAG_MAX_SIZE); | |
91 | ctx->taglen = GCM_TAG_MAX_SIZE; | |
92 | } else { | |
2e9645c8 | 93 | if (CRYPTO_gcm128_finish(&ctx->gcm, tag, ctx->taglen) != 0) |
a672a02a SL |
94 | return 0; |
95 | } | |
96 | return 1; | |
97 | } | |
98 | ||
4a42e264 SL |
99 | int gcm_one_shot(PROV_GCM_CTX *ctx, unsigned char *aad, size_t aad_len, |
100 | const unsigned char *in, size_t in_len, | |
101 | unsigned char *out, unsigned char *tag, size_t tag_len) | |
a672a02a SL |
102 | { |
103 | int ret = 0; | |
104 | ||
105 | /* Use saved AAD */ | |
106 | if (!ctx->hw->aadupdate(ctx, aad, aad_len)) | |
107 | goto err; | |
108 | if (!ctx->hw->cipherupdate(ctx, in, in_len, out)) | |
109 | goto err; | |
110 | ctx->taglen = GCM_TAG_MAX_SIZE; | |
111 | if (!ctx->hw->cipherfinal(ctx, tag)) | |
112 | goto err; | |
113 | ret = 1; | |
114 | ||
115 | err: | |
116 | return ret; | |
117 | } |