(key types.AES128Key, dir uint8, addr types.DevAddr, fCnt uint32, payload []byte, opts ...EncryptionOption)
| 47 | } |
| 48 | |
| 49 | func encryptMessage(key types.AES128Key, dir uint8, addr types.DevAddr, fCnt uint32, payload []byte, opts ...EncryptionOption) ([]byte, error) { |
| 50 | encOpts := &encryptionOptions{} |
| 51 | for _, opt := range opts { |
| 52 | opt(encOpts) |
| 53 | } |
| 54 | k := len(payload) / aes.BlockSize |
| 55 | if len(payload)%aes.BlockSize != 0 { |
| 56 | k++ |
| 57 | } |
| 58 | if k > math.MaxUint8 { |
| 59 | panic(fmt.Sprintf("k value of %d overflows byte", k)) |
| 60 | } |
| 61 | encrypted := make([]byte, 0, k*16) |
| 62 | cipher, err := aes.NewCipher(key[:]) |
| 63 | if err != nil { |
| 64 | panic(err) // types.AES128Key |
| 65 | } |
| 66 | var a [aes.BlockSize]byte |
| 67 | a[0] = 0x01 |
| 68 | copy(a[1:5], encOpts.frameTypeConstant[:]) |
| 69 | a[5] = dir |
| 70 | copy(a[6:10], reverse(addr[:])) |
| 71 | binary.LittleEndian.PutUint32(a[10:14], fCnt) |
| 72 | var s [aes.BlockSize]byte |
| 73 | var b [aes.BlockSize]byte |
| 74 | for i := uint8(0); i < uint8(k); i++ { |
| 75 | copy(b[:], payload[i*aes.BlockSize:]) |
| 76 | a[15] = i + 1 |
| 77 | cipher.Encrypt(s[:], a[:]) |
| 78 | for j := range aes.BlockSize { |
| 79 | b[j] = b[j] ^ s[j] |
| 80 | } |
| 81 | encrypted = append(encrypted, b[:]...) |
| 82 | } |
| 83 | return encrypted[:len(payload)], nil |
| 84 | } |
| 85 | |
| 86 | // EncryptUplink encrypts an uplink payload |
| 87 | // - The payload contains the FRMPayload bytes |
no test coverage detected