Exemple #1
0
// HashReader hashes the given reader with the specified hash,
// returning the final sum. This is done in blocks, so reading
// from large files or other out-of-memory sources should not
// cause memory issues.
func HashReader(h hash.Hash, r io.Reader) (gocrypt.Hash, error) {
	block := make([]byte, h.BlockSize())
	for {
		cnt, err := r.Read(block)
		h.Write(block[:cnt])

		if err == io.EOF {
			break
		} else if err != nil {
			return nil, err
		}
	}

	return h.Sum(nil), nil
}
Exemple #2
0
// NIST SP 800-56 Concatenation Key Derivation Function (see section 5.8.1).
func concatKDF(hash hash.Hash, z, s1 []byte, kdLen int) (k []byte, err error) {
	if s1 == nil {
		s1 = make([]byte, 0)
	}

	reps := ((kdLen + 7) * 8) / (hash.BlockSize() * 8)
	if big.NewInt(int64(reps)).Cmp(big2To32M1) > 0 {
		fmt.Println(big2To32M1)
		return nil, ErrKeyDataTooLong
	}

	counter := []byte{0, 0, 0, 1}
	k = make([]byte, 0)

	for i := 0; i <= reps; i++ {
		hash.Write(counter)
		hash.Write(z)
		hash.Write(s1)
		k = append(k, hash.Sum(nil)...)
		hash.Reset()
		incCounter(counter)
	}

	k = k[:kdLen]
	return
}
Exemple #3
0
// Encode a message with fixed salt, return the encoded message and random salt
func Encode(hash hash.Hash, msg, salt []byte) ([]byte, []byte, error) {
	if hash == nil {
		hash = sha256.New()
	}
	rand, err := rand.B.Alphanumeric(hash.BlockSize())
	if err != nil {
		return nil, nil, err
	}

	return SaltEncode(hash, msg, salt, rand), rand, err
}
Exemple #4
0
func Hash(hashname string, filename string) (sum string, err error) {
	f, err := os.Open(filename)
	if err != nil {
		return
	}

	var h hash.Hash

	switch hashname {
	case "md5":
		h = md5.New()
	case "sha1":
		h = sha1.New()
	case "sha2", "sha256":
		h = sha256.New()
	case "sha5", "sha512":
		h = sha512.New()
	default:
		err = errors.New("unknown hash: " + hashname)
		return
	}

	var nr int
	buf := make([]byte, h.BlockSize())
	bf := bufio.NewReader(f)
	for {
		nr, _ = bf.Read(buf)
		h.Write(buf[0:nr])
		if nr < len(buf) {
			break
		}
	}
	f.Close()
	sum = fmt.Sprintf("%0x", h.Sum(nil))
	return
}
Exemple #5
0
func (t *HashTest) BlockSize() {
	var h hash.Hash
	var err error

	// AES-128
	h, err = cmac.New(make([]byte, 16))
	AssertEq(nil, err)
	ExpectEq(16, h.BlockSize())

	// AES-192
	h, err = cmac.New(make([]byte, 24))
	AssertEq(nil, err)
	ExpectEq(16, h.BlockSize())

	// AES-256
	h, err = cmac.New(make([]byte, 32))
	AssertEq(nil, err)
	ExpectEq(16, h.BlockSize())
}
Exemple #6
0
func (this HashFile) Exec(input types.Value) (out types.Value, err error) {
	var inputMap types.Map
	if i, ok := input.(types.Map); ok {
		inputMap = i
	} else {
		err = errors.New(fmt.Sprintf("expected a map as input, got a %T", input))
		return
	}

	var hashName string
	var hashNameElement = inputMap[types.Keyword("hash")]
	if hashNameElement == nil {
		hashName = "sha256"
	} else if h, ok := hashNameElement.(types.String); ok {
		hashName = string(h)
	} else if k, ok := hashNameElement.(types.Keyword); ok {
		hashName = string(k)
	} else if s, ok := hashNameElement.(types.Symbol); ok {
		hashName = string(s)
	} else {
		err = errors.New(":hash must be a string, keyword, or symbol if specified")
		return
	}
	hashName = strings.ToLower(hashName)

	var hash hash.Hash
	if hashName == "md5" {
		hash = md5.New()
	} else if hashName == "sha" || hashName == "sha1" || hashName == "sha-1" {
		hash = sha1.New()
	} else if hashName == "sha224" || hashName == "sha-224" {
		hash = sha256.New224()
	} else if hashName == "sha256" || hashName == "sha-256" {
		hash = sha256.New()
	} else if hashName == "sha384" || hashName == "sha-384" {
		hash = sha512.New384()
	} else if hashName == "sha512/224" || hashName == "sha-512/224" {
		hash = sha512.New512_224()
	} else if hashName == "sha512/256" || hashName == "sha-512/256" {
		hash = sha512.New512_256()
	} else if hashName == "sha512" || hashName == "sha-512" {
		hash = sha512.New()
	} else {
		err = errors.New(fmt.Sprint("unknown hash name: ", hashName))
		return
	}

	var fileName string
	var fileElem = inputMap[types.Keyword("file")]
	if fileElem == nil {
		err = errors.New(":file argument is required")
		return
	} else if f, ok := fileElem.(types.String); ok {
		fileName = string(f)
	} else {
		err = errors.New(":file argument must be a string")
		return
	}

	file, err := os.Open(fileName)
	if err != nil {
		return
	}
	hashOut := bufio.NewWriterSize(hash, hash.BlockSize())
	wrote, err := io.Copy(hashOut, file)
	hashOut.Flush()
	if err != nil {
		return
	}
	out = types.Map{
		types.Keyword("success"): types.Bool(true),
		types.Keyword("size"):    types.Int(wrote),
		types.Keyword("file"):    types.String(fileName),
		types.Keyword("hash"):    types.Keyword(hashName),
		types.Keyword("digest"):  types.String(fmt.Sprintf("%x", hash.Sum(nil))),
	}
	return
}