CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

strange bootloader behavior when using table read protect

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
loupan



Joined: 22 Oct 2007
Posts: 21

View user's profile Send private message

strange bootloader behavior when using table read protect
PostPosted: Fri Jan 01, 2010 11:27 am     Reply with quote

I would appreciate some help on what appears to be a subtle issue (at least to me!)

I have built a bootloader based on the CCS example files. All worked well. I then tried to adapt the bootloader to afford protection by encrypting the hex file and having the bootloader decrypt. Again, all worked well.

I then proceeded to the "code protection" step to prevent external reads of the pgm with an external programmer, and to prevent someone from loading in their own bootloader and reading the program with "read_program_eeprom()".

Code:
 #fuses HS, NOWDT, NOLVP, PROTECT, CPB, BBSIZ1

The above fuses (PROTECT and CPB) correctly protect the external programmer from reading the data - so far so good.

I then add EBTR (read protect non-boot blocks 0 -7)
with the goal of preventing any reads of the main program from a potential bootloader that might be loaded with the intent of doing table reads to capture the program.

This is still a "work in progress" as to the best strategy, but blocking the table reads with the EBTR fuse results in strange behavior - the bootloader writing only every 4th line starting at block 0. Below is a snippet of reading the chip contents back after attempted loading of the application with the bootloader (with code protect temporarily disabled) with NOEBTR case (which works as expected) and EBTR (which only writes one of every 4 lines:

NOEBTR (no write protection of blocks 0-7): - all OK
Code:

:1007E00006E050AE05D0D850010AD86E01D0D8909E
:1007F000000C4850D8B4A5D0546E4C50D8B4A1D0F9
:10080000545E05E37F0E5426D8B09BD006D0810EEF
:10081000545ED8A096D0D8B494D054C000F0016AE9
:10082000026A036A536A49C052F0528E4AC051F0BC
:100830004BC050F0190E546E4F50505E0DE2010E39
:10084000515E0AE2525E08E2535E06E2532A522AE1
:10085000512A4F50502628D04E50515E12E2010EC0
:10086000525E0FE2535E0DE2532A522A4E50512639
:100870004F50502619E3512A17E1522A15E1532A05


EBTR: EBTR (write protection of blocks 0-7 active): only 1 of 4 lines written
Code:

:1007E00006E050AE05D0D850010AD86E01D0D8909E
:1007F000000C4850D8B4A5D0546E4C50D8B4A1D0F9
:1008000000000000000000000000000000000000E8
:1008100000000000000000000000000000000000D8
:1008200000000000000000000000000000000000C8
:100830004BC050F0190E546E4F50505E0DE2010E39
:1008400000000000000000000000000000000000A8
:100850000000000000000000000000000000000098
:100860000000000000000000000000000000000088
:100870004F50502619E3512A17E1522A15E1532A05


The chip is an 18F8722 (128k memory) and the environment is 4.100.

I have checked the fuses in the .LST file and they track the .c files. I have also confirmed that the getenv reads the erase and write sizes as 64 and therefore excludes the conditional compilation of the erase statement.

The relevant section of the bootloader is shown below:
Code:

if (checksum != atoi_b16 (&buffer[buffidx-3]))
               do_GOOD_ACK = FALSE;
            else   {
               if (line_type == 0) {
                  // Loops through all of the data and stores it in data
                  // The last 2 bytes are the check sum, hence buffidx-3
                  for (i = 9,dataidx=0; i < buffidx-3; i += 2)
                     data[dataidx++]=atoi_b16(&buffer[i]);

                  #if getenv("FLASH_ERASE_SIZE") > getenv("FLASH_WRITE_SIZE")
                     if ((addr!=next_addr)&&(addr&(getenv("FLASH_ERASE_SIZE")/2-1)!=0))
                        erase_program_eeprom(addr);
                     next_addr = addr + 1;
                  #endif
                  write_program_memory(addr, data, count);
               }
               else if (line_type == 4)     // new high adrs
                  h_addr = make16(atoi_b16(&buffer[9]), atoi_b16(&buffer[11]));
            }
         }

The above ccs bootloader writes 16 bytes at a time vs the specified EEPROM write size of 64 bytes, but since all works well with the bootloader until I try to disable table reads with the EBTR fuse, I discounted the 64 byte vs the 16 byte write size.

I know this is a long post!! Thanks for any help, and Happy New Years to all.

Lou
Ttelmah
Guest







PostPosted: Fri Jan 01, 2010 3:33 pm     Reply with quote

Every constant array access in PIC18 code, uses table reads.
Almost certainly, a value is being loaded this way in your bootloader code, hence the problem...
You would have to avoid all of these in your code (both bootloader, and the main program), before the EBTR fuse can be used.
How is the third party bootloader going to get into the system in the first place?. If your encryption is any good, and the bootloader you have implemented, itself checks that the incoming code has a well coded 'key', the probability is low of this being possible.

Best Wishes
Guest








PostPosted: Fri Jan 01, 2010 6:13 pm     Reply with quote

Ttelmah wrote:
Every constant array access in PIC18 code, uses table reads.
Almost certainly, a value is being loaded this way in your bootloader code, hence the problem...
You would have to avoid all of these in your code (both bootloader, and the main program), before the EBTR fuse can be used.
How is the third party bootloader going to get into the system in the first place?. If your encryption is any good, and the bootloader you have implemented, itself checks that the incoming code has a well coded 'key', the probability is low of this being possible.

Best Wishes


Ttelmah,

You are good! Obviously I missed the forest for the trees on this one.
It therefore seems that the EBTR fuse is of very limited value.

If I may, let me ask you this.

If the Bootloader and code is code protected, that blocks one avenue - reading the code with a programmer. However, couldn't someone overwrite my bootloader with their own (i.e., just the Boot Block), and then read the application, which resides in the remainder of program memory (blocks 0-7) with the rogue bootloader?

Thanks again. Your help is much appreciated.

Regards,
Lou
treitmey



Joined: 23 Jan 2004
Posts: 1094
Location: Appleton,WI USA

View user's profile Send private message Visit poster's website

PostPosted: Fri Jan 01, 2010 8:43 pm     Reply with quote

But I think they wouldn't be able to program over the bootloader.
They would need access to YOUR bootloader, OR
erase the whole chip.
((They can't magically overwrite the little area called the bootloader))
Guest








PostPosted: Sat Jan 02, 2010 12:40 pm     Reply with quote

treitmey wrote:
But I think they wouldn't be able to program over the bootloader.
They would need access to YOUR bootloader, OR
erase the whole chip.
((They can't magically overwrite the little area called the bootloader))


Thanks for the comment. I was under the impression that a partial erase and reprogram of the chip was possible. I'll look into that aspect more closely.

Regards,
Lou
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group