Bulletproof firmware upgrades
Use a chip that has more than twice the amount of Flash memory you will need for your code. This way you can get the new firmware to this memory while still leaving the old one in case anything goes wrong.

After you decrypt and verify the checksums on the new firmware a bootloader can copy it to it's final location, replacing the old one. If anything goes wrong during this part, after a hard-reset the bootloader should see that the new firmware is not valid (by running the checksum once again) and retry the copying.

This is the simplest and most foolproof way I know. It also requires little code in the bootloader and does not require duplicating any functionality between the main program and the bootloader (you do not need any communication logic in the bootloader).