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 }
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)) }
// 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{}) }
func (t *PadBlockTest) AllBytesMissing() { b := []byte{} expected := append([]byte{0x80}, bytes.Repeat([]byte{0x00}, 15)...) ExpectThat(common.PadBlock(b), DeepEquals(expected)) }
func (t *PadBlockTest) LongBlock() { b := make([]byte, 17) f := func() { common.PadBlock(b) } ExpectThat(f, Panics(HasSubstr("16 bytes"))) }