Ejemplo n.º 1
0
func (h *cmacHash) Sum(b []byte) []byte {
	dataLen := len(h.data)

	// We should have at most one block left.
	if dataLen > blockSize {
		panic(fmt.Sprintf("Unexpected data: %x", h.data))
	}

	// Calculate M_last.
	mLast := make([]byte, blockSize)
	if dataLen == blockSize {
		common.Xor(mLast, h.data, h.k1)
	} else {
		// TODO(jacobsa): Accept a destination buffer in common.PadBlock and
		// simplify this code.
		common.Xor(mLast, common.PadBlock(h.data), h.k2)
	}

	y := make([]byte, blockSize)
	common.Xor(y, mLast, h.x)

	result := make([]byte, blockSize)
	h.ciph.Encrypt(result, y)

	b = append(b, result...)
	return b
}
Ejemplo n.º 2
0
func (t *PadBlockTest) MultipleBytesMissing() {
	b, err := hex.DecodeString("deadbeeffeedfaceba5eba11ca")
	AssertEq(nil, err)
	AssertEq(13, len(b))

	expected := append(b, 0x80, 0x00, 0x00)
	ExpectThat(common.PadBlock(b), DeepEquals(expected))
}
Ejemplo n.º 3
0
// Run the S2V "string to vector" function of RFC 5297 using the input key and
// string vector, which must be non-empty. (RFC 5297 defines S2V to handle the
// empty vector case, but it is never used that way by higher-level functions.)
//
// If provided, the supplied scatch space will be used to avoid an allocation.
// It should be (but is not required to be) as large as the last element of
// strings.
//
// The result is guaranteed to be of length s2vSize.
func s2v(key []byte, strings [][]byte, scratch []byte) []byte {
	numStrings := len(strings)
	if numStrings == 0 {
		panic("strings vector must be non-empty.")
	}

	// Create a CMAC hash.
	h, err := cmac.New(key)
	if err != nil {
		panic(fmt.Sprintf("cmac.New: %v", err))
	}

	// Initialize.
	if _, err := h.Write(s2vZero); err != nil {
		panic(fmt.Sprintf("h.Write: %v", err))
	}

	d := h.Sum([]byte{})
	h.Reset()

	// Handle all strings but the last.
	for i := 0; i < numStrings-1; i++ {
		if _, err := h.Write(strings[i]); err != nil {
			panic(fmt.Sprintf("h.Write: %v", err))
		}

		common.Xor(d, dbl(d), h.Sum([]byte{}))
		h.Reset()
	}

	// Handle the last string.
	lastString := strings[numStrings-1]
	var t []byte
	if len(lastString) >= aes.BlockSize {
		// Make an output buffer the length of lastString.
		if cap(scratch) >= len(lastString) {
			t = scratch[:len(lastString)]
		} else {
			t = make([]byte, len(lastString))
		}

		// XOR d on the end of lastString.
		xorend(t, lastString, d)
	} else {
		t = make([]byte, aes.BlockSize)
		common.Xor(t, dbl(d), common.PadBlock(lastString))
	}

	if _, err := h.Write(t); err != nil {
		panic(fmt.Sprintf("h.Write: %v", err))
	}

	return h.Sum([]byte{})
}
Ejemplo n.º 4
0
func (t *PadBlockTest) AllBytesMissing() {
	b := []byte{}
	expected := append([]byte{0x80}, bytes.Repeat([]byte{0x00}, 15)...)
	ExpectThat(common.PadBlock(b), DeepEquals(expected))
}
Ejemplo n.º 5
0
func (t *PadBlockTest) LongBlock() {
	b := make([]byte, 17)
	f := func() { common.PadBlock(b) }
	ExpectThat(f, Panics(HasSubstr("16 bytes")))
}