aboutsummaryrefslogtreecommitdiff
path: root/cryptech_console
blob: 5ac12ba841cdc718b748a089f75e8bb5c2fc5d9c (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#!/usr/bin/env python
#
# Copyright (c) 2017, NORDUnet A/S All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
# - Redistributions of source code must retain the above copyright notice,
#   this list of conditions and the following disclaimer.
#
# - Redistributions in binary form must reproduce the above copyright
#   notice, this list of conditions and the following disclaimer in the
#   documentation and/or other materials provided with the distribution.
#
# - Neither the name of the NORDUnet nor the names of its contributors may
#   be used to endorse or promote products derived from this software
#   without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
# TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

"""
Console client shim to work with Cryptech Python multiplexer.
"""

import os
import sys
import socket
import atexit
import termios
import argparse

import tornado.iostream
import tornado.ioloop
import tornado.gen

class FemtoTerm(object):

    def __init__(self, s):
        self.termios_setup()
        self.stdin_stream  = tornado.iostream.PipeIOStream(sys.stdin.fileno())
        self.stdout_stream = tornado.iostream.PipeIOStream(sys.stdout.fileno())
        self.socket_stream = tornado.iostream.IOStream(s)
        self.closed = False

    def close(self):
        self.termios_teardown()
        self.stdin_stream.close()
        self.stdout_stream.close()
        self.socket_stream.close()
        self.closed = True

    @tornado.gen.coroutine
    def run(self):
        yield [self.stdout_loop(), self.stdin_loop()]

    def termios_setup(self):
        self.fd = sys.stdin.fileno()
        self.old_tcattr = termios.tcgetattr(self.fd)
        self.new_tcattr = termios.tcgetattr(self.fd)
        atexit.register(self.termios_teardown)
        self.new_tcattr[3] &= ~(termios.ICANON | termios.ECHO) #  | termios.ISIG
        self.new_tcattr[6][termios.VMIN] = 1
        self.new_tcattr[6][termios.VTIME] = 0
        termios.tcsetattr(self.fd, termios.TCSANOW, self.new_tcattr)

    def termios_teardown(self):
        if self.fd is not None:
            termios.tcsetattr(self.fd, termios.TCSAFLUSH, self.old_tcattr)
            self.fd = None

    @tornado.gen.coroutine
    def copy_loop(self, stream1, stream2, text1, text2, buffer_size = 1024):
        try:
            while not self.closed:
                buffer = yield stream1.read_bytes(buffer_size, partial = True)
                yield stream2.write(buffer.replace(text1, text2))
        except tornado.iostream.StreamClosedError:
            self.close()

    def stdin_loop(self):
        return self.copy_loop(self.stdin_stream, self.socket_stream, "\n", "\r")

    def stdout_loop(self):
        return self.copy_loop(self.socket_stream, self.stdout_stream, "\r\n", "\n")

def main():
    parser = argparse.ArgumentParser(formatter_class = argparse.ArgumentDefaultsHelpFormatter)
    parser.add_argument("cty_socket",
                        nargs = "?",
                        help = "CTY PF_UNIX socket name",
                        default = os.getenv("CRYPTECH_CTY_CLIENT_SOCKET_NAME",
                                            "/tmp/.cryptech_muxd.cty"))
    args = parser.parse_args()

    s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
    try:
        s.connect(args.cty_socket)
    except socket.error:
        sys.exit("Couldn't connect to socket {}".format(args.cty_socket))
    tornado.ioloop.IOLoop.current().run_sync(FemtoTerm(s).run)

if __name__ == "__main__":
    try:
        main()
    except KeyboardInterrupt:
        pass
s="c1">// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF // ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // //====================================================================== module uart_core( input wire clk, input wire reset_n, // Configuration parameters input wire [15 : 0] bit_rate, input wire [1 : 0] stop_bits, // External data interface input wire rxd, output wire txd, // Internal receive interface. output wire rxd_syn, output [7 : 0] rxd_data, input wire rxd_ack, // Internal transmit interface. input wire txd_syn, input wire [7 : 0] txd_data, output wire txd_ack ); //---------------------------------------------------------------- // Internal constant and parameter definitions. //---------------------------------------------------------------- // The default clock rate is based on target clock frequency // divided by the bit rate times in order to hit the // center of the bits. I.e. // Clock: 50 MHz // Bitrate: 19200 bps // Divisor = 50*10E6 / 9600 = 5208 parameter DEFAULT_CLK_RATE = 5208; parameter DEFAULT_HALF_CLK_RATE = DEFAULT_CLK_RATE / 2; parameter DEFAULT_DATA_BITS = 8; parameter DEFAULT_STOP_BITS = 1; parameter ERX_IDLE = 0; parameter ERX_START = 1; parameter ERX_BITS = 2; parameter ERX_STOP = 3; parameter ERX_SYN = 4; parameter ETX_IDLE = 0; parameter ETX_ACK = 1; parameter ETX_START = 2; parameter ETX_BITS = 3; parameter ETX_STOP = 4; //---------------------------------------------------------------- // Registers including update variables and write enable. //---------------------------------------------------------------- reg rxd_reg; reg [7 : 0] rxd_byte_reg; reg rxd_byte_we; reg [4 : 0] rxd_bit_ctr_reg; reg [4 : 0] rxd_bit_ctr_new; reg rxd_bit_ctr_we; reg rxd_bit_ctr_rst; reg rxd_bit_ctr_inc; reg [15 : 0] rxd_bitrate_ctr_reg; reg [15 : 0] rxd_bitrate_ctr_new; reg rxd_bitrate_ctr_we; reg rxd_bitrate_ctr_rst; reg rxd_bitrate_ctr_inc; reg rxd_syn_reg; reg rxd_syn_new; reg rxd_syn_we; reg [2 : 0] erx_ctrl_reg; reg [2 : 0] erx_ctrl_new; reg erx_ctrl_we; reg txd_reg; reg txd_new; reg txd_we; reg [7 : 0] txd_byte_reg; reg [7 : 0] txd_byte_new; reg txd_byte_we; reg [4 : 0] txd_bit_ctr_reg; reg [4 : 0] txd_bit_ctr_new; reg txd_bit_ctr_we; reg txd_bit_ctr_rst; reg txd_bit_ctr_inc; reg [15 : 0] txd_bitrate_ctr_reg; reg [15 : 0] txd_bitrate_ctr_new; reg txd_bitrate_ctr_we; reg txd_bitrate_ctr_rst; reg txd_bitrate_ctr_inc; reg txd_ack_reg; reg txd_ack_new; reg txd_ack_we; reg [2 : 0] etx_ctrl_reg; reg [2 : 0] etx_ctrl_new; reg etx_ctrl_we; //---------------------------------------------------------------- // Wires. //---------------------------------------------------------------- //---------------------------------------------------------------- // Concurrent connectivity for ports etc. //---------------------------------------------------------------- assign txd = txd_reg; assign rxd_syn = rxd_syn_reg; assign rxd_data = rxd_byte_reg; assign txd_ack = txd_ack_reg; //---------------------------------------------------------------- // reg_update // // Update functionality for all registers in the core. // All registers are positive edge triggered with synchronous // active low reset. All registers have write enable. //---------------------------------------------------------------- always @ (posedge clk) begin: reg_update if (!reset_n) begin rxd_reg <= 0; rxd_byte_reg <= 8'h00; rxd_bit_ctr_reg <= 4'h0; rxd_bitrate_ctr_reg <= 16'h0000; rxd_syn_reg <= 0; erx_ctrl_reg <= ERX_IDLE; txd_reg <= 1; txd_byte_reg <= 8'h00; txd_bit_ctr_reg <= 4'h0; txd_bitrate_ctr_reg <= 16'h0000; txd_ack_reg <= 0; etx_ctrl_reg <= ETX_IDLE; end else begin // We sample the rx input port every cycle. rxd_reg <= rxd; // We shift the rxd bit into msb. if (rxd_byte_we) begin rxd_byte_reg <= {rxd_reg, rxd_byte_reg[7 : 1]}; end if (rxd_bit_ctr_we) begin rxd_bit_ctr_reg <= rxd_bit_ctr_new; end if (rxd_bitrate_ctr_we) begin rxd_bitrate_ctr_reg <= rxd_bitrate_ctr_new; end if (rxd_syn_we) begin rxd_syn_reg <= rxd_syn_new; end if (erx_ctrl_we) begin erx_ctrl_reg <= erx_ctrl_new; end if (txd_we) begin txd_reg <= txd_new; end if (txd_byte_we) begin txd_byte_reg <= txd_byte_new; end if (txd_bit_ctr_we) begin txd_bit_ctr_reg <= txd_bit_ctr_new; end if (txd_bitrate_ctr_we) begin txd_bitrate_ctr_reg <= txd_bitrate_ctr_new; end if (txd_ack_we) begin txd_ack_reg <= txd_ack_new; end if (etx_ctrl_we) begin etx_ctrl_reg <= etx_ctrl_new; end end end // reg_update //---------------------------------------------------------------- // rxd_bit_ctr // // Bit counter for receiving data on the external // serial interface. //---------------------------------------------------------------- always @* begin: rxd_bit_ctr rxd_bit_ctr_new = 4'h0; rxd_bit_ctr_we = 0; if (rxd_bit_ctr_rst) begin rxd_bit_ctr_new = 4'h0; rxd_bit_ctr_we = 1; end else if (rxd_bit_ctr_inc) begin rxd_bit_ctr_new = rxd_bit_ctr_reg + 4'b0001; rxd_bit_ctr_we = 1; end end // rxd_bit_ctr //---------------------------------------------------------------- // rxd_bitrate_ctr // // Bitrate counter for receiving data on the external // serial interface. //---------------------------------------------------------------- always @* begin: rxd_bitrate_ctr rxd_bitrate_ctr_new = 16'h0000; rxd_bitrate_ctr_we = 0; if (rxd_bitrate_ctr_rst) begin rxd_bitrate_ctr_new = 16'h0000; rxd_bitrate_ctr_we = 1; end else if (rxd_bitrate_ctr_inc) begin rxd_bitrate_ctr_new = rxd_bitrate_ctr_reg + 16'h0001; rxd_bitrate_ctr_we = 1; end end // rxd_bitrate_ctr //---------------------------------------------------------------- // txd_bit_ctr // // Bit counter for transmitting data on the external // serial interface. //---------------------------------------------------------------- always @* begin: txd_bit_ctr txd_bit_ctr_new = 4'h0; txd_bit_ctr_we = 0; if (txd_bit_ctr_rst) begin txd_bit_ctr_new = 4'h0; txd_bit_ctr_we = 1; end else if (txd_bit_ctr_inc) begin txd_bit_ctr_new = txd_bit_ctr_reg + 4'b0001; txd_bit_ctr_we = 1; end end // txd_bit_ctr //---------------------------------------------------------------- // txd_bitrate_ctr // // Bitrate counter for transmitting data on the external // serial interface. //---------------------------------------------------------------- always @* begin: txd_bitrate_ctr txd_bitrate_ctr_new = 16'h0000; txd_bitrate_ctr_we = 0; if (txd_bitrate_ctr_rst) begin txd_bitrate_ctr_new = 16'h0000; txd_bitrate_ctr_we = 1; end else if (txd_bitrate_ctr_inc) begin txd_bitrate_ctr_new = txd_bitrate_ctr_reg + 16'h0001; txd_bitrate_ctr_we = 1; end end // txd_bitrate_ctr //---------------------------------------------------------------- // external_rx_engine // // Logic that implements the receive engine towards // the external interface. Detects incoming data, collects it, // if required checks parity and store correct data into // the rx buffer. //---------------------------------------------------------------- always @* begin: external_rx_engine rxd_bit_ctr_rst = 0; rxd_bit_ctr_inc = 0; rxd_bitrate_ctr_rst = 0; rxd_bitrate_ctr_inc = 0; rxd_byte_we = 0; rxd_syn_new = 0; rxd_syn_we = 0; erx_ctrl_new = ERX_IDLE; erx_ctrl_we = 0; case (erx_ctrl_reg) ERX_IDLE: begin if (!rxd_reg) begin // Possible start bit detected. rxd_bitrate_ctr_rst = 1; erx_ctrl_new = ERX_START; erx_ctrl_we = 1; end end ERX_START: begin rxd_bitrate_ctr_inc = 1; if (rxd_reg) begin // Just a glitch. erx_ctrl_new = ERX_IDLE; erx_ctrl_we = 1; end else begin if (rxd_bitrate_ctr_reg == DEFAULT_HALF_CLK_RATE) begin // start bit assumed. We start sampling data. rxd_bit_ctr_rst = 1; rxd_bitrate_ctr_rst = 1; erx_ctrl_new = ERX_BITS; erx_ctrl_we = 1; end end end ERX_BITS: begin if (rxd_bitrate_ctr_reg < DEFAULT_CLK_RATE) begin rxd_bitrate_ctr_inc = 1; end else begin rxd_byte_we = 1; rxd_bit_ctr_inc = 1; rxd_bitrate_ctr_rst = 1; if (rxd_bit_ctr_reg == DEFAULT_DATA_BITS - 1) begin erx_ctrl_new = ERX_STOP; erx_ctrl_we = 1; end end end ERX_STOP: begin rxd_bitrate_ctr_inc = 1; if (rxd_bitrate_ctr_reg == DEFAULT_CLK_RATE * DEFAULT_STOP_BITS) begin rxd_syn_new = 1; rxd_syn_we = 1; erx_ctrl_new = ERX_SYN; erx_ctrl_we = 1; end end ERX_SYN: begin if (rxd_ack) begin rxd_syn_new = 0; rxd_syn_we = 1; erx_ctrl_new = ERX_IDLE; erx_ctrl_we = 1; end end default: begin end endcase // case (erx_ctrl_reg) end // external_rx_engine //---------------------------------------------------------------- // external_tx_engine // // Logic that implements the transmit engine towards // the external interface. //---------------------------------------------------------------- always @* begin: external_tx_engine txd_new = 0; txd_we = 0; txd_byte_new = 0; txd_byte_we = 0; txd_bit_ctr_rst = 0; txd_bit_ctr_inc = 0; txd_bitrate_ctr_rst = 0; txd_bitrate_ctr_inc = 0; txd_ack_new = 0; txd_ack_we = 0; etx_ctrl_new = ETX_IDLE; etx_ctrl_we = 0; case (etx_ctrl_reg) ETX_IDLE: begin txd_new = 1; txd_we = 1; if (txd_syn) begin txd_byte_new = txd_data; txd_byte_we = 1; txd_ack_new = 1; txd_ack_we = 1; txd_bitrate_ctr_rst = 1; etx_ctrl_new = ETX_ACK; etx_ctrl_we = 1; end end ETX_ACK: begin if (!txd_syn) begin txd_new = 0; txd_we = 1; txd_ack_new = 0; txd_ack_we = 1; etx_ctrl_new = ETX_START; etx_ctrl_we = 1; end end ETX_START: begin if (txd_bitrate_ctr_reg == DEFAULT_CLK_RATE) begin txd_bit_ctr_rst = 1; etx_ctrl_new = ETX_BITS; etx_ctrl_we = 1; end else begin txd_bitrate_ctr_inc = 1; end end ETX_BITS: begin if (txd_bitrate_ctr_reg < DEFAULT_CLK_RATE) begin txd_bitrate_ctr_inc = 1; end else begin txd_bitrate_ctr_rst = 1; if (txd_bit_ctr_reg == DEFAULT_DATA_BITS) begin txd_new = 1; txd_we = 1; etx_ctrl_new = ETX_STOP; etx_ctrl_we = 1; end else begin txd_new = txd_byte_reg[txd_bit_ctr_reg]; txd_we = 1; txd_bit_ctr_inc = 1; end end end ETX_STOP: begin txd_bitrate_ctr_inc = 1; if (txd_bitrate_ctr_reg == DEFAULT_CLK_RATE * DEFAULT_STOP_BITS) begin etx_ctrl_new = ETX_IDLE; etx_ctrl_we = 1; end end default: begin end endcase // case (etx_ctrl_reg) end // external_tx_engine endmodule // uart //====================================================================== // EOF uart.v //======================================================================