1 /* 2 * 3 * Copyright 2018 gRPC authors. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 */ 18 19 #include <grpc/support/port_platform.h> 20 21 #include "src/core/tsi/alts/crypt/gsec.h" 22 23 #include <stdio.h> 24 #include <string.h> 25 26 #include <grpc/support/alloc.h> 27 28 static const char vtable_error_msg[] = 29 "crypter or crypter->vtable has not been initialized properly"; 30 31 static void maybe_copy_error_msg(const char* src, char** dst) { 32 if (dst != nullptr && src != nullptr) { 33 *dst = static_cast<char*>(gpr_malloc(strlen(src) + 1)); 34 memcpy(*dst, src, strlen(src) + 1); 35 } 36 } 37 38 grpc_status_code gsec_aead_crypter_encrypt( 39 gsec_aead_crypter* crypter, const uint8_t* nonce, size_t nonce_length, 40 const uint8_t* aad, size_t aad_length, const uint8_t* plaintext, 41 size_t plaintext_length, uint8_t* ciphertext_and_tag, 42 size_t ciphertext_and_tag_length, size_t* bytes_written, 43 char** error_details) { 44 if (crypter != nullptr && crypter->vtable != nullptr && 45 crypter->vtable->encrypt_iovec != nullptr) { 46 struct iovec aad_vec = {(void*)aad, aad_length}; 47 struct iovec plaintext_vec = {(void*)plaintext, plaintext_length}; 48 struct iovec ciphertext_vec = {ciphertext_and_tag, 49 ciphertext_and_tag_length}; 50 return crypter->vtable->encrypt_iovec( 51 crypter, nonce, nonce_length, &aad_vec, 1, &plaintext_vec, 1, 52 ciphertext_vec, bytes_written, error_details); 53 } 54 /* An error occurred. */ 55 maybe_copy_error_msg(vtable_error_msg, error_details); 56 return GRPC_STATUS_INVALID_ARGUMENT; 57 } 58 59 grpc_status_code gsec_aead_crypter_encrypt_iovec( 60 gsec_aead_crypter* crypter, const uint8_t* nonce, size_t nonce_length, 61 const struct iovec* aad_vec, size_t aad_vec_length, 62 const struct iovec* plaintext_vec, size_t plaintext_vec_length, 63 struct iovec ciphertext_vec, size_t* ciphertext_bytes_written, 64 char** error_details) { 65 if (crypter != nullptr && crypter->vtable != nullptr && 66 crypter->vtable->encrypt_iovec != nullptr) { 67 return crypter->vtable->encrypt_iovec( 68 crypter, nonce, nonce_length, aad_vec, aad_vec_length, plaintext_vec, 69 plaintext_vec_length, ciphertext_vec, ciphertext_bytes_written, 70 error_details); 71 } 72 /* An error occurred. */ 73 maybe_copy_error_msg(vtable_error_msg, error_details); 74 return GRPC_STATUS_INVALID_ARGUMENT; 75 } 76 77 grpc_status_code gsec_aead_crypter_decrypt( 78 gsec_aead_crypter* crypter, const uint8_t* nonce, size_t nonce_length, 79 const uint8_t* aad, size_t aad_length, const uint8_t* ciphertext_and_tag, 80 size_t ciphertext_and_tag_length, uint8_t* plaintext, 81 size_t plaintext_length, size_t* bytes_written, char** error_details) { 82 if (crypter != nullptr && crypter->vtable != nullptr && 83 crypter->vtable->decrypt_iovec != nullptr) { 84 struct iovec aad_vec = {(void*)aad, aad_length}; 85 struct iovec ciphertext_vec = {(void*)ciphertext_and_tag, 86 ciphertext_and_tag_length}; 87 struct iovec plaintext_vec = {plaintext, plaintext_length}; 88 return crypter->vtable->decrypt_iovec( 89 crypter, nonce, nonce_length, &aad_vec, 1, &ciphertext_vec, 1, 90 plaintext_vec, bytes_written, error_details); 91 } 92 /* An error occurred. */ 93 maybe_copy_error_msg(vtable_error_msg, error_details); 94 return GRPC_STATUS_INVALID_ARGUMENT; 95 } 96 97 grpc_status_code gsec_aead_crypter_decrypt_iovec( 98 gsec_aead_crypter* crypter, const uint8_t* nonce, size_t nonce_length, 99 const struct iovec* aad_vec, size_t aad_vec_length, 100 const struct iovec* ciphertext_vec, size_t ciphertext_vec_length, 101 struct iovec plaintext_vec, size_t* plaintext_bytes_written, 102 char** error_details) { 103 if (crypter != nullptr && crypter->vtable != nullptr && 104 crypter->vtable->encrypt_iovec != nullptr) { 105 return crypter->vtable->decrypt_iovec( 106 crypter, nonce, nonce_length, aad_vec, aad_vec_length, ciphertext_vec, 107 ciphertext_vec_length, plaintext_vec, plaintext_bytes_written, 108 error_details); 109 } 110 /* An error occurred. */ 111 maybe_copy_error_msg(vtable_error_msg, error_details); 112 return GRPC_STATUS_INVALID_ARGUMENT; 113 } 114 115 grpc_status_code gsec_aead_crypter_max_ciphertext_and_tag_length( 116 const gsec_aead_crypter* crypter, size_t plaintext_length, 117 size_t* max_ciphertext_and_tag_length_to_return, char** error_details) { 118 if (crypter != nullptr && crypter->vtable != nullptr && 119 crypter->vtable->max_ciphertext_and_tag_length != nullptr) { 120 return crypter->vtable->max_ciphertext_and_tag_length( 121 crypter, plaintext_length, max_ciphertext_and_tag_length_to_return, 122 error_details); 123 } 124 /* An error occurred. */ 125 maybe_copy_error_msg(vtable_error_msg, error_details); 126 return GRPC_STATUS_INVALID_ARGUMENT; 127 } 128 129 grpc_status_code gsec_aead_crypter_max_plaintext_length( 130 const gsec_aead_crypter* crypter, size_t ciphertext_and_tag_length, 131 size_t* max_plaintext_length_to_return, char** error_details) { 132 if (crypter != nullptr && crypter->vtable != nullptr && 133 crypter->vtable->max_plaintext_length != nullptr) { 134 return crypter->vtable->max_plaintext_length( 135 crypter, ciphertext_and_tag_length, max_plaintext_length_to_return, 136 error_details); 137 } 138 /* An error occurred. */ 139 maybe_copy_error_msg(vtable_error_msg, error_details); 140 return GRPC_STATUS_INVALID_ARGUMENT; 141 } 142 143 grpc_status_code gsec_aead_crypter_nonce_length( 144 const gsec_aead_crypter* crypter, size_t* nonce_length_to_return, 145 char** error_details) { 146 if (crypter != nullptr && crypter->vtable != nullptr && 147 crypter->vtable->nonce_length != nullptr) { 148 return crypter->vtable->nonce_length(crypter, nonce_length_to_return, 149 error_details); 150 } 151 /* An error occurred. */ 152 maybe_copy_error_msg(vtable_error_msg, error_details); 153 return GRPC_STATUS_INVALID_ARGUMENT; 154 } 155 156 grpc_status_code gsec_aead_crypter_key_length(const gsec_aead_crypter* crypter, 157 size_t* key_length_to_return, 158 char** error_details) { 159 if (crypter != nullptr && crypter->vtable != nullptr && 160 crypter->vtable->key_length != nullptr) { 161 return crypter->vtable->key_length(crypter, key_length_to_return, 162 error_details); 163 } 164 /* An error occurred */ 165 maybe_copy_error_msg(vtable_error_msg, error_details); 166 return GRPC_STATUS_INVALID_ARGUMENT; 167 } 168 169 grpc_status_code gsec_aead_crypter_tag_length(const gsec_aead_crypter* crypter, 170 size_t* tag_length_to_return, 171 char** error_details) { 172 if (crypter != nullptr && crypter->vtable != nullptr && 173 crypter->vtable->tag_length != nullptr) { 174 return crypter->vtable->tag_length(crypter, tag_length_to_return, 175 error_details); 176 } 177 /* An error occurred. */ 178 maybe_copy_error_msg(vtable_error_msg, error_details); 179 return GRPC_STATUS_INVALID_ARGUMENT; 180 } 181 182 void gsec_aead_crypter_destroy(gsec_aead_crypter* crypter) { 183 if (crypter != nullptr) { 184 if (crypter->vtable != nullptr && crypter->vtable->destruct != nullptr) { 185 crypter->vtable->destruct(crypter); 186 } 187 gpr_free(crypter); 188 } 189 } 190