You'll practice your programming skills by writing some subroutines. You'll need to use both the call-by-value and call-by-reference techniques to pass arguments to your subroutines.
You'll write a program that decrypts an encrypted message using a simple encryption technique. To achieve A-level functionality, you'll have to decrypt a message without knowledge of its key.
A simple, yet effective encryption technique is to
XOR a piece of information with a key and send the result. The receiver must have the key in order to decrypt the message - which is accomplished simply by
XORing the encrypted data with the key. Let's say I wanted to send the binary byte
0b01100011 and my key was
0b11001010. To encrypt, I
XOR the two - the resulting byte is
0b10101001. To decrypt, I
XOR it with the key again - the resulting byte is
0b01100011 - the same as the original byte!
An encrypted message of arbitrary length is stored in ROM. Your job is to decrypt it, given a key - which is also stored in ROM. The contents of the message are ASCII characters - each character is encoded in a single byte. You can tell how long the message is by counting the number of bytes or by finding the difference between the address of the last byte and the address of the first byte.
You must write two subroutines:
Almost all of the work of your program will be performed in your two subroutines. Your main program should look something like this:
;initialize stack ;disable watchdog ;load addresses into registers to pass to decrypt_message subroutine call #decrypt_message CPUtrap: jmp CPUtrap
Sometimes the key isn't conveniently the same length as the unit of information you're trying to decrypt. To achieve B functionality, you'll have to adjust your implementation to handle arbitrary length keys.
Be sure to maintain good program structure and programming discipline when adjusting your program for B Functionality.
To achieve unbreakable encryption, the key and the message must be the same length. For long messages, this is often impractical and a key substantially shorter than the message is used. Thus, the key must be applied repeatedly to decrypt the message. You can exploit this repetition to crack the message. This is even easier if you have knowledge of the contents of the message (ASCII text, for instance). To achieve A Functionality, you'll have to use this technique to decrypt a message without knowledge of the key.
In addition to the Required Functionality, your program must decrypt messages with arbitrarily long keys. The keys are arbitrarily long series of bytes.
The length of the key should be a parameter passed into your
decryptMessage subroutine. You know the length of the key in advance. Also, you should not have to change your
Successfully decrypting this message will give you useful information to achieve A Functionality.
In addition to B Functionality, you must decrypt the following message without knowledge of its key (to include its length!):
Again, your program must find the key and decrypt the message, specifically in one glorious run. There are many ways to attack this problem. Some techniques require substantially more CPU time than others. Some techniques can be done by hand. Take the time to think through your approach before you begin coding.
Remember, the Prelab is due one full business day prior to the lab in order to provide your instructor time to provide you feedback on your plan (before you start implementing it).
Include in your prelab any other information, if any, from this lab you think will be useful in creating your program.
Read the guidance on Labs / Lab Notebooks / Coding standards thoroughly and follow it.
If you want, decrypt the first word of the message by hand so you get the idea of how it works. If the ASCII characters you are getting do not make sense, you are probably thinking about the problem incorrectly.
The MCU is fast - your program should execute almost instantaneously. Set a breakpoint at the point in your code where you trap the CPU - if it isn't hit quickly, you've got a problem.
In CCS, it's possible to view memory as Characters - this will be helpful in determining whether you successfully decrypted a message.
Since decryption and encryption are the same operation, you can encrypt test messages using the same subroutines you'll use to decrypt them. This would be a great way to test functionality of your code.
Use assembler directives for placing strings / byte sequences in memory:
stringLabel .string "This is a string!" byteLabel .byte 0xab,0xcd,0xef
Rather than documenting proof of functionality, in this lab you will be performing a live demo to prove that your code works. Videos may be accepted at instructor discretion.
If the instructor who verifies your demo does not teach your section, it is recommended that you print and provide a copy of the Printable Lab 2 Cutsheet to the instructor evaluating your code functionality. Provide this cutsheet to your instructor when the lab is due.
The final report will be very limited in scope. Simply document any changes to your design, limitations, and test plan since the Prelab. This is especially important for A functionality. If there are no changes, however, simply state that fact. Note, any broken functionality is considered a limitation.
You do not need to include any other sections in your final report.
Lab 2 Grade Sheet
|Prelab||On-Time: ---- Late: 1Day ---- 2Days ---- 3Days ---- 4+Days||25||Bus. Day Prior to L11|
|Required Functionality||On-Time: ---- Late: 1Day ---- 2Days ---- 3Days ---- 4+Days||35||L13|
|B Functionality||On-Time: ---- Late: 1Day ---- 2Days ---- 3Days ---- 4+Days||20||L13|
|A Functionality (Bonus)||On-Time: ---- Late: 1Day ---- 2Days ---- 3Days ---- 4+Days||10||L13|
|Code||On-Time: ---- Late: 1Day ---- 2Days ---- 3Days ---- 4+Days||10||L13 Taps|
|Lab Notebook||On-Time: ---- Late: 1Day ---- 2Days ---- 3Days ---- 4+Days||10||L13 Taps|