Example #1
0
func (state fastGCMState) Seal(dst, nonce, plaintext, data []byte) []byte {
	rawenc := make([]byte, len(plaintext))
	sched := (*_Ctype_gcm_state)(unsafe.Pointer(&state[0]))
	FASSERT(C.gcm_reset(sched) == C.CRYPT_OK)
	FASSERT(C.gcm_add_iv(sched, unsafe_bytes(nonce), 12) == C.CRYPT_OK)
	C.gcm_add_aad(sched, nil, 0)
	FASSERT(C.gcm_process(sched, unsafe_bytes(plaintext), C.ulong(len(plaintext)),
		unsafe_bytes(rawenc), C.GCM_ENCRYPT) == C.CRYPT_OK)
	tag := buf.Alloc()
	thing := C.ulong(16)
	FASSERT(C.gcm_done(sched, unsafe_bytes(tag), &thing) == C.CRYPT_OK)
	rawenc = append(rawenc, tag[:int(thing)]...)
	buf.Free(tag)
	return append(dst, rawenc...)
}
Example #2
0
func (state fastGCMState) Open(dst, nonce, ciphertext, data []byte) ([]byte, error) {
	rawpt := make([]byte, len(ciphertext)-16)
	sched := (*_Ctype_gcm_state)(unsafe.Pointer(&state[0]))
	FASSERT(C.gcm_reset(sched) == C.CRYPT_OK)
	FASSERT(C.gcm_add_iv(sched, unsafe_bytes(nonce), 12) == C.CRYPT_OK)
	FASSERT(C.gcm_add_aad(sched, nil, 0) == C.CRYPT_OK)
	FASSERT(C.gcm_process(sched, unsafe_bytes(rawpt), C.ulong(len(rawpt)),
		unsafe_bytes(ciphertext), C.GCM_DECRYPT) == C.CRYPT_OK)
	tag := buf.Alloc()
	thing := C.ulong(16)
	C.gcm_done(sched, unsafe_bytes(tag), &thing)

	if subtle.ConstantTimeCompare(tag[:int(thing)], ciphertext[len(rawpt):]) != 1 {
		return nil, errors.New("WTF! HASH OF MISMATCHINGS!")
	}
	buf.Free(tag)
	return append(dst, rawpt...), nil
}