github.com/transparency-dev/armored-witness-os@v0.1.3-0.20240514084412-27eef7325168/trusted_os/net.go (about)

     1  // Copyright 2022 The Armored Witness OS authors. All Rights Reserved.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package main
    16  
    17  import (
    18  	"fmt"
    19  	"net"
    20  
    21  	"github.com/usbarmory/tamago/soc/nxp/enet"
    22  	"github.com/usbarmory/tamago/soc/nxp/imx6ul"
    23  	"github.com/usbarmory/tamago/soc/nxp/usb"
    24  
    25  	"github.com/usbarmory/GoTEE/monitor"
    26  
    27  	"github.com/usbarmory/imx-usbnet"
    28  
    29  	"gvisor.dev/gvisor/pkg/tcpip"
    30  	"gvisor.dev/gvisor/pkg/tcpip/link/channel"
    31  )
    32  
    33  const (
    34  	RXQueueSize = 1000
    35  	TXQueueSize = 1000
    36  )
    37  
    38  // Trusted OS syscalls
    39  const (
    40  	RX   = 0x10000000
    41  	TX   = 0x10000001
    42  	FIQ  = 0x10000002
    43  	FREQ = 0x10000003
    44  )
    45  
    46  // default Trusted OS USB network settings
    47  const (
    48  	deviceMAC = "1a:55:89:a2:69:41"
    49  	hostMAC   = "1a:55:89:a2:69:42"
    50  )
    51  
    52  var (
    53  	rxQueue chan []byte
    54  	txQueue chan []byte
    55  )
    56  
    57  func asyncRx(buf []byte) {
    58  	select {
    59  	case rxQueue <- buf:
    60  	default:
    61  	}
    62  }
    63  
    64  func asyncTx() (buf []byte) {
    65  	select {
    66  	case buf = <-txQueue:
    67  	default:
    68  	}
    69  
    70  	return
    71  }
    72  
    73  func rxFromApplet(ctx *monitor.ExecCtx) (err error) {
    74  	select {
    75  	case buf := <-rxQueue:
    76  		off, n, err := ctx.TransferRegion()
    77  
    78  		if err != nil {
    79  			return err
    80  		}
    81  
    82  		r := len(buf)
    83  
    84  		if r > n {
    85  			return fmt.Errorf("invalid transfer size (%d > %d)", r, n)
    86  		}
    87  
    88  		ctx.Memory.Write(ctx.Memory.Start(), off, buf)
    89  		ctx.Ret(r)
    90  	default:
    91  		ctx.Ret(0)
    92  	}
    93  
    94  	return
    95  }
    96  
    97  func txFromApplet(ctx *monitor.ExecCtx) (err error) {
    98  	off, n, err := ctx.TransferRegion()
    99  
   100  	if err != nil {
   101  		return
   102  	}
   103  
   104  	buf := make([]byte, n)
   105  
   106  	ctx.Memory.Read(ctx.Memory.Start(), off, buf)
   107  
   108  	switch {
   109  	case LAN != nil:
   110  		LAN.Tx(buf)
   111  	case USB != nil:
   112  		txQueue <- buf
   113  	}
   114  
   115  	return
   116  }
   117  
   118  func netStartUSB() {
   119  	hostHardwareAddr, _ := net.ParseMAC(hostMAC)
   120  	deviceHardwareAddr, _ := net.ParseMAC(deviceMAC)
   121  
   122  	device := &usb.Device{}
   123  	usbnet.ConfigureDevice(device, deviceMAC)
   124  
   125  	linkAddr, _ := tcpip.ParseMACAddress(deviceMAC)
   126  
   127  	nic := &usbnet.NIC{
   128  		HostMAC:   hostHardwareAddr,
   129  		DeviceMAC: deviceHardwareAddr,
   130  		Link:      channel.New(256, usbnet.MTU, linkAddr),
   131  		Device:    device,
   132  	}
   133  
   134  	rxQueue = make(chan []byte, RXQueueSize)
   135  	txQueue = make(chan []byte, TXQueueSize)
   136  
   137  	nic.Rx = func(buf []byte, lastErr error) (_ []byte, err error) {
   138  		asyncRx(buf)
   139  		return
   140  	}
   141  
   142  	nic.Tx = func(_ []byte, lastErr error) (in []byte, err error) {
   143  		in = asyncTx()
   144  		return
   145  	}
   146  
   147  	if err := nic.Init(); err != nil {
   148  		panic(err)
   149  	}
   150  
   151  	USB.Device = device
   152  
   153  	USB.Init()
   154  	USB.DeviceMode()
   155  
   156  	USB.EnableInterrupt(usb.IRQ_URI) // reset
   157  	USB.EnableInterrupt(usb.IRQ_PCI) // port change detect
   158  	USB.EnableInterrupt(usb.IRQ_UI)  // transfer completion
   159  
   160  	irqHandler[USB.IRQ] = func() {
   161  		USB.ServiceInterrupts()
   162  	}
   163  
   164  	imx6ul.GIC.EnableInterrupt(USB.IRQ, true)
   165  }
   166  
   167  func netStartLAN() {
   168  	rxQueue = make(chan []byte, RXQueueSize)
   169  
   170  	irqHandler[LAN.IRQ] = func() {
   171  		for buf := LAN.Rx(); buf != nil; buf = LAN.Rx() {
   172  			asyncRx(buf)
   173  			LAN.ClearInterrupt(enet.IRQ_RXF)
   174  		}
   175  
   176  	}
   177  
   178  	LAN.EnableInterrupt(enet.IRQ_RXF)
   179  	LAN.Start(false)
   180  
   181  	imx6ul.GIC.EnableInterrupt(LAN.IRQ, true)
   182  }
   183  
   184  func netStart() {
   185  	switch {
   186  	case LAN != nil:
   187  		netStartLAN()
   188  	case USB != nil:
   189  		netStartUSB()
   190  	}
   191  }