%PDF- %PDF-
Direktori : /data/old/usr/lib/golang/src/crypto/internal/boring/ |
Current File : //data/old/usr/lib/golang/src/crypto/internal/boring/openssl_port_aead_gcm.c |
// This file contains a port of the BoringSSL AEAD interface. // +build linux // +build !android // +build !no_openssl // +build !cmd_go_bootstrap // +build !msan // +build !static #include "goboringcrypto.h" #include <openssl/err.h> int _goboringcrypto_EVP_CIPHER_CTX_seal( uint8_t *out, uint8_t *iv, uint8_t *aad, size_t aad_len, uint8_t *plaintext, size_t plaintext_len, size_t *ciphertext_len, uint8_t *key, int key_size) { EVP_CIPHER_CTX *ctx; int len; int ret; if (plaintext_len == 0) { plaintext = ""; } if (aad_len == 0) { aad = ""; } // Create and initialise the context. if(!(ctx = _goboringcrypto_EVP_CIPHER_CTX_new())) { goto err; } switch(key_size) { case 128: if (!_goboringcrypto_EVP_EncryptInit_ex(ctx, _goboringcrypto_EVP_aes_128_gcm(), NULL, NULL, NULL)) { goto err; } break; case 256: if (!_goboringcrypto_EVP_EncryptInit_ex(ctx, _goboringcrypto_EVP_aes_256_gcm(), NULL, NULL, NULL)) { goto err; } break; default: goto err; } // Initialize IV. if (!_goboringcrypto_EVP_EncryptInit_ex(ctx, NULL, NULL, key, NULL)) { goto err; } if (!_goboringcrypto_EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, 12, 0)) { goto err; } if (!_goboringcrypto_EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IV_FIXED, -1, iv)) { goto err; } if (!_goboringcrypto_EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_IV_GEN, 0, iv)) { goto err; } // Provide AAD data. if (!_goboringcrypto_EVP_EncryptUpdate(ctx, NULL, &len, aad, aad_len)) { goto err; } if (!_goboringcrypto_EVP_EncryptUpdate(ctx, out, &len, plaintext, plaintext_len)) { goto err; } *ciphertext_len = len; if (!_goboringcrypto_EVP_EncryptFinal_ex(ctx, out + len, &len)) { goto err; } *ciphertext_len += len; if (!_goboringcrypto_EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, 16, out+(*ciphertext_len))) { goto err; } *ciphertext_len += 16; ret = 1; err: _goboringcrypto_EVP_CIPHER_CTX_free(ctx); if(ret > 0) { return ret; } else { return 0; } } int _goboringcrypto_EVP_CIPHER_CTX_open( uint8_t *ciphertext, int ciphertext_len, uint8_t *aad, int aad_len, uint8_t *tag, uint8_t *key, int key_size, uint8_t *iv, int iv_len, uint8_t *plaintext, size_t *plaintext_len) { EVP_CIPHER_CTX *ctx; int len; int ret; if (aad_len == 0) { aad = ""; } // Create and initialise the context. if(!(ctx = _goboringcrypto_EVP_CIPHER_CTX_new())) return 0; switch(key_size) { case 128: if (!_goboringcrypto_EVP_DecryptInit_ex(ctx, _goboringcrypto_EVP_aes_128_gcm(), NULL, NULL, NULL)) { goto err; } break; case 256: if (!_goboringcrypto_EVP_DecryptInit_ex(ctx, _goboringcrypto_EVP_aes_256_gcm(), NULL, NULL, NULL)) { goto err; } break; } // Initialize key and nonce. if(!_goboringcrypto_EVP_DecryptInit_ex(ctx, NULL, NULL, key, iv)) { goto err; } // Provide any AAD data. if(!_goboringcrypto_EVP_DecryptUpdate(ctx, NULL, &len, aad, aad_len)) { goto err; } // Provide the message to be decrypted, and obtain the plaintext output. if(!_goboringcrypto_EVP_DecryptUpdate(ctx, plaintext, &len, ciphertext, ciphertext_len)) { goto err; } *plaintext_len = len; // Set expected tag value. Works in OpenSSL 1.0.1d and later. if(!_goboringcrypto_EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, 16, tag)) { goto err; } // Finalise the decryption. A positive return value indicates success, // anything else is a failure - the plaintext is not trustworthy. ret = _goboringcrypto_EVP_DecryptFinal_ex(ctx, plaintext + len, &len); err: _goboringcrypto_EVP_CIPHER_CTX_free(ctx); if(ret > 0) { // Success *plaintext_len += len; return ret; } else { // Verify failed return 0; } }