%PDF- %PDF-
Mini Shell

Mini Shell

Direktori : /data/old/usr/lib/golang/src/crypto/internal/boring/
Upload File :
Create Path :
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;
	}
}

Zerion Mini Shell 1.0