Example #1
0
func main() {
	var (
		plaintext = "My super super super super duper long string to be encrypted"
		ivLen     = 12

		sLen, eLen               int
		encrypted, decrypted, iv string
		bufEncrypt, bufDecrypt   []byte
		ctxEncrypt, ctxDecrypt   crypto.EVP_CIPHER_CTX
	)

	// Setup error strings
	crypto.ERR_load_crypto_strings()

	// Add all OpenSSL algorithms
	crypto.OpenSSL_add_all_algorithms()

	// Load an OpenSSL config
	crypto.OPENSSL_config("")

	// Enable FIPS mode
	crypto.FIPS_mode_set(1)

	// Create new EVP_CIPHER_CTX instances
	ctxEncrypt, ctxDecrypt = crypto.EVP_CIPHER_CTX_new(), crypto.EVP_CIPHER_CTX_new()

	// Panic if either EVP_CIPHER_CTX fails to create
	if ctxEncrypt == nil {
		panic("ctxEncrypt is nil")
	}
	if ctxDecrypt == nil {
		panic("ctxDecrypt is nil")
	}

	// Initialize the EVP_CIPHER_CTX instances
	crypto.EVP_CIPHER_CTX_init(ctxEncrypt)
	crypto.EVP_CIPHER_CTX_init(ctxDecrypt)

	// Create random IV for nondeterministic encryption
	buf := make([]byte, ivLen)
	_, e := rand.Read(buf)
	if e != nil {
		panic(e)
	}
	iv = string(buf)

	// Pass the IV into the encrypted string to be used when decoding
	encrypted = iv

	// Print plaintext string
	fmt.Printf("plaintext: %s\n", plaintext)

	/*
		Encrypting a string
	*/
	// Initialize the ctxEncrypt context for encryption
	crypto.EVP_EncryptInit_ex(ctxEncrypt, crypto.EVP_aes_256_cbc(), crypto.SwigcptrStruct_SS_engine_st(0), "somekey", iv)

	// Make a buffer with enough size for the plaintext plus one block
	bufEncrypt = make([]byte, len(plaintext)+ctxEncrypt.GetCipher().GetBlock_size())

	// Update the cipher with some content
	crypto.EVP_EncryptUpdate(ctxEncrypt, bufEncrypt, &sLen, plaintext, len(plaintext))

	// Append encrypted data to encrypted string
	encrypted += string(bufEncrypt[:sLen])

	// Finalize the cipher to flush any remaining data
	crypto.EVP_EncryptFinal_ex(ctxEncrypt, bufEncrypt, &eLen)

	// Append any remaining data to the encrypted string
	encrypted += string(bufEncrypt[:eLen])

	// Clean up the EVP_CIPHER_CTX
	crypto.EVP_CIPHER_CTX_cleanup(ctxEncrypt)

	/*
		Decrypting a string
	*/
	// Grab the IV from the encrypted string
	iv = string([]byte(encrypted)[:ivLen])

	// Slice the encrypted string to begin after the iv
	encrypted = encrypted[ivLen:]

	// Initialize the ctxDecrypt context for decryption
	crypto.EVP_DecryptInit_ex(ctxDecrypt, crypto.EVP_aes_256_cbc(), crypto.SwigcptrStruct_SS_engine_st(0), "somekey", iv)

	// Make a buffer the exact size of the encrypted text
	bufDecrypt = make([]byte, len(encrypted))

	// Update the cipher with the encrypted string
	crypto.EVP_DecryptUpdate(ctxDecrypt, bufDecrypt, &sLen, encrypted, len(encrypted))

	// Append decrypted data to decrypted string
	decrypted = string(bufDecrypt[:sLen])

	// Finalize the cipher to flush any remaining data
	crypto.EVP_DecryptFinal_ex(ctxDecrypt, bufDecrypt, &eLen)

	// Append any remaining data to decrypted string
	decrypted += string(bufDecrypt[:eLen])

	// Print decoded string
	fmt.Printf("decrypted: %s\n", decrypted)

	// Clean up the EVP_CIPHER_CTX
	crypto.EVP_CIPHER_CTX_cleanup(ctxDecrypt)
}
		BeforeEach(func() {
			/* Create contexts for encryption and decryption */
			ivLen = 12 // Standard length for AEAD
			ctxEncrypt = EVP_CIPHER_CTX_new()
			EVP_CIPHER_CTX_init(ctxEncrypt)
			ctxDecrypt = EVP_CIPHER_CTX_new()
			EVP_CIPHER_CTX_init(ctxDecrypt)

			Expect(ctxEncrypt).NotTo(BeNil())
			Expect(ctxDecrypt).NotTo(BeNil())
			key = "somekey"

			/* Setup a random IV */
			buf := make([]byte, ivLen)
			l, err := rand.Read(buf)
			Expect(err).NotTo(HaveOccurred())
			Expect(l).To(Equal(len(buf)))
			iv = string(buf)

			/* Get our aad - in a real world use, this could be almost anything, e.g. a host:ip tuple */
			aad = "additionalAuthenticationData"

			tagLen = 16
			tag = make([]byte, tagLen)

			encrypted = ""
			decrypted = ""
		})

		It("Encrypts and decrypts a string using a standard 12 byte IV", func() {