You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

63 lines
1.3 KiB

  1. package nano
  2. import (
  3. "bytes"
  4. "crypto/sha512"
  5. "github.com/pkg/errors"
  6. )
  7. const (
  8. App = 0x80
  9. Init = 0x00
  10. Update = 0x01
  11. Digest = 0x02
  12. MaxChunk = 253
  13. KeyLength = 32
  14. SigLength = 64
  15. )
  16. var separator = []byte{0, 0xCA, 0xFE, 0}
  17. func generateSignRequests(payload []byte) [][]byte {
  18. // nice one-shot
  19. digest := []byte{App, Digest}
  20. if len(payload) < MaxChunk {
  21. return [][]byte{append(digest, payload...)}
  22. }
  23. // large payload is multi-chunk
  24. result := [][]byte{{App, Init}}
  25. update := []byte{App, Update}
  26. for len(payload) > MaxChunk {
  27. msg := append(update, payload[:MaxChunk]...)
  28. payload = payload[MaxChunk:]
  29. result = append(result, msg)
  30. }
  31. result = append(result, append(update, payload...))
  32. result = append(result, digest)
  33. return result
  34. }
  35. func parseDigest(resp []byte) (key, sig []byte, err error) {
  36. if resp[0] != App || resp[1] != Digest {
  37. return nil, nil, errors.New("Invalid header")
  38. }
  39. resp = resp[2:]
  40. if len(resp) != KeyLength+SigLength+len(separator) {
  41. return nil, nil, errors.Errorf("Incorrect length: %d", len(resp))
  42. }
  43. key, resp = resp[:KeyLength], resp[KeyLength:]
  44. if !bytes.Equal(separator, resp[:len(separator)]) {
  45. return nil, nil, errors.New("Cannot find 0xCAFE")
  46. }
  47. sig = resp[len(separator):]
  48. return key, sig, nil
  49. }
  50. func hashMsg(data []byte) []byte {
  51. res := sha512.Sum512(data)
  52. return res[:]
  53. }