go.mondoo.com/cnquery@v0.0.0-20231005093811-59568235f6ea/llx/chunk.go (about) 1 // Copyright (c) Mondoo, Inc. 2 // SPDX-License-Identifier: BUSL-1.1 3 4 package llx 5 6 import ( 7 "encoding/base64" 8 "encoding/binary" 9 10 "go.mondoo.com/cnquery/types" 11 "go.mondoo.com/cnquery/utils/sortx" 12 "golang.org/x/crypto/blake2b" 13 ) 14 15 // Checksum computes the checksum of this chunk 16 func (c *Chunk) ChecksumV1(code *CodeV1) string { 17 data := []byte(c.Id) 18 19 b := make([]byte, 4) 20 binary.LittleEndian.PutUint32(b, uint32(c.Call)) 21 data = append(data, b...) 22 23 if c.Primitive != nil { 24 cs := c.Primitive.checksumV1(code) 25 data = append(data, cs...) 26 } 27 28 if c.Function != nil { 29 data = append(data, c.Function.checksumV1(code)...) 30 } 31 32 hash := blake2b.Sum512(data) 33 return base64.StdEncoding.EncodeToString(hash[:]) 34 } 35 36 func (f *Function) checksumV1(code *CodeV1) []byte { 37 res := []byte(f.Type) 38 39 for i := range f.Args { 40 cs := f.Args[i].checksumV1(code) 41 res = append(res, cs...) 42 } 43 44 return res 45 } 46 47 func (p *Primitive) checksumV1(code *CodeV1) []byte { 48 ref, ok := p.RefV1() 49 if ok { 50 typ := types.Type(p.Type) 51 if typ == types.Ref { 52 refChecksum, ok := code.Checksums[int32(ref)] 53 if !ok { 54 panic("llx> cannot compute checksum for primitive, it doesn't seem to reference a variable on the stack") 55 } 56 57 return []byte(refChecksum) 58 } 59 60 if typ.Underlying() == types.FunctionLike { 61 refFunction := code.Functions[int32(ref)-1] 62 if !ok { 63 panic("llx> cannot compute checksum for primitive, it doesn't seem to reference a function on the stack") 64 } 65 66 return []byte(refFunction.Id) 67 } 68 69 panic("llx> received a reference of an unknown type in trying to calculate the checksum") 70 } 71 72 res := []byte(p.Type) 73 res = append(res, p.Value...) 74 75 for i := range p.Array { 76 entry := p.Array[i] 77 res = append(res, entry.checksumV1(code)...) 78 } 79 80 keys := sortx.Keys(p.Map) 81 82 for _, k := range keys { 83 v := p.Map[k] 84 res = append(res, k...) 85 res = append(res, v.checksumV1(code)...) 86 } 87 88 return res 89 } 90 91 // Checksum computes the checksum of this chunk 92 func (c *Chunk) ChecksumV2(blockRef uint64, code *CodeV2) string { 93 data := []byte(c.Id) 94 95 b := make([]byte, 4) 96 binary.LittleEndian.PutUint32(b, uint32(c.Call)) 97 data = append(data, b...) 98 99 if c.Primitive != nil { 100 cs := c.Primitive.checksumV2(code) 101 data = append(data, cs...) 102 } 103 104 if c.Function != nil { 105 data = append(data, c.Function.checksumV2(code)...) 106 } 107 108 hash := blake2b.Sum512(data) 109 return base64.StdEncoding.EncodeToString(hash[:]) 110 } 111 112 func (f *Function) checksumV2(code *CodeV2) []byte { 113 res := []byte(f.Type) 114 115 if f.Binding != 0 { 116 ref := code.Checksums[f.Binding] 117 if ref == "" { 118 panic("cannot compute checksum for chunk, it doesn't seem to reference a function on the stack") 119 } 120 res = append(res, ref...) 121 } 122 123 for i := range f.Args { 124 cs := f.Args[i].checksumV2(code) 125 res = append(res, cs...) 126 } 127 128 return res 129 } 130 131 func (p *Primitive) checksumV2(code *CodeV2) []byte { 132 ref, ok := p.RefV2() 133 if ok { 134 typ := types.Type(p.Type) 135 if typ == types.Ref { 136 refChecksum, ok := code.Checksums[ref] 137 if !ok { 138 panic("llx> cannot compute checksum for primitive, it doesn't seem to reference a variable on the stack") 139 } 140 141 return []byte(refChecksum) 142 } else if typ.Underlying() == types.FunctionLike { 143 refChecksum := code.Blocks[(ref>>32)-1].checksum(code) 144 return []byte(refChecksum) 145 146 } 147 148 panic("llx> received a reference of an unknown type in trying to calculate the checksum") 149 } 150 151 res := []byte(p.Type) 152 res = append(res, p.Value...) 153 154 for i := range p.Array { 155 entry := p.Array[i] 156 res = append(res, entry.checksumV2(code)...) 157 } 158 159 keys := sortx.Keys(p.Map) 160 for _, k := range keys { 161 v := p.Map[k] 162 res = append(res, k...) 163 res = append(res, v.checksumV2(code)...) 164 } 165 166 return res 167 }