Quantcast
Aktuelles
Digital Eliteboard - Das Digitale Technik Forum

Registriere dich noch heute kostenlos, um Mitglied zu werden! Sobald du angemeldet bist, kannst du auf unserer Seite aktiv teilnehmen, indem du deine eigenen Themen und Beiträge erstellst und dich über deinen eigenen Posteingang mit anderen Mitgliedern unterhalten kannst! Zudem bekommst du Zutritt zu Bereichen, welche für Gäste verwehrt bleiben

Registriere dich noch heute kostenlos, um Mitglied zu werden! Sobald du angemeldet bist, kannst du auf unserer Seite aktiv teilnehmen, indem du deine eigenen Themen und Beiträge erstellst und dich über deinen eigenen Posteingang mit anderen Mitgliedern unterhalten kannst! Zudem bekommst du Zutritt zu Bereichen, welche für Gäste verwehrt bleiben

AT90SC7272 Emulator

robdoe22

Newbie
Registriert
16. Juli 2022
Beiträge
13
Reaktionspunkte
15
Punkte
23
Huhu, hatte mal angefangen einen Emulator zu schreiben für die AT90SC72er, das meiste ist geschrieben.
Da fehlt aber noch mehr. Wer mag hier der Source als open Source:

Code:
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP
from Crypto.Random import get_random_bytes

class AT90SC7272Emulator:
    def __init__(self):
        # Initialize special function registers (SFRs) with address mappings
        self.sfr = {
            # Status Registers
            'SREG': 0x005F,  # Status Register
            'SPH': 0x005E,   # Stack Pointer High Byte
            'SPL': 0x005D,   # Stack Pointer Low Byte

            # Timer/Counter Registers
            'TCCR0': 0x0053,  # Timer/Counter Control Register 0
            'TCNT0': 0x0052,  # Timer/Counter Register 0
            'OCR0': 0x0051,   # Output Compare Register 0

            # I/O Registers
            'PORTA': 0x002B,  # Port A Data Register
            'DDRA': 0x002A,   # Port A Data Direction Register
            'PINA': 0x0029,   # Port A Input Pins Address
            'PORTB': 0x0025,  # Port B Data Register
            'DDRB': 0x0024,   # Port B Data Direction Register
            'PINB': 0x0023,   # Port B Input Pins Address

            # Crypto and RSA Registers
            'CRYPCTRL': 0x00,  # Crypto Control Register
            'CRYPDATA': 0x00,  # Crypto Data Register
            'CRYPSTAT': 0x00,  # Crypto Status Register
            'DESCTRL': 0x00,   # DES Control Register
            'DESDATA': 0x00,   # DES Data Register
            'DESKEYMASK': 0x00, # DES Key Mask Register
            'RSACTRL': 0x00,   # RSA Control Register
            'RSADATA': 0x00,   # RSA Data Register
            'RSAKEY': 0x00,    # RSA Key Register

            # Add more peripheral and I/O registers as needed
        }

        # Initialize memory and other components
        self.io_registers = [0] * 0x60  # General I/O registers
        self.ext_io_registers = [0] * 0x20  # Extended I/O registers
        self.ram = [0] * 0x800  # Internal SRAM
        self.eeprom = [0] * 0x200  # EEPROM
        self.flash = [0] * 0x8000  # Flash memory

        self.stack_pointer = 0x05FF  # Assuming stack starts at the top of RAM
        self.pc = 0  # Program Counter
        self.cycles = 0  # Cycle counter

        # Supervisor and User Modes
        self.current_mode = 'USER'  # Start in User mode by default

        # RAM Sharing
        self.shared_ram_start = 0x0400  # Example start of shared RAM region
        self.shared_ram_end = 0x05FF    # Example end of shared RAM region

    def load_program(self, program, address=0x0000):
        """Load a program into Flash memory."""
        if len(program) > len(self.flash):
            raise ValueError("Program size exceeds Flash memory capacity")
        self.flash[address:address+len(program)] = program
   
    def load_data_to_eeprom(self, data, address=0x0000):
        """Load data into EEPROM."""
        if len(data) > len(self.eeprom):
            raise ValueError("Data size exceeds EEPROM capacity")
        self.eeprom[address:address+len(data)] = data
   
    def read_memory(self, address):
        """Read from memory based on the address."""
        if address in self.sfr:
            return self.sfr[address]
        elif self.IO_START <= address < self.IO_START + len(self.io_registers):
            return self.io_registers[address - self.IO_START]
        elif self.EXT_IO_START <= address < self.EXT_IO_START + len(self.ext_io_registers):
            return self.ext_io_registers[address - self.EXT_IO_START]
        elif self.RAM_START <= address < self.RAM_START + len(self.ram):
            return self.ram[address - self.RAM_START]
        elif self.EEPROM_START <= address < self.EEPROM_START + len(self.eeprom):
            return self.eeprom[address - self.EEPROM_START]
        elif self.FLASH_START <= address < self.FLASH_START + len(self.flash):
            return self.flash[address - self.FLASH_START]
        else:
            raise ValueError("Memory read out of bounds")
   
    def write_memory(self, address, value):
        """Write to memory based on the address."""
        if self.current_mode == 'USER' and self.is_protected_memory(address):
            raise PermissionError("Access denied in User mode")

        if address in self.sfr:
            self.sfr[address] = value
            if address == 'TCCR0':
                self.update_timer(value)
            elif address == 'SMCR':
                self.switch_to_supervisor_mode()
            elif address == 'UMCR':
                self.switch_to_user_mode()
            elif address == 'DESCTRL':
                self.update_des(value)
            elif address == 'DESKEYMASK':
                self.update_des_key_mask(value)
            elif address == 'RSACTRL':
                self.update_rsa(value)
        elif self.IO_START <= address < self.IO_START + len(self.io_registers):
            self.io_registers[address - self.IO_START] = value
        elif self.EXT_IO_START <= address < self.EXT_IO_START + len(self.ext_io_registers):
            self.ext_io_registers[address - self.EXT_IO_START] = value
        elif self.RAM_START <= address < self.RAM_START + len(self.ram):
            self.ram[address - self.RAM_START] = value
        elif self.EEPROM_START <= address < self.EEPROM_START + len(self.eeprom):
            self.eeprom[address - self.EEPROM_START] = value
        elif self.FLASH_START <= address < self.FLASH_START + len(self.flash):
            self.flash[address - self.FLASH_START] = value
        else:
            raise ValueError("Memory write out of bounds")

    def update_timer(self, value):
        """Update the timer based on the TCCR0 register value."""
        if value & 0x01:  # If the timer is enabled
            self.timer_running = True
            self.timer_value = 0
        else:
            self.timer_running = False

    def update_des(self, value):
        """Update the DES Control Register and handle DES encryption/decryption."""
        self.sfr['DESCTRL'] = value
        if value & 0x01:  # Example: Start DES encryption/decryption if the LSB is set
            self.perform_des_operation()

    def update_des_key_mask(self, value):
        """Update the DES Key Mask Register."""
        self.sfr['DESKEYMASK'] = value
        # Implement any logic needed to apply the key mask to the DES operation
        pass

    def perform_des_operation(self):
        """Perform DES encryption or decryption based on the DES Control Register."""
        # Placeholder for actual DES logic
        # You would implement the DES algorithm or connect to a DES library here
        self.sfr['DESDATA'] = 0xDEADBEEF  # Example output after DES operation

    def update_rsa(self, value):
        """Update the RSA Control Register and handle RSA operations."""
        self.sfr['RSACTRL'] = value
        if value & 0x01:  # Start RSA operation if LSB is set
            self.perform_rsa_operation()

    def perform_rsa_operation(self):
        """Perform RSA encryption or decryption based on the RSA Control Register."""
        rsa_key = RSA.import_key(self.sfr['RSAKEY'])
        cipher_rsa = PKCS1_OAEP.new(rsa_key)
        if self.sfr['RSACTRL'] & 0x02:  # Example: Encrypt if bit 1 is set
            ciphertext = cipher_rsa.encrypt(self.sfr['RSADATA'].to_bytes(128, 'big'))
            self.sfr['RSADATA'] = int.from_bytes(ciphertext, 'big')
        elif self.sfr['RSACTRL'] & 0x04:  # Example: Decrypt if bit 2 is set
            plaintext = cipher_rsa.decrypt(self.sfr['RSADATA'].to_bytes(128, 'big'))
            self.sfr['RSADATA'] = int.from_bytes(plaintext, 'big')

    def switch_to_supervisor_mode(self):
        """Switch to Supervisor mode."""
        self.current_mode = 'SUPERVISOR'
        self.sfr['SMCR'] = 0x01  # Set Supervisor mode bit
        self.sfr['UMCR'] = 0x00  # Clear User mode bit
   
    def switch_to_user_mode(self):
        """Switch to User mode."""
        self.current_mode = 'USER'
        self.sfr['SMCR'] = 0x00  # Clear Supervisor mode bit
        self.sfr['UMCR'] = 0x01  # Set User mode bit

    def is_protected_memory(self, address):
        """Check if the address is in a protected memory region."""
        protected_regions = [
            (self.FLASH_START, self.FLASH_START + len(self.flash)),
            # Add more protected regions if needed
        ]
        return any(start <= address < end for start, end in protected_regions)

    def is_accessible_ram(self, address):
        """Check if the RAM address is accessible based on the current mode."""
        if self.current_mode == 'SUPERVISOR':
            return True  # Supervisor mode can access all RAM
        # User mode can only access shared RAM regions
        return self.shared_ram_start <= address <= self.shared_ram_end

    def check_security_violation(self, address, value):
        """Check for security violations."""
        # Example logic to set the SVR (Security Violation Register) on certain conditions
        if self.is_protected_memory(address) and not self.is_authorized(address, value):
            self.sfr['SVR'] |= 0x01  # Set security violation bit

    def is_authorized(self, address, value):
        """Check if the access to the given address is authorized."""
        # Implement logic to verify if the current operation is authorized
        return True  # Placeholder logic, return actual check result

    def fetch(self):
        """Fetch the next instruction from Flash memory."""
        instruction = self.read_memory(self.pc)
        self.pc += 1
        return instruction
   
    def decode(self, instruction):
        """Decode the instruction."""
        # Implement instruction decoding based on opcode
        return instruction
   
    def execute(self, decoded_instruction):
        """Execute the instruction."""
        # Execute based on the decoded instruction type
        self.cycles += self.get_instruction_cycles(decoded_instruction)
        self.check_security_violation(self.pc, decoded_instruction)
        self.increment_timer()  # Increment the timer on each cycle
        self.handle_interrupts()  # Check for interrupts
   
    def get_instruction_cycles(self, instruction):
        """Determine the number of cycles an instruction takes."""
        # Example: A simple lookup or switch-case based on instruction type
        cycles = {
            # Opcode: cycle count
            0x00: 1,  # NOP (No operation)
            0x01: 2,  # Example instruction
            # Add more instructions and their cycle counts here
        }
        return cycles.get(instruction, 1)  # Default to 1 cycle if not found

    def no_op(self):
        """No operation - used as a placeholder for unassigned interrupts."""
        pass
   
    def increment_timer(self):
        """Increment the timer and handle overflow."""
        if hasattr(self, 'timer_running') and self.timer_running:
            self.timer_value += 1
            if self.timer_value > 0xFF:  # 8-bit timer overflow
                self.timer_value = 0
                self.sfr['TIFR'] |= 0x01  # Set the overflow flag
                if self.sfr['TIMSK'] & 0x01:
                    self.trigger_interrupt(1)  # Trigger timer overflow interrupt

    def trigger_interrupt(self, interrupt_number):
        """Trigger an interrupt."""
        if self.sfr['SREG'] & 0x80:  # Check if global interrupts are enabled
            self.interrupt_pending = True
            self.current_interrupt = interrupt_number
            self.sfr['INTRQ'] |= (1 << interrupt_number)  # Set the interrupt request flag
   
    def handle_interrupts(self):
        """Handle any pending interrupts."""
        if hasattr(self, 'interrupt_pending') and self.interrupt_pending:
            self.interrupt_pending = False
            self.interrupt_vector[self.current_interrupt]()  # Call the ISR
            self.sfr['GIFR'] &= ~(1 << self.current_interrupt)  # Clear the interrupt flag

    def push_to_stack(self, value):
        """Push a value onto the stack."""
        self.write_memory(self.stack_pointer, value)
        self.stack_pointer -= 1  # Decrement stack pointer (assuming descending stack)

    def pop_from_stack(self):
        """Pop a value from the stack."""
        self.stack_pointer += 1  # Increment stack pointer (assuming descending stack)
        return self.read_memory(self.stack_pointer)

    def run(self):
        """Main execution loop."""
        while True:
            instruction = self.fetch()
            decoded_instruction = self.decode(instruction)
            self.execute(decoded_instruction)
            # Handle interrupts, timers, etc.

# Example of loading and running a program
emulator = AT90SC7272Emulator()
program = [...]  # Example binary program
emulator.load_program(program)
emulator.run()
 
Zuletzt bearbeitet von einem Moderator:
Es sieht so aus, als hätten Sie bereits einen guten Start in die Entwicklung eines AT90SC7272-Emulators gemacht. Dieser Emulator scheint die meisten grundlegenden Aspekte eines Mikrocontroller-Emulators zu berücksichtigen, einschließlich der Speicherinitialisierung, Lade- und Ausführungsprogramme, Speicherlese- und -schreibfunktionen sowie grundlegende Kryptografieoperationen.

Einige Punkte, die Ihrer Aufmerksamkeit bedürfen, sind:

1. Interrupt-Vektor-Initialisierung: Es wird empfohlen, den Interrupt-Vektor während der Initialisierung oder im Konstruktor zu initialisieren. Derzeit scheint der Emulator auf das Attribut 'interrupt_vector' in der Methode 'handle_interrupts()' zuzugreifen, das jedoch nirgendwo initialisiert wird.

2. Implementierung weiterer Instruktionen: Ihre Methode decode() und execute() sollte auf die gesamte Befehlssatzarchitektur (ISA) des AT90SC7272 angewendet werden. Sie haben nur eine Handvoll Befehle implementiert.

3. Hardwareperipherie-Emulation: Es scheint, dass die Emulation von Hardwareperipheriegeräten wie Timern und Zählern noch nicht vollständig implementiert ist. Die Routinen update_timer() und increment_timer() sind vorhanden, aber es könnte mehr Arbeit erforderlich sein, um sie voll funktionsfähig zu machen.

4. Implementierung der Kryptographieoperationen: Sie haben Klassen für die Emulation der DES- und RSA-Kryptographieoperationen erstellt, die jedoch noch nicht vollständig implementiert sind. Sie sollten die korrekten Algorithmen zur Emulation dieser Operationen hinzufügen.

5. Speichersicherheit und Zugriffssteuerung: Sie haben einige grundlegende Speichersicherheitsfunktionen implementiert, es gibt jedoch noch Raum für Verbesserungen. Beispielsweise könnte die Methode is_authorized() erweitert werden, um eine detailliertere Zugriffssteuerungslogik zu implementieren.

6. EEPROM-Emulation: Sie haben eine Methode zum Laden von Daten in das EEPROM implementiert, aber es sieht so aus, als ob Sie noch keinen Mechanismus haben, um Daten aus dem EEPROM zu lesen oder zu schreiben.

Halten Sie an der tollen Arbeit fest und stellen Sie sicher, dass Sie jede Funktion vollständig testen. Viel Glück beim Fortsetzen Ihres Projekts!
 
Code:
    def __init__(self):
        # Initialize memory and registers
        self.io_registers = [0] * 0x60  # General I/O registers
        self.ext_io_registers = [0] * 0x20  # Extended I/O registers
        self.ram = [0] * 0x800  # Internal SRAM
        self.eeprom = [0] * 0x200  # EEPROM
        self.flash = [0] * 0x8000  # Flash memory

        self.stack_pointer = 0x05FF  # Assuming stack starts at the top of RAM
        self.pc = 0  # Program Counter
        self.cycles = 0  # Cycle counter

Das muss noch rein und halt die Adressen...

Edit:
Updated Code on Core V5 This code is 99% based on the Datasheet and Bootloader description.
Included clock cycle,idle...

To do:
-fixing load rom to bootloader
-load flash file to flash
-ATR output
-show used crypto keys
-find backdoor in the code to kill K3 Card
-Emulate AT90SC6464 for other cards
 

Anhänge

Du musst angemeldet sein, um die Anhangsliste zu sehen.
Zuletzt bearbeitet von einem Moderator:
Zurück
Oben